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]

[patch 3/8] Types GC [display_uses_solib_p to exp_iterate]


Hi,

display_uses_solib_p was already provided and similiar functionality was needed
for the types mark-and-sweep GC to find objfile references in the expressions.

display_uses_solib_p also contained a bug as it ignores objfiles references in
UNOP_MEMVAL_TLS.

exp_iterate in this patch already supports the `struct type' callback which is
not used here.  It gets used in the patch 6/8 (just made the split easier).

solib_contains_address_p gets replaced by block_objfile which has a different
principle of its operation; still both functions should return the same
results.

obsoletes:
	Re: [patch] Make a function for block->objfile lookups
	http://sourceware.org/ml/gdb-patches/2009-04/msg00609.html


Thanks,
Jan

gdb/
2009-05-25  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* block.c (block_objfile): New function.
	* block.h (block_objfile): New prototype.
	* parse.c: Include ada-lang.h.
	(exp_iterate, exp_uses_objfile_iter, exp_uses_objfile): New functions.
	* parser-defs.h (exp_uses_objfile): New declaration.
	* printcmd.c: Remove including solib.h.
	(display_uses_solib_p): Remove the function.
	(clear_dangling_display_expressions): Change the parameter `solib' to
	`objfile'.  Remove variable `objfile'.  Call block_objfile and
	exp_uses_objfile instead of display_uses_solib_p.
	(_initialize_printcmd): Register clear_dangling_display_expressions now
	using observer objfile_unloading.
---
 gdb/block.c       |   18 ++++++++
 gdb/block.h       |    2 +
 gdb/parse.c       |  113 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 gdb/parser-defs.h |    2 +
 gdb/printcmd.c    |   67 +++++---------------------------
 5 files changed, 145 insertions(+), 57 deletions(-)

diff --git a/gdb/block.c b/gdb/block.c
index 8f0140c..2290663 100644
--- a/gdb/block.c
+++ b/gdb/block.c
@@ -309,3 +309,21 @@ allocate_block (struct obstack *obstack)
 
   return bl;
 }
+
+/* Return OBJFILE in which BLOCK is located or NULL if we cannot find it for
+   whatever reason.  */
+
+struct objfile *
+block_objfile (const struct block *block)
+{
+  struct symbol *func;
+
+  if (block == NULL)
+    return NULL;
+
+  func = block_linkage_function (block);
+  if (func == NULL)
+    return NULL;
+
+  return SYMBOL_SYMTAB (func)->objfile;
+}
diff --git a/gdb/block.h b/gdb/block.h
index 9b43144..ec0aa16 100644
--- a/gdb/block.h
+++ b/gdb/block.h
@@ -164,4 +164,6 @@ extern const struct block *block_global_block (const struct block *block);
 
 extern struct block *allocate_block (struct obstack *obstack);
 
+extern struct objfile *block_objfile (const struct block *block);
+
 #endif /* BLOCK_H */
diff --git a/gdb/parse.c b/gdb/parse.c
index 96dc1c5..0157122 100644
--- a/gdb/parse.c
+++ b/gdb/parse.c
@@ -54,6 +54,7 @@
 #include "objfiles.h"
 #include "exceptions.h"
 #include "user-regs.h"
+#include "ada-lang.h"
 
 /* Standard set of definitions for printing, dumping, prefixifying,
  * and evaluating expressions.  */
@@ -1359,6 +1360,118 @@ parser_fprintf (FILE *x, const char *y, ...)
   va_end (args);
 }
 
