[lld] r268668 - Fix copy relocations in pie.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Thu May 5 12:41:50 PDT 2016


Author: rafael
Date: Thu May  5 14:41:49 2016
New Revision: 268668

URL: http://llvm.org/viewvc/llvm-project?rev=268668&view=rev
Log:
Fix copy relocations in pie.

We were creating the copy relocations just fine, but then thinking that
the .bss position could be preempted and creating a dynamic relocation
to it, which would crash at runtime since that memory is read only.

Added:
    lld/trunk/test/ELF/Inputs/copy-rel-pie.s
    lld/trunk/test/ELF/copy-rel-pie.s
Modified:
    lld/trunk/ELF/Symbols.cpp
    lld/trunk/ELF/Writer.cpp
    lld/trunk/test/ELF/mips-got-and-copy.s
    lld/trunk/test/ELF/relro.s

Modified: lld/trunk/ELF/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.cpp?rev=268668&r1=268667&r2=268668&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.cpp (original)
+++ lld/trunk/ELF/Symbols.cpp Thu May  5 14:41:49 2016
@@ -113,9 +113,11 @@ bool SymbolBody::isPreemptible() const {
   if (isLocal())
     return false;
 
-  // Shared symbols resolve to the definition in the DSO.
+  // Shared symbols resolve to the definition in the DSO. The exceptions are
+  // symbols with copy relocations (which resolve to .bss) or preempt plt
+  // entries (which resolve to that plt entry).
   if (isShared())
-    return true;
+    return !NeedsCopyOrPltAddr;
 
   // That's all that can be preempted in a non-DSO.
   if (!Config->Shared)

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=268668&r1=268667&r2=268668&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Thu May  5 14:41:49 2016
@@ -606,13 +606,10 @@ void Writer<ELFT>::scanRelocs(InputSecti
     if (Offset == (uintX_t)-1)
       continue;
 
+    bool Preemptible = Body.isPreemptible();
     Expr = adjustExpr(Body, IsWrite, Expr, Type);
     if (HasError)
       continue;
-    bool Preemptible = Body.isPreemptible();
-    if (auto *B = dyn_cast<SharedSymbol<ELFT>>(&Body))
-      if (B->needsCopy())
-        Preemptible = false;
 
     // This relocation does not require got entry, but it is relative to got and
     // needs it to be created. Here we request for that.
@@ -711,7 +708,7 @@ void Writer<ELFT>::scanRelocs(InputSecti
       continue;
     }
 
-    if (Preemptible) {
+    if (Body.isPreemptible()) {
       // We don't know anything about the finaly symbol. Just ask the dynamic
       // linker to handle the relocation for us.
       AddDyn({Target->getDynRel(Type), C.OutSec, Offset, false, &Body, Addend});

Added: lld/trunk/test/ELF/Inputs/copy-rel-pie.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/Inputs/copy-rel-pie.s?rev=268668&view=auto
==============================================================================
--- lld/trunk/test/ELF/Inputs/copy-rel-pie.s (added)
+++ lld/trunk/test/ELF/Inputs/copy-rel-pie.s Thu May  5 14:41:49 2016
@@ -0,0 +1,9 @@
+.global foo
+.type foo, @object
+.size foo, 4
+foo:
+.long 0
+
+.global bar
+.type bar, @function
+bar:

Added: lld/trunk/test/ELF/copy-rel-pie.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/copy-rel-pie.s?rev=268668&view=auto
==============================================================================
--- lld/trunk/test/ELF/copy-rel-pie.s (added)
+++ lld/trunk/test/ELF/copy-rel-pie.s Thu May  5 14:41:49 2016
@@ -0,0 +1,44 @@
+// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
+// RUN: llvm-mc %p/Inputs/copy-rel-pie.s -o %t2.o -filetype=obj -triple=x86_64-pc-linux
+// RUN: ld.lld %t2.o -o %t2.so -shared
+// RUN: ld.lld %t.o %t2.so -o %t.exe -pie
+// RUN: llvm-readobj -s -r %t.exe | FileCheck %s
+// RUN: llvm-objdump -d %t.exe | FileCheck --check-prefix=DISASM %s
+
+.global _start
+_start:
+        call bar
+        call foo
+
+// CHECK:      Name: .plt
+// CHECK-NEXT: Type: SHT_PROGBITS
+// CHECK-NEXT: Flags [
+// CHECK-NEXT:   SHF_ALLOC
+// CHECK-NEXT:   SHF_EXECINSTR
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address: 0x1010
+
+// CHECK:      Name: .bss
+// CHECK-NEXT: Type: SHT_NOBITS
+// CHECK-NEXT: Flags [
+// CHECK-NEXT:   SHF_ALLOC
+// CHECK-NEXT:   SHF_WRITE
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address: 0x3020
+
+// CHECK:      Relocations [
+// CHECK-NEXT:   Section (4) .rela.dyn {
+// CHECK-NEXT:     0x3020 R_X86_64_COPY foo 0x0
+// CHECK-NEXT:   }
+// CHECK-NEXT:   Section (5) .rela.plt {
+// CHECK-NEXT:     0x3018 R_X86_64_JUMP_SLOT bar 0x0
+// CHECK-NEXT:   }
+// CHECK-NEXT: ]
+
+// (0x1010 + 0x10) - 0x1005 = 27
+// 0x3020          - 0x100a = 8214
+
+// DISASM:      Disassembly of section .text:
+// DISASM-NEXT: _start:
+// DISASM-NEXT:     1000:       e8 1b 00 00 00  callq   27
+// DISASM-NEXT:     1005:       e8 16 20 00 00  callq   8214 <foo>

Modified: lld/trunk/test/ELF/mips-got-and-copy.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/mips-got-and-copy.s?rev=268668&r1=268667&r2=268668&view=diff
==============================================================================
--- lld/trunk/test/ELF/mips-got-and-copy.s (original)
+++ lld/trunk/test/ELF/mips-got-and-copy.s Thu May  5 14:41:49 2016
@@ -23,15 +23,21 @@
 # CHECK-NEXT:   Reserved entries [
 # CHECK:        ]
 # CHECK-NEXT:   Local entries [
-# CHECK-NEXT:   ]
-# CHECK-NEXT:   Global entries [
 # CHECK-NEXT:     Entry {
-# CHECK:            Section: .bss
-# CHECK-NEXT:       Name: data0
+# CHECK-NEXT:       Address: 0x30008
+# CHECK-NEXT:       Access: -32744
+# CHECK-NEXT:       Initial: 0x40010
 # CHECK-NEXT:     }
+# CHECK-NEXT:   ]
+# CHECK-NEXT:   Global entries [
 # CHECK-NEXT:     Entry {
-# CHECK:            Section: .bss
-# CHECK-NEXT:       Name: data1
+# CHECK-NEXT:       Address: 0x3000C
+# CHECK-NEXT:       Access: -32740
+# CHECK-NEXT:       Initial: 0x40010
+# CHECK-NEXT:       Value: 0x40010
+# CHECK-NEXT:       Type: Object (0x1)
+# CHECK-NEXT:       Section: .bss (0xC)
+# CHECK-NEXT:       Name: data1@ (7)
 # CHECK-NEXT:     }
 # CHECK-NEXT:   ]
 # CHECK-NEXT:   Number of TLS and multi-GOT entries: 0

Modified: lld/trunk/test/ELF/relro.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/relro.s?rev=268668&r1=268667&r2=268668&view=diff
==============================================================================
--- lld/trunk/test/ELF/relro.s (original)
+++ lld/trunk/test/ELF/relro.s Thu May  5 14:41:49 2016
@@ -232,7 +232,7 @@
 .global _start
 _start:
   .long bar
-  jmp *bar at GOTPCREL(%rip)
+  jmp *bar2 at GOTPCREL(%rip)
 
 .section .data,"aw"
 .quad 0




More information about the llvm-commits mailing list