bug-binutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug ld/21464] relocation truncated to fit: R_OR1K_GOT16 on OpenRISC, wh


From: shorne at gmail dot com
Subject: [Bug ld/21464] relocation truncated to fit: R_OR1K_GOT16 on OpenRISC, when linking libQtGui.so.4.8.7
Date: Sun, 21 Mar 2021 21:29:22 +0000

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

-- 
You are receiving this mail because:
You are on the CC list for the bug.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]