Skip to content

Commit 60936d9

Browse files
committed
[RISCV] Fix alignment when mixing rvc/norvc relax/norelax code
The issue we want to show is the alignment problem when mixing RVC and non-RVC code, especially when the RVC code is relaxed and the alignment with in the non-RVC region will not got expected alignment requirement. Give an example, this example will build with `rv64gc` and `-mrelax` option, and assume text section is start from `0x1000`: ``` _start: lui a0, %hi(foo) addi a0, a0, %lo(foo) mul a0, a1, a4 .option push .option norelax .option norvc .balign 8 SHOULD_ALIGN_8_HERE: .word 0x12345678 ``` Then when we assemble this file, assembler will insert NOP and `R_RISCV_RELAX`/`R_RISCV_ALIGN` like below: ``` Disassembly of section .text: 0000000000000000 <_start-0x2>: 0: 0001 nop 0: R_RISCV_ALIGN *ABS*+0x2 0000000000000002 <_start>: 2: 00000537 lui a0,0x0 2: R_RISCV_HI20 foo 2: R_RISCV_RELAX *ABS* 6: 00050513 mv a0,a0 6: R_RISCV_LO12_I foo 6: R_RISCV_RELAX *ABS* a: 8082 ret c: 00000013 nop 0000000000000010 <SHOULD_ALIGN_8_HERE>: 10: 12345678 .word 0x12345678 ``` And we didn't insert `R_RISCV_ALIGN` before `SHOULD_ALIGN_8_HERE`, because `norelax` option are given and the alignment seems already meet. However...the linker relaxation will remove first NOP in the text section before the `_start` symbol for meet the alignment requirement, then `SHOULD_ALIGN_8_HERE` no longer aligned to 8 bytes. So this should be fixed in the MC assembler by inserting `R_RISCV_ALIGN` correctly before `SHOULD_ALIGN_8_HERE`, even if the norelax option is given, but that not means we should always inserting that, we just need insert when relax has ever enabled on that section. Also it should emit N-2 bytes NOPs even norvc status if this section has enable RVC ever, so that linker has enough NOPs to remove for meet the alignment requirement. This is not really lld bug, but this must be put within lld testcases so that we can verify the alignment result is wrong after linking. Not all testcase are fail with out this fix, however some of them may fail on binutils side, so I think it worth to put all testcase to lld test to prevent future regression.
1 parent eb0c863 commit 60936d9

15 files changed

+870
-2
lines changed

lld/test/ELF/riscv-relax-align-1.s

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# REQUIRES: riscv
2+
## Testing the aligment is correct when mixing with rvc/norvc relax/norelax
3+
4+
# RUN: rm -rf %t && split-file %s %t && cd %t
5+
6+
## NORVC, NORELAX
7+
# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+relax,+c,+m a.s -o a.o --defsym=NORVC=1 --defsym=NORELAX=1
8+
# RUN: ld.lld -T lds a.o -o a.out
9+
# RUN: llvm-nm a.out | FileCheck %s --check-prefix=NORVC-NORELAX
10+
11+
# NORVC-NORELAX: 0000000000001010 t SHOULD_ALIGN_8_HERE
12+
13+
## NORVC, RELAX
14+
# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+relax,+c,+m a.s -o a.o --defsym=NORVC=1
15+
# RUN: ld.lld -T lds a.o -o a.out
16+
# RUN: llvm-nm a.out | FileCheck %s --check-prefix=NORVC
17+
18+
# NORVC: 0000000000001010 t SHOULD_ALIGN_8_HERE
19+
20+
## RVC, NORELAX
21+
# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+relax,+c,+m a.s -o a.o --defsym=NORELAX=1
22+
# RUN: ld.lld -T lds a.o -o a.out
23+
# RUN: llvm-nm a.out | FileCheck %s --check-prefix=NORELAX
24+
25+
# NORELAX: 0000000000001010 t SHOULD_ALIGN_8_HERE
26+
27+
## RVC, RELAX
28+
# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+relax,+c,+m a.s -o a.o
29+
# RUN: ld.lld -T lds a.o -o a.out
30+
# RUN: llvm-nm a.out | FileCheck %s --check-prefix=RELAX-RVC
31+
32+
# RELAX-RVC: 0000000000001010 t SHOULD_ALIGN_8_HERE
33+
34+
#--- a.s
35+
.text
36+
.option relax
37+
.balign 4
38+
.global _start
39+
.type _start, @function
40+
_start:
41+
lui a0, %hi(foo)
42+
addi a0, a0, %lo(foo)
43+
mul a0, a1, a4
44+
.option push
45+
46+
.ifdef NORELAX
47+
.option norelax
48+
.endif
49+
.ifdef NORVC
50+
.option norvc
51+
.endif
52+
.balign 8
53+
SHOULD_ALIGN_8_HERE:
54+
.word 0x12345678
55+
56+
.option pop
57+
58+
foo:
59+
ret
60+
61+
62+
63+
#--- lds
64+
ENTRY(_start)
65+
SECTIONS {
66+
.text 0x0001000 : {
67+
*(.text*)
68+
}
69+
}

