[lld] r248799 - Add support for R_386_GOT32.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 29 07:42:38 PDT 2015


Author: rafael
Date: Tue Sep 29 09:42:37 2015
New Revision: 248799

URL: http://llvm.org/viewvc/llvm-project?rev=248799&view=rev
Log:
Add support for R_386_GOT32.

Modified:
    lld/trunk/ELF/InputSection.cpp
    lld/trunk/ELF/Target.cpp
    lld/trunk/ELF/Target.h
    lld/trunk/test/elf2/relocation-i686.s

Modified: lld/trunk/ELF/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=248799&r1=248798&r2=248799&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Tue Sep 29 09:42:37 2015
@@ -37,6 +37,7 @@ void InputSection<ELFT>::relocate(
   for (const RelType &RI : Rels) {
     uint32_t SymIndex = RI.getSymbol(IsMips64EL);
     uint32_t Type = RI.getType(IsMips64EL);
+    uintX_t GotVA = GotSec.getVA();
     uintX_t SymVA;
 
     // Handle relocations for local symbols -- they never get
@@ -56,9 +57,9 @@ void InputSection<ELFT>::relocate(
         Type = Target->getPCRelReloc();
       } else if (Target->relocNeedsGot(Type)) {
         SymVA = GotSec.getEntryAddr(Body);
-        Type = Target->getPCRelReloc();
+        Type = Target->getGotRefReloc();
       } else if (Target->relocPointsToGot(Type)) {
-        SymVA = GotSec.getVA();
+        SymVA = GotVA;
         Type = Target->getPCRelReloc();
       } else if (isa<SharedSymbol<ELFT>>(Body)) {
         continue;
@@ -66,7 +67,7 @@ void InputSection<ELFT>::relocate(
     }
 
     Target->relocateOne(Buf, reinterpret_cast<const void *>(&RI), Type,
-                        BaseAddr, SymVA);
+                        BaseAddr, SymVA, GotVA);
   }
 }
 

