[cmake-commits] king committed cmELF.cxx 1.3 1.4 cmELF.h 1.1 1.2
cmake-commits at cmake.org
cmake-commits at cmake.org
Fri Feb 29 11:13:01 EST 2008
Update of /cvsroot/CMake/CMake/Source
In directory public:/mounts/ram/cvs-serv7316/Source
Modified Files:
cmELF.cxx cmELF.h
Log Message:
ENH: Make cmELF parser more general and powerful
- Add support to get RPATH and RUNPATH entries.
- Add support to get file offsets to strings.
- Add more DT_* tags to byte swapping.
Index: cmELF.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmELF.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- cmELF.h 27 Feb 2008 21:26:35 -0000 1.1
+++ cmELF.h 29 Feb 2008 16:12:59 -0000 1.2
@@ -54,6 +54,16 @@
FileTypeCore
};
+ /** Represent string table entries. */
+ struct StringEntry
+ {
+ // The string value itself.
+ std::string Value;
+
+ // The position in the file at which the string appears.
+ unsigned long Position;
+ };
+
/** Get the type of the file opened. */
FileType GetFileType() const;
@@ -62,6 +72,13 @@
/** Get the SONAME field if any. */
bool GetSOName(std::string& soname);
+ StringEntry const* GetSOName();
+
+ /** Get the RPATH field if any. */
+ StringEntry const* GetRPath();
+
+ /** Get the RUNPATH field if any. */
+ StringEntry const* GetRunPath();
/** Print human-readable information about the ELF file. */
void PrintInfo(std::ostream& os) const;
Index: cmELF.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmELF.cxx,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- cmELF.cxx 28 Feb 2008 13:43:10 -0000 1.3
+++ cmELF.cxx 29 Feb 2008 16:12:59 -0000 1.4
@@ -65,6 +65,7 @@
class cmELFInternal
{
public:
+ typedef cmELF::StringEntry StringEntry;
enum ByteOrderType { ByteOrderMSB, ByteOrderLSB };
// Construct and take ownership of the file stream object.
@@ -95,9 +96,31 @@
// Forward to the per-class implementation.
virtual unsigned int GetNumberOfSections() const = 0;
- virtual bool GetSOName(std::string& soname) = 0;
+ virtual StringEntry const* GetDynamicSectionString(int tag) = 0;
virtual void PrintInfo(std::ostream& os) const = 0;
+ // Lookup the SONAME in the DYNAMIC section.
+ StringEntry const* GetSOName()
+ {
+ return this->GetDynamicSectionString(DT_SONAME);
+ }
+
+ // Lookup the RPATH in the DYNAMIC section.
+ StringEntry const* GetRPath()
+ {
+ return this->GetDynamicSectionString(DT_RPATH);
+ }
+
+ // Lookup the RUNPATH in the DYNAMIC section.
+ StringEntry const* GetRunPath()
+ {
+#if defined(DT_RUNPATH)
+ return this->GetDynamicSectionString(DT_RUNPATH);
+#else
+ return 0;
+#endif
+ }
+
// Return the recorded ELF type.
cmELF::FileType GetFileType() const { return this->ELFType; }
protected:
@@ -127,6 +150,9 @@
this->External->ErrorMessage = msg;
this->ELFType = cmELF::FileTypeInvalid;
}
+
+ // Store string table entry states.
+ std::map<int, StringEntry> DynamicSectionStrings;
};
//----------------------------------------------------------------------------
@@ -173,8 +199,8 @@
return static_cast<unsigned int>(this->ELFHeader.e_shnum);
}
- // Lookup the SONAME in the DYNAMIC section.
- virtual bool GetSOName(std::string& soname);
+ // Lookup a string from the dynamic section with the given tag.
+ virtual StringEntry const* GetDynamicSectionString(int tag);
// Print information about the ELF file.
virtual void PrintInfo(std::ostream& os) const
@@ -270,6 +296,33 @@
case DT_DEBUG: cmELFByteSwap(dyn.d_un.d_ptr); break;
case DT_TEXTREL: /* dyn.d_un ignored */ break;
case DT_JMPREL: cmELFByteSwap(dyn.d_un.d_ptr); break;
+#ifdef T_BIND_NOW
+ case T_BIND_NOW: /* dyn.d_un ignored */ break;
+#endif
+#ifdef DT_INIT_ARRAY
+ case DT_INIT_ARRAY: cmELFByteSwap(dyn.d_un.d_ptr); break;
+#endif
+#ifdef DT_FINI_ARRAY
+ case DT_FINI_ARRAY: cmELFByteSwap(dyn.d_un.d_ptr); break;
+#endif
+#ifdef DT_INIT_ARRAYSZ
+ case DT_INIT_ARRAYSZ: cmELFByteSwap(dyn.d_un.d_val); break;
+#endif
+#ifdef DT_FINI_ARRAYSZ
+ case DT_FINI_ARRAYSZ: cmELFByteSwap(dyn.d_un.d_val); break;
+#endif
+#ifdef DT_RUNPATH
+ case DT_RUNPATH: cmELFByteSwap(dyn.d_un.d_val); break;
+#endif
+#ifdef DT_FLAGS
+ case DT_FLAGS: cmELFByteSwap(dyn.d_un.d_val); break;
+#endif
+#ifdef DT_PREINIT_ARRAY
+ case DT_PREINIT_ARRAY: cmELFByteSwap(dyn.d_un.d_ptr); break;
+#endif
+#ifdef DT_PREINIT_ARRAYSZ
+ case DT_PREINIT_ARRAYSZ: cmELFByteSwap(dyn.d_un.d_val); break;
+#endif
}
}
@@ -329,10 +382,6 @@
// Store all entries of the DYNAMIC section.
std::vector<ELF_Dyn> DynamicSectionEntries;
-
- // Store the SOName if it has been loaded.
- std::string SOName;
- bool SONameChecked;
};
//----------------------------------------------------------------------------
@@ -343,9 +392,6 @@
ByteOrderType order):
cmELFInternal(external, fin, order)
{
- // Initialize state.
- this->SONameChecked = false;
-
// Read the main header.
if(!this->Read(this->ELFHeader))
{
@@ -424,20 +470,29 @@
//----------------------------------------------------------------------------
template <class Types>
-bool cmELFInternalImpl<Types>::GetSOName(std::string& soname)
+cmELF::StringEntry const*
+cmELFInternalImpl<Types>::GetDynamicSectionString(int tag)
{
// Short-circuit if already checked.
- if(this->SONameChecked)
+ std::map<int, StringEntry>::iterator dssi =
+ this->DynamicSectionStrings.find(tag);
+ if(dssi != this->DynamicSectionStrings.end())
{
- soname = this->SOName;
- return !soname.empty();
+ if(dssi->second.Position > 0)
+ {
+ return &dssi->second;
+ }
+ return 0;
}
- this->SONameChecked = true;
+
+ // Create an entry for this tag. Assume it is missing until found.
+ StringEntry& se = this->DynamicSectionStrings[tag];
+ se.Position = 0;
// Try reading the dynamic section.
if(!this->LoadDynamicSection())
{
- return false;
+ return 0;
}
// Get the string table referenced by the DYNAMIC section.
@@ -445,35 +500,43 @@
if(sec.sh_link >= this->SectionHeaders.size())
{
this->SetErrorMessage("Section DYNAMIC has invalid string table index.");
- return false;
+ return 0;
}
ELF_Shdr const& strtab = this->SectionHeaders[sec.sh_link];
- // Look for the soname entry.
+ // Look for the requested entry.
for(typename std::vector<ELF_Dyn>::iterator
di = this->DynamicSectionEntries.begin();
di != this->DynamicSectionEntries.end(); ++di)
{
ELF_Dyn& dyn = *di;
- if(dyn.d_tag == DT_SONAME)
+ if(dyn.d_tag == tag)
{
+ // Seek to the position reported by the entry.
this->Stream.seekg(strtab.sh_offset + dyn.d_un.d_val);
+
+ // Read the string.
char c;
while(this->Stream.get(c) && c != 0)
{
- this->SOName += c;
+ se.Value += c;
}
+
+ // Make sure the whole value was read.
if(!this->Stream)
{
- this->SetErrorMessage("Dynamic section specifies unreadable SONAME.");
- this->SOName = "";
- return false;
+ this->SetErrorMessage("Dynamic section specifies unreadable RPATH.");
+ se.Value = "";
+ return 0;
}
- soname = this->SOName;
- return true;
+
+ // The value has been read successfully. Report it.
+ se.Position =
+ static_cast<unsigned long>(strtab.sh_offset + dyn.d_un.d_val);
+ return &se;
}
}
- return false;
+ return 0;
}
//============================================================================
@@ -593,14 +656,58 @@
//----------------------------------------------------------------------------
bool cmELF::GetSOName(std::string& soname)
{
+ if(StringEntry const* se = this->GetSOName())
+ {
+ soname = se->Value;
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+//----------------------------------------------------------------------------
+cmELF::StringEntry const* cmELF::GetSOName()
+{
if(this->Valid() &&
this->Internal->GetFileType() == cmELF::FileTypeSharedLibrary)
{
- return this->Internal->GetSOName(soname);
+ return this->Internal->GetSOName();
}
else
{
- return false;
+ return 0;
+ }
+}
+
+//----------------------------------------------------------------------------
+cmELF::StringEntry const* cmELF::GetRPath()
+{
+ if(this->Valid() &&
+ this->Internal->GetFileType() == cmELF::FileTypeExecutable ||
+ this->Internal->GetFileType() == cmELF::FileTypeSharedLibrary)
+ {
+ return this->Internal->GetRPath();
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+//----------------------------------------------------------------------------
+cmELF::StringEntry const* cmELF::GetRunPath()
+{
+ if(this->Valid() &&
+ this->Internal->GetFileType() == cmELF::FileTypeExecutable ||
+ this->Internal->GetFileType() == cmELF::FileTypeSharedLibrary)
+ {
+ return this->Internal->GetRunPath();
+ }
+ else
+ {
+ return 0;
}
}
More information about the Cmake-commits
mailing list