[lld] r340159 - [ELF] Add support for older Arm Architectures with smaller branch range
Peter Smith via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 20 02:19:31 PDT 2018
Author: psmith
Date: Mon Aug 20 02:19:30 2018
New Revision: 340159
URL: http://llvm.org/viewvc/llvm-project?rev=340159&view=rev
Log:
[ELF] Add support for older Arm Architectures with smaller branch range
The Thumb BL and BLX instructions on older Arm Architectures such as v5 and
v6 have a constrained encoding J1 and J2 must equal 1, later Architectures
relaxed this restriction allowing J1 and J2 to be used to calculate a larger
immediate.
This patch adds support for the old encoding, it is used when the build
attributes for the input objects only contain older architectures.
Differential Revision: https://reviews.llvm.org/D50076
Added:
lld/trunk/test/ELF/arm-bl-v6-inrange.s
Modified:
lld/trunk/ELF/Arch/ARM.cpp
lld/trunk/ELF/Driver.cpp
lld/trunk/test/ELF/arm-bl-v6.s
lld/trunk/test/ELF/arm-blx-v4t.s
lld/trunk/test/ELF/arm-thumb-branch.s
lld/trunk/test/ELF/arm-thumb-condbranch-thunk.s
lld/trunk/test/ELF/arm-thumb-mix-range-thunk-os.s
lld/trunk/test/ELF/arm-thumb-plt-range-thunk-os.s
lld/trunk/test/ELF/arm-thumb-range-thunk-os.s
lld/trunk/test/ELF/arm-thumb-thunk-empty-pass.s
lld/trunk/test/ELF/arm-thunk-largesection.s
lld/trunk/test/ELF/arm-thunk-linkerscript-large.s
lld/trunk/test/ELF/arm-thunk-linkerscript-sort.s
lld/trunk/test/ELF/arm-thunk-multipass.s
Modified: lld/trunk/ELF/Arch/ARM.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Arch/ARM.cpp?rev=340159&r1=340158&r2=340159&view=diff
==============================================================================
--- lld/trunk/ELF/Arch/ARM.cpp (original)
+++ lld/trunk/ELF/Arch/ARM.cpp Mon Aug 20 02:19:30 2018
@@ -342,7 +342,7 @@ bool ARM::inBranchRange(RelType Type, ui
break;
case R_ARM_THM_JUMP24:
case R_ARM_THM_CALL:
- Range = 0x1000000;
+ Range = Config->ARMJ1J2BranchEncoding ? 0x1000000 : 0x400000;
InstrSize = 2;
break;
default:
@@ -447,11 +447,23 @@ void ARM::relocateOne(uint8_t *Loc, RelT
}
// Bit 12 is 0 for BLX, 1 for BL
write16le(Loc + 2, (read16le(Loc + 2) & ~0x1000) | (Val & 1) << 12);
+ if (!Config->ARMJ1J2BranchEncoding) {
+ // Older Arm architectures do not support R_ARM_THM_JUMP24 and have
+ // different encoding rules and range due to J1 and J2 always being 1.
+ checkInt(Loc, Val, 23, Type);
+ write16le(Loc,
+ 0xf000 | // opcode
+ ((Val >> 12) & 0x07ff)); // imm11
+ write16le(Loc + 2,
+ (read16le(Loc + 2) & 0xd000) | // opcode
+ 0x2800 | // J1 == J2 == 1
+ ((Val >> 1) & 0x07ff)); // imm11
+ break;
+ }
// Fall through as rest of encoding is the same as B.W
LLVM_FALLTHROUGH;
case R_ARM_THM_JUMP24:
// Encoding B T4, BL T1, BLX T2: Val = S:I1:I2:imm10:imm11:0
- // FIXME: Use of I1 and I2 require v6T2ops
checkInt(Loc, Val, 25, Type);
write16le(Loc,
0xf000 | // opcode
@@ -542,10 +554,19 @@ int64_t ARM::getImplicitAddend(const uin
((Lo & 0x07ff) << 1)); // imm11:0
}
case R_ARM_THM_CALL:
+ if (!Config->ARMJ1J2BranchEncoding) {
+ // Older Arm architectures do not support R_ARM_THM_JUMP24 and have
+ // different encoding rules and range due to J1 and J2 always being 1.
+ uint16_t Hi = read16le(Buf);
+ uint16_t Lo = read16le(Buf + 2);
+ return SignExtend64<22>(((Hi & 0x7ff) << 12) | // imm11
+ ((Lo & 0x7ff) << 1)); // imm11:0
+ break;
+ }
+ LLVM_FALLTHROUGH;
case R_ARM_THM_JUMP24: {
// Encoding B T4, BL T1, BLX T2: A = S:I1:I2:imm10:imm11:0
// I1 = NOT(J1 EOR S), I2 = NOT(J2 EOR S)
- // FIXME: I1 and I2 require v6T2ops
uint16_t Hi = read16le(Buf);
uint16_t Lo = read16le(Buf + 2);
return SignExtend64<24>(((Hi & 0x0400) << 14) | // S
Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=340159&r1=340158&r2=340159&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Mon Aug 20 02:19:30 2018
@@ -1504,9 +1504,6 @@ template <class ELFT> void LinkerDriver:
if (Config->ARMHasBlx == false)
warn("lld uses blx instruction, no object with architecture supporting "
"feature detected.");
- if (Config->ARMJ1J2BranchEncoding == false)
- warn("lld uses extended branch encoding, no object with architecture "
- "supporting feature detected.");
if (Config->ARMHasMovtMovw == false)
warn("lld may use movt/movw, no object with architecture supporting "
"feature detected.");
Added: lld/trunk/test/ELF/arm-bl-v6-inrange.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-bl-v6-inrange.s?rev=340159&view=auto
==============================================================================
--- lld/trunk/test/ELF/arm-bl-v6-inrange.s (added)
+++ lld/trunk/test/ELF/arm-bl-v6-inrange.s Mon Aug 20 02:19:30 2018
@@ -0,0 +1,47 @@
+// REQUIRES: arm
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv6-none-linux-gnueabi %s -o %t
+// RUN: echo "SECTIONS { \
+// RUN: .callee1 0x100004 : { *(.callee_low) } \
+// RUN: .caller 0x500000 : { *(.text) } \
+// RUN: .callee2 0x900004 : { *(.callee_high) } } " > %t.script
+// RUN: ld.lld %t --script %t.script -o %t2 2>&1
+// RUN: llvm-objdump -d -triple=thumbv6-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-THUMB %s
+// RUN: llvm-objdump -d -triple=armv6-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-ARM %s
+
+// On older Arm Architectures such as v5 and v6 the Thumb BL and BLX relocation
+// uses a slightly different encoding that has a lower range. These relocations
+// are at the extreme range of what is permitted.
+ .thumb
+ .text
+ .syntax unified
+ .cpu arm1176jzf-s
+ .globl _start
+ .type _start,%function
+_start:
+ bl thumbfunc
+ bl armfunc
+ bx lr
+
+ .section .callee_low, "ax", %progbits
+ .globl thumbfunc
+ .type thumbfunc, %function
+thumbfunc:
+ bx lr
+// CHECK-THUMB: Disassembly of section .callee1:
+// CHECK-THUMB-NEXT: thumbfunc:
+// CHECK-THUMB-NEXT: 100004: 70 47 bx lr
+// CHECK-THUMB-NEXT: Disassembly of section .caller:
+// CHECK-THUMB-NEXT: _start:
+// CHECK-THUMB-NEXT: 500000: 00 f4 00 f8 bl #-4194304
+// CHECK-THUMB-NEXT: 500004: ff f3 fe ef blx #4194300
+// CHECK-THUMB-NEXT: 500008: 70 47 bx lr
+
+ .arm
+ .section .callee_high, "ax", %progbits
+ .globl armfunc
+ .type armfunc, %function
+armfunc:
+ bx lr
+// CHECK-ARM: Disassembly of section .callee2:
+// CHECK-ARM-NEXT: armfunc:
+// CHECK-ARM-NEXT: 900004: 1e ff 2f e1 bx lr
Modified: lld/trunk/test/ELF/arm-bl-v6.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-bl-v6.s?rev=340159&r1=340158&r2=340159&view=diff
==============================================================================
--- lld/trunk/test/ELF/arm-bl-v6.s (original)
+++ lld/trunk/test/ELF/arm-bl-v6.s Mon Aug 20 02:19:30 2018
@@ -1,5 +1,5 @@
// REQUIRES: arm
-// RUN: llvm-mc -filetype=obj -triple=arm-none-linux-gnueabi %s -o %t
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv6-none-linux-gnueabi %s -o %t
// RUN: ld.lld %t -o /dev/null 2>&1 | FileCheck %s
// On Arm v6 the range of a Thumb BL instruction is only 4 megabytes as the
@@ -9,14 +9,12 @@
// use these instructions either. At present we don't support v6 so we give a
// warning for unsupported features.
-// CHECK: warning: lld uses extended branch encoding, no object with architecture supporting feature detected.
-// CHECK-NEXT: warning: lld may use movt/movw, no object with architecture supporting feature detected.
+// CHECK: warning: lld may use movt/movw, no object with architecture supporting feature detected.
// ARM v6 supports blx so we shouldn't see the blx not supported warning.
// CHECK-NOT: warning: lld uses blx instruction, no object with architecture supporting feature detected.
.text
.syntax unified
.cpu arm1176jzf-s
- .eabi_attribute 6, 6 @ Tag_CPU_arch
.globl _start
.type _start,%function
.balign 0x1000
Modified: lld/trunk/test/ELF/arm-blx-v4t.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-blx-v4t.s?rev=340159&r1=340158&r2=340159&view=diff
==============================================================================
--- lld/trunk/test/ELF/arm-blx-v4t.s (original)
+++ lld/trunk/test/ELF/arm-blx-v4t.s Mon Aug 20 02:19:30 2018
@@ -1,5 +1,5 @@
// REQUIRES: arm
-// RUN: llvm-mc -filetype=obj -triple=arm-none-linux-gnueabi %s -o %t
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=arm-none-linux-gnueabi %s -o %t
// RUN: ld.lld %t -o /dev/null 2>&1 | FileCheck %s
// On Arm v4t there is no blx instruction so all interworking must go via
@@ -7,13 +7,11 @@
// features.
// CHECK: warning: lld uses blx instruction, no object with architecture supporting feature detected.
-// CHECK-NEXT: warning: lld uses extended branch encoding, no object with architecture supporting feature detected.
// CHECK-NEXT: warning: lld may use movt/movw, no object with architecture supporting feature detected.
.text
.syntax unified
.cpu arm7tdmi
- .eabi_attribute 6, 2 @ Tag_CPU_arch
.arm
.globl _start
.type _start,%function
Modified: lld/trunk/test/ELF/arm-thumb-branch.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-thumb-branch.s?rev=340159&r1=340158&r2=340159&view=diff
==============================================================================
--- lld/trunk/test/ELF/arm-thumb-branch.s (original)
+++ lld/trunk/test/ELF/arm-thumb-branch.s Mon Aug 20 02:19:30 2018
@@ -1,6 +1,6 @@
// REQUIRES: arm
-// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
-// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %S/Inputs/far-arm-thumb-abs.s -o %tfar
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %S/Inputs/far-arm-thumb-abs.s -o %tfar
// RUN: echo "SECTIONS { \
// RUN: . = 0xb4; \
// RUN: .callee1 : { *(.callee_low) } \
Modified: lld/trunk/test/ELF/arm-thumb-condbranch-thunk.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-thumb-condbranch-thunk.s?rev=340159&r1=340158&r2=340159&view=diff
==============================================================================
--- lld/trunk/test/ELF/arm-thumb-condbranch-thunk.s (original)
+++ lld/trunk/test/ELF/arm-thumb-condbranch-thunk.s Mon Aug 20 02:19:30 2018
@@ -1,5 +1,5 @@
// REQUIRES: arm
-// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
// RUN: ld.lld %t -o %t2 2>&1
// The output file is large, most of it zeroes. We dissassemble only the
// parts we need to speed up the test and avoid a large output file
Modified: lld/trunk/test/ELF/arm-thumb-mix-range-thunk-os.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-thumb-mix-range-thunk-os.s?rev=340159&r1=340158&r2=340159&view=diff
==============================================================================
--- lld/trunk/test/ELF/arm-thumb-mix-range-thunk-os.s (original)
+++ lld/trunk/test/ELF/arm-thumb-mix-range-thunk-os.s Mon Aug 20 02:19:30 2018
@@ -1,5 +1,5 @@
// REQUIRES: arm
-// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
// RUN: ld.lld %t -o %t2 2>&1
// The output file is large, most of it zeroes. We dissassemble only the
// parts we need to speed up the test and avoid a large output file
Modified: lld/trunk/test/ELF/arm-thumb-plt-range-thunk-os.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-thumb-plt-range-thunk-os.s?rev=340159&r1=340158&r2=340159&view=diff
==============================================================================
--- lld/trunk/test/ELF/arm-thumb-plt-range-thunk-os.s (original)
+++ lld/trunk/test/ELF/arm-thumb-plt-range-thunk-os.s Mon Aug 20 02:19:30 2018
@@ -1,5 +1,5 @@
// REQUIRES: arm
-// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
// RUN: ld.lld %t --shared --icf=all -o %t.so
// The output file is large, most of it zeroes. We dissassemble only the
// parts we need to speed up the test and avoid a large output file
Modified: lld/trunk/test/ELF/arm-thumb-range-thunk-os.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-thumb-range-thunk-os.s?rev=340159&r1=340158&r2=340159&view=diff
==============================================================================
--- lld/trunk/test/ELF/arm-thumb-range-thunk-os.s (original)
+++ lld/trunk/test/ELF/arm-thumb-range-thunk-os.s Mon Aug 20 02:19:30 2018
@@ -1,5 +1,5 @@
// REQUIRES: arm
-// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
// RUN: ld.lld %t -o %t2 2>&1
// The output file is large, most of it zeroes. We dissassemble only the
// parts we need to speed up the test and avoid a large output file
Modified: lld/trunk/test/ELF/arm-thumb-thunk-empty-pass.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-thumb-thunk-empty-pass.s?rev=340159&r1=340158&r2=340159&view=diff
==============================================================================
--- lld/trunk/test/ELF/arm-thumb-thunk-empty-pass.s (original)
+++ lld/trunk/test/ELF/arm-thumb-thunk-empty-pass.s Mon Aug 20 02:19:30 2018
@@ -1,5 +1,5 @@
// REQUIRES: arm
-// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
// RUN: ld.lld %t -o %t2 2>&1
// RUN: llvm-objdump -d %t2 -start-address=69632 -stop-address=69646 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK1 %s
// RUN: llvm-objdump -d %t2 -start-address=16846856 -stop-address=16846874 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK2 %s
Modified: lld/trunk/test/ELF/arm-thunk-largesection.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-thunk-largesection.s?rev=340159&r1=340158&r2=340159&view=diff
==============================================================================
--- lld/trunk/test/ELF/arm-thunk-largesection.s (original)
+++ lld/trunk/test/ELF/arm-thunk-largesection.s Mon Aug 20 02:19:30 2018
@@ -1,5 +1,5 @@
// REQUIRES: arm
-// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
// RUN: ld.lld %t -o %t2 2>&1
// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi -start-address=69632 -stop-address=69636 %t2 | FileCheck -check-prefix=CHECK1 %s
// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi -start-address=73732 -stop-address=73742 %t2 | FileCheck -check-prefix=CHECK2 %s
Modified: lld/trunk/test/ELF/arm-thunk-linkerscript-large.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-thunk-linkerscript-large.s?rev=340159&r1=340158&r2=340159&view=diff
==============================================================================
--- lld/trunk/test/ELF/arm-thunk-linkerscript-large.s (original)
+++ lld/trunk/test/ELF/arm-thunk-linkerscript-large.s Mon Aug 20 02:19:30 2018
@@ -1,5 +1,5 @@
// REQUIRES: arm
-// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
// RUN: echo "SECTIONS { \
// RUN: .text 0x100000 : { *(.text) } \
// RUN: .textl : { *(.text_l0*) *(.text_l1*) *(.text_l2*) *(.text_l3*) } \
@@ -21,7 +21,8 @@
// per OutputSection basis
.syntax unified
-// Define a function that we can match with .text_l* aligned on a megabyte // boundary
+// Define a function that we can match with .text_l* aligned on a megabyte
+// boundary
.macro FUNCTIONL suff
.section .text_l\suff\(), "ax", %progbits
.thumb
Modified: lld/trunk/test/ELF/arm-thunk-linkerscript-sort.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-thunk-linkerscript-sort.s?rev=340159&r1=340158&r2=340159&view=diff
==============================================================================
--- lld/trunk/test/ELF/arm-thunk-linkerscript-sort.s (original)
+++ lld/trunk/test/ELF/arm-thunk-linkerscript-sort.s Mon Aug 20 02:19:30 2018
@@ -1,5 +1,5 @@
// REQUIRES: arm
-// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
// RUN: echo "SECTIONS { \
// RUN: .text 0x100000 : { *(SORT_BY_NAME(.text.*)) } \
// RUN: }" > %t.script
Modified: lld/trunk/test/ELF/arm-thunk-multipass.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-thunk-multipass.s?rev=340159&r1=340158&r2=340159&view=diff
==============================================================================
--- lld/trunk/test/ELF/arm-thunk-multipass.s (original)
+++ lld/trunk/test/ELF/arm-thunk-multipass.s Mon Aug 20 02:19:30 2018
@@ -1,5 +1,5 @@
// REQUIRES: arm
-// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
// RUN: ld.lld %t -o %t2 2>&1
// The output file is large, most of it zeroes. We dissassemble only the
// parts we need to speed up the test and avoid a large output file
More information about the llvm-commits
mailing list