aboutsummaryrefslogtreecommitdiff
path: root/gdb/elfread.c
diff options
context:
space:
mode:
authorTom Tromey <tromey@adacore.com>2021-08-03 12:42:43 -0600
committerTom Tromey <tromey@adacore.com>2022-01-05 10:44:53 -0700
commit28a4e64dd1b17b0d9f267c3466d7da3e8a41afd8 (patch)
tree21c1eeea078734080beb0abcef03b8d9efbd40ef /gdb/elfread.c
parent72df4c816f8a2c6dfb76988ccceee28e28bbaa3d (diff)
downloadgdb-28a4e64dd1b17b0d9f267c3466d7da3e8a41afd8.zip
gdb-28a4e64dd1b17b0d9f267c3466d7da3e8a41afd8.tar.gz
gdb-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.c69
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);
+ }
}
}
}