[PATCH] D44414: Error instead of producing broken binary

Rafael Avila de Espindola via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 14 09:42:16 PDT 2018


espindola updated this revision to Diff 138393.

https://reviews.llvm.org/D44414

Files:
  ELF/Arch/X86.cpp
  ELF/Relocations.cpp
  ELF/Target.h
  test/ELF/Inputs/i386-pic-plt.s
  test/ELF/i386-pic-plt.s


Index: test/ELF/i386-pic-plt.s
===================================================================
--- /dev/null
+++ 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
+
+.global _start
+_start:
+  call foo
Index: test/ELF/Inputs/i386-pic-plt.s
===================================================================
--- /dev/null
+++ test/ELF/Inputs/i386-pic-plt.s
@@ -0,0 +1,4 @@
+        .global foo
+        .type foo, @function
+foo:
+        nop
Index: ELF/Target.h
===================================================================
--- ELF/Target.h
+++ ELF/Target.h
@@ -107,6 +107,8 @@
   // executable OutputSections.
   uint32_t TrapInstr = 0;
 
+  bool SupportsPltPreemption = true;
+
   virtual RelExpr adjustRelaxExpr(RelType Type, const uint8_t *Data,
                                   RelExpr Expr) const;
   virtual void relaxGot(uint8_t *Loc, uint64_t Val) const;
Index: ELF/Relocations.cpp
===================================================================
--- ELF/Relocations.cpp
+++ ELF/Relocations.cpp
@@ -875,6 +875,9 @@
     // 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).
+    if (!Target->SupportsPltPreemption)
+      errorOrWarn("symbol '" + toString(Sym) + "' cannot be preempted" +
+                  getLocation(Sec, Sym, Offset));
     Sym.NeedsPltAddr = true;
     Expr = toPlt(Expr);
     Sec.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
Index: ELF/Arch/X86.cpp
===================================================================
--- ELF/Arch/X86.cpp
+++ ELF/Arch/X86.cpp
@@ -60,6 +60,15 @@
   PltHeaderSize = 16;
   TlsGdRelaxSkip = 2;
   TrapInstr = 0xcccccccc; // 0xcc = INT3
+
+  // For position independent executable, 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)
+    SupportsPltPreemption = false;
 }
 
 static bool hasBaseReg(uint8_t ModRM) { return (ModRM & 0xc7) != 0x5; }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D44414.138393.patch
Type: text/x-patch
Size: 2604 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180314/9506acf4/attachment.bin>


More information about the llvm-commits mailing list