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]

[commit] Handle minimal symbols pointing to function descriptors


Hello,

this patch adds support for minimal symbols pointing to function
descriptors (as is typical on PowerPC64) in:

- minsym_found (prologue parsing needs function code, not the
  descriptor)

- write_exp_msymbol (values of function type are assumed by GDB
  to refer to code, not the descriptor)

- value_fn_field (likewise)

- fixup_section (when searching for the minimal symbol corresponding
  to a debug symbol, make sure it points to the same address -- on
  PowerPC the debug symbol point to code, but the minimal symbol 
  points to the descriptor)

In addition, the patch extracts a piece of find_function_start_sal
into a new function find_function_start_pc (so it can be used by
minsym_found as well), and adds a function minsym_objfile to retrieve
the objfile where a minimal symbol is defined (this allows to get
rid of a number of current_gdbarch uses).


Tested on powerpc-linux and powerpc64-linux; on the latter the
following FAILs are now fixed:

FAIL: gdb.base/nodebug.exp: whatis top
FAIL: gdb.base/nodebug.exp: ptype top
FAIL: gdb.base/nodebug.exp: whatis middle
FAIL: gdb.base/nodebug.exp: ptype middle
FAIL: gdb.base/prologue.exp: same pc from minimal symbol
FAIL: gdb.cp/bs15503.exp: print s.length()
FAIL: gdb.cp/bs15503.exp: print s[0]
FAIL: gdb.cp/bs15503.exp: print s[s.length()-1]
FAIL: gdb.cp/bs15503.exp: print (const char *) s
FAIL: gdb.cp/bs15503.exp: print (const char *) s.substr(0,4)
FAIL: gdb.cp/bs15503.exp: print (const char *) (s=s.substr(0,4))
FAIL: gdb.cp/mb-ctor.exp: set-breakpoint at ctor
FAIL: gdb.cp/mb-ctor.exp: set-breakpoint at ctor
FAIL: gdb.cp/mb-ctor.exp: run to breakpoint
FAIL: gdb.cp/mb-ctor.exp: run to breakpoint 2
FAIL: gdb.cp/mb-ctor.exp: run to breakpoint 3
FAIL: gdb.cp/mb-ctor.exp: run to breakpoint 4 (the program is no longer running)
FAIL: gdb.cp/mb-ctor.exp: run to exit (the program is no longer running)

Committed to mainline.

Bye,
Ulrich


ChangeLog:

	* linespec.c: Include "target.h".
	(minsym_found): Handle minimal symbols pointing to function
	descriptors.  Use find_function_start_pc.
	* minsyms.c (msymbol_objfile): New function.
	* parse.c (write_exp_msymbol): Handle minimal symbols pointing
	to function descriptors.
	* symtab.c (fixup_section): Only use minimal symbol at the same
	address to determine section of a symbol.
	(find_function_start_pc): New function.
	(find_function_start_sal): Use it.
	* symtab.h (msymbol_objfile): Add prototype.
	(find_function_start_pc): Likewise.
	* value.c: Include "objfiles.h".
	(value_fn_field): Handle minimal symbols pointing to function
        descriptors. 
	* Makefile.in (linespec.o): Update dependencies.
	(value.o): Likewise.


diff -urNp gdb-orig/gdb/linespec.c gdb-head/gdb/linespec.c
--- gdb-orig/gdb/linespec.c	2008-05-03 00:53:58.209923000 +0200
+++ gdb-head/gdb/linespec.c	2008-05-03 01:59:47.220185418 +0200
@@ -38,6 +38,7 @@
 #include "language.h"
 #include "interps.h"
 #include "mi/mi-cmds.h"
+#include "target.h"
 
 /* We share this one with symtab.c, but it is not exported widely. */
 
