1// REQUIRES: arm 2// RUN: llvm-mc --triple=thumbv7m-none-eabi --arm-add-build-attributes -filetype=obj -o %t.o %s 3// RUN: echo "SECTIONS { \ 4// RUN: .rodata.low 0x8012 : { *(.rodata.low) } \ 5// RUN: .text.low 0x8f00 : { *(.text.low) } \ 6// RUN: .text.neg 0x9000 : { *(.text.neg) } \ 7// RUN: .text.pos 0x10000 : { *(.text.pos) } \ 8// RUN: .text.high 0x10100 : { *(.text.high) } \ 9// RUN: .data_high 0x1100f : { *(.data.high) } \ 10// RUN: } " > %t.script 11// RUN: ld.lld --script %t.script %t.o -o %t 12// RUN: llvm-readobj --symbols %t | FileCheck %s --check-prefix=SYMS 13// RUN: llvm-objdump --no-print-imm-hex -d --no-show-raw-insn %t | FileCheck %s 14 15/// Test the various legal cases for the R_ARM_THM_PC12 relocation 16/// Interesting things to note 17/// Range is +- 4095 bytes 18/// The Thumb bit for function symbols is ignored 19/// The expression is S + A - Pa where Pa is AlignDown(PC, 4) so we will use 20/// 2-byte nops to make some of the ldr instructions 2-byte aligned. 21 .section .rodata.low, "a", %progbits 22dat1: 23 .byte 0 24dat2: 25 .byte 1 26dat3: 27 .byte 2 28dat4: 29 .byte 3 30 31 .section .text.low, "ax", %progbits 32 .balign 4 33 .global target1 34 .type target1, %function 35target1: 36 bx lr 37 .type target2, %function 38target2: 39 bx lr 40 41 .section .text.neg, "ax", %progbits 42 .balign 4 43 .global _start 44 .thumb_func 45_start: 46 nop 47/// ldr r0, dat1 48 .inst.w 0xf85f0004 49 .reloc 2, R_ARM_THM_PC12, dat1 50/// ldr r1, dat2 51 .inst.w 0xf85f1004 52 .reloc 6, R_ARM_THM_PC12, dat2 53 nop 54/// ldr r2, dat3 55 .inst.w 0xf85f2004 56 .reloc 0xc, R_ARM_THM_PC12, dat3 57/// ldr r3, dat4 58 .inst.w 0xf85f3004 59 .reloc 0x10, R_ARM_THM_PC12, dat4 60 61/// ldr r0, target1 62 .inst.w 0xf85f0004 63 .reloc 0x14, R_ARM_THM_PC12, target1 64 65 nop 66/// ldr r1, target2 67 .inst.w 0xf85f1004 68 .reloc 0x1a, R_ARM_THM_PC12, target2 69 70 .section .text.pos, "ax", %progbits 71 .balign 4 72 .global pos 73 .thumb_func 74pos: 75/// ldr r2, target3 76 .inst.w 0xf85f2004 77 .reloc 0, R_ARM_THM_PC12, target3 78 nop 79/// ldr r3, target4 80 .inst.w 0xf85f3004 81 .reloc 6, R_ARM_THM_PC12, target4 82 nop 83/// ldr r0, dat5 84 .inst.w 0xf85f0004 85 .reloc 0xc, R_ARM_THM_PC12, dat5 86/// ldr r1, dat6 87 .inst.w 0xf85f1004 88 .reloc 0x10, R_ARM_THM_PC12, dat6 89 nop 90/// ldr r2, dat7 91 .inst.w 0xf85f2004 92 .reloc 0x16, R_ARM_THM_PC12, dat7 93/// ldr r3, dat8 94 .inst.w 0xf85f3004 95 .reloc 0x1a, R_ARM_THM_PC12, dat8 96/// positive addend in instruction, all others are -4 (PC bias) 97///ldr.w r4, dat5 + 8 98 .inst 0xf8df4004 99 .reloc 0x1e, R_ARM_THM_PC12, dat5 100 101 .section .text.high, "ax", %progbits 102 .balign 4 103 .thumb_func 104 .global target3 105target3: 106 bx lr 107 .thumb_func 108target4: 109 bx lr 110 111 .section .data.high, "aw", %progbits 112dat5: 113 .byte 0 114dat6: 115 .byte 1 116dat7: 117 .byte 2 118dat8: 119 .byte 3 120 121// SYMS: Name: dat1 122// SYMS-NEXT: Value: 0x8012 123// SYMS: Name: dat2 124// SYMS-NEXT: Value: 0x8013 125// SYMS: Name: dat3 126// SYMS-NEXT: Value: 0x8014 127// SYMS: Name: dat4 128// SYMS-NEXT: Value: 0x8015 129 130// CHECK: 00008f00 <target1>: 131// CHECK-NEXT: 8f00: bx lr 132// CHECK: 00008f02 <target2>: 133// CHECK-NEXT: 8f02: bx lr 134 135// CHECK: 00009000 <_start>: 136// CHECK-NEXT: 9000: nop 137/// AlignDown(0x9002+4, 4) - 0xff2 = 0x8012 138// CHECK-NEXT: 9002: ldr.w r0, [pc, #-4082] 139/// AlignDown(0x9006+4, 4) - 0xff5 = 0x8013 140// CHECK-NEXT: 9006: ldr.w r1, [pc, #-4085] 141// CHECK-NEXT: 900a: nop 142/// AlignDown(0x900c+4, 4) - 0xffc = 0x8014 143// CHECK-NEXT: 900c: ldr.w r2, [pc, #-4092] 144/// AlignDown(0x9010+4, 4) - 0xfff = 0x8015 145// CHECK-NEXT: 9010: ldr.w r3, [pc, #-4095] 146/// AlignDown(0x9014+4, 4) - 0x118 = 0x8f00 147// CHECK-NEXT: 9014: ldr.w r0, [pc, #-280] 148// CHECK-NEXT: 9018: nop 149/// AlignDown(0x901a+4, 4) - 0x11a = 0x8f02 150// CHECK-NEXT: 901a: ldr.w r1, [pc, #-282] 151 152// CHECK: 00010000 <pos>: 153/// AlignDown(0x10000+4, 4) + 0x1c = 0x10100 154// CHECK-NEXT: 10000: ldr.w r2, [pc, #252] 155// CHECK-NEXT: 10004: nop 156/// AlignDown(0x10006+4, 4) + 0x1a = 0x10122 157// CHECK-NEXT: 10006: ldr.w r3, [pc, #250] 158// CHECK-NEXT: 1000a: nop 159/// AlignDown(0x1000c+4, 4) + 0xfff = 0x1100f 160// CHECK-NEXT: 1000c: ldr.w r0, [pc, #4095] 161/// AlignDown(0x10010+4, 4) + 0xffc = 0x11010 162// CHECK-NEXT: 10010: ldr.w r1, [pc, #4092] 163// CHECK-NEXT: 10014: nop 164/// AlignDown(0x10016+4, 4) + 0xff9 = 0x11011 165// CHECK-NEXT: 10016: ldr.w r2, [pc, #4089] 166/// AlignDown(0x1001a+4, 4) + 0xff6 = 0x11012 167// CHECK-NEXT: 1001a: ldr.w r3, [pc, #4086] 168/// AlignDown(0x1001e+4, 4) + 0xff7 = 0x11017 = dat5 + 8 169// CHECK-NEXT: 1001e: ldr.w r4, [pc, #4087] 170 171// CHECK: 00010100 <target3>: 172// CHECK-NEXT: 10100: bx lr 173 174// CHECK: 00010102 <target4>: 175// CHECK-NEXT: 10102: bx lr 176 177// SYMS: Name: dat5 178// SYMS-NEXT: Value: 0x1100F 179// SYMS: Name: dat6 180// SYMS-NEXT: Value: 0x11010 181// SYMS: Name: dat7 182// SYMS-NEXT: Value: 0x11011 183// SYMS: Name: dat8 184// SYMS-NEXT: Value: 0x11012 185