lld/test/ELF/riscv-relax-align-10.s

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# REQUIRES: riscv
2+
## Testing the aligment is correct when mixing with rvc/norvc relax/norelax
3+
4+
# RUN: rm -rf %t && split-file %s %t && cd %t
5+
6+
## NORVC, NORELAX
7+
# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+relax,+c,+m a.s -o a.o --defsym=NORVC=1 --defsym=NORELAX=1
8+
# RUN: ld.lld -T lds a.o -o a.out
9+
# RUN: llvm-nm a.out | FileCheck %s --check-prefix=NORVC-NORELAX
10+
11+
# NORVC-NORELAX: 0000000000001010 t SHOULD_ALIGN_16_HERE
12+
13+
## NORVC, RELAX
14+
# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+relax,+c,+m a.s -o a.o --defsym=NORVC=1
15+
# RUN: ld.lld -T lds a.o -o a.out
16+
# RUN: llvm-nm a.out | FileCheck %s --check-prefix=NORVC
17+
18+
# NORVC: 0000000000001010 t SHOULD_ALIGN_16_HERE
19+
20+
## RVC, NORELAX
21+
# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+relax,+c,+m a.s -o a.o --defsym=NORELAX=1
22+
# RUN: ld.lld -T lds a.o -o a.out
23+
# RUN: llvm-nm a.out | FileCheck %s --check-prefix=NORELAX
24+
25+
# NORELAX: 0000000000001010 t SHOULD_ALIGN_16_HERE
26+
27+
## RVC, RELAX
28+
# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+relax,+c,+m a.s -o a.o
29+
# RUN: ld.lld -T lds a.o -o a.out
30+
# RUN: llvm-nm a.out | FileCheck %s --check-prefix=RELAX-RVC
31+
32+
# RELAX-RVC: 0000000000001010 t SHOULD_ALIGN_16_HERE
33+
34+
#--- a.s
35+
.text
36+
.option relax
37+
.balign 2
38+
.global _start
39+
.type _start, @function
40+
_start:
41+
call foo
42+
.option norvc
43+
mul a0, a1, a4
44+
.option push
45+
46+
.ifdef NORELAX
47+
.option norelax
48+
.endif
49+
.ifdef NORVC
50+
.option norvc
51+
.endif
52+
.balign 16
53+
SHOULD_ALIGN_16_HERE:
54+
.word 0x12345678
55+
56+
.option pop
57+
58+
foo:
59+
ret
60+
61+
62+
63+
#--- lds
64+
ENTRY(_start)
65+
SECTIONS {
66+
.text 0x0001000 : {
67+
*(.text*)
68+
}
69+
}

