summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Collingbourne <peter@pcc.me.uk>2016-04-13 02:24:48 +0000
committerPeter Collingbourne <peter@pcc.me.uk>2016-04-13 02:24:48 +0000
commit1f71d748aefd58255dfbc6c7c4f7a1f740943c5e (patch)
tree553466486e92343148cc4591e4b7f548085afcfc
parentf1c23dc4c735987a253b2a979f6623ac1c64035c (diff)
downloadbcm5719-llvm-1f71d748aefd58255dfbc6c7c4f7a1f740943c5e.tar.gz
bcm5719-llvm-1f71d748aefd58255dfbc6c7c4f7a1f740943c5e.zip
ELF: Do not create relative relocations for undefined symbols.
We need to ensure that the address of an undefined weak symbol evaluates to zero. We were getting this right for non-PIC executables (where the symbol can be evaluated directly) and for DSOs (where we emit a symbolic relocation for these symbols, as they are preemptible). But we weren't getting it right for PIEs. Probably the simplest way to ensure that these symbols evaluate to zero is by not creating a relocation in .got for them. Differential Revision: http://reviews.llvm.org/D19044 llvm-svn: 266161
-rw-r--r--lld/ELF/Writer.cpp4
-rw-r--r--lld/test/ELF/pie-weak.s16
2 files changed, 20 insertions, 0 deletions
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index ff1ba2e6635..c4f8ffc25c5 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -573,6 +573,10 @@ void Writer<ELFT>::scanRelocs(InputSectionBase<ELFT> &C, ArrayRef<RelTy> Rels) {
DynType = Target->TlsGotRel;
else if (Preemptible)
DynType = Target->GotRel;
+ else if (Body.isUndefined())
+ // Weak undefined symbols evaluate to zero, so don't create
+ // relocations for them.
+ continue;
else
DynType = Target->RelativeRel;
AddDyn({DynType, Out<ELFT>::Got, Body.getGotOffset<ELFT>(),
diff --git a/lld/test/ELF/pie-weak.s b/lld/test/ELF/pie-weak.s
new file mode 100644
index 00000000000..eff9553cf80
--- /dev/null
+++ b/lld/test/ELF/pie-weak.s
@@ -0,0 +1,16 @@
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: ld.lld -pie %t.o -o %t
+# RUN: llvm-readobj -r %t | FileCheck --check-prefix=RELOCS %s
+# RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASM %s
+
+# RELOCS: Relocations [
+# RELOCS-NEXT: ]
+
+.weak foo
+
+.globl _start
+_start:
+# DISASM: _start:
+# DISASM-NEXT: 1000: 48 8b 05 69 10 00 00 movq 4201(%rip), %rax
+# ^ .got - (.text + 7)
+mov foo@gotpcrel(%rip), %rax
OpenPOWER on IntegriCloud