[PATCH] elf: Keep only one '@' for undefined versioned symbols

H.J. Lu hjl.tools@gmail.com
Fri Aug 14 00:29:48 GMT 2020


On Thu, Aug 13, 2020 at 4:52 PM Fangrui Song <i@maskray.me> wrote:
>
> Thanks for working on this issue.
>
> On Thu, Aug 13, 2020 at 3:47 PM H.J. Lu via Binutils
> <binutils@sourceware.org> wrote:
> >
> > The symbol string table in the .symtab section is optional.  Keep only
> > one '@' for undefined versioned symbols, which are defined in shared
> > objects, in the symbol string table.  Update "nm -D" to display only
> > one '@' for undefined versioned symbols.
> >
> > bfd/
> >
> >         PR ld/26382
> >         * elflink.c (elf_link_output_symstrtab): Keep only one '@' for
> >         versioned symbols, which are defined in shared  objects, in
> >         symbol string table.
> >
> > binutils/
> >
> >         PR ld/26382
> >         * nm.c (print_symname): Display only one '@' for undefined
> >         versioned symbols.
> >
> > ld/
> >
> >         PR ld/26382
> >         * testsuite/ld-elf/pr26302.nd: Updated.
> >         * testsuite/ld-elf/pr26302.rd: New file.
> >         * testsuite/ld-elf/shared.exp: Add a test for readelf -sW.
> > ---
> >  bfd/elflink.c                  | 22 +++++++++++++++++++++-
> >  binutils/nm.c                  |  5 ++++-
> >  ld/testsuite/ld-elf/pr26302.nd |  2 +-
> >  ld/testsuite/ld-elf/pr26302.rd | 12 ++++++++++++
> >  ld/testsuite/ld-elf/shared.exp |  3 ++-
> >  5 files changed, 40 insertions(+), 4 deletions(-)
> >  create mode 100644 ld/testsuite/ld-elf/pr26302.rd
> >
> > diff --git a/bfd/elflink.c b/bfd/elflink.c
> > index 0a7f5bb152..17a423270e 100644
> > --- a/bfd/elflink.c
> > +++ b/bfd/elflink.c
> > @@ -9642,9 +9642,29 @@ elf_link_output_symstrtab (struct elf_final_link_info *flinfo,
> >      {
> >        /* Call _bfd_elf_strtab_offset after _bfd_elf_strtab_finalize
> >          to get the final offset for st_name.  */
> > +      char *versioned_name = (char *) name;
> > +      if (h != NULL && h->versioned == versioned && h->def_dynamic)
> > +       {
> > +         /* Keep only one '@' for versioned symbols defined in shared
> > +            objects.  */
> > +         char *version = strrchr (name, ELF_VER_CHR);
> > +         char *base_end = strchr (name, ELF_VER_CHR);
> > +         if (version != base_end)
> > +           {
> > +             size_t base_len;
> > +             size_t len = strlen (name);
> > +             versioned_name = bfd_alloc (flinfo->output_bfd, len);
> > +             if (versioned_name == NULL)
> > +               return 0;
> > +             base_len = base_end - name;
> > +             memcpy (versioned_name, name, base_len);
> > +             memcpy (versioned_name + base_len, version,
> > +                     len - base_len);
> > +           }
> > +       }
> >        elfsym->st_name
> >         = (unsigned long) _bfd_elf_strtab_add (flinfo->symstrtab,
> > -                                              name, FALSE);
> > +                                              versioned_name, FALSE);
> >        if (elfsym->st_name == (unsigned long) -1)
> >         return 0;
> >      }
>
> 'name' has two @. This piece of code erases one @. Is it possible to
> fix the place constructing 'name'? On the line of 4855,

@@ is needed to mark the symbol with the default version.  My patch
only changes names of undefined versioned symbols when putting
these symbols in the optional .symtab section.  It is purely cosmetic.

>       /* If this is a defined non-hidden version symbol,
> we add another @ to the name.  This indicates the
> default version of the symbol.  */
>       if ((iver.vs_vers & VERSYM_HIDDEN) == 0
>   && isym->st_shndx != SHN_UNDEF)
> *p++ = ELF_VER_CHR;
>
> Note the condition 'isym->st_shndx != SHN_UNDEF', so at least in one
> place the code is aware of the case for an undefined symbol.



-- 
H.J.


More information about the Binutils mailing list