This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[patch 3/8] Types GC [display_uses_solib_p to exp_iterate]
- From: Jan Kratochvil <jan dot kratochvil at redhat dot com>
- To: gdb-patches at sourceware dot org
- Date: Mon, 25 May 2009 10:01:57 +0200
- Subject: [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