mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-27 15:06:05 +00:00
[ELF][X86] Support R_X86_64_PLTOFF64
For a function call (using the default `-fplt`), GCC `-mcmodel=large` generates an assembly modifier which leads to an R_X86_64_PLTOFF64 relocation. In real world, http://git.ageinghacker.net/jitter (used by GNU poke) uses `-mcmodel=large`. R_X86_64_PLTOFF64's formula is (if preemptible) `L - GOT + A` or (if non-preemptible) `S - GOT + A` where `GOT` is (confusingly) the address of `.got.plt` Reviewed By: peter.smith Differential Revision: https://reviews.llvm.org/D112386
This commit is contained in:
parent
a14ccaf509
commit
ca8105b76c
@ -356,6 +356,8 @@ RelExpr X86_64::getRelExpr(RelType type, const Symbol &s,
|
||||
return R_GOT_PC;
|
||||
case R_X86_64_GOTOFF64:
|
||||
return R_GOTPLTREL;
|
||||
case R_X86_64_PLTOFF64:
|
||||
return R_PLT_GOTPLT;
|
||||
case R_X86_64_GOTPC32:
|
||||
case R_X86_64_GOTPC64:
|
||||
return R_GOTPLTONLY_PC;
|
||||
@ -718,6 +720,7 @@ int64_t X86_64::getImplicitAddend(const uint8_t *buf, RelType type) const {
|
||||
case R_X86_64_GOT64:
|
||||
case R_X86_64_GOTOFF64:
|
||||
case R_X86_64_GOTPC64:
|
||||
case R_X86_64_PLTOFF64:
|
||||
case R_X86_64_IRELATIVE:
|
||||
case R_X86_64_RELATIVE:
|
||||
return read64le(buf);
|
||||
@ -779,6 +782,7 @@ void X86_64::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
|
||||
case R_X86_64_GOT64:
|
||||
case R_X86_64_GOTOFF64:
|
||||
case R_X86_64_GOTPC64:
|
||||
case R_X86_64_PLTOFF64:
|
||||
write64le(loc, val);
|
||||
break;
|
||||
default:
|
||||
|
@ -795,6 +795,8 @@ uint64_t InputSectionBase::getRelocTargetVA(const InputFile *file, RelType type,
|
||||
case R_PLT_PC:
|
||||
case R_PPC64_CALL_PLT:
|
||||
return sym.getPltVA() + a - p;
|
||||
case R_PLT_GOTPLT:
|
||||
return sym.getPltVA() + a - in.gotPlt->getVA();
|
||||
case R_PPC32_PLTREL:
|
||||
// R_PPC_PLTREL24 uses the addend (usually 0 or 0x8000) to indicate r30
|
||||
// stores _GLOBAL_OFFSET_TABLE_ or .got2+0x8000. The addend is ignored for
|
||||
|
@ -188,7 +188,8 @@ static bool isAbsoluteValue(const Symbol &sym) {
|
||||
|
||||
// Returns true if Expr refers a PLT entry.
|
||||
static bool needsPlt(RelExpr expr) {
|
||||
return oneof<R_PLT_PC, R_PPC32_PLTREL, R_PPC64_CALL_PLT, R_PLT>(expr);
|
||||
return oneof<R_PLT, R_PLT_PC, R_PLT_GOTPLT, R_PPC32_PLTREL, R_PPC64_CALL_PLT>(
|
||||
expr);
|
||||
}
|
||||
|
||||
// Returns true if Expr refers a GOT entry. Note that this function
|
||||
@ -224,11 +225,10 @@ static bool isStaticLinkTimeConstant(RelExpr e, RelType type, const Symbol &sym,
|
||||
R_MIPS_GOT_LOCAL_PAGE, R_MIPS_GOTREL, R_MIPS_GOT_OFF,
|
||||
R_MIPS_GOT_OFF32, R_MIPS_GOT_GP_PC, R_MIPS_TLSGD,
|
||||
R_AARCH64_GOT_PAGE_PC, R_GOT_PC, R_GOTONLY_PC, R_GOTPLTONLY_PC,
|
||||
R_PLT_PC, R_TLSGD_GOT, R_TLSGD_GOTPLT, R_TLSGD_PC, R_PPC32_PLTREL,
|
||||
R_PPC64_CALL_PLT, R_PPC64_RELAX_TOC, R_RISCV_ADD, R_TLSDESC_CALL,
|
||||
R_TLSDESC_PC, R_AARCH64_TLSDESC_PAGE, R_TLSLD_HINT, R_TLSIE_HINT,
|
||||
R_AARCH64_GOT_PAGE>(
|
||||
e))
|
||||
R_PLT_PC, R_PLT_GOTPLT, R_TLSGD_GOT, R_TLSGD_GOTPLT, R_TLSGD_PC,
|
||||
R_PPC32_PLTREL, R_PPC64_CALL_PLT, R_PPC64_RELAX_TOC, R_RISCV_ADD,
|
||||
R_TLSDESC_CALL, R_TLSDESC_PC, R_AARCH64_TLSDESC_PAGE, R_TLSLD_HINT,
|
||||
R_TLSIE_HINT, R_AARCH64_GOT_PAGE>(e))
|
||||
return true;
|
||||
|
||||
// These never do, except if the entire file is position dependent or if
|
||||
@ -300,6 +300,8 @@ static RelExpr fromPlt(RelExpr expr) {
|
||||
return R_PPC64_CALL;
|
||||
case R_PLT:
|
||||
return R_ABS;
|
||||
case R_PLT_GOTPLT:
|
||||
return R_GOTPLTREL;
|
||||
default:
|
||||
return expr;
|
||||
}
|
||||
@ -1394,8 +1396,9 @@ static void scanReloc(InputSectionBase &sec, OffsetGetter &getOffset, RelTy *&i,
|
||||
// If the relocation does not emit a GOT or GOTPLT entry but its computation
|
||||
// uses their addresses, we need GOT or GOTPLT to be created.
|
||||
//
|
||||
// The 4 types that relative GOTPLT are all x86 and x86-64 specific.
|
||||
if (oneof<R_GOTPLTONLY_PC, R_GOTPLTREL, R_GOTPLT, R_TLSGD_GOTPLT>(expr)) {
|
||||
// The 5 types that relative GOTPLT are all x86 and x86-64 specific.
|
||||
if (oneof<R_GOTPLTONLY_PC, R_GOTPLTREL, R_GOTPLT, R_PLT_GOTPLT,
|
||||
R_TLSGD_GOTPLT>(expr)) {
|
||||
in.gotPlt->hasGotPltOffRel = true;
|
||||
} else if (oneof<R_GOTONLY_PC, R_GOTREL, R_PPC64_TOCBASE, R_PPC64_RELAX_TOC>(
|
||||
expr)) {
|
||||
|
@ -45,6 +45,7 @@ enum RelExpr {
|
||||
R_PC,
|
||||
R_PLT,
|
||||
R_PLT_PC,
|
||||
R_PLT_GOTPLT,
|
||||
R_RELAX_GOT_PC,
|
||||
R_RELAX_GOT_PC_NOPIC,
|
||||
R_RELAX_TLS_GD_TO_IE,
|
||||
|
41
lld/test/ELF/x86-64-reloc-pltoff64.s
Normal file
41
lld/test/ELF/x86-64-reloc-pltoff64.s
Normal file
@ -0,0 +1,41 @@
|
||||
# REQUIRES: x86
|
||||
## Test R_X86_64_PLTOFF64 (preemptible: L - GOT + A; non-preemptible: S - GOT + A).
|
||||
|
||||
# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o
|
||||
# RUN: ld.lld %t.o -shared -o %t.so
|
||||
# RUN: llvm-readelf -S %t.so | FileCheck %s --check-prefix=SEC-SHARED
|
||||
# RUN: llvm-objdump -d --no-show-raw-insn %t.so | FileCheck %s --check-prefix=SHARED
|
||||
|
||||
# RUN: ld.lld %t.o -o %t
|
||||
# RUN: llvm-readelf -S %t | FileCheck %s --check-prefix=SEC-PDE
|
||||
# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s --check-prefix=PDE
|
||||
|
||||
# SEC-SHARED: .got.plt PROGBITS 00000000000033c0 0003c0 000028
|
||||
|
||||
## foo@plt - .got.plt = 0x12f0 - 0x33c0 = -8400
|
||||
## undefweak@plt - .got.plt = 0x1300 - 0x33c0 = -8384
|
||||
# SHARED-LABEL: <.text>:
|
||||
# SHARED-NEXT: movabsq $-8400, %rdx
|
||||
# SHARED-NEXT: movabsq $-8384, %rdx
|
||||
# SHARED-LABEL: <foo@plt>:
|
||||
# SHARED-NEXT: 12f0: jmpq {{.*}}(%rip)
|
||||
|
||||
# SEC-PDE: .got.plt PROGBITS 0000000000202170 000170 000018
|
||||
|
||||
## Avoid PLT since the referenced symbol is non-preemptible.
|
||||
## foo - .got.plt = 0x20116c - 0x202170 = -4100
|
||||
## 0 - .got.plt = 0 - 0x202168 = -2105712
|
||||
# PDE-LABEL: <.text>:
|
||||
# PDE-NEXT: movabsq $-4100, %rdx
|
||||
# PDE-NEXT: movabsq $-2105712, %rdx
|
||||
# PDE-LABEL: <foo>:
|
||||
# PDE-NEXT: 20116c: retq
|
||||
|
||||
movabsq $foo@PLTOFF, %rdx
|
||||
movabsq $undefweak@PLTOFF, %rdx
|
||||
|
||||
.globl foo
|
||||
foo:
|
||||
ret
|
||||
|
||||
.weak undefweak
|
Loading…
x
Reference in New Issue
Block a user