mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-02-13 05:40:59 +00:00
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:
parent
188a7c5f9e
commit
66434562e7
@ -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)
|
||||
|
@ -606,13 +606,10 @@ void Writer<ELFT>::scanRelocs(InputSectionBase<ELFT> &C, ArrayRef<RelTy> Rels) {
|
||||
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(InputSectionBase<ELFT> &C, ArrayRef<RelTy> Rels) {
|
||||
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});
|
||||
|
9
lld/test/ELF/Inputs/copy-rel-pie.s
Normal file
9
lld/test/ELF/Inputs/copy-rel-pie.s
Normal file
@ -0,0 +1,9 @@
|
||||
.global foo
|
||||
.type foo, @object
|
||||
.size foo, 4
|
||||
foo:
|
||||
.long 0
|
||||
|
||||
.global bar
|
||||
.type bar, @function
|
||||
bar:
|
44
lld/test/ELF/copy-rel-pie.s
Normal file
44
lld/test/ELF/copy-rel-pie.s
Normal 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>
|
@ -23,15 +23,21 @@
|
||||
# CHECK-NEXT: Reserved entries [
|
||||
# CHECK: ]
|
||||
# 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: Global entries [
|
||||
# CHECK-NEXT: Entry {
|
||||
# CHECK: Section: .bss
|
||||
# CHECK-NEXT: Name: data0
|
||||
# CHECK-NEXT: }
|
||||
# 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
|
||||
|
@ -232,7 +232,7 @@
|
||||
.global _start
|
||||
_start:
|
||||
.long bar
|
||||
jmp *bar@GOTPCREL(%rip)
|
||||
jmp *bar2@GOTPCREL(%rip)
|
||||
|
||||
.section .data,"aw"
|
||||
.quad 0
|
||||
|
Loading…
x
Reference in New Issue
Block a user