summaryrefslogtreecommitdiffstats
path: root/Source/cmELF.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/cmELF.cxx')
-rw-r--r--Source/cmELF.cxx699
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";
- }
+ }
}