diff options
Diffstat (limited to 'Source/cmELF.cxx')
-rw-r--r-- | Source/cmELF.cxx | 699 |
1 files changed, 342 insertions, 357 deletions
diff --git a/Source/cmELF.cxx b/Source/cmELF.cxx index c6ae205..26f1a44 100644 --- a/Source/cmELF.cxx +++ b/Source/cmELF.cxx @@ -18,58 +18,75 @@ // Include the ELF format information system header. #if defined(__OpenBSD__) -# include <elf_abi.h> -# include <stdint.h> +#include <elf_abi.h> +#include <stdint.h> #elif defined(__HAIKU__) -# include <elf32.h> -# include <elf64.h> - typedef struct Elf32_Ehdr Elf32_Ehdr; - typedef struct Elf32_Shdr Elf32_Shdr; - typedef struct Elf32_Sym Elf32_Sym; - typedef struct Elf32_Rel Elf32_Rel; - typedef struct Elf32_Rela Elf32_Rela; -# define ELFMAG0 0x7F -# define ELFMAG1 'E' -# define ELFMAG2 'L' -# define ELFMAG3 'F' -# define ET_NONE 0 -# define ET_REL 1 -# define ET_EXEC 2 -# define ET_DYN 3 -# define ET_CORE 4 -# define EM_386 3 -# define EM_SPARC 2 -# define EM_PPC 20 +#include <elf32.h> +#include <elf64.h> +typedef struct Elf32_Ehdr Elf32_Ehdr; +typedef struct Elf32_Shdr Elf32_Shdr; +typedef struct Elf32_Sym Elf32_Sym; +typedef struct Elf32_Rel Elf32_Rel; +typedef struct Elf32_Rela Elf32_Rela; +#define ELFMAG0 0x7F +#define ELFMAG1 'E' +#define ELFMAG2 'L' +#define ELFMAG3 'F' +#define ET_NONE 0 +#define ET_REL 1 +#define ET_EXEC 2 +#define ET_DYN 3 +#define ET_CORE 4 +#define EM_386 3 +#define EM_SPARC 2 +#define EM_PPC 20 #else -# include <elf.h> +#include <elf.h> #endif #if defined(__sun) -# include <sys/link.h> // For dynamic section information +#include <sys/link.h> // For dynamic section information #endif // Low-level byte swapping implementation. -template <size_t s> struct cmELFByteSwapSize {}; +template <size_t s> +struct cmELFByteSwapSize +{ +}; void cmELFByteSwap(char*, cmELFByteSwapSize<1> const&) { } void cmELFByteSwap(char* data, cmELFByteSwapSize<2> const&) { char one_byte; - one_byte = data[0]; data[0] = data[1]; data[1] = one_byte; + one_byte = data[0]; + data[0] = data[1]; + data[1] = one_byte; } void cmELFByteSwap(char* data, cmELFByteSwapSize<4> const&) { char one_byte; - one_byte = data[0]; data[0] = data[3]; data[3] = one_byte; - one_byte = data[1]; data[1] = data[2]; data[2] = one_byte; + one_byte = data[0]; + data[0] = data[3]; + data[3] = one_byte; + one_byte = data[1]; + data[1] = data[2]; + data[2] = one_byte; } void cmELFByteSwap(char* data, cmELFByteSwapSize<8> const&) { char one_byte; - one_byte = data[0]; data[0] = data[7]; data[7] = one_byte; - one_byte = data[1]; data[1] = data[6]; data[6] = one_byte; - one_byte = data[2]; data[2] = data[5]; data[5] = one_byte; - one_byte = data[3]; data[3] = data[4]; data[4] = one_byte; + one_byte = data[0]; + data[0] = data[7]; + data[7] = one_byte; + one_byte = data[1]; + data[1] = data[6]; + data[6] = one_byte; + one_byte = data[2]; + data[2] = data[5]; + data[5] = one_byte; + one_byte = data[3]; + data[3] = data[4]; + data[4] = one_byte; } // Low-level byte swapping interface. @@ -83,20 +100,23 @@ class cmELFInternal { public: typedef cmELF::StringEntry StringEntry; - enum ByteOrderType { ByteOrderMSB, ByteOrderLSB }; + enum ByteOrderType + { + ByteOrderMSB, + ByteOrderLSB + }; // Construct and take ownership of the file stream object. - cmELFInternal(cmELF* external, - cmsys::auto_ptr<cmsys::ifstream>& fin, - ByteOrderType order): - External(external), - Stream(*fin.release()), - ByteOrder(order), - ELFType(cmELF::FileTypeInvalid) - { - // In most cases the processor-specific byte order will match that - // of the target execution environment. If we choose wrong here - // it is fixed when the header is read. + cmELFInternal(cmELF* external, cmsys::auto_ptr<cmsys::ifstream>& fin, + ByteOrderType order) + : External(external) + , Stream(*fin.release()) + , ByteOrder(order) + , ELFType(cmELF::FileTypeInvalid) + { +// In most cases the processor-specific byte order will match that +// of the target execution environment. If we choose wrong here +// it is fixed when the header is read. #if KWIML_ABI_ENDIAN_ID == KWIML_ABI_ENDIAN_ID_LITTLE this->NeedSwap = (this->ByteOrder == ByteOrderMSB); #elif KWIML_ABI_ENDIAN_ID == KWIML_ABI_ENDIAN_ID_BIG @@ -107,13 +127,10 @@ public: // We have not yet loaded the section info. this->DynamicSectionIndex = -1; - } + } // Destruct and delete the file stream object. - virtual ~cmELFInternal() - { - delete &this->Stream; - } + virtual ~cmELFInternal() { delete &this->Stream; } // Forward to the per-class implementation. virtual unsigned int GetNumberOfSections() const = 0; @@ -123,33 +140,33 @@ public: 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; - } + return this->Stream ? true : false; + } // 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; } @@ -176,10 +193,10 @@ protected: // Helper methods for subclasses. void SetErrorMessage(const char* msg) - { + { this->External->ErrorMessage = msg; this->ELFType = cmELF::FileTypeInvalid; - } + } // Store string table entry states. std::map<unsigned int, StringEntry> DynamicSectionStrings; @@ -190,7 +207,7 @@ struct cmELFTypes32 { typedef Elf32_Ehdr ELF_Ehdr; typedef Elf32_Shdr ELF_Shdr; - typedef Elf32_Dyn ELF_Dyn; + typedef Elf32_Dyn ELF_Dyn; typedef Elf32_Half ELF_Half; typedef KWIML_INT_uint32_t tagtype; static const char* GetName() { return "32-bit"; } @@ -201,7 +218,7 @@ struct cmELFTypes64 { typedef Elf64_Ehdr ELF_Ehdr; typedef Elf64_Shdr ELF_Shdr; - typedef Elf64_Dyn ELF_Dyn; + typedef Elf64_Dyn ELF_Dyn; typedef Elf64_Half ELF_Half; typedef KWIML_INT_uint64_t tagtype; static const char* GetName() { return "64-bit"; } @@ -209,26 +226,25 @@ struct cmELFTypes64 // Parser implementation template. template <class Types> -class cmELFInternalImpl: public cmELFInternal +class cmELFInternalImpl : public cmELFInternal { public: // Copy the ELF file format types from our configuration parameter. typedef typename Types::ELF_Ehdr ELF_Ehdr; typedef typename Types::ELF_Shdr ELF_Shdr; - typedef typename Types::ELF_Dyn ELF_Dyn; + typedef typename Types::ELF_Dyn ELF_Dyn; typedef typename Types::ELF_Half ELF_Half; typedef typename Types::tagtype tagtype; // Construct with a stream and byte swap indicator. - cmELFInternalImpl(cmELF* external, - cmsys::auto_ptr<cmsys::ifstream>& fin, + cmELFInternalImpl(cmELF* external, cmsys::auto_ptr<cmsys::ifstream>& fin, ByteOrderType order); // Return the number of sections as specified by the ELF header. virtual unsigned int GetNumberOfSections() const - { + { return static_cast<unsigned int>(this->ELFHeader.e_shnum); - } + } // Get the file position and size of a dynamic section entry. virtual unsigned int GetDynamicEntryCount(); @@ -239,18 +255,14 @@ public: // Print information about the ELF file. virtual void PrintInfo(std::ostream& os) const - { + { os << "ELF " << Types::GetName(); - if(this->ByteOrder == ByteOrderMSB) - { + if (this->ByteOrder == ByteOrderMSB) { os << " MSB"; - } - else if(this->ByteOrder == ByteOrderLSB) - { + } else if (this->ByteOrder == ByteOrderLSB) { os << " LSB"; - } - switch(this->ELFType) - { + } + switch (this->ELFType) { case cmELF::FileTypeInvalid: os << " invalid file"; break; @@ -272,13 +284,13 @@ public: case cmELF::FileTypeSpecificProc: os << " processor-specific type"; break; - } - os << "\n"; } + os << "\n"; + } private: void ByteSwap(ELF_Ehdr& elf_header) - { + { cmELFByteSwap(elf_header.e_type); cmELFByteSwap(elf_header.e_machine); cmELFByteSwap(elf_header.e_version); @@ -292,10 +304,10 @@ private: cmELFByteSwap(elf_header.e_shentsize); cmELFByteSwap(elf_header.e_shnum); cmELFByteSwap(elf_header.e_shstrndx); - } + } void ByteSwap(ELF_Shdr& sec_header) - { + { cmELFByteSwap(sec_header.sh_name); cmELFByteSwap(sec_header.sh_type); cmELFByteSwap(sec_header.sh_flags); @@ -306,97 +318,154 @@ private: cmELFByteSwap(sec_header.sh_info); cmELFByteSwap(sec_header.sh_addralign); cmELFByteSwap(sec_header.sh_entsize); - } + } 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; + 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; + 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; + 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; + 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; + 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; + 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; + case DT_RUNPATH: + cmELFByteSwap(dyn.d_un.d_val); + break; #endif #ifdef DT_FLAGS - case DT_FLAGS: cmELFByteSwap(dyn.d_un.d_val); break; + 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; + 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; + case DT_PREINIT_ARRAYSZ: + cmELFByteSwap(dyn.d_un.d_val); + break; #endif - } } + } bool FileTypeValid(ELF_Half et) - { + { unsigned int eti = static_cast<unsigned int>(et); - if(eti == ET_NONE || eti == ET_REL || eti == ET_EXEC || - eti == ET_DYN || eti == ET_CORE) - { + if (eti == ET_NONE || eti == ET_REL || eti == ET_EXEC || eti == ET_DYN || + eti == ET_CORE) { return true; - } + } #if defined(ET_LOOS) && defined(ET_HIOS) - if(eti >= ET_LOOS && eti <= ET_HIOS) - { + if (eti >= ET_LOOS && eti <= ET_HIOS) { return true; - } + } #endif #if defined(ET_LOPROC) && defined(ET_HIPROC) - if(eti >= ET_LOPROC && eti <= ET_HIPROC) - { + if (eti >= ET_LOPROC && eti <= ET_HIPROC) { return true; - } + } #endif return false; - } + } bool Read(ELF_Ehdr& x) - { + { // Read the header from the file. - if(!this->Stream.read(reinterpret_cast<char*>(&x), sizeof(x))) - { + if (!this->Stream.read(reinterpret_cast<char*>(&x), sizeof(x))) { return false; - } + } // The byte order of ELF header fields may not match that of the // processor-specific data. The header fields are ordered to @@ -405,63 +474,55 @@ private: // value. As a heuristic, if the type is invalid but its // swapped value is okay then flip our swap mode. ELF_Half et = x.e_type; - if(this->NeedSwap) - { + if (this->NeedSwap) { cmELFByteSwap(et); - } - if(!this->FileTypeValid(et)) - { + } + if (!this->FileTypeValid(et)) { cmELFByteSwap(et); - if(this->FileTypeValid(et)) - { + if (this->FileTypeValid(et)) { // The previous byte order guess was wrong. Flip it. this->NeedSwap = !this->NeedSwap; - } } + } // Fix the byte order of the header. - if(this->NeedSwap) - { + if (this->NeedSwap) { ByteSwap(x); - } - return true; } + return true; + } bool Read(ELF_Shdr& x) - { - if(this->Stream.read(reinterpret_cast<char*>(&x), sizeof(x)) && - this->NeedSwap) - { + { + if (this->Stream.read(reinterpret_cast<char*>(&x), sizeof(x)) && + this->NeedSwap) { ByteSwap(x); - } - return this->Stream? true:false; } + return this->Stream ? true : false; + } bool Read(ELF_Dyn& x) - { - if(this->Stream.read(reinterpret_cast<char*>(&x), sizeof(x)) && - this->NeedSwap) - { + { + if (this->Stream.read(reinterpret_cast<char*>(&x), sizeof(x)) && + this->NeedSwap) { ByteSwap(x); - } - return this->Stream? true:false; } + return this->Stream ? true : false; + } bool LoadSectionHeader(ELF_Half i) - { + { // Read the section header from the file. this->Stream.seekg(this->ELFHeader.e_shoff + this->ELFHeader.e_shentsize * i); - if(!this->Read(this->SectionHeaders[i])) - { + if (!this->Read(this->SectionHeaders[i])) { return false; - } + } // Identify some important sections. - if(this->SectionHeaders[i].sh_type == SHT_DYNAMIC) - { + if (this->SectionHeaders[i].sh_type == SHT_DYNAMIC) { this->DynamicSectionIndex = i; - } - return true; } + return true; + } bool LoadDynamicSection(); @@ -476,22 +537,18 @@ private: }; template <class Types> -cmELFInternalImpl<Types> -::cmELFInternalImpl(cmELF* external, - cmsys::auto_ptr<cmsys::ifstream>& fin, - ByteOrderType order): - cmELFInternal(external, fin, order) +cmELFInternalImpl<Types>::cmELFInternalImpl( + cmELF* external, cmsys::auto_ptr<cmsys::ifstream>& fin, ByteOrderType order) + : cmELFInternal(external, fin, order) { // Read the main header. - if(!this->Read(this->ELFHeader)) - { + if (!this->Read(this->ELFHeader)) { this->SetErrorMessage("Failed to read main ELF header."); return; - } + } // Determine the ELF file type. - switch(this->ELFHeader.e_type) - { + switch (this->ELFHeader.e_type) { case ET_NONE: this->SetErrorMessage("ELF file type is NONE."); return; @@ -507,133 +564,116 @@ cmELFInternalImpl<Types> case ET_CORE: this->ELFType = cmELF::FileTypeCore; break; - default: - { + default: { unsigned int eti = static_cast<unsigned int>(this->ELFHeader.e_type); #if defined(ET_LOOS) && defined(ET_HIOS) - if(eti >= ET_LOOS && eti <= ET_HIOS) - { + if (eti >= ET_LOOS && eti <= ET_HIOS) { this->ELFType = cmELF::FileTypeSpecificOS; break; - } + } #endif #if defined(ET_LOPROC) && defined(ET_HIPROC) - if(eti >= ET_LOPROC && eti <= ET_HIPROC) - { + if (eti >= ET_LOPROC && eti <= ET_HIPROC) { this->ELFType = cmELF::FileTypeSpecificProc; break; - } + } #endif std::ostringstream e; e << "Unknown ELF file type " << eti; this->SetErrorMessage(e.str().c_str()); return; - } } + } // Load the section headers. this->SectionHeaders.resize(this->ELFHeader.e_shnum); - for(ELF_Half i=0; i < this->ELFHeader.e_shnum; ++i) - { - if(!this->LoadSectionHeader(i)) - { + for (ELF_Half i = 0; i < this->ELFHeader.e_shnum; ++i) { + if (!this->LoadSectionHeader(i)) { this->SetErrorMessage("Failed to load section headers."); return; - } } + } } template <class Types> bool cmELFInternalImpl<Types>::LoadDynamicSection() { // If there is no dynamic section we are done. - if(this->DynamicSectionIndex < 0) - { + if (this->DynamicSectionIndex < 0) { return false; - } + } // If the section was already loaded we are done. - if(!this->DynamicSectionEntries.empty()) - { + if (!this->DynamicSectionEntries.empty()) { return true; - } + } // If there are no entries we are done. ELF_Shdr const& sec = this->SectionHeaders[this->DynamicSectionIndex]; - if(sec.sh_entsize == 0) - { + if (sec.sh_entsize == 0) { return false; - } + } // Allocate the dynamic section entries. int n = static_cast<int>(sec.sh_size / sec.sh_entsize); this->DynamicSectionEntries.resize(n); // Read each entry. - for(int j=0; j < n; ++j) - { + for (int j = 0; j < n; ++j) { // Seek to the beginning of the section entry. - this->Stream.seekg(sec.sh_offset + sec.sh_entsize*j); + this->Stream.seekg(sec.sh_offset + sec.sh_entsize * j); ELF_Dyn& dyn = this->DynamicSectionEntries[j]; // Try reading the entry. - if(!this->Read(dyn)) - { + if (!this->Read(dyn)) { this->SetErrorMessage("Error reading entry from DYNAMIC section."); this->DynamicSectionIndex = -1; return false; - } } + } return true; } template <class Types> unsigned int cmELFInternalImpl<Types>::GetDynamicEntryCount() { - if(!this->LoadDynamicSection()) - { + if (!this->LoadDynamicSection()) { return 0; - } - for(unsigned int i = 0; i < this->DynamicSectionEntries.size(); ++i) - { - if(this->DynamicSectionEntries[i].d_tag == DT_NULL) - { + } + for (unsigned int i = 0; i < this->DynamicSectionEntries.size(); ++i) { + if (this->DynamicSectionEntries[i].d_tag == DT_NULL) { return i; - } } + } return static_cast<unsigned int>(this->DynamicSectionEntries.size()); } template <class Types> unsigned long cmELFInternalImpl<Types>::GetDynamicEntryPosition(int j) { - if(!this->LoadDynamicSection()) - { + if (!this->LoadDynamicSection()) { return 0; - } - if(j < 0 || j >= static_cast<int>(this->DynamicSectionEntries.size())) - { + } + if (j < 0 || j >= static_cast<int>(this->DynamicSectionEntries.size())) { return 0; - } + } ELF_Shdr const& sec = this->SectionHeaders[this->DynamicSectionIndex]; - return static_cast<unsigned long>(sec.sh_offset + sec.sh_entsize*j); + return static_cast<unsigned long>(sec.sh_offset + sec.sh_entsize * j); } template <class Types> -cmELF::StringEntry const* -cmELFInternalImpl<Types>::GetDynamicSectionString(unsigned int tag) +cmELF::StringEntry const* cmELFInternalImpl<Types>::GetDynamicSectionString( + unsigned int tag) { // Short-circuit if already checked. std::map<unsigned int, StringEntry>::iterator dssi = this->DynamicSectionStrings.find(tag); - if(dssi != this->DynamicSectionStrings.end()) - { - if(dssi->second.Position > 0) - { + if (dssi != this->DynamicSectionStrings.end()) { + if (dssi->second.Position > 0) { return &dssi->second; - } - return 0; } + return 0; + } // Create an entry for this tag. Assume it is missing until found. StringEntry& se = this->DynamicSectionStrings[tag]; @@ -642,36 +682,31 @@ cmELFInternalImpl<Types>::GetDynamicSectionString(unsigned int tag) se.IndexInSection = -1; // Try reading the dynamic section. - if(!this->LoadDynamicSection()) - { + if (!this->LoadDynamicSection()) { return 0; - } + } // Get the string table referenced by the DYNAMIC section. ELF_Shdr const& sec = this->SectionHeaders[this->DynamicSectionIndex]; - if(sec.sh_link >= this->SectionHeaders.size()) - { + if (sec.sh_link >= this->SectionHeaders.size()) { this->SetErrorMessage("Section DYNAMIC has invalid string table index."); return 0; - } + } ELF_Shdr const& strtab = this->SectionHeaders[sec.sh_link]; // Look for the requested entry. - for(typename std::vector<ELF_Dyn>::iterator - di = this->DynamicSectionEntries.begin(); - di != this->DynamicSectionEntries.end(); ++di) - { + for (typename std::vector<ELF_Dyn>::iterator di = + this->DynamicSectionEntries.begin(); + di != this->DynamicSectionEntries.end(); ++di) { ELF_Dyn& dyn = *di; - if(static_cast<tagtype>(dyn.d_tag) == static_cast<tagtype>(tag)) - { + if (static_cast<tagtype>(dyn.d_tag) == static_cast<tagtype>(tag)) { // We found the tag requested. // Make sure the position given is within the string section. - if(dyn.d_un.d_val >= strtab.sh_size) - { + if (dyn.d_un.d_val >= strtab.sh_size) { this->SetErrorMessage("Section DYNAMIC references string beyond " "the end of its string section."); return 0; - } + } // Seek to the position reported by the entry. unsigned long first = static_cast<unsigned long>(dyn.d_un.d_val); @@ -686,26 +721,21 @@ cmELFInternalImpl<Types>::GetDynamicSectionString(unsigned int tag) // assumption. bool terminated = false; char c; - while(last != end && this->Stream.get(c) && !(terminated && c)) - { + while (last != end && this->Stream.get(c) && !(terminated && c)) { ++last; - if(c) - { + if (c) { se.Value += c; - } - else - { + } else { terminated = true; - } } + } // Make sure the whole value was read. - if(!this->Stream) - { + if (!this->Stream) { this->SetErrorMessage("Dynamic section specifies unreadable RPATH."); se.Value = ""; return 0; - } + } // The value has been read successfully. Report it. se.Position = static_cast<unsigned long>(strtab.sh_offset + first); @@ -713,84 +743,69 @@ cmELFInternalImpl<Types>::GetDynamicSectionString(unsigned int tag) se.IndexInSection = static_cast<int>(di - this->DynamicSectionEntries.begin()); return &se; - } } + } return 0; } //============================================================================ // External class implementation. -cmELF::cmELF(const char* fname): Internal(0) +cmELF::cmELF(const char* fname) + : Internal(0) { // Try to open the file. cmsys::auto_ptr<cmsys::ifstream> fin(new cmsys::ifstream(fname)); // Quit now if the file could not be opened. - if(!fin.get() || !*fin) - { + if (!fin.get() || !*fin) { this->ErrorMessage = "Error opening input file."; return; - } + } // Read the ELF identification block. char ident[EI_NIDENT]; - if(!fin->read(ident, EI_NIDENT)) - { + if (!fin->read(ident, EI_NIDENT)) { this->ErrorMessage = "Error reading ELF identification."; return; - } - if(!fin->seekg(0)) - { + } + if (!fin->seekg(0)) { this->ErrorMessage = "Error seeking to beginning of file."; return; - } + } // Verify the ELF identification. - if(!(ident[EI_MAG0] == ELFMAG0 && - ident[EI_MAG1] == ELFMAG1 && - ident[EI_MAG2] == ELFMAG2 && - ident[EI_MAG3] == ELFMAG3)) - { + if (!(ident[EI_MAG0] == ELFMAG0 && ident[EI_MAG1] == ELFMAG1 && + ident[EI_MAG2] == ELFMAG2 && ident[EI_MAG3] == ELFMAG3)) { this->ErrorMessage = "File does not have a valid ELF identification."; return; - } + } // Check the byte order in which the rest of the file is encoded. cmELFInternal::ByteOrderType order; - if(ident[EI_DATA] == ELFDATA2LSB) - { + if (ident[EI_DATA] == ELFDATA2LSB) { // File is LSB. - order = cmELFInternal::ByteOrderLSB; - } - else if(ident[EI_DATA] == ELFDATA2MSB) - { + order = cmELFInternal::ByteOrderLSB; + } else if (ident[EI_DATA] == ELFDATA2MSB) { // File is MSB. - order = cmELFInternal::ByteOrderMSB; - } - else - { + order = cmELFInternal::ByteOrderMSB; + } else { this->ErrorMessage = "ELF file is not LSB or MSB encoded."; return; - } + } // Check the class of the file and construct the corresponding // parser implementation. - if(ident[EI_CLASS] == ELFCLASS32) - { + if (ident[EI_CLASS] == ELFCLASS32) { // 32-bit ELF this->Internal = new cmELFInternalImpl<cmELFTypes32>(this, fin, order); - } - else if(ident[EI_CLASS] == ELFCLASS64) - { + } else if (ident[EI_CLASS] == ELFCLASS64) { // 64-bit ELF this->Internal = new cmELFInternalImpl<cmELFTypes64>(this, fin, order); - } - else - { + } else { this->ErrorMessage = "ELF file class is not 32-bit or 64-bit."; return; - } + } } cmELF::~cmELF() @@ -805,126 +820,96 @@ bool cmELF::Valid() const cmELF::FileType cmELF::GetFileType() const { - if(this->Valid()) - { + if (this->Valid()) { return this->Internal->GetFileType(); - } - else - { + } else { return FileTypeInvalid; - } + } } unsigned int cmELF::GetNumberOfSections() const { - if(this->Valid()) - { + if (this->Valid()) { return this->Internal->GetNumberOfSections(); - } - else - { + } else { return 0; - } + } } unsigned int cmELF::GetDynamicEntryCount() const { - if(this->Valid()) - { + if (this->Valid()) { return this->Internal->GetDynamicEntryCount(); - } - else - { + } else { return 0; - } + } } unsigned long cmELF::GetDynamicEntryPosition(int index) const { - if(this->Valid()) - { + if (this->Valid()) { return this->Internal->GetDynamicEntryPosition(index); - } - else - { + } else { return 0; - } + } } bool cmELF::ReadBytes(unsigned long pos, unsigned long size, char* buf) const { - if(this->Valid()) - { + if (this->Valid()) { return this->Internal->ReadBytes(pos, size, buf); - } - else - { + } else { return false; - } + } } bool cmELF::GetSOName(std::string& soname) { - if(StringEntry const* se = this->GetSOName()) - { + if (StringEntry const* se = this->GetSOName()) { soname = se->Value; return true; - } - else - { + } else { return false; - } + } } cmELF::StringEntry const* cmELF::GetSOName() { - if(this->Valid() && - this->Internal->GetFileType() == cmELF::FileTypeSharedLibrary) - { + if (this->Valid() && + this->Internal->GetFileType() == cmELF::FileTypeSharedLibrary) { return this->Internal->GetSOName(); - } - else - { + } else { return 0; - } + } } cmELF::StringEntry const* cmELF::GetRPath() { - if(this->Valid() && - (this->Internal->GetFileType() == cmELF::FileTypeExecutable || - this->Internal->GetFileType() == cmELF::FileTypeSharedLibrary)) - { + if (this->Valid() && + (this->Internal->GetFileType() == cmELF::FileTypeExecutable || + this->Internal->GetFileType() == cmELF::FileTypeSharedLibrary)) { return this->Internal->GetRPath(); - } - else - { + } else { return 0; - } + } } cmELF::StringEntry const* cmELF::GetRunPath() { - if(this->Valid() && - (this->Internal->GetFileType() == cmELF::FileTypeExecutable || - this->Internal->GetFileType() == cmELF::FileTypeSharedLibrary)) - { + if (this->Valid() && + (this->Internal->GetFileType() == cmELF::FileTypeExecutable || + this->Internal->GetFileType() == cmELF::FileTypeSharedLibrary)) { return this->Internal->GetRunPath(); - } - else - { + } else { return 0; - } + } } void cmELF::PrintInfo(std::ostream& os) const { - if(this->Valid()) - { + if (this->Valid()) { this->Internal->PrintInfo(os); - } - else - { + } else { os << "Not a valid ELF file.\n"; - } + } } |