[PATCH 1/3] RISC-V: Allow to generate RELATIVE in got if pie and sections of GOT_HO20 are all discared
Nelson Chu
nelson@rivosinc.com
Fri Jun 20 05:28:56 GMT 2025
Hi guys,
I plan to commit this one, and the latter one "RISC-V: Don't allocate
dynamic relocation if it's section was discarded", if there are no
objections until next weekend ;)
Thanks
Nelson
On Sat, Jun 7, 2025 at 4:36 PM Nelson Chu <nelson@rivosinc.com> wrote:
> This happened when I was porting the relr stuff, and caused problem for
> relr-discard testcases. Considering there is an got entry needs an dynamic
> RELATIVE relocation when pie, we used to have an assert to make sure that
> the
> h->got.offset was marked as done in the relocate_section function. But if
> the
> sections of related GOT_HO20 are all discared by linker script, all related
> GOT_HI20 will be skipped and converted to R_RISCV_NONE in the
> relocate_section,
> so that the h->got.offset won't be marked as done, and then break the link.
>
> According to the relr-discard testcases of aarch64 and loongarch, it seems
> still need to generate a dynamic RELATIVE for this case. The loongarch
> seems
> doesn't have the assert, but aarch64 and x86 have. I don't know how it
> works
> with the assert check for this case, so I just ignore the assert until
> someone
> clarify and figure it out.
> ---
> bfd/elfnn-riscv.c | 17 ++++-
> ld/testsuite/ld-riscv-elf/discard-pic.d | 15 +++++
> ld/testsuite/ld-riscv-elf/discard-pie.d | 15 +++++
> ld/testsuite/ld-riscv-elf/discard.ld | 13 ++++
> ld/testsuite/ld-riscv-elf/discard.s | 75 ++++++++++++++++++++++
> ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp | 3 +
> 6 files changed, 135 insertions(+), 3 deletions(-)
> create mode 100644 ld/testsuite/ld-riscv-elf/discard-pic.d
> create mode 100644 ld/testsuite/ld-riscv-elf/discard-pie.d
> create mode 100644 ld/testsuite/ld-riscv-elf/discard.ld
> create mode 100644 ld/testsuite/ld-riscv-elf/discard.s
>
> diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
> index 1c494f5f986..db9372c2b10 100644
> --- a/bfd/elfnn-riscv.c
> +++ b/bfd/elfnn-riscv.c
> @@ -3446,9 +3446,20 @@ riscv_elf_finish_dynamic_symbol (bfd *output_bfd,
> /* If this is a local symbol reference, we just want to emit
> a RELATIVE reloc. This can happen if it is a -Bsymbolic link,
> or a pie link, or the symbol was forced to be local because
> - of a version file. The entry in the global offset table will
> - already have been initialized in the relocate_section
> function. */
> - BFD_ASSERT ((h->got.offset & 1) != 0);
> + of a version file. The entry in the global offset table
> "should"
> + already have been initialized in the relocate_section
> function,
> + except the sections of the related relocation are all
> discarded. */
> +
> + /* If the sections of the related relocation are all discarded,
> then
> + the RELOC_AGAINST_DISCARDED_SECTION cleans all related
> relocation
> + to R_RISCV_NONE in the relocate_section, so the h->got.offset
> will
> + not be marked as done in the relocate_section function. In
> this
> + case most of the targets seems still generate a RELATIVE
> reloc,
> + but I don't know how that works with the following assert, so
> just
> + ignore it until someone clarify and figure this out.
> +
> + BFD_ASSERT ((h->got.offset & 1) != 0); */
> +
> asection *sec = h->root.u.def.section;
> rela.r_info = ELFNN_R_INFO (0, R_RISCV_RELATIVE);
> rela.r_addend = (h->root.u.def.value
> diff --git a/ld/testsuite/ld-riscv-elf/discard-pic.d
> b/ld/testsuite/ld-riscv-elf/discard-pic.d
> new file mode 100644
> index 00000000000..f876cdf06ba
> --- /dev/null
> +++ b/ld/testsuite/ld-riscv-elf/discard-pic.d
> @@ -0,0 +1,15 @@
> +#source: discard.s
> +#as: -march=rv64i -mabi=lp64
> +#ld: -shared -T discard.ld -melf64lriscv
> +#readelf: -rW
> +
> +Relocation section '\.rela\.dyn'.*
> +[ ]+Offset[ ]+Info[ ]+Type.*
> +0000000000020010[ ]+[0-9a-f]+[ ]+R_RISCV_RELATIVE[ ]+10004
> +0+0[ ]+0+0[ ]+R_RISCV_NONE[ ]+0
> +0+0[ ]+0+0[ ]+R_RISCV_NONE[ ]+0
> +0+0[ ]+0+0[ ]+R_RISCV_NONE[ ]+0
> +0+0[ ]+0+0[ ]+R_RISCV_NONE[ ]+0
> +0+0[ ]+0+0[ ]+R_RISCV_NONE[ ]+0
> +0000000000020018[ ]+[0-9a-f]+[ ]+R_RISCV_64[
> ]+000000000001000c[ ]+sym_global \+ 0
> +0000000000020020[ ]+[0-9a-f]+[ ]+R_RISCV_64[
> ]+000000000001000c[ ]+sym_global_keep \+ 0
> diff --git a/ld/testsuite/ld-riscv-elf/discard-pie.d
> b/ld/testsuite/ld-riscv-elf/discard-pie.d
> new file mode 100644
> index 00000000000..4e0d8cfb495
> --- /dev/null
> +++ b/ld/testsuite/ld-riscv-elf/discard-pie.d
> @@ -0,0 +1,15 @@
> +#source: discard.s
> +#as: -march=rv64i -mabi=lp64
> +#ld: -pie -T discard.ld -melf64lriscv
> +#readelf: -rW
> +
> +Relocation section '\.rela\.dyn'.*
> +[ ]+Offset[ ]+Info[ ]+Type.*
> +0000000000020010[ ]+[0-9a-f]+[ ]+R_RISCV_RELATIVE[ ]+10004
> +0000000000020018[ ]+[0-9a-f]+[ ]+R_RISCV_RELATIVE[ ]+1000c
> +0000000000020020[ ]+[0-9a-f]+[ ]+R_RISCV_RELATIVE[ ]+1000c
> +0+0[ ]+0+0[ ]+R_RISCV_NONE[ ]+0
> +0+0[ ]+0+0[ ]+R_RISCV_NONE[ ]+0
> +0+0[ ]+0+0[ ]+R_RISCV_NONE[ ]+0
> +0+0[ ]+0+0[ ]+R_RISCV_NONE[ ]+0
> +0+0[ ]+0+0[ ]+R_RISCV_NONE[ ]+0
> diff --git a/ld/testsuite/ld-riscv-elf/discard.ld
> b/ld/testsuite/ld-riscv-elf/discard.ld
> new file mode 100644
> index 00000000000..3afed216fbc
> --- /dev/null
> +++ b/ld/testsuite/ld-riscv-elf/discard.ld
> @@ -0,0 +1,13 @@
> +OUTPUT_ARCH(riscv)
> +ENTRY(_start)
> +SECTIONS
> +{
> + /DISCARD/ : { *(.discard.*) }
> +
> + . = 0x10000;
> + .text : { *(.text) }
> + . = 0x20000;
> + .got : { *(.got) *(.got.plt)}
> + . = 0x30000;
> + .data : { *(.data) *(.data.*) }
> +}
> diff --git a/ld/testsuite/ld-riscv-elf/discard.s
> b/ld/testsuite/ld-riscv-elf/discard.s
> new file mode 100644
> index 00000000000..729a5f9995a
> --- /dev/null
> +++ b/ld/testsuite/ld-riscv-elf/discard.s
> @@ -0,0 +1,75 @@
> +.text
> +.option pic
> +.p2align 3
> +.global _start
> +_start:
> + nop
> +
> +sym_local:
> +sym_local_keep:
> + nop
> +
> +.global sym_hidden
> +.hidden sym_hidden
> +sym_hidden:
> + nop
> +
> +.global sym_global
> +.global sym_global_keep
> +sym_global:
> +sym_global_keep:
> + nop
> +
> +.global sym_global_abs
> +.set sym_global_abs, 42
> +
> +.global sym_weak_undef
> +.weak sym_weak_undef
> +
> +.section .got_local_keep,"ax"
> + la x1, sym_local_keep
> +.section .discard.got_local_keep,"ax"
> + la x1, sym_local_keep
> +
> +.section .got_global_keep,"ax"
> + la x1, sym_global_keep
> +.section .discard.got_global_keep,"ax"
> + la x1, sym_global_keep
> +
> +# All relocation refer to sym_local are discarded.
> +.section .discard.got_local,"ax"
> + la x1, sym_local
> +
> +# All relocation refer to sym_global are discarded.
> +.section .discard.got_global,"ax"
> + la x1, sym_global
> +
> +.section .discard.local,"a"
> +.p2align 1
> +discard_local:
> +.quad sym_local
> +
> +.section .discard.hidden,"a"
> +.p2align 1
> +discard_hidden:
> +.quad sym_hidden
> +
> +.section .discard.global,"a"
> +.p2align 1
> +discard_global:
> +.quad sym_global
> +
> +.section .discard.global_abs,"a"
> +.p2align 1
> +discard_global_abs:
> +.quad sym_global_abs
> +
> +.section .discard.weak_undef,"a"
> +.p2align 1
> +discard_weak_undef:
> +.quad sym_weak_undef
> +
> +.section .discard._DYNAMIC,"a"
> +.p2align 1
> +discard_DYNAMIC:
> +.quad _DYNAMIC
> diff --git a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
> b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
> index 9cb847d3d8a..d68a9145dcd 100644
> --- a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
> +++ b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
> @@ -227,6 +227,9 @@ if [istarget "riscv*-*-*"] {
> run_dump_test "data-reloc-rv64-addr32-pic"
> run_dump_test "data-reloc-rv64-undef32-pic"
>
> + run_dump_test "discard-pie"
> + run_dump_test "discard-pic"
> +
> # IFUNC testcases.
> # Check IFUNC by single type relocs.
> run_dump_test_ifunc "ifunc-reloc-call-01" rv32 exe
> --
> 2.39.5 (Apple Git-154)
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://sourceware.org/pipermail/binutils/attachments/20250620/aa50bae4/attachment-0001.htm>
More information about the Binutils
mailing list