summaryrefslogtreecommitdiff
path: root/include/llvm/Object/ELF.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/Object/ELF.h')
-rw-r--r--include/llvm/Object/ELF.h103
1 files changed, 42 insertions, 61 deletions
diff --git a/include/llvm/Object/ELF.h b/include/llvm/Object/ELF.h
index 1c34cf1485..9e8b6fafd8 100644
--- a/include/llvm/Object/ELF.h
+++ b/include/llvm/Object/ELF.h
@@ -582,7 +582,6 @@ protected:
private:
typedef SmallVector<const Elf_Shdr *, 2> Sections_t;
typedef DenseMap<unsigned, unsigned> IndexMap_t;
- typedef DenseMap<const Elf_Shdr*, SmallVector<uint32_t, 1> > RelocMap_t;
const Elf_Ehdr *Header;
const Elf_Shdr *SectionHeaderTable;
@@ -634,13 +633,9 @@ private:
void LoadVersionNeeds(const Elf_Shdr *ec) const;
void LoadVersionMap() const;
- /// @brief Map sections to an array of relocation sections that reference
- /// them sorted by section index.
- RelocMap_t SectionRelocMap;
-
/// @brief Get the relocation section that contains \a Rel.
const Elf_Shdr *getRelSection(DataRefImpl Rel) const {
- return getSection(Rel.w.b);
+ return getSection(Rel.d.a);
}
public:
@@ -712,6 +707,7 @@ protected:
bool &Result) const;
virtual relocation_iterator getSectionRelBegin(DataRefImpl Sec) const;
virtual relocation_iterator getSectionRelEnd(DataRefImpl Sec) const;
+ virtual section_iterator getRelocatedSection(DataRefImpl Sec) const;
virtual error_code getRelocationNext(DataRefImpl Rel,
RelocationRef &Res) const;
@@ -1458,13 +1454,9 @@ template<class ELFT>
relocation_iterator
ELFObjectFile<ELFT>::getSectionRelBegin(DataRefImpl Sec) const {
DataRefImpl RelData;
- const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
- typename RelocMap_t::const_iterator ittr = SectionRelocMap.find(sec);
- if (sec != 0 && ittr != SectionRelocMap.end()) {
- RelData.w.a = getSection(ittr->second[0])->sh_info;
- RelData.w.b = ittr->second[0];
- RelData.w.c = 0;
- }
+ uintptr_t SHT = reinterpret_cast<uintptr_t>(SectionHeaderTable);
+ RelData.d.a = (Sec.p - SHT) / Header->e_shentsize;
+ RelData.d.b = 0;
return relocation_iterator(RelocationRef(RelData, this));
}
@@ -1472,44 +1464,41 @@ template<class ELFT>
relocation_iterator
ELFObjectFile<ELFT>::getSectionRelEnd(DataRefImpl Sec) const {
DataRefImpl RelData;
- const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
- typename RelocMap_t::const_iterator ittr = SectionRelocMap.find(sec);
- if (sec != 0 && ittr != SectionRelocMap.end()) {
- // Get the index of the last relocation section for this section.
- std::size_t relocsecindex = ittr->second[ittr->second.size() - 1];
- const Elf_Shdr *relocsec = getSection(relocsecindex);
- RelData.w.a = relocsec->sh_info;
- RelData.w.b = relocsecindex;
- RelData.w.c = relocsec->sh_size / relocsec->sh_entsize;
- }
+ uintptr_t SHT = reinterpret_cast<uintptr_t>(SectionHeaderTable);
+ const Elf_Shdr *S = reinterpret_cast<const Elf_Shdr *>(Sec.p);
+ RelData.d.a = (Sec.p - SHT) / Header->e_shentsize;
+ if (S->sh_type != ELF::SHT_RELA && S->sh_type != ELF::SHT_REL)
+ RelData.d.b = 0;
+ else
+ RelData.d.b = S->sh_size / S->sh_entsize;
+
return relocation_iterator(RelocationRef(RelData, this));
}
+template <class ELFT>
+section_iterator
+ELFObjectFile<ELFT>::getRelocatedSection(DataRefImpl Sec) const {
+ if (Header->e_type != ELF::ET_REL)
+ return end_sections();
+
+ const Elf_Shdr *S = reinterpret_cast<const Elf_Shdr *>(Sec.p);
+ unsigned sh_type = S->sh_type;
+ if (sh_type != ELF::SHT_RELA && sh_type != ELF::SHT_REL)
+ return end_sections();
+
+ unsigned SecIndex = S->sh_info;
+ assert(SecIndex != 0);
+ const Elf_Shdr *R = getSection(S->sh_info);
+ DataRefImpl D;
+ D.p = reinterpret_cast<uintptr_t>(R);
+ return section_iterator(SectionRef(D, this));
+}
+
// Relocations
template<class ELFT>
error_code ELFObjectFile<ELFT>::getRelocationNext(DataRefImpl Rel,
RelocationRef &Result) const {
- ++Rel.w.c;
- const Elf_Shdr *relocsec = getSection(Rel.w.b);
- if (Rel.w.c >= (relocsec->sh_size / relocsec->sh_entsize)) {
- // We have reached the end of the relocations for this section. See if there
- // is another relocation section.
- typename RelocMap_t::mapped_type relocseclist =
- SectionRelocMap.lookup(getSection(Rel.w.a));
-
- // Do a binary search for the current reloc section index (which must be
- // present). Then get the next one.
- typename RelocMap_t::mapped_type::const_iterator loc =
- std::lower_bound(relocseclist.begin(), relocseclist.end(), Rel.w.b);
- ++loc;
-
- // If there is no next one, don't do anything. The ++Rel.w.c above sets Rel
- // to the end iterator.
- if (loc != relocseclist.end()) {
- Rel.w.b = *loc;
- Rel.w.a = 0;
- }
- }
+ ++Rel.d.b;
Result = RelocationRef(Rel, this);
return object_error::success;
}
@@ -1518,7 +1507,7 @@ template<class ELFT>
error_code ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel,
SymbolRef &Result) const {
uint32_t symbolIdx;
- const Elf_Shdr *sec = getSection(Rel.w.b);
+ const Elf_Shdr *sec = getRelSection(Rel);
switch (sec->sh_type) {
default :
report_fatal_error("Invalid section type in Rel!");
@@ -1561,7 +1550,7 @@ error_code ELFObjectFile<ELFT>::getRelocationOffset(DataRefImpl Rel,
template<class ELFT>
uint64_t ELFObjectFile<ELFT>::getROffset(DataRefImpl Rel) const {
- const Elf_Shdr *sec = getSection(Rel.w.b);
+ const Elf_Shdr *sec = getRelSection(Rel);
switch (sec->sh_type) {
default:
report_fatal_error("Invalid section type in Rel!");
@@ -1575,7 +1564,7 @@ uint64_t ELFObjectFile<ELFT>::getROffset(DataRefImpl Rel) const {
template<class ELFT>
error_code ELFObjectFile<ELFT>::getRelocationType(DataRefImpl Rel,
uint64_t &Result) const {
- const Elf_Shdr *sec = getSection(Rel.w.b);
+ const Elf_Shdr *sec = getRelSection(Rel);
switch (sec->sh_type) {
default :
report_fatal_error("Invalid section type in Rel!");
@@ -2192,7 +2181,7 @@ StringRef ELFObjectFile<ELFT>::getRelocationTypeName(uint32_t Type) const {
template<class ELFT>
error_code ELFObjectFile<ELFT>::getRelocationTypeName(
DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
- const Elf_Shdr *sec = getSection(Rel.w.b);
+ const Elf_Shdr *sec = getRelSection(Rel);
uint32_t type;
switch (sec->sh_type) {
default :
@@ -2234,7 +2223,7 @@ error_code ELFObjectFile<ELFT>::getRelocationTypeName(
template<class ELFT>
error_code ELFObjectFile<ELFT>::getRelocationAddend(
DataRefImpl Rel, int64_t &Result) const {
- const Elf_Shdr *sec = getSection(Rel.w.b);
+ const Elf_Shdr *sec = getRelSection(Rel);
switch (sec->sh_type) {
default :
report_fatal_error("Invalid section type in Rel!");
@@ -2252,7 +2241,7 @@ error_code ELFObjectFile<ELFT>::getRelocationAddend(
template<class ELFT>
error_code ELFObjectFile<ELFT>::getRelocationValueString(
DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
- const Elf_Shdr *sec = getSection(Rel.w.b);
+ const Elf_Shdr *sec = getRelSection(Rel);
uint8_t type;
StringRef res;
int64_t addend = 0;
@@ -2402,10 +2391,8 @@ ELFObjectFile<ELFT>::ELFObjectFile(MemoryBuffer *Object, error_code &ec)
break;
}
case ELF::SHT_REL:
- case ELF::SHT_RELA: {
- SectionRelocMap[getSection(sh->sh_info)].push_back(i);
+ case ELF::SHT_RELA:
break;
- }
case ELF::SHT_DYNAMIC: {
if (dot_dynamic_sec != NULL)
// FIXME: Proper error handling.
@@ -2438,12 +2425,6 @@ ELFObjectFile<ELFT>::ELFObjectFile(MemoryBuffer *Object, error_code &ec)
++sh;
}
- // Sort section relocation lists by index.
- for (typename RelocMap_t::iterator i = SectionRelocMap.begin(),
- e = SectionRelocMap.end(); i != e; ++i) {
- std::sort(i->second.begin(), i->second.end());
- }
-
// Get string table sections.
dot_shstrtab_sec = getSection(getStringTableIndex());
if (dot_shstrtab_sec) {
@@ -2795,13 +2776,13 @@ ELFObjectFile<ELFT>::getSymbol(DataRefImpl Symb) const {
template<class ELFT>
const typename ELFObjectFile<ELFT>::Elf_Rel *
ELFObjectFile<ELFT>::getRel(DataRefImpl Rel) const {
- return getEntry<Elf_Rel>(Rel.w.b, Rel.w.c);
+ return getEntry<Elf_Rel>(Rel.d.a, Rel.d.b);
}
template<class ELFT>
const typename ELFObjectFile<ELFT>::Elf_Rela *
ELFObjectFile<ELFT>::getRela(DataRefImpl Rela) const {
- return getEntry<Elf_Rela>(Rela.w.b, Rela.w.c);
+ return getEntry<Elf_Rela>(Rela.d.a, Rela.d.b);
}
template<class ELFT>