Don't return "(null)" from bfd_elf_sym_name

Thiago Jung Bauermann thiago.bauermann@linaro.org
Fri Oct 4 00:45:56 GMT 2024


Hello,

Alan Modra <amodra@gmail.com> writes:

> A NULL return from bfd_elf_string_from_elf_section indicates an error.
> That shouldn't be masked by bfd_elf_sym_name but rather passed up to
> callers such as group_signature.  If we want to print "(null)" then
> that should be done at a higher level.  That's what this patch does,
> except that I chose to print "<null>" instead, like readelf.  If we
> see "(null)" we're probably passing a NULL to printf.  I haven't
> changed aoutx.h or pdp11.c print_symbol functions because they already
> handle NULL names by omitting the name.  I also haven't changed
> mach-o.c, mmo.c, som.c, srec.c, tekhex.c, vms-alpha.c and
> wasm-module.c print_symbol function because it looks like they will
> never have NULL symbol names.

This patch causes GDB to segfault in a test with a mangled symbol table:

Running gdb.base/bfd-errors.exp ...
ERROR: GDB process no longer exists
UNRESOLVED: gdb.base/bfd-errors.exp: load library with add-symbol-file

This is how the test corrupts the symbol table:

  # [...] a shared object with at least four symbols is
  # created.  The .dynsym section is extracted and offsets which should
  # refer to strings in the .dynstr section are changed to be
  # larger than the size of the .dynstr section.

GDB crashed because it wasn't prepared to get a NULL result from
bfd_asymbol_name () while building the dynamic symbols table.  I did the
obvious fix:

diff --git a/gdb/elfread.c b/gdb/elfread.c
index e959d3a2f9d3..6907d4b7e3e3 100644
--- a/gdb/elfread.c
+++ b/gdb/elfread.c
@@ -612,6 +612,8 @@ elf_rel_plt_read (minimal_symbol_reader &reader,
       const size_t got_suffix_len = strlen (SYMBOL_GOT_PLT_SUFFIX);

       name = bfd_asymbol_name (*relplt->relocation[reloc].sym_ptr_ptr);
+      if (name == nullptr)
+	name = "(null)";
       address = relplt->relocation[reloc].address;

       asection *msym_section;

But then I get a crash within BFD itself, when GDB passes the dynamic
symbols table it built to bfd_get_synthetic_symtab (). The relevant part
of the backtrace is:

#6  <signal handler called>
#7  __strlen_evex () at ../sysdeps/x86_64/multiarch/strlen-evex-base.S:81
#8  0x00005802042ce8d1 in _bfd_x86_elf_get_synthetic_symtab
      (abfd=0x58020840f8e0, count=2, relsize=72, got_addr=0,
       plts=0x7ffcefa985e0, dynsyms=0x580208466f60, ret=0x7ffcefa98718)
      at /home/bauermann/src/binutils-gdb-wt-2/bfd/elfxx-x86.c:3713
#9  0x00005802042c4c41 in elf_x86_64_get_synthetic_symtab
      (abfd=0x58020840f8e0, symcount=28, syms=0x580208457480,
       dynsymcount=9, dynsyms=0x580208466f60, ret=0x7ffcefa98718)
      at /home/bauermann/src/binutils-gdb-wt-2/bfd/elf64-x86-64.c:5427
#10 0x0000580203989601 in elf_read_minimal_symbols
      (objfile=0x58020840bfd0, symfile_flags=2, ei=0x7ffcefa98810)
      at /home/bauermann/src/binutils-gdb-wt-2/gdb/elfread.c:1160

Frame 8's line is:

3713	      size += strlen ((*p->sym_ptr_ptr)->name) + sizeof ("@plt");

Where:

(top-gdb) p **p->sym_ptr_ptr
$8 = {
  the_bfd = 0x58020840f8e0,
  name = 0x0,
  value = 0,
  flags = 4227073,
  section = 0x580205cfcad8 <_bfd_std_section+280>,
  udata = {
    p = 0x0,
    i = 0
  }
}

So it looks like bfd_get_synthetic_symtab () isn't prepared to deal with
the existance of symbols without a name. Should it? Or should GDB fix up
the section contents so that they'd point to a "(null)" string?

-- 
Thiago


More information about the Gdb-patches mailing list