lld/test/ELF/riscv-relax-align-11.s

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# REQUIRES: riscv
2+
## Testing the aligment is correct when mixing with rvc/norvc relax/norelax
3+
4+
# RUN: rm -rf %t && split-file %s %t && cd %t
5+
6+
## NORVC, NORELAX
7+
# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+relax,+c,+m a.s -o a.o --defsym=NORVC=1 --defsym=NORELAX=1
8+
# RUN: ld.lld -T lds a.o -o a.out
9+
# RUN: llvm-nm a.out | FileCheck %s --check-prefix=NORVC-NORELAX
10+
11+
# NORVC-NORELAX: 0000000000001010 t SHOULD_ALIGN_16_HERE
12+
13+
## NORVC, RELAX
14+
# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+relax,+c,+m a.s -o a.o --defsym=NORVC=1
15+
# RUN: ld.lld -T lds a.o -o a.out
16+
# RUN: llvm-nm a.out | FileCheck %s --check-prefix=NORVC
17+
18+
# NORVC: 0000000000001010 t SHOULD_ALIGN_16_HERE
19+
20+
## RVC, NORELAX
21+
# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+relax,+c,+m a.s -o a.o --defsym=NORELAX=1
22+
# RUN: ld.lld -T lds a.o -o a.out
23+
# RUN: llvm-nm a.out | FileCheck %s --check-prefix=NORELAX
24+
25+
# NORELAX: 0000000000001010 t SHOULD_ALIGN_16_HERE
26+
27+
## RVC, RELAX
28+
# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+relax,+c,+m a.s -o a.o
29+
# RUN: ld.lld -T lds a.o -o a.out
30+
# RUN: llvm-nm a.out | FileCheck %s --check-prefix=RELAX-RVC
31+
32+
# RELAX-RVC: 0000000000001010 t SHOULD_ALIGN_16_HERE
33+
34+
#--- a.s
35+
.text
36+
.option relax
37+
.balign 2
38+
.global _start
39+
.type _start, @function
40+
_start:
41+
lui a0, %hi(foo)
42+
addi a0, a0, %lo(foo)
43+
.option norvc
44+
mul a0, a1, a4
45+
.option push
46+
47+
.ifdef NORELAX
48+
.option norelax
49+
.endif
50+
.ifdef NORVC
51+
.option norvc
52+
.endif
53+
.balign 16
54+
SHOULD_ALIGN_16_HERE:
55+
ret
56+
57+
.option pop
58+
59+
foo:
60+
ret
61+
62+
63+
64+
#--- lds
65+
ENTRY(_start)
66+
SECTIONS {
67+
.text 0x0001000 : {
68+
*(.text*)
69+
}
70+
}

lld/test/ELF/riscv-relax-align-12.s

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# REQUIRES: riscv
2+
## Testing the aligment is correct when mixing with rvc/norvc relax/norelax
3+
4+
# RUN: rm -rf %t && split-file %s %t && cd %t
5+
6+
## NORVC, NORELAX
7+
# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+relax,+c,+m a.s -o a.o --defsym=NORVC=1 --defsym=NORELAX=1
8+
# RUN: ld.lld -T lds a.o -o a.out
9+
# RUN: llvm-nm a.out | FileCheck %s --check-prefix=NORVC-NORELAX
10+
11+
# NORVC-NORELAX: 0000000000001010 t SHOULD_ALIGN_16_HERE
12+
13+
## NORVC, RELAX
14+
# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+relax,+c,+m a.s -o a.o --defsym=NORVC=1
15+
# RUN: ld.lld -T lds a.o -o a.out
16+
# RUN: llvm-nm a.out | FileCheck %s --check-prefix=NORVC
17+
18+
# NORVC: 0000000000001010 t SHOULD_ALIGN_16_HERE
19+
20+
## RVC, NORELAX
21+
# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+relax,+c,+m a.s -o a.o --defsym=NORELAX=1
22+
# RUN: ld.lld -T lds a.o -o a.out
23+
# RUN: llvm-nm a.out | FileCheck %s --check-prefix=NORELAX
24+
25+
# NORELAX: 0000000000001010 t SHOULD_ALIGN_16_HERE
26+
27+
## RVC, RELAX
28+
# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+relax,+c,+m a.s -o a.o
29+
# RUN: ld.lld -T lds a.o -o a.out
30+
# RUN: llvm-nm a.out | FileCheck %s --check-prefix=RELAX-RVC
31+
32+
# RELAX-RVC: 0000000000001010 t SHOULD_ALIGN_16_HERE
33+
34+
#--- a.s
35+
.text
36+
.option relax
37+
.balign 2
38+
.global _start
39+
.type _start, @function
40+
_start:
41+
call foo
42+
.option norvc
43+
mul a0, a1, a4
44+
.option push
45+
46+
.ifdef NORELAX
47+
.option norelax
48+
.endif
49+
.ifdef NORVC
50+
.option norvc
51+
.endif
52+
.balign 16
53+
SHOULD_ALIGN_16_HERE:
54+
ret
55+
56+
.option pop
57+
58+
foo:
59+
ret
60+
61+
62+
63+
#--- lds
64+
ENTRY(_start)
65+
SECTIONS {
66+
.text 0x0001000 : {
67+
*(.text*)
68+
}
69+
}

