Your code will break what we discussed in the pr13302 - "riscv inserts the dynamic relocations in the order of plt and got entry offset" On Thu, May 23, 2024 at 11:54 AM Hau Hsu wrote: > 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 >> >> >> > >