[PPC][PPC64] PPC_REL14 and PPC64_REL14 relocations
When linking the linux kernel on ppc64 and ppc ld.lld: error: unrecognized reloc 11 11 is PPC_REL14 and PPC64_REL14 Differential revision: https://reviews.llvm.org/D54868 llvm-svn: 348255
This commit is contained in:
parent
58d44235e5
commit
aa6086a64c
|
@ -37,6 +37,7 @@ PPC::PPC() {
|
|||
RelExpr PPC::getRelExpr(RelType Type, const Symbol &S,
|
||||
const uint8_t *Loc) const {
|
||||
switch (Type) {
|
||||
case R_PPC_REL14:
|
||||
case R_PPC_REL24:
|
||||
case R_PPC_REL32:
|
||||
return R_PC;
|
||||
|
@ -62,6 +63,9 @@ void PPC::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
|
|||
case R_PPC_REL32:
|
||||
write32be(Loc, Val);
|
||||
break;
|
||||
case R_PPC_REL14:
|
||||
write32be(Loc, read32be(Loc) | (Val & 0xFFFC));
|
||||
break;
|
||||
case R_PPC_PLTREL24:
|
||||
case R_PPC_REL24:
|
||||
write32be(Loc, read32be(Loc) | (Val & 0x3FFFFFC));
|
||||
|
|
|
@ -421,6 +421,7 @@ RelExpr PPC64::getRelExpr(RelType Type, const Symbol &S,
|
|||
return R_GOTREL;
|
||||
case R_PPC64_TOC:
|
||||
return R_PPC_TOC;
|
||||
case R_PPC64_REL14:
|
||||
case R_PPC64_REL24:
|
||||
return R_PPC_CALL_PLT;
|
||||
case R_PPC64_REL16_LO:
|
||||
|
@ -692,6 +693,13 @@ void PPC64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
|
|||
case R_PPC64_TOC:
|
||||
write64(Loc, Val);
|
||||
break;
|
||||
case R_PPC64_REL14: {
|
||||
uint32_t Mask = 0x0000FFFC;
|
||||
checkInt(Loc, Val, 16, Type);
|
||||
checkAlignment(Loc, Val, 4, Type);
|
||||
write32(Loc, (read32(Loc) & ~Mask) | (Val & Mask));
|
||||
break;
|
||||
}
|
||||
case R_PPC64_REL24: {
|
||||
uint32_t Mask = 0x03FFFFFC;
|
||||
checkInt(Loc, Val, 26, Type);
|
||||
|
@ -709,8 +717,7 @@ void PPC64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
|
|||
|
||||
bool PPC64::needsThunk(RelExpr Expr, RelType Type, const InputFile *File,
|
||||
uint64_t BranchAddr, const Symbol &S) const {
|
||||
// The only call relocation we currently support is the REL24 type.
|
||||
if (Type != R_PPC64_REL24)
|
||||
if (Type != R_PPC64_REL14 && Type != R_PPC64_REL24)
|
||||
return false;
|
||||
|
||||
// If a function is in the Plt it needs to be called with a call-stub.
|
||||
|
@ -728,9 +735,13 @@ bool PPC64::needsThunk(RelExpr Expr, RelType Type, const InputFile *File,
|
|||
}
|
||||
|
||||
bool PPC64::inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const {
|
||||
assert(Type == R_PPC64_REL24 && "Unexpected relocation type used in branch");
|
||||
int64_t Offset = Dst - Src;
|
||||
return isInt<26>(Offset);
|
||||
if (Type == R_PPC64_REL14)
|
||||
return isInt<16>(Offset);
|
||||
if (Type == R_PPC64_REL24)
|
||||
return isInt<26>(Offset);
|
||||
llvm_unreachable("unsupported relocation type used in branch");
|
||||
return false;
|
||||
}
|
||||
|
||||
RelExpr PPC64::adjustRelaxExpr(RelType Type, const uint8_t *Data,
|
||||
|
|
|
@ -55,6 +55,17 @@ mystr:
|
|||
# CHECK: .FR_PPC_REL24:
|
||||
# CHECK: 1101c: 48 00 00 04 b .+4
|
||||
|
||||
.section .R_PPC_REL14,"ax",@progbits
|
||||
.globl .FR_PPC_REL14
|
||||
.FR_PPC_REL14:
|
||||
beq .Lfooy
|
||||
.section .R_PPC_REL14_2,"ax",@progbits
|
||||
.Lfooy:
|
||||
|
||||
# CHECK: Disassembly of section .R_PPC_REL14:
|
||||
# CHECK: .FR_PPC_REL14:
|
||||
# CHECK: 11020: {{.*}} bt 2, .+4
|
||||
|
||||
.section .R_PPC_REL32,"ax",@progbits
|
||||
.globl .FR_PPC_REL32
|
||||
.FR_PPC_REL32:
|
||||
|
@ -64,7 +75,7 @@ mystr:
|
|||
|
||||
# CHECK: Disassembly of section .R_PPC_REL32:
|
||||
# CHECK: .FR_PPC_REL32:
|
||||
# CHECK: 11020: 00 00 00 04
|
||||
# CHECK: 11024: 00 00 00 04
|
||||
|
||||
.section .R_PPC_ADDR32,"ax",@progbits
|
||||
.globl .FR_PPC_ADDR32
|
||||
|
@ -75,7 +86,7 @@ mystr:
|
|||
|
||||
# CHECK: Disassembly of section .R_PPC_ADDR32:
|
||||
# CHECK: .FR_PPC_ADDR32:
|
||||
# CHECK: 11024: 00 01 10 28
|
||||
# CHECK: 11028: 00 01 10 2c
|
||||
|
||||
.align 2
|
||||
.section .R_PPC_PLTREL24,"ax",@progbits
|
||||
|
@ -87,4 +98,4 @@ mystr:
|
|||
|
||||
# CHECK: Disassembly of section .R_PPC_PLTREL24:
|
||||
# CHECK: .R_PPC_PLTREL24:
|
||||
# CHECK: 11028: 48 00 00 04 b .+4
|
||||
# CHECK: 1102c: 48 00 00 04 b .+4
|
||||
|
|
|
@ -76,6 +76,17 @@ _start:
|
|||
# CHECK: .FR_PPC64_REL24:
|
||||
# CHECK: 1001001c: {{.*}} b .+4
|
||||
|
||||
.section .R_PPC64_REL14,"ax",@progbits
|
||||
.globl .FR_PPC64_REL14
|
||||
.FR_PPC64_REL14:
|
||||
beq .Lfooy
|
||||
.section .R_PPC64_REL14_2,"ax",@progbits
|
||||
.Lfooy:
|
||||
|
||||
# CHECK: Disassembly of section .R_PPC64_REL14:
|
||||
# CHECK: .FR_PPC64_REL14:
|
||||
# CHECK: 10010020: {{.*}} bt 2, .+4
|
||||
|
||||
.section .R_PPC64_ADDR16_LO,"ax",@progbits
|
||||
.globl .FR_PPC64_ADDR16_LO
|
||||
.FR_PPC64_ADDR16_LO:
|
||||
|
@ -83,7 +94,7 @@ _start:
|
|||
|
||||
# CHECK: Disassembly of section .R_PPC64_ADDR16_LO:
|
||||
# CHECK: .FR_PPC64_ADDR16_LO:
|
||||
# CHECK: 10010020: {{.*}} li 1, 0
|
||||
# CHECK: 10010024: {{.*}} li 1, 0
|
||||
|
||||
.section .R_PPC64_ADDR16_HI,"ax",@progbits
|
||||
.globl .FR_PPC64_ADDR16_HI
|
||||
|
@ -92,7 +103,7 @@ _start:
|
|||
|
||||
# CHECK: Disassembly of section .R_PPC64_ADDR16_HI:
|
||||
# CHECK: .FR_PPC64_ADDR16_HI:
|
||||
# CHECK: 10010024: {{.*}} li 1, 4097
|
||||
# CHECK: 10010028: {{.*}} li 1, 4097
|
||||
|
||||
.section .R_PPC64_ADDR16_HA,"ax",@progbits
|
||||
.globl .FR_PPC64_ADDR16_HA
|
||||
|
@ -101,7 +112,7 @@ _start:
|
|||
|
||||
# CHECK: Disassembly of section .R_PPC64_ADDR16_HA:
|
||||
# CHECK: .FR_PPC64_ADDR16_HA:
|
||||
# CHECK: 10010028: {{.*}} li 1, 4097
|
||||
# CHECK: 1001002c: {{.*}} li 1, 4097
|
||||
|
||||
.section .R_PPC64_ADDR16_HIGHER,"ax",@progbits
|
||||
.globl .FR_PPC64_ADDR16_HIGHER
|
||||
|
@ -110,7 +121,7 @@ _start:
|
|||
|
||||
# CHECK: Disassembly of section .R_PPC64_ADDR16_HIGHER:
|
||||
# CHECK: .FR_PPC64_ADDR16_HIGHER:
|
||||
# CHECK: 1001002c: {{.*}} li 1, 0
|
||||
# CHECK: 10010030: {{.*}} li 1, 0
|
||||
|
||||
.section .R_PPC64_ADDR16_HIGHERA,"ax",@progbits
|
||||
.globl .FR_PPC64_ADDR16_HIGHERA
|
||||
|
@ -119,7 +130,7 @@ _start:
|
|||
|
||||
# CHECK: Disassembly of section .R_PPC64_ADDR16_HIGHERA:
|
||||
# CHECK: .FR_PPC64_ADDR16_HIGHERA:
|
||||
# CHECK: 10010030: {{.*}} li 1, 0
|
||||
# CHECK: 10010034: {{.*}} li 1, 0
|
||||
|
||||
.section .R_PPC64_ADDR16_HIGHEST,"ax",@progbits
|
||||
.globl .FR_PPC64_ADDR16_HIGHEST
|
||||
|
@ -128,7 +139,7 @@ _start:
|
|||
|
||||
# CHECK: Disassembly of section .R_PPC64_ADDR16_HIGHEST:
|
||||
# CHECK: .FR_PPC64_ADDR16_HIGHEST:
|
||||
# CHECK: 10010034: {{.*}} li 1, 0
|
||||
# CHECK: 10010038: {{.*}} li 1, 0
|
||||
|
||||
.section .R_PPC64_ADDR16_HIGHESTA,"ax",@progbits
|
||||
.globl .FR_PPC64_ADDR16_HIGHESTA
|
||||
|
@ -137,7 +148,7 @@ _start:
|
|||
|
||||
# CHECK: Disassembly of section .R_PPC64_ADDR16_HIGHESTA:
|
||||
# CHECK: .FR_PPC64_ADDR16_HIGHESTA:
|
||||
# CHECK: 10010038: {{.*}} li 1, 0
|
||||
# CHECK: 1001003c: {{.*}} li 1, 0
|
||||
|
||||
.section .R_PPC64_REL32, "ax",@progbits
|
||||
.globl .FR_PPC64_REL32
|
||||
|
@ -149,20 +160,20 @@ _start:
|
|||
|
||||
# DATALE: Disassembly of section .rodata:
|
||||
# DATALE: .rodata:
|
||||
# DATALE: 10000190: b4 fe 00 00
|
||||
# DATALE: 10000190: b8 fe 00 00
|
||||
|
||||
# DATABE: Disassembly of section .rodata:
|
||||
# DATABE: .rodata:
|
||||
# DATABE: 10000190: 00 00 fe b4
|
||||
# DATABE: 10000190: 00 00 fe b8
|
||||
|
||||
# Address of rodata + value stored at rodata entry
|
||||
# should equal address of LBB0_2.
|
||||
# 0x10000190 + 0xfeb4 = 0x10010044
|
||||
# CHECK: Disassembly of section .R_PPC64_REL32:
|
||||
# CHECK: .FR_PPC64_REL32:
|
||||
# CHECK: 1001003c: {{.*}} nop
|
||||
# CHECK: 10010040: {{.*}} ld 5, -32736(2)
|
||||
# CHECK: 10010044: {{.*}} add 3, 3, 4
|
||||
# CHECK: 10010040: {{.*}} nop
|
||||
# CHECK: 10010044: {{.*}} ld 5, -32736(2)
|
||||
# CHECK: 10010048: {{.*}} add 3, 3, 4
|
||||
|
||||
.section .R_PPC64_REL64, "ax",@progbits
|
||||
.globl .FR_PPC64_REL64
|
||||
|
@ -178,16 +189,16 @@ __foo:
|
|||
|
||||
# Check that address of eh_frame entry + value stored
|
||||
# should equal the address of foo. Since it is not aligned,
|
||||
# the entry is not stored exactly at 100001a8. It starts at
|
||||
# address 0x100001aa and has the value 0xfeaa.
|
||||
# 0x100001aa + 0xfeaa = 0x10010054
|
||||
# the entry is not stored exactly at 10000198. It starts at
|
||||
# address 0x1000019a and has the value 0xfeaa.
|
||||
# 0x100001aa + 0xfeae = 0x10010058
|
||||
# DATALE: Disassembly of section .eh_frame:
|
||||
# DATALE: .eh_frame:
|
||||
# DATALE: 100001a8: {{.*}} aa fe
|
||||
# DATALE: 100001a8: {{.*}} ae fe
|
||||
|
||||
# DATABE: Disassembly of section .eh_frame:
|
||||
# DATABE: .eh_frame:
|
||||
# DATABE: 100001b0: fe aa {{.*}}
|
||||
# DATABE: 100001b0: fe ae {{.*}}
|
||||
|
||||
# CHECK: __foo
|
||||
# CHECK-NEXT: 10010054: {{.*}} li 3, 0
|
||||
# CHECK-NEXT: 10010058: {{.*}} li 3, 0
|
||||
|
|
Loading…
Reference in New Issue