diff options
-rw-r--r-- | gdb/ChangeLog | 26 | ||||
-rw-r--r-- | gdb/findvar.c | 42 | ||||
-rw-r--r-- | gdb/gdbarch.c | 25 | ||||
-rw-r--r-- | gdb/gdbarch.h | 24 | ||||
-rwxr-xr-x | gdb/gdbarch.sh | 22 | ||||
-rw-r--r-- | gdb/objfiles.c | 25 | ||||
-rw-r--r-- | gdb/objfiles.h | 5 | ||||
-rw-r--r-- | gdb/symtab.c | 118 |
8 files changed, 253 insertions, 34 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 743e974..a6448a7 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,31 @@ 2012-06-05 Joel Brobecker <brobecker@adacore.com> + * gdbarch.sh: Add generation of + "iterate_over_objfiles_in_search_order_cb_ftype" typedef in + gdbarch.h. Add include of "objfiles.h" in gdbarch.c. + (iterate_over_objfiles_in_search_order): New gdbarch method. + * gdbarch.h, gdbarch.c: Regenerate. + * objfiles.h (default_iterate_over_objfiles_in_search_order): + Add declaration. + * objfiles.c (default_iterate_over_objfiles_in_search_order): + New function. + * symtab.c (lookup_symbol_aux_objfile): New function, extracted + out of lookup_symbol_aux_symtabs. + (lookup_symbol_aux_symtabs): Replace extracted-out code by + call to lookup_symbol_aux_objfile. + (struct global_sym_lookup_data): New type. + (lookup_symbol_global_iterator_cb): New function. + (lookup_symbol_global): Search for symbol using + gdbarch_iterate_over_objfiles_in_search_order and + lookup_symbol_global_iterator_cb. + * findvar.c (struct minsym_lookup_data): New type. + (minsym_lookup_iterator_cb): New function. + (default_read_var_value) [case LOC_UNRESOLVED]: Resolve the + symbol's address via gdbarch_iterate_over_objfiles_in_search_order + and minsym_lookup_iterator_cb. + +2012-06-05 Joel Brobecker <brobecker@adacore.com> + Revert the following patch: * findvar.c (default_read_var_value): For LOC_UNRESOLVED symbols, try locating the symbol in the symbol's own objfile first, before diff --git a/gdb/findvar.c b/gdb/findvar.c index 9009e6f..66bcebe 100644 --- a/gdb/findvar.c +++ b/gdb/findvar.c @@ -406,6 +406,37 @@ symbol_read_needs_frame (struct symbol *sym) return 1; } +/* Private data to be used with minsym_lookup_iterator_cb. */ + +struct minsym_lookup_data +{ + /* The name of the minimal symbol we are searching for. */ + const char *name; + + /* The field where the callback should store the minimal symbol + if found. It should be initialized to NULL before the search + is started. */ + struct minimal_symbol *result; +}; + +/* A callback function for gdbarch_iterate_over_objfiles_in_search_order. + It searches by name for a minimal symbol within the given OBJFILE. + The arguments are passed via CB_DATA, which in reality is a pointer + to struct minsym_lookup_data. */ + +static int +minsym_lookup_iterator_cb (struct objfile *objfile, void *cb_data) +{ + struct minsym_lookup_data *data = (struct minsym_lookup_data *) cb_data; + + gdb_assert (data->result == NULL); + + data->result = lookup_minimal_symbol (data->name, NULL, objfile); + + /* The iterator should stop iff a match was found. */ + return (data->result != NULL); +} + /* A default implementation for the "la_read_var_value" hook in the language vector which should work in most situations. */ @@ -559,10 +590,19 @@ default_read_var_value (struct symbol *var, struct frame_info *frame) case LOC_UNRESOLVED: { + struct minsym_lookup_data lookup_data; struct minimal_symbol *msym; struct obj_section *obj_section; - msym = lookup_minimal_symbol (SYMBOL_LINKAGE_NAME (var), NULL, NULL); + memset (&lookup_data, 0, sizeof (lookup_data)); + lookup_data.name = SYMBOL_LINKAGE_NAME (var); + + gdbarch_iterate_over_objfiles_in_search_order + (get_objfile_arch (SYMBOL_SYMTAB (var)->objfile), + minsym_lookup_iterator_cb, &lookup_data, + SYMBOL_SYMTAB (var)->objfile); + msym = lookup_data.result; + if (msym == NULL) error (_("No global symbol \"%s\"."), SYMBOL_LINKAGE_NAME (var)); if (overlay_debugging) diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c index 9d7b67a..4d46a5d 100644 --- a/gdb/gdbarch.c +++ b/gdb/gdbarch.c @@ -49,6 +49,7 @@ #include "gdb_obstack.h" #include "observer.h" #include "regcache.h" +#include "objfiles.h" /* Static function declarations */ @@ -284,6 +285,7 @@ struct gdbarch int has_dos_based_file_system; gdbarch_gen_return_address_ftype *gen_return_address; gdbarch_info_proc_ftype *info_proc; + gdbarch_iterate_over_objfiles_in_search_order_ftype *iterate_over_objfiles_in_search_order; }; @@ -451,6 +453,7 @@ struct gdbarch startup_gdbarch = 0, /* has_dos_based_file_system */ default_gen_return_address, /* gen_return_address */ 0, /* info_proc */ + default_iterate_over_objfiles_in_search_order, /* iterate_over_objfiles_in_search_order */ /* startup_gdbarch() */ }; @@ -541,6 +544,7 @@ gdbarch_alloc (const struct gdbarch_info *info, gdbarch->auto_charset = default_auto_charset; gdbarch->auto_wide_charset = default_auto_wide_charset; gdbarch->gen_return_address = default_gen_return_address; + gdbarch->iterate_over_objfiles_in_search_order = default_iterate_over_objfiles_in_search_order; /* gdbarch_alloc() */ return gdbarch; @@ -749,6 +753,7 @@ verify_gdbarch (struct gdbarch *gdbarch) /* Skip verify of has_dos_based_file_system, invalid_p == 0 */ /* Skip verify of gen_return_address, invalid_p == 0 */ /* Skip verify of info_proc, has predicate. */ + /* Skip verify of iterate_over_objfiles_in_search_order, invalid_p == 0 */ buf = ui_file_xstrdup (log, &length); make_cleanup (xfree, buf); if (length > 0) @@ -1067,6 +1072,9 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) "gdbarch_dump: integer_to_address = <%s>\n", host_address_to_string (gdbarch->integer_to_address)); fprintf_unfiltered (file, + "gdbarch_dump: iterate_over_objfiles_in_search_order = <%s>\n", + host_address_to_string (gdbarch->iterate_over_objfiles_in_search_order)); + fprintf_unfiltered (file, "gdbarch_dump: long_bit = %s\n", plongest (gdbarch->long_bit)); fprintf_unfiltered (file, @@ -4245,6 +4253,23 @@ set_gdbarch_info_proc (struct gdbarch *gdbarch, gdbarch->info_proc = info_proc; } +void +gdbarch_iterate_over_objfiles_in_search_order (struct gdbarch *gdbarch, iterate_over_objfiles_in_search_order_cb_ftype *cb, void *cb_data, struct objfile *current_objfile) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->iterate_over_objfiles_in_search_order != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_iterate_over_objfiles_in_search_order called\n"); + gdbarch->iterate_over_objfiles_in_search_order (gdbarch, cb, cb_data, current_objfile); +} + +void +set_gdbarch_iterate_over_objfiles_in_search_order (struct gdbarch *gdbarch, + gdbarch_iterate_over_objfiles_in_search_order_ftype iterate_over_objfiles_in_search_order) +{ + gdbarch->iterate_over_objfiles_in_search_order = iterate_over_objfiles_in_search_order; +} + /* Keep a registry of per-architecture data-pointers required by GDB modules. */ diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h index e4e7abf..a82e8bb 100644 --- a/gdb/gdbarch.h +++ b/gdb/gdbarch.h @@ -69,6 +69,12 @@ struct stap_parse_info; GDB, this global should be made target-specific. */ extern struct gdbarch *target_gdbarch; +/* Callback type for the 'iterate_over_objfiles_in_search_order' + gdbarch method. */ + +typedef int (iterate_over_objfiles_in_search_order_cb_ftype) + (struct objfile *objfile, void *cb_data); + /* The following are pre-initialized by GDBARCH. */ @@ -1175,6 +1181,24 @@ typedef void (gdbarch_info_proc_ftype) (struct gdbarch *gdbarch, char *args, enu extern void gdbarch_info_proc (struct gdbarch *gdbarch, char *args, enum info_proc_what what); extern void set_gdbarch_info_proc (struct gdbarch *gdbarch, gdbarch_info_proc_ftype *info_proc); +/* Iterate over all objfiles in the order that makes the most sense + for the architecture to make global symbol searches. + + CB is a callback function where OBJFILE is the objfile to be searched, + and CB_DATA a pointer to user-defined data (the same data that is passed + when calling this gdbarch method). The iteration stops if this function + returns nonzero. + + CB_DATA is a pointer to some user-defined data to be passed to + the callback. + + If not NULL, CURRENT_OBJFILE corresponds to the objfile being + inspected when the symbol search was requested. */ + +typedef void (gdbarch_iterate_over_objfiles_in_search_order_ftype) (struct gdbarch *gdbarch, iterate_over_objfiles_in_search_order_cb_ftype *cb, void *cb_data, struct objfile *current_objfile); +extern void gdbarch_iterate_over_objfiles_in_search_order (struct gdbarch *gdbarch, iterate_over_objfiles_in_search_order_cb_ftype *cb, void *cb_data, struct objfile *current_objfile); +extern void set_gdbarch_iterate_over_objfiles_in_search_order (struct gdbarch *gdbarch, gdbarch_iterate_over_objfiles_in_search_order_ftype *iterate_over_objfiles_in_search_order); + /* Definition for an unknown syscall, used basically in error-cases. */ #define UNKNOWN_SYSCALL (-1) diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh index 0f58def..2324138 100755 --- a/gdb/gdbarch.sh +++ b/gdb/gdbarch.sh @@ -936,6 +936,21 @@ m:void:gen_return_address:struct agent_expr *ax, struct axs_value *value, CORE_A # Implement the "info proc" command. M:void:info_proc:char *args, enum info_proc_what what:args, what +# Iterate over all objfiles in the order that makes the most sense +# for the architecture to make global symbol searches. +# +# CB is a callback function where OBJFILE is the objfile to be searched, +# and CB_DATA a pointer to user-defined data (the same data that is passed +# when calling this gdbarch method). The iteration stops if this function +# returns nonzero. +# +# CB_DATA is a pointer to some user-defined data to be passed to +# the callback. +# +# If not NULL, CURRENT_OBJFILE corresponds to the objfile being +# inspected when the symbol search was requested. +m:void:iterate_over_objfiles_in_search_order:iterate_over_objfiles_in_search_order_cb_ftype *cb, void *cb_data, struct objfile *current_objfile:cb, cb_data, current_objfile:0:default_iterate_over_objfiles_in_search_order::0 + EOF } @@ -1064,6 +1079,12 @@ struct stap_parse_info; Eventually, when support for multiple targets is implemented in GDB, this global should be made target-specific. */ extern struct gdbarch *target_gdbarch; + +/* Callback type for the 'iterate_over_objfiles_in_search_order' + gdbarch method. */ + +typedef int (iterate_over_objfiles_in_search_order_cb_ftype) + (struct objfile *objfile, void *cb_data); EOF # function typedef's @@ -1382,6 +1403,7 @@ cat <<EOF #include "gdb_obstack.h" #include "observer.h" #include "regcache.h" +#include "objfiles.h" /* Static function declarations */ diff --git a/gdb/objfiles.c b/gdb/objfiles.c index 8d9f8a5..f5e5c75 100644 --- a/gdb/objfiles.c +++ b/gdb/objfiles.c @@ -1525,6 +1525,31 @@ gdb_bfd_unref (struct bfd *abfd) xfree (name); } +/* The default implementation for the "iterate_over_objfiles_in_search_order" + gdbarch method. It is equivalent to use the ALL_OBJFILES macro, + searching the objfiles in the order they are stored internally, + ignoring CURRENT_OBJFILE. + + On most platorms, it should be close enough to doing the best + we can without some knowledge specific to the architecture. */ + +void +default_iterate_over_objfiles_in_search_order + (struct gdbarch *gdbarch, + iterate_over_objfiles_in_search_order_cb_ftype *cb, + void *cb_data, struct objfile *current_objfile) +{ + int stop = 0; + struct objfile *objfile; + + ALL_OBJFILES (objfile) + { + stop = cb (objfile, cb_data); + if (stop) + return; + } +} + /* Provide a prototype to silence -Wmissing-prototypes. */ extern initialize_file_ftype _initialize_objfiles; diff --git a/gdb/objfiles.h b/gdb/objfiles.h index 98cc39e..01c3aea 100644 --- a/gdb/objfiles.h +++ b/gdb/objfiles.h @@ -525,6 +525,11 @@ extern void *objfile_data (struct objfile *objfile, extern struct bfd *gdb_bfd_ref (struct bfd *abfd); extern void gdb_bfd_unref (struct bfd *abfd); extern int gdb_bfd_close_or_warn (struct bfd *abfd); + +extern void default_iterate_over_objfiles_in_search_order + (struct gdbarch *gdbarch, + iterate_over_objfiles_in_search_order_cb_ftype *cb, + void *cb_data, struct objfile *current_objfile); /* Traverse all object files in the current program space. diff --git a/gdb/symtab.c b/gdb/symtab.c index 7e6483f..6133b5c 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -1498,40 +1498,55 @@ lookup_global_symbol_from_objfile (const struct objfile *main_objfile, return NULL; } -/* Check to see if the symbol is defined in one of the symtabs. - BLOCK_INDEX should be either GLOBAL_BLOCK or STATIC_BLOCK, +/* Check to see if the symbol is defined in one of the OBJFILE's + symtabs. BLOCK_INDEX should be either GLOBAL_BLOCK or STATIC_BLOCK, depending on whether or not we want to search global symbols or static symbols. */ static struct symbol * +lookup_symbol_aux_objfile (struct objfile *objfile, int block_index, + const char *name, const domain_enum domain) +{ + struct symbol *sym = NULL; + struct blockvector *bv; + const struct block *block; + struct symtab *s; + + if (objfile->sf) + objfile->sf->qf->pre_expand_symtabs_matching (objfile, block_index, + name, domain); + + ALL_OBJFILE_SYMTABS (objfile, s) + if (s->primary) + { + bv = BLOCKVECTOR (s); + block = BLOCKVECTOR_BLOCK (bv, block_index); + sym = lookup_block_symbol (block, name, domain); + if (sym) + { + block_found = block; + return fixup_symbol_section (sym, objfile); + } + } + + return NULL; +} + +/* Same as lookup_symbol_aux_objfile, except that it searches all + objfiles. Return the first match found. */ + +static struct symbol * lookup_symbol_aux_symtabs (int block_index, const char *name, const domain_enum domain) { struct symbol *sym; struct objfile *objfile; - struct blockvector *bv; - const struct block *block; - struct symtab *s; ALL_OBJFILES (objfile) { - if (objfile->sf) - objfile->sf->qf->pre_expand_symtabs_matching (objfile, - block_index, - name, domain); - - ALL_OBJFILE_SYMTABS (objfile, s) - if (s->primary) - { - bv = BLOCKVECTOR (s); - block = BLOCKVECTOR_BLOCK (bv, block_index); - sym = lookup_block_symbol (block, name, domain); - if (sym) - { - block_found = block; - return fixup_symbol_section (sym, objfile); - } - } + sym = lookup_symbol_aux_objfile (objfile, block_index, name, domain); + if (sym) + return sym; } return NULL; @@ -1648,6 +1663,46 @@ lookup_symbol_static (const char *name, return NULL; } +/* Private data to be used with lookup_symbol_global_iterator_cb. */ + +struct global_sym_lookup_data +{ + /* The name of the symbol we are searching for. */ + const char *name; + + /* The domain to use for our search. */ + domain_enum domain; + + /* The field where the callback should store the symbol if found. + It should be initialized to NULL before the search is started. */ + struct symbol *result; +}; + +/* A callback function for gdbarch_iterate_over_objfiles_in_search_order. + It searches by name for a symbol in the GLOBAL_BLOCK of the given + OBJFILE. The arguments for the search are passed via CB_DATA, + which in reality is a pointer to struct global_sym_lookup_data. */ + +static int +lookup_symbol_global_iterator_cb (struct objfile *objfile, + void *cb_data) +{ + struct global_sym_lookup_data *data = + (struct global_sym_lookup_data *) cb_data; + + gdb_assert (data->result == NULL); + + data->result = lookup_symbol_aux_objfile (objfile, GLOBAL_BLOCK, + data->name, data->domain); + if (data->result == NULL) + data->result = lookup_symbol_aux_quick (objfile, GLOBAL_BLOCK, + data->name, data->domain); + + /* If we found a match, tell the iterator to stop. Otherwise, + keep going. */ + return (data->result != NULL); +} + /* Lookup a symbol in all files' global blocks (searching psymtabs if necessary). */ @@ -1658,6 +1713,7 @@ lookup_symbol_global (const char *name, { struct symbol *sym = NULL; struct objfile *objfile = NULL; + struct global_sym_lookup_data lookup_data; /* Call library-specific lookup procedure. */ objfile = lookup_objfile_from_block (block); @@ -1666,18 +1722,14 @@ lookup_symbol_global (const char *name, if (sym != NULL) return sym; - sym = lookup_symbol_aux_symtabs (GLOBAL_BLOCK, name, domain); - if (sym != NULL) - return sym; - - ALL_OBJFILES (objfile) - { - sym = lookup_symbol_aux_quick (objfile, GLOBAL_BLOCK, name, domain); - if (sym) - return sym; - } + memset (&lookup_data, 0, sizeof (lookup_data)); + lookup_data.name = name; + lookup_data.domain = domain; + gdbarch_iterate_over_objfiles_in_search_order + (objfile != NULL ? get_objfile_arch (objfile) : target_gdbarch, + lookup_symbol_global_iterator_cb, &lookup_data, objfile); - return NULL; + return lookup_data.result; } int |