[lld] r248319 - Move relocation processing to Target.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 22 13:54:08 PDT 2015


Author: rafael
Date: Tue Sep 22 15:54:08 2015
New Revision: 248319

URL: http://llvm.org/viewvc/llvm-project?rev=248319&view=rev
Log:
Move relocation processing to Target.

I will add a couple of ppc64 relocs in the next patches.

Modified:
    lld/trunk/ELF/InputSection.cpp
    lld/trunk/ELF/InputSection.h
    lld/trunk/ELF/SymbolTable.cpp
    lld/trunk/ELF/Target.cpp
    lld/trunk/ELF/Target.h

Modified: lld/trunk/ELF/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=248319&r1=248318&r2=248319&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Tue Sep 22 15:54:08 2015
@@ -13,8 +13,6 @@
 #include "OutputSections.h"
 #include "Target.h"
 
-#include "llvm/Support/raw_ostream.h"
-
 using namespace llvm;
 using namespace llvm::ELF;
 using namespace llvm::object;
@@ -27,57 +25,6 @@ InputSection<ELFT>::InputSection(ObjectF
     : File(F), Header(Header) {}
 
 template <class ELFT>
-void InputSection<ELFT>::relocateOne(uint8_t *Buf, const Elf_Rel &Rel,
-                                     uint32_t Type, uintX_t BaseAddr,
-                                     uintX_t SymVA) {
-  uintX_t Offset = Rel.r_offset;
-  uint8_t *Location = Buf + Offset;
-  uint32_t Addend = *(support::ulittle32_t *)Location;
-  switch (Type) {
-  case R_386_PC32:
-    support::endian::write32le(Location, SymVA + Addend - (BaseAddr + Offset));
-    break;
-  case R_386_32:
-    support::endian::write32le(Location, SymVA + Addend);
-    break;
-  default:
-    llvm::errs() << Twine("unrecognized reloc ") + Twine(Type) << '\n';
-    break;
-  }
-}
-
-template <class ELFT>
-void InputSection<ELFT>::relocateOne(uint8_t *Buf, const Elf_Rela &Rel,
-                                     uint32_t Type, uintX_t BaseAddr,
-                                     uintX_t SymVA) {
-  uintX_t Offset = Rel.r_offset;
-  uint8_t *Location = Buf + Offset;
-  switch (Type) {
-  case R_X86_64_PC32:
-    support::endian::write32le(Location,
-                               SymVA + Rel.r_addend - (BaseAddr + Offset));
-    break;
-  case R_X86_64_64:
-    support::endian::write64le(Location, SymVA + Rel.r_addend);
-    break;
-  case R_X86_64_32: {
-  case R_X86_64_32S:
-    uint64_t VA = SymVA + Rel.r_addend;
-    if (Type == R_X86_64_32 && !isUInt<32>(VA))
-      error("R_X86_64_32 out of range");
-    else if (!isInt<32>(VA))
-      error("R_X86_64_32S out of range");
-
-    support::endian::write32le(Location, VA);
-    break;
-  }
-  default:
-    llvm::errs() << Twine("unrecognized reloc ") + Twine(Type) << '\n';
-    break;
-  }
-}
-
-template <class ELFT>
 template <bool isRela>
 void InputSection<ELFT>::relocate(
     uint8_t *Buf, iterator_range<const Elf_Rel_Impl<ELFT, isRela> *> Rels,
@@ -134,7 +81,8 @@ void InputSection<ELFT>::relocate(
       }
     }
 
-    relocateOne(Buf, RI, Type, BaseAddr, SymVA);
+    Target->relocateOne(Buf, reinterpret_cast<const void *>(&RI), Type,
+                        BaseAddr, SymVA);
   }
 }
 

Modified: lld/trunk/ELF/InputSection.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.h?rev=248319&r1=248318&r2=248319&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.h (original)
+++ lld/trunk/ELF/InputSection.h Tue Sep 22 15:54:08 2015
@@ -60,11 +60,6 @@ public:
   SmallVector<const Elf_Shdr *, 1> RelocSections;
 
 private:
