[lld] 051c4d5 - [LLD][ELF][AArch64] Do not use thunk for undefined weak symbol.
Peter Smith via llvm-commits
llvm-commits at lists.llvm.org
Tue Jan 7 01:59:02 PST 2020
Author: Peter Smith
Date: 2020-01-07T09:57:51Z
New Revision: 051c4d5b7bcfb0c1feb69f4701086ac725322527
URL: https://github.com/llvm/llvm-project/commit/051c4d5b7bcfb0c1feb69f4701086ac725322527
DIFF: https://github.com/llvm/llvm-project/commit/051c4d5b7bcfb0c1feb69f4701086ac725322527.diff
LOG: [LLD][ELF][AArch64] Do not use thunk for undefined weak symbol.
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
Added:
Modified:
lld/ELF/Arch/AArch64.cpp
lld/test/ELF/aarch64-undefined-weak.s
lld/test/ELF/arm-undefined-weak.s
Removed:
################################################################################
diff --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp
index 29c5fb58c348..df41a12f7454 100644
--- a/lld/ELF/Arch/AArch64.cpp
+++ b/lld/ELF/Arch/AArch64.cpp
@@ -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.
diff --git a/lld/test/ELF/aarch64-undefined-weak.s b/lld/test/ELF/aarch64-undefined-weak.s
index ee75d40dd9ac..902796b73880 100644
--- a/lld/test/ELF/aarch64-undefined-weak.s
+++ b/lld/test/ELF/aarch64-undefined-weak.s
@@ -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
diff --git a/lld/test/ELF/arm-undefined-weak.s b/lld/test/ELF/arm-undefined-weak.s
index 18805ab327c8..2d4726358095 100644
--- a/lld/test/ELF/arm-undefined-weak.s
+++ b/lld/test/ELF/arm-undefined-weak.s
@@ -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
More information about the llvm-commits
mailing list