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]

[trunk + 7.4] sort minsyms by priority


I'm checking this in on the trunk and the 7.4 branch.

Previously, linespec was trying to filter out minsyms as they were
seen.  However, this isn't faithful to gdb's historical approach, which
is to priority-order minsyms; see lookup_minimal_symbol.

This patch changes linespec to collect all the minsyms, sort them into
priority order, and then use all the resulting minsyms with the highest
found priority.  That is, if we see both mst_text and mst_solib_trampoline
symbols in a given program space, only the former will be used.

Built and regtested on x86-64 F15 and the compile farm PPC.

This helps a little with PPC regressions, but we need a bit more, to
follow.

Tom

2011-12-16  Tom Tromey  <tromey@redhat.com>

	* linespec.c (struct collect_info) <objfile>: Remove field.
	(decode_objc): Update.
	(find_method): Update.
	(decode_variable): Update.
	(struct minsym_and_objfile): New.
	(struct collect_minsyms): New.
	(classify_mtype): New function.
	(compare_msyms): Likewise.
	(add_minsym): Likewise.
	(check_minsym): Remove.
	(search_minsyms_for_name): Sort minsyms and apply only those with
	top priority.

>From 0b3b2c603c6523a4de03e3e8f63c5fa5562bf01e Mon Sep 17 00:00:00 2001
From: Tom Tromey <tromey@redhat.com>
Date: Fri, 16 Dec 2011 08:43:24 -0800
Subject: [PATCH 1/4] first minsym fix; but still fails sometimes on ppc

---
 gdb/ChangeLog  |   15 ++++++
 gdb/linespec.c |  142 +++++++++++++++++++++++++++++++++++++++++++++-----------
 2 files changed, 130 insertions(+), 27 deletions(-)

diff --git a/gdb/linespec.c b/gdb/linespec.c
index cdfb59c..3d9c0c7 100644
--- a/gdb/linespec.c
+++ b/gdb/linespec.c
@@ -121,9 +121,6 @@ struct collect_info
 
   /* The result being accumulated.  */
   struct symtabs_and_lines result;
-
-  /* The current objfile; used only by the minimal symbol code.  */
-  struct objfile *objfile;
 };
 
 /* Prototypes for local functions.  */
@@ -1462,7 +1459,6 @@ decode_objc (struct linespec_state *self, char **argptr)
   info.state = self;
   info.result.sals = NULL;
   info.result.nelts = 0;
-  info.objfile = NULL;
 
   new_argptr = find_imps (*argptr, &symbol_names); 
   if (VEC_empty (const_char_ptr, symbol_names))
