[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
Thu Jul 3 03:19:08 GMT 2025


Forgot this patch, I think the right solution should be here,
https://sourceware.org/pipermail/binutils/2025-July/142095.html, thanks.

Nelson

On Mon, Jun 23, 2025 at 11:46 PM Nelson Chu <nelson@rivosinc.com> wrote:

> 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
>>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://sourceware.org/pipermail/binutils/attachments/20250703/dfb63089/attachment-0001.htm>


More information about the Binutils mailing list