-  void relocateOne(uint8_t *Buf, const Elf_Rela &Rel, uint32_t Type,
-                   uintX_t BaseAddr, uintX_t SymVA);
-  void relocateOne(uint8_t *Buf, const Elf_Rel &Rel, uint32_t Type,
-                   uintX_t BaseAddr, uintX_t SymVA);
-
   template <bool isRela>
   void relocate(uint8_t *Buf,
                 llvm::iterator_range<

Modified: lld/trunk/ELF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=248319&r1=248318&r2=248319&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.cpp (original)
+++ lld/trunk/ELF/SymbolTable.cpp Tue Sep 22 15:54:08 2015
@@ -40,7 +40,9 @@ void SymbolTable::addFile(std::unique_pt
 }
 
 template <class ELFT> void SymbolTable::init(uint16_t EMachine) {
-  if (EMachine == EM_X86_64)
+  if (EMachine == EM_PPC64)
+    Target.reset(new PPC64TargetInfo());
+  else if (EMachine == EM_X86_64)
     Target.reset(new X86_64TargetInfo());
   else
     Target.reset(new X86TargetInfo());

Modified: lld/trunk/ELF/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.cpp?rev=248319&r1=248318&r2=248319&view=diff
==============================================================================
--- lld/trunk/ELF/Target.cpp (original)
+++ lld/trunk/ELF/Target.cpp Tue Sep 22 15:54:08 2015
@@ -8,12 +8,15 @@
 //===----------------------------------------------------------------------===//
 
 #include "Target.h"
+#include "Error.h"
 
 #include "llvm/ADT/ArrayRef.h"
+#include "llvm/Object/ELF.h"
 #include "llvm/Support/Endian.h"
 #include "llvm/Support/ELF.h"
 
 using namespace llvm;
+using namespace llvm::object;
 using namespace llvm::ELF;
 
 namespace lld {
@@ -59,6 +62,27 @@ bool X86TargetInfo::relocNeedsPlt(uint32
   }
 }
 
+void X86TargetInfo::relocateOne(uint8_t *Buf, const void *RelP, uint32_t Type,
+                                uint64_t BaseAddr, uint64_t SymVA) const {
+  typedef ELFFile<ELF32LE>::Elf_Rel Elf_Rel;
+  auto &Rel = *reinterpret_cast<const Elf_Rel *>(RelP);
+
+  uint32_t Offset = Rel.r_offset;
+  uint8_t *Location = Buf + Offset;
+  uint32_t Addend = *(support::ulittle32_t *)Location;
+  switch (Type) {
+  case R_386_PC32:
+    support::endian::write32le(Location, SymVA + Addend - (BaseAddr + Offset));
+    break;
+  case R_386_32:
+    support::endian::write32le(Location, SymVA + Addend);
+    break;
+  default:
+    error(Twine("unrecognized reloc ") + Twine(Type));
+    break;
+  }
+}
+
 X86_64TargetInfo::X86_64TargetInfo() { PCRelReloc = R_X86_64_PC32; }
 
 void X86_64TargetInfo::writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr,
@@ -96,5 +120,48 @@ bool X86_64TargetInfo::relocNeedsPlt(uin
     return true;
   }
 }
+
+void X86_64TargetInfo::relocateOne(uint8_t *Buf, const void *RelP,
+                                   uint32_t Type, uint64_t BaseAddr,
+                                   uint64_t SymVA) const {
+  typedef ELFFile<ELF64LE>::Elf_Rela Elf_Rela;
+  auto &Rel = *reinterpret_cast<const Elf_Rela *>(RelP);
+
+  uint64_t Offset = Rel.r_offset;
+  uint8_t *Location = Buf + Offset;
+  switch (Type) {
+  case R_X86_64_PC32:
+    support::endian::write32le(Location,
+                               SymVA + Rel.r_addend - (BaseAddr + Offset));
+    break;
+  case R_X86_64_64:
+    support::endian::write64le(Location, SymVA + Rel.r_addend);
+    break;
+  case R_X86_64_32: {
+  case R_X86_64_32S:
+    uint64_t VA = SymVA + Rel.r_addend;
+    if (Type == R_X86_64_32 && !isUInt<32>(VA))
+      error("R_X86_64_32 out of range");
+    else if (!isInt<32>(VA))
+      error("R_X86_64_32S out of range");
+
+    support::endian::write32le(Location, VA);
+    break;
+  }
+  default:
+    error(Twine("unrecognized reloc ") + Twine(Type));
+    break;
+  }
+}
+
+PPC64TargetInfo::PPC64TargetInfo() {
+  // PCRelReloc = FIXME
+}
+void PPC64TargetInfo::writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr,
+                                    uint64_t PltEntryAddr) const {}
+bool PPC64TargetInfo::relocNeedsGot(uint32_t Type) const { return false; }
+bool PPC64TargetInfo::relocNeedsPlt(uint32_t Type) const { return false; }
+void PPC64TargetInfo::relocateOne(uint8_t *Buf, const void *RelP, uint32_t Type,
+                                  uint64_t BaseAddr, uint64_t SymVA) const {}
 }
 }

Modified: lld/trunk/ELF/Target.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.h?rev=248319&r1=248318&r2=248319&view=diff
==============================================================================
--- lld/trunk/ELF/Target.h (original)
+++ lld/trunk/ELF/Target.h Tue Sep 22 15:54:08 2015
@@ -23,6 +23,9 @@ public:
                              uint64_t PltEntryAddr) const = 0;
   virtual bool relocNeedsGot(uint32_t Type) const = 0;
   virtual bool relocNeedsPlt(uint32_t Type) const = 0;
+  virtual void relocateOne(uint8_t *Buf, const void *RelP, uint32_t Type,
+                           uint64_t BaseAddr, uint64_t SymVA) const = 0;
+
   virtual ~TargetInfo();
 
 protected:
@@ -36,6 +39,8 @@ public:
                      uint64_t PltEntryAddr) const override;
   bool relocNeedsGot(uint32_t Type) const override;
   bool relocNeedsPlt(uint32_t Type) const override;
+  void relocateOne(uint8_t *Buf, const void *RelP, uint32_t Type,
+                   uint64_t BaseAddr, uint64_t SymVA) const override;
 };
 
 class X86_64TargetInfo final : public TargetInfo {
@@ -45,6 +50,19 @@ public:
                      uint64_t PltEntryAddr) const override;
   bool relocNeedsGot(uint32_t Type) const override;
   bool relocNeedsPlt(uint32_t Type) const override;
+  void relocateOne(uint8_t *Buf, const void *RelP, uint32_t Type,
+                   uint64_t BaseAddr, uint64_t SymVA) const override;
+};
+
+class PPC64TargetInfo final : public TargetInfo {
+public:
+  PPC64TargetInfo();
+  void writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr,
+                     uint64_t PltEntryAddr) const override;
+  bool relocNeedsGot(uint32_t Type) const override;
+  bool relocNeedsPlt(uint32_t Type) const override;
+  void relocateOne(uint8_t *Buf, const void *RelP, uint32_t Type,
+                   uint64_t BaseAddr, uint64_t SymVA) const override;
 };
 
 extern std::unique_ptr<TargetInfo> Target;




More information about the llvm-commits mailing list