[PATCH] elf: Keep only one '@' for undefined versioned symbols
Alan Modra
amodra@gmail.com
Sat Jul 31 10:32:55 GMT 2021
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
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
More information about the Binutils
mailing list