[lld] 723b5a1 - [lld][ELF][AArch64] Handle R_AARCH64_PLT32 relocation

Leonard Chan via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 23 16:10:26 PDT 2020


Author: Leonard Chan
Date: 2020-06-23T16:10:07-07:00
New Revision: 723b5a1785426245e3c56b4666ef526b32be84a9

URL: https://github.com/llvm/llvm-project/commit/723b5a1785426245e3c56b4666ef526b32be84a9
DIFF: https://github.com/llvm/llvm-project/commit/723b5a1785426245e3c56b4666ef526b32be84a9.diff

LOG: [lld][ELF][AArch64] Handle R_AARCH64_PLT32 relocation

This is the followup to D77647 which implements handling for the new
R_AARCH64_PLT32 relocation type in lld. This relocation would benefit the
PIC-friendly vtables feature described in D72959.

Differential Revision: https://reviews.llvm.org/D81184

Added: 
    lld/test/ELF/aarch64-range-thunk-extension-plt32.s
    lld/test/ELF/aarch64-reloc-plt32.s

Modified: 
    lld/ELF/Arch/AArch64.cpp
    lld/ELF/InputSection.cpp
    lld/ELF/Thunks.cpp
    lld/test/ELF/aarch64-undefined-weak.s

Removed: 
    


