[PATCH] Change how versioned symbols are recorded

Tom Tromey tromey@adacore.com
Mon Aug 16 17:20:02 GMT 2021


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.
---
 gdb/elfread.c | 69 +++++++++++++++++++++++++--------------------------
 1 file changed, 34 insertions(+), 35 deletions(-)

diff --git a/gdb/elfread.c b/gdb/elfread.c
index 1dea226242d..1b6a8e6e45b 100644
--- a/gdb/elfread.c
+++ b/gdb/elfread.c
@@ -267,6 +267,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.  */
@@ -374,7 +376,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)
 		{
@@ -482,7 +484,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);
 		}
 
@@ -496,41 +497,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);
+			}
 		    }
 		}
 	    }
-- 
2.26.3



More information about the Gdb-patches mailing list