https://sourceware.org/bugzilla/show_bug.cgi?id=21464
--- Comment #10 from Giulio Benetti <giulio.benetti at micronovasrl dot com> --- Il 21/03/2021 22:29, shorne at gmail dot com ha scritto: > https://sourceware.org/bugzilla/show_bug.cgi?id=21464 > > --- Comment #9 from Stafford Horne <shorne at gmail dot com> --- > On Sun, Mar 21, 2021 at 06:09:09PM +0000, giulio.benetti at micronovasrl dot > com wrote: >> https://sourceware.org/bugzilla/show_bug.cgi?id=21464 >> >> --- Comment #8 from Giulio Benetti <giulio.benetti at micronovasrl dot com> >> --- >> Hi Stafford, >> >> Il 21/03/2021 04:00, shorne at gmail dot com ha scritto: >>> https://sourceware.org/bugzilla/show_bug.cgi?id=21464 >>> >>> --- Comment #7 from Stafford Horne <shorne at gmail dot com> --- >>> On Wed, Mar 17, 2021 at 10:10:13PM +0000, shorne at gmail dot com wrote: >>>> https://sourceware.org/bugzilla/show_bug.cgi?id=21464 >>>> >>>> --- Comment #6 from Stafford Horne <shorne at gmail dot com> --- >>>> On Wed, Mar 17, 2021 at 09:31:59PM +0000, giulio.benetti at micronovasrl >>>> dot >>>> com wrote: >>>>> https://sourceware.org/bugzilla/show_bug.cgi?id=21464 >>>>> >>>>> --- Comment #5 from Giulio Benetti <giulio.benetti at micronovasrl dot >>>>> com> --- >>>>> Hi Nick, >>>>> >>>>> this bug still shows up with binutils 2.36.1 like: >>>>> /home/giuliobenetti/git/upstream/or1k-binutils-2.36.1/host/lib/gcc/or1k-buildroot-linux-uclibc/9.3.0/../../../../or1k-buildroot-linux-uclibc/bin/ld: >>>>> BFD (GNU Binutils) 2.36.1 assertion fail elf32-or1k.c:2377 >>>>> /home/giuliobenetti/git/upstream/or1k-binutils-2.36.1/host/lib/gcc/or1k-buildroot-linux-uclibc/9.3.0/../../../../or1k-buildroot-linux-uclibc/bin/ld: >>>>> BFD (GNU Binutils) 2.36.1 assertion fail elf32-or1k.c:2377 >>>>> /home/giuliobenetti/git/upstream/or1k-binutils-2.36.1/host/lib/gcc/or1k-buildroot-linux-uclibc/9.3.0/../../../../or1k-buildroot-linux-uclibc/bin/ld: >>>>> BFD (GNU Binutils) 2.36.1 assertion fail elf32-or1k.c:2377 >>>>> collect2: error: ld returned 1 exit status >>>>> >>> >>> Hello, >>> >>> I was able to reproduce the "assertion fail elf32-or1k.c:2377" issue with my >>> latest glibc toolchain versions, and I also did some debugging of LD to try >>> to >>> get an idea of what is going on. >>> >>> Reproduced with: >>> - Just building protobuf on its own, not using buildroot, that was >>> giving me >>> some exceptions about not being able to find a thread librarty. >>> >>> Notes >>> >>> 1. The "relocation truncated to fit: R_OR1K_GOT16" error seems not be >>> outputted >>> in the latest LD. I maybe have removed it incorrectly with some recent >>> changes? The >>> issue is not fixed. The R_OR1K_GOT16 relocation limit means OpenRISC >>> fails >>> to >>> run some PLT entries at run time when there are too many symbols. I am >>> planning >>> to fix this. >> >> It seems to be the same bug since it fails on assert(), but maybe I'm wrong. >> >>> I have two ideas: >>> 1. When we get to big plt entries over the limit will use 2 >>> relocations to >>> compose the GOT offset >>> 2. Use an extra PLT trampoline entry to add the extra offset i.e. 16k >>> When we go over 32k we have another trampoline, that adds 16k and >>> jumps >>> to >>> the previous trampoline. >>> >>> 2. The "assertion fail elf32-or1k.c:2377" seems to be something different to >>> me, >>> and not related to the count of GOT entries, maybe it should be a >>> different >>> bug issue? >> >> Yes, it seems since... >> >>> 3. When debugging the "assertion fail elf32-or1k.c:2377" I see, the line we >>> are >>> failing on is: >>> >>> Breakpoint 1, or1k_elf_finish_dynamic_symbol (output_bfd=0x568460, >>> info=0x543320 <link_info>, h=0x81c0f8, sym=0x7fffffffb260) at >>> /home/shorne/work/gnu-toolchain/binutils-gdb/bfd/elf32-or1k.c:2377 >>> 2377 BFD_ASSERT (h->dynindx != -1); >>> >>> So, it's asserting that the dynindx is defined, in >>> or1k_elf_finish_dynamic_symbol before >>> we write out the PLT entry. >>> >>> In the failure cases we see: >>> >>> h->root.type bfd_link_hash_defweak AND h->forced_local >>> >>> These failing symbols have been forced_local but we are still trying to >>> write the PLT entry. >>> That doesn't seem to make much sense. >>> >>> The forced_local has been set in _bfd_elf_link_hash_hide_symbol(), the >>> generic >>> elflink code: >>> >>> #0 _bfd_elf_link_hash_hide_symbol (info=0x543320 <link_info>, >>> h=0x2bcbeb8, force_local=1) at >>> /home/shorne/work/gnu-toolchain/binutils-gdb/bfd/elflink.c:7756 >>> #1 0x000000000045e61e in _bfd_elf_link_assign_sym_version >>> (h=0x2bcbeb8, >>> data=0x7fffffffb2f0) at >>> /home/shorne/work/gnu-toolchain/binutils-gdb/bfd/elflink.c:2483 >>> #2 0x000000000043055d in bfd_link_hash_traverse (htab=0x56a790, >>> func=func@entry=0x45e33d <_bfd_elf_link_assign_sym_version>, >>> info=info@entry=0x7fffffffb2f0) >>> >>> I tried to look at other architectures and I see that most do the same >>> assert, so >>> so would they also fail? >>> >>> In riscv (a relatively modern implementation) they seem to just detect >>> this >>> case and return FALSE. >>> I will try to do that and send a patch, but it will be hard to test. >> >> I've tried to imitate what riscv does: >> ''' >> diff --git a/bfd/elf32-or1k.c b/bfd/elf32-or1k.c >> index 65938e5137..74cff4bf01 100644 >> --- a/bfd/elf32-or1k.c >> +++ b/bfd/elf32-or1k.c >> @@ -2372,15 +2372,22 @@ or1k_elf_finish_dynamic_symbol (bfd *output_bfd, >> bfd_vma got_addr; >> Elf_Internal_Rela rela; >> >> - /* This symbol has an entry in the procedure linkage table. Set >> - it up. */ >> - BFD_ASSERT (h->dynindx != -1); >> - >> splt = htab->root.splt; >> sgot = htab->root.sgotplt; >> srela = htab->root.srelplt; >> BFD_ASSERT (splt != NULL && sgot != NULL && srela != NULL); >> >> + /* This symbol has an entry in the procedure linkage table. Set >> + it up. */ >> + if ((h->dynindx == -1 >> + && !((h->forced_local || bfd_link_executable (info)) >> + && h->def_regular >> + && h->type == STT_GNU_IFUNC)) >> + || splt == NULL >> + || sgot == NULL >> + || srela == NULL) >> + return FALSE; >> + >> plt_base_addr = splt->output_section->vma + splt->output_offset; >> got_base_addr = sgot->output_section->vma + sgot->output_offset; >> >> -- >> ''' >> >> but it still fails and without emitting anything, only: >> collect2: error: ld returned 1 exit status >> >>> Any suggestion for a test case for this? >>> > > I did some more investigation about why we are actually calling the dynamic > finishup code for these symbols. > > I found some other code that might help... > > diff --git a/bfd/elf32-or1k.c b/bfd/elf32-or1k.c > index 38406eda3d6..f1cfed230a1 100644 > --- a/bfd/elf32-or1k.c > +++ b/bfd/elf32-or1k.c > @@ -2566,11 +2566,10 @@ or1k_elf_adjust_dynamic_symbol (struct bfd_link_info > *info, > if (h->type == STT_FUNC > || h->needs_plt) > { > - if (! bfd_link_pic (info) > - && !h->def_dynamic > - && !h->ref_dynamic > - && h->root.type != bfd_link_hash_undefweak > - && h->root.type != bfd_link_hash_undefined) > + if (h->plt.refcount <= 0 > + || (SYMBOL_CALLS_LOCAL (info, h) > + || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT > + && h->root.type == bfd_link_hash_undefweak))) > { > /* This case can occur if we saw a PLT reloc in an input > file, but the symbol was never referred to by a dynamic > > -- > > With this patch we skip the PLT calls once we determine they have been "forced > local". It seems to work. > > -Stafford > Hi Stafford, thank you for providing such fix, it works with binutils: - 2.32 - 2.34 - 2.35.2 - 2.36.1 while building these packages: - protobuf - libtheora - zeromq that were previously failing to link. Thanks a lot! Best regards Giulio Benetti -- You are receiving this mail because: You are on the CC list for the bug.