brintos

brintos / llvm-project-archived public Read only

0
0
Text · 13.3 KiB · ba18a5e Raw
330 lines · plain
1REQUIRES: aarch642 3## Test handling of addends taken from the relocated word or instruction4## in AArch64 relocation sections of type SHT_REL. These can be generated5## by assemblers other than LLVM, in particular the legacy 'armasm'.6##7## llvm-mc will only generate SHT_RELA when targeting AArch64. So to make8## an input file with SHT_REL, we assemble our test source file, then9## round-trip via YAML and do some seddery to change the type of the10## relocation section. Since all the relocations were made manually with11## .reloc directives containing no addend, this succeeds.12 13# RUN: rm -rf %t && split-file %s %t && cd %t14 15# RUN: llvm-mc -filetype=obj -triple=aarch64 relocs.s -o rela.o16# RUN: obj2yaml rela.o -o rela.yaml17# RUN: sed "s/\.rela/\.rel/;s/SHT_RELA/SHT_REL/" rela.yaml > rel.yaml18# RUN: yaml2obj rel.yaml -o rel.o19# RUN: llvm-mc -filetype=obj -triple=aarch64 symbols.s -o symbols.o20# RUN: ld.lld rel.o symbols.o -o a.out --image-base=0x80000 --section-start=.data=0x100000 --section-start=.text=0x20000021# RUN: llvm-objdump -s a.out | FileCheck %s --check-prefix=DATALE22# RUN: llvm-objdump -d a.out | FileCheck %s --check-prefix=CODE23 24# RUN: llvm-mc -filetype=obj -triple=aarch64_be relocs.s -o rela_be.o25# RUN: obj2yaml rela_be.o -o rela_be.yaml26# RUN: sed "s/\.rela/\.rel/;s/SHT_RELA/SHT_REL/" rela_be.yaml > rel_be.yaml27# RUN: yaml2obj rel_be.yaml -o rel_be.o28# RUN: llvm-mc -filetype=obj -triple=aarch64_be symbols.s -o symbols_be.o29# RUN: ld.lld -EB rel_be.o symbols_be.o -o be.out --image-base=0x80000 --section-start=.data=0x100000 --section-start=.text=0x20000030# RUN: llvm-objdump -s be.out | FileCheck %s --check-prefix=DATABE31# RUN: llvm-objdump -d be.out | FileCheck %s --check-prefix=CODE32 33#--- symbols.s34 35// Source file containing the values of target symbols for the relocations. If36// we don't keep these in their own file, then llvm-mc is clever enough to37// resolve some of the relocations during assembly, even though they're written38// as explicit .reloc directives. But we want the relocations to be present in39// the object file, so that yaml2obj can change their type and we can test40// lld's handling of the result. So we ensure that llvm-mc can't see both the41// .reloc and the target symbol value at the same time.42 43.globl abs1644.globl abs3245.globl abs6446.globl big6447.globl pcrel48.globl data49.globl branchtarget50.globl calltarget51 52.equ abs16, 0x999953.equ data, 0x10000054.equ branchtarget, 0x20010055.equ calltarget, 0x0200010056.equ pcrel, 0x24567857.equ abs32, 0x8888888858.equ abs64, 0x777777777777777759.equ big64, 0x77ffffffffffff7760 61#--- relocs.s62 63// Source file containing the test instructions and their relocations, with the64// FileCheck comments interleaved.65 66// DATALE: Contents of section .data:67// DATABE: Contents of section .data:68.data69 70// First test absolute data relocations. For each one I show the expected71// value in a comment, and then expect a line in llvm-objdump -s containing72// all the values together.73 74        // 0x7777777777777777 + 0x1234567887654321 = 0x89abcdeffedcba9875        .reloc ., R_AARCH64_ABS64, abs6476        .xword 0x123456788765432177 78        // 0x88888888 + 0x12344321 = 0x9abccba979        .reloc ., R_AARCH64_ABS32, abs3280        .word 0x1234432181 82        // 0x9999 + 0x1234 = 0xabcd83        .reloc ., R_AARCH64_ABS16, abs1684        .hword 0x123485 86        // DATALE-NEXT:  100000 98badcfe efcdab89 a9cbbc9a cdab87        // DATABE-NEXT:  100000 89abcdef fedcba98 9abccba9 abcd88 89        .balign 1690 91// Test relative data relocs, each subtracting the address of the relocated92// word.93 94        // 0x100000 + 0x1234567887654321 - 0x100010 = 0x123456788765431195        .reloc ., R_AARCH64_PREL64, data96        .xword 0x123456788765432197 98        // 0x100000 + 0x12344321 - 0x100018 = 0x1234430999        .reloc ., R_AARCH64_PREL32, data100        .word 0x12344321101 102        // 0x100000 + 0x1234 - 0x10001c = 0x1218103        .reloc ., R_AARCH64_PREL16, data104        .hword 0x1234105 106        // DATALE-NEXT:  100010 11436587 78563412 09433412 1812107        // DATABE-NEXT:  100010 12345678 87654311 12344309 1218108 109// CODE: 0000000000200000 <_start>:110.text111.globl _start112_start:113 114// Full set of 4 instructions loading the constant 'abs64' and adding 0x1234 to115// it.116 117// Expected constant is 0x7777777777777777 + 0x1234 = 0x77777777777789ab118 119        .reloc ., R_AARCH64_MOVW_UABS_G0_NC, abs64120        movz x0, #0x1234121        // CODE-NEXT:  200000: d2913560      mov     x0, #0x89ab122        .reloc ., R_AARCH64_MOVW_UABS_G1_NC, abs64123        movk x0, #0x1234, lsl #16124        // CODE-NEXT:  200004: f2aeeee0      movk    x0, #0x7777, lsl #16125        .reloc ., R_AARCH64_MOVW_UABS_G2_NC, abs64126        movk x0, #0x1234, lsl #32127        // CODE-NEXT:  200008: f2ceeee0      movk    x0, #0x7777, lsl #32128        .reloc ., R_AARCH64_MOVW_UABS_G3,    abs64129        movk x0, #0x1234, lsl #48130        // CODE-NEXT:  20000c: f2eeeee0      movk    x0, #0x7777, lsl #48131 132// The same, but this constant has ffff in the middle 32 bits, forcing carries133// to be propagated.134 135// Expected constant: 0x77ffffffffffff77 + 0x1234 = 0x78000000000011ab136 137        .reloc ., R_AARCH64_MOVW_UABS_G0_NC, big64138        movz x0, #0x1234139        // CODE-NEXT:  200010: d2823560      mov     x0, #0x11ab140        .reloc ., R_AARCH64_MOVW_UABS_G1_NC, big64141        movk x0, #0x1234, lsl #16142        // CODE-NEXT:  200014: f2a00000      movk    x0, #0x0, lsl #16143        .reloc ., R_AARCH64_MOVW_UABS_G2_NC, big64144        movk x0, #0x1234, lsl #32145        // CODE-NEXT:  200018: f2c00000      movk    x0, #0x0, lsl #32146        .reloc ., R_AARCH64_MOVW_UABS_G3,    big64147        movk x0, #0x1234, lsl #48148        // CODE-NEXT:  20001c: f2ef0000      movk    x0, #0x7800, lsl #48149 150// Demonstrate that offsets are treated as signed: this one is taken to be151// -0x1234. (If it were +0xedcc then you'd be able to tell the difference by152// the carry into the second halfword.)153 154// Expected value: 0x7777777777777777 - 0x1234 = 0x7777777777776543155 156        .reloc ., R_AARCH64_MOVW_UABS_G0_NC, abs64157        movz x0, #0xedcc158        // CODE-NEXT:  200020: d28ca860      mov     x0, #0x6543159        .reloc ., R_AARCH64_MOVW_UABS_G1_NC, abs64160        movk x0, #0xedcc, lsl #16161        // CODE-NEXT:  200024: f2aeeee0      movk    x0, #0x7777, lsl #16162        .reloc ., R_AARCH64_MOVW_UABS_G2_NC, abs64163        movk x0, #0xedcc, lsl #32164        // CODE-NEXT:  200028: f2ceeee0      movk    x0, #0x7777, lsl #32165        .reloc ., R_AARCH64_MOVW_UABS_G3,    abs64166        movk x0, #0xedcc, lsl #48167        // CODE-NEXT:  20002c: f2eeeee0      movk    x0, #0x7777, lsl #48168 169// Check various bits of the ADR immediate, including in particular the low 2170// 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 bit173// of the addend is the top bit, counting as negative, i.e. we expect the value174// 0x254678 - 0x100000 = 0x145678.175 176        .reloc ., R_AARCH64_ADR_PREL_LO21, pcrel177        adr x0, .+1178        // CODE-NEXT:  200030: 3022b240      adr     x0, 0x245679179        .reloc ., R_AARCH64_ADR_PREL_LO21, pcrel180        adr x0, .+2181        // CODE-NEXT:  200034: 5022b220      adr     x0, 0x24567a182        .reloc ., R_AARCH64_ADR_PREL_LO21, pcrel183        adr x0, .+4184        // CODE-NEXT:  200038: 1022b220      adr     x0, 0x24567c185        .reloc ., R_AARCH64_ADR_PREL_LO21, pcrel186        adr x0, .+8187        // CODE-NEXT:  20003c: 1022b220      adr     x0, 0x245680188        .reloc ., R_AARCH64_ADR_PREL_LO21, pcrel189        adr x0, .+1<<19190        // CODE-NEXT:  200040: 1062b1c0      adr     x0, 0x2c5678191        .reloc ., R_AARCH64_ADR_PREL_LO21, pcrel192        adr x0, .-1<<20193        // CODE-NEXT:  200044: 10a2b1a0      adr     x0, 0x145678194 195// Now load the same set of values with ADRP+ADD. But because the real ADRP196// instruction shifts its immediate, we must account for that.197 198        .reloc ., R_AARCH64_ADR_PREL_PG_HI21, pcrel199        adrp x0, 1<<12200        // CODE-NEXT:  200048: b0000220      adrp    x0, 0x245000201        .reloc ., R_AARCH64_ADD_ABS_LO12_NC,  pcrel202        add x0, x0, #1203        // CODE-NEXT:  20004c: 9119e400      add     x0, x0, #0x679204        .reloc ., R_AARCH64_ADR_PREL_PG_HI21, pcrel205        adrp x0, 2<<12206        // CODE-NEXT:  200050: b0000220      adrp    x0, 0x245000207        .reloc ., R_AARCH64_ADD_ABS_LO12_NC,  pcrel208        add x0, x0, #2209        // CODE-NEXT:  200054: 9119e800      add     x0, x0, #0x67a210        .reloc ., R_AARCH64_ADR_PREL_PG_HI21, pcrel211        adrp x0, 4<<12212        // CODE-NEXT:  200058: b0000220      adrp    x0, 0x245000213        .reloc ., R_AARCH64_ADD_ABS_LO12_NC,  pcrel214        add x0, x0, #4215        // CODE-NEXT:  20005c: 9119f000      add     x0, x0, #0x67c216        .reloc ., R_AARCH64_ADR_PREL_PG_HI21, pcrel217        adrp x0, 8<<12218        // CODE-NEXT:  200060: b0000220      adrp    x0, 0x245000219        .reloc ., R_AARCH64_ADD_ABS_LO12_NC,  pcrel220        add x0, x0, #8221        // CODE-NEXT:  200064: 911a0000      add     x0, x0, #0x680222 223        // Starting here, the high bits won't fit in the ADD immediate, so that224        // becomes 0, and only the ADRP immediate shows evidence of the addend.225 226        .reloc ., R_AARCH64_ADR_PREL_PG_HI21, pcrel227        adrp x0, 1<<(19+12)228        // CODE-NEXT:  200068: b0000620      adrp    x0, 0x2c5000229        .reloc ., R_AARCH64_ADD_ABS_LO12_NC,  pcrel230        add x0, x0, #0231        // CODE-NEXT:  20006c: 9119e000      add     x0, x0, #0x678232 233        .reloc ., R_AARCH64_ADR_PREL_PG_HI21, pcrel234        adrp x0, -1<<(20+12)235        // CODE-NEXT:  200070: b0fffa20      adrp    x0, 0x145000236        .reloc ., R_AARCH64_ADD_ABS_LO12_NC,  pcrel237        add x0, x0, #0238        // CODE-NEXT:  200074: 9119e000      add     x0, x0, #0x678239 240        // Finally, an example with a full 21-bit addend.241        // Expected value = 0x245678 + 0xfedcb - 0x100000 = 0x244443242        .reloc ., R_AARCH64_ADR_PREL_PG_HI21, pcrel243        adrp x0, (0xfedcb-0x100000)<<12244        // CODE-NEXT:  200078: 90000220      adrp    x0, 0x244000245        .reloc ., R_AARCH64_ADD_ABS_LO12_NC,  pcrel246        add x0, x0, #0xdcb247        // CODE-NEXT:  20007c: 91110c00      add     x0, x0, #0x443248 249// PC-relative loads, in which the 19-bit offset is shifted. The offsets are250// the same as the ADRs above, except for the first two, which can't be251// 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 as254// `ldr x0, [pc, #offset]`, but LLVM writes just `#offset`.)255 256        .reloc ., R_AARCH64_LD_PREL_LO19,     pcrel257        ldr w0, #4258        // CODE-NEXT:  200080: 1822afe0      ldr     w0, 0x24567c259        .reloc ., R_AARCH64_LD_PREL_LO19,     pcrel260        ldr w0, #8261        // CODE-NEXT:  200084: 1822afe0      ldr     w0, 0x245680262        .reloc ., R_AARCH64_LD_PREL_LO19,     pcrel263        ldr w0, #1<<19264        // CODE-NEXT:  200088: 1862af80      ldr     w0, 0x2c5678265        .reloc ., R_AARCH64_LD_PREL_LO19,     pcrel266        ldr w0, #-1<<20267        // CODE-NEXT:  20008c: 18a2af60      ldr     w0, 0x145678268 269 270// For these, the branch target is 0x200100 plus powers of 2, except the offset271// 2^15, which is negative, because the addend is treated as signed.272 273        .reloc ., R_AARCH64_TSTBR14, branchtarget274        tbnz x1, #63, #4275        // CODE-NEXT:  200090: b7f803a1      tbnz    x1, #0x3f, 0x200104276        .reloc ., R_AARCH64_TSTBR14, branchtarget277        tbnz x1, #62, #8278        // CODE-NEXT:  200094: b7f003a1      tbnz    x1, #0x3e, 0x200108279        .reloc ., R_AARCH64_TSTBR14, branchtarget280        tbnz x1, #61, #1<<14281        // CODE-NEXT:  200098: b7ea0341      tbnz    x1, #0x3d, 0x204100282        .reloc ., R_AARCH64_TSTBR14, branchtarget283        tbnz x1, #60, #-1<<15284        // CODE-NEXT:  20009c: b7e40321      tbnz    x1, #0x3c, 0x1f8100285 286// CONDBR19 is used for both cbz/cbnz and B.cond, so test both at once. Base287// offset is the same again (from 0x200100), but this time, offsets can go up288// to 2^20.289 290        .reloc ., R_AARCH64_CONDBR19, branchtarget291        cbnz x2, #4292        // CODE-NEXT:  2000a0: b5000322      cbnz    x2, 0x200104293        .reloc ., R_AARCH64_CONDBR19, branchtarget294        b.eq #8295        // CODE-NEXT:  2000a4: 54000320      b.eq    0x200108296        .reloc ., R_AARCH64_CONDBR19, branchtarget297        cbz x2, #1<<19298        // CODE-NEXT:  2000a8: b44002c2      cbz     x2, 0x280100299        .reloc ., R_AARCH64_CONDBR19, branchtarget300        b.vs #-1<<20301        // CODE-NEXT:  2000ac: 548002a6      b.vs    0x100100302 303// And for BL and B, the offsets go up to 2^25.304 305        .reloc ., R_AARCH64_CALL26, calltarget306        bl #4307        // CODE-NEXT:  2000b0: 94780015      bl      0x2000104308        .reloc ., R_AARCH64_CALL26, calltarget309        bl #8310        // CODE-NEXT:  2000b4: 94780015      bl      0x2000108311        .reloc ., R_AARCH64_CALL26, calltarget312        bl #1<<24313        // CODE-NEXT:  2000b8: 94b80012      bl      0x3000100314        .reloc ., R_AARCH64_CALL26, calltarget315        bl #-1<<25316        // CODE-NEXT:  2000bc: 97f80011      bl      0x100317 318        .reloc ., R_AARCH64_JUMP26, calltarget319        b #4320        // CODE-NEXT:  2000c0: 14780011      b       0x2000104321        .reloc ., R_AARCH64_JUMP26, calltarget322        b #8323        // CODE-NEXT:  2000c4: 14780011      b       0x2000108324        .reloc ., R_AARCH64_JUMP26, calltarget325        b #1<<24326        // CODE-NEXT:  2000c8: 14b8000e      b       0x3000100327        .reloc ., R_AARCH64_JUMP26, calltarget328        b #-1<<25329        // CODE-NEXT:  2000cc: 17f8000d      b       0x100330