diff options
Diffstat (limited to 'Source/cmELF.cxx')
-rw-r--r-- | Source/cmELF.cxx | 224 |
1 files changed, 79 insertions, 145 deletions
diff --git a/Source/cmELF.cxx b/Source/cmELF.cxx index 2d86674..0655da9 100644 --- a/Source/cmELF.cxx +++ b/Source/cmELF.cxx @@ -132,18 +132,13 @@ 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 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; - bool ReadBytes(unsigned long pos, unsigned long size, char* buf) - { - this->Stream.seekg(pos); - this->Stream.read(buf, size); - return !this->Stream.fail(); - } - // Lookup the SONAME in the DYNAMIC section. StringEntry const* GetSOName() { @@ -246,10 +241,13 @@ public: return static_cast<unsigned int>(this->ELFHeader.e_shnum); } - // Get the file position and size of a dynamic section entry. - unsigned int GetDynamicEntryCount() CM_OVERRIDE; + // Get the file position of a dynamic section entry. 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; @@ -289,6 +287,10 @@ public: } private: + // ByteSwap(ELF_Dyn) assumes d_val and d_ptr are the same size + typedef char dyn_size_assert + [sizeof(ELF_Dyn().d_un.d_val) == sizeof(ELF_Dyn().d_un.d_ptr) ? 1 : -1]; + void ByteSwap(ELF_Ehdr& elf_header) { cmELFByteSwap(elf_header.e_type); @@ -323,121 +325,7 @@ private: void ByteSwap(ELF_Dyn& dyn) { cmELFByteSwap(dyn.d_tag); - switch (dyn.d_tag) { - case DT_NULL: /* dyn.d_un ignored */ - break; - case DT_NEEDED: - cmELFByteSwap(dyn.d_un.d_val); - break; - case DT_PLTRELSZ: - cmELFByteSwap(dyn.d_un.d_val); - break; - case DT_PLTGOT: - cmELFByteSwap(dyn.d_un.d_ptr); - break; - case DT_HASH: - cmELFByteSwap(dyn.d_un.d_ptr); - break; - case DT_STRTAB: - cmELFByteSwap(dyn.d_un.d_ptr); - break; - case DT_SYMTAB: - cmELFByteSwap(dyn.d_un.d_ptr); - break; - case DT_RELA: - cmELFByteSwap(dyn.d_un.d_ptr); - break; - case DT_RELASZ: - cmELFByteSwap(dyn.d_un.d_val); - break; - case DT_RELAENT: - cmELFByteSwap(dyn.d_un.d_val); - break; - case DT_STRSZ: - cmELFByteSwap(dyn.d_un.d_val); - break; - case DT_SYMENT: - cmELFByteSwap(dyn.d_un.d_val); - break; - case DT_INIT: - cmELFByteSwap(dyn.d_un.d_ptr); - break; - case DT_FINI: - cmELFByteSwap(dyn.d_un.d_ptr); - break; - case DT_SONAME: - cmELFByteSwap(dyn.d_un.d_val); - break; - case DT_RPATH: - cmELFByteSwap(dyn.d_un.d_val); - break; - case DT_SYMBOLIC: /* dyn.d_un ignored */ - break; - case DT_REL: - cmELFByteSwap(dyn.d_un.d_ptr); - break; - case DT_RELSZ: - cmELFByteSwap(dyn.d_un.d_val); - break; - case DT_RELENT: - cmELFByteSwap(dyn.d_un.d_val); - break; - case DT_PLTREL: - cmELFByteSwap(dyn.d_un.d_val); - break; - 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 - } + cmELFByteSwap(dyn.d_un.d_val); } bool FileTypeValid(ELF_Half et) @@ -636,30 +524,64 @@ bool cmELFInternalImpl<Types>::LoadDynamicSection() } template <class Types> -unsigned int cmELFInternalImpl<Types>::GetDynamicEntryCount() +unsigned long cmELFInternalImpl<Types>::GetDynamicEntryPosition(int j) { 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; - } + if (j < 0 || j >= static_cast<int>(this->DynamicSectionEntries.size())) { + return 0; } - return static_cast<unsigned int>(this->DynamicSectionEntries.size()); + ELF_Shdr const& sec = this->SectionHeaders[this->DynamicSectionIndex]; + return static_cast<unsigned long>(sec.sh_offset + sec.sh_entsize * j); } template <class Types> -unsigned long cmELFInternalImpl<Types>::GetDynamicEntryPosition(int j) +cmELF::DynamicEntryList cmELFInternalImpl<Types>::GetDynamicEntries() { + cmELF::DynamicEntryList result; + + // Ensure entries have been read from file if (!this->LoadDynamicSection()) { - return 0; + return result; } - if (j < 0 || j >= static_cast<int>(this->DynamicSectionEntries.size())) { - return 0; + + // 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)); } - ELF_Shdr const& sec = this->SectionHeaders[this->DynamicSectionIndex]; - return static_cast<unsigned long>(sec.sh_offset + sec.sh_entsize * j); + + 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> @@ -752,6 +674,15 @@ cmELF::StringEntry const* cmELFInternalImpl<Types>::GetDynamicSectionString( //============================================================================ // External class implementation. +const long cmELF::TagRPath = DT_RPATH; +const long cmELF::TagRunPath = DT_RUNPATH; + +#ifdef DT_MIPS_RLD_MAP_REL +const long cmELF::TagMipsRldMapRel = DT_MIPS_RLD_MAP_REL; +#else +const long cmELF::TagMipsRldMapRel = 0; +#endif + cmELF::cmELF(const char* fname) : Internal(CM_NULLPTR) { @@ -839,28 +770,31 @@ unsigned int cmELF::GetNumberOfSections() const return 0; } -unsigned int cmELF::GetDynamicEntryCount() const +unsigned long cmELF::GetDynamicEntryPosition(int index) const { if (this->Valid()) { - return this->Internal->GetDynamicEntryCount(); + return this->Internal->GetDynamicEntryPosition(index); } return 0; } -unsigned long cmELF::GetDynamicEntryPosition(int index) const +cmELF::DynamicEntryList cmELF::GetDynamicEntries() const { if (this->Valid()) { - return this->Internal->GetDynamicEntryPosition(index); + return this->Internal->GetDynamicEntries(); } - return 0; + + return cmELF::DynamicEntryList(); } -bool cmELF::ReadBytes(unsigned long pos, unsigned long size, char* buf) const +std::vector<char> cmELF::EncodeDynamicEntries( + const cmELF::DynamicEntryList& dentries) const { if (this->Valid()) { - return this->Internal->ReadBytes(pos, size, buf); + return this->Internal->EncodeDynamicEntries(dentries); } - return false; + + return std::vector<char>(); } bool cmELF::GetSOName(std::string& soname) |