[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