[lld] [lld][AArch64] Fix handling of SHT_REL relocation addends. (PR #98291)
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 15 10:48:59 PDT 2024
================
@@ -1,97 +1,318 @@
-## Test certain REL relocation types generated by legacy armasm.
-# RUN: yaml2obj %s -o %t.o
-# RUN: ld.lld %t.o -o %t
-# RUN: llvm-objdump -s %t | FileCheck %s
-
-# CHECK: Contents of section .abs:
-# CHECK-NEXT: [[#%x,]] 29002800 00002700 00000000 0000fcff ).(...'.........
-# CHECK-NEXT: [[#%x,]] ffffffff ffff ......
-# CHECK-NEXT: Contents of section .uabs:
-# CHECK-NEXT: [[#%x,]] 40ffffff 40ffffff 20ffffff 20ffffff @... at ... ... ...
-# CHECK-NEXT: [[#%x,]] 00ffffff 00ffffff ........
-# CHECK-NEXT: Contents of section .prel:
-# CHECK-NEXT: [[#%x,]] 00ffffff fcfeffff f8feffff a0ffffff ................
-# CHECK-NEXT: [[#%x,]] 0010009f 0010009f ........
-# CHECK-NEXT: Contents of section .branch:
-# CHECK-NEXT: [[#%x,]] f0ffffff f0ffffff fdffffff fcffff14 ................
-
----
-!ELF
-FileHeader:
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- Type: ET_REL
- Machine: EM_AARCH64
-Sections:
- - Name: .abs
- Type: SHT_PROGBITS
- Flags: [ SHF_ALLOC ]
- Content: fffffefffffffdfffffffffffffffcffffffffffffff
- - Name: .rel.abs
- Type: SHT_REL
- Link: .symtab
- Info: .abs
- Relocations:
- - {Offset: 0, Symbol: abs, Type: R_AARCH64_ABS16}
- - {Offset: 2, Symbol: abs, Type: R_AARCH64_ABS32}
- - {Offset: 6, Symbol: abs, Type: R_AARCH64_ABS64}
- - {Offset: 14, Symbol: abs, Type: R_AARCH64_ADD_ABS_LO12_NC}
-
- - Name: .uabs
- Type: SHT_PROGBITS
- Flags: [ SHF_ALLOC ]
- AddressAlign: 4
- Content: 00ffffff00ffffff00ffffff00ffffff00ffffff00ffffff
- - Name: .rel.uabs
- Type: SHT_REL
- Link: .symtab
- Info: .uabs
- Relocations:
- - {Offset: 0, Symbol: abs, Type: R_AARCH64_MOVW_UABS_G0}
- - {Offset: 4, Symbol: abs, Type: R_AARCH64_MOVW_UABS_G0_NC}
- - {Offset: 8, Symbol: abs, Type: R_AARCH64_MOVW_UABS_G1}
- - {Offset: 12, Symbol: abs, Type: R_AARCH64_MOVW_UABS_G1_NC}
- - {Offset: 16, Symbol: abs, Type: R_AARCH64_MOVW_UABS_G2}
- - {Offset: 20, Symbol: abs, Type: R_AARCH64_MOVW_UABS_G2_NC}
-
- - Name: .prel
- Type: SHT_PROGBITS
- Flags: [ SHF_ALLOC ]
- AddressAlign: 4
- Content: 00ffffff00ffffff00ffffff00ffffff00ffffff00ffffff
- - Name: .rel.prel
- Type: SHT_REL
- Link: .symtab
- Info: .prel
- Relocations:
- - {Offset: 0, Symbol: .prel, Type: R_AARCH64_PREL64}
- - {Offset: 4, Symbol: .prel, Type: R_AARCH64_PREL32}
- - {Offset: 8, Symbol: .prel, Type: R_AARCH64_PREL16}
- - {Offset: 12, Symbol: .prel, Type: R_AARCH64_LD_PREL_LO19}
- - {Offset: 16, Symbol: .prel, Type: R_AARCH64_ADR_PREL_PG_HI21}
- - {Offset: 20, Symbol: .prel, Type: R_AARCH64_ADR_PREL_PG_HI21_NC}
-
- - Name: .branch
- Type: SHT_PROGBITS
- Flags: [ SHF_ALLOC ]
- AddressAlign: 4
- Content: f0fffffff0fffffff0fffffff0ffffff
- - Name: .rel.branch
- Type: SHT_REL
- Link: .symtab
- Info: .branch
- Relocations:
- - {Offset: 0, Symbol: .branch, Type: R_AARCH64_TSTBR14}
- - {Offset: 4, Symbol: .branch, Type: R_AARCH64_CONDBR19}
- - {Offset: 8, Symbol: .branch, Type: R_AARCH64_CALL26}
- - {Offset: 12, Symbol: .branch, Type: R_AARCH64_JUMP26}
-
-Symbols:
- - Name: .branch
- Section: .branch
- - Name: .prel
- Section: .prel
- - Name: abs
- Index: SHN_ABS
- Value: 42
- Binding: STB_GLOBAL
+REQUIRES: aarch64
+
+## Test handling of addends taken from the relocated word or instruction
+## in AArch64 relocation sections of type SHT_REL. These can be generated
+## by assemblers other than LLVM, in particular the legacy 'armasm'.
+##
+## llvm-mc will only generate SHT_RELA when targeting AArch64. So to make
+## an input file with SHT_REL, we assemble our test source file, then
+## round-trip via YAML and do some seddery to change the type of the
+## relocation section. Since all the relocations were made manually with
+## .reloc directives containing no addend, this succeeds.
+
+# RUN: rm -rf %t
+# RUN: split-file %s %t
+
+# RUN: llvm-mc -filetype=obj -triple=aarch64 %t/Inputs/relocs.s -o %t/rela.o
+# RUN: obj2yaml %t/rela.o -o %t/rela.yaml
+# RUN: sed "s/\.rela/\.rel/;s/SHT_RELA/SHT_REL/" %t/rela.yaml > %t/rel.yaml
+# RUN: yaml2obj %t/rel.yaml -o %t/rel.o
+# RUN: llvm-mc -filetype=obj -triple=aarch64 %t/Inputs/symbols.s -o %t/symbols.o
+# RUN: ld.lld %t/rel.o %t/symbols.o -o %t/a.out --section-start=.data=0x100000 --section-start=.text=0x200000
+# RUN: llvm-objdump -s %t/a.out | FileCheck %s --check-prefix=DATA
+# RUN: llvm-objdump -d %t/a.out | FileCheck %s --check-prefix=CODE
+
+#--- Inputs/symbols.s
+
+// Source file containing the values of target symbols for the relocations. If
+// we don't keep these in their own file, then llvm-mc is clever enough to
+// resolve some of the relocations during assembly, even though they're written
+// as explicit .reloc directives. But we want the relocations to be present in
+// the object file, so that yaml2obj can change their type and we can test
+// lld's handling of the result. So we ensure that llvm-mc can't see both the
+// .reloc and the target symbol value at the same time.
+
+.globl abs16
+.globl abs32
+.globl abs64
+.globl big64
+.globl pcrel
+.globl data
+.globl branchtarget
+.globl calltarget
+
+.equ abs16, 0x9999
+.equ data, 0x100000
+.equ branchtarget, 0x200100
+.equ calltarget, 0x02000100
+.equ pcrel, 0x245678
+.equ abs32, 0x88888888
+.equ abs64, 0x7777777777777777
+.equ big64, 0x77ffffffffffff77
+
+#--- Inputs/relocs.s
+
+// Source file containing the test instructions and their relocations, with the
+// FileCheck comments interleaved.
+
+// DATA: Contents of section .data:
+.data
+
+// First test absolute data relocations. For each one I show the expected
+// value in a comment, and then expect a line in llvm-objdump -s containing
+// all the values together.
+
+ // 0x7777777777777777 + 0x1234567887654321 = 0x89abcdeffedcba98
+ .reloc ., R_AARCH64_ABS64, abs64
+ .xword 0x1234567887654321
+
+ // 0x88888888 + 0x12344321 = 0x9abccba9
+ .reloc ., R_AARCH64_ABS32, abs32
+ .word 0x12344321
+
+ // 0x9999 + 0x1234 = 0xabcd
+ .reloc ., R_AARCH64_ABS16, abs16
+ .hword 0x1234
+
+ // DATA-NEXT: 100000 98badcfe efcdab89 a9cbbc9a cdab
+
+ .balign 16
+
+// Test relative data relocs, each subtracting the address of the relocated
+// word.
+
+ // 0x100000 + 0x1234567887654321 - 0x100010 = 0x1234567887654311
+ .reloc ., R_AARCH64_PREL64, data
+ .xword 0x1234567887654321
+
+ // 0x100000 + 0x12344321 - 0x100018 = 0x12344309
+ .reloc ., R_AARCH64_PREL32, data
+ .word 0x12344321
+
+ // 0x100000 + 0x1234 - 0x10001c = 0x1218
+ .reloc ., R_AARCH64_PREL16, data
+ .hword 0x1234
+
+ // DATA-NEXT: 100010 11436587 78563412 09433412 1812
+
+// CODE: 0000000000200000 <_start>:
+.text
+.globl _start
+_start:
+
+// Full set of 4 instructions loading the constant 'abs64' and adding 0x1234 to
+// it.
+
+// Expected constant is 0x7777777777777777 + 0x1234 = 0x77777777777789ab
+
+ .reloc ., R_AARCH64_MOVW_UABS_G0_NC, abs64
+ movz x0, #0x1234
+ // CODE-NEXT: 200000: d2913560 mov x0, #0x89ab
+ .reloc ., R_AARCH64_MOVW_UABS_G1_NC, abs64
+ movk x0, #0x1234, lsl #16
+ // CODE-NEXT: 200004: f2aeeee0 movk x0, #0x7777, lsl #16
----------------
MaskRay wrote:
We can remove the leading addresses so that changing the address would not require updates to every CHECK line.
In other tests, we keep some addresses when the instruction is referenced. I think that doesn't apply to this test.
https://github.com/llvm/llvm-project/pull/98291
More information about the llvm-commits
mailing list