1// REQUIRES: arm 2// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-linux-gnueabihf %s -o %t 3// RUN: echo "SECTIONS { \ 4// RUN: . = SIZEOF_HEADERS; \ 5// RUN: .text 0x00011000 : { *(.text.*) } \ 6// RUN: } \ 7// RUN: sym = .;" > %t.script 8// RUN: ld.lld --script %t.script %t -o %t2 9// RUN: llvm-readobj --sections --symbols %t2 | FileCheck --check-prefix=CHECK-ELF %s 10// RUN: llvm-objdump --no-show-raw-insn --start-address=0x11000 --stop-address=0x11048 -d %t2 | FileCheck %s 11 12// An example of thunk generation that takes the maximum number of permitted 13// passes to converge. We start with a set of branches of which all but one are 14// in range. Any thunk added to extend the range of a branch is inserted in 15// between the branches and the targets which knocks some more branches out 16// of range. At the end of 9 passes of createThunks() every branch has a 17// range extension thunk, allowing the final pass to check that no more thunks 18// are required. 19// 20// As the size of the .text section changes 9 times, the symbol sym which 21// depends on the size of .text will be updated 9 times. This test checks that 22// any iteration limit to updating symbols does not limit thunk convergence. 23// up to its pass limit without 24// 25// CHECK-ELF: Name: .text 26// CHECK-ELF-NEXT: Type: SHT_PROGBITS 27// CHECK-ELF-NEXT: Flags [ 28// CHECK-ELF-NEXT: SHF_ALLOC 29// CHECK-ELF-NEXT: SHF_EXECINSTR 30// CHECK-ELF-NEXT: ] 31// CHECK-ELF-NEXT: Address: 0x11000 32// CHECK-ELF-NEXT: Offset: 0x1000 33// CHECK-ELF-NEXT: Size: 16777292 34// CHECK-ELF: Name: sym 35// CHECK-ELF-NEXT: Value: 0x101104C 36 37// CHECK: 00011000 <_start>: 38// CHECK-NEXT: 11000: b.w 0xe11048 <__Thumbv7ABSLongThunk_f2> 39// CHECK-NEXT: 11004: b.w 0xe11048 <__Thumbv7ABSLongThunk_f2> 40// CHECK-NEXT: 11008: b.w 0xe1104c <__Thumbv7ABSLongThunk_f3> 41// CHECK-NEXT: 1100c: b.w 0xe1104c <__Thumbv7ABSLongThunk_f3> 42// CHECK-NEXT: 11010: b.w 0xe11050 <__Thumbv7ABSLongThunk_f4> 43// CHECK-NEXT: 11014: b.w 0xe11050 <__Thumbv7ABSLongThunk_f4> 44// CHECK-NEXT: 11018: b.w 0xe11054 <__Thumbv7ABSLongThunk_f5> 45// CHECK-NEXT: 1101c: b.w 0xe11054 <__Thumbv7ABSLongThunk_f5> 46// CHECK-NEXT: 11020: b.w 0xe11058 <__Thumbv7ABSLongThunk_f6> 47// CHECK-NEXT: 11024: b.w 0xe11058 <__Thumbv7ABSLongThunk_f6> 48// CHECK-NEXT: 11028: b.w 0xe1105c <__Thumbv7ABSLongThunk_f7> 49// CHECK-NEXT: 1102c: b.w 0xe1105c <__Thumbv7ABSLongThunk_f7> 50// CHECK-NEXT: 11030: b.w 0xe11060 <__Thumbv7ABSLongThunk_f8> 51// CHECK-NEXT: 11034: b.w 0xe11060 <__Thumbv7ABSLongThunk_f8> 52// CHECK-NEXT: 11038: b.w 0xe11064 <__Thumbv7ABSLongThunk_f9> 53// CHECK-NEXT: 1103c: b.w 0xe11064 <__Thumbv7ABSLongThunk_f9> 54// CHECK-NEXT: 11040: b.w 0xe11068 <__Thumbv7ABSLongThunk_f10> 55// CHECK-NEXT: 11044: b.w 0xe11068 <__Thumbv7ABSLongThunk_f10> 56 57 58 .thumb 59 .section .text.00, "ax", %progbits 60 .globl _start 61 .thumb_func 62_start: b.w f2 63 b.w f2 64 b.w f3 65 b.w f3 66 b.w f4 67 b.w f4 68 b.w f5 69 b.w f5 70 b.w f6 71 b.w f6 72 b.w f7 73 b.w f7 74 b.w f8 75 b.w f8 76 b.w f9 77 b.w f9 78 b.w f10 79 b.w f10 80 81 .section .text.01, "ax", %progbits 82 .space 14 * 1024 * 1024 83// Thunks are inserted here, initially only 1 branch is out of range and needs 84// a thunk. However the added thunk is 4-bytes in size which makes another 85// branch out of range, which adds another thunk ... 86 .section .text.02, "ax", %progbits 87 .space (2 * 1024 * 1024) - 68 88 .thumb_func 89f2: bx lr 90 nop 91 .thumb_func 92f3: bx lr 93 nop 94 .thumb_func 95f4: bx lr 96 nop 97 .thumb_func 98f5: bx lr 99 nop 100 .thumb_func 101f6: bx lr 102 nop 103 .thumb_func 104f7: bx lr 105 nop 106 .thumb_func 107f8: bx lr 108 nop 109 .thumb_func 110f9: bx lr 111 nop 112 .thumb_func 113f10: bx lr 114 nop 115