diff options
author | Nelson Chu <nelson.chu@sifive.com> | 2020-10-06 20:48:22 -0700 |
---|---|---|
committer | Nelson Chu <nelson.chu@sifive.com> | 2020-10-16 10:11:18 +0800 |
commit | 02dd9d25682311f45e1bb9629cbe4f6727e245a8 (patch) | |
tree | a502756cbc8df40a0fbb1d3b30666e021868273d /ld | |
parent | e7f2f959e38e929ee04601abf97c4a637305771d (diff) | |
download | binutils-gdb-02dd9d25682311f45e1bb9629cbe4f6727e245a8.tar.gz |
RISC-V: Support GNU indirect functions.
Generally, glibc dynamic linker should have two ways to deal with ifunc
- one is to handle the IRELATIVE relocations for the non-preemtive ifunc
symbols, the other is to handle the R_RISCV_32/64 and R_RISCV_JUMP_SLOT
relocations with the STT_IFUNC preemtive symbols. No matter which method
is used, both of them should get the resolved ifunc symbols at runtime.
Therefore, linker needs to generate the correct dynamic relocations for
ifunc to make sure the the dynamic linker works well. For now, there are
thirteen relocations are supported for ifunc in GNU ld,
* R_RISCV_CALL and R_RISCV_CALL_PLT:
The RISC-V compiler won't generate R_RISCV_JAL directly to jump to an
ifunc. Besides, we disable the relaxations for the relocation referenced
to ifunc, so just handling the R_RISCV_CALL and R_RISCV_CALL_PLT should be
enough. Linker should generate a .plt entry and a .got.plt entry for it,
and also needs to insert a dynamic IRELATIVE in the .got.plt enrty, or
insert a R_RISCV_JUMP_SLOT when generating shared library.
* R_RISCV_PCREL_HI20 and R_RISCV_PCREL_LO12_I/S:
LA/LLA pattern with local fPIC ifunc symbol, or any non-PIC ifunc symbol.
The PC-relative relocation. The current linker will deal with them in
the same way as R_RISCV_CALL_PLT.
* R_RISCV_GOT_HI20 and R_RISCV_PCREL_LO12_I/S:
LA pattern with global PIC ifunc symbol. Linker should insert a dynamic
IRELATIVE in the .got entry, or insert a R_RISCV_32/64 when generating
shared library.
* R_RISCV_32 and R_RISCV_64:
Store the ifunc symbol into the data section. Linker should insert a
dynamic IRELATIVE in the data section, or insert a R_RISCV_32/64 when
generating shared library.
* R_RISCV_HI20 and R_RISCV_LO12_I/S:
The LUI + ADDI/LW/SW patterns. The absolute access relocation. The
medlow model without the -fPIC compiler option should generate them.
The ld ifunc testsuites "Build pr23169a" and "Build pr23169d" need the
relocations, they are in the ld/testsuite/ld-ifunc/, and need compiler
support.
However, we also made some optimizations with reference to x86,
* If GOT and PLT relocations refer to the same ifunc symbol when generating
pie, then they can actually share a .got entry without creating two entries
to store the same value and relocation.
* If GOT, PLT and DATA relocations refer to the same ifunc symbol when
generating position dependency executable, then linker will fill the address
of .plt entry into the corresponding .got entry and data section, without
insert any dynamic relocations for the GOT and DATA relocations.
For the ifunc testcases, there are three types of them,
1. ifunc-reloc-*: Only check the single type of relocation refers to
ifunc symbol.
* ifunc-reloc-call: R_RISCV_CALL and R_RISCV_CALL_PLT.
* ifunc-reloc-data: R_RISCV_32 and R_RISCV_64.
* ifunc-reloc-got: R_RISCV_GOT_HI20 and R_RISCV_PCREL_LO_I/S.
* ifunc-reloc-pcrel: R_RISCV_PCREL_HI20 and R_RISCV_PCREL_LO_I/S.
2. ifunc-[nonplt|plt]-*: If we don't have PLT relocs, then don't need to
create the PLT and it's .plt entries.
* ifunc-nonplt: Combine R_RISCV_GOT_HI20 and R_RISCV_32/64.
* ifunc-plt: Combine all ifunc relocations.
3. ifunc-seperate-*: If we link the ifunc caller and resolver into the
same module (link the objects), then the results are the same as the
ifunc-reloc-* and ifunc-[noplt|plt]-* testcases. Consider the cases that
the ifunc callers and resolver are in the different modules, that is, we
compile the ifunc resolver to the shared library first, and then link it
with the ifunc callers. The output of ifunc callers should be the same as
the normal STT_FUNC cases, and the shared ifunc resolver should define the
symbols as STT_IFUNC.
The R_RISCV_PCREL_HI20 reloc is special. It should be linked and resolved
locally, so if the ifunc resolver is defined in other modules (other shared
libraries), then the R_RISCV_PCREL_HI20 is unresolvable, and linker should
issue an unresolvable reloc error.
bfd/
* elfnn-riscv.c: Include "objalloc.h" since we need objalloc_alloc.
(riscv_elf_link_hash_table): Add loc_hash_table and loc_hash_memory
for local STT_GNU_IFUNC symbols.
(riscv_elf_got_plt_val): Removed.
(riscv_elf_local_htab_hash, riscv_elf_local_htab_eq): New functions.
Use to compare local hash entries.
(riscv_elf_get_local_sym_hash): New function. Find a hash entry for
local symbol, and create a new one if needed.
(riscv_elf_link_hash_table_free): New function. Destroy an riscv
elf linker hash table.
(riscv_elf_link_hash_table_create): Create hash table for local ifunc.
(riscv_elf_check_relocs): Create a fake global symbol to track the
local ifunc symbol. Add support to check and handle the relocations
reference to ifunc symbols.
(allocate_dynrelocs): Let allocate_ifunc_dynrelocs and
allocate_local_ifunc_dynrelocs to handle the ifunc symbols if they
are defined and referenced in a non-shared object.
(allocate_ifunc_dynrelocs): New function. Allocate space in .plt,
.got and associated reloc sections for ifunc dynamic relocs.
(allocate_local_ifunc_dynrelocs): Likewise, but for local ifunc
dynamic relocs.
(riscv_elf_relocate_section): Add support to handle the relocation
referenced to ifunc symbols.
(riscv_elf_size_dynamic_sections): Updated.
(riscv_elf_adjust_dynamic_symbol): Updated.
(riscv_elf_finish_dynamic_symbol): Finish up the ifunc handling,
including fill the PLT and GOT entries for ifunc symbols.
(riscv_elf_finish_local_dynamic_symbol): New function. Called by
riscv_elf_finish_dynamic_symbol to handle the local ifunc symbols.
(_bfd_riscv_relax_section): Don't do the relaxation for ifunc.
* elfxx-riscv.c: Add R_RISCV_IRELATIVE.
* configure.ac: Link elf-ifunc.lo to use the generic ifunc support.
* configure: Regenerated.
include/
* elf/riscv.h: Add R_RISCV_IRELATIVE to 58.
ld/
* emulparams/elf32lriscv-defs.sh: Add IREL_IN_PLT.
* testsuite/ld-ifunc/ifunc.exp: Enable ifunc tests for RISC-V.
* testsuite/ld-riscv-elf/ld-riscv-elf.exp (run_dump_test_ifunc):
New dump test for ifunc. There are two arguments, 'target` and
`output`. The `target` is rv32 or rv64, and the `output` is used
to choose which output you want to test (exe, pie or .so).
* testsuite/ld-riscv-elf/ifunc-reloc-call-01.s: New testcase.
* testsuite/ld-riscv-elf/ifunc-reloc-call-01.d: Likewise.
* testsuite/ld-riscv-elf/ifunc-reloc-call-01-exe.rd: Likewise.
* testsuite/ld-riscv-elf/ifunc-reloc-call-01-pic.rd: Likewise.
* testsuite/ld-riscv-elf/ifunc-reloc-call-01-pie.rd: Likewise.
* testsuite/ld-riscv-elf/ifunc-reloc-call-02.s: Likewise.
* testsuite/ld-riscv-elf/ifunc-reloc-call-02.d: Likewise.
* testsuite/ld-riscv-elf/ifunc-reloc-call-02-exe.rd: Likewise.
* testsuite/ld-riscv-elf/ifunc-reloc-call-02-pic.rd: Likewise.
* testsuite/ld-riscv-elf/ifunc-reloc-call-02-pie.rd: Likewise.
* testsuite/ld-riscv-elf/ifunc-reloc-data.s: Likewise.
* testsuite/ld-riscv-elf/ifunc-reloc-data.d: Likewise.
* testsuite/ld-riscv-elf/ifunc-reloc-data-exe.rd: Likewise.
* testsuite/ld-riscv-elf/ifunc-reloc-data-pic.rd: Likewise.
* testsuite/ld-riscv-elf/ifunc-reloc-data-pie.rd: Likewise.
* testsuite/ld-riscv-elf/ifunc-reloc-got.s: Likewise.
* testsuite/ld-riscv-elf/ifunc-reloc-got.d: Likewise.
* testsuite/ld-riscv-elf/ifunc-reloc-got-exe.rd: Likewise.
* testsuite/ld-riscv-elf/ifunc-reloc-got-pic.rd: Likewise.
* testsuite/ld-riscv-elf/ifunc-reloc-got-pie.rd: Likewise.
* testsuite/ld-riscv-elf/ifunc-reloc-pcrel.s: Likewise.
* testsuite/ld-riscv-elf/ifunc-reloc-pcrel.d: Likewise.
* testsuite/ld-riscv-elf/ifunc-reloc-pcrel-exe.rd: Likewise.
* testsuite/ld-riscv-elf/ifunc-reloc-pcrel-pic.rd: Likewise.
* testsuite/ld-riscv-elf/ifunc-reloc-pcrel-pie.rd: Likewise.
* testsuite/ld-riscv-elf/ifunc-nonplt.s: Likewise.
* testsuite/ld-riscv-elf/ifunc-nonplt.d: Likewise.
* testsuite/ld-riscv-elf/ifunc-nonplt-exe.rd: Likewise.
* testsuite/ld-riscv-elf/ifunc-nonplt-pic.rd: Likewise.
* testsuite/ld-riscv-elf/ifunc-nonplt-pie.rd: Likewise.
* testsuite/ld-riscv-elf/ifunc-plt-01.s: Likewise.
* testsuite/ld-riscv-elf/ifunc-plt-01.d: Likewise.
* testsuite/ld-riscv-elf/ifunc-plt-01-exe.rd: Likewise.
* testsuite/ld-riscv-elf/ifunc-plt-01-pic.rd: Likewise.
* testsuite/ld-riscv-elf/ifunc-plt-01-pie.rd: Likewise.
* testsuite/ld-riscv-elf/ifunc-plt-02.s: Likewise.
* testsuite/ld-riscv-elf/ifunc-plt-02.d: Likewise.
* testsuite/ld-riscv-elf/ifunc-plt-02-exe.rd: Likewise.
* testsuite/ld-riscv-elf/ifunc-plt-02-pic.rd: Likewise.
* testsuite/ld-riscv-elf/ifunc-plt-02-pie.rd: Likewise.
* testsuite/ld-riscv-elf/ifunc-seperate-resolver.s: Likewise.
* testsuite/ld-riscv-elf/ifunc-seperate-caller.s: Likewise.
* testsuite/ld-riscv-elf/ifunc-seperate-exe.d: Likewise.
* testsuite/ld-riscv-elf/ifunc-seperate-pic.d: Likewise.
* testsuite/ld-riscv-elf/ifunc-seperate-pie.d: Likewise.
* testsuite/ld-riscv-elf/ifunc-seperate-caller-pcrel.s: Likewise.
* testsuite/ld-riscv-elf/ifunc-seperate-pcrel-pic.d: Likewise.
* testsuite/ld-riscv-elf/ifunc-seperate-pcrel-pie.d: Likewise.
Diffstat (limited to 'ld')
56 files changed, 785 insertions, 2 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog index 205f6acb87c..3a9d3810984 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,60 @@ +2020-10-16 Nelson Chu <nelson.chu@sifive.com> + + * emulparams/elf32lriscv-defs.sh: Add IREL_IN_PLT. + * testsuite/ld-ifunc/ifunc.exp: Enable ifunc tests for RISC-V. + * testsuite/ld-riscv-elf/ld-riscv-elf.exp (run_dump_test_ifunc): + New dump test for ifunc. There are two arguments, 'target` and + `output`. The `target` is rv32 or rv64, and the `output` is used + to choose which output you want to test (exe, pie or .so). + * testsuite/ld-riscv-elf/ifunc-reloc-call-01.s: New testcase. + * testsuite/ld-riscv-elf/ifunc-reloc-call-01.d: Likewise. + * testsuite/ld-riscv-elf/ifunc-reloc-call-01-exe.rd: Likewise. + * testsuite/ld-riscv-elf/ifunc-reloc-call-01-pic.rd: Likewise. + * testsuite/ld-riscv-elf/ifunc-reloc-call-01-pie.rd: Likewise. + * testsuite/ld-riscv-elf/ifunc-reloc-call-02.s: Likewise. + * testsuite/ld-riscv-elf/ifunc-reloc-call-02.d: Likewise. + * testsuite/ld-riscv-elf/ifunc-reloc-call-02-exe.rd: Likewise. + * testsuite/ld-riscv-elf/ifunc-reloc-call-02-pic.rd: Likewise. + * testsuite/ld-riscv-elf/ifunc-reloc-call-02-pie.rd: Likewise. + * testsuite/ld-riscv-elf/ifunc-reloc-data.s: Likewise. + * testsuite/ld-riscv-elf/ifunc-reloc-data.d: Likewise. + * testsuite/ld-riscv-elf/ifunc-reloc-data-exe.rd: Likewise. + * testsuite/ld-riscv-elf/ifunc-reloc-data-pic.rd: Likewise. + * testsuite/ld-riscv-elf/ifunc-reloc-data-pie.rd: Likewise. + * testsuite/ld-riscv-elf/ifunc-reloc-got.s: Likewise. + * testsuite/ld-riscv-elf/ifunc-reloc-got.d: Likewise. + * testsuite/ld-riscv-elf/ifunc-reloc-got-exe.rd: Likewise. + * testsuite/ld-riscv-elf/ifunc-reloc-got-pic.rd: Likewise. + * testsuite/ld-riscv-elf/ifunc-reloc-got-pie.rd: Likewise. + * testsuite/ld-riscv-elf/ifunc-reloc-pcrel.s: Likewise. + * testsuite/ld-riscv-elf/ifunc-reloc-pcrel.d: Likewise. + * testsuite/ld-riscv-elf/ifunc-reloc-pcrel-exe.rd: Likewise. + * testsuite/ld-riscv-elf/ifunc-reloc-pcrel-pic.rd: Likewise. + * testsuite/ld-riscv-elf/ifunc-reloc-pcrel-pie.rd: Likewise. + * testsuite/ld-riscv-elf/ifunc-nonplt.s: Likewise. + * testsuite/ld-riscv-elf/ifunc-nonplt.d: Likewise. + * testsuite/ld-riscv-elf/ifunc-nonplt-exe.rd: Likewise. + * testsuite/ld-riscv-elf/ifunc-nonplt-pic.rd: Likewise. + * testsuite/ld-riscv-elf/ifunc-nonplt-pie.rd: Likewise. + * testsuite/ld-riscv-elf/ifunc-plt-01.s: Likewise. + * testsuite/ld-riscv-elf/ifunc-plt-01.d: Likewise. + * testsuite/ld-riscv-elf/ifunc-plt-01-exe.rd: Likewise. + * testsuite/ld-riscv-elf/ifunc-plt-01-pic.rd: Likewise. + * testsuite/ld-riscv-elf/ifunc-plt-01-pie.rd: Likewise. + * testsuite/ld-riscv-elf/ifunc-plt-02.s: Likewise. + * testsuite/ld-riscv-elf/ifunc-plt-02.d: Likewise. + * testsuite/ld-riscv-elf/ifunc-plt-02-exe.rd: Likewise. + * testsuite/ld-riscv-elf/ifunc-plt-02-pic.rd: Likewise. + * testsuite/ld-riscv-elf/ifunc-plt-02-pie.rd: Likewise. + * testsuite/ld-riscv-elf/ifunc-seperate-resolver.s: Likewise. + * testsuite/ld-riscv-elf/ifunc-seperate-caller.s: Likewise. + * testsuite/ld-riscv-elf/ifunc-seperate-exe.d: Likewise. + * testsuite/ld-riscv-elf/ifunc-seperate-pic.d: Likewise. + * testsuite/ld-riscv-elf/ifunc-seperate-pie.d: Likewise. + * testsuite/ld-riscv-elf/ifunc-seperate-caller-pcrel.s: Likewise. + * testsuite/ld-riscv-elf/ifunc-seperate-pcrel-pic.d: Likewise. + * testsuite/ld-riscv-elf/ifunc-seperate-pcrel-pie.d: Likewise. + 2020-10-09 H.J. Lu <hongjiu.lu@intel.com> PR gas/26703 diff --git a/ld/emulparams/elf32lriscv-defs.sh b/ld/emulparams/elf32lriscv-defs.sh index bc464918e5c..b823cedacab 100644 --- a/ld/emulparams/elf32lriscv-defs.sh +++ b/ld/emulparams/elf32lriscv-defs.sh @@ -26,6 +26,7 @@ case "$target" in ;; esac +IREL_IN_PLT= TEXT_START_ADDR=0x10000 MAXPAGESIZE="CONSTANT (MAXPAGESIZE)" COMMONPAGESIZE="CONSTANT (COMMONPAGESIZE)" diff --git a/ld/testsuite/ld-ifunc/ifunc.exp b/ld/testsuite/ld-ifunc/ifunc.exp index 63ab18d41ac..9ed4bd7841a 100644 --- a/ld/testsuite/ld-ifunc/ifunc.exp +++ b/ld/testsuite/ld-ifunc/ifunc.exp @@ -39,7 +39,6 @@ if { ![is_elf_format] || ![supports_gnu_osabi] || [istarget nds32*-*-*] || [istarget nios2-*-*] || [istarget or1k-*-*] - || [istarget riscv*-*-*] || [istarget score*-*-*] || [istarget sh*-*-*] || [istarget tic6x-*-*] @@ -736,7 +735,8 @@ run_ld_link_exec_tests [list \ if { [isnative] && !([istarget "powerpc-*-*"] || [istarget "aarch64*-*-*"] - || [istarget "sparc*-*-*"]) } { + || [istarget "sparc*-*-*"] + || [istarget "riscv*-*-*"]) } { run_ld_link_exec_tests [list \ [list \ "Run pr23169a" \ diff --git a/ld/testsuite/ld-riscv-elf/ifunc-nonplt-exe.rd b/ld/testsuite/ld-riscv-elf/ifunc-nonplt-exe.rd new file mode 100644 index 00000000000..0de47a4009f --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-nonplt-exe.rd @@ -0,0 +1,4 @@ +Relocation section '.rela.plt' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_IRELATIVE[ ]+[0-9a-f]* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_IRELATIVE[ ]+[0-9a-f]* diff --git a/ld/testsuite/ld-riscv-elf/ifunc-nonplt-pic.rd b/ld/testsuite/ld-riscv-elf/ifunc-nonplt-pic.rd new file mode 100644 index 00000000000..e2e7ad923a5 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-nonplt-pic.rd @@ -0,0 +1,7 @@ +Relocation section '.rela.got' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_(32|64)[ ]+foo\(\)[ ]+foo \+ 0 +#... +Relocation section '.rela.ifunc' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_(32|64)[ ]+foo\(\)[ ]+foo \+ 0 diff --git a/ld/testsuite/ld-riscv-elf/ifunc-nonplt-pie.rd b/ld/testsuite/ld-riscv-elf/ifunc-nonplt-pie.rd new file mode 100644 index 00000000000..f9fbd877c58 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-nonplt-pie.rd @@ -0,0 +1,7 @@ +Relocation section '.rela.got' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_IRELATIVE[ ]+[0-9a-f]* +#... +Relocation section '.rela.ifunc' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_IRELATIVE[ ]+[0-9a-f]* diff --git a/ld/testsuite/ld-riscv-elf/ifunc-nonplt.d b/ld/testsuite/ld-riscv-elf/ifunc-nonplt.d new file mode 100644 index 00000000000..e3517d3c654 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-nonplt.d @@ -0,0 +1,11 @@ +#... +Disassembly of section .text: +#... +0+[0-9a-f]+ <foo_resolver>: +#... +0+[0-9a-f]+ <bar>: +.*:[ ]+[0-9a-f]+[ ]+auipc[ ]+.* +.*:[ ]+[0-9a-f]+[ ]+(lw|ld)[ ]+.*<(_GLOBAL_OFFSET_TABLE_.*|.*)> +.*:[ ]+[0-9a-f]+[ ]+auipc[ ]+.* +.*:[ ]+[0-9a-f]+[ ]+(lw|ld)[ ]+.*<(__DATA_BEGIN__|.*)> +#... diff --git a/ld/testsuite/ld-riscv-elf/ifunc-nonplt.s b/ld/testsuite/ld-riscv-elf/ifunc-nonplt.s new file mode 100644 index 00000000000..ce6ca691fa7 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-nonplt.s @@ -0,0 +1,39 @@ + .text + + .type foo_resolver, @function +foo_resolver: + ret + .size foo_resolver, .-foo_resolver + + .globl foo + .type foo, %gnu_indirect_function + .set foo, foo_resolver + + .globl bar + .type bar, @function +bar: +.L1: + auipc x1, %got_pcrel_hi (foo) +.ifdef __64_bit__ + ld x1, %pcrel_lo (.L1) (x1) +.else + lw x1, %pcrel_lo (.L1) (x1) +.endif + +.L2: + auipc x2, %pcrel_hi (foo_addr) +.ifdef __64_bit__ + ld x2, %pcrel_lo (.L2) (x2) +.else + lw x2, %pcrel_lo (.L2) (x2) +.endif + ret + .size bar, .-bar + + .data +foo_addr: +.ifdef __64_bit__ + .quad foo +.else + .long foo +.endif diff --git a/ld/testsuite/ld-riscv-elf/ifunc-plt-01-exe.rd b/ld/testsuite/ld-riscv-elf/ifunc-plt-01-exe.rd new file mode 100644 index 00000000000..97461e43ccc --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-plt-01-exe.rd @@ -0,0 +1,3 @@ +Relocation section '.rela.plt' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_IRELATIVE[ ]+[0-9a-f]* diff --git a/ld/testsuite/ld-riscv-elf/ifunc-plt-01-pic.rd b/ld/testsuite/ld-riscv-elf/ifunc-plt-01-pic.rd new file mode 100644 index 00000000000..6f5218b9678 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-plt-01-pic.rd @@ -0,0 +1,7 @@ +Relocation section '.rela.got' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_(32|64)[ ]+foo\(\)[ ]+foo \+ 0 +#... +Relocation section '.rela.plt' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_JUMP_SLOT[ ]+foo\(\)[ ]+foo \+ 0 diff --git a/ld/testsuite/ld-riscv-elf/ifunc-plt-01-pie.rd b/ld/testsuite/ld-riscv-elf/ifunc-plt-01-pie.rd new file mode 100644 index 00000000000..97461e43ccc --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-plt-01-pie.rd @@ -0,0 +1,3 @@ +Relocation section '.rela.plt' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_IRELATIVE[ ]+[0-9a-f]* diff --git a/ld/testsuite/ld-riscv-elf/ifunc-plt-01.d b/ld/testsuite/ld-riscv-elf/ifunc-plt-01.d new file mode 100644 index 00000000000..bed9fe67955 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-plt-01.d @@ -0,0 +1,19 @@ +#... +Disassembly of section .plt: +#... +0+[0-9a-f]+ <(\*ABS\*\+0x[0-9a-f]+@plt|foo@plt|.plt)>: +#... +Disassembly of section .text: +#... +0+[0-9a-f]+ <foo_resolver>: +#... +0+[0-9a-f]+ <bar>: +.*:[ ]+[0-9a-f]+[ ]+auipc[ ]+.* +.*:[ ]+[0-9a-f]+[ ]+(lw|ld)[ ]+.*<(_GLOBAL_OFFSET_TABLE_.*|__DATA_BEGIN__.*|.*)> +.*:[ ]+[0-9a-f]+[ ]+auipc[ ]+.* +.*:[ ]+[0-9a-f]+[ ]+addi[ ]+.*<(\*ABS\*\+0x[0-9a-f]+@plt|foo@plt|.plt)> +.*:[ ]+[0-9a-f]+[ ]+auipc[ ]+.* +.*:[ ]+[0-9a-f]+[ ]+jalr[ ]+.*<(\*ABS\*\+0x[0-9a-f]+@plt|foo@plt|.plt)> +.*:[ ]+[0-9a-f]+[ ]+auipc[ ]+.* +.*:[ ]+[0-9a-f]+[ ]+jalr[ ]+.*<(\*ABS\*\+0x[0-9a-f]+@plt|foo@plt|.plt)> +#... diff --git a/ld/testsuite/ld-riscv-elf/ifunc-plt-01.s b/ld/testsuite/ld-riscv-elf/ifunc-plt-01.s new file mode 100644 index 00000000000..65c65cdca57 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-plt-01.s @@ -0,0 +1,31 @@ + .text + + .type foo_resolver, @function +foo_resolver: + ret + .size foo_resolver, .-foo_resolver + + .globl foo + .type foo, %gnu_indirect_function + .set foo, foo_resolver + + .globl bar + .type bar, @function +bar: +.L1: + auipc x1, %got_pcrel_hi (foo) +.ifdef __64_bit__ + ld x1, %pcrel_lo (.L1) (x1) +.else + lw x1, %pcrel_lo (.L1) (x1) +.endif + +.L2: + auipc x2, %pcrel_hi (foo) + addi x2, x2, %pcrel_lo (.L2) + + call foo + call foo@plt + + ret + .size bar, .-bar diff --git a/ld/testsuite/ld-riscv-elf/ifunc-plt-02-exe.rd b/ld/testsuite/ld-riscv-elf/ifunc-plt-02-exe.rd new file mode 100644 index 00000000000..97461e43ccc --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-plt-02-exe.rd @@ -0,0 +1,3 @@ +Relocation section '.rela.plt' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_IRELATIVE[ ]+[0-9a-f]* diff --git a/ld/testsuite/ld-riscv-elf/ifunc-plt-02-pic.rd b/ld/testsuite/ld-riscv-elf/ifunc-plt-02-pic.rd new file mode 100644 index 00000000000..3299aa48f24 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-plt-02-pic.rd @@ -0,0 +1,11 @@ +Relocation section '.rela.got' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_(32|64)[ ]+foo\(\)[ ]+foo \+ 0 +#... +Relocation section '.rela.ifunc' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_(32|64)[ ]+foo\(\)[ ]+foo \+ 0 +#... +Relocation section '.rela.plt' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_JUMP_SLOT[ ]+foo\(\)[ ]+foo \+ 0 diff --git a/ld/testsuite/ld-riscv-elf/ifunc-plt-02-pie.rd b/ld/testsuite/ld-riscv-elf/ifunc-plt-02-pie.rd new file mode 100644 index 00000000000..28a3c992f4b --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-plt-02-pie.rd @@ -0,0 +1,7 @@ +Relocation section '.rela.ifunc' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_IRELATIVE[ ]+[0-9a-f]* +#... +Relocation section '.rela.plt' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_IRELATIVE[ ]+[0-9a-f]* diff --git a/ld/testsuite/ld-riscv-elf/ifunc-plt-02.d b/ld/testsuite/ld-riscv-elf/ifunc-plt-02.d new file mode 100644 index 00000000000..b8638b963fd --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-plt-02.d @@ -0,0 +1,21 @@ +#... +Disassembly of section .plt: +#... +0+[0-9a-f]+ <(\*ABS\*\+0x[0-9a-f]+@plt|foo@plt|.plt)>: +#... +Disassembly of section .text: +#... +0+[0-9a-f]+ <foo_resolver>: +#... +0+[0-9a-f]+ <bar>: +.*:[ ]+[0-9a-f]+[ ]+auipc[ ]+.* +.*:[ ]+[0-9a-f]+[ ]+(lw|ld)[ ]+.*<(_GLOBAL_OFFSET_TABLE_.*|.*)> +.*:[ ]+[0-9a-f]+[ ]+auipc[ ]+.* +.*:[ ]+[0-9a-f]+[ ]+(lw|ld)[ ]+.*<(__DATA_BEGIN__.*|.*)> +.*:[ ]+[0-9a-f]+[ ]+auipc[ ]+.* +.*:[ ]+[0-9a-f]+[ ]+addi[ ]+.*<(\*ABS\*\+0x[0-9a-f]+@plt|foo@plt|.plt)> +.*:[ ]+[0-9a-f]+[ ]+auipc[ ]+.* +.*:[ ]+[0-9a-f]+[ ]+jalr[ ]+.*<(\*ABS\*\+0x[0-9a-f]+@plt|foo@plt|.plt)> +.*:[ ]+[0-9a-f]+[ ]+auipc[ ]+.* +.*:[ ]+[0-9a-f]+[ ]+jalr[ ]+.*<(\*ABS\*\+0x[0-9a-f]+@plt|foo@plt|.plt)> +#... diff --git a/ld/testsuite/ld-riscv-elf/ifunc-plt-02.s b/ld/testsuite/ld-riscv-elf/ifunc-plt-02.s new file mode 100644 index 00000000000..c3022be0e08 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-plt-02.s @@ -0,0 +1,46 @@ + .text + + .type foo_resolver, @function +foo_resolver: + ret + .size foo_resolver, .-foo_resolver + + .globl foo + .type foo, %gnu_indirect_function + .set foo, foo_resolver + + .globl bar + .type bar, @function +bar: +.L1: + auipc x1, %got_pcrel_hi (foo) +.ifdef __64_bit__ + ld x1, %pcrel_lo (.L1) (x1) +.else + lw x1, %pcrel_lo (.L1) (x1) +.endif + +.L2: + auipc x2, %pcrel_hi (foo_addr) +.ifdef __64_bit__ + ld x2, %pcrel_lo (.L2) (x2) +.else + lw x2, %pcrel_lo (.L2) (x2) +.endif + +.L3: + auipc x3, %pcrel_hi (foo) + addi x3, x3, %pcrel_lo (.L3) + + call foo + call foo@plt + ret + .size bar, .-bar + + .data +foo_addr: +.ifdef __64_bit__ + .quad foo +.else + .long foo +.endif diff --git a/ld/testsuite/ld-riscv-elf/ifunc-reloc-call-01-exe.rd b/ld/testsuite/ld-riscv-elf/ifunc-reloc-call-01-exe.rd new file mode 100644 index 00000000000..97461e43ccc --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-reloc-call-01-exe.rd @@ -0,0 +1,3 @@ +Relocation section '.rela.plt' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_IRELATIVE[ ]+[0-9a-f]* diff --git a/ld/testsuite/ld-riscv-elf/ifunc-reloc-call-01-pic.rd b/ld/testsuite/ld-riscv-elf/ifunc-reloc-call-01-pic.rd new file mode 100644 index 00000000000..7bfaa2d266b --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-reloc-call-01-pic.rd @@ -0,0 +1,3 @@ +Relocation section '.rela.plt' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_JUMP_SLOT[ ]+foo\(\)[ ]+foo \+ 0 diff --git a/ld/testsuite/ld-riscv-elf/ifunc-reloc-call-01-pie.rd b/ld/testsuite/ld-riscv-elf/ifunc-reloc-call-01-pie.rd new file mode 100644 index 00000000000..97461e43ccc --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-reloc-call-01-pie.rd @@ -0,0 +1,3 @@ +Relocation section '.rela.plt' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_IRELATIVE[ ]+[0-9a-f]* diff --git a/ld/testsuite/ld-riscv-elf/ifunc-reloc-call-01.d b/ld/testsuite/ld-riscv-elf/ifunc-reloc-call-01.d new file mode 100644 index 00000000000..d4457c9be3c --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-reloc-call-01.d @@ -0,0 +1,13 @@ +#... +Disassembly of section .plt: +#... +0+[0-9a-f]+ <(\*ABS\*\+0x[0-9a-f]+@plt|foo@plt|.plt)>: +#... +Disassembly of section .text: +#... +0+[0-9a-f]+ <foo_resolver>: +#... +0+[0-9a-f]+ <bar>: +.*:[ ]+[0-9a-f]+[ ]+auipc[ ]+.* +.*:[ ]+[0-9a-f]+[ ]+jalr[ ]+.*<(\*ABS\*\+0x[0-9a-f]+@plt|foo@plt|.plt)> +#... diff --git a/ld/testsuite/ld-riscv-elf/ifunc-reloc-call-01.s b/ld/testsuite/ld-riscv-elf/ifunc-reloc-call-01.s new file mode 100644 index 00000000000..89e63260fe2 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-reloc-call-01.s @@ -0,0 +1,17 @@ + .text + + .type foo_resolver, @function +foo_resolver: + ret + .size foo_resolver, .-foo_resolver + + .globl foo + .type foo, %gnu_indirect_function + .set foo, foo_resolver + + .globl bar + .type bar, @function +bar: + call foo + ret + .size bar, .-bar diff --git a/ld/testsuite/ld-riscv-elf/ifunc-reloc-call-02-exe.rd b/ld/testsuite/ld-riscv-elf/ifunc-reloc-call-02-exe.rd new file mode 100644 index 00000000000..97461e43ccc --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-reloc-call-02-exe.rd @@ -0,0 +1,3 @@ +Relocation section '.rela.plt' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_IRELATIVE[ ]+[0-9a-f]* diff --git a/ld/testsuite/ld-riscv-elf/ifunc-reloc-call-02-pic.rd b/ld/testsuite/ld-riscv-elf/ifunc-reloc-call-02-pic.rd new file mode 100644 index 00000000000..7bfaa2d266b --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-reloc-call-02-pic.rd @@ -0,0 +1,3 @@ +Relocation section '.rela.plt' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_JUMP_SLOT[ ]+foo\(\)[ ]+foo \+ 0 diff --git a/ld/testsuite/ld-riscv-elf/ifunc-reloc-call-02-pie.rd b/ld/testsuite/ld-riscv-elf/ifunc-reloc-call-02-pie.rd new file mode 100644 index 00000000000..97461e43ccc --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-reloc-call-02-pie.rd @@ -0,0 +1,3 @@ +Relocation section '.rela.plt' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_IRELATIVE[ ]+[0-9a-f]* diff --git a/ld/testsuite/ld-riscv-elf/ifunc-reloc-call-02.d b/ld/testsuite/ld-riscv-elf/ifunc-reloc-call-02.d new file mode 100644 index 00000000000..40c0309ee26 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-reloc-call-02.d @@ -0,0 +1,15 @@ +#... +Disassembly of section .plt: +#... +0+[0-9a-f]+ <(\*ABS\*\+0x[0-9a-f]+@plt|foo@plt|.plt)>: +#... +Disassembly of section .text: +#... +0+[0-9a-f]+ <foo_resolver>: +#... +0+[0-9a-f]+ <bar>: +.*:[ ]+[0-9a-f]+[ ]+auipc[ ]+.* +.*:[ ]+[0-9a-f]+[ ]+jalr[ ]+.*<(\*ABS\*\+0x[0-9a-f]+@plt|foo@plt|.plt)> +.*:[ ]+[0-9a-f]+[ ]+auipc[ ]+.* +.*:[ ]+[0-9a-f]+[ ]+jalr[ ]+.*<(\*ABS\*\+0x[0-9a-f]+@plt|foo@plt|.plt)> +#... diff --git a/ld/testsuite/ld-riscv-elf/ifunc-reloc-call-02.s b/ld/testsuite/ld-riscv-elf/ifunc-reloc-call-02.s new file mode 100644 index 00000000000..e493c47341a --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-reloc-call-02.s @@ -0,0 +1,18 @@ + .text + + .type foo_resolver, @function +foo_resolver: + ret + .size foo_resolver, .-foo_resolver + + .globl foo + .type foo, %gnu_indirect_function + .set foo, foo_resolver + + .globl bar + .type bar, @function +bar: + call foo@plt + call foo + ret + .size bar, .-bar diff --git a/ld/testsuite/ld-riscv-elf/ifunc-reloc-data-exe.rd b/ld/testsuite/ld-riscv-elf/ifunc-reloc-data-exe.rd new file mode 100644 index 00000000000..97461e43ccc --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-reloc-data-exe.rd @@ -0,0 +1,3 @@ +Relocation section '.rela.plt' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_IRELATIVE[ ]+[0-9a-f]* diff --git a/ld/testsuite/ld-riscv-elf/ifunc-reloc-data-pic.rd b/ld/testsuite/ld-riscv-elf/ifunc-reloc-data-pic.rd new file mode 100644 index 00000000000..9be346bd20e --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-reloc-data-pic.rd @@ -0,0 +1,3 @@ +Relocation section '.rela.ifunc' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_(32|64)[ ]+foo\(\)[ ]+foo \+ 0 diff --git a/ld/testsuite/ld-riscv-elf/ifunc-reloc-data-pie.rd b/ld/testsuite/ld-riscv-elf/ifunc-reloc-data-pie.rd new file mode 100644 index 00000000000..e14b02ba75d --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-reloc-data-pie.rd @@ -0,0 +1,3 @@ +Relocation section '.rela.ifunc' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_IRELATIVE[ ]+[0-9a-f]* diff --git a/ld/testsuite/ld-riscv-elf/ifunc-reloc-data.d b/ld/testsuite/ld-riscv-elf/ifunc-reloc-data.d new file mode 100644 index 00000000000..1956cc3e101 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-reloc-data.d @@ -0,0 +1,9 @@ +#... +Disassembly of section .text: +#... +0+[0-9a-f]+ <foo_resolver>: +#... +0+[0-9a-f]+ <bar>: +.*:[ ]+[0-9a-f]+[ ]+auipc[ ]+.* +.*:[ ]+[0-9a-f]+[ ]+(lw|ld)[ ]+.*<(__DATA_BEGIN__.*|.*)> +#... diff --git a/ld/testsuite/ld-riscv-elf/ifunc-reloc-data.s b/ld/testsuite/ld-riscv-elf/ifunc-reloc-data.s new file mode 100644 index 00000000000..b49bda1279d --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-reloc-data.s @@ -0,0 +1,31 @@ + .text + + .type foo_resolver, @function +foo_resolver: + ret + .size foo_resolver, .-foo_resolver + + .globl foo + .type foo, %gnu_indirect_function + .set foo, foo_resolver + + .globl bar + .type bar, @function +bar: +.L1: + auipc x1, %pcrel_hi (foo_addr) +.ifdef __64_bit__ + ld x1, %pcrel_lo (.L1) (x1) +.else + lw x1, %pcrel_lo (.L1) (x1) +.endif + ret + .size bar, .-bar + + .data +foo_addr: +.ifdef __64_bit__ + .quad foo +.else + .long foo +.endif diff --git a/ld/testsuite/ld-riscv-elf/ifunc-reloc-got-exe.rd b/ld/testsuite/ld-riscv-elf/ifunc-reloc-got-exe.rd new file mode 100644 index 00000000000..97461e43ccc --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-reloc-got-exe.rd @@ -0,0 +1,3 @@ +Relocation section '.rela.plt' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_IRELATIVE[ ]+[0-9a-f]* diff --git a/ld/testsuite/ld-riscv-elf/ifunc-reloc-got-pic.rd b/ld/testsuite/ld-riscv-elf/ifunc-reloc-got-pic.rd new file mode 100644 index 00000000000..41cbc0712c9 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-reloc-got-pic.rd @@ -0,0 +1,3 @@ +Relocation section '.rela.got' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_(32|64)[ ]+foo\(\)[ ]+foo \+ 0 diff --git a/ld/testsuite/ld-riscv-elf/ifunc-reloc-got-pie.rd b/ld/testsuite/ld-riscv-elf/ifunc-reloc-got-pie.rd new file mode 100644 index 00000000000..cef1a77c437 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-reloc-got-pie.rd @@ -0,0 +1,3 @@ +Relocation section '.rela.got' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_IRELATIVE[ ]+[0-9a-f]* diff --git a/ld/testsuite/ld-riscv-elf/ifunc-reloc-got.d b/ld/testsuite/ld-riscv-elf/ifunc-reloc-got.d new file mode 100644 index 00000000000..3277e8f10bd --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-reloc-got.d @@ -0,0 +1,9 @@ +#... +Disassembly of section .text: +#... +0+[0-9a-f]+ <foo_resolver>: +#... +0+[0-9a-f]+ <bar>: +.*:[ ]+[0-9a-f]+[ ]+auipc[ ]+.* +.*:[ ]+[0-9a-f]+[ ]+(lw|ld)[ ]+.*<(_GLOBAL_OFFSET_TABLE_.*|.*)> +#... diff --git a/ld/testsuite/ld-riscv-elf/ifunc-reloc-got.s b/ld/testsuite/ld-riscv-elf/ifunc-reloc-got.s new file mode 100644 index 00000000000..eca16d52cfd --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-reloc-got.s @@ -0,0 +1,23 @@ + .text + + .type foo_resolver, @function +foo_resolver: + ret + .size foo_resolver, .-foo_resolver + + .globl foo + .type foo, %gnu_indirect_function + .set foo, foo_resolver + + .globl bar + .type bar, @function +bar: +.L1: + auipc x1, %got_pcrel_hi (foo) +.ifdef __64_bit__ + ld x1, %pcrel_lo (.L1) (x1) +.else + lw x1, %pcrel_lo (.L1) (x1) +.endif + ret + .size bar, .-bar diff --git a/ld/testsuite/ld-riscv-elf/ifunc-reloc-pcrel-exe.rd b/ld/testsuite/ld-riscv-elf/ifunc-reloc-pcrel-exe.rd new file mode 100644 index 00000000000..97461e43ccc --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-reloc-pcrel-exe.rd @@ -0,0 +1,3 @@ +Relocation section '.rela.plt' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_IRELATIVE[ ]+[0-9a-f]* diff --git a/ld/testsuite/ld-riscv-elf/ifunc-reloc-pcrel-pic.rd b/ld/testsuite/ld-riscv-elf/ifunc-reloc-pcrel-pic.rd new file mode 100644 index 00000000000..7bfaa2d266b --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-reloc-pcrel-pic.rd @@ -0,0 +1,3 @@ +Relocation section '.rela.plt' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_JUMP_SLOT[ ]+foo\(\)[ ]+foo \+ 0 diff --git a/ld/testsuite/ld-riscv-elf/ifunc-reloc-pcrel-pie.rd b/ld/testsuite/ld-riscv-elf/ifunc-reloc-pcrel-pie.rd new file mode 100644 index 00000000000..97461e43ccc --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-reloc-pcrel-pie.rd @@ -0,0 +1,3 @@ +Relocation section '.rela.plt' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_IRELATIVE[ ]+[0-9a-f]* diff --git a/ld/testsuite/ld-riscv-elf/ifunc-reloc-pcrel.d b/ld/testsuite/ld-riscv-elf/ifunc-reloc-pcrel.d new file mode 100644 index 00000000000..bc947e3cf29 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-reloc-pcrel.d @@ -0,0 +1,15 @@ +#... +Disassembly of section .plt: +#... +0+[0-9a-f]+ <(\*ABS\*\+0x[0-9a-f]+@plt|foo@plt|.plt)>: +#... +Disassembly of section .text: +#... +0+[0-9a-f]+ <foo_resolver>: +#... +0+[0-9a-f]+ <bar>: +.*:[ ]+[0-9a-f]+[ ]+auipc[ ]+.* +.*:[ ]+[0-9a-f]+[ ]+addi[ ]+.*<(\*ABS\*\+0x[0-9a-f]+@plt|foo@plt|.plt)> +.*:[ ]+[0-9a-f]+[ ]+auipc[ ]+.* +.*:[ ]+[0-9a-f]+[ ]+(lw|ld)[ ]+.*<(\*ABS\*\+0x[0-9a-f]+@plt|foo@plt|.plt)> +#... diff --git a/ld/testsuite/ld-riscv-elf/ifunc-reloc-pcrel.s b/ld/testsuite/ld-riscv-elf/ifunc-reloc-pcrel.s new file mode 100644 index 00000000000..7ea454cec58 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-reloc-pcrel.s @@ -0,0 +1,26 @@ + .text + + .type foo_resolver, @function +foo_resolver: + ret + .size foo_resolver, .-foo_resolver + + .globl foo + .type foo, %gnu_indirect_function + .set foo, foo_resolver + + .globl bar + .type bar, @function +bar: +.L1: + auipc x1, %pcrel_hi (foo) + addi x1, x1, %pcrel_lo (.L1) +.L2: + auipc x2, %pcrel_hi (foo) +.ifdef __64_bit__ + ld x2, %pcrel_lo (.L2) (x2) +.else + lw x2, %pcrel_lo (.L2) (x2) +.endif + ret + .size bar, .-bar diff --git a/ld/testsuite/ld-riscv-elf/ifunc-seperate-caller-nonplt.s b/ld/testsuite/ld-riscv-elf/ifunc-seperate-caller-nonplt.s new file mode 100644 index 00000000000..23c7254ad5b --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-seperate-caller-nonplt.s @@ -0,0 +1,23 @@ + .text + + # Call the IFUNC `foo` which is defined in the other modules. + .globl foo + .type foo, %function + + .globl main + .type main, @function +main: +.L1: + auipc x1, %got_pcrel_hi (foo) + addi x1, x1, %pcrel_lo (.L1) + +.L2: + auipc x2, %pcrel_hi (foo_addr) + addi x2, x2, %pcrel_lo (.L2) + + ret + .size main, .-main + + .data +foo_addr: + .long foo diff --git a/ld/testsuite/ld-riscv-elf/ifunc-seperate-caller-pcrel.s b/ld/testsuite/ld-riscv-elf/ifunc-seperate-caller-pcrel.s new file mode 100644 index 00000000000..2d29bcd121b --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-seperate-caller-pcrel.s @@ -0,0 +1,14 @@ + .text + + # Call the IFUNC `foo` which is defined in the other modules. + .globl foo + .type foo, %function + + .globl main + .type main, @function +main: +.L1: + auipc x1, %pcrel_hi (foo) + addi x1, x1, %pcrel_lo (.L1) + ret + .size main, .-main diff --git a/ld/testsuite/ld-riscv-elf/ifunc-seperate-caller-plt.s b/ld/testsuite/ld-riscv-elf/ifunc-seperate-caller-plt.s new file mode 100644 index 00000000000..8aa64034706 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-seperate-caller-plt.s @@ -0,0 +1,26 @@ + .text + + # Call the IFUNC `foo` which is defined in the other modules. + .globl foo + .type foo, %function + + .globl main + .type main, @function +main: +.L1: + auipc x1, %got_pcrel_hi (foo) + addi x1, x1, %pcrel_lo (.L1) + +.L2: + auipc x2, %pcrel_hi (foo_addr) + addi x2, x2, %pcrel_lo (.L2) + + call foo + call foo@plt + + ret + .size main, .-main + + .data +foo_addr: + .long foo diff --git a/ld/testsuite/ld-riscv-elf/ifunc-seperate-nonplt-exe.d b/ld/testsuite/ld-riscv-elf/ifunc-seperate-nonplt-exe.d new file mode 100644 index 00000000000..540a21bc0a3 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-seperate-nonplt-exe.d @@ -0,0 +1,14 @@ +#name: Link shared ifunc resolver with non-PLT caller (exe) +#source: ifunc-seperate-caller-nonplt.s +#as: +#ld: -z nocombreloc tmpdir/ifunc-seperate-resolver.so +#warning: .* +#readelf: -rW + +Relocation section '.rela.got' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_(32|64)[ ]+[0-9a-f]+[ ]+foo \+ 0 +#... +Relocation section '.rela.plt' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_JUMP_SLOT[ ]+[0-9a-f]+[ ]+foo \+ 0 diff --git a/ld/testsuite/ld-riscv-elf/ifunc-seperate-nonplt-pic.d b/ld/testsuite/ld-riscv-elf/ifunc-seperate-nonplt-pic.d new file mode 100644 index 00000000000..3ed1812cbf5 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-seperate-nonplt-pic.d @@ -0,0 +1,13 @@ +#name: Link shared ifunc resolver with non-PLT caller (pic) +#source: ifunc-seperate-caller-nonplt.s +#as: +#ld: -z nocombreloc -shared tmpdir/ifunc-seperate-resolver.so +#readelf: -rW + +Relocation section '.rela.data' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_(32|64)[ ]+[0-9a-f]+[ ]+foo \+ 0 +#... +Relocation section '.rela.got' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_(32|64)[ ]+[0-9a-f]+[ ]+foo \+ 0 diff --git a/ld/testsuite/ld-riscv-elf/ifunc-seperate-nonplt-pie.d b/ld/testsuite/ld-riscv-elf/ifunc-seperate-nonplt-pie.d new file mode 100644 index 00000000000..c9c9eabaeb0 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-seperate-nonplt-pie.d @@ -0,0 +1,14 @@ +#name: Link shared ifunc resolver with non-PLT caller (pie) +#source: ifunc-seperate-caller-nonplt.s +#as: +#ld: -z nocombreloc -pie tmpdir/ifunc-seperate-resolver.so +#warning: .* +#readelf: -rW + +Relocation section '.rela.data' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_(32|64)[ ]+[0-9a-f]+[ ]+foo \+ 0 +#... +Relocation section '.rela.got' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_(32|64)[ ]+[0-9a-f]+[ ]+foo \+ 0 diff --git a/ld/testsuite/ld-riscv-elf/ifunc-seperate-pcrel-pic.d b/ld/testsuite/ld-riscv-elf/ifunc-seperate-pcrel-pic.d new file mode 100644 index 00000000000..1c11a2d15b2 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-seperate-pcrel-pic.d @@ -0,0 +1,5 @@ +#name: Link shared IFUNC resolver with PCREL caller (pic) +#source: ifunc-seperate-caller-pcrel.s +#as: +#ld: -z nocombreloc -shared tmpdir/ifunc-seperate-resolver.so +#error: .*unresolvable R_RISCV_PCREL_HI20 relocation.* diff --git a/ld/testsuite/ld-riscv-elf/ifunc-seperate-pcrel-pie.d b/ld/testsuite/ld-riscv-elf/ifunc-seperate-pcrel-pie.d new file mode 100644 index 00000000000..0d0e3cc1c82 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-seperate-pcrel-pie.d @@ -0,0 +1,5 @@ +#name: Link shared IFUNC resolver with PCREL caller (pie) +#source: ifunc-seperate-caller-pcrel.s +#as: +#ld: -z nocombreloc -pie tmpdir/ifunc-seperate-resolver.so +#error: .*unresolvable R_RISCV_PCREL_HI20 relocation.* diff --git a/ld/testsuite/ld-riscv-elf/ifunc-seperate-plt-exe.d b/ld/testsuite/ld-riscv-elf/ifunc-seperate-plt-exe.d new file mode 100644 index 00000000000..a5385641868 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-seperate-plt-exe.d @@ -0,0 +1,14 @@ +#name: Link shared ifunc resolver with PLT caller (exe) +#source: ifunc-seperate-caller-plt.s +#as: +#ld: -z nocombreloc tmpdir/ifunc-seperate-resolver.so +#warning: .* +#readelf: -rW + +Relocation section '.rela.got' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_(32|64)[ ]+[0-9a-f]+[ ]+foo \+ 0 +#... +Relocation section '.rela.plt' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_JUMP_SLOT[ ]+[0-9a-f]+[ ]+foo \+ 0 diff --git a/ld/testsuite/ld-riscv-elf/ifunc-seperate-plt-pic.d b/ld/testsuite/ld-riscv-elf/ifunc-seperate-plt-pic.d new file mode 100644 index 00000000000..9efa244f044 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-seperate-plt-pic.d @@ -0,0 +1,17 @@ +#name: Link shared ifunc resolver with PLT caller (pic) +#source: ifunc-seperate-caller-plt.s +#as: +#ld: -z nocombreloc -shared tmpdir/ifunc-seperate-resolver.so +#readelf: -rW + +Relocation section '.rela.data' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_(32|64)[ ]+[0-9a-f]+[ ]+foo \+ 0 +#... +Relocation section '.rela.got' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_(32|64)[ ]+[0-9a-f]+[ ]+foo \+ 0 +#... +Relocation section '.rela.plt' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_JUMP_SLOT[ ]+[0-9a-f]+[ ]+foo \+ 0 diff --git a/ld/testsuite/ld-riscv-elf/ifunc-seperate-plt-pie.d b/ld/testsuite/ld-riscv-elf/ifunc-seperate-plt-pie.d new file mode 100644 index 00000000000..8349e61ed48 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-seperate-plt-pie.d @@ -0,0 +1,18 @@ +#name: Link shared ifunc resolver with PLT caller (pie) +#source: ifunc-seperate-caller-plt.s +#as: +#ld: -z nocombreloc -pie tmpdir/ifunc-seperate-resolver.so +#warning: .* +#readelf: -rW + +Relocation section '.rela.data' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_(32|64)[ ]+[0-9a-f]+[ ]+foo \+ 0 +#... +Relocation section '.rela.got' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_(32|64)[ ]+[0-9a-f]+[ ]+foo \+ 0 +#... +Relocation section '.rela.plt' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_JUMP_SLOT[ ]+[0-9a-f]+[ ]+foo \+ 0 diff --git a/ld/testsuite/ld-riscv-elf/ifunc-seperate-resolver.s b/ld/testsuite/ld-riscv-elf/ifunc-seperate-resolver.s new file mode 100644 index 00000000000..a2228473422 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/ifunc-seperate-resolver.s @@ -0,0 +1,11 @@ + .text + + .type foo_resolver, @function +foo_resolver: + ret + .size foo_resolver, .-foo_resolver + + # The ifunc `foo` is called by the ifunc-caller. + .globl foo + .type foo, %gnu_indirect_function + .set foo, foo_resolver diff --git a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp index 2c008d4c35c..b82e0921afd 100644 --- a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp +++ b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp @@ -19,6 +19,47 @@ # MA 02110-1301, USA. # +# target: rv32 or rv64. +# output: Which output you want? (exe, pie, .so) +proc run_dump_test_ifunc { name target output} { + set asflags "" + set ldflags "-z nocombreloc" + + switch -- $output { + exe { + set ext "exe" + } + pie { + set ext "pie" + set ldflags "$ldflags -pie" + } + pic { + set ext "so" + set ldflags "$ldflags -shared" + } + } + + switch -- $target { + rv32 { + set asflags "$asflags -march=rv32i -mabi=ilp32" + set ldflags "$ldflags -melf32lriscv" + } + rv64 { + set asflags "$asflags -march=rv64i -mabi=lp64 -defsym __64_bit__=1" + set ldflags "$ldflags -melf64lriscv" + } + } + + run_ld_link_tests [list \ + [list "$name ($target-$output)" \ + "$ldflags" "" \ + "$asflags" \ + [list "$name.s"] \ + [concat [list "readelf -rW $name-$output.rd"] \ + [list "objdump -dw $name.d"]] \ + "$name-$target.$ext"]] +} + if [istarget "riscv*-*-*"] { run_dump_test "call-relax" run_dump_test "c-lui" @@ -88,4 +129,74 @@ if [istarget "riscv*-*-*"] { {} "lib-nopic-01a.so" } } run_dump_test "lib-nopic-01b" + + # IFUNC testcases. + # Check IFUNC by single type relocs. + run_dump_test_ifunc "ifunc-reloc-call-01" rv32 exe + run_dump_test_ifunc "ifunc-reloc-call-01" rv32 pie + run_dump_test_ifunc "ifunc-reloc-call-01" rv32 pic + run_dump_test_ifunc "ifunc-reloc-call-02" rv32 exe + run_dump_test_ifunc "ifunc-reloc-call-02" rv32 pie + run_dump_test_ifunc "ifunc-reloc-call-02" rv32 pic + run_dump_test_ifunc "ifunc-reloc-pcrel" rv32 exe + run_dump_test_ifunc "ifunc-reloc-pcrel" rv32 pie + run_dump_test_ifunc "ifunc-reloc-pcrel" rv32 pic + run_dump_test_ifunc "ifunc-reloc-data" rv32 exe + run_dump_test_ifunc "ifunc-reloc-data" rv32 pie + run_dump_test_ifunc "ifunc-reloc-data" rv32 pic + run_dump_test_ifunc "ifunc-reloc-got" rv32 exe + run_dump_test_ifunc "ifunc-reloc-got" rv32 pie + run_dump_test_ifunc "ifunc-reloc-got" rv32 pic + run_dump_test_ifunc "ifunc-reloc-pcrel" rv64 exe + run_dump_test_ifunc "ifunc-reloc-pcrel" rv64 pie + run_dump_test_ifunc "ifunc-reloc-pcrel" rv64 pic + run_dump_test_ifunc "ifunc-reloc-data" rv64 exe + run_dump_test_ifunc "ifunc-reloc-data" rv64 pie + run_dump_test_ifunc "ifunc-reloc-data" rv64 pic + run_dump_test_ifunc "ifunc-reloc-got" rv64 exe + run_dump_test_ifunc "ifunc-reloc-got" rv64 pie + run_dump_test_ifunc "ifunc-reloc-got" rv64 pic + # Check the IFUNC PLT and non-PLT relocs. + run_dump_test_ifunc "ifunc-nonplt" rv32 exe + run_dump_test_ifunc "ifunc-nonplt" rv32 pie + run_dump_test_ifunc "ifunc-nonplt" rv32 pic + run_dump_test_ifunc "ifunc-plt-01" rv32 exe + run_dump_test_ifunc "ifunc-plt-01" rv32 pie + run_dump_test_ifunc "ifunc-plt-01" rv32 pic + run_dump_test_ifunc "ifunc-plt-02" rv32 exe + run_dump_test_ifunc "ifunc-plt-02" rv32 pie + run_dump_test_ifunc "ifunc-plt-02" rv32 pic + run_dump_test_ifunc "ifunc-nonplt" rv64 exe + run_dump_test_ifunc "ifunc-nonplt" rv64 pie + run_dump_test_ifunc "ifunc-nonplt" rv64 pic + run_dump_test_ifunc "ifunc-plt-01" rv64 exe + run_dump_test_ifunc "ifunc-plt-01" rv64 pie + run_dump_test_ifunc "ifunc-plt-01" rv64 pic + run_dump_test_ifunc "ifunc-plt-02" rv64 exe + run_dump_test_ifunc "ifunc-plt-02" rv64 pie + run_dump_test_ifunc "ifunc-plt-02" rv64 pic + + # Setup shared libraries. + run_ld_link_tests { + { "Build shared library for IFUNC non-PLT caller" + "-shared" "" "" {ifunc-seperate-caller-nonplt.s} + {} "ifunc-seperate-caller.so" } + { "Build shared library for IFUNC PLT caller" + "-shared" "" "" {ifunc-seperate-caller-plt.s} + {} "ifunc-seperate-caller.so" } + { "Build shared library for IFUNC resolver" + "-shared" "" "" {ifunc-seperate-resolver.s} + {} "ifunc-seperate-resolver.so" } + } + # The IFUNC resolver and caller are in the seperate modules. + # If IFUNC resolver and caller are linked to the same module, + # then the result are the same as the run_dump_test_ifunc. + run_dump_test "ifunc-seperate-nonplt-exe" + run_dump_test "ifunc-seperate-nonplt-pie" + run_dump_test "ifunc-seperate-nonplt-pic" + run_dump_test "ifunc-seperate-plt-exe" + run_dump_test "ifunc-seperate-plt-pie" + run_dump_test "ifunc-seperate-plt-pic" + run_dump_test "ifunc-seperate-pcrel-pie" + run_dump_test "ifunc-seperate-pcrel-pic" } |