diff options
-rw-r--r-- | lld/ELF/Target.cpp | 9 | ||||
-rw-r--r-- | lld/ELF/Target.h | 1 | ||||
-rw-r--r-- | lld/ELF/Writer.cpp | 8 | ||||
-rw-r--r-- | lld/test/ELF/i386-gotpc.s | 20 |
4 files changed, 26 insertions, 12 deletions
diff --git a/lld/ELF/Target.cpp b/lld/ELF/Target.cpp index 8c58617cabe..20dbbf02064 100644 --- a/lld/ELF/Target.cpp +++ b/lld/ELF/Target.cpp @@ -93,7 +93,6 @@ public: void relaxTlsIeToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const override; void relaxTlsLdToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const override; - bool isGotRelative(uint32_t Type) const override; bool refersToGotEntry(uint32_t Type) const override; }; @@ -271,7 +270,6 @@ bool TargetInfo::needsCopyRel(uint32_t Type, const SymbolBody &S) const { return mayNeedCopy<ELFT>(S) && needsCopyRelImpl(Type); } -bool TargetInfo::isGotRelative(uint32_t Type) const { return false; } bool TargetInfo::isHintRel(uint32_t Type) const { return false; } bool TargetInfo::isRelRelative(uint32_t Type) const { return true; } @@ -487,13 +485,6 @@ bool X86TargetInfo::needsPltImpl(uint32_t Type) const { return Type == R_386_PLT32; } -bool X86TargetInfo::isGotRelative(uint32_t Type) const { - // This relocation does not require got entry, - // but it is relative to got and needs it to be created. - // Here we request for that. - return Type == R_386_GOTOFF; -} - bool X86TargetInfo::refersToGotEntry(uint32_t Type) const { return Type == R_386_GOT32; } diff --git a/lld/ELF/Target.h b/lld/ELF/Target.h index 47b8852e045..7b461ea21fc 100644 --- a/lld/ELF/Target.h +++ b/lld/ELF/Target.h @@ -68,7 +68,6 @@ public: virtual RelExpr getRelExpr(uint32_t Type, const SymbolBody &S) const = 0; virtual void relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const = 0; - virtual bool isGotRelative(uint32_t Type) const; bool canRelaxTls(uint32_t Type, const SymbolBody *S) const; template <class ELFT> bool needsCopyRel(uint32_t Type, const SymbolBody &S) const; diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index c799d54c6e6..3421eb3e2a4 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -467,8 +467,6 @@ void Writer<ELFT>::scanRelocs(InputSectionBase<ELFT> &C, ArrayRef<RelTy> Rels) { if (Offset == (uintX_t)-1) continue; - if (Target->isGotRelative(Type)) - HasGotOffRel = true; // Set "used" bit for --as-needed. if (OrigBody.isUndefined() && !OrigBody.isWeak()) @@ -476,6 +474,12 @@ void Writer<ELFT>::scanRelocs(InputSectionBase<ELFT> &C, ArrayRef<RelTy> Rels) { S->File->IsUsed = true; RelExpr Expr = Target->getRelExpr(Type, Body); + + // This relocation does not require got entry, but it is relative to got and + // needs it to be created. Here we request for that. + if (Expr == R_GOTONLY_PC || Expr == R_GOTREL) + HasGotOffRel = true; + uintX_t Addend = getAddend<ELFT>(RI); const uint8_t *BufLoc = Buf + RI.r_offset; if (!RelTy::IsRela) diff --git a/lld/test/ELF/i386-gotpc.s b/lld/test/ELF/i386-gotpc.s new file mode 100644 index 00000000000..14c2fcbec06 --- /dev/null +++ b/lld/test/ELF/i386-gotpc.s @@ -0,0 +1,20 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o +// RUN: ld.lld %t.o -o %t.so -shared +// RUN: llvm-readobj -s %t.so | FileCheck %s +// RUN: llvm-objdump -d %t.so | FileCheck --check-prefix=DISASM %s + +movl $_GLOBAL_OFFSET_TABLE_, %eax + +// CHECK: Name: .got (38) +// CHECK-NEXT: Type: SHT_PROGBITS +// CHECK-NEXT: Flags [ +// CHECK-NEXT: SHF_ALLOC +// CHECK-NEXT: SHF_WRITE +// CHECK-NEXT: ] +// CHECK-NEXT: Address: 0x2030 + +// DISASM: Disassembly of section .text: +// DISASM-NEXT: .text: +// DISASM-NEXT: 1000: {{.*}} movl $4144, %eax +// 0x2030 - 0x1000 = 4144 |