################################################################################
diff  --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp
index 704ef1a84012..637046e90bbd 100644
--- a/lld/ELF/Arch/AArch64.cpp
+++ b/lld/ELF/Arch/AArch64.cpp
@@ -126,6 +126,7 @@ RelExpr AArch64::getRelExpr(RelType type, const Symbol &s,
   case R_AARCH64_CONDBR19:
   case R_AARCH64_JUMP26:
   case R_AARCH64_TSTBR14:
+  case R_AARCH64_PLT32:
     return R_PLT_PC;
   case R_AARCH64_PREL16:
   case R_AARCH64_PREL32:
@@ -244,7 +245,8 @@ bool AArch64::needsThunk(RelExpr expr, RelType type, const InputFile *file,
   // ELF for the ARM 64-bit architecture, section Call and Jump relocations
   // only permits range extension thunks for R_AARCH64_CALL26 and
   // R_AARCH64_JUMP26 relocation types.
-  if (type != R_AARCH64_CALL26 && type != R_AARCH64_JUMP26)
+  if (type != R_AARCH64_CALL26 && type != R_AARCH64_JUMP26 &&
+      type != R_AARCH64_PLT32)
     return false;
   uint64_t dst = expr == R_PLT_PC ? s.getPltVA() : s.getVA(a);
   return !inBranchRange(type, branchAddr, dst);
@@ -258,11 +260,13 @@ uint32_t AArch64::getThunkSectionSpacing() const {
 }
 
 bool AArch64::inBranchRange(RelType type, uint64_t src, uint64_t dst) const {
-  if (type != R_AARCH64_CALL26 && type != R_AARCH64_JUMP26)
+  if (type != R_AARCH64_CALL26 && type != R_AARCH64_JUMP26 &&
+      type != R_AARCH64_PLT32)
     return true;
   // The AArch64 call and unconditional branch instructions have a range of
-  // +/- 128 MiB.
-  uint64_t range = 128 * 1024 * 1024;
+  // +/- 128 MiB. The PLT32 relocation supports a range up to +/- 2 GiB.
+  uint64_t range =
+      type == R_AARCH64_PLT32 ? (UINT64_C(1) << 31) : (128 * 1024 * 1024);
   if (dst > src) {
     // Immediate of branch is signed.
     range -= 4;
@@ -325,6 +329,10 @@ void AArch64::relocate(uint8_t *loc, const Relocation &rel,
     checkIntUInt(loc, val, 32, rel);
     write32le(loc, val);
     break;
+  case R_AARCH64_PLT32:
+    checkInt(loc, val, 32, rel);
+    write32le(loc, val);
+    break;
   case R_AARCH64_ABS64:
   case R_AARCH64_PREL64:
     write64le(loc, val);

diff  --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index d439db0039db..33bad9fbb0ef 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -556,6 +556,7 @@ static uint64_t getAArch64UndefinedRelativeWeakVA(uint64_t type, uint64_t a,
   case R_AARCH64_PREL64:
   case R_AARCH64_ADR_PREL_LO21:
   case R_AARCH64_LD_PREL_LO19:
+  case R_AARCH64_PLT32:
     return p + a;
   }
   llvm_unreachable("AArch64 pc-relative relocation expected\n");

diff  --git a/lld/ELF/Thunks.cpp b/lld/ELF/Thunks.cpp
index 6f0d16ae6796..744ceaf725cf 100644
--- a/lld/ELF/Thunks.cpp
+++ b/lld/ELF/Thunks.cpp
@@ -838,7 +838,8 @@ Thunk::Thunk(Symbol &d, int64_t a) : destination(d), addend(a), offset(0) {}
 Thunk::~Thunk() = default;
 
 static Thunk *addThunkAArch64(RelType type, Symbol &s, int64_t a) {
-  if (type != R_AARCH64_CALL26 && type != R_AARCH64_JUMP26)
+  if (type != R_AARCH64_CALL26 && type != R_AARCH64_JUMP26 &&
+      type != R_AARCH64_PLT32)
     fatal("unrecognized relocation type");
   if (config->picThunk)
     return make<AArch64ADRPThunk>(s, a);

diff  --git a/lld/test/ELF/aarch64-range-thunk-extension-plt32.s b/lld/test/ELF/aarch64-range-thunk-extension-plt32.s
new file mode 100644
index 000000000000..20b497fcb67e
--- /dev/null
+++ b/lld/test/ELF/aarch64-range-thunk-extension-plt32.s
@@ -0,0 +1,36 @@
+// REQUIRES: aarch64
+// RUN: llvm-mc -filetype=obj -triple=aarch64 %s -o %t.o
+// RUN: echo 'SECTIONS { \
+// RUN:         .text.1 0x10000 : { *(.text.1) } \
+// RUN:         .text.2 0x200000000 : AT(0x20000) { *(.text.2) } \
+// RUN:       } ' > %t.script
+// RUN: ld.lld --script %t.script %t.o -o %t
+// RUN: llvm-objdump -d --no-show-raw-insn --print-imm-hex %t | FileCheck %s
+
+// The word should be an offset to the range extension thunk.
+// CHECK-LABEL: <_start>:
+// CHECK-NEXT:    10000:       04 00 00 00     .word   0x00000004
+
+// The thunk redirects to the address of callee.
+// CHECK-LABEL: <__AArch64AbsLongThunk_callee>:
+// CHECK-NEXT:    10004:       ldr     x16, 0x1000c <$d>
+// CHECK-NEXT:    10008:       br      x16
+
+// CHECK-LABEL: <$d>:
+// CHECK-NEXT:    1000c:       00 00 00 00     .word   0x00000000
+// CHECK-NEXT:    10010:       02 00 00 00     .word   0x00000002
+
+// CHECK-LABEL: <callee>:
+// CHECK-NEXT:    200000000:      ret
+
+  .section .text.1, "ax", %progbits
+  .global _start
+  .type _start, %function
+_start:
+  .word callee at PLT - .
+
+  .section .text.2, "ax", %progbits
+  .global callee
+  .type callee, %function
+callee:
+  ret

diff  --git a/lld/test/ELF/aarch64-reloc-plt32.s b/lld/test/ELF/aarch64-reloc-plt32.s
new file mode 100644
index 000000000000..a7467562b2db
--- /dev/null
+++ b/lld/test/ELF/aarch64-reloc-plt32.s
@@ -0,0 +1,32 @@
+// REQUIRES: aarch64
+// RUN: llvm-mc -filetype=obj -triple=aarch64 %s -o %t.o
+// RUN: llvm-mc -filetype=obj -triple=aarch64 %S/Inputs/abs255.s -o %t255.o
+// RUN: llvm-mc -filetype=obj -triple=aarch64 %S/Inputs/abs256.s -o %t256.o
+// RUN: llvm-mc -filetype=obj -triple=aarch64 %S/Inputs/abs257.s -o %t257.o
+
+/// Check for overflow with a R_AACH64_PLT32 relocation.
+
+// RUN: ld.lld -z max-page-size=4096 %t.o %t256.o -o %t2
+// RUN: llvm-objdump -s --section=.data %t2 | FileCheck %s
+
+// CHECK: Contents of section .data:
+/// 202158: S = 0x100, A = 0x80202057, P = 0x202158
+///         S + A - P = 0xffffff7f
+/// 20215c: S = 0x100, A = -0x7fdfdfa4, P = 0x20215c
+///         S + A - P = 0x80000000
+/// 202160: S = 0x100, A = 0, P = 0x202160
+///         S + A - P = 0xffdfdfa0
+// CHECK-NEXT: 202158 ffffff7f 00000080 a0dfdfff
+
+// RUN: not ld.lld -z max-page-size=4096 %t.o %t255.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=OVERFLOW1
+// OVERFLOW1: relocation R_AARCH64_PLT32 out of range: -2147483649 is not in [-2147483648, 2147483647]; references foo
+
+// RUN: not ld.lld -z max-page-size=4096 %t.o %t257.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=OVERFLOW2
+// OVERFLOW2: relocation R_AARCH64_PLT32 out of range: 2147483648 is not in [-2147483648, 2147483647]; references foo
+
+  .globl _start
+  _start:
+.data
+  .word foo at PLT - . + 2149589079
+  .word foo at PLT - . - 2145378212
+  .word foo at PLT - .

diff  --git a/lld/test/ELF/aarch64-undefined-weak.s b/lld/test/ELF/aarch64-undefined-weak.s
index 839dd8d14d61..9a4b7c23aa7a 100644
--- a/lld/test/ELF/aarch64-undefined-weak.s
+++ b/lld/test/ELF/aarch64-undefined-weak.s
@@ -33,6 +33,8 @@ _start:
  .xword target - .
 // R_AARCH64_PREL16
  .hword target - .
+// R_AARCH64_PLT32
+ .word target at PLT - .
 
 // CHECK: Disassembly of section .text:
 // CHECK-EMPTY:
@@ -47,4 +49,5 @@ _start:
 // CHECK:      1001013c: 00 00 00 00     .word   0x00000000
 // CHECK-NEXT: 10010140: 00 00 00 00     .word   0x00000000
 // CHECK-NEXT: 10010144: 00 00 00 00     .word   0x00000000
-// CHECK-NEXT: 10010148: 00 00           .short  0x0000
+// CHECK-NEXT: 10010148: 00 00 00 00     .word   0x00000000
+// CHECK-NEXT: 1001014c: 00 00           .short  0x0000


        


More information about the llvm-commits mailing list