@@ -1966,7 +1962,6 @@ find_method (struct linespec_state *self, char *saved_arg,
   info.state = self;
   info.result.sals = NULL;
   info.result.nelts = 0;
-  info.objfile = NULL;
 
   /* Iterate over all the types, looking for the names of existing
      methods matching COPY.  If we cannot find a direct method in a
@@ -2711,30 +2706,81 @@ minsym_found (struct linespec_state *self, struct objfile *objfile,
   add_sal_to_sals (self, result, &sal, SYMBOL_NATURAL_NAME (msymbol));
 }
 
-/* Callback for iterate_over_minimal_symbols that may add the symbol
-   to the result.  */
+/* A helper struct which just holds a minimal symbol and the object
+   file from which it came.  */
 
-static void
-check_minsym (struct minimal_symbol *minsym, void *d)
+typedef struct minsym_and_objfile
 {
-  struct collect_info *info = d;
+  struct minimal_symbol *minsym;
+  struct objfile *objfile;
+} minsym_and_objfile_d;
 
-  if (MSYMBOL_TYPE (minsym) == mst_unknown
-      || MSYMBOL_TYPE (minsym) == mst_slot_got_plt
-      || MSYMBOL_TYPE (minsym) == mst_solib_trampoline)
-    {
-      /* Reject some odd ones.  */
-    }
-  else if (info->state->funfirstline
-	   && MSYMBOL_TYPE (minsym) != mst_text
-	   && MSYMBOL_TYPE (minsym) != mst_text_gnu_ifunc
-	   && MSYMBOL_TYPE (minsym) != mst_file_text)
+DEF_VEC_O (minsym_and_objfile_d);
+
+/* A helper struct to pass some data through
+   iterate_over_minimal_symbols.  */
+
+struct collect_minsyms
+{
+  /* The objfile we're examining.  */
+  struct objfile *objfile;
+
+  /* The funfirstline setting from the initial call.  */
+  int funfirstline;
+
+  /* The resulting symbols.  */
+  VEC (minsym_and_objfile_d) *msyms;
+};
+
+/* A helper function to classify a minimal_symbol_type according to
+   priority.  */
+
+static int
+classify_mtype (enum minimal_symbol_type t)
+{
+  switch (t)
     {
-      /* When FUNFIRSTLINE, only allow text symbols.  */
+    case mst_file_text:
+    case mst_file_data:
+    case mst_file_bss:
+      /* Intermediate priority.  */
+      return 1;
+
+    case mst_solib_trampoline:
+      /* Lowest priority.  */
+      return 2;
+
+    default:
+      /* Highest priority.  */
+      return 0;
     }
-  else if (maybe_add_address (info->state->addr_set, info->objfile->pspace,
-			      SYMBOL_VALUE_ADDRESS (minsym)))
-    minsym_found (info->state, info->objfile, minsym, &info->result);
+}
+
+/* Callback for qsort that sorts symbols by priority.  */
+
+static int
+compare_msyms (const void *a, const void *b)
+{
+  const minsym_and_objfile_d *moa = a;
+  const minsym_and_objfile_d *mob = b;
+  enum minimal_symbol_type ta = MSYMBOL_TYPE (moa->minsym);
+  enum minimal_symbol_type tb = MSYMBOL_TYPE (mob->minsym);
+
+  return classify_mtype (ta) - classify_mtype (tb);
+}
+
+/* Callback for iterate_over_minimal_symbols that adds the symbol to
+   the result.  */
+
+static void
+add_minsym (struct minimal_symbol *minsym, void *d)
+{
+  struct collect_minsyms *info = d;
+  minsym_and_objfile_d mo;
+
+  mo.minsym = minsym;
+  mo.objfile = info->objfile;
+  VEC_safe_push (minsym_and_objfile_d, info->msyms, &mo);
 }
 
 /* Search minimal symbols in all objfiles for NAME.  If SEARCH_PSPACE
@@ -2750,6 +2796,9 @@ search_minsyms_for_name (struct collect_info *info, const char *name,
 
   ALL_PSPACES (pspace)
   {
+    struct collect_minsyms local;
+    struct cleanup *cleanup;
+
     if (search_pspace != NULL && search_pspace != pspace)
       continue;
     if (pspace->executing_startup)
@@ -2757,11 +2806,51 @@ search_minsyms_for_name (struct collect_info *info, const char *name,
 
     set_current_program_space (pspace);
 
+    memset (&local, 0, sizeof (local));
+    local.funfirstline = info->state->funfirstline;
+
+    cleanup = make_cleanup (VEC_cleanup (minsym_and_objfile_d),
+			    &local.msyms);
+
     ALL_OBJFILES (objfile)
     {
-      info->objfile = objfile;
-      iterate_over_minimal_symbols (objfile, name, check_minsym, info);
+      local.objfile = objfile;
+      iterate_over_minimal_symbols (objfile, name, add_minsym, &local);
     }
+
+    if (!VEC_empty (minsym_and_objfile_d, local.msyms))
+      {
+	int classification;
+	int ix;
+	minsym_and_objfile_d *item;
+
+	qsort (VEC_address (minsym_and_objfile_d, local.msyms),
+	       VEC_length (minsym_and_objfile_d, local.msyms),
+	       sizeof (minsym_and_objfile_d),
+	       compare_msyms);
+
+	/* Now the minsyms are in classification order.  So, we walk
+	   over them and process just the minsyms with the same
+	   classification as the very first minsym in the list.  */
+	item = VEC_index (minsym_and_objfile_d, local.msyms, 0);
+	classification = classify_mtype (MSYMBOL_TYPE (item->minsym));
+
+	for (ix = 0;
+	     VEC_iterate (minsym_and_objfile_d, local.msyms, ix, item);
+	     ++ix)
+	  {
+	    if (classify_mtype (MSYMBOL_TYPE (item->minsym)) != classification)
+	      break;
+
+	    if (maybe_add_address (info->state->addr_set, 
+				   item->objfile->pspace,
+				   SYMBOL_VALUE_ADDRESS (item->minsym)))
+	      minsym_found (info->state, item->objfile, item->minsym,
+			    &info->result);
+	  }
+      }
+
+    do_cleanups (cleanup);
   }
 }
 
@@ -2815,7 +2904,6 @@ decode_variable (struct linespec_state *self, char *copy)
   info.state = self;
   info.result.sals = NULL;
   info.result.nelts = 0;
-  info.objfile = NULL;
 
   cleanup = demangle_for_lookup (copy, current_language->la_language,
 				 &lookup_name);
-- 
1.7.6.4


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