+/* Call TYPE_FUNC and OBJFILE_FUNC for any TYPE and OBJFILE found being
+   referenced by EXP.  The functions are never called with NULL TYPE or NULL
+   OBJFILE.  Functions get passed an arbitrary caller supplied DATA pointer.
+   If any of the functions returns non-zero value then (any other) non-zero
+   value is immediately returned to the caller.  Otherwise zero is returned
+   after iterating through whole EXP.  */
+
+static int
+exp_iterate (struct expression *exp,
+	     int (*type_func) (struct type *type, void *data),
+	     int (*objfile_func) (struct objfile *objfile, void *data),
+	     void *data)
+{
+  int endpos;
+  const union exp_element *const elts = exp->elts;
+
+  for (endpos = exp->nelts; endpos > 0; )
+    {
+      int i, args, oplen = 0;
+      struct type *type = NULL;
+      struct objfile *objfile = NULL;
+
+      exp->language_defn->la_exp_desc->operator_length (exp, endpos,
+							&oplen, &args);
+      gdb_assert (oplen > 0);
+
+      /* Track the callers of write_exp_elt_type for this table.  */
+
+      i = endpos - oplen;
+      switch (elts[i].opcode)
+	{
+	case UNOP_IN_RANGE:
+	case UNOP_QUAL:
+	  if (exp->language_defn->la_language == language_ada)
+	    type = elts[i + 1].type;
+	  break;
+
+	case BINOP_VAL:
+	case OP_COMPLEX:
+	case OP_DECFLOAT:
+	case OP_DOUBLE:
+	case OP_LONG:
+	case OP_SCOPE:
+	case OP_TYPE:
+	case UNOP_CAST:
+	case UNOP_MAX:
+	case UNOP_MEMVAL:
+	case UNOP_MIN:
+	  gdb_assert (elts[i].opcode < OP_EXTENDED0);
+	  type = elts[i + 1].type;
+	  break;
+
+	case UNOP_MEMVAL_TLS:
+	  gdb_assert (elts[i].opcode < OP_EXTENDED0);
+	  objfile = elts[i + 1].objfile;
+	  type = elts[i + 2].type;
+	  break;
+
+	case OP_VAR_VALUE:
+	  {
+	    const struct block *const block = elts[i + 1].block;
+	    const struct symbol *const symbol = elts[i + 2].symbol;
+	    const struct obj_section *const section =
+	      SYMBOL_OBJ_SECTION (symbol);
+
+	    /* Check objfile where the variable itself is placed.  */
+	    if (section && objfile_func
+		&& (*objfile_func) (section->objfile, data))
+	      return 1;
+
+	    /* Check objfile where is placed the code touching the variable.  */
+	    objfile = block_objfile (block);
+
+	    type = SYMBOL_TYPE (symbol);
+	  }
+	  break;
+	}
+      endpos -= oplen;
+
+      /* Invoke callbacks for TYPE and OBJFILE if they were set as non-NULL.  */
+
+      if (type && type_func && (*type_func) (type, data))
+	return 1;
+      if (type && TYPE_OBJFILE (type) && objfile_func
+          && (*objfile_func) (TYPE_OBJFILE (type), data))
+	return 1;
+      if (objfile && objfile_func && (*objfile_func) (objfile, data))
+	return 1;
+    }
+
+  return 0;
+}
+
+/* Helper for exp_uses_objfile.  */
+
+static int
+exp_uses_objfile_iter (struct objfile *exp_objfile, void *objfile_voidp)
+{
+  struct objfile *objfile = objfile_voidp;
+
+  return exp_objfile == objfile;
+}
+
+/* Return 1 if EXP uses OBJFILE (and will become dangling when OBJFILE
+   is unloaded), otherwise return 0.  */
+
+int
+exp_uses_objfile (struct expression *exp, struct objfile *objfile)
+{
+  return exp_iterate (exp, NULL, exp_uses_objfile_iter, objfile);
+}
+
 void
 _initialize_parse (void)
 {
diff --git a/gdb/parser-defs.h b/gdb/parser-defs.h
index cbda9c3..3159a21 100644
--- a/gdb/parser-defs.h
+++ b/gdb/parser-defs.h
@@ -299,4 +299,6 @@ extern void print_subexp_standard (struct expression *, int *,
 
 extern void parser_fprintf (FILE *, const char *, ...) ATTR_FORMAT (printf, 2 ,3);
 
+extern int exp_uses_objfile (struct expression *exp, struct objfile *objfile);
+
 #endif /* PARSER_DEFS_H */
diff --git a/gdb/printcmd.c b/gdb/printcmd.c
index 8403d5f..38b988c 100644
--- a/gdb/printcmd.c
+++ b/gdb/printcmd.c
@@ -46,7 +46,6 @@
 #include "exceptions.h"
 #include "observer.h"
 #include "solist.h"
-#include "solib.h"
 #include "parser-defs.h"
 #include "charset.h"
 
@@ -1760,50 +1759,6 @@ disable_display_command (char *args, int from_tty)
       }
 }
 
-/* Return 1 if D uses SOLIB (and will become dangling when SOLIB
-   is unloaded), otherwise return 0.  */
-
-static int
-display_uses_solib_p (const struct display *d,
-		      const struct so_list *solib)
-{
-  int endpos;
-  struct expression *const exp = d->exp;
-  const union exp_element *const elts = exp->elts;
-
-  if (d->block != NULL
-      && solib_contains_address_p (solib, d->block->startaddr))
-    return 1;
-
-  for (endpos = exp->nelts; endpos > 0; )
-    {
-      int i, args, oplen = 0;
-
-      exp->language_defn->la_exp_desc->operator_length (exp, endpos,
-							&oplen, &args);
-      gdb_assert (oplen > 0);
-
-      i = endpos - oplen;
-      if (elts[i].opcode == OP_VAR_VALUE)
-	{
-	  const struct block *const block = elts[i + 1].block;
-	  const struct symbol *const symbol = elts[i + 2].symbol;
-	  const struct obj_section *const section =
-	    SYMBOL_OBJ_SECTION (symbol);
-
-	  if (block != NULL
-	      && solib_contains_address_p (solib, block->startaddr))
-	    return 1;
-
-	  if (section && section->objfile == solib->objfile)
-	    return 1;
-	}
-      endpos -= oplen;
-    }
-
-  return 0;
-}
-
 /* display_chain items point to blocks and expressions.  Some expressions in
    turn may point to symbols.
    Both symbols and blocks are obstack_alloc'd on objfile_stack, and are
@@ -1813,20 +1768,18 @@ display_uses_solib_p (const struct display *d,
    an item by re-parsing .exp_string field in the new execution context.  */
 
 static void
-clear_dangling_display_expressions (struct so_list *solib)
+clear_dangling_display_expressions (struct objfile *objfile)
 {
   struct display *d;
-  struct objfile *objfile = NULL;
 
-  for (d = display_chain; d; d = d->next)
-    {
-      if (d->exp && display_uses_solib_p (d, solib))
-	{
-	  xfree (d->exp);
-	  d->exp = NULL;
-	  d->block = NULL;
-	}
-    }
+  for (d = display_chain; d != NULL; d = d->next)
+    if (block_objfile (d->block) == objfile
+	|| (d->exp && exp_uses_objfile (d->exp, objfile)))
+      {
+	xfree (d->exp);
+	d->exp = NULL;
+	d->block = NULL;
+      }
 }
 
 
@@ -2544,7 +2497,7 @@ _initialize_printcmd (void)
 
   current_display_number = -1;
 
-  observer_attach_solib_unloaded (clear_dangling_display_expressions);
+  observer_attach_objfile_unloading (clear_dangling_display_expressions);
 
   add_info ("address", address_info,
 	    _("Describe where symbol SYM is stored."));
-- 
1.6.2.2


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