1REQUIRES: aarch64 2 3## Test handling of addends taken from the relocated word or instruction 4## in AArch64 relocation sections of type SHT_REL. These can be generated 5## by assemblers other than LLVM, in particular the legacy 'armasm'. 6## 7## llvm-mc will only generate SHT_RELA when targeting AArch64. So to make 8## an input file with SHT_REL, we assemble our test source file, then 9## round-trip via YAML and do some seddery to change the type of the 10## relocation section. Since all the relocations were made manually with 11## .reloc directives containing no addend, this succeeds. 12 13# RUN: rm -rf %t && split-file %s %t && cd %t 14 15# RUN: llvm-mc -filetype=obj -triple=aarch64 relocs.s -o rela.o 16# RUN: obj2yaml rela.o -o rela.yaml 17# RUN: sed "s/\.rela/\.rel/;s/SHT_RELA/SHT_REL/" rela.yaml > rel.yaml 18# RUN: yaml2obj rel.yaml -o rel.o 19# RUN: llvm-mc -filetype=obj -triple=aarch64 symbols.s -o symbols.o 20# RUN: ld.lld rel.o symbols.o -o a.out --section-start=.data=0x100000 --section-start=.text=0x200000 21# RUN: llvm-objdump -s a.out | FileCheck %s --check-prefix=DATALE 22# RUN: llvm-objdump -d a.out | FileCheck %s --check-prefix=CODE 23 24# RUN: llvm-mc -filetype=obj -triple=aarch64_be relocs.s -o rela_be.o 25# RUN: obj2yaml rela_be.o -o rela_be.yaml 26# RUN: sed "s/\.rela/\.rel/;s/SHT_RELA/SHT_REL/" rela_be.yaml > rel_be.yaml 27# RUN: yaml2obj rel_be.yaml -o rel_be.o 28# RUN: llvm-mc -filetype=obj -triple=aarch64_be symbols.s -o symbols_be.o 29# RUN: ld.lld -EB rel_be.o symbols_be.o -o be.out --section-start=.data=0x100000 --section-start=.text=0x200000 30# RUN: llvm-objdump -s be.out | FileCheck %s --check-prefix=DATABE 31# RUN: llvm-objdump -d be.out | FileCheck %s --check-prefix=CODE 32 33#--- symbols.s 34 35// Source file containing the values of target symbols for the relocations. If 36// we don't keep these in their own file, then llvm-mc is clever enough to 37// resolve some of the relocations during assembly, even though they're written 38// as explicit .reloc directives. But we want the relocations to be present in 39// the object file, so that yaml2obj can change their type and we can test 40// lld's handling of the result. So we ensure that llvm-mc can't see both the 41// .reloc and the target symbol value at the same time. 42 43.globl abs16 44.globl abs32 45.globl abs64 46.globl big64 47.globl pcrel 48.globl data 49.globl branchtarget 50.globl calltarget 51 52.equ abs16, 0x9999 53.equ data, 0x100000 54.equ branchtarget, 0x200100 55.equ calltarget, 0x02000100 56.equ pcrel, 0x245678 57.equ abs32, 0x88888888 58.equ abs64, 0x7777777777777777 59.equ big64, 0x77ffffffffffff77 60 61#--- relocs.s 62 63// Source file containing the test instructions and their relocations, with the 64// FileCheck comments interleaved. 65 66// DATALE: Contents of section .data: 67// DATABE: Contents of section .data: 68.data 69 70// First test absolute data relocations. For each one I show the expected 71// value in a comment, and then expect a line in llvm-objdump -s containing 72// all the values together. 73 74 // 0x7777777777777777 + 0x1234567887654321 = 0x89abcdeffedcba98 75 .reloc ., R_AARCH64_ABS64, abs64 76 .xword 0x1234567887654321 77 78 // 0x88888888 + 0x12344321 = 0x9abccba9 79 .reloc ., R_AARCH64_ABS32, abs32 80 .word 0x12344321 81 82 // 0x9999 + 0x1234 = 0xabcd 83 .reloc ., R_AARCH64_ABS16, abs16 84 .hword 0x1234 85 86 // DATALE-NEXT: 100000 98badcfe efcdab89 a9cbbc9a cdab 87 // DATABE-NEXT: 100000 89abcdef fedcba98 9abccba9 abcd 88 89 .balign 16 90 91// Test relative data relocs, each subtracting the address of the relocated 92// word. 93 94 // 0x100000 + 0x1234567887654321 - 0x100010 = 0x1234567887654311 95 .reloc ., R_AARCH64_PREL64, data 96 .xword 0x1234567887654321 97 98 // 0x100000 + 0x12344321 - 0x100018 = 0x12344309 99 .reloc ., R_AARCH64_PREL32, data 100 .word 0x12344321 101 102 // 0x100000 + 0x1234 - 0x10001c = 0x1218 103 .reloc ., R_AARCH64_PREL16, data 104 .hword 0x1234 105 106 // DATALE-NEXT: 100010 11436587 78563412 09433412 1812 107 // DATABE-NEXT: 100010 12345678 87654311 12344309 1218 108 109// CODE: 0000000000200000 <_start>: 110.text 111.globl _start 112_start: 113 114// Full set of 4 instructions loading the constant 'abs64' and adding 0x1234 to 115// it. 116 117// Expected constant is 0x7777777777777777 + 0x1234 = 0x77777777777789ab 118 119 .reloc ., R_AARCH64_MOVW_UABS_G0_NC, abs64 120 movz x0, #0x1234 121 // CODE-NEXT: 200000: d2913560 mov x0, #0x89ab 122 .reloc ., R_AARCH64_MOVW_UABS_G1_NC, abs64 123 movk x0, #0x1234, lsl #16 124 // CODE-NEXT: 200004: f2aeeee0 movk x0, #0x7777, lsl #16 125 .reloc ., R_AARCH64_MOVW_UABS_G2_NC, abs64 126 movk x0, #0x1234, lsl #32 127 // CODE-NEXT: 200008: f2ceeee0 movk x0, #0x7777, lsl #32 128 .reloc ., R_AARCH64_MOVW_UABS_G3, abs64 129 movk x0, #0x1234, lsl #48 130 // CODE-NEXT: 20000c: f2eeeee0 movk x0, #0x7777, lsl #48 131 132// The same, but this constant has ffff in the middle 32 bits, forcing carries 133// to be propagated. 134 135// Expected constant: 0x77ffffffffffff77 + 0x1234 = 0x78000000000011ab 136 137 .reloc ., R_AARCH64_MOVW_UABS_G0_NC, big64 138 movz x0, #0x1234 139 // CODE-NEXT: 200010: d2823560 mov x0, #0x11ab 140 .reloc ., R_AARCH64_MOVW_UABS_G1_NC, big64 141 movk x0, #0x1234, lsl #16 142 // CODE-NEXT: 200014: f2a00000 movk x0, #0x0, lsl #16 143 .reloc ., R_AARCH64_MOVW_UABS_G2_NC, big64 144 movk x0, #0x1234, lsl #32 145 // CODE-NEXT: 200018: f2c00000 movk x0, #0x0, lsl #32 146 .reloc ., R_AARCH64_MOVW_UABS_G3, big64 147 movk x0, #0x1234, lsl #48 148 // CODE-NEXT: 20001c: f2ef0000 movk x0, #0x7800, lsl #48 149 150// Demonstrate that offsets are treated as signed: this one is taken to be 151// -0x1234. (If it were +0xedcc then you'd be able to tell the difference by 152// the carry into the second halfword.) 153 154// Expected value: 0x7777777777777777 - 0x1234 = 0x7777777777776543 155 156 .reloc ., R_AARCH64_MOVW_UABS_G0_NC, abs64 157 movz x0, #0xedcc 158 // CODE-NEXT: 200020: d28ca860 mov x0, #0x6543 159 .reloc ., R_AARCH64_MOVW_UABS_G1_NC, abs64 160 movk x0, #0xedcc, lsl #16 161 // CODE-NEXT: 200024: f2aeeee0 movk x0, #0x7777, lsl #16 162 .reloc ., R_AARCH64_MOVW_UABS_G2_NC, abs64 163 movk x0, #0xedcc, lsl #32 164 // CODE-NEXT: 200028: f2ceeee0 movk x0, #0x7777, lsl #32 165 .reloc ., R_AARCH64_MOVW_UABS_G3, abs64 166 movk x0, #0xedcc, lsl #48 167 // CODE-NEXT: 20002c: f2eeeee0 movk x0, #0x7777, lsl #48 168 169// Check various bits of the ADR immediate, including in particular the low 2 170// bits, which are not contiguous with the rest in the encoding. 171// 172// These values are all 0x245678 + 2^n, except the last one, where the set bit 173// of the addend is the top bit, counting as negative, i.e. we expect the value 174// 0x254678 - 0x100000 = 0x145678. 175 176 .reloc ., R_AARCH64_ADR_PREL_LO21, pcrel 177 adr x0, .+1 178 // CODE-NEXT: 200030: 3022b240 adr x0, 0x245679 179 .reloc ., R_AARCH64_ADR_PREL_LO21, pcrel 180 adr x0, .+2 181 // CODE-NEXT: 200034: 5022b220 adr x0, 0x24567a 182 .reloc ., R_AARCH64_ADR_PREL_LO21, pcrel 183 adr x0, .+4 184 // CODE-NEXT: 200038: 1022b220 adr x0, 0x24567c 185 .reloc ., R_AARCH64_ADR_PREL_LO21, pcrel 186 adr x0, .+8 187 // CODE-NEXT: 20003c: 1022b220 adr x0, 0x245680 188 .reloc ., R_AARCH64_ADR_PREL_LO21, pcrel 189 adr x0, .+1<<19 190 // CODE-NEXT: 200040: 1062b1c0 adr x0, 0x2c5678 191 .reloc ., R_AARCH64_ADR_PREL_LO21, pcrel 192 adr x0, .-1<<20 193 // CODE-NEXT: 200044: 10a2b1a0 adr x0, 0x145678 194 195// Now load the same set of values with ADRP+ADD. But because the real ADRP 196// instruction shifts its immediate, we must account for that. 197 198 .reloc ., R_AARCH64_ADR_PREL_PG_HI21, pcrel 199 adrp x0, 1<<12 200 // CODE-NEXT: 200048: b0000220 adrp x0, 0x245000 201 .reloc ., R_AARCH64_ADD_ABS_LO12_NC, pcrel 202 add x0, x0, #1 203 // CODE-NEXT: 20004c: 9119e400 add x0, x0, #0x679 204 .reloc ., R_AARCH64_ADR_PREL_PG_HI21, pcrel 205 adrp x0, 2<<12 206 // CODE-NEXT: 200050: b0000220 adrp x0, 0x245000 207 .reloc ., R_AARCH64_ADD_ABS_LO12_NC, pcrel 208 add x0, x0, #2 209 // CODE-NEXT: 200054: 9119e800 add x0, x0, #0x67a 210 .reloc ., R_AARCH64_ADR_PREL_PG_HI21, pcrel 211 adrp x0, 4<<12 212 // CODE-NEXT: 200058: b0000220 adrp x0, 0x245000 213 .reloc ., R_AARCH64_ADD_ABS_LO12_NC, pcrel 214 add x0, x0, #4 215 // CODE-NEXT: 20005c: 9119f000 add x0, x0, #0x67c 216 .reloc ., R_AARCH64_ADR_PREL_PG_HI21, pcrel 217 adrp x0, 8<<12 218 // CODE-NEXT: 200060: b0000220 adrp x0, 0x245000 219 .reloc ., R_AARCH64_ADD_ABS_LO12_NC, pcrel 220 add x0, x0, #8 221 // CODE-NEXT: 200064: 911a0000 add x0, x0, #0x680 222 223 // Starting here, the high bits won't fit in the ADD immediate, so that 224 // becomes 0, and only the ADRP immediate shows evidence of the addend. 225 226 .reloc ., R_AARCH64_ADR_PREL_PG_HI21, pcrel 227 adrp x0, 1<<(19+12) 228 // CODE-NEXT: 200068: b0000620 adrp x0, 0x2c5000 229 .reloc ., R_AARCH64_ADD_ABS_LO12_NC, pcrel 230 add x0, x0, #0 231 // CODE-NEXT: 20006c: 9119e000 add x0, x0, #0x678 232 233 .reloc ., R_AARCH64_ADR_PREL_PG_HI21, pcrel 234 adrp x0, -1<<(20+12) 235 // CODE-NEXT: 200070: b0fffa20 adrp x0, 0x145000 236 .reloc ., R_AARCH64_ADD_ABS_LO12_NC, pcrel 237 add x0, x0, #0 238 // CODE-NEXT: 200074: 9119e000 add x0, x0, #0x678 239 240 // Finally, an example with a full 21-bit addend. 241 // Expected value = 0x245678 + 0xfedcb - 0x100000 = 0x244443 242 .reloc ., R_AARCH64_ADR_PREL_PG_HI21, pcrel 243 adrp x0, (0xfedcb-0x100000)<<12 244 // CODE-NEXT: 200078: 90000220 adrp x0, 0x244000 245 .reloc ., R_AARCH64_ADD_ABS_LO12_NC, pcrel 246 add x0, x0, #0xdcb 247 // CODE-NEXT: 20007c: 91110c00 add x0, x0, #0x443 248 249// PC-relative loads, in which the 19-bit offset is shifted. The offsets are 250// the same as the ADRs above, except for the first two, which can't be 251// expressed by pc-relative LDR with an offset shifted left 2. 252// 253// (The input syntax is confusing here. I'd normally expect to write this as 254// `ldr x0, [pc, #offset]`, but LLVM writes just `#offset`.) 255 256 .reloc ., R_AARCH64_LD_PREL_LO19, pcrel 257 ldr w0, #4 258 // CODE-NEXT: 200080: 1822afe0 ldr w0, 0x24567c 259 .reloc ., R_AARCH64_LD_PREL_LO19, pcrel 260 ldr w0, #8 261 // CODE-NEXT: 200084: 1822afe0 ldr w0, 0x245680 262 .reloc ., R_AARCH64_LD_PREL_LO19, pcrel 263 ldr w0, #1<<19 264 // CODE-NEXT: 200088: 1862af80 ldr w0, 0x2c5678 265 .reloc ., R_AARCH64_LD_PREL_LO19, pcrel 266 ldr w0, #-1<<20 267 // CODE-NEXT: 20008c: 18a2af60 ldr w0, 0x145678 268 269 270// For these, the branch target is 0x200100 plus powers of 2, except the offset 271// 2^15, which is negative, because the addend is treated as signed. 272 273 .reloc ., R_AARCH64_TSTBR14, branchtarget 274 tbnz x1, #63, #4 275 // CODE-NEXT: 200090: b7f803a1 tbnz x1, #0x3f, 0x200104 276 .reloc ., R_AARCH64_TSTBR14, branchtarget 277 tbnz x1, #62, #8 278 // CODE-NEXT: 200094: b7f003a1 tbnz x1, #0x3e, 0x200108 279 .reloc ., R_AARCH64_TSTBR14, branchtarget 280 tbnz x1, #61, #1<<14 281 // CODE-NEXT: 200098: b7ea0341 tbnz x1, #0x3d, 0x204100 282 .reloc ., R_AARCH64_TSTBR14, branchtarget 283 tbnz x1, #60, #-1<<15 284 // CODE-NEXT: 20009c: b7e40321 tbnz x1, #0x3c, 0x1f8100 285 286// CONDBR19 is used for both cbz/cbnz and B.cond, so test both at once. Base 287// offset is the same again (from 0x200100), but this time, offsets can go up 288// to 2^20. 289 290 .reloc ., R_AARCH64_CONDBR19, branchtarget 291 cbnz x2, #4 292 // CODE-NEXT: 2000a0: b5000322 cbnz x2, 0x200104 293 .reloc ., R_AARCH64_CONDBR19, branchtarget 294 b.eq #8 295 // CODE-NEXT: 2000a4: 54000320 b.eq 0x200108 296 .reloc ., R_AARCH64_CONDBR19, branchtarget 297 cbz x2, #1<<19 298 // CODE-NEXT: 2000a8: b44002c2 cbz x2, 0x280100 299 .reloc ., R_AARCH64_CONDBR19, branchtarget 300 b.vs #-1<<20 301 // CODE-NEXT: 2000ac: 548002a6 b.vs 0x100100 302 303// And for BL and B, the offsets go up to 2^25. 304 305 .reloc ., R_AARCH64_CALL26, calltarget 306 bl #4 307 // CODE-NEXT: 2000b0: 94780015 bl 0x2000104 308 .reloc ., R_AARCH64_CALL26, calltarget 309 bl #8 310 // CODE-NEXT: 2000b4: 94780015 bl 0x2000108 311 .reloc ., R_AARCH64_CALL26, calltarget 312 bl #1<<24 313 // CODE-NEXT: 2000b8: 94b80012 bl 0x3000100 314 .reloc ., R_AARCH64_CALL26, calltarget 315 bl #-1<<25 316 // CODE-NEXT: 2000bc: 97f80011 bl 0x100 317 318 .reloc ., R_AARCH64_JUMP26, calltarget 319 b #4 320 // CODE-NEXT: 2000c0: 14780011 b 0x2000104 321 .reloc ., R_AARCH64_JUMP26, calltarget 322 b #8 323 // CODE-NEXT: 2000c4: 14780011 b 0x2000108 324 .reloc ., R_AARCH64_JUMP26, calltarget 325 b #1<<24 326 // CODE-NEXT: 2000c8: 14b8000e b 0x3000100 327 .reloc ., R_AARCH64_JUMP26, calltarget 328 b #-1<<25 329 // CODE-NEXT: 2000cc: 17f8000d b 0x100 330