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,
|
void X86_64::prepareSymbolRelocation(lld::macho::Symbol *sym,
|
||||||
const InputSection *isec, const Reloc &r) {
|
const InputSection *isec, const Reloc &r) {
|
||||||
switch (r.type) {
|
switch (r.type) {
|
||||||
case X86_64_RELOC_GOT_LOAD:
|
case X86_64_RELOC_GOT_LOAD: {
|
||||||
// TODO: implement mov -> lea relaxation for non-dynamic symbols
|
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: {
|
case X86_64_RELOC_GOT: {
|
||||||
in.got->addEntry(sym);
|
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,
|
uint64_t X86_64::resolveSymbolVA(uint8_t *buf, const lld::macho::Symbol &sym,
|
||||||
uint8_t type) const {
|
uint8_t type) const {
|
||||||
switch (type) {
|
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:
|
case X86_64_RELOC_GOT:
|
||||||
return in.got->addr + sym.gotIndex * WordSize;
|
return in.got->addr + sym.gotIndex * WordSize;
|
||||||
case X86_64_RELOC_BRANCH: {
|
case X86_64_RELOC_BRANCH: {
|
||||||
|
|
|
@ -37,13 +37,16 @@ _main:
|
||||||
|
|
||||||
movl $0x2000004, %eax # write() syscall
|
movl $0x2000004, %eax # write() syscall
|
||||||
mov $1, %rdi # stdout
|
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
|
mov $13, %rdx # length of str
|
||||||
syscall
|
syscall
|
||||||
|
|
||||||
movl $0x2000004, %eax # write() syscall
|
movl $0x2000004, %eax # write() syscall
|
||||||
mov $1, %rdi # stdout
|
mov $1, %rdi # stdout
|
||||||
movq _goodbye_world@GOTPCREL(%rip), %rsi
|
pushq _goodbye_world@GOTPCREL(%rip)
|
||||||
|
popq %rsi
|
||||||
mov $15, %rdx # length of str
|
mov $15, %rdx # length of str
|
||||||
syscall
|
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