summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2018-03-14 18:08:33 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2018-03-14 18:08:33 +0000
commite2cc92ce284719b80deb46511ca10682adeca03e (patch)
tree56f17b9afc30c8bfe0244820100a56e273db202d
parent60d24445dd76dfccc7eeaea3bdcb10d751c8e2ad (diff)
downloadbcm5719-llvm-e2cc92ce284719b80deb46511ca10682adeca03e.tar.gz
bcm5719-llvm-e2cc92ce284719b80deb46511ca10682adeca03e.zip
Error instead of producing broken binary.
This "fixes" PR36678 by just producing an error when we find a case where we would produce an plt entry that used ebx but ebx would not be set. llvm-svn: 327542
-rw-r--r--lld/ELF/Relocations.cpp11
-rw-r--r--lld/test/ELF/Inputs/i386-pic-plt.s4
-rw-r--r--lld/test/ELF/i386-pic-plt.s12
3 files changed, 27 insertions, 0 deletions
diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index c168b01d127..0f975be42c0 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -875,6 +875,17 @@ static RelExpr processRelocAux(InputSectionBase &Sec, RelExpr Expr,
// that points to the real function is a dedicated got entry used by the
// plt. That is identified by special relocation types (R_X86_64_JUMP_SLOT,
// R_386_JMP_SLOT, etc).
+
+ // For position independent executable on i386, the plt entry requires ebx
+ // to be set. This causes two problems:
+ // * If some code has a direct reference to a function, it was probably
+ // compiled without -fPIE/-fPIC and doesn't maintain ebx.
+ // * If a library definition gets preempted to the executable, it will have
+ // the wrong ebx value.
+ if (Config->Pie && Config->EMachine == EM_386)
+ errorOrWarn("symbol '" + toString(Sym) +
+ "' cannot be preempted; recompile with -fPIE" +
+ getLocation(Sec, Sym, Offset));
Sym.NeedsPltAddr = true;
Expr = toPlt(Expr);
Sec.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
diff --git a/lld/test/ELF/Inputs/i386-pic-plt.s b/lld/test/ELF/Inputs/i386-pic-plt.s
new file mode 100644
index 00000000000..a7a812194fa
--- /dev/null
+++ b/lld/test/ELF/Inputs/i386-pic-plt.s
@@ -0,0 +1,4 @@
+ .global foo
+ .type foo, @function
+foo:
+ nop
diff --git a/lld/test/ELF/i386-pic-plt.s b/lld/test/ELF/i386-pic-plt.s
new file mode 100644
index 00000000000..0d32436899a
--- /dev/null
+++ b/lld/test/ELF/i386-pic-plt.s
@@ -0,0 +1,12 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %s -o %t.o
+// RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %p/Inputs/i386-pic-plt.s -o %t2.o
+// RUN: ld.lld -shared %t2.o -o %t2.so
+// RUN: ld.lld %t.o %t2.so -o %t
+// RUN: not ld.lld %t.o %t2.so -o %t -pie 2>&1 | FileCheck %s
+
+// CHECK: error: symbol 'foo' cannot be preempted; recompile with -fPIE
+
+.global _start
+_start:
+ call foo
OpenPOWER on IntegriCloud