From aa6086a64c8c5bfaf67891c1a974532a206ac304 Mon Sep 17 00:00:00 2001 From: Martell Malone Date: Tue, 4 Dec 2018 12:26:21 +0000 Subject: [PATCH] [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 --- lld/ELF/Arch/PPC.cpp | 4 ++++ lld/ELF/Arch/PPC64.cpp | 19 ++++++++++++++---- lld/test/ELF/ppc-relocs.s | 17 +++++++++++++--- lld/test/ELF/ppc64-relocs.s | 47 ++++++++++++++++++++++++++++----------------- 4 files changed, 62 insertions(+), 25 deletions(-) diff --git a/lld/ELF/Arch/PPC.cpp b/lld/ELF/Arch/PPC.cpp index a01068c..7673780 100644 --- a/lld/ELF/Arch/PPC.cpp +++ b/lld/ELF/Arch/PPC.cpp @@ -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)); diff --git a/lld/ELF/Arch/PPC64.cpp b/lld/ELF/Arch/PPC64.cpp index 6562eeb..747c873 100644 --- a/lld/ELF/Arch/PPC64.cpp +++ b/lld/ELF/Arch/PPC64.cpp @@ -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, diff --git a/lld/test/ELF/ppc-relocs.s b/lld/test/ELF/ppc-relocs.s index 2681000..40536b6 100644 --- a/lld/test/ELF/ppc-relocs.s +++ b/lld/test/ELF/ppc-relocs.s @@ -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 diff --git a/lld/test/ELF/ppc64-relocs.s b/lld/test/ELF/ppc64-relocs.s index 725f3c6..b439c44 100644 --- a/lld/test/ELF/ppc64-relocs.s +++ b/lld/test/ELF/ppc64-relocs.s @@ -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 -- 2.7.4