aboutsummaryrefslogtreecommitdiffstats
path: root/include/llvm/Object
diff options
context:
space:
mode:
authorSid Manning <sidneym@codeaurora.org>2012-09-17 12:27:39 +0000
committerSid Manning <sidneym@codeaurora.org>2012-09-17 12:27:39 +0000
commit9b7ca410621f6988b2d4203b90058dd4252848a8 (patch)
tree964cd033a2969a63131dbec7857ef75a86b6456c /include/llvm/Object
parenta26cadc58d32a739ccf99423922bfc542c1026b1 (diff)
downloadexternal_llvm-9b7ca410621f6988b2d4203b90058dd4252848a8.zip
external_llvm-9b7ca410621f6988b2d4203b90058dd4252848a8.tar.gz
external_llvm-9b7ca410621f6988b2d4203b90058dd4252848a8.tar.bz2
Add Michael Spencer's iterator class for stepping through relocations. Add method that, given a symbol index, will return the symbol's data.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@164026 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/llvm/Object')
-rw-r--r--include/llvm/Object/ELF.h85
1 files changed, 85 insertions, 0 deletions
diff --git a/include/llvm/Object/ELF.h b/include/llvm/Object/ELF.h
index 06edf43..759d63c 100644
--- a/include/llvm/Object/ELF.h
+++ b/include/llvm/Object/ELF.h
@@ -462,6 +462,59 @@ private:
// This is set the first time getLoadName is called.
mutable const char *dt_soname;
+public:
+ /// \brief Iterate over relocations in a .rel or .rela section.
+ template<class RelocT>
+ class ELFRelocationIterator {
+ public:
+ typedef void difference_type;
+ typedef const RelocT value_type;
+ typedef std::forward_iterator_tag iterator_category;
+ typedef value_type &reference;
+ typedef value_type *pointer;
+
+ /// \brief Default construct iterator.
+ ELFRelocationIterator() : Section(0), Current(0) {}
+ ELFRelocationIterator(const Elf_Shdr *Sec, const char *Start)
+ : Section(Sec)
+ , Current(Start) {}
+
+ reference operator *() {
+ assert(Current && "Attempted to dereference an invalid iterator!");
+ return *reinterpret_cast<const RelocT*>(Current);
+ }
+
+ pointer operator ->() {
+ assert(Current && "Attempted to dereference an invalid iterator!");
+ return reinterpret_cast<const RelocT*>(Current);
+ }
+
+ bool operator ==(const ELFRelocationIterator &Other) {
+ return Section == Other.Section && Current == Other.Current;
+ }
+
+ bool operator !=(const ELFRelocationIterator &Other) {
+ return !(*this == Other);
+ }
+
+ ELFRelocationIterator &operator ++(int) {
+ assert(Current && "Attempted to increment an invalid iterator!");
+ Current += Section->sh_entsize;
+ return *this;
+ }
+
+ ELFRelocationIterator operator ++() {
+ ELFRelocationIterator Tmp = *this;
+ ++*this;
+ return Tmp;
+ }
+
+ private:
+ const Elf_Shdr *Section;
+ const char *Current;
+ };
+
+private:
// Records for each version index the corresponding Verdef or Vernaux entry.
// This is filled the first time LoadVersionMap() is called.
class VersionMapEntry : public PointerIntPair<const void*, 1> {
@@ -597,6 +650,27 @@ public:
virtual dyn_iterator begin_dynamic_table() const;
virtual dyn_iterator end_dynamic_table() const;
+ typedef ELFRelocationIterator<Elf_Rela> Elf_Rela_Iter;
+ typedef ELFRelocationIterator<Elf_Rel> Elf_Rel_Iter;
+
+ virtual Elf_Rela_Iter beginELFRela(const Elf_Shdr *sec) const {
+ return Elf_Rela_Iter(sec, (const char *)(base() + sec->sh_offset));
+ };
+
+ virtual Elf_Rela_Iter endELFRela(const Elf_Shdr *sec) const {
+ return Elf_Rela_Iter(sec, (const char *)
+ (base() + sec->sh_offset + sec->sh_size));
+ };
+
+ virtual Elf_Rel_Iter beginELFRel(const Elf_Shdr *sec) const {
+ return Elf_Rel_Iter(sec, (const char *)(base() + sec->sh_offset));
+ };
+
+ virtual Elf_Rel_Iter endELFRel(const Elf_Shdr *sec) const {
+ return Elf_Rel_Iter(sec, (const char *)
+ (base() + sec->sh_offset + sec->sh_size));
+ };
+
virtual uint8_t getBytesInAddress() const;
virtual StringRef getFileFormatName() const;
virtual StringRef getObjectType() const { return "ELF"; }
@@ -611,6 +685,7 @@ public:
const Elf_Shdr *getSection(const Elf_Sym *symb) const;
const Elf_Shdr *getElfSection(section_iterator &It) const;
const Elf_Sym *getElfSymbol(symbol_iterator &It) const;
+ const Elf_Sym *getElfSymbol(uint32_t index) const;
// Methods for type inquiry through isa, cast, and dyn_cast
bool isDyldType() const { return isDyldELFObject; }
@@ -807,6 +882,16 @@ ELFObjectFile<target_endianness, is64Bits>
}
template<support::endianness target_endianness, bool is64Bits>
+const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Sym *
+ELFObjectFile<target_endianness, is64Bits>
+ ::getElfSymbol(uint32_t index) const {
+ DataRefImpl SymbolData;
+ SymbolData.d.a = index;
+ SymbolData.d.b = 1;
+ return getSymbol(SymbolData);
+}
+
+template<support::endianness target_endianness, bool is64Bits>
error_code ELFObjectFile<target_endianness, is64Bits>
::getSymbolFileOffset(DataRefImpl Symb,
uint64_t &Result) const {