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())
|
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)
|
||||||
|
@ -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});
|
||||||
|
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-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
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user