[PATCH] elf: Keep only one '@' for undefined versioned symbols
Tom Tromey
tromey@adacore.com
Thu Jul 29 19:13:35 GMT 2021
>>>>> ">" == H J Lu via Binutils <binutils@sourceware.org> writes:
>> 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.
This change broke an Ada test case for gdb. It's in the internal
AdaCore test suite, but I can share it if it's important. It only fails
for PPC and AArch64 targets.
The test case builds a .so and an executable. A function .so raises an
exception. In Ada this amounts to something like "throw
&global_variable".
The symbol in the library is like so:
$ nm lib/libsal.so |grep some_kind
00020004 D some_package__some_kind_of_error
00001eb0 R some_package__some_kind_of_errorE
and in the executable:
$ nm bin/qc04_049 |grep some_kind
10020224 B some_package__some_kind_of_error@SYMS
Note the single "@".
There's a copy reloc for this symbol:
$ readelf -r bin/qc04_049 | grep some
10020224 00003713 R_PPC_COPY 10020224 some_package__some_kin@SYMS + 0
gdb tries to find the address of this symbol. However, it picks the
wrong one -- the one from the library.
It used to work because gdb has a special hack for @@ symbols:
/* If we see a default versioned symbol, install it under
its version-less name. */
if (msym != NULL)
{
const char *atsign = strchr (sym->name, '@');
if (atsign != NULL && atsign[1] == '@' && atsign > sym->name)
{
int len = atsign - sym->name;
record_minimal_symbol (reader,
gdb::string_view (sym->name, len),
true, symaddr, ms_type, sym->section,
objfile);
That is, previously this symbol was named
some_package__some_kind_of_error@@SYMS, so gdb also recognized it
as "some_package__some_kind_of_error", causing gdb's other code to handle
Ada exceptions to find the correct address.
I considered extending this treatment to single-"@" symbols, but IIUC,
there could be multiple such symbols with the same base name and
different version suffixes.
I suppose gdb could keep track of this and DTRT if there's just a single
such symbol. But, that seems like a lot of work to undo a decision
that, according to the email at least, is supposedly purely cosmetic.
I don't really know this area very well, so I'd appreciate any advice.
Maybe there's some other way to do this that I don't understand.
I did examine the bfd_symbol itself but it doesn't seem to record any
special info:
(gdb) p *sym
$41 = {
the_bfd = 0x2750dd0,
name = 0x279358a "some_package__some_kind_of_error@SYMS",
value = 4,
flags = 65538,
section = 0x277f508,
udata = {
p = 0x0,
i = 0
}
}
In particular the flags are just BSF_OBJECT | BSF_GLOBAL.
(I suppose I was hoping for some other flag that could differentiate
this case.)
thanks,
Tom
More information about the Binutils
mailing list