Skip to content
This repository was archived by the owner on Mar 6, 2025. It is now read-only.

Commit 3785783

Browse files
Nelson Chuouuleilei-bot
Nelson Chu
authored andcommitted
RISC-V: Clarify link behaviors of R_RISCV_32/64 relocations with ABS symbol.
There are two improvements, which are all referenced to aarch64, * R_RISCV_32 with non ABS symbol cannot be used under RV64 when making shard objects. * Don't need dynamic relocation for R_RISCV_32/64 under RV32/RV64 when making shared objects, if the referenced symbol is local ABS symbol. However, considering this link, riscv-non-isa/riscv-elf-psabi-doc#341 Seems like we should makes all R_RISCV_32/64 relocs with ABS symbol that don't need any dynamic relocations when making the shared objects. But anyway, I just sync the current behavior as aarch64 ld, in case there are any unexpected behaviors happen. Passed the gcc/binutils regressions in riscv-gnu-toolchain. bfd/ * elfnn-riscv.c (riscv_elf_check_relocs): Only allow R_RISCV_32 with ABS symbol under RV64. (riscv_elf_relocate_section): R_RISCV_32/64 with local ABS symbol under RV32/RV64 doesn't need any dynamic relocation when making shared objects. I just make the implementations similar to other targets, so that will be more easy to mainatain. ld/ * testsuite/ld-riscv-elf/data-reloc*: New testcases. * testsuite/ld-riscv-elf/ld-riscv-elf.exp: Added new data-reloc* testcases, and need to make ifunc-seperate* testcases work for rv32. * testsuite/ld-riscv-elf/ifunc-seperate-caller-nonplt.s: Likewise. * testsuite/ld-riscv-elf/ifunc-seperate-caller-plt.s: Likewise.
1 parent 9237688 commit 3785783

14 files changed

+228
-10
lines changed

bfd/elfnn-riscv.c

+45-8
Original file line numberDiff line numberDiff line change
@@ -806,13 +806,31 @@ riscv_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
806806
case R_RISCV_HI20:
807807
if (bfd_link_pic (info))
808808
return bad_static_reloc (abfd, r_type, h);
809-
/* Fall through. */
809+
goto static_reloc;
810+
811+
case R_RISCV_32:
812+
if (ARCH_SIZE > 32
813+
&& bfd_link_pic (info)
814+
&& (sec->flags & SEC_ALLOC) != 0)
815+
{
816+
if (h != NULL && bfd_is_abs_symbol (&h->root))
817+
break;
818+
819+
reloc_howto_type *r_t = riscv_elf_rtype_to_howto (abfd, r_type);
820+
_bfd_error_handler
821+
(_("%pB: relocation %s against `%s' can not be used in RVNN "
822+
"when making a shared object"),
823+
abfd, r_t ? r_t->name : _("<unknown>"),
824+
h != NULL ? h->root.root.string : "a local symbol");
825+
bfd_set_error (bfd_error_bad_value);
826+
return false;
827+
}
828+
goto static_reloc;
810829

811830
case R_RISCV_COPY:
812831
case R_RISCV_JUMP_SLOT:
813832
case R_RISCV_RELATIVE:
814833
case R_RISCV_64:
815-
case R_RISCV_32:
816834
/* Fall through. */
817835

