diff options
-rw-r--r-- | Source/cmELF.cxx | 77 | ||||
-rw-r--r-- | Source/cmELF.h | 18 |
2 files changed, 95 insertions, 0 deletions
diff --git a/Source/cmELF.cxx b/Source/cmELF.cxx index f78eed5..bf0130a 100644 --- a/Source/cmELF.cxx +++ b/Source/cmELF.cxx @@ -134,6 +134,9 @@ public: virtual unsigned int GetNumberOfSections() const = 0; virtual unsigned int GetDynamicEntryCount() = 0; virtual unsigned long GetDynamicEntryPosition(int j) = 0; + virtual cmELF::DynamicEntryList GetDynamicEntries() = 0; + virtual std::vector<char> EncodeDynamicEntries( + const cmELF::DynamicEntryList&) = 0; virtual StringEntry const* GetDynamicSectionString(unsigned int tag) = 0; virtual void PrintInfo(std::ostream& os) const = 0; @@ -250,6 +253,10 @@ public: unsigned int GetDynamicEntryCount() CM_OVERRIDE; unsigned long GetDynamicEntryPosition(int j) CM_OVERRIDE; + cmELF::DynamicEntryList GetDynamicEntries() CM_OVERRIDE; + std::vector<char> EncodeDynamicEntries(const cmELF::DynamicEntryList&) + CM_OVERRIDE; + // Lookup a string from the dynamic section with the given tag. StringEntry const* GetDynamicSectionString(unsigned int tag) CM_OVERRIDE; @@ -553,6 +560,54 @@ unsigned long cmELFInternalImpl<Types>::GetDynamicEntryPosition(int j) } template <class Types> +cmELF::DynamicEntryList cmELFInternalImpl<Types>::GetDynamicEntries() +{ + cmELF::DynamicEntryList result; + + // Ensure entries have been read from file + if (!this->LoadDynamicSection()) { + return result; + } + + // Copy into public array + result.reserve(this->DynamicSectionEntries.size()); + for (typename std::vector<ELF_Dyn>::iterator di = + this->DynamicSectionEntries.begin(); + di != this->DynamicSectionEntries.end(); ++di) { + ELF_Dyn& dyn = *di; + result.push_back( + std::pair<unsigned long, unsigned long>(dyn.d_tag, dyn.d_un.d_val)); + } + + return result; +} + +template <class Types> +std::vector<char> cmELFInternalImpl<Types>::EncodeDynamicEntries( + const cmELF::DynamicEntryList& entries) +{ + std::vector<char> result; + result.reserve(sizeof(ELF_Dyn) * entries.size()); + + for (cmELF::DynamicEntryList::const_iterator it = entries.begin(); + it != entries.end(); it++) { + // Store the entry in an ELF_Dyn, byteswap it, then serialize to chars + ELF_Dyn dyn; + dyn.d_tag = static_cast<tagtype>(it->first); + dyn.d_un.d_val = static_cast<tagtype>(it->second); + + if (this->NeedSwap) { + ByteSwap(dyn); + } + + char* pdyn = reinterpret_cast<char*>(&dyn); + result.insert(result.end(), pdyn, pdyn + sizeof(ELF_Dyn)); + } + + return result; +} + +template <class Types> cmELF::StringEntry const* cmELFInternalImpl<Types>::GetDynamicSectionString( unsigned int tag) { @@ -642,6 +697,9 @@ cmELF::StringEntry const* cmELFInternalImpl<Types>::GetDynamicSectionString( //============================================================================ // External class implementation. +const long cmELF::TagRPath = DT_RPATH; +const long cmELF::TagRunPath = DT_RUNPATH; + cmELF::cmELF(const char* fname) : Internal(CM_NULLPTR) { @@ -745,6 +803,25 @@ unsigned long cmELF::GetDynamicEntryPosition(int index) const return 0; } +cmELF::DynamicEntryList cmELF::GetDynamicEntries() const +{ + if (this->Valid()) { + return this->Internal->GetDynamicEntries(); + } + + return cmELF::DynamicEntryList(); +} + +std::vector<char> cmELF::EncodeDynamicEntries( + const cmELF::DynamicEntryList& dentries) const +{ + if (this->Valid()) { + return this->Internal->EncodeDynamicEntries(dentries); + } + + return std::vector<char>(); +} + bool cmELF::ReadBytes(unsigned long pos, unsigned long size, char* buf) const { if (this->Valid()) { diff --git a/Source/cmELF.h b/Source/cmELF.h index 7e7c1d6..3fc59b4 100644 --- a/Source/cmELF.h +++ b/Source/cmELF.h @@ -7,6 +7,8 @@ #include <iosfwd> #include <string> +#include <utility> +#include <vector> #if !defined(CMAKE_USE_ELF_PARSER) #error "This file may be included only if CMAKE_USE_ELF_PARSER is enabled." @@ -61,6 +63,9 @@ public: int IndexInSection; }; + /** Represent entire dynamic section header */ + typedef std::vector<std::pair<long, unsigned long> > DynamicEntryList; + /** Get the type of the file opened. */ FileType GetFileType() const; @@ -75,6 +80,15 @@ public: zero on error. */ unsigned long GetDynamicEntryPosition(int index) const; + /** Get a copy of all the DYNAMIC section header entries. + Returns an empty vector on error */ + DynamicEntryList GetDynamicEntries() const; + + /** Encodes a DYNAMIC section header entry list into a char vector according + to the type of ELF file this is */ + std::vector<char> EncodeDynamicEntries( + const DynamicEntryList& entries) const; + /** Read bytes from the file. */ bool ReadBytes(unsigned long pos, unsigned long size, char* buf) const; @@ -91,6 +105,10 @@ public: /** Print human-readable information about the ELF file. */ void PrintInfo(std::ostream& os) const; + /** Interesting dynamic tags. + If the tag is 0, it does not exist in the host ELF implementation */ + static const long TagRPath, TagRunPath; + private: friend class cmELFInternal; bool Valid() const; |