[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