forked from OSchip/llvm-project
Simplify. Thanks to Rui for the suggestion.
llvm-svn: 270551
This commit is contained in:
parent
97434957ef
commit
dba64b8ea4
|
@ -169,6 +169,7 @@ getSymVA(uint32_t Type, typename ELFT::uint A, typename ELFT::uint P,
|
|||
switch (Expr) {
|
||||
case R_HINT:
|
||||
llvm_unreachable("cannot relocate hint relocs");
|
||||
case R_RELAXABLE_GOT_PC:
|
||||
case R_RELAX_TLS_GD_TO_LE:
|
||||
case R_RELAX_TLS_GD_TO_IE:
|
||||
case R_RELAX_TLS_IE_TO_LE:
|
||||
|
@ -250,6 +251,7 @@ getSymVA(uint32_t Type, typename ELFT::uint A, typename ELFT::uint P,
|
|||
return SymVA - P;
|
||||
}
|
||||
case R_PC:
|
||||
case R_RELAX_GOT_PC:
|
||||
return Body.getVA<ELFT>(A) - P;
|
||||
case R_PAGE_PC:
|
||||
return getAArch64Page(Body.getVA<ELFT>(A)) - getAArch64Page(P);
|
||||
|
@ -317,13 +319,10 @@ void InputSectionBase<ELFT>::relocate(uint8_t *Buf, uint8_t *BufEnd) {
|
|||
uint64_t SymVA = SignExtend64<Bits>(
|
||||
getSymVA<ELFT>(Type, A, AddrLoc, *Rel.Sym, BufLoc, *File, Expr));
|
||||
|
||||
if (Expr == R_PPC_PLT_OPD) {
|
||||
uint32_t Nop = 0x60000000;
|
||||
if (BufLoc + 8 <= BufEnd && read32be(BufLoc + 4) == Nop)
|
||||
write32be(BufLoc + 4, 0xe8410028); // ld %r2, 40(%r1)
|
||||
}
|
||||
|
||||
switch (Expr) {
|
||||
case R_RELAX_GOT_PC:
|
||||
Target->relaxGot(BufLoc, SymVA);
|
||||
break;
|
||||
case R_RELAX_TLS_IE_TO_LE:
|
||||
Target->relaxTlsIeToLe(BufLoc, Type, SymVA);
|
||||
break;
|
||||
|
@ -336,6 +335,11 @@ void InputSectionBase<ELFT>::relocate(uint8_t *Buf, uint8_t *BufEnd) {
|
|||
case R_RELAX_TLS_GD_TO_IE:
|
||||
Target->relaxTlsGdToIe(BufLoc, Type, SymVA);
|
||||
break;
|
||||
case R_PPC_PLT_OPD:
|
||||
// Patch a nop (0x60000000) to a ld.
|
||||
if (BufLoc + 8 <= BufEnd && read32be(BufLoc + 4) == 0x60000000)
|
||||
write32be(BufLoc + 4, 0xe8410028); // ld %r2, 40(%r1)
|
||||
// fallthrough
|
||||
default:
|
||||
Target->relocateOne(BufLoc, Type, SymVA);
|
||||
break;
|
||||
|
|
|
@ -47,6 +47,8 @@ enum RelExpr {
|
|||
R_PPC_OPD,
|
||||
R_PPC_PLT_OPD,
|
||||
R_PPC_TOC,
|
||||
R_RELAXABLE_GOT_PC,
|
||||
R_RELAX_GOT_PC,
|
||||
R_RELAX_TLS_GD_TO_IE,
|
||||
R_RELAX_TLS_GD_TO_LE,
|
||||
R_RELAX_TLS_IE_TO_LE,
|
||||
|
|
|
@ -113,6 +113,7 @@ public:
|
|||
int32_t Index, unsigned RelOff) const override;
|
||||
void relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const override;
|
||||
|
||||
void relaxGot(uint8_t *Loc, uint64_t Val) const override;
|
||||
void relaxTlsGdToIe(uint8_t *Loc, uint32_t Type, uint64_t Val) const override;
|
||||
void relaxTlsGdToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const override;
|
||||
void relaxTlsIeToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const override;
|
||||
|
@ -232,6 +233,10 @@ bool TargetInfo::isTlsGlobalDynamicRel(uint32_t Type) const {
|
|||
return false;
|
||||
}
|
||||
|
||||
void TargetInfo::relaxGot(uint8_t *Loc, uint64_t Val) const {
|
||||
llvm_unreachable("Should not have claimed to be relaxable");
|
||||
}
|
||||
|
||||
void TargetInfo::relaxTlsGdToLe(uint8_t *Loc, uint32_t Type,
|
||||
uint64_t Val) const {
|
||||
llvm_unreachable("Should not have claimed to be relaxable");
|
||||
|
@ -516,10 +521,11 @@ RelExpr X86_64TargetInfo::getRelExpr(uint32_t Type, const SymbolBody &S) const {
|
|||
case R_X86_64_GOT32:
|
||||
return R_GOT_FROM_END;
|
||||
case R_X86_64_GOTPCREL:
|
||||
case R_X86_64_GOTPCRELX:
|
||||
case R_X86_64_REX_GOTPCRELX:
|
||||
case R_X86_64_GOTTPOFF:
|
||||
return R_GOT_PC;
|
||||
case R_X86_64_GOTPCRELX:
|
||||
case R_X86_64_REX_GOTPCRELX:
|
||||
return R_RELAXABLE_GOT_PC;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -727,6 +733,11 @@ void X86_64TargetInfo::relocateOne(uint8_t *Loc, uint32_t Type,
|
|||
}
|
||||
}
|
||||
|
||||
void X86_64TargetInfo::relaxGot(uint8_t *Loc, uint64_t Val) const {
|
||||
Loc[-2] = 0x8d;
|
||||
relocateOne(Loc, R_X86_64_PC32, Val);
|
||||
}
|
||||
|
||||
// Relocation masks following the #lo(value), #hi(value), #ha(value),
|
||||
// #higher(value), #highera(value), #highest(value), and #highesta(value)
|
||||
// macros defined in section 4.5.1. Relocation Types of the PPC-elf64abi
|
||||
|
|
|
@ -88,6 +88,7 @@ public:
|
|||
|
||||
uint32_t ThunkSize = 0;
|
||||
|
||||
virtual void relaxGot(uint8_t *Loc, uint64_t Val) const;
|
||||
virtual void relaxTlsGdToIe(uint8_t *Loc, uint32_t Type, uint64_t Val) const;
|
||||
virtual void relaxTlsGdToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const;
|
||||
virtual void relaxTlsIeToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const;
|
||||
|
|
|
@ -432,7 +432,8 @@ static bool needsPlt(RelExpr Expr) {
|
|||
// True if this expression is of the form Sym - X, where X is a position in the
|
||||
// file (PC, or GOT for example).
|
||||
static bool isRelExpr(RelExpr Expr) {
|
||||
return Expr == R_PC || Expr == R_GOTREL || Expr == R_PAGE_PC;
|
||||
return Expr == R_PC || Expr == R_GOTREL || Expr == R_PAGE_PC ||
|
||||
Expr == R_RELAX_GOT_PC;
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
|
@ -510,10 +511,17 @@ static RelExpr adjustExpr(const elf::ObjectFile<ELFT> &File, SymbolBody &Body,
|
|||
if (Target->needsThunk(Type, File, Body))
|
||||
return R_THUNK;
|
||||
bool Preemptible = Body.isPreemptible();
|
||||
if (Body.isGnuIFunc())
|
||||
if (Body.isGnuIFunc()) {
|
||||
Expr = toPlt(Expr);
|
||||
else if (needsPlt(Expr) && !Preemptible)
|
||||
Expr = fromPlt(Expr);
|
||||
} else if (!Preemptible) {
|
||||
if (needsPlt(Expr))
|
||||
Expr = fromPlt(Expr);
|
||||
if (Expr == R_RELAXABLE_GOT_PC)
|
||||
Expr = R_RELAX_GOT_PC;
|
||||
}
|
||||
|
||||
if (Expr == R_RELAXABLE_GOT_PC)
|
||||
Expr = R_GOT_PC;
|
||||
|
||||
if (IsWrite || isStaticLinkTimeConstant<ELFT>(Expr, Type, Body))
|
||||
return Expr;
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
.globl dsofoo
|
||||
.type dsofoo, @function
|
||||
dsofoo:
|
||||
nop
|
|
@ -0,0 +1,73 @@
|
|||
# REQUIRES: x86
|
||||
# RUN: llvm-mc -filetype=obj -relax-relocations -triple=x86_64-unknown-linux %s -o %t.o
|
||||
# RUN: llvm-mc -filetype=obj -relax-relocations -triple=x86_64-pc-linux %S/Inputs/gotpc-relax-und-dso.s -o %tdso.o
|
||||
# RUN: ld.lld -shared %tdso.o -o %t.so
|
||||
# RUN: ld.lld -shared %t.o %t.so -o %tout
|
||||
# RUN: llvm-readobj -r -s %tout | FileCheck --check-prefix=RELOC %s
|
||||
# RUN: llvm-objdump -d %tout | FileCheck --check-prefix=DISASM %s
|
||||
|
||||
# RELOC: Relocations [
|
||||
# RELOC-NEXT: Section ({{.*}}) .rela.dyn {
|
||||
# RELOC-NEXT: 0x20A8 R_X86_64_GLOB_DAT dsofoo 0x0
|
||||
# RELOC-NEXT: 0x20B0 R_X86_64_GLOB_DAT foo 0x0
|
||||
# RELOC-NEXT: 0x20A0 R_X86_64_GLOB_DAT und 0x0
|
||||
# RELOC-NEXT: }
|
||||
# RELOC-NEXT: ]
|
||||
|
||||
# 0x101e + 7 - 36 = 0x1001
|
||||
# 0x1025 + 7 - 43 = 0x1001
|
||||
# DISASM: Disassembly of section .text:
|
||||
# DISASM-NEXT: foo:
|
||||
# DISASM-NEXT: 1000: 90 nop
|
||||
# DISASM: hid:
|
||||
# DISASM-NEXT: 1001: 90 nop
|
||||
# DISASM: _start:
|
||||
# DISASM-NEXT: 1002: 48 8b 05 97 10 00 00 movq 4247(%rip), %rax
|
||||
# DISASM-NEXT: 1009: 48 8b 05 90 10 00 00 movq 4240(%rip), %rax
|
||||
# DISASM-NEXT: 1010: 48 8b 05 91 10 00 00 movq 4241(%rip), %rax
|
||||
# DISASM-NEXT: 1017: 48 8b 05 8a 10 00 00 movq 4234(%rip), %rax
|
||||
# DISASM-NEXT: 101e: 48 8d 05 dc ff ff ff leaq -36(%rip), %rax
|
||||
# DISASM-NEXT: 1025: 48 8d 05 d5 ff ff ff leaq -43(%rip), %rax
|
||||
# DISASM-NEXT: 102c: 48 8b 05 7d 10 00 00 movq 4221(%rip), %rax
|
||||
# DISASM-NEXT: 1033: 48 8b 05 76 10 00 00 movq 4214(%rip), %rax
|
||||
# DISASM-NEXT: 103a: 8b 05 60 10 00 00 movl 4192(%rip), %eax
|
||||
# DISASM-NEXT: 1040: 8b 05 5a 10 00 00 movl 4186(%rip), %eax
|
||||
# DISASM-NEXT: 1046: 8b 05 5c 10 00 00 movl 4188(%rip), %eax
|
||||
# DISASM-NEXT: 104c: 8b 05 56 10 00 00 movl 4182(%rip), %eax
|
||||
# DISASM-NEXT: 1052: 8d 05 a9 ff ff ff leal -87(%rip), %eax
|
||||
# DISASM-NEXT: 1058: 8d 05 a3 ff ff ff leal -93(%rip), %eax
|
||||
# DISASM-NEXT: 105e: 8b 05 4c 10 00 00 movl 4172(%rip), %eax
|
||||
# DISASM-NEXT: 1064: 8b 05 46 10 00 00 movl 4166(%rip), %eax
|
||||
|
||||
.text
|
||||
.globl foo
|
||||
.type foo, @function
|
||||
foo:
|
||||
nop
|
||||
|
||||
.globl hid
|
||||
.hidden hid
|
||||
.type hid, @function
|
||||
hid:
|
||||
nop
|
||||
|
||||
.globl _start
|
||||
.type _start, @function
|
||||
_start:
|
||||
movq und@GOTPCREL(%rip), %rax
|
||||
movq und@GOTPCREL(%rip), %rax
|
||||
movq dsofoo@GOTPCREL(%rip), %rax
|
||||
movq dsofoo@GOTPCREL(%rip), %rax
|
||||
movq hid@GOTPCREL(%rip), %rax
|
||||
movq hid@GOTPCREL(%rip), %rax
|
||||
movq foo@GOTPCREL(%rip), %rax
|
||||
movq foo@GOTPCREL(%rip), %rax
|
||||
|
||||
movl und@GOTPCREL(%rip), %eax
|
||||
movl und@GOTPCREL(%rip), %eax
|
||||
movl dsofoo@GOTPCREL(%rip), %eax
|
||||
movl dsofoo@GOTPCREL(%rip), %eax
|
||||
movl hid@GOTPCREL(%rip), %eax
|
||||
movl hid@GOTPCREL(%rip), %eax
|
||||
movl foo@GOTPCREL(%rip), %eax
|
||||
movl foo@GOTPCREL(%rip), %eax
|
|
@ -0,0 +1,69 @@
|
|||
# REQUIRES: x86
|
||||
# RUN: llvm-mc -filetype=obj -relax-relocations -triple=x86_64-unknown-linux %s -o %t.o
|
||||
# RUN: ld.lld %t.o -o %t1
|
||||
# RUN: llvm-readobj -r %t1 | FileCheck --check-prefix=RELOC %s
|
||||
# RUN: llvm-objdump -d %t1 | FileCheck --check-prefix=DISASM %s
|
||||
|
||||
## There is no relocations.
|
||||
# RELOC: Relocations [
|
||||
# RELOC: ]
|
||||
|
||||
# 0x11003 + 7 - 10 = 0x11000
|
||||
# 0x1100a + 7 - 17 = 0x11000
|
||||
# 0x11011 + 7 - 23 = 0x11001
|
||||
# 0x11018 + 7 - 30 = 0x11001
|
||||
# DISASM: Disassembly of section .text:
|
||||
# DISASM-NEXT: foo:
|
||||
# DISASM-NEXT: 11000: 90 nop
|
||||
# DISASM: hid:
|
||||
# DISASM-NEXT: 11001: 90 nop
|
||||
# DISASM: ifunc:
|
||||
# DISASM-NEXT: 11002: c3 retq
|
||||
# DISASM: _start:
|
||||
# DISASM-NEXT: 11003: 48 8d 05 f6 ff ff ff leaq -10(%rip), %rax
|
||||
# DISASM-NEXT: 1100a: 48 8d 05 ef ff ff ff leaq -17(%rip), %rax
|
||||
# DISASM-NEXT: 11011: 48 8d 05 e9 ff ff ff leaq -23(%rip), %rax
|
||||
# DISASM-NEXT: 11018: 48 8d 05 e2 ff ff ff leaq -30(%rip), %rax
|
||||
# DISASM-NEXT: 1101f: 48 8b 05 da 0f 00 00 movq 4058(%rip), %rax
|
||||
# DISASM-NEXT: 11026: 48 8b 05 d3 0f 00 00 movq 4051(%rip), %rax
|
||||
# DISASM-NEXT: 1102d: 8d 05 cd ff ff ff leal -51(%rip), %eax
|
||||
# DISASM-NEXT: 11033: 8d 05 c7 ff ff ff leal -57(%rip), %eax
|
||||
# DISASM-NEXT: 11039: 8d 05 c2 ff ff ff leal -62(%rip), %eax
|
||||
# DISASM-NEXT: 1103f: 8d 05 bc ff ff ff leal -68(%rip), %eax
|
||||
# DISASM-NEXT: 11045: 8b 05 b5 0f 00 00 movl 4021(%rip), %eax
|
||||
# DISASM-NEXT: 1104b: 8b 05 af 0f 00 00 movl 4015(%rip), %eax
|
||||
|
||||
.text
|
||||
.globl foo
|
||||
.type foo, @function
|
||||
foo:
|
||||
nop
|
||||
|
||||
.globl hid
|
||||
.hidden hid
|
||||
.type hid, @function
|
||||
hid:
|
||||
nop
|
||||
|
||||
.text
|
||||
.type ifunc STT_GNU_IFUNC
|
||||
.globl ifunc
|
||||
.type ifunc, @function
|
||||
ifunc:
|
||||
ret
|
||||
|
||||
.globl _start
|
||||
.type _start, @function
|
||||
_start:
|
||||
movq foo@GOTPCREL(%rip), %rax
|
||||
movq foo@GOTPCREL(%rip), %rax
|
||||
movq hid@GOTPCREL(%rip), %rax
|
||||
movq hid@GOTPCREL(%rip), %rax
|
||||
movq ifunc@GOTPCREL(%rip), %rax
|
||||
movq ifunc@GOTPCREL(%rip), %rax
|
||||
movl foo@GOTPCREL(%rip), %eax
|
||||
movl foo@GOTPCREL(%rip), %eax
|
||||
movl hid@GOTPCREL(%rip), %eax
|
||||
movl hid@GOTPCREL(%rip), %eax
|
||||
movl ifunc@GOTPCREL(%rip), %eax
|
||||
movl ifunc@GOTPCREL(%rip), %eax
|
Loading…
Reference in New Issue