@@ -1846,21 +1847,32 @@ symbol_found (int funfirstline, char ***
 static struct symtabs_and_lines
 minsym_found (int funfirstline, struct minimal_symbol *msymbol)
 {
+  struct objfile *objfile = msymbol_objfile (msymbol);
+  struct gdbarch *gdbarch = get_objfile_arch (objfile);
   struct symtabs_and_lines values;
+  CORE_ADDR pc;
 
   values.sals = (struct symtab_and_line *)
     xmalloc (sizeof (struct symtab_and_line));
   values.sals[0] = find_pc_sect_line (SYMBOL_VALUE_ADDRESS (msymbol),
 				      (struct bfd_section *) 0, 0);
   values.sals[0].section = SYMBOL_BFD_SECTION (msymbol);
+
+  /* The minimal symbol might point to a function descriptor;
+     resolve it to the actual code address instead.  */
+  pc = gdbarch_convert_from_func_ptr_addr (gdbarch,
+                                           values.sals[0].pc,
+                                           &current_target);
+  if (pc != values.sals[0].pc)
+    values.sals[0] = find_pc_sect_line (pc, NULL, 0);
+
   if (funfirstline)
     {
       struct symtab_and_line sal;
 
-      values.sals[0].pc
-	+= gdbarch_deprecated_function_start_offset (current_gdbarch);
-      values.sals[0].pc = gdbarch_skip_prologue
-			    (current_gdbarch, values.sals[0].pc);
+      values.sals[0].pc = find_function_start_pc (gdbarch,
+						  values.sals[0].pc,
+						  values.sals[0].section);
 
       sal = find_pc_sect_line (values.sals[0].pc, values.sals[0].section, 0);
 
diff -urNp gdb-orig/gdb/Makefile.in gdb-head/gdb/Makefile.in
--- gdb-orig/gdb/Makefile.in	2008-05-03 01:25:56.722613000 +0200
+++ gdb-head/gdb/Makefile.in	2008-05-03 01:59:47.282176489 +0200
@@ -2373,7 +2373,8 @@ libunwind-frame.o: libunwind-frame.c $(d
 linespec.o: linespec.c $(defs_h) $(symtab_h) $(frame_h) $(command_h) \
 	$(symfile_h) $(objfiles_h) $(source_h) $(demangle_h) $(value_h) \
 	$(completer_h) $(cp_abi_h) $(parser_defs_h) $(block_h) $(interps_h) \
-	$(objc_lang_h) $(linespec_h) $(exceptions_h) $(language_h) $(mi_cmds_h)
+	$(objc_lang_h) $(linespec_h) $(exceptions_h) $(language_h) \
+	$(mi_cmds_h) $(target_h)
 linux-fork.o: linux-fork.c $(defs_h) $(inferior_h) $(regcache_h) $(gdbcmd_h) \
 	$(infcall_h) $(gdb_assert_h) $(gdb_string_h) $(linux_fork_h) \
 	$(linux_nat_h) $(gdb_wait_h) $(gdb_dirent_h)
@@ -2967,7 +2968,7 @@ valprint.o: valprint.c $(defs_h) $(gdb_s
 value.o: value.c $(defs_h) $(gdb_string_h) $(symtab_h) $(gdbtypes_h) \
 	$(value_h) $(gdbcore_h) $(command_h) $(gdbcmd_h) $(target_h) \
 	$(language_h) $(demangle_h) $(doublest_h) \
-	$(gdb_assert_h) $(regcache_h) $(block_h) $(dfp_h)
+	$(gdb_assert_h) $(regcache_h) $(block_h) $(dfp_h) $(objfiles_h)
 varobj.o: varobj.c $(defs_h) $(exceptions_h) $(value_h) $(expression_h) \
 	$(frame_h) $(language_h) $(wrapper_h) $(gdbcmd_h) $(block_h) \
 	$(gdb_assert_h) $(gdb_string_h) $(varobj_h) $(vec_h) $(gdbthread_h) \
diff -urNp gdb-orig/gdb/minsyms.c gdb-head/gdb/minsyms.c
--- gdb-orig/gdb/minsyms.c	2008-05-03 00:53:58.302909000 +0200
+++ gdb-head/gdb/minsyms.c	2008-05-03 01:59:47.325170296 +0200
@@ -132,6 +132,26 @@ add_minsym_to_demangled_hash_table (stru
 }
 
 
+/* Return OBJFILE where minimal symbol SYM is defined.  */
+struct objfile *
+msymbol_objfile (struct minimal_symbol *sym)
+{
+  struct objfile *objf;
+  struct minimal_symbol *tsym;
+
+  unsigned int hash
+    = msymbol_hash (SYMBOL_LINKAGE_NAME (sym)) % MINIMAL_SYMBOL_HASH_SIZE;
+
+  for (objf = object_files; objf; objf = objf->next)
+    for (tsym = objf->msymbol_hash[hash]; tsym; tsym = tsym->hash_next)
+      if (tsym == sym)
+	return objf;
+
+  /* We should always be able to find the objfile ...  */
+  internal_error (__FILE__, __LINE__, _("failed internal consistency check"));
+}
+
+
 /* Look through all the current minimal symbol tables and find the
    first minimal symbol that matches NAME.  If OBJF is non-NULL, limit
    the search to that objfile.  If SFILE is non-NULL, the only file-scope
diff -urNp gdb-orig/gdb/parse.c gdb-head/gdb/parse.c
--- gdb-orig/gdb/parse.c	2008-05-03 00:53:58.308908000 +0200
+++ gdb-head/gdb/parse.c	2008-05-03 01:59:47.331169432 +0200
@@ -400,39 +400,46 @@ write_exp_msymbol (struct minimal_symbol
 		   struct type *text_symbol_type, 
 		   struct type *data_symbol_type)
 {
-  struct gdbarch *gdbarch = current_gdbarch;
-  CORE_ADDR addr;
+  struct objfile *objfile = msymbol_objfile (msymbol);
+  struct gdbarch *gdbarch = get_objfile_arch (objfile);
+
+  CORE_ADDR addr = SYMBOL_VALUE_ADDRESS (msymbol);
+  asection *bfd_section = SYMBOL_BFD_SECTION (msymbol);
+  enum minimal_symbol_type type = msymbol->type;
+  CORE_ADDR pc;
+
+  /* The minimal symbol might point to a function descriptor;
+     resolve it to the actual code address instead.  */
+  pc = gdbarch_convert_from_func_ptr_addr (gdbarch, addr, &current_target);
+  if (pc != addr)
+    {
+      /* In this case, assume we have a code symbol instead of
+	 a data symbol.  */
+      type = mst_text;
+      bfd_section = NULL;
+      addr = pc;
+    }
+
+  if (overlay_debugging)
+    addr = symbol_overlayed_address (addr, bfd_section);
 
   write_exp_elt_opcode (OP_LONG);
   /* Let's make the type big enough to hold a 64-bit address.  */
   write_exp_elt_type (builtin_type_CORE_ADDR);
-
-  addr = SYMBOL_VALUE_ADDRESS (msymbol);
-  if (overlay_debugging)
-    addr = symbol_overlayed_address (addr, SYMBOL_BFD_SECTION (msymbol));
   write_exp_elt_longcst ((LONGEST) addr);
-
   write_exp_elt_opcode (OP_LONG);
 
-  if (SYMBOL_BFD_SECTION (msymbol)
-      && SYMBOL_BFD_SECTION (msymbol)->flags & SEC_THREAD_LOCAL)
+  if (bfd_section && bfd_section->flags & SEC_THREAD_LOCAL)
     {
-      bfd *bfd = SYMBOL_BFD_SECTION (msymbol)->owner;
-      struct objfile *ofp;
-
-      ALL_OBJFILES (ofp)
-	if (ofp->obfd == bfd)
-	  break;
-
       write_exp_elt_opcode (UNOP_MEMVAL_TLS);
-      write_exp_elt_objfile (ofp);
+      write_exp_elt_objfile (objfile);
       write_exp_elt_type (builtin_type (gdbarch)->nodebug_tls_symbol);
       write_exp_elt_opcode (UNOP_MEMVAL_TLS);
       return;
     }
 
   write_exp_elt_opcode (UNOP_MEMVAL);
-  switch (msymbol->type)
+  switch (type)
     {
     case mst_text:
     case mst_file_text:
diff -urNp gdb-orig/gdb/symtab.c gdb-head/gdb/symtab.c
--- gdb-orig/gdb/symtab.c	2008-05-03 00:54:03.606941000 +0200
+++ gdb-head/gdb/symtab.c	2008-05-03 01:59:47.343167704 +0200
@@ -998,7 +998,13 @@ fixup_section (struct general_symbol_inf
   struct minimal_symbol *msym;
   msym = lookup_minimal_symbol (ginfo->name, NULL, objfile);
 
-  if (msym)
+  /* First, check whether a minimal symbol with the same name exists
+     and points to the same address.  The address check is required
+     e.g. on PowerPC64, where the minimal symbol for a function will
+     point to the function descriptor, while the debug symbol will
+     point to the actual function code.  */
+  if (msym
+      && SYMBOL_VALUE_ADDRESS (msym) == ginfo->value.address)
     {
       ginfo->bfd_section = SYMBOL_BFD_SECTION (msym);
       ginfo->section = SYMBOL_SECTION (msym);
@@ -2530,6 +2536,26 @@ find_pc_line_pc_range (CORE_ADDR pc, COR
   return sal.symtab != 0;
 }
 
+/* Given a function start address PC and SECTION, find the first
+   address after the function prologue.  */
+CORE_ADDR
+find_function_start_pc (struct gdbarch *gdbarch,
+			CORE_ADDR pc, asection *section)
+{
+  /* If the function is in an unmapped overlay, use its unmapped LMA address,
+     so that gdbarch_skip_prologue has something unique to work on.  */
+  if (section_is_overlay (section) && !section_is_mapped (section))
+    pc = overlay_unmapped_address (pc, section);
+
+  pc += gdbarch_deprecated_function_start_offset (gdbarch);
+  pc = gdbarch_skip_prologue (gdbarch, pc);
+
+  /* For overlays, map pc back into its mapped VMA range.  */
+  pc = overlay_mapped_address (pc, section);
+
+  return pc;
+}
+
 /* Given a function symbol SYM, find the symtab and line for the start
    of the function.
    If the argument FUNFIRSTLINE is nonzero, we want the first line
@@ -2538,34 +2564,27 @@ find_pc_line_pc_range (CORE_ADDR pc, COR
 struct symtab_and_line
 find_function_start_sal (struct symbol *sym, int funfirstline)
 {
+  struct block *block = SYMBOL_BLOCK_VALUE (sym);
+  struct objfile *objfile = lookup_objfile_from_block (block);
+  struct gdbarch *gdbarch = get_objfile_arch (objfile);
+
   CORE_ADDR pc;
   struct symtab_and_line sal;
 
-  pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
-  fixup_symbol_section (sym, NULL);
+  pc = BLOCK_START (block);
+  fixup_symbol_section (sym, objfile);
   if (funfirstline)
-    {				/* skip "first line" of function (which is actually its prologue) */
-      asection *section = SYMBOL_BFD_SECTION (sym);
-      /* If function is in an unmapped overlay, use its unmapped LMA
-         address, so that gdbarch_skip_prologue has something unique to work
-         on */
-      if (section_is_overlay (section) &&
-	  !section_is_mapped (section))
-	pc = overlay_unmapped_address (pc, section);
-
-      pc += gdbarch_deprecated_function_start_offset (current_gdbarch);
-      pc = gdbarch_skip_prologue (current_gdbarch, pc);
-
-      /* For overlays, map pc back into its mapped VMA range */
-      pc = overlay_mapped_address (pc, section);
+    {
+      /* Skip "first line" of function (which is actually its prologue).  */
+      pc = find_function_start_pc (gdbarch, pc, SYMBOL_BFD_SECTION (sym));
     }
   sal = find_pc_sect_line (pc, SYMBOL_BFD_SECTION (sym), 0);
 
   /* Check if gdbarch_skip_prologue left us in mid-line, and the next
      line is still part of the same function.  */
   if (sal.pc != pc
-      && BLOCK_START (SYMBOL_BLOCK_VALUE (sym)) <= sal.end
-      && sal.end < BLOCK_END (SYMBOL_BLOCK_VALUE (sym)))
+      && BLOCK_START (block) <= sal.end
+      && sal.end < BLOCK_END (block))
     {
       /* First pc of next line */
       pc = sal.end;
diff -urNp gdb-orig/gdb/symtab.h gdb-head/gdb/symtab.h
--- gdb-orig/gdb/symtab.h	2008-05-03 00:53:58.363900000 +0200
+++ gdb-head/gdb/symtab.h	2008-05-03 01:59:47.385161655 +0200
@@ -1168,6 +1168,8 @@ extern unsigned int msymbol_hash_iw (con
 
 extern unsigned int msymbol_hash (const char *);
 
+extern struct objfile * msymbol_objfile (struct minimal_symbol *sym);
+
 extern void
 add_minsym_to_hash_table (struct minimal_symbol *sym,
 			  struct minimal_symbol **table);
@@ -1342,6 +1344,9 @@ extern struct partial_symtab *find_main_
 
 extern struct symtab *find_line_symtab (struct symtab *, int, int *, int *);
 
+extern CORE_ADDR find_function_start_pc (struct gdbarch *,
+					 CORE_ADDR, asection *);
+
 extern struct symtab_and_line find_function_start_sal (struct symbol *sym,
 						       int);
 
diff -urNp gdb-orig/gdb/value.c gdb-head/gdb/value.c
--- gdb-orig/gdb/value.c	2008-05-03 00:53:58.370899000 +0200
+++ gdb-head/gdb/value.c	2008-05-03 01:59:47.392160647 +0200
@@ -35,6 +35,7 @@
 #include "regcache.h"
 #include "block.h"
 #include "dfp.h"
+#include "objfiles.h"
 
 /* Prototypes for exported functions. */
 
@@ -1433,7 +1434,14 @@ value_fn_field (struct value **arg1p, st
     }
   else
     {
-      VALUE_ADDRESS (v) = SYMBOL_VALUE_ADDRESS (msym);
+      /* The minimal symbol might point to a function descriptor;
+	 resolve it to the actual code address instead.  */
+      struct objfile *objfile = msymbol_objfile (msym);
+      struct gdbarch *gdbarch = get_objfile_arch (objfile);
+
+      VALUE_ADDRESS (v)
+	= gdbarch_convert_from_func_ptr_addr
+	   (gdbarch, SYMBOL_VALUE_ADDRESS (msym), &current_target);
     }
 
   if (arg1p)
-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com


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