This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Shared library call problems on PowerPC with current binutils/gdb


On Sat, May 03, 2008 at 05:38:40PM +0200, Ulrich Weigand wrote:
> I see.  Hmmm, we could do the same for versioned symbols and just
> install two minsyms.  For disassembly, we'd see the decorated name,
> but searching for just the base name would find the function as well ...

There's a downside of this; it shows up twice in info functions,
rbreak, et cetera.

(gdb) rbreak malloc
Breakpoint 3 at 0x97f8
<function, no debug info> malloc;
Note: breakpoint 3 also set at pc 0x97f8.
Breakpoint 4 at 0x97f8
<function, no debug info> malloc@plt;

So it may be worth pursuing the two-names approach, or fixing up
things that list symbols to omit multiple symbols at the same address.
That latter could be useful anyway for glibc aliases.  I'm not sure.

> > > > Hmm, thinking about this more, it probably won't work for your
> > > > case after all.  lookup_solib_trampoline_symbol_by_pc will return
> > > > NULL if the first symbol we find is the text version.
> > > 
> > > If we have two symbols, *both* need to be mst_solib_trampoline.
> > 
> > Would that be true if we could search for a symbol with the
> > appropriate type?  Prefer the trampoline when trying to find a
> > trampoline target, prefer the text symbol with the decorated name
> > otherwise.
> 
> That's probably the best solution, right.

Here's the patch I'm currently using.

-- 
Daniel Jacobowitz
CodeSourcery

2008-05-03  Daniel Jacobowitz  <dan@codesourcery.com>

	* elfread.c (elf_symtab_read): Create trampolines for @plt symbols.
	* minsyms.c (lookup_minimal_symbol_by_pc_section_1): Renamed from
	lookup_minimal_symbol_by_pc_section.  Prefer trampolines if requested.
	(lookup_minimal_symbol_by_pc_section): Use
	lookup_minimal_symbol_by_pc_section_1.
	(lookup_solib_trampoline_symbol_by_pc): Likewise.

--- gdb/elfread.c	(revision 1034)
+++ gdb/elfread.c	(local)
@@ -521,6 +521,33 @@ elf_symtab_read (struct objfile *objfile
 	  if (msym != NULL)
 	    msym->filename = filesymname;
 	  gdbarch_elf_make_msymbol_special (gdbarch, sym, msym);
+
+	  /* 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)
+		{
+		  char *base_name = alloca (len - 4 + 1);
+		  struct minimal_symbol *mtramp;
+
+		  memcpy (base_name, sym->name, len - 4);
+		  base_name[len - 4] = '\0';
+		  mtramp = record_minimal_symbol (base_name, symaddr,
+						  mst_solib_trampoline,
+						  sym->section, objfile);
+		  if (mtramp)
+		    {
+		      MSYMBOL_SIZE (mtramp) = MSYMBOL_SIZE (msym);
+		      mtramp->filename = filesymname;
+		      gdbarch_elf_make_msymbol_special (gdbarch, sym, mtramp);
+		    }
+		}
+	    }
 	}
     }
 }
--- gdb/minsyms.c	(revision 1034)
+++ gdb/minsyms.c	(local)
@@ -357,10 +357,15 @@ lookup_minimal_symbol_solib_trampoline (
    ALL the minimal symbol tables before deciding on the symbol that
    comes closest to the specified PC.  This is because objfiles can
    overlap, for example objfile A has .text at 0x100 and .data at
-   0x40000 and objfile B has .text at 0x234 and .data at 0x40048.  */
+   0x40000 and objfile B has .text at 0x234 and .data at 0x40048.
 
-struct minimal_symbol *
-lookup_minimal_symbol_by_pc_section (CORE_ADDR pc, asection *section)
+   If WANT_TRAMPOLINE is set, prefer mst_solib_trampoline symbols when
+   there are text and trampoline symbols at the same address.
+   Otherwise prefer mst_text symbols.  */
+
+static struct minimal_symbol *
+lookup_minimal_symbol_by_pc_section_1 (CORE_ADDR pc, asection *section,
+				       int want_trampoline)
 {
   int lo;
   int hi;
@@ -369,7 +374,11 @@ lookup_minimal_symbol_by_pc_section (COR
   struct minimal_symbol *msymbol;
   struct minimal_symbol *best_symbol = NULL;
   struct obj_section *pc_section;
+  enum minimal_symbol_type want_type, other_type;
 
+  want_type = want_trampoline ? mst_solib_trampoline : mst_text;
+  other_type = want_trampoline ? mst_text : mst_solib_trampoline;
+  
   /* PC has to be in a known section.  This ensures that anything
      beyond the end of the last segment doesn't appear to be part of
      the last function in the last segment.  */
@@ -486,6 +495,24 @@ lookup_minimal_symbol_by_pc_section (COR
 		      continue;
 		    }
 
+		  /* If we are looking for a trampoline and this is a
+		     text symbol, or the other way around, check the
+		     preceeding symbol too.  If they are otherwise
+		     identical prefer that one.  */
+		  if (hi > 0
+		      && MSYMBOL_TYPE (&msymbol[hi]) == other_type
+		      && MSYMBOL_TYPE (&msymbol[hi - 1]) == want_type
+		      && (MSYMBOL_SIZE (&msymbol[hi])
+			  == MSYMBOL_SIZE (&msymbol[hi - 1]))
+		      && (SYMBOL_VALUE_ADDRESS (&msymbol[hi])
+			  == SYMBOL_VALUE_ADDRESS (&msymbol[hi - 1]))
+		      && (SYMBOL_BFD_SECTION (&msymbol[hi])
+			  == SYMBOL_BFD_SECTION (&msymbol[hi - 1])))
+		    {
+		      hi--;
+		      continue;
+		    }
+
 		  /* If the minimal symbol has a zero size, save it
 		     but keep scanning backwards looking for one with
 		     a non-zero size.  A zero size may mean that the
@@ -566,6 +593,12 @@ lookup_minimal_symbol_by_pc_section (COR
   return (best_symbol);
 }
 
+struct minimal_symbol *
+lookup_minimal_symbol_by_pc_section (CORE_ADDR pc, asection *section)
+{
+  return lookup_minimal_symbol_by_pc_section_1 (pc, section, 0);
+}
+
 /* Backward compatibility: search through the minimal symbol table 
    for a matching PC (no section given) */
 
@@ -1019,7 +1052,13 @@ msymbols_sort (struct objfile *objfile)
 struct minimal_symbol *
 lookup_solib_trampoline_symbol_by_pc (CORE_ADDR pc)
 {
-  struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (pc);
+  struct obj_section *section = find_pc_section (pc);
+  struct minimal_symbol *msymbol;
+
+  if (section == NULL)
+    return NULL;
+  msymbol = lookup_minimal_symbol_by_pc_section_1 (pc, section->the_bfd_section,
+						   1);
 
   if (msymbol != NULL && MSYMBOL_TYPE (msymbol) == mst_solib_trampoline)
     return msymbol;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]