-
Notifications
You must be signed in to change notification settings - Fork 12.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[ELF][AArch64] Add support for AArch64 range thunks.
The AArch64 unconditional branch and branch and link instructions have a maximum range of 128 Mib. This is usually enough for most programs but there are cases when it isn't enough. This change adds support for range extension thunks to AArch64. For pc-relative thunks we follow the small code model and use ADRP, ADD, BR. This has a limit of 4 gigabytes. Differential Revision: https://reviews.llvm.org/D39744 llvm-svn: 319307
- Loading branch information
Showing
9 changed files
with
330 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| // RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %S/Inputs/abs.s -o %tabs | ||
| // RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %s -o %t | ||
| // RUN: ld.lld %t %tabs -o %t2 2>&1 | ||
| // RUN: llvm-objdump -d -triple=aarch64-pc-freebsd %t2 | FileCheck %s | ||
| // REQUIRES: aarch64 | ||
|
|
||
| .text | ||
| .globl _start | ||
| _start: | ||
| bl big | ||
|
|
||
| // CHECK: Disassembly of section .text: | ||
| // CHECK-NEXT: _start: | ||
| // CHECK-NEXT: 20000: 02 00 00 94 bl #8 | ||
| // CHECK: __AArch64AbsLongThunk_big: | ||
| // CHECK-NEXT: 20008: 50 00 00 58 ldr x16, #8 | ||
| // CHECK-NEXT: 2000c: 00 02 1f d6 br x16 | ||
| // CHECK: $d: | ||
| // CHECK-NEXT: 20010: 00 00 00 00 .word 0x00000000 | ||
| // CHECK-NEXT: 20014: 10 00 00 00 .word 0x00000010 | ||
|
|
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| // RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %S/Inputs/abs.s -o %tabs | ||
| // RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %s -o %t | ||
| // RUN: ld.lld %t %tabs -o %t2 2>&1 | ||
| // RUN: llvm-objdump -d -triple=aarch64-pc-freebsd %t2 | FileCheck %s | ||
| // REQUIRES: aarch64 | ||
|
|
||
| .text | ||
| .globl _start | ||
| _start: | ||
| b big | ||
|
|
||
| // CHECK: Disassembly of section .text: | ||
| // CHECK-NEXT: _start: | ||
| // CHECK-NEXT: 20000: 02 00 00 14 b #8 | ||
| // CHECK: __AArch64AbsLongThunk_big: | ||
| // CHECK-NEXT: 20008: 50 00 00 58 ldr x16, #8 | ||
| // CHECK-NEXT: 2000c: 00 02 1f d6 br x16 | ||
| // CHECK: $d: | ||
| // CHECK-NEXT: 20010: 00 00 00 00 .word 0x00000000 | ||
| // CHECK-NEXT: 20014: 10 00 00 00 .word 0x00000010 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,91 @@ | ||
| // RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %s -o %t | ||
| // RUN: echo "SECTIONS { \ | ||
| // RUN: .text_low : { *(.text_low) } \ | ||
| // RUN: .text_high 0x10000000 : { *(.text_high) } \ | ||
| // RUN: } " > %t.script | ||
| // RUN: ld.lld --script %t.script --shared %t -o %t2 2>&1 | ||
| // RUN: llvm-objdump -d -triple=aarch64-linux-gnu %t2 | FileCheck %s | ||
| // REQUIRES: aarch64 | ||
|
|
||
| // Check that Position Independent thunks are generated for shared libraries. | ||
| .section .text_low, "ax", %progbits | ||
| .globl low_target | ||
| .type low_target, %function | ||
| low_target: | ||
| // Need thunk to high_target@plt | ||
| bl high_target | ||
| ret | ||
| // CHECK: low_target: | ||
| // CHECK-NEXT: 0: 04 00 00 94 bl #16 | ||
| // CHECK-NEXT: 4: c0 03 5f d6 ret | ||
|
|
||
| .hidden low_target2 | ||
| .globl low_target2 | ||
| .type low_target2, %function | ||
| low_target2: | ||
| // Need thunk to high_target | ||
| bl high_target2 | ||
| ret | ||
| // CHECK: low_target2: | ||
| // CHECK-NEXT: 8: 05 00 00 94 bl #20 | ||
| // CHECK-NEXT: c: c0 03 5f d6 ret | ||
|
|
||
| // Expect range extension thunks for .text_low | ||
| // adrp calculation is (PC + signed immediate) & (!0xfff) | ||
| // CHECK: __AArch64ADRPThunk_high_target: | ||
| // CHECK-NEXT: 10: 10 00 08 90 adrp x16, #268435456 | ||
| // CHECK-NEXT: 14: 10 82 04 91 add x16, x16, #288 | ||
| // CHECK-NEXT: 18: 00 02 1f d6 br x16 | ||
| // CHECK: __AArch64ADRPThunk_high_target2: | ||
| // CHECK-NEXT: 1c: 10 00 08 90 adrp x16, #268435456 | ||
| // CHECK-NEXT: 20: 10 22 00 91 add x16, x16, #8 | ||
| // CHECK-NEXT: 24: 00 02 1f d6 br x16 | ||
|
|
||
|
|
||
| .section .text_high, "ax", %progbits | ||
| .globl high_target | ||
| .type high_target, %function | ||
| high_target: | ||
| // No thunk needed as we can reach low_target@plt | ||
| bl low_target | ||
| ret | ||
| // CHECK: high_target: | ||
| // CHECK-NEXT: 10000000: 4c 00 00 94 bl #304 | ||
| // CHECK-NEXT: 10000004: c0 03 5f d6 ret | ||
|
|
||
| .hidden high_target2 | ||
| .globl high_target2 | ||
| .type high_target2, %function | ||
| high_target2: | ||
| // Need thunk to low_target | ||
| bl low_target2 | ||
| ret | ||
| // CHECK: high_target2: | ||
| // CHECK-NEXT: 10000008: 02 00 00 94 bl #8 | ||
| // CHECK-NEXT: 1000000c: c0 03 5f d6 ret | ||
|
|
||
| // Expect Thunk for .text.high | ||
|
|
||
| // CHECK: __AArch64ADRPThunk_low_target2: | ||
| // CHECK-NEXT: 10000010: 10 00 f8 90 adrp x16, #-268435456 | ||
| // CHECK-NEXT: 10000014: 10 22 00 91 add x16, x16, #8 | ||
| // CHECK-NEXT: 10000018: 00 02 1f d6 br x16 | ||
|
|
||
| // CHECK: Disassembly of section .plt: | ||
| // CHECK-NEXT: .plt: | ||
| // CHECK-NEXT: 10000100: f0 7b bf a9 stp x16, x30, [sp, #-16]! | ||
| // CHECK-NEXT: 10000104: 10 00 00 90 adrp x16, #0 | ||
| // CHECK-NEXT: 10000108: 11 aa 40 f9 ldr x17, [x16, #336] | ||
| // CHECK-NEXT: 1000010c: 10 42 05 91 add x16, x16, #336 | ||
| // CHECK-NEXT: 10000110: 20 02 1f d6 br x17 | ||
| // CHECK-NEXT: 10000114: 1f 20 03 d5 nop | ||
| // CHECK-NEXT: 10000118: 1f 20 03 d5 nop | ||
| // CHECK-NEXT: 1000011c: 1f 20 03 d5 nop | ||
| // CHECK-NEXT: 10000120: 10 00 00 90 adrp x16, #0 | ||
| // CHECK-NEXT: 10000124: 11 ae 40 f9 ldr x17, [x16, #344] | ||
| // CHECK-NEXT: 10000128: 10 62 05 91 add x16, x16, #344 | ||
| // CHECK-NEXT: 1000012c: 20 02 1f d6 br x17 | ||
| // CHECK-NEXT: 10000130: 10 00 00 90 adrp x16, #0 | ||
| // CHECK-NEXT: 10000134: 11 b2 40 f9 ldr x17, [x16, #352] | ||
| // CHECK-NEXT: 10000138: 10 82 05 91 add x16, x16, #352 | ||
| // CHECK-NEXT: 1000013c: 20 02 1f d6 br x17 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| // RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %s -o %t | ||
| // RUN: echo "SECTIONS { \ | ||
| // RUN: .text_low 0x2000: { *(.text_low) } \ | ||
| // RUN: .text_high 0x8002000 : { *(.text_high) } \ | ||
| // RUN: } " > %t.script | ||
| // RUN: ld.lld --script %t.script %t -o %t2 2>&1 | ||
| // RUN: llvm-objdump -d -triple=aarch64-linux-gnu %t2 | FileCheck %s | ||
| // REQUIRES: aarch64 | ||
|
|
||
| // Check that we have the out of branch range calculation right. The immediate | ||
| // field is signed so we have a slightly higher negative displacement. | ||
| .section .text_low, "ax", %progbits | ||
| .globl _start | ||
| .type _start, %function | ||
| _start: | ||
| // Need thunk to high_target@plt | ||
| bl high_target | ||
| ret | ||
|
|
||
| .section .text_high, "ax", %progbits | ||
| .globl high_target | ||
| .type high_target, %function | ||
| high_target: | ||
| // No Thunk needed as we are within signed immediate range | ||
| bl _start | ||
| ret | ||
|
|
||
| // CHECK: Disassembly of section .text_low: | ||
| // CHECK-NEXT: _start: | ||
| // CHECK-NEXT: 2000: 02 00 00 94 bl #8 | ||
| // CHECK-NEXT: 2004: c0 03 5f d6 ret | ||
| // CHECK: __AArch64AbsLongThunk_high_target: | ||
| // CHECK-NEXT: 2008: 50 00 00 58 ldr x16, #8 | ||
| // CHECK-NEXT: 200c: 00 02 1f d6 br x16 | ||
| // CHECK: $d: | ||
| // CHECK-NEXT: 2010: 00 20 00 08 .word 0x08002000 | ||
| // CHECK-NEXT: 2014: 00 00 00 00 .word 0x00000000 | ||
| // CHECK: Disassembly of section .text_high: | ||
| // CHECK-NEXT: high_target: | ||
| // CHECK-NEXT: 8002000: 00 00 00 96 bl #-134217728 | ||
| // CHECK-NEXT: 8002004: c0 03 5f d6 ret |
Oops, something went wrong.