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, https://github.com/riscv-non-isa/riscv-elf-psabi-doc/issues/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.
This commit is contained in:
parent
23068b02d3
commit
b679fb488a
@ -734,6 +734,7 @@ riscv_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
||||
unsigned int r_type;
|
||||
unsigned int r_symndx;
|
||||
struct elf_link_hash_entry *h;
|
||||
bool is_abs_symbol = false;
|
||||
|
||||
r_symndx = ELFNN_R_SYM (rel->r_info);
|
||||
r_type = ELFNN_R_TYPE (rel->r_info);
|
||||
@ -753,6 +754,8 @@ riscv_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
||||
if (isym == NULL)
|
||||
return false;
|
||||
|
||||
is_abs_symbol = isym->st_shndx == SHN_ABS ? true : false;
|
||||
|
||||
/* Check relocation against local STT_GNU_IFUNC symbol. */
|
||||
if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
|
||||
{
|
||||
@ -778,6 +781,8 @@ riscv_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
||||
while (h->root.type == bfd_link_hash_indirect
|
||||
|| h->root.type == bfd_link_hash_warning)
|
||||
h = (struct elf_link_hash_entry *) h->root.u.i.link;
|
||||
|
||||
is_abs_symbol = bfd_is_abs_symbol (&h->root) ? true : false;
|
||||
}
|
||||
|
||||
if (h != NULL)
|
||||
@ -879,13 +884,31 @@ riscv_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
||||
case R_RISCV_HI20:
|
||||
if (bfd_link_pic (info))
|
||||
return bad_static_reloc (abfd, r_type, h);
|
||||
/* Fall through. */
|
||||
goto static_reloc;
|
||||
|
||||
case R_RISCV_32:
|
||||
if (ARCH_SIZE > 32
|
||||
&& bfd_link_pic (info)
|
||||
&& (sec->flags & SEC_ALLOC) != 0)
|
||||
{
|
||||
if (is_abs_symbol)
|
||||
break;
|
||||
|
||||
reloc_howto_type *r_t = riscv_elf_rtype_to_howto (abfd, r_type);
|
||||
_bfd_error_handler
|
||||
(_("%pB: relocation %s against non-absolute symbol `%s' can "
|
||||
"not be used in RVNN when making a shared object"),
|
||||
abfd, r_t ? r_t->name : _("<unknown>"),
|
||||
h != NULL ? h->root.root.string : "a local symbol");
|
||||
bfd_set_error (bfd_error_bad_value);
|
||||
return false;
|
||||
}
|
||||
goto static_reloc;
|
||||
|
||||
case R_RISCV_COPY:
|
||||
case R_RISCV_JUMP_SLOT:
|
||||
case R_RISCV_RELATIVE:
|
||||
case R_RISCV_64:
|
||||
case R_RISCV_32:
|
||||
/* Fall through. */
|
||||
|
||||
static_reloc:
|
||||
@ -2630,6 +2653,11 @@ riscv_elf_relocate_section (bfd *output_bfd,
|
||||
break;
|
||||
|
||||
case R_RISCV_32:
|
||||
/* Non ABS symbol should be blocked in check_relocs. */
|
||||
if (ARCH_SIZE > 32)
|
||||
break;
|
||||
/* Fall through. */
|
||||
|
||||
case R_RISCV_64:
|
||||
if ((input_section->flags & SEC_ALLOC) == 0)
|
||||
break;
|
||||
@ -2639,7 +2667,6 @@ riscv_elf_relocate_section (bfd *output_bfd,
|
||||
{
|
||||
Elf_Internal_Rela outrel;
|
||||
asection *sreloc;
|
||||
bool skip_static_relocation, skip_dynamic_relocation;
|
||||
|
||||
/* When generating a shared object, these relocations
|
||||
are copied into the output file to be resolved at run
|
||||
@ -2648,26 +2675,44 @@ riscv_elf_relocate_section (bfd *output_bfd,
|
||||
outrel.r_offset =
|
||||
_bfd_elf_section_offset (output_bfd, info, input_section,
|
||||
rel->r_offset);
|
||||
skip_static_relocation = outrel.r_offset != (bfd_vma) -2;
|
||||
skip_dynamic_relocation = outrel.r_offset >= (bfd_vma) -2;
|
||||
bool skip = false;
|
||||
bool relocate = false;
|
||||
if (outrel.r_offset == (bfd_vma) -1)
|
||||
skip = true;
|
||||
else if (outrel.r_offset == (bfd_vma) -2)
|
||||
{
|
||||
skip = true;
|
||||
relocate = true;
|
||||
}
|
||||
else if (h != NULL && bfd_is_abs_symbol (&h->root))
|
||||
{
|
||||
/* Don't need dynamic reloc when the ABS symbol is
|
||||
non-dynamic or forced to local. Maybe just use
|
||||
SYMBOL_REFERENCES_LOCAL to check? */
|
||||
skip = (h->forced_local || (h->dynindx == -1));
|
||||
relocate = skip;
|
||||
}
|
||||
|
||||
outrel.r_offset += sec_addr (input_section);
|
||||
|
||||
if (skip_dynamic_relocation)
|
||||
memset (&outrel, 0, sizeof outrel);
|
||||
if (skip)
|
||||
memset (&outrel, 0, sizeof outrel); /* R_RISCV_NONE. */
|
||||
else if (RISCV_COPY_INPUT_RELOC (info, h))
|
||||
{
|
||||
/* Maybe just use !SYMBOL_REFERENCES_LOCAL to check? */
|
||||
outrel.r_info = ELFNN_R_INFO (h->dynindx, r_type);
|
||||
outrel.r_addend = rel->r_addend;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This symbol is local, or marked to become local. */
|
||||
outrel.r_info = ELFNN_R_INFO (0, R_RISCV_RELATIVE);
|
||||
outrel.r_addend = relocation + rel->r_addend;
|
||||
}
|
||||
|
||||
sreloc = elf_section_data (input_section)->sreloc;
|
||||
riscv_elf_append_rela (output_bfd, sreloc, &outrel);
|
||||
if (skip_static_relocation)
|
||||
if (!relocate)
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
21
ld/testsuite/ld-riscv-elf/data-reloc-rv32-pic.d
Normal file
21
ld/testsuite/ld-riscv-elf/data-reloc-rv32-pic.d
Normal file
@ -0,0 +1,21 @@
|
||||
#source: data-reloc.s
|
||||
#as: -march=rv32i -mabi=ilp32 -defsym __abs__=1 -defsym __addr__=1 -defsym __undef__=1
|
||||
#ld: -m[riscv_choose_ilp32_emul] -Ttext 0x8000 --defsym _start=0x0 --defsym abs=0x100 --defsym abs_local=0x200 -shared
|
||||
#objdump: -dR
|
||||
|
||||
.*:[ ]+file format .*
|
||||
|
||||
|
||||
Disassembly of section .text:
|
||||
|
||||
0+8000 <addr_globl>:
|
||||
8000: 00000000 .word 0x00000000
|
||||
8000: R_RISCV_32 addr_globl
|
||||
|
||||
0+8004 <addr_local>:
|
||||
...
|
||||
8004: R_RISCV_RELATIVE \*ABS\*\+0x8004
|
||||
8008: R_RISCV_32 abs
|
||||
800c: 00000200 .word 0x00000200
|
||||
8010: 00000000 .word 0x00000000
|
||||
8010: R_RISCV_32 undef
|
18
ld/testsuite/ld-riscv-elf/data-reloc-rv32-pie.d
Normal file
18
ld/testsuite/ld-riscv-elf/data-reloc-rv32-pie.d
Normal file
@ -0,0 +1,18 @@
|
||||
#source: data-reloc.s
|
||||
#as: -march=rv32i -mabi=ilp32 -defsym __abs__=1 -defsym __addr__=1
|
||||
#ld: -m[riscv_choose_ilp32_emul] -Ttext 0x8000 --defsym _start=0x0 --defsym abs=0x100 --defsym abs_local=0x200 -pie
|
||||
#objdump: -dR
|
||||
|
||||
.*:[ ]+file format .*
|
||||
|
||||
Disassembly of section .text:
|
||||
|
||||
0+8000 <addr_globl>:
|
||||
8000: 00000000 .word 0x00000000
|
||||
8000: R_RISCV_RELATIVE \*ABS\*\+0x8000
|
||||
|
||||
0+8004 <addr_local>:
|
||||
8004: 00000000 .word 0x00000000
|
||||
8004: R_RISCV_RELATIVE \*ABS\*\+0x8004
|
||||
8008: 00000100 .word 0x00000100
|
||||
800c: 00000200 .word 0x00000200
|
21
ld/testsuite/ld-riscv-elf/data-reloc-rv32-symbolic.d
Normal file
21
ld/testsuite/ld-riscv-elf/data-reloc-rv32-symbolic.d
Normal file
@ -0,0 +1,21 @@
|
||||
#source: data-reloc.s
|
||||
#as: -march=rv32i -mabi=ilp32 -defsym __abs__=1 -defsym __addr__=1 -defsym __undef__=1
|
||||
#ld: -m[riscv_choose_ilp32_emul] -Ttext 0x8000 --defsym _start=0x0 --defsym abs=0x100 --defsym abs_local=0x200 -shared -Bsymbolic
|
||||
#objdump: -dR
|
||||
|
||||
.*:[ ]+file format .*
|
||||
|
||||
|
||||
Disassembly of section .text:
|
||||
|
||||
0+8000 <addr_globl>:
|
||||
8000: 00000000 .word 0x00000000
|
||||
8000: R_RISCV_RELATIVE \*ABS\*\+0x8000
|
||||
|
||||
0+8004 <addr_local>:
|
||||
...
|
||||
8004: R_RISCV_RELATIVE \*ABS\*\+0x8004
|
||||
8008: R_RISCV_RELATIVE \*ABS\*\+0x100
|
||||
800c: 00000200 .word 0x00000200
|
||||
8010: 00000000 .word 0x00000000
|
||||
8010: R_RISCV_32 undef
|
13
ld/testsuite/ld-riscv-elf/data-reloc-rv64-abs32-pic.d
Normal file
13
ld/testsuite/ld-riscv-elf/data-reloc-rv64-abs32-pic.d
Normal file
@ -0,0 +1,13 @@
|
||||
#source: data-reloc.s
|
||||
#as: -march=rv64i -mabi=lp64 -defsym __abs__=1
|
||||
#ld: -m[riscv_choose_lp64_emul] -Ttext 0x8000 --defsym _start=0x0 --defsym abs=0x100 --defsym abs_local=0x200 -shared
|
||||
#objdump: -dR
|
||||
|
||||
.*:[ ]+file format .*
|
||||
|
||||
|
||||
Disassembly of section .text:
|
||||
|
||||
0+8000 <.text>:
|
||||
8000: 00000100 .word 0x00000100
|
||||
8004: 00000200 .word 0x00000200
|
4
ld/testsuite/ld-riscv-elf/data-reloc-rv64-addr32-pic.d
Normal file
4
ld/testsuite/ld-riscv-elf/data-reloc-rv64-addr32-pic.d
Normal file
@ -0,0 +1,4 @@
|
||||
#source: data-reloc.s
|
||||
#as: -march=rv64i -mabi=lp64 -defsym __addr__=1
|
||||
#ld: -m[riscv_choose_lp64_emul] -Ttext 0x8000 --defsym _start=0x0 -shared
|
||||
#error: .*relocation R_RISCV_32 against non-absolute symbol `addr_globl' can not be used in RV64 when making a shared object.*
|
21
ld/testsuite/ld-riscv-elf/data-reloc-rv64-pic.d
Normal file
21
ld/testsuite/ld-riscv-elf/data-reloc-rv64-pic.d
Normal file
@ -0,0 +1,21 @@
|
||||
#source: data-reloc.s
|
||||
#as: -march=rv64i -mabi=lp64 -defsym __64_bit__=1 -defsym __abs__=1 -defsym __addr__=1 -defsym __undef__=1
|
||||
#ld: -m[riscv_choose_lp64_emul] -Ttext 0x8000 --defsym _start=0x0 --defsym abs=0x100 --defsym abs_local=0x200 -shared
|
||||
#objdump: -dR
|
||||
|
||||
.*:[ ]+file format .*
|
||||
|
||||
|
||||
Disassembly of section .text:
|
||||
|
||||
0+8000 <addr_globl>:
|
||||
...
|
||||
8000: R_RISCV_64 addr_globl
|
||||
|
||||
0+8008 <addr_local>:
|
||||
...
|
||||
8008: R_RISCV_RELATIVE \*ABS\*\+0x8008
|
||||
8010: R_RISCV_64 abs
|
||||
8018: 00000200 .word 0x00000200
|
||||
...
|
||||
8020: R_RISCV_64 undef
|
21
ld/testsuite/ld-riscv-elf/data-reloc-rv64-pie.d
Normal file
21
ld/testsuite/ld-riscv-elf/data-reloc-rv64-pie.d
Normal file
@ -0,0 +1,21 @@
|
||||
#source: data-reloc.s
|
||||
#as: -march=rv64i -mabi=lp64 -defsym __64_bit__=1 -defsym __abs__=1 -defsym __addr__=1
|
||||
#ld: -m[riscv_choose_lp64_emul] -Ttext 0x8000 --defsym _start=0x0 --defsym abs=0x100 --defsym abs_local=0x200 -pie
|
||||
#objdump: -dR
|
||||
|
||||
.*:[ ]+file format .*
|
||||
|
||||
|
||||
Disassembly of section .text:
|
||||
|
||||
0+8000 <addr_globl>:
|
||||
...
|
||||
8000: R_RISCV_RELATIVE \*ABS\*\+0x8000
|
||||
|
||||
0+8008 <addr_local>:
|
||||
...
|
||||
8008: R_RISCV_RELATIVE \*ABS\*\+0x8008
|
||||
8010: 00000100 .word 0x00000100
|
||||
8014: 00000000 .word 0x00000000
|
||||
8018: 00000200 .word 0x00000200
|
||||
801c: 00000000 .word 0x00000000
|
21
ld/testsuite/ld-riscv-elf/data-reloc-rv64-symbolic.d
Normal file
21
ld/testsuite/ld-riscv-elf/data-reloc-rv64-symbolic.d
Normal file
@ -0,0 +1,21 @@
|
||||
#source: data-reloc.s
|
||||
#as: -march=rv64i -mabi=lp64 -defsym __64_bit__=1 -defsym __abs__=1 -defsym __addr__=1 -defsym __undef__=1
|
||||
#ld: -m[riscv_choose_lp64_emul] -Ttext 0x8000 --defsym _start=0x0 --defsym abs=0x100 --defsym abs_local=0x200 -shared -Bsymbolic
|
||||
#objdump: -dR
|
||||
|
||||
.*:[ ]+file format .*
|
||||
|
||||
|
||||
Disassembly of section .text:
|
||||
|
||||
0+8000 <addr_globl>:
|
||||
...
|
||||
8000: R_RISCV_RELATIVE \*ABS\*\+0x8000
|
||||
|
||||
0+8008 <addr_local>:
|
||||
...
|
||||
8008: R_RISCV_RELATIVE \*ABS\*\+0x8008
|
||||
8010: R_RISCV_RELATIVE \*ABS\*\+0x100
|
||||
8018: 00000200 .word 0x00000200
|
||||
...
|
||||
8020: R_RISCV_64 undef
|
4
ld/testsuite/ld-riscv-elf/data-reloc-rv64-undef32-pic.d
Normal file
4
ld/testsuite/ld-riscv-elf/data-reloc-rv64-undef32-pic.d
Normal file
@ -0,0 +1,4 @@
|
||||
#source: data-reloc.s
|
||||
#as: -march=rv64i -mabi=lp64 -defsym __undef__=1
|
||||
#ld: -m[riscv_choose_lp64_emul] -Ttext 0x8000 --defsym _start=0x0 -shared
|
||||
#error: .*relocation R_RISCV_32 against non-absolute symbol `undef' can not be used in RV64 when making a shared object.*
|
22
ld/testsuite/ld-riscv-elf/data-reloc.s
Normal file
22
ld/testsuite/ld-riscv-elf/data-reloc.s
Normal file
@ -0,0 +1,22 @@
|
||||
.macro DATA symbol
|
||||
.ifdef __64_bit__
|
||||
.quad \symbol
|
||||
.else
|
||||
.word \symbol
|
||||
.endif
|
||||
.endm
|
||||
.ifdef __addr__
|
||||
.globl addr_globl
|
||||
addr_globl:
|
||||
DATA addr_globl
|
||||
addr_local:
|
||||
DATA addr_local
|
||||
.endif
|
||||
.ifdef __abs__
|
||||
.hidden abs_local
|
||||
DATA abs
|
||||
DATA abs_local
|
||||
.endif
|
||||
.ifdef __undef__
|
||||
DATA undef
|
||||
.endif
|
@ -20,4 +20,4 @@ main:
|
||||
|
||||
.data
|
||||
foo_addr:
|
||||
.long foo
|
||||
.quad foo
|
||||
|
@ -23,4 +23,4 @@ main:
|
||||
|
||||
.data
|
||||
foo_addr:
|
||||
.long foo
|
||||
.quad foo
|
||||
|
@ -217,6 +217,16 @@ if [istarget "riscv*-*-*"] {
|
||||
run_dump_test "shared-lib-nopic-03"
|
||||
run_dump_test "shared-lib-nopic-04"
|
||||
|
||||
run_dump_test "data-reloc-rv64-pic"
|
||||
run_dump_test "data-reloc-rv64-pie"
|
||||
run_dump_test "data-reloc-rv64-symbolic"
|
||||
run_dump_test "data-reloc-rv32-pic"
|
||||
run_dump_test "data-reloc-rv32-pie"
|
||||
run_dump_test "data-reloc-rv32-symbolic"
|
||||
run_dump_test "data-reloc-rv64-abs32-pic"
|
||||
run_dump_test "data-reloc-rv64-addr32-pic"
|
||||
run_dump_test "data-reloc-rv64-undef32-pic"
|
||||
|
||||
# IFUNC testcases.
|
||||
# Check IFUNC by single type relocs.
|
||||
run_dump_test_ifunc "ifunc-reloc-call-01" rv32 exe
|
||||
@ -270,6 +280,11 @@ if [istarget "riscv*-*-*"] {
|
||||
run_dump_test_ifunc "ifunc-plt-got-overwrite" rv64 pie
|
||||
run_dump_test_ifunc "ifunc-plt-got-overwrite" rv64 pic
|
||||
|
||||
# TODO: Make the following tests work under RV32.
|
||||
if [istarget "riscv32-*-*"] {
|
||||
return
|
||||
}
|
||||
|
||||
# Setup shared libraries.
|
||||
run_ld_link_tests {
|
||||
{ "Build shared library for IFUNC non-PLT caller"
|
||||
|
Loading…
x
Reference in New Issue
Block a user