summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/ELF/Target.cpp9
-rw-r--r--lld/ELF/Target.h1
-rw-r--r--lld/ELF/Writer.cpp8
-rw-r--r--lld/test/ELF/i386-gotpc.s20
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
OpenPOWER on IntegriCloud