Răsfoiți Sursa

ENH: Added cmELF methods to get information about DYNAMIC section entries.

Brad King 17 ani în urmă
părinte
comite
3ff5404cca
2 a modificat fișierele cu 102 adăugiri și 0 ștergeri
  1. 88 0
      Source/cmELF.cxx
  2. 14 0
      Source/cmELF.h

+ 88 - 0
Source/cmELF.cxx

@@ -98,9 +98,18 @@ public:
 
   // Forward to the per-class implementation.
   virtual unsigned int GetNumberOfSections() const = 0;
+  virtual unsigned int GetDynamicEntryCount() = 0;
+  virtual unsigned long GetDynamicEntryPosition(int j) = 0;
   virtual StringEntry const* GetDynamicSectionString(int tag) = 0;
   virtual void PrintInfo(std::ostream& os) const = 0;
 
+  bool ReadBytes(unsigned long pos, unsigned long size, char* buf)
+    {
+    this->Stream.seekg(pos);
+    this->Stream.read(buf, size);
+    return this->Stream?true:false;
+    }
+
   // Lookup the SONAME in the DYNAMIC section.
   StringEntry const* GetSOName()
     {
@@ -201,6 +210,10 @@ public:
     return static_cast<unsigned int>(this->ELFHeader.e_shnum);
     }
 
+  // Get the file position and size of a dynamic section entry.
+  virtual unsigned int GetDynamicEntryCount();
+  virtual unsigned long GetDynamicEntryPosition(int j);
+
   // Lookup a string from the dynamic section with the given tag.
   virtual StringEntry const* GetDynamicSectionString(int tag);
 
@@ -550,6 +563,40 @@ bool cmELFInternalImpl<Types>::LoadDynamicSection()
   return true;
 }
 
+//----------------------------------------------------------------------------
+template <class Types>
+unsigned int cmELFInternalImpl<Types>::GetDynamicEntryCount()
+{
+  if(!this->LoadDynamicSection())
+    {
+    return 0;
+    }
+  for(unsigned int i = 0; i < this->DynamicSectionEntries.size(); ++i)
+    {
+    if(this->DynamicSectionEntries[i].d_tag == DT_NULL)
+      {
+      return i;
+      }
+    }
+  return this->DynamicSectionEntries.size();
+}
+
+//----------------------------------------------------------------------------
+template <class Types>
+unsigned long cmELFInternalImpl<Types>::GetDynamicEntryPosition(int j)
+{
+  if(!this->LoadDynamicSection())
+    {
+    return 0;
+    }
+  if(j < 0 || j >= this->DynamicSectionEntries.size())
+    {
+    return 0;
+    }
+  ELF_Shdr const& sec = this->SectionHeaders[this->DynamicSectionIndex];
+  return sec.sh_offset + sec.sh_entsize*j;
+}
+
 //----------------------------------------------------------------------------
 template <class Types>
 cmELF::StringEntry const*
@@ -571,6 +618,7 @@ cmELFInternalImpl<Types>::GetDynamicSectionString(int tag)
   StringEntry& se = this->DynamicSectionStrings[tag];
   se.Position = 0;
   se.Size = 0;
+  se.IndexInSection = -1;
 
   // Try reading the dynamic section.
   if(!this->LoadDynamicSection())
@@ -641,6 +689,7 @@ cmELFInternalImpl<Types>::GetDynamicSectionString(int tag)
       // The value has been read successfully.  Report it.
       se.Position = static_cast<unsigned long>(strtab.sh_offset + first);
       se.Size = last - first;
+      se.IndexInSection = di - this->DynamicSectionEntries.begin();
       return &se;
       }
     }
@@ -761,6 +810,45 @@ unsigned int cmELF::GetNumberOfSections() const
     }
 }
 
+//----------------------------------------------------------------------------
+unsigned int cmELF::GetDynamicEntryCount() const
+{
+  if(this->Valid())
+    {
+    return this->Internal->GetDynamicEntryCount();
+    }
+  else
+    {
+    return 0;
+    }
+}
+
+//----------------------------------------------------------------------------
+unsigned long cmELF::GetDynamicEntryPosition(int index) const
+{
+  if(this->Valid())
+    {
+    return this->Internal->GetDynamicEntryPosition(index);
+    }
+  else
+    {
+    return 0;
+    }
+}
+
+//----------------------------------------------------------------------------
+bool cmELF::ReadBytes(unsigned long pos, unsigned long size, char* buf) const
+{
+  if(this->Valid())
+    {
+    return this->Internal->ReadBytes(pos, size, buf);
+    }
+  else
+    {
+    return false;
+    }
+}
+
 //----------------------------------------------------------------------------
 bool cmELF::GetSOName(std::string& soname)
 {

+ 14 - 0
Source/cmELF.h

@@ -68,6 +68,9 @@ public:
     // The size of the string table entry.  This includes the space
     // allocated for one or more null terminators.
     unsigned long Size;
+
+    // The index of the section entry referencing the string.
+    int IndexInSection;
   };
 
   /** Get the type of the file opened.  */
@@ -76,6 +79,17 @@ public:
   /** Get the number of ELF sections present.  */
   unsigned int GetNumberOfSections() const;
 
+  /** Get the number of DYNAMIC section entries before the first
+      DT_NULL.  Returns zero on error.  */
+  unsigned int GetDynamicEntryCount() const;
+
+  /** Get the position of a DYNAMIC section header entry.  Returns
+      zero on error.  */
+  unsigned long GetDynamicEntryPosition(int index) const;
+
+  /** Read bytes from the file.  */
+  bool ReadBytes(unsigned long pos, unsigned long size, char* buf) const;
+
   /** Get the SONAME field if any.  */
   bool GetSOName(std::string& soname);
   StringEntry const* GetSOName();