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.

llvm-svn: 268668
This commit is contained in:
Rafael Espindola 2016-05-05 19:41:49 +00:00
parent 188a7c5f9e
commit 66434562e7
6 changed files with 72 additions and 14 deletions

View File

@ -113,9 +113,11 @@ bool SymbolBody::isPreemptible() const {
if (isLocal()) if (isLocal())
return false; 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()) if (isShared())
return true; return !NeedsCopyOrPltAddr;
// That's all that can be preempted in a non-DSO. // That's all that can be preempted in a non-DSO.
if (!Config->Shared) if (!Config->Shared)

View File

@ -606,13 +606,10 @@ void Writer<ELFT>::scanRelocs(InputSectionBase<ELFT> &C, ArrayRef<RelTy> Rels) {
if (Offset == (uintX_t)-1) if (Offset == (uintX_t)-1)
continue; continue;
bool Preemptible = Body.isPreemptible();
Expr = adjustExpr(Body, IsWrite, Expr, Type); Expr = adjustExpr(Body, IsWrite, Expr, Type);
if (HasError) if (HasError)
continue; 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 // This relocation does not require got entry, but it is relative to got and
// needs it to be created. Here we request for that. // needs it to be created. Here we request for that.
@ -711,7 +708,7 @@ void Writer<ELFT>::scanRelocs(InputSectionBase<ELFT> &C, ArrayRef<RelTy> Rels) {
continue; continue;
} }
if (Preemptible) { if (Body.isPreemptible()) {
// We don't know anything about the finaly symbol. Just ask the dynamic // We don't know anything about the finaly symbol. Just ask the dynamic
// linker to handle the relocation for us. // linker to handle the relocation for us.
AddDyn({Target->getDynRel(Type), C.OutSec, Offset, false, &Body, Addend}); AddDyn({Target->getDynRel(Type), C.OutSec, Offset, false, &Body, Addend});

View File

@ -0,0 +1,9 @@
.global foo
.type foo, @object
.size foo, 4
foo:
.long 0
.global bar
.type bar, @function
bar:

View File

@ -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>

View File

@ -23,15 +23,21 @@
# CHECK-NEXT: Reserved entries [ # CHECK-NEXT: Reserved entries [
# CHECK: ] # CHECK: ]
# CHECK-NEXT: Local entries [ # CHECK-NEXT: Local entries [
# CHECK-NEXT: Entry {
# CHECK-NEXT: Address: 0x30008
# CHECK-NEXT: Access: -32744
# CHECK-NEXT: Initial: 0x40010
# CHECK-NEXT: }
# CHECK-NEXT: ] # CHECK-NEXT: ]
# CHECK-NEXT: Global entries [ # CHECK-NEXT: Global entries [
# CHECK-NEXT: Entry { # CHECK-NEXT: Entry {
# CHECK: Section: .bss # CHECK-NEXT: Address: 0x3000C
# CHECK-NEXT: Name: data0 # CHECK-NEXT: Access: -32740
# CHECK-NEXT: } # CHECK-NEXT: Initial: 0x40010
# CHECK-NEXT: Entry { # CHECK-NEXT: Value: 0x40010
# CHECK: Section: .bss # CHECK-NEXT: Type: Object (0x1)
# CHECK-NEXT: Name: data1 # CHECK-NEXT: Section: .bss (0xC)
# CHECK-NEXT: Name: data1@ (7)
# CHECK-NEXT: } # CHECK-NEXT: }
# CHECK-NEXT: ] # CHECK-NEXT: ]
# CHECK-NEXT: Number of TLS and multi-GOT entries: 0 # CHECK-NEXT: Number of TLS and multi-GOT entries: 0

View File

@ -232,7 +232,7 @@
.global _start .global _start
_start: _start:
.long bar .long bar
jmp *bar@GOTPCREL(%rip) jmp *bar2@GOTPCREL(%rip)
.section .data,"aw" .section .data,"aw"
.quad 0 .quad 0