[lld] r348255 - [PPC][PPC64] PPC_REL14 and PPC64_REL14 relocations

Martell Malone via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 4 04:26:21 PST 2018


Author: martell
Date: Tue Dec  4 04:26:21 2018
New Revision: 348255

URL: http://llvm.org/viewvc/llvm-project?rev=348255&view=rev
Log:
[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

Modified:
    lld/trunk/ELF/Arch/PPC.cpp
    lld/trunk/ELF/Arch/PPC64.cpp
    lld/trunk/test/ELF/ppc-relocs.s
    lld/trunk/test/ELF/ppc64-relocs.s

Modified: lld/trunk/ELF/Arch/PPC.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Arch/PPC.cpp?rev=348255&r1=348254&r2=348255&view=diff
==============================================================================
--- lld/trunk/ELF/Arch/PPC.cpp (original)
+++ lld/trunk/ELF/Arch/PPC.cpp Tue Dec  4 04:26:21 2018
@@ -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, RelT
   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));

Modified: lld/trunk/ELF/Arch/PPC64.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Arch/PPC64.cpp?rev=348255&r1=348254&r2=348255&view=diff
==============================================================================
--- lld/trunk/ELF/Arch/PPC64.cpp (original)
+++ lld/trunk/ELF/Arch/PPC64.cpp Tue Dec  4 04:26:21 2018
@@ -421,6 +421,7 @@ RelExpr PPC64::getRelExpr(RelType Type,
     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, Re
   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, Re
 
 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, Rel
 }
 
 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,

Modified: lld/trunk/test/ELF/ppc-relocs.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/ppc-relocs.s?rev=348255&r1=348254&r2=348255&view=diff
==============================================================================
--- lld/trunk/test/ELF/ppc-relocs.s (original)
+++ lld/trunk/test/ELF/ppc-relocs.s Tue Dec  4 04:26:21 2018
@@ -55,6 +55,17 @@ mystr:
 # CHECK: .FR_PPC_REL24:
 # CHECK:    1101c:       48 00 00 04     b .+4
 
+.section .R_PPC_REL14,"ax", at progbits
+.globl .FR_PPC_REL14
+.FR_PPC_REL14:
+  beq .Lfooy
+.section .R_PPC_REL14_2,"ax", at progbits
+.Lfooy:
+
+# CHECK: Disassembly of section .R_PPC_REL14:
+# CHECK: .FR_PPC_REL14:
+# CHECK:    11020: {{.*}} bt 2, .+4
+
 .section .R_PPC_REL32,"ax", at 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", at 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", at 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

Modified: lld/trunk/test/ELF/ppc64-relocs.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/ppc64-relocs.s?rev=348255&r1=348254&r2=348255&view=diff
==============================================================================
--- lld/trunk/test/ELF/ppc64-relocs.s (original)
+++ lld/trunk/test/ELF/ppc64-relocs.s Tue Dec  4 04:26:21 2018
@@ -76,6 +76,17 @@ _start:
 # CHECK: .FR_PPC64_REL24:
 # CHECK: 1001001c: {{.*}} b .+4
 
+.section .R_PPC64_REL14,"ax", at progbits
+.globl .FR_PPC64_REL14
+.FR_PPC64_REL14:
+  beq .Lfooy
+.section .R_PPC64_REL14_2,"ax", at progbits
+.Lfooy:
+
+# CHECK: Disassembly of section .R_PPC64_REL14:
+# CHECK: .FR_PPC64_REL14:
+# CHECK: 10010020: {{.*}} bt 2, .+4
+
 .section .R_PPC64_ADDR16_LO,"ax", at 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", at 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", at 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", at 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", at 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", at 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", at 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", at 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", at 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




More information about the llvm-commits mailing list