[LLD][ELF][AArch64] Do not use thunk for undefined weak symbol.
authorPeter Smith <peter.smith@linaro.org>
Mon, 6 Jan 2020 14:16:05 +0000 (14:16 +0000)
committerPeter Smith <peter.smith@linaro.org>
Tue, 7 Jan 2020 09:57:51 +0000 (09:57 +0000)
In AArch64 a branch to an undefined weak symbol that does not have a PLT
entry should resolve to the next instruction. The thunk generation code
can prevent this from happening as a range extension thunk can be generated
if the branch is sufficiently far away from 0, the value of an undefined
weak symbol.

The fix is taken from the Arm implementation of needsThunk(), we prevent a
thunk from being generated to an undefined weak symbol.

fixes pr44451

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

lld/ELF/Arch/AArch64.cpp
lld/test/ELF/aarch64-undefined-weak.s
lld/test/ELF/arm-undefined-weak.s

index 29c5fb5..df41a12 100644 (file)
@@ -234,6 +234,10 @@ void AArch64::writePlt(uint8_t *buf, const Symbol &sym,
 bool AArch64::needsThunk(RelExpr expr, RelType type, const InputFile *file,
                          uint64_t branchAddr, const Symbol &s,
                          int64_t a) const {
+  // If s is an undefined weak symbol and does not have a PLT entry then it
+  // will be resolved as a branch to the next instruction.
+  if (s.isUndefWeak() && !s.isInPlt())
+    return false;
   // 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.
index ee75d40..902796b 100644 (file)
@@ -1,12 +1,13 @@
 // REQUIRES: aarch64
 // RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux %s -o %t.o
-// RUN: ld.lld %t.o -o %t
+// RUN: ld.lld --image-base=0x10000000 %t.o -o %t
 // RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s
 
 // Check that the ARM 64-bit ABI rules for undefined weak symbols are applied.
 // Branch instructions are resolved to the next instruction. Undefined
 // Symbols in relative are resolved to the place so S - P + A = A.
-
+// We place the image-base at 0x10000000 to test that a range extensions thunk
+// is not generated.
  .weak target
 
  .text
@@ -24,27 +25,26 @@ _start:
  adr x0, target
 // R_AARCH64_ADR_PREL_PG_HI21
  adrp x0, target
+// R_AARCH64_LD_PREL_LO19
+ ldr x8, target
 // R_AARCH64_PREL32
  .word target - .
 // R_AARCH64_PREL64
  .xword target - .
 // R_AARCH64_PREL16
  .hword target - .
-// R_AARCH64_LD_PREL_LO19
- ldr x8, target
 
 // CHECK: Disassembly of section .text:
 // CHECK-EMPTY:
-// 2162688 = 0x210000
-// CHECK:         210120:       b       #4
-// CHECK-NEXT:    210124:       bl      #4
-// CHECK-NEXT:    210128:       b.eq    #4
-// CHECK-NEXT:    21012c:       cbz     x1, #4
-// CHECK-NEXT:    210130:       adr     x0, #0
-// CHECK-NEXT:    210134:       adrp    x0, #0
-// CHECK:         210138:       00 00 00 00 .word   0x00000000
-// CHECK-NEXT:    21013c:       00 00 00 00 .word   0x00000000
-// CHECK-NEXT:    210140:       00 00 00 00 .word   0x00000000
-// CHECK-NEXT:    210144:       00 00 .short  0x0000
-// CHECK:         $x.2:
-// CHECK-NEXT:    210146:       ldr     x8, #0
+// CHECK-NEXT: 0000000010010120 _start:
+// CHECK-NEXT: 10010120: b       #4
+// CHECK-NEXT: 10010124: bl      #4
+// CHECK-NEXT: 10010128: b.eq    #4
+// CHECK-NEXT: 1001012c: cbz     x1, #4
+// CHECK-NEXT: 10010130: adr     x0, #0
+// CHECK-NEXT: 10010134: adrp    x0, #0
+// CHECK-NEXT: 10010138: ldr     x8, #0
+// 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
index 18805ab..2d47263 100644 (file)
@@ -1,11 +1,13 @@
 // REQUIRES: arm
-// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
-// RUN: ld.lld %t -o %t2
-// RUN: llvm-objdump -triple=armv7a-none-linux-gnueabi -d %t2 | FileCheck %s
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
+// RUN: ld.lld --image-base=0x10000000 %t -o %t2
+// RUN: llvm-objdump -triple=armv7a-none-linux-gnueabi --no-show-raw-insn -d %t2 | FileCheck %s
 
 // Check that the ARM ABI rules for undefined weak symbols are applied.
 // Branch instructions are resolved to the next instruction. Undefined
 // Symbols in relative are resolved to the place so S - P + A = A.
+// We place the image-base at 0x10000000 to test that a range extensions thunk
+// is not generated.
 
  .syntax unified
 
@@ -29,11 +31,10 @@ _start:
 
 // CHECK: Disassembly of section .text:
 // CHECK-EMPTY:
-// CHECK:         110b4: {{.*}} b       #-4 <_start+0x4>
-// CHECK-NEXT:    110b8: {{.*}} bl      #-4 <_start+0x8>
-// blx is transformed into bl so we don't change state
-// CHECK-NEXT:    110bc: {{.*}} bl      #-4 <_start+0xc>
-// CHECK-NEXT:    110c0: {{.*}} movt    r0, #0
-// CHECK-NEXT:    110c4: {{.*}} movw    r0, #0
-// CHECK:         110c8: {{.*}} .word   0x00000000
-
+// CHECK-NEXT: 100010b4 _start:
+// CHECK-NEXT: 100010b4: b       #-4
+// CHECK-NEXT: 100010b8: bl      #-4
+// CHECK-NEXT: 100010bc: bl      #-4
+// CHECK-NEXT: 100010c0: movt    r0, #0
+// CHECK-NEXT: 100010c4: movw    r0, #0
+// CHECK:      100010c8: 00 00 00 00     .word   0x00000000