Cleanup getRelocationAddend.
authorRafael Espindola <rafael.espindola@gmail.com>
Tue, 30 Jun 2015 00:33:59 +0000 (00:33 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Tue, 30 Jun 2015 00:33:59 +0000 (00:33 +0000)
Realistically, this will be returning ErrorOr for some time as refactoring the
user code to check once per section will take some time.

Given that, use it for checking if a relocation has addend or not.

While at it, add ELFRelocationRef to simplify the users.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@241028 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Object/ELFObjectFile.h
include/llvm/Object/RelocVisitor.h
lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
lib/Target/X86/MCTargetDesc/X86ELFRelocationInfo.cpp

index 39c504848e770fd7b8f93efed2503353173b9eff..b21a1a1c99c73f7baa912c7166198685a41147d6 100644 (file)
@@ -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;
@@ -733,11 +762,6 @@ ELFObjectFile<ELFT>::getRelocationAddend(DataRefImpl Rel) const {
   return (int64_t)getRela(Rel)->r_addend;
 }
 
-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 {
index 4dca6a2959353e807319734ece7826769d8ffef0..950e2ed0e3389010e25aefc05b3784a6af507490 100644 (file)
@@ -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;
index b303e30047032109b90539cb3e30ecb09633f1c1..6311c6ec5e433f73e4d25c2296ded2f9561dad54 100644 (file)
@@ -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
index 8d2ae67dd7bd54baa4556c61b7b563da2afebb13..857838443583e869f42103e1a16cc121a1021043 100644 (file)
@@ -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.