[lld] r264863 - Fix handling of addends on i386.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 30 05:40:38 PDT 2016


Author: rafael
Date: Wed Mar 30 07:40:38 2016
New Revision: 264863

URL: http://llvm.org/viewvc/llvm-project?rev=264863&view=rev
Log:
Fix handling of addends on i386.

Because of merge sections it is not sufficient to just add them while
applying a relocation.

Added:
    lld/trunk/test/ELF/i386-merge.s
Modified:
    lld/trunk/ELF/InputSection.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=264863&r1=264862&r2=264863&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Wed Mar 30 07:40:38 2016
@@ -274,6 +274,8 @@ void InputSectionBase<ELFT>::relocate(ui
       continue;
     }
 
+    if (!RelTy::IsRela)
+      A += Target->getImplicitAddend(BufLoc, Type);
     uintX_t SymVA = Body.getVA<ELFT>(A);
     if (Config->EMachine == EM_MIPS)
       A += findMipsPairedAddend(Buf, BufLoc, Body, &RI, Rels.end());

Modified: lld/trunk/ELF/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.cpp?rev=264863&r1=264862&r2=264863&view=diff
==============================================================================
--- lld/trunk/ELF/Target.cpp (original)
+++ lld/trunk/ELF/Target.cpp Wed Mar 30 07:40:38 2016
@@ -39,7 +39,6 @@ template <endianness E> static void add3
   write32<E>(P, read32<E>(P) + V);
 }
 
-static void add32le(uint8_t *P, int32_t V) { add32<support::little>(P, V); }
 static void or32le(uint8_t *P, int32_t V) { write32le(P, read32le(P) | V); }
 
 template <unsigned N> static void checkInt(int64_t V, uint32_t Type) {
@@ -74,6 +73,7 @@ namespace {
 class X86TargetInfo final : public TargetInfo {
 public:
   X86TargetInfo();
+  uint64_t getImplicitAddend(uint8_t *Buf, uint32_t Type) const override;
   void writeGotPltHeader(uint8_t *Buf) const override;
   uint32_t getDynRel(uint32_t Type) const override;
   uint32_t getTlsGotRel(uint32_t Type) const override;
@@ -241,6 +241,10 @@ TargetInfo *createTarget() {
 
 TargetInfo::~TargetInfo() {}
 
+uint64_t TargetInfo::getImplicitAddend(uint8_t *Buf, uint32_t Type) const {
+  return 0;
+}
+
 bool TargetInfo::canRelaxTls(uint32_t Type, const SymbolBody *S) const {
   if (Config->Shared || (S && !S->IsTls))
     return false;
@@ -509,28 +513,42 @@ bool X86TargetInfo::refersToGotEntry(uin
   return Type == R_386_GOT32;
 }
 
+uint64_t X86TargetInfo::getImplicitAddend(uint8_t *Buf, uint32_t Type) const {
+  switch (Type) {
+  default:
+    return 0;
+  case R_386_32:
+  case R_386_GOT32:
+  case R_386_GOTOFF:
+  case R_386_GOTPC:
+  case R_386_PC32:
+  case R_386_PLT32:
+    return read32le(Buf);
+  }
+}
+
 void X86TargetInfo::relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type,
                                 uint64_t P, uint64_t SA, uint64_t ZA) const {
   switch (Type) {
   case R_386_32:
-    add32le(Loc, SA);
+    write32le(Loc, SA);
     break;
   case R_386_GOT32: {
     uint64_t V = SA - Out<ELF32LE>::Got->getVA() -
                  Out<ELF32LE>::Got->getNumEntries() * 4;
     checkInt<32>(V, Type);
-    add32le(Loc, V);
+    write32le(Loc, V);
     break;
   }
   case R_386_GOTOFF:
-    add32le(Loc, SA - Out<ELF32LE>::Got->getVA());
+    write32le(Loc, SA - Out<ELF32LE>::Got->getVA());
     break;
   case R_386_GOTPC:
-    add32le(Loc, SA + Out<ELF32LE>::Got->getVA() - P);
+    write32le(Loc, SA + Out<ELF32LE>::Got->getVA() - P);
     break;
   case R_386_PC32:
   case R_386_PLT32:
-    add32le(Loc, SA - P);
+    write32le(Loc, SA - P);
     break;
   case R_386_TLS_GD:
   case R_386_TLS_LDM:

Modified: lld/trunk/ELF/Target.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.h?rev=264863&r1=264862&r2=264863&view=diff
==============================================================================
--- lld/trunk/ELF/Target.h (original)
+++ lld/trunk/ELF/Target.h Wed Mar 30 07:40:38 2016
@@ -31,6 +31,7 @@ public:
   virtual void writeGotHeader(uint8_t *Buf) const {}
   virtual void writeGotPltHeader(uint8_t *Buf) const {}
   virtual void writeGotPlt(uint8_t *Buf, uint64_t Plt) const {};
+  virtual uint64_t getImplicitAddend(uint8_t *Buf, uint32_t Type) const;
 
   // If lazy binding is supported, the first entry of the PLT has code
   // to call the dynamic linker to resolve PLT entries the first time

Added: lld/trunk/test/ELF/i386-merge.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/i386-merge.s?rev=264863&view=auto
==============================================================================
--- lld/trunk/test/ELF/i386-merge.s (added)
+++ lld/trunk/test/ELF/i386-merge.s Wed Mar 30 07:40:38 2016
@@ -0,0 +1,49 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %s -o %t.o
+// RUN: ld.lld %t.o -o %t -shared
+// RUN: llvm-readobj -s -section-data %t | FileCheck %s
+
+// CHECK:      Name: .mysec
+// CHECK-NEXT: Type:
+// CHECK-NEXT: Flags [
+// CHECK-NEXT:   SHF_ALLOC
+// CHECK-NEXT:   SHF_MERGE
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address: 0x114
+// CHECK-NEXT: Offset:
+// CHECK-NEXT: Size:
+// CHECK-NEXT: Link:
+// CHECK-NEXT: Info:
+// CHECK-NEXT: AddressAlignment:
+// CHECK-NEXT: EntrySize:
+// CHECK-NEXT: SectionData (
+// CHECK-NEXT:   0000: 42000000 |
+// CHECK-NEXT: )
+
+
+// CHECK:      Name: .text
+// CHECK-NEXT: Type: SHT_PROGBITS
+// CHECK-NEXT: Flags [
+// CHECK-NEXT:   SHF_ALLOC
+// CHECK-NEXT:   SHF_EXECINSTR
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address: 0x1000
+// CHECK-NEXT: Offset: 0x1000
+// CHECK-NEXT: Size: 4
+// CHECK-NEXT: Link: 0
+// CHECK-NEXT: Info: 0
+// CHECK-NEXT: AddressAlignment: 4
+// CHECK-NEXT: EntrySize: 0
+// CHECK-NEXT: SectionData (
+// CHECK-NEXT:   0000: 14010000 |
+// CHECK-NEXT: )
+
+// The content of .text should be the address of .mysec. 14010000 is 0x114 in
+// little endian.
+
+        .long .mysec+4
+
+        .section        .mysec,"aM", at progbits,4
+        .align  4
+        .long   0x42
+        .long   0x42




More information about the llvm-commits mailing list