forked from OSchip/llvm-project
[lld-macho] Implement GOT_LOAD relaxation
We can have GOT_LOAD relocations that reference `__dso_handle`. However, our binding opcode encoder doesn't support binding to the DSOHandle symbol. Instead of adding support for that, I decided it would be cleaner to implement GOT_LOAD relaxation since `__dso_handle`'s location is always statically known. Reviewed By: #lld-macho, smeenai Differential Revision: https://reviews.llvm.org/D86641
This commit is contained in:
parent
2a38dba7dd
commit
7083363c05
|
@ -220,8 +220,15 @@ void X86_64::writeStubHelperEntry(uint8_t *buf, const DylibSymbol &sym,
|
|||
void X86_64::prepareSymbolRelocation(lld::macho::Symbol *sym,
|
||||
const InputSection *isec, const Reloc &r) {
|
||||
switch (r.type) {
|
||||
case X86_64_RELOC_GOT_LOAD:
|
||||
// TODO: implement mov -> lea relaxation for non-dynamic symbols
|
||||
case X86_64_RELOC_GOT_LOAD: {
|
||||
if (sym->isWeakDef() || isa<DylibSymbol>(sym))
|
||||
in.got->addEntry(sym);
|
||||
|
||||
if (sym->isTlv())
|
||||
error("found GOT relocation referencing thread-local variable in " +
|
||||
toString(isec));
|
||||
break;
|
||||
}
|
||||
case X86_64_RELOC_GOT: {
|
||||
in.got->addEntry(sym);
|
||||
|
||||
|
@ -288,7 +295,15 @@ void X86_64::prepareSymbolRelocation(lld::macho::Symbol *sym,
|
|||
uint64_t X86_64::resolveSymbolVA(uint8_t *buf, const lld::macho::Symbol &sym,
|
||||
uint8_t type) const {
|
||||
switch (type) {
|
||||
case X86_64_RELOC_GOT_LOAD:
|
||||
case X86_64_RELOC_GOT_LOAD: {
|
||||
if (!sym.isInGot()) {
|
||||
if (buf[-2] != 0x8b)
|
||||
error("X86_64_RELOC_GOT_LOAD must be used with movq instructions");
|
||||
buf[-2] = 0x8d;
|
||||
return sym.getVA();
|
||||
}
|
||||
LLVM_FALLTHROUGH;
|
||||
}
|
||||
case X86_64_RELOC_GOT:
|
||||
return in.got->addr + sym.gotIndex * WordSize;
|
||||
case X86_64_RELOC_BRANCH: {
|
||||
|
|
|
@ -37,13 +37,16 @@ _main:
|
|||
|
||||
movl $0x2000004, %eax # write() syscall
|
||||
mov $1, %rdi # stdout
|
||||
movq _hello_world@GOTPCREL(%rip), %rsi
|
||||
## We use pushq/popq here instead of movq in order to avoid relaxation.
|
||||
pushq _hello_world@GOTPCREL(%rip)
|
||||
popq %rsi
|
||||
mov $13, %rdx # length of str
|
||||
syscall
|
||||
|
||||
movl $0x2000004, %eax # write() syscall
|
||||
mov $1, %rdi # stdout
|
||||
movq _goodbye_world@GOTPCREL(%rip), %rsi
|
||||
pushq _goodbye_world@GOTPCREL(%rip)
|
||||
popq %rsi
|
||||
mov $15, %rdx # length of str
|
||||
syscall
|
||||
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
# REQUIRES: x86
|
||||
|
||||
## Check that we perform relaxation for GOT_LOAD relocations to defined symbols.
|
||||
## Note: GOT_LOAD relocations to dylib symbols are already tested in dylink.s.
|
||||
|
||||
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t.o
|
||||
# RUN: lld -flavor darwinnew -o %t %t.o
|
||||
# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s
|
||||
# CHECK: leaq [[#]](%rip), %rax # {{.*}} <_foo>
|
||||
|
||||
.globl _main, _foo
|
||||
|
||||
_main:
|
||||
movq _foo@GOTPCREL(%rip), %rax
|
||||
ret
|
||||
|
||||
_foo:
|
||||
.space 0
|
Loading…
Reference in New Issue