Modified: lld/trunk/ELF/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.cpp?rev=248799&r1=248798&r2=248799&view=diff
==============================================================================
--- lld/trunk/ELF/Target.cpp (original)
+++ lld/trunk/ELF/Target.cpp Tue Sep 29 09:42:37 2015
@@ -32,6 +32,7 @@ bool TargetInfo::relocPointsToGot(uint32
 X86TargetInfo::X86TargetInfo() {
   PCRelReloc = R_386_PC32;
   GotReloc = R_386_GLOB_DAT;
+  GotRefReloc = R_386_GOT32;
 }
 
 void X86TargetInfo::writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr,
@@ -75,13 +76,17 @@ bool X86TargetInfo::relocNeedsPlt(uint32
 static void add32le(uint8_t *P, int32_t V) { write32le(P, read32le(P) + V); }
 
 void X86TargetInfo::relocateOne(uint8_t *Buf, const void *RelP, uint32_t Type,
-                                uint64_t BaseAddr, uint64_t SymVA) const {
+                                uint64_t BaseAddr, uint64_t SymVA,
+                                uint64_t GotVA) 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;
   switch (Type) {
+  case R_386_GOT32:
+    add32le(Location, SymVA - GotVA);
+    break;
   case R_386_PC32:
     add32le(Location, SymVA - (BaseAddr + Offset));
     break;
@@ -97,6 +102,7 @@ void X86TargetInfo::relocateOne(uint8_t
 X86_64TargetInfo::X86_64TargetInfo() {
   PCRelReloc = R_X86_64_PC32;
   GotReloc = R_X86_64_GLOB_DAT;
+  GotRefReloc = R_X86_64_PC32;
 }
 
 void X86_64TargetInfo::writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr,
@@ -137,7 +143,7 @@ bool X86_64TargetInfo::relocNeedsPlt(uin
 
 void X86_64TargetInfo::relocateOne(uint8_t *Buf, const void *RelP,
                                    uint32_t Type, uint64_t BaseAddr,
-                                   uint64_t SymVA) const {
+                                   uint64_t SymVA, uint64_t GotVA) const {
   typedef ELFFile<ELF64LE>::Elf_Rela Elf_Rela;
   auto &Rel = *reinterpret_cast<const Elf_Rela *>(RelP);
 
@@ -177,7 +183,8 @@ void PPC64TargetInfo::writePltEntry(uint
 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 {
+                                  uint64_t BaseAddr, uint64_t SymVA,
+                                  uint64_t GotVA) const {
   typedef ELFFile<ELF64BE>::Elf_Rela Elf_Rela;
   auto &Rel = *reinterpret_cast<const Elf_Rela *>(RelP);
 
@@ -205,7 +212,8 @@ void PPCTargetInfo::writePltEntry(uint8_
 bool PPCTargetInfo::relocNeedsGot(uint32_t Type) const { return false; }
 bool PPCTargetInfo::relocNeedsPlt(uint32_t Type) const { return false; }
 void PPCTargetInfo::relocateOne(uint8_t *Buf, const void *RelP, uint32_t Type,
-                                uint64_t BaseAddr, uint64_t SymVA) const {}
+                                uint64_t BaseAddr, uint64_t SymVA,
+                                uint64_t GotVA) const {}
 
 ARMTargetInfo::ARMTargetInfo() {
   // PCRelReloc = FIXME
@@ -216,7 +224,8 @@ void ARMTargetInfo::writePltEntry(uint8_
 bool ARMTargetInfo::relocNeedsGot(uint32_t Type) const { return false; }
 bool ARMTargetInfo::relocNeedsPlt(uint32_t Type) const { return false; }
 void ARMTargetInfo::relocateOne(uint8_t *Buf, const void *RelP, uint32_t Type,
-                                uint64_t BaseAddr, uint64_t SymVA) const {}
+                                uint64_t BaseAddr, uint64_t SymVA,
+                                uint64_t GotVA) const {}
 
 AArch64TargetInfo::AArch64TargetInfo() {
   // PCRelReloc = FIXME
@@ -241,7 +250,7 @@ static void handle_ADR_PREL_LO21(uint8_t
 
 void AArch64TargetInfo::relocateOne(uint8_t *Buf, const void *RelP,
                                     uint32_t Type, uint64_t BaseAddr,
-                                    uint64_t SymVA) const {
+                                    uint64_t SymVA, uint64_t GotVA) const {
   typedef ELFFile<ELF64LE>::Elf_Rela Elf_Rela;
   auto &Rel = *reinterpret_cast<const Elf_Rela *>(RelP);
 
@@ -273,6 +282,7 @@ bool MipsTargetInfo::relocNeedsGot(uint3
 bool MipsTargetInfo::relocNeedsPlt(uint32_t Type) const { return false; }
 
 void MipsTargetInfo::relocateOne(uint8_t *Buf, const void *RelP, uint32_t Type,
-                                 uint64_t BaseAddr, uint64_t SymVA) const {}
+                                 uint64_t BaseAddr, uint64_t SymVA,
+                                 uint64_t GotVA) const {}
 }
 }

Modified: lld/trunk/ELF/Target.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.h?rev=248799&r1=248798&r2=248799&view=diff
==============================================================================
--- lld/trunk/ELF/Target.h (original)
+++ lld/trunk/ELF/Target.h Tue Sep 29 09:42:37 2015
@@ -23,18 +23,21 @@ public:
   llvm::StringRef getDefaultEntry() const { return DefaultEntry; }
   unsigned getPCRelReloc() const { return PCRelReloc; }
   unsigned getGotReloc() const { return GotReloc; }
+  unsigned getGotRefReloc() const { return GotRefReloc; };
   virtual void writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr,
                              uint64_t PltEntryAddr) const = 0;
   virtual bool relocNeedsGot(uint32_t Type) const = 0;
   virtual bool relocPointsToGot(uint32_t Type) const;
   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;
+                           uint64_t BaseAddr, uint64_t SymVA,
+                           uint64_t GotVA) const = 0;
 
   virtual ~TargetInfo();
 
 protected:
   unsigned PCRelReloc;
+  unsigned GotRefReloc;
   unsigned GotReloc;
   llvm::StringRef DefaultEntry = "_start";
 };
@@ -48,7 +51,8 @@ public:
   bool relocPointsToGot(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;
+                   uint64_t BaseAddr, uint64_t SymVA,
+                   uint64_t GotVA) const override;
 };
 
 class X86_64TargetInfo final : public TargetInfo {
@@ -59,7 +63,8 @@ public:
   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;
+                   uint64_t BaseAddr, uint64_t SymVA,
+                   uint64_t GotVA) const override;
 };
 
 class PPC64TargetInfo final : public TargetInfo {
@@ -70,7 +75,8 @@ public:
   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;
+                   uint64_t BaseAddr, uint64_t SymVA,
+                   uint64_t GotVA) const override;
 };
 
 class PPCTargetInfo final : public TargetInfo {
@@ -81,7 +87,8 @@ public:
   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;
+                   uint64_t BaseAddr, uint64_t SymVA,
+                   uint64_t GotVA) const override;
 };
 
 class ARMTargetInfo final : public TargetInfo {
@@ -92,7 +99,8 @@ public:
   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;
+                   uint64_t BaseAddr, uint64_t SymVA,
+                   uint64_t GotVA) const override;
 };
 
 class AArch64TargetInfo final : public TargetInfo {
@@ -103,7 +111,8 @@ public:
   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;
+                   uint64_t BaseAddr, uint64_t SymVA,
+                   uint64_t GotVA) const override;
 };
 
 class MipsTargetInfo final : public TargetInfo {
@@ -114,7 +123,8 @@ public:
   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;
+                   uint64_t BaseAddr, uint64_t SymVA,
+                   uint64_t GotVA) const override;
 };
 
 extern std::unique_ptr<TargetInfo> Target;

Modified: lld/trunk/test/elf2/relocation-i686.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/relocation-i686.s?rev=248799&r1=248798&r2=248799&view=diff
==============================================================================
--- lld/trunk/test/elf2/relocation-i686.s (original)
+++ lld/trunk/test/elf2/relocation-i686.s Tue Sep 29 09:42:37 2015
@@ -40,7 +40,7 @@ R_386_PC32_2:
 movl bar at GOT, %eax
 
 
-// ADDR:      Name: .got (14)
+// ADDR:      Name: .got
 // ADDR-NEXT: Type: SHT_PROGBITS
 // ADDR-NEXT: Flags [
 // ADDR-NEXT:   SHF_ALLOC
@@ -63,3 +63,12 @@ R_386_GOTPC:
 // CHECK:      Disassembly of section .dynamic_reloc:
 // CHECK-NEXT: .dynamic_reloc:
 // CHECK-NEXT:   11019:  e8 00 00 00 00  calll  0
+
+.section .R_386_GOT32,"ax", at progbits
+.global R_386_GOT32
+R_386_GOT32:
+        movl R_386_GOT32 at GOT, %eax
+// This is the second symbol in the got, so the offset is 4.
+// CHECK:      Disassembly of section .R_386_GOT32:
+// CHECK-NEXT: R_386_GOT32:
+// CHECK-NEXT:   1101e:  {{.*}} movl 4, %eax




More information about the llvm-commits mailing list