[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:
Jez Ng 2020-08-27 15:59:45 -07:00
parent 2a38dba7dd
commit 7083363c05
3 changed files with 41 additions and 5 deletions

View File

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

View File

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

View File

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