lld/test/ELF/riscv-relax-align-2.s

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# REQUIRES: riscv
2+
## Testing the aligment is correct when mixing with rvc/norvc relax/norelax
3+
4+
# RUN: rm -rf %t && split-file %s %t && cd %t
5+
6+
## NORVC, NORELAX
7+
# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+relax,+c,+m a.s -o a.o --defsym=NORVC=1 --defsym=NORELAX=1
8+
# RUN: ld.lld -T lds a.o -o a.out
9+
# RUN: llvm-nm a.out | FileCheck %s --check-prefix=NORVC-NORELAX
10+
11+
# NORVC-NORELAX: 0000000000001008 t SHOULD_ALIGN_8_HERE
12+
13+
## NORVC, RELAX
14+
# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+relax,+c,+m a.s -o a.o --defsym=NORVC=1
15+
# RUN: ld.lld -T lds a.o -o a.out
16+
# RUN: llvm-nm a.out | FileCheck %s --check-prefix=NORVC
17+
18+
# NORVC: 0000000000001008 t SHOULD_ALIGN_8_HERE
19+
20+
## RVC, NORELAX
21+
# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+relax,+c,+m a.s -o a.o --defsym=NORELAX=1
22+
# RUN: ld.lld -T lds a.o -o a.out
23+
# RUN: llvm-nm a.out | FileCheck %s --check-prefix=NORELAX
24+
25+
# NORELAX: 0000000000001008 t SHOULD_ALIGN_8_HERE
26+
27+
## RVC, RELAX
28+
# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+relax,+c,+m a.s -o a.o
29+
# RUN: ld.lld -T lds a.o -o a.out
30+
# RUN: llvm-nm a.out | FileCheck %s --check-prefix=RELAX-RVC
31+
32+
# RELAX-RVC: 0000000000001008 t SHOULD_ALIGN_8_HERE
33+
34+
#--- a.s
35+
.text
36+
.option relax
37+
.balign 4
38+
.global _start
39+
.type _start, @function
40+
_start:
41+
call foo
42+
mul a0, a1, a4
43+
.option push
44+
45+
.ifdef NORELAX
46+
.option norelax
47+
.endif
48+
.ifdef NORVC
49+
.option norvc
50+
.endif
51+
.balign 8
52+
SHOULD_ALIGN_8_HERE:
53+
.word 0x12345678
54+
55+
.option pop
56+
57+
foo:
58+
ret
59+
60+
61+
62+
#--- lds
63+
ENTRY(_start)
64+
SECTIONS {
65+
.text 0x0001000 : {
66+
*(.text*)
67+
}
68+
}

0 commit comments

Comments
 (0)