[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