[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
Mon Jun 23 15:46:06 GMT 2025
Umm, I probably found the root cause, so the workaround in this patch
should be wrong. I will send another patch for this issue later after
passing some regressions.
Thanks
Nelson
On Fri, Jun 20, 2025 at 1:28 PM Nelson Chu <nelson@rivosinc.com> wrote:
> 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/20250623/298cfd34/attachment.htm>
More information about the Binutils
mailing list