summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/Object/ELFObjectFile.h46
-rw-r--r--llvm/include/llvm/Object/RelocVisitor.h4
-rw-r--r--llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp12
-rw-r--r--llvm/lib/Target/X86/MCTargetDesc/X86ELFRelocationInfo.cpp3
4 files changed, 42 insertions, 23 deletions
diff --git a/llvm/include/llvm/Object/ELFObjectFile.h b/llvm/include/llvm/Object/ELFObjectFile.h
index 39c504848e7..b21a1a1c99c 100644
--- a/llvm/include/llvm/Object/ELFObjectFile.h
+++ b/llvm/include/llvm/Object/ELFObjectFile.h
@@ -37,10 +37,12 @@ namespace object {
class elf_symbol_iterator;
class ELFSymbolRef;
+class ELFRelocationRef;
class ELFObjectFileBase : public ObjectFile {
friend class ELFSymbolRef;
friend class ELFSectionRef;
+ friend class ELFRelocationRef;
protected:
ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source);
@@ -52,12 +54,8 @@ protected:
virtual uint32_t getSectionType(DataRefImpl Sec) const = 0;
virtual uint64_t getSectionFlags(DataRefImpl Sec) const = 0;
-public:
virtual ErrorOr<int64_t> getRelocationAddend(DataRefImpl Rel) const = 0;
-
- // FIXME: This is a bit of a hack. Every caller should know if it expecting
- // and addend or not.
- virtual bool hasRelocationAddend(DataRefImpl Rel) const = 0;
+public:
typedef iterator_range<elf_symbol_iterator> elf_symbol_iterator_range;
virtual elf_symbol_iterator_range getDynamicSymbolIterators() const = 0;
@@ -139,6 +137,38 @@ public:
}
};
+class ELFRelocationRef : public RelocationRef {
+public:
+ ELFRelocationRef(const RelocationRef &B) : RelocationRef(B) {
+ assert(isa<ELFObjectFileBase>(RelocationRef::getObject()));
+ }
+
+ const ELFObjectFileBase *getObject() const {
+ return cast<ELFObjectFileBase>(RelocationRef::getObject());
+ }
+
+ ErrorOr<int64_t> getAddend() const {
+ return getObject()->getRelocationAddend(getRawDataRefImpl());
+ }
+};
+
+class elf_relocation_iterator : public relocation_iterator {
+public:
+ elf_relocation_iterator(const relocation_iterator &B)
+ : relocation_iterator(RelocationRef(
+ B->getRawDataRefImpl(), cast<ELFObjectFileBase>(B->getObject()))) {}
+
+ const ELFRelocationRef *operator->() const {
+ return static_cast<const ELFRelocationRef *>(
+ relocation_iterator::operator->());
+ }
+
+ const ELFRelocationRef &operator*() const {
+ return static_cast<const ELFRelocationRef &>(
+ relocation_iterator::operator*());
+ }
+};
+
inline ELFObjectFileBase::elf_symbol_iterator_range
ELFObjectFileBase::symbols() const {
return elf_symbol_iterator_range(symbol_begin(), symbol_end());
@@ -295,7 +325,6 @@ public:
section_iterator section_end() const override;
ErrorOr<int64_t> getRelocationAddend(DataRefImpl Rel) const override;
- bool hasRelocationAddend(DataRefImpl Rel) const override;
uint8_t getBytesInAddress() const override;
StringRef getFileFormatName() const override;
@@ -734,11 +763,6 @@ ELFObjectFile<ELFT>::getRelocationAddend(DataRefImpl Rel) const {
}
template <class ELFT>
-bool ELFObjectFile<ELFT>::hasRelocationAddend(DataRefImpl Rel) const {
- return getRelSection(Rel)->sh_type == ELF::SHT_RELA;
-}
-
-template <class ELFT>
const typename ELFFile<ELFT>::Elf_Sym *
ELFObjectFile<ELFT>::getSymbol(DataRefImpl Symb) const {
return &*toELFSymIter(Symb);
diff --git a/llvm/include/llvm/Object/RelocVisitor.h b/llvm/include/llvm/Object/RelocVisitor.h
index 4dca6a29593..950e2ed0e33 100644
--- a/llvm/include/llvm/Object/RelocVisitor.h
+++ b/llvm/include/llvm/Object/RelocVisitor.h
@@ -240,9 +240,7 @@ private:
}
int64_t getELFAddend(RelocationRef R) {
- const auto *Obj = cast<ELFObjectFileBase>(R.getObject());
- DataRefImpl DRI = R.getRawDataRefImpl();
- ErrorOr<int64_t> AddendOrErr = Obj->getRelocationAddend(DRI);
+ ErrorOr<int64_t> AddendOrErr = ELFRelocationRef(R).getAddend();
if (std::error_code EC = AddendOrErr.getError())
report_fatal_error(EC.message());
return *AddendOrErr;
diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
index b303e300470..6311c6ec5e4 100644
--- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
+++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
@@ -767,8 +767,8 @@ void RuntimeDyldELF::findOPDEntrySection(const ELFObjectFileBase &Obj,
if (RelSectionName != ".opd")
continue;
- for (relocation_iterator i = si->relocation_begin(),
- e = si->relocation_end();
+ for (elf_relocation_iterator i = si->relocation_begin(),
+ e = si->relocation_end();
i != e;) {
// The R_PPC64_ADDR64 relocation indicates the first field
// of a .opd entry
@@ -781,8 +781,7 @@ void RuntimeDyldELF::findOPDEntrySection(const ELFObjectFileBase &Obj,
uint64_t TargetSymbolOffset = i->getOffset();
symbol_iterator TargetSymbol = i->getSymbol();
- ErrorOr<int64_t> AddendOrErr =
- Obj.getRelocationAddend(i->getRawDataRefImpl());
+ ErrorOr<int64_t> AddendOrErr = i->getAddend();
Check(AddendOrErr.getError());
int64_t Addend = *AddendOrErr;
@@ -1062,9 +1061,8 @@ relocation_iterator RuntimeDyldELF::processRelocationRef(
const auto &Obj = cast<ELFObjectFileBase>(O);
uint64_t RelType;
Check(RelI->getType(RelType));
- int64_t Addend = 0;
- if (Obj.hasRelocationAddend(RelI->getRawDataRefImpl()))
- Addend = *Obj.getRelocationAddend(RelI->getRawDataRefImpl());
+ ErrorOr<int64_t> AddendOrErr = ELFRelocationRef(*RelI).getAddend();
+ int64_t Addend = AddendOrErr ? *AddendOrErr : 0;
elf_symbol_iterator Symbol = RelI->getSymbol();
// Obtain the symbol name which is referenced in the relocation
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86ELFRelocationInfo.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86ELFRelocationInfo.cpp
index 8d2ae67dd7b..85783844358 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86ELFRelocationInfo.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86ELFRelocationInfo.cpp
@@ -31,9 +31,8 @@ public:
StringRef SymName; SymI->getName(SymName);
uint64_t SymAddr; SymI->getAddress(SymAddr);
- auto *Obj = cast<ELFObjectFileBase>(Rel.getObject());
uint64_t SymSize = SymI->getSize();
- int64_t Addend = *Obj->getRelocationAddend(Rel.getRawDataRefImpl());
+ int64_t Addend = *ELFRelocationRef(Rel).getAddend();
MCSymbol *Sym = Ctx.getOrCreateSymbol(SymName);
// FIXME: check that the value is actually the same.
OpenPOWER on IntegriCloud