diff options
author | Tom Tromey <tromey@adacore.com> | 2021-08-03 12:42:43 -0600 |
---|---|---|
committer | Tom Tromey <tromey@adacore.com> | 2022-01-05 10:44:53 -0700 |
commit | 28a4e64dd1b17b0d9f267c3466d7da3e8a41afd8 (patch) | |
tree | 21c1eeea078734080beb0abcef03b8d9efbd40ef /gdb/elfread.c | |
parent | 72df4c816f8a2c6dfb76988ccceee28e28bbaa3d (diff) | |
download | binutils-28a4e64dd1b17b0d9f267c3466d7da3e8a41afd8.zip binutils-28a4e64dd1b17b0d9f267c3466d7da3e8a41afd8.tar.gz binutils-28a4e64dd1b17b0d9f267c3466d7da3e8a41afd8.tar.bz2 |
Change how versioned symbols are recorded
A change to BFD caused a gdb regression when using the Ada "catch
exception" feature. The bug is visible when a shared library throws
an exception that is caught in the main executable.
This was discussed here:
https://sourceware.org/pipermail/binutils/2021-July/117538.html
This patch implements Alan's proposed fix, namely to use VERSYM_HIDDEN
rather than the name when deciding to install a version-less symbol.
The internal test case is identical to the catch_ex_std.exp that is
in-tree, so I haven't added a new test. I could not make that one
fail on x86-64 Linux, though. It's possible that maybe I'd have to
update the system linker first, but I didn't want to try that.
Regression tested on x86-64 Fedora 32.
Diffstat (limited to 'gdb/elfread.c')
-rw-r--r-- | gdb/elfread.c | 69 |
1 files changed, 34 insertions, 35 deletions
diff --git a/gdb/elfread.c b/gdb/elfread.c index 9f87c9f..3f2d8b4 100644 --- a/gdb/elfread.c +++ b/gdb/elfread.c @@ -266,6 +266,8 @@ elf_symtab_read (minimal_symbol_reader &reader, continue; } + elf_symbol_type *elf_sym = (elf_symbol_type *) sym; + /* Skip "special" symbols, e.g. ARM mapping symbols. These are symbols which do not correspond to objects in the symbol table, but have some other target-specific meaning. */ @@ -373,7 +375,7 @@ elf_symtab_read (minimal_symbol_reader &reader, NOTE: uweigand-20071112: Synthetic symbols do not have an ELF-private part, so do not touch those. */ unsigned int shndx = type == ST_SYNTHETIC ? 0 : - ((elf_symbol_type *) sym)->internal_elf_sym.st_shndx; + elf_sym->internal_elf_sym.st_shndx; switch (shndx) { @@ -481,7 +483,6 @@ elf_symtab_read (minimal_symbol_reader &reader, if (type != ST_SYNTHETIC) { /* Pass symbol size field in via BFD. FIXME!!! */ - elf_symbol_type *elf_sym = (elf_symbol_type *) sym; SET_MSYMBOL_SIZE (msym, elf_sym->internal_elf_sym.st_size); } @@ -495,41 +496,39 @@ elf_symtab_read (minimal_symbol_reader &reader, 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); - } - } - - /* For @plt symbols, also record a trampoline to the - destination symbol. The @plt symbol will be used in - disassembly, and the trampoline will be used when we are - trying to find the target. */ - if (msym && ms_type == mst_text && type == ST_SYNTHETIC) - { - int len = strlen (sym->name); - - if (len > 4 && strcmp (sym->name + len - 4, "@plt") == 0) + bool is_at_symbol = atsign != nullptr && atsign > sym->name; + bool is_plt = is_at_symbol && strcmp (atsign, "@plt") == 0; + int len = is_at_symbol ? atsign - sym->name : 0; + + if (is_at_symbol + && !is_plt + && (elf_sym->version & VERSYM_HIDDEN) == 0) + record_minimal_symbol (reader, + gdb::string_view (sym->name, len), + true, symaddr, ms_type, sym->section, + objfile); + else if (is_plt) { - struct minimal_symbol *mtramp; - - mtramp = record_minimal_symbol - (reader, gdb::string_view (sym->name, len - 4), true, - symaddr, mst_solib_trampoline, sym->section, objfile); - if (mtramp) + /* For @plt symbols, also record a trampoline to the + destination symbol. The @plt symbol will be used + in disassembly, and the trampoline will be used + when we are trying to find the target. */ + if (ms_type == mst_text && type == ST_SYNTHETIC) { - SET_MSYMBOL_SIZE (mtramp, MSYMBOL_SIZE (msym)); - mtramp->created_by_gdb = 1; - mtramp->filename = filesymname; - if (elf_make_msymbol_special_p) - gdbarch_elf_make_msymbol_special (gdbarch, - sym, mtramp); + struct minimal_symbol *mtramp; + + mtramp = record_minimal_symbol + (reader, gdb::string_view (sym->name, len), true, + symaddr, mst_solib_trampoline, sym->section, objfile); + if (mtramp) + { + SET_MSYMBOL_SIZE (mtramp, MSYMBOL_SIZE (msym)); + mtramp->created_by_gdb = 1; + mtramp->filename = filesymname; + if (elf_make_msymbol_special_p) + gdbarch_elf_make_msymbol_special (gdbarch, + sym, mtramp); + } } } } |