I used riscv-gnu-toolchain to run gcc test suite (linux) and got no regressions: ========= Summary of gcc testsuite ========= | # of unexpected case / # of unique unexpected case | gcc | g++ | gfortran | rv64imafdc/ lp64d/ medlow | 0 / 0 | 0 / 0 | 0 / 0 | >> I think the quite easy solution is - don't use riscv_elf_append_rela to emit dynamic IRELATIVE for R_RISCV_32/64 into iplt section. Seems like commit 51a8a7c2e3cc only handles the finish_dynamic_symbol, but forgot to apply a similar fix in the relocate_section. It seems my change works. But I can try to modify code as suggested. Hau Hsu > On May 17, 2024, at 10:32 AM, Hau Hsu wrote: > > Let me run more toolchain integrated tests. > Thanks! > > Hau > > > >> On May 16, 2024, at 4:28 PM, Nelson Chu wrote: >> >> I think the quite easy solution is - don't use riscv_elf_append_rela to emit dynamic IRELATIVE for R_RISCV_32/64 into iplt section. Seems like commit 51a8a7c2e3cc only handles the finish_dynamic_symbol, but forgot to apply a similar fix in the relocate_section. >> >> https://github.com/bminor/binutils-gdb/blob/master/bfd/elfnn-riscv.c#L2408 >> diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c >> index 604f6de4511..dca446c0495 100644 >> --- a/bfd/elfnn-riscv.c >> +++ b/bfd/elfnn-riscv.c >> @@ -2399,13 +2399,16 @@ riscv_elf_relocate_section (bfd *output_bfd, >> 2. .rela.got section in dynamic executable. >> 3. .rela.iplt section in static executable. */ >> if (bfd_link_pic (info)) >> - sreloc = htab->elf.irelifunc; >> + riscv_elf_append_rela (output_bfd, htab->elf.irelifunc, &outrel); >> else if (htab->elf.splt != NULL) >> - sreloc = htab->elf.srelgot; >> + riscv_elf_append_rela (output_bfd, htab->elf.srelgot, &outrel); >> else >> - sreloc = htab->elf.irelplt; >> - >> - riscv_elf_append_rela (output_bfd, sreloc, &outrel); >> + { >> + const struct elf_backend_data *bed = get_elf_backend_data (output_bfd); >> + bfd_vma iplt_idx = htab->last_iplt_index--; >> + bfd_byte *loc = htab->elf.irelplt->contents + iplt_idx * sizeof (ElfNN_External_Rela); >> + bed->s->swap_reloca_out (output_bfd, &outrel, loc); >> + } >> >> /* If this reloc is against an external symbol, we >> do not want to fiddle with the addend. Otherwise, >> >> The above changes seem to fix the testcase you provided, but without testing fully riscv-gnu-toolchain regressions. >> Or we should find a way to handle reloc_index for iplt, and all use riscv_elf_append_rela to emit the dynamic relocation. >> >> Nelson >> >> On Thu, May 16, 2024 at 3:30 PM Hau Hsu > wrote: >>> >>>> On May 16, 2024, at 3:07 PM, Nelson Chu > wrote: >>>> >>>> On Thu, May 16, 2024 at 2:16 PM Hau Hsu > wrote: >>>>> Hi Nelson, >>>>> >>>>> Sorry for the late reply. >>>>> >>>>>> On May 8, 2024, at 9:00 AM, Nelson Chu > wrote: >>>>>> >>>>>> Can you provide the testcase to show the case which I mentioned in the pr13302? Which is that an ifunc with a dynamic jump slot calls another ifunc, and are not in the rel.dyn. >>>>> I am not quite sure what's the issue you mentioned in PR13302. >>>>> You mean the order issue of cause by one ifunc (generates JUMP_SLOT[32|64]) calls another JUMP_SLOT[32|64] ifunc? >>>>> >>>>>> Since according to the testcase below, it seems no requirement to apply this fix though. >>>>> The new test case uses two methods to call ifuncs: >>>>> 1. Through a normal function call: PLT + GOT >>>>> 2. Through a global function pointer: GOT only >>>>> >>>>> Without the fix, the relocation of the first method overwrites the second's. >>>>> The relocation section of my test case would be: >>>>> >>>>> Relocation section '.rela.plt' at offset 0x94 contains 2 entries: >>>>> Offset Info Type Sym. Value Symbol's Name + Addend >>>>> 000110dc 0000003a R_RISCV_IRELATIVE 100c0 >>>>> 00000000 00000000 R_RISCV_NONE 0 >>>>> >>>>> >>>>> With the fix, it becomes >>>>> >>>>> Relocation section '.rela.plt' at offset 0x94 contains 2 entries: >>>>> Offset Info Type Sym. Value Symbol's Name + Addend >>>>> 000110e0 0000003a R_RISCV_IRELATIVE 100c0 >>>>> 000110dc 0000003a R_RISCV_IRELATIVE 100c0 >>>>> >>>> >>>> So it seems like the overwrite problem, not the order problem we were discussing in the pr13302... >>> >>> Yes. Sorry that I didn't explain the whole story well. >>> >>> This PR is originally to fix the overwrite problem, as my commit message says: >>> > This commit resolved two issues: >>> > 1. When an ifunc is referenced by a pointer, the relocation of >>> > the pointer in .rela.plt would be overwritten by normal ifunc call. >>> We found the issue when building glibc testbench statically. >>> >>> To fix this issue, I sent a PR (https://sourceware.org/pipermail/binutils/2023-July/128485.html) about a year ago. >>> The PR use the method smilier to your previous commit, i.e. >>> https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=51a8a7c2e3cc0730831963651a55d23d1fae624d >>> Then you suggested to check whether the relocation order is correct. >>> After that I checked the X86 implementation, I sent this PR. >>> >>>> >>>>>>> --- /dev/null >>>>>>> +++ b/ld/testsuite/ld-riscv-elf/ifunc-macro.s >>>>>>> @@ -0,0 +1,19 @@ >>>>>>> +/* Define macros to handle similar behaviors for rv32/rv64. >>>>>>> + Assumes macro "__64_bit__" defined for rv64. >>>>>>> + The macro is specifically defined for ifunc tests in ld-riscv-elf.exp. */ >>>>>>> + >>>>>>> +.macro PTR_DATA name >>>>>>> +.ifdef __64_bit__ >>>>>>> + .quad \name >>>>>>> +.else >>>>>>> + .long \name >>>>>>> +.endif >>>>>>> +.endm >>>>>>> + >>>>>>> +.macro LOAD rd, rs, offset >>>>>>> +.ifdef __64_bit__ >>>>>>> + ld \rd, \offset (\rs) >>>>>>> +.else >>>>>>> + lw \rd, \offset (\rs) >>>>>>> +.endif >>>>>>> +.endm >>>> >>>> Btw, can we not use these macroes? >>> >>> No problem. I just want to avoid similar codes in the ifunc tests. >>> >>>> >>>> Nelson >>> >