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