[PATCH] elf: Keep only one '@' for undefined versioned symbols
H.J. Lu
hjl.tools@gmail.com
Sat Jul 31 16:00:45 GMT 2021
On Sat, Jul 31, 2021 at 3:33 AM Alan Modra via Binutils
<binutils@sourceware.org> wrote:
>
> On Fri, Jul 30, 2021 at 08:15:54AM -0600, Tom Tromey wrote:
> > Alan> The first thing that jumps out at me from your description of the
> > Alan> problem is that some_package__some_kind_of_error@SYMS in the
> > Alan> executable is in fact a defined symbol, whereas HJ's log for the
> > Alan> change that removed an "@" from the symbol name talks about undefined
> > Alan> symbols. We very likely have a linker bug.
> >
> > Thank you for looking at this.
> >
> > Alan> However, I'd like to see the result of
> > Alan> nm -D lib/libsal.so | grep some_kind
> > Alan> before making too many more comments. The dynamic symbols are the
> > Alan> ones that matter.
> >
> > $ nm -D lib/libsal.so | grep some_kind
> > 00020004 D some_package__some_kind_of_error
> > 00001ee0 R some_package__some_kind_of_errorE
>
> Heh, that doesn't help much really. The output depends on the version
> of nm.
>
> Here's a little more analysis. Dynamic symbols have a name and an
> optional version. If they have a version, it is given by an entry in
> a SHT_GNU_verdef section for defined symbols, and an entry in a
> SHT_GNU_verneed section for undefined symbols. The name string
> reported by readelf and nm (if recent) is manufactured from the symbol
> st_name and version indices looking up relevant string table sections.
> No '@' appears in either the st_name or version strings. Those are
> manufactured by readelf and nm. For readelf the number of '@'s shown
> depends on whether the version came from SHT_GNU_verneed (one '@') or
> from SHT_GNU_verdef (one '@' for symbols that only define a specific
> version, two '@'s if the symbol is the default version which satisfies
readelf.c has
/* Versioned symbol info. */
enum versioned_symbol_info
{
symbol_undefined,
symbol_hidden,
symbol_public
};
...
*sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
...
if (version_string)
printf (sym_info == symbol_public ? "@@%s" : "@%s",
version_string);
...
if (version_string)
{
if (sym_info == symbol_undefined)
printf ("@%s (%d)", version_string, vna_other);
else
printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
version_string);
}
It matches nm behavior.
> unversioned references as well a specific version). nm does it a
> little differently.
>
> Rather weirdly, dynamic symbols for variables copied into an
> executable .dynbss section and initialised by copy relocations, are
> given versions in SHT_GNU_verneed. This despite them being
> definitions. I haven't delved into why that is so, but this is the
> reason why readelf displays them with one '@'. nm displays them with
> two '@'s if they don't have the VERSYM_HIDDEN flag (the flag that says
> only to satisfy a specific versioned reference).
>
> Non-dynamic symbols (those in .symtab) don't make use of verdef or
> verneed sections, instead putting @VER and @@VER in the symbol name.
> HJ's patch was to match dynamic symbol naming (the manufactured
> readelf string) for symbols emitted in an executable or shared library
> .symtab.
>
> In summary, we have either a bug in readelf (my guess) or a bug in nm.
> ld may have a copy reloc symbol bug. And gdb doesn't do the right
> thing for dynamic symbols, since looking for @'s in their names is
> futile. I believe gdb ought to look at
> ((elf_symbol_type *) sym)->version & VERSYM_HIDDEN
> instead for dynamic symbols.
>
> I hope I got all that correct..
>
> --
> Alan Modra
> Australia Development Lab, IBM
--
H.J.
More information about the Binutils
mailing list