818836
static_reloc:
@@ -2606,6 +2624,11 @@ riscv_elf_relocate_section (bfd *output_bfd,
26062624
break;
26072625

26082626
case R_RISCV_32:
2627+
/* Non ABS symbol should be blocked in check_relocs. */
2628+
if (ARCH_SIZE > 32)
2629+
break;
2630+
/* Fall through. */
2631+
26092632
case R_RISCV_64:
26102633
if ((input_section->flags & SEC_ALLOC) == 0)
26112634
break;
@@ -2628,7 +2651,6 @@ riscv_elf_relocate_section (bfd *output_bfd,
26282651
{
26292652
Elf_Internal_Rela outrel;
26302653
asection *sreloc;
2631-
bool skip_static_relocation, skip_dynamic_relocation;
26322654

26332655
/* When generating a shared object, these relocations
26342656
are copied into the output file to be resolved at run
@@ -2637,12 +2659,27 @@ riscv_elf_relocate_section (bfd *output_bfd,
26372659
outrel.r_offset =
26382660
_bfd_elf_section_offset (output_bfd, info, input_section,
26392661
rel->r_offset);
2640-
skip_static_relocation = outrel.r_offset != (bfd_vma) -2;
2641-
skip_dynamic_relocation = outrel.r_offset >= (bfd_vma) -2;
2662+
2663+
bool skip = false;
2664+
bool relocate = false;
2665+
if (outrel.r_offset == (bfd_vma) -1)
2666+
skip = true;
2667+
else if (outrel.r_offset == (bfd_vma) -2)
2668+
{
2669+
skip = true;
2670+
relocate = true;
2671+
}
2672+
else if (h != NULL && bfd_is_abs_symbol (&h->root))
2673+
{
2674+
/* Local absolute symbol. */
2675+
skip = (h->forced_local || (h->dynindx == -1));
2676+
relocate = skip;
2677+
}
2678+
26422679
outrel.r_offset += sec_addr (input_section);
26432680

2644-
if (skip_dynamic_relocation)
2645-
memset (&outrel, 0, sizeof outrel);
2681+
if (skip)
2682+
memset (&outrel, 0, sizeof outrel); /* R_RISCV_NONE. */
26462683
else if (h != NULL && h->dynindx != -1
26472684
&& !(bfd_link_pic (info)
26482685
&& SYMBOLIC_BIND (info, h)
@@ -2659,7 +2696,7 @@ riscv_elf_relocate_section (bfd *output_bfd,
26592696

26602697
sreloc = elf_section_data (input_section)->sreloc;
26612698
riscv_elf_append_rela (output_bfd, sreloc, &outrel);
2662-
if (skip_static_relocation)
2699+
if (!relocate)
26632700
continue;
26642701
}
26652702
break;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#source: data-reloc.s
2+
#as: -march=rv32i -mabi=ilp32 -defsym __abs__=1 -defsym __addr__=1 -defsym __undef__=1
3+
#ld: -m[riscv_choose_ilp32_emul] -Ttext 0x8000 --defsym _start=0x0 --defsym abs=0x100 --defsym abs_local=0x200 -shared
4+
#objdump: -dR
5+
6+
.*:[ ]+file format .*
7+
8+
9+
Disassembly of section .text:
10+
11+
0+8000 <addr_globl>:
12+
8000: 00000000 .word 0x00000000
13+
8000: R_RISCV_32 addr_globl
14+
15+
0+8004 <addr_local>:
16+
...
17+
8004: R_RISCV_RELATIVE \*ABS\*\+0x8004
18+
8008: R_RISCV_32 abs
19+
800c: 00000200 .word 0x00000200
20+
8010: 00000000 .word 0x00000000
21+
8010: R_RISCV_32 undef
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#source: data-reloc.s
2+
#as: -march=rv32i -mabi=ilp32 -defsym __abs__=1 -defsym __addr__=1
3+
#ld: -m[riscv_choose_ilp32_emul] -Ttext 0x8000 --defsym _start=0x0 --defsym abs=0x100 --defsym abs_local=0x200 -pie
4+
#objdump: -dR
5+
6+
.*:[ ]+file format .*
7+
8+
Disassembly of section .text:
9+
10+
0+8000 <addr_globl>:
11+
8000: 00000000 .word 0x00000000
12+
8000: R_RISCV_RELATIVE \*ABS\*\+0x8000
13+
14+
0+8004 <addr_local>:
15+
8004: 00000000 .word 0x00000000
16+
8004: R_RISCV_RELATIVE \*ABS\*\+0x8004
17+
8008: 00000100 .word 0x00000100
18+
800c: 00000200 .word 0x00000200
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#source: data-reloc.s
2+
#as: -march=rv32i -mabi=ilp32 -defsym __abs__=1 -defsym __addr__=1 -defsym __undef__=1
3+
#ld: -m[riscv_choose_ilp32_emul] -Ttext 0x8000 --defsym _start=0x0 --defsym abs=0x100 --defsym abs_local=0x200 -shared -Bsymbolic
4+
#objdump: -dR
5+
6+
.*:[ ]+file format .*
7+
8+
9+
Disassembly of section .text:
10+
11+
0+8000 <addr_globl>:
12+
8000: 00000000 .word 0x00000000
13+
8000: R_RISCV_RELATIVE \*ABS\*\+0x8000
14+
15+
0+8004 <addr_local>:
16+
...
17+
8004: R_RISCV_RELATIVE \*ABS\*\+0x8004
18+
8008: R_RISCV_RELATIVE \*ABS\*\+0x100
19+
800c: 00000200 .word 0x00000200
20+
8010: 00000000 .word 0x00000000
21+
8010: R_RISCV_32 undef
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#source: data-reloc.s
2+
#as: -march=rv64i -mabi=lp64 -defsym __abs__=1
3+
#ld: -m[riscv_choose_lp64_emul] -Ttext 0x8000 --defsym _start=0x0 --defsym abs=0x100 --defsym abs_local=0x200 -shared
4+
#objdump: -dR
5+
6+
.*:[ ]+file format .*
7+
8+
9+
Disassembly of section .text:
10+
11+
0+8000 <.text>:
12+
8000: 00000100 .word 0x00000100
13+
8004: 00000200 .word 0x00000200
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#source: data-reloc.s
2+
#as: -march=rv64i -mabi=lp64 -defsym __addr__=1
3+
#ld: -m[riscv_choose_lp64_emul] -Ttext 0x8000 --defsym _start=0x0 -shared
4+
#error: .*relocation R_RISCV_32 against `addr_globl' can not be used in RV64 when making a shared object.*
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#source: data-reloc.s
2+
#as: -march=rv64i -mabi=lp64 -defsym __64_bit__=1 -defsym __abs__=1 -defsym __addr__=1 -defsym __undef__=1
3+
#ld: -m[riscv_choose_lp64_emul] -Ttext 0x8000 --defsym _start=0x0 --defsym abs=0x100 --defsym abs_local=0x200 -shared
4+
#objdump: -dR
5+
6+
.*:[ ]+file format .*
7+
8+
9+
Disassembly of section .text:
10+
11+
0+8000 <addr_globl>:
12+
...
13+
8000: R_RISCV_64 addr_globl
14+
15+
0+8008 <addr_local>:
16+
...
17+
8008: R_RISCV_RELATIVE \*ABS\*\+0x8008
18+
8010: R_RISCV_64 abs
19+
8018: 00000200 .word 0x00000200
20+
...
21+
8020: R_RISCV_64 undef
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#source: data-reloc.s
2+
#as: -march=rv64i -mabi=lp64 -defsym __64_bit__=1 -defsym __abs__=1 -defsym __addr__=1
3+
#ld: -m[riscv_choose_lp64_emul] -Ttext 0x8000 --defsym _start=0x0 --defsym abs=0x100 --defsym abs_local=0x200 -pie
4+
#objdump: -dR
5+
6+
.*:[ ]+file format .*
7+
8+
9+
Disassembly of section .text:
10+
11+
0+8000 <addr_globl>:
12+
...
13+
8000: R_RISCV_RELATIVE \*ABS\*\+0x8000
14+
15+
0+8008 <addr_local>:
16+
...
17+
8008: R_RISCV_RELATIVE \*ABS\*\+0x8008
18+
8010: 00000100 .word 0x00000100
19+
8014: 00000000 .word 0x00000000
20+
8018: 00000200 .word 0x00000200
21+
801c: 00000000 .word 0x00000000
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#source: data-reloc.s
2+
#as: -march=rv64i -mabi=lp64 -defsym __64_bit__=1 -defsym __abs__=1 -defsym __addr__=1 -defsym __undef__=1
3+
#ld: -m[riscv_choose_lp64_emul] -Ttext 0x8000 --defsym _start=0x0 --defsym abs=0x100 --defsym abs_local=0x200 -shared -Bsymbolic
4+
#objdump: -dR
5+
6+
.*:[ ]+file format .*
7+
8+
9+
Disassembly of section .text:
10+
11+
0+8000 <addr_globl>:
12+
...
13+
8000: R_RISCV_RELATIVE \*ABS\*\+0x8000
14+
15+
0+8008 <addr_local>:
16+
...
17+
8008: R_RISCV_RELATIVE \*ABS\*\+0x8008
18+
8010: R_RISCV_RELATIVE \*ABS\*\+0x100
19+
8018: 00000200 .word 0x00000200
20+
...
21+
8020: R_RISCV_64 undef
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#source: data-reloc.s
2+
#as: -march=rv64i -mabi=lp64 -defsym __undef__=1
3+
#ld: -m[riscv_choose_lp64_emul] -Ttext 0x8000 --defsym _start=0x0 -shared
4+
#error: .*relocation R_RISCV_32 against `undef' can not be used in RV64 when making a shared object.*
+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
.macro DATA symbol
2+
.ifdef __64_bit__
3+
.quad \symbol
4+
.else
5+
.word \symbol
6+
.endif
7+
.endm
8+
.ifdef __addr__
9+
.globl addr_globl
10+
addr_globl:
11+
DATA addr_globl
12+
addr_local:
13+
DATA addr_local
14+
.endif
15+
.ifdef __abs__
16+
.hidden abs_local
17+
DATA abs
18+
DATA abs_local
19+
.endif
20+
.ifdef __undef__
21+
DATA undef
22+
.endif

ld/testsuite/ld-riscv-elf/ifunc-seperate-caller-nonplt.s

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,4 @@ main:
2020

2121
.data
2222
foo_addr:
23-
.long foo
23+
.quad foo

ld/testsuite/ld-riscv-elf/ifunc-seperate-caller-plt.s

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,4 @@ main:
2323

2424
.data
2525
foo_addr:
26-
.long foo
26+
.quad foo

ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp

+15
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,16 @@ if [istarget "riscv*-*-*"] {
217217
run_dump_test "shared-lib-nopic-03"
218218
run_dump_test "shared-lib-nopic-04"
219219

220+
run_dump_test "data-reloc-rv64-pic"
221+
run_dump_test "data-reloc-rv64-pie"
222+
run_dump_test "data-reloc-rv64-symbolic"
223+
run_dump_test "data-reloc-rv32-pic"
224+
run_dump_test "data-reloc-rv32-pie"
225+
run_dump_test "data-reloc-rv32-symbolic"
226+
run_dump_test "data-reloc-rv64-abs32-pic"
227+
run_dump_test "data-reloc-rv64-addr32-pic"
228+
run_dump_test "data-reloc-rv64-undef32-pic"
229+
220230
# IFUNC testcases.
221231
# Check IFUNC by single type relocs.
222232
run_dump_test_ifunc "ifunc-reloc-call-01" rv32 exe
@@ -270,6 +280,11 @@ if [istarget "riscv*-*-*"] {
270280
run_dump_test_ifunc "ifunc-plt-got-overwrite" rv64 pie
271281
run_dump_test_ifunc "ifunc-plt-got-overwrite" rv64 pic
272282

283+
# TODO: Make the following tests work under RV32.
284+
if [istarget "riscv32-*-*"] {
285+
return
286+
}
287+
273288
# Setup shared libraries.
274289
run_ld_link_tests {
275290
{ "Build shared library for IFUNC non-PLT caller"

0 commit comments

Comments
 (0)