From 2c1994ee331282d510f0f843a2ad67a428ce02e8 Mon Sep 17 00:00:00 2001 From: Pedro Alves Date: Fri, 1 Apr 2016 16:06:18 +0100 Subject: [PATCH] Incremental breakpoint_re_set for linespec When you have a pending breakpoint, the next bottleneck is breakpoint_re_set again. $ time $g --batch -q -ex "run" -ex "c" -iex "set breakpoint pending on" -iex "b mainasdfasdf" --args ./testsuite/outputs/gdb.base/jit/jit-main ./testsuite/outputs/gdb.base/jit/jit-solib.so 8000 No symbol table is loaded. Use the "file" command. Breakpoint 1 (mainasdfasdf) pending. /home/pedro/gdb/mygit/src/gdb/testsuite/gdb.base/jit-main.c:164: libname = ./testsuite/outputs/gdb.base/jit/jit-solib.so, count = 8000 [Inferior 1 (process 25753) exited normally] The program is not being run. real 0m31.738s user 0m29.221s sys 0m2.827s This implement per-objfile re-set for linespece-based breakpoints. - Hoist out plt locations when we find other breakpoint locations It's what the linespec code does if we let it look up in the whole program space. - Check that the sals the linespec code returns match the search scope - Address locations always use a program_space-wide search scope - Fix exception.exp - we may only find the probe interface after seeing __cxa_begin_catch on other objfiles - validate_sals --- gdb/ada-lang.c | 4 +- gdb/break-catch-throw.c | 9 +- gdb/breakpoint.c | 163 +++++++++++++++++++++----- gdb/breakpoint.h | 4 +- gdb/elfread.c | 4 +- gdb/linespec.c | 252 +++++++++++++++++++++++++++------------- gdb/linespec.h | 4 +- gdb/symtab.h | 8 ++ 8 files changed, 329 insertions(+), 119 deletions(-) diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c index 9eda7a84828..a13625fa5da 100644 --- a/gdb/ada-lang.c +++ b/gdb/ada-lang.c @@ -12368,7 +12368,9 @@ create_excep_cond_exprs (struct ada_catchpoint *c, /* Iterate over all the catchpoint's locations, and parse an expression for each. */ - for (bl = c->base.loc; bl != NULL; bl = bl->next) + for (bl = c->base.loc; + bl != NULL && bp_location_matches_search_scope (bl, search_scope); + bl = bl->next) { struct ada_catchpoint_location *ada_loc = (struct ada_catchpoint_location *) bl; diff --git a/gdb/break-catch-throw.c b/gdb/break-catch-throw.c index 5ffad947899..efaad3acbd5 100644 --- a/gdb/break-catch-throw.c +++ b/gdb/break-catch-throw.c @@ -212,8 +212,13 @@ re_set_exception_catchpoint (struct breakpoint *self, struct cleanup *cleanup; enum exception_event_kind kind = classify_exception_breakpoint (self); struct event_location *location; + struct sym_search_scope pspace_scope = null_search_scope (); struct program_space *filter_pspace = search_scope->pspace; + /* Re-set in the whole pspace for now. */ + pspace_scope.pspace = search_scope->pspace; + search_scope = &pspace_scope; + /* We first try to use the probe interface. */ TRY { @@ -236,7 +241,7 @@ re_set_exception_catchpoint (struct breakpoint *self, = ASTRDUP (exception_functions[kind].function); location = new_explicit_location (&explicit_loc); cleanup = make_cleanup_delete_event_location (location); - self->ops->decode_location (self, location, filter_pspace, &sals); + self->ops->decode_location (self, location, search_scope, &sals); do_cleanups (cleanup); } CATCH (ex, RETURN_MASK_ERROR) @@ -251,7 +256,7 @@ re_set_exception_catchpoint (struct breakpoint *self, END_CATCH cleanup = make_cleanup (xfree, sals.sals); - update_breakpoint_locations (self, filter_pspace, sals, sals_end); + update_breakpoint_locations (self, search_scope, sals, sals_end); do_cleanups (cleanup); } diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 73295f0b8c7..afce9d314b0 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -126,7 +126,7 @@ static void create_breakpoints_sal_default (struct gdbarch *, static void decode_location_default (struct breakpoint *b, const struct event_location *location, - struct program_space *search_pspace, + struct sym_search_scope *search_scope, struct symtabs_and_lines *sals); static void clear_command (char *, int); @@ -13051,7 +13051,7 @@ base_breakpoint_create_breakpoints_sal (struct gdbarch *gdbarch, static void base_breakpoint_decode_location (struct breakpoint *b, const struct event_location *location, - struct program_space *filter_pspace, + struct sym_search_scope *search_scope, struct symtabs_and_lines *sals) { internal_error_pure_virtual_called (); @@ -13301,10 +13301,10 @@ bkpt_create_breakpoints_sal (struct gdbarch *gdbarch, static void bkpt_decode_location (struct breakpoint *b, const struct event_location *location, - struct program_space *search_pspace, + struct sym_search_scope *search_scope, struct symtabs_and_lines *sals) { - decode_location_default (b, location, search_pspace, sals); + decode_location_default (b, location, search_scope, sals); } /* Virtual table for internal breakpoints. */ @@ -13501,10 +13501,10 @@ bkpt_probe_create_sals_from_location (const struct event_location *location, static void bkpt_probe_decode_location (struct breakpoint *b, const struct event_location *location, - struct program_space *search_pspace, + struct sym_search_scope *search_scope, struct symtabs_and_lines *sals) { - *sals = parse_probes (location, search_pspace, NULL); + *sals = parse_probes (location, search_scope->pspace, NULL); if (!sals->sals) error (_("probe not found")); } @@ -13626,10 +13626,10 @@ tracepoint_create_breakpoints_sal (struct gdbarch *gdbarch, static void tracepoint_decode_location (struct breakpoint *b, const struct event_location *location, - struct program_space *search_pspace, + struct sym_search_scope *search_scope, struct symtabs_and_lines *sals) { - decode_location_default (b, location, search_pspace, sals); + decode_location_default (b, location, search_scope, sals); } struct breakpoint_ops tracepoint_breakpoint_ops; @@ -13650,11 +13650,11 @@ tracepoint_probe_create_sals_from_location static void tracepoint_probe_decode_location (struct breakpoint *b, const struct event_location *location, - struct program_space *search_pspace, + struct sym_search_scope *search_scope, struct symtabs_and_lines *sals) { /* We use the same method for breakpoint on probes. */ - bkpt_probe_decode_location (b, location, search_pspace, sals); + bkpt_probe_decode_location (b, location, search_scope, sals); } static struct breakpoint_ops tracepoint_probe_breakpoint_ops; @@ -13819,7 +13819,7 @@ strace_marker_create_breakpoints_sal (struct gdbarch *gdbarch, static void strace_marker_decode_location (struct breakpoint *b, const struct event_location *location, - struct program_space *search_pspace, + struct sym_search_scope *search_scope, struct symtabs_and_lines *sals) { struct tracepoint *tp = (struct tracepoint *) b; @@ -14067,13 +14067,13 @@ bp_location_matches_search_scope (struct bp_location *bl, considered. */ static int -all_locations_are_pending (struct breakpoint *b, struct program_space *pspace) +all_locations_are_pending (struct breakpoint *b, + struct sym_search_scope *search_scope) { struct bp_location *loc; for (loc = b->loc; loc != NULL; loc = loc->next) - if ((pspace == NULL - || loc->pspace == pspace) + if (bp_location_matches_search_scope (loc, search_scope) && !loc->shlib_disabled && !loc->pspace->executing_startup) return 0; @@ -14279,19 +14279,84 @@ locations_are_equal (struct bp_location *a, struct bp_location *b) return 1; } +static int +msymbol_name_is (struct minimal_symbol *msymbol, const char *function_name) +{ + int (*cmp) (const char *, const char *); + + cmp = (case_sensitivity == case_sensitive_on ? strcmp : strcasecmp); + if (cmp (MSYMBOL_LINKAGE_NAME (msymbol), function_name) == 0) + return 1; + + if (MSYMBOL_MATCHES_SEARCH_NAME (msymbol, function_name)) + return 1; + + return 0; +} + +static int +should_hoist_location (struct bp_location *bl, + struct symtabs_and_lines new_sals, + struct sym_search_scope *search_scope) +{ + if (bp_location_matches_search_scope (bl, search_scope)) + return 1; + + /* If the search scope is restricted to an objfile, we may still + want to hoist out locations of other objfiles of the search + pspace. */ + if (search_scope->objfile != NULL + && search_scope->pspace == bl->pspace) + { + /* We've now resolved the location. Remove previously pending + ones. */ + if (bl->shlib_disabled) + return 1; + + /* If we had a plt symbol set on another objfile, and we now + found the matching text symbol, we'll no longer need the plt + symbol location. */ + if (bl->sal.msymbol != NULL + && MSYMBOL_TYPE (bl->sal.msymbol) == mst_solib_trampoline + && bl->function_name != NULL) + { + int i; + + for (i = 0; i < new_sals.nelts; i++) + { + struct symbol *symbol = new_sals.sals[i].symbol; + struct minimal_symbol *msymbol = new_sals.sals[i].msymbol; + + if (symbol != NULL + && SYMBOL_CLASS (symbol) == LOC_BLOCK + && strcmp (SYMBOL_LINKAGE_NAME (symbol), bl->function_name)) + return 1; + + if (msymbol != NULL + && msymbol_name_is (msymbol, bl->function_name)) + return 1; + } + } + } + + return 0; +} + /* Split all locations of B that are bound to PSPACE out of B's location list to a separate list and return that list's head. If PSPACE is NULL, hoist out all locations of B. */ static struct bp_location * -hoist_existing_locations (struct breakpoint *b, struct program_space *pspace) +hoist_existing_locations (struct breakpoint *b, + struct symtabs_and_lines new_sals, + struct sym_search_scope *search_scope) { struct bp_location head; struct bp_location *i = b->loc; struct bp_location **i_link = &b->loc; struct bp_location *hoisted = &head; - if (pspace == NULL) + if (search_scope->pspace == NULL) { i = b->loc; b->loc = NULL; @@ -14302,7 +14367,7 @@ hoist_existing_locations (struct breakpoint *b, struct program_space *pspace) while (i != NULL) { - if (i->pspace == pspace) + if (should_hoist_location (i, new_sals, search_scope)) { *i_link = i->next; i->next = NULL; @@ -14325,7 +14390,7 @@ hoist_existing_locations (struct breakpoint *b, struct program_space *pspace) void update_breakpoint_locations (struct breakpoint *b, - struct program_space *filter_pspace, + struct sym_search_scope *search_scope, struct symtabs_and_lines sals, struct symtabs_and_lines sals_end) { @@ -14349,14 +14414,36 @@ update_breakpoint_locations (struct breakpoint *b, We'd like to retain the location, so that when the library is loaded again, we don't loose the enabled/disabled status of the individual locations. */ - if (all_locations_are_pending (b, filter_pspace) && sals.nelts == 0) + if (all_locations_are_pending (b, search_scope) && sals.nelts == 0) return; - existing_locations = hoist_existing_locations (b, filter_pspace); + existing_locations = hoist_existing_locations (b, sals, search_scope); for (i = 0; i < sals.nelts; ++i) { struct bp_location *new_loc; + struct symtab_and_line *sal = &sals.sals[i]; + struct minimal_symbol *msymbol = sal->msymbol; + + /* If we found a new location, then we no longer need the one + previously set on a plt symbol (usually in the main + executable). */ + if (msymbol != NULL + && MSYMBOL_TYPE (msymbol) == mst_solib_trampoline) + { + struct bp_location *bl; + + for (bl = b->loc; bl != NULL; bl = bl->next) + { + if (bl->pspace == sal->pspace + && bl->function_name != NULL + && msymbol_name_is (msymbol, bl->function_name)) + break; + } + + if (bl != NULL) + continue; + } switch_to_program_space_and_thread (sals.sals[i].pspace); @@ -14441,7 +14528,7 @@ update_breakpoint_locations (struct breakpoint *b, static struct symtabs_and_lines location_to_sals (struct breakpoint *b, struct event_location *location, - struct program_space *search_pspace, int *found) + struct sym_search_scope *search_scope, int *found) { struct symtabs_and_lines sals = {0}; struct gdb_exception exception = exception_none; @@ -14450,7 +14537,7 @@ location_to_sals (struct breakpoint *b, struct event_location *location, TRY { - b->ops->decode_location (b, location, search_pspace, &sals); + b->ops->decode_location (b, location, search_scope, &sals); } CATCH (e, RETURN_MASK_ERROR) { @@ -14468,8 +14555,7 @@ location_to_sals (struct breakpoint *b, struct event_location *location, if (e.error == NOT_FOUND_ERROR && (b->condition_not_parsed || (b->loc != NULL - && search_pspace != NULL - && b->loc->pspace != search_pspace) + && !bp_location_matches_search_scope (b->loc, search_scope)) || (b->loc && b->loc->shlib_disabled) || (b->loc && b->loc->pspace->executing_startup) || b->enable_state == bp_disabled)) @@ -14489,6 +14575,8 @@ location_to_sals (struct breakpoint *b, struct event_location *location, } END_CATCH + validate_sals (&sals, search_scope); + if (exception.reason == 0 || exception.error != NOT_FOUND_ERROR) { int i; @@ -14539,19 +14627,32 @@ breakpoint_re_set_default (struct breakpoint *b, struct symtabs_and_lines sals, sals_end; struct symtabs_and_lines expanded = {0}; struct symtabs_and_lines expanded_end = {0}; - struct program_space *filter_pspace = search_scope->pspace; + struct sym_search_scope pspace_search_scope; - sals = location_to_sals (b, b->location, filter_pspace, &found); + /* These require arbitrary expressions and symbol lookups. Punt on + resetting locations of specific objfiles, and let the parsers see + the whole program space. */ + if (search_scope->objfile != NULL + && event_location_type (b->location) == ADDRESS_LOCATION) + { + pspace_search_scope = null_search_scope (); + pspace_search_scope.pspace = search_scope->pspace; + search_scope = &pspace_search_scope; + } + + sals = location_to_sals (b, b->location, search_scope, &found); if (found) { make_cleanup (xfree, sals.sals); expanded = sals; } + validate_sals (&expanded, search_scope); + if (b->location_range_end != NULL) { - sals_end = location_to_sals (b, b->location_range_end, - filter_pspace, &found); + sals_end = location_to_sals (b, b->location_range_end, search_scope, + &found); if (found) { make_cleanup (xfree, sals_end.sals); @@ -14559,7 +14660,7 @@ breakpoint_re_set_default (struct breakpoint *b, } } - update_breakpoint_locations (b, filter_pspace, expanded, expanded_end); + update_breakpoint_locations (b, search_scope, expanded, expanded_end); } /* Default method for creating SALs from an address string. It basically @@ -14603,13 +14704,13 @@ create_breakpoints_sal_default (struct gdbarch *gdbarch, static void decode_location_default (struct breakpoint *b, const struct event_location *location, - struct program_space *search_pspace, + struct sym_search_scope *search_scope, struct symtabs_and_lines *sals) { struct linespec_result canonical; init_linespec_result (&canonical); - decode_line_full (location, DECODE_LINE_FUNFIRSTLINE, search_pspace, + decode_line_full (location, DECODE_LINE_FUNFIRSTLINE, search_scope, (struct symtab *) NULL, 0, &canonical, multiple_symbols_all, b->filter); diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h index 891f7631f59..9cc33fc7e8c 100644 --- a/gdb/breakpoint.h +++ b/gdb/breakpoint.h @@ -624,7 +624,7 @@ struct breakpoint_ops This function is called inside `location_to_sals'. */ void (*decode_location) (struct breakpoint *b, const struct event_location *location, - struct program_space *search_pspace, + struct sym_search_scope *search_scope, struct symtabs_and_lines *sals); /* Return true if this breakpoint explains a signal. See @@ -1219,7 +1219,7 @@ extern void init_bp_location (struct bp_location *loc, struct breakpoint *owner); extern void update_breakpoint_locations (struct breakpoint *b, - struct program_space *filter_pspace, + struct sym_search_scope *search_scope, struct symtabs_and_lines sals, struct symtabs_and_lines sals_end); diff --git a/gdb/elfread.c b/gdb/elfread.c index 84355cf032f..da0c4c9831e 100644 --- a/gdb/elfread.c +++ b/gdb/elfread.c @@ -963,6 +963,7 @@ elf_gnu_ifunc_resolver_return_stop (struct breakpoint *b) CORE_ADDR resolved_address, resolved_pc; struct symtab_and_line sal; struct symtabs_and_lines sals, sals_end; + struct sym_search_scope search_scope = null_search_scope (); gdb_assert (b->type == bp_gnu_ifunc_resolver_return); @@ -1010,7 +1011,8 @@ elf_gnu_ifunc_resolver_return_stop (struct breakpoint *b) sals_end.nelts = 0; b->type = bp_breakpoint; - update_breakpoint_locations (b, current_program_space, sals, sals_end); + search_scope.pspace = current_program_space; + update_breakpoint_locations (b, &search_scope, sals, sals_end); } /* A helper function for elf_symfile_read that reads the minimal diff --git a/gdb/linespec.c b/gdb/linespec.c index d449c295a30..0c10f046594 100644 --- a/gdb/linespec.c +++ b/gdb/linespec.c @@ -45,6 +45,12 @@ #include "stack.h" #include "location.h" +static int search_scope_matches_symbol (struct sym_search_scope *search_scope, + struct symbol *sym); +static int search_scope_matches_bound_msymbol + (struct sym_search_scope *search_scope, + struct bound_minimal_symbol *msym); + typedef struct symbol *symbolp; DEF_VEC_P (symbolp); @@ -123,9 +129,8 @@ struct linespec_state /* The program space as seen when the module was entered. */ struct program_space *program_space; - /* If not NULL, the search is restricted to just this program - space. */ - struct program_space *search_pspace; + /* Symbol search is restricted to this scope. */ + struct sym_search_scope *search_scope; /* The default symtab to use, if no other symtab is specified. */ struct symtab *default_symtab; @@ -279,7 +284,7 @@ static struct symtabs_and_lines decode_objc (struct linespec_state *self, const char *arg); static VEC (symtab_ptr) *symtabs_from_filename (const char *, - struct program_space *pspace); + struct sym_search_scope *scope); static VEC (symbolp) *find_label_symbols (struct linespec_state *self, VEC (symbolp) *function_symbols, @@ -301,15 +306,15 @@ static int symbol_to_sal (struct symtab_and_line *result, static void add_matching_symbols_to_info (const char *name, struct collect_info *info, - struct program_space *pspace); + struct sym_search_scope *scope); -static void add_all_symbol_names_from_pspace (struct collect_info *info, - struct program_space *pspace, - VEC (const_char_ptr) *names); +static void add_all_symbol_names_from_search_scope (struct collect_info *info, + struct sym_search_scope *scope, + VEC (const_char_ptr) *names); static VEC (symtab_ptr) * collect_symtabs_from_filename (const char *file, - struct program_space *pspace); + struct sym_search_scope *scope); static void decode_digits_ordinary (struct linespec_state *self, linespec_p ls, @@ -970,10 +975,10 @@ iterate_name_matcher (const char *name, void *d) } /* A helper that walks over all matching symtabs in all objfiles and - calls CALLBACK for each symbol matching NAME. If SEARCH_PSPACE is - not NULL, then the search is restricted to just that program - space. If INCLUDE_INLINE is nonzero then symbols representing - inlined instances of functions will be included in the result. */ + calls CALLBACK for each symbol matching NAME. The search is + restricted to SEARCH_SCOPE. If INCLUDE_INLINE is nonzero then + symbols representing inlined instances of functions will be + included in the result. */ static void iterate_over_all_matching_symtabs (struct linespec_state *state, @@ -981,7 +986,7 @@ iterate_over_all_matching_symtabs (struct linespec_state *state, const domain_enum domain, symbol_found_callback_ftype *callback, void *data, - struct program_space *search_pspace, + struct sym_search_scope *search_scope, int include_inline) { struct objfile *objfile; @@ -994,16 +999,14 @@ iterate_over_all_matching_symtabs (struct linespec_state *state, ? state->language->la_get_symbol_name_cmp (name) : strcmp_iw; - ALL_PSPACES (pspace) + ALL_SEARCH_PSPACES (search_scope->pspace, pspace) { - if (search_pspace != NULL && search_pspace != pspace) - continue; if (pspace->executing_startup) continue; set_current_program_space (pspace); - ALL_OBJFILES (objfile) + ALL_SEARCH_OBJFILES (pspace, search_scope->objfile, objfile) { struct compunit_symtab *cu; @@ -1849,7 +1852,7 @@ create_sals_line_offset (struct linespec_state *self, VEC_pop (symtab_ptr, ls->file_symtabs); VEC_free (symtab_ptr, ls->file_symtabs); ls->file_symtabs = collect_symtabs_from_filename (fullname, - self->search_pspace); + self->search_scope); use_default = 1; } @@ -2003,6 +2006,9 @@ convert_linespec_to_sals (struct linespec_state *state, linespec_p ls) { struct program_space *pspace = SYMTAB_PSPACE (symbol_symtab (sym)); + gdb_assert (search_scope_matches_symbol (state->search_scope, + sym)); + if (symbol_to_sal (&sal, state->funfirstline, sym) && maybe_add_address (state->addr_set, pspace, sal.pc)) add_sal_to_sals (state, &sals, &sal, @@ -2028,6 +2034,9 @@ convert_linespec_to_sals (struct linespec_state *state, linespec_p ls) for (i = 0; VEC_iterate (symbolp, ls->function_symbols, i, sym); ++i) { + gdb_assert (search_scope_matches_symbol (state->search_scope, + sym)); + pspace = SYMTAB_PSPACE (symbol_symtab (sym)); set_current_program_space (pspace); if (symbol_to_sal (&sal, state->funfirstline, sym) @@ -2049,6 +2058,9 @@ convert_linespec_to_sals (struct linespec_state *state, linespec_p ls) i, elem); ++i) { + gdb_assert (search_scope_matches_bound_msymbol + (state->search_scope, + elem)); pspace = elem->objfile->pspace; set_current_program_space (pspace); minsym_found (state, elem->objfile, elem->minsym, &sals); @@ -2102,7 +2114,7 @@ convert_explicit_location_to_sals (struct linespec_state *self, { result->file_symtabs = symtabs_from_filename (explicit_loc->source_filename, - self->search_pspace); + self->search_scope); } CATCH (except, RETURN_MASK_ERROR) { @@ -2294,7 +2306,7 @@ parse_linespec (linespec_parser *parser, const char *arg) { PARSER_RESULT (parser)->file_symtabs = symtabs_from_filename (user_filename, - PARSER_STATE (parser)->search_pspace); + PARSER_STATE (parser)->search_scope); } CATCH (ex, RETURN_MASK_ERROR) { @@ -2376,7 +2388,7 @@ parse_linespec (linespec_parser *parser, const char *arg) static void linespec_state_constructor (struct linespec_state *self, int flags, const struct language_defn *language, - struct program_space *search_pspace, + struct sym_search_scope *search_scope, struct symtab *default_symtab, int default_line, struct linespec_result *canonical) @@ -2385,7 +2397,8 @@ linespec_state_constructor (struct linespec_state *self, self->language = language; self->funfirstline = (flags & DECODE_LINE_FUNFIRSTLINE) ? 1 : 0; self->list_mode = (flags & DECODE_LINE_LIST_MODE) ? 1 : 0; - self->search_pspace = search_pspace; + self->search_scope = search_scope; + gdb_assert (search_scope != NULL); self->default_symtab = default_symtab; self->default_line = default_line; self->canonical = canonical; @@ -2400,7 +2413,7 @@ linespec_state_constructor (struct linespec_state *self, static void linespec_parser_new (linespec_parser *parser, int flags, const struct language_defn *language, - struct program_space *search_pspace, + struct sym_search_scope *search_scope, struct symtab *default_symtab, int default_line, struct linespec_result *canonical) @@ -2410,7 +2423,7 @@ linespec_parser_new (linespec_parser *parser, memset (PARSER_RESULT (parser), 0, sizeof (struct linespec)); PARSER_EXPLICIT (parser)->line_offset.sign = LINE_OFFSET_UNKNOWN; linespec_state_constructor (PARSER_STATE (parser), flags, language, - search_pspace, + search_scope, default_symtab, default_line, canonical); } @@ -2460,11 +2473,13 @@ linespec_lex_to_end (char **stringp) struct cleanup *cleanup; linespec_token token; const char *orig; + struct sym_search_scope search_scope = null_search_scope (); if (stringp == NULL || *stringp == NULL) return; - linespec_parser_new (&parser, 0, current_language, NULL, NULL, 0, NULL); + linespec_parser_new (&parser, 0, current_language, &search_scope, + NULL, 0, NULL); cleanup = make_cleanup (linespec_parser_delete, &parser); parser.lexer.saved_arg = *stringp; PARSER_STREAM (&parser) = orig = *stringp; @@ -2561,7 +2576,7 @@ event_location_to_sals (linespec_parser *parser, void decode_line_full (const struct event_location *location, int flags, - struct program_space *search_pspace, + struct sym_search_scope *search_scope, struct symtab *default_symtab, int default_line, struct linespec_result *canonical, const char *select_mode, @@ -2572,6 +2587,10 @@ decode_line_full (const struct event_location *location, int flags, VEC (const_char_ptr) *filters = NULL; linespec_parser parser; struct linespec_state *state; + struct sym_search_scope null_scope = null_search_scope (); + + if (search_scope == NULL) + search_scope = &null_scope; gdb_assert (canonical != NULL); /* The filter only makes sense for 'all'. */ @@ -2583,7 +2602,7 @@ decode_line_full (const struct event_location *location, int flags, gdb_assert ((flags & DECODE_LINE_LIST_MODE) == 0); linespec_parser_new (&parser, flags, current_language, - search_pspace, default_symtab, + search_scope, default_symtab, default_line, canonical); cleanups = make_cleanup (linespec_parser_delete, &parser); save_current_program_space (); @@ -2594,6 +2613,16 @@ decode_line_full (const struct event_location *location, int flags, gdb_assert (result.nelts == 1 || canonical->pre_expanded); canonical->pre_expanded = 1; + validate_sals (&result, search_scope); + + if (VEC_length (linespec_sals, canonical->sals) > 0) + { + struct linespec_sals *lsal; + + lsal = VEC_index (linespec_sals, canonical->sals, 0); + validate_sals (&lsal->sals, search_scope); + } + /* Arrange for allocated canonical names to be freed. */ if (result.nelts > 0) { @@ -2629,29 +2658,94 @@ decode_line_full (const struct event_location *location, int flags, else decode_line_2 (state, &result, select_mode); + validate_sals (&result, search_scope); + do_cleanups (cleanups); } +static int +search_scope_matches_objfile (struct sym_search_scope *search_scope, + struct objfile *objfile) +{ + if (search_scope->pspace == NULL) + return 1; + + if (search_scope->pspace != objfile->pspace) + return 0; + + if (search_scope->objfile != NULL) + { + struct objfile *parent = search_scope->objfile; + struct objfile *iter; + + for (iter = parent; + iter; + iter = objfile_separate_debug_iterate (parent, iter)) + if (objfile == iter) + return 1; + } + else + return 1; + + return 0; +} + +static int +search_scope_matches_symbol (struct sym_search_scope *search_scope, + struct symbol *sym) +{ + return search_scope_matches_objfile (search_scope, + SYMTAB_OBJFILE (symbol_symtab (sym))); +} + +static int +search_scope_matches_bound_msymbol (struct sym_search_scope *search_scope, + struct bound_minimal_symbol *msym) +{ + return search_scope_matches_objfile (search_scope, msym->objfile); +} + +void +validate_sals (struct symtabs_and_lines *result, + struct sym_search_scope *search_scope) +{ + int i; + + for (i = 0; i < result->nelts; i++) + { + struct symtab_and_line *sal = &result->sals[i]; + + gdb_assert (search_scope_matches_objfile (search_scope, sal->objfile)); + } +} + /* See linespec.h. */ struct symtabs_and_lines decode_line_1 (const struct event_location *location, int flags, - struct program_space *search_pspace, + struct sym_search_scope *search_scope, struct symtab *default_symtab, int default_line) { struct symtabs_and_lines result; linespec_parser parser; struct cleanup *cleanups; + struct sym_search_scope null_scope = null_search_scope (); + int i; + + if (search_scope == NULL) + search_scope = &null_scope; linespec_parser_new (&parser, flags, current_language, - search_pspace, default_symtab, + search_scope, default_symtab, default_line, NULL); cleanups = make_cleanup (linespec_parser_delete, &parser); save_current_program_space (); result = event_location_to_sals (&parser, location); + validate_sals (&result, search_scope); + do_cleanups (cleanups); return result; } @@ -2787,7 +2881,7 @@ decode_objc (struct linespec_state *self, linespec_p ls, const char *arg) return values; } - add_all_symbol_names_from_pspace (&info, NULL, symbol_names); + add_all_symbol_names_from_search_scope (&info, NULL, symbol_names); if (!VEC_empty (symbolp, info.result.symbols) || !VEC_empty (bound_minimal_symbol_d, info.result.minimal_symbols)) @@ -2897,10 +2991,10 @@ lookup_prefix_sym (struct linespec_state *state, VEC (symtab_ptr) *file_symtabs, { iterate_over_all_matching_symtabs (state, class_name, STRUCT_DOMAIN, collect_one_symbol, &collector, - NULL, 0); + state->search_scope, 0); iterate_over_all_matching_symtabs (state, class_name, VAR_DOMAIN, collect_one_symbol, &collector, - NULL, 0); + state->search_scope, 0); } else { @@ -2986,15 +3080,15 @@ compare_msymbols (const void *a, const void *b) are considered. Results are stored into INFO. */ static void -add_all_symbol_names_from_pspace (struct collect_info *info, - struct program_space *pspace, - VEC (const_char_ptr) *names) +add_all_symbol_names_from_search_scope (struct collect_info *info, + struct sym_search_scope *search_scope, + VEC (const_char_ptr) *names) { int ix; const char *iter; for (ix = 0; VEC_iterate (const_char_ptr, names, ix, iter); ++ix) - add_matching_symbols_to_info (iter, info, pspace); + add_matching_symbols_to_info (iter, info, search_scope); } static void @@ -3091,6 +3185,8 @@ find_method (struct linespec_state *self, VEC (symtab_ptr) *file_symtabs, != SYMTAB_PSPACE (symbol_symtab (VEC_index (symbolp, sym_classes, ix + 1))))) { + struct sym_search_scope search_scope = null_search_scope (); + /* If we did not find a direct implementation anywhere in this program space, consider superclasses. */ if (VEC_length (const_char_ptr, result_names) == last_result_len) @@ -3098,9 +3194,11 @@ find_method (struct linespec_state *self, VEC (symtab_ptr) *file_symtabs, &result_names); /* We have a list of candidate symbol names, so now we - iterate over the symbol tables looking for all - matches in this pspace. */ - add_all_symbol_names_from_pspace (&info, pspace, result_names); + iterate over the symbol tables looking for all matches in + this pspace. */ + search_scope.pspace = pspace; + add_all_symbol_names_from_search_scope (&info, &search_scope, + result_names); VEC_truncate (typep, superclass_vec, 0); last_result_len = VEC_length (const_char_ptr, result_names); @@ -3152,13 +3250,12 @@ add_symtabs_to_list (struct symtab *symtab, void *d) return 0; } -/* Given a file name, return a VEC of all matching symtabs. If - SEARCH_PSPACE is not NULL, the search is restricted to just that - program space. */ +/* Return a VEC of all symtabs in SEARCH_SCOPE that match a + filename. */ static VEC (symtab_ptr) * collect_symtabs_from_filename (const char *file, - struct program_space *search_pspace) + struct sym_search_scope *search_scope) { struct symtab_collector collector; struct cleanup *cleanups; @@ -3170,20 +3267,12 @@ collect_symtabs_from_filename (const char *file, cleanups = make_cleanup_htab_delete (collector.symtab_table); /* Find that file's data. */ - if (search_pspace == NULL) + ALL_SEARCH_PSPACES (search_scope->pspace, pspace) { - ALL_PSPACES (pspace) - { - if (pspace->executing_startup) - continue; + if (pspace->executing_startup) + continue; - set_current_program_space (pspace); - iterate_over_symtabs (file, add_symtabs_to_list, &collector); - } - } - else - { - set_current_program_space (search_pspace); + set_current_program_space (pspace); iterate_over_symtabs (file, add_symtabs_to_list, &collector); } @@ -3191,16 +3280,16 @@ collect_symtabs_from_filename (const char *file, return collector.symtabs; } -/* Return all the symtabs associated to the FILENAME. If SEARCH_PSPACE is - not NULL, the search is restricted to just that program space. */ +/* Return all the symtabs associated to the FILENAME. The search is + restricted to SEARCH_SCOPE. */ static VEC (symtab_ptr) * symtabs_from_filename (const char *filename, - struct program_space *search_pspace) + struct sym_search_scope *search_scope) { VEC (symtab_ptr) *result; - result = collect_symtabs_from_filename (filename, search_pspace); + result = collect_symtabs_from_filename (filename, search_scope); if (VEC_empty (symtab_ptr, result)) { @@ -3237,10 +3326,10 @@ find_function_symbols (struct linespec_state *state, /* Try NAME as an Objective-C selector. */ find_imps (name, &symbol_names); if (!VEC_empty (const_char_ptr, symbol_names)) - add_all_symbol_names_from_pspace (&info, state->search_pspace, - symbol_names); + add_all_symbol_names_from_search_scope (&info, state->search_scope, + symbol_names); else - add_matching_symbols_to_info (name, &info, state->search_pspace); + add_matching_symbols_to_info (name, &info, state->search_scope); do_cleanups (cleanup); @@ -3502,6 +3591,7 @@ decode_digits_ordinary (struct linespec_state *self, init_sal (&sal); sal.pspace = SYMTAB_PSPACE (elt); + sal.objfile = SYMTAB_OBJFILE (elt); sal.symtab = elt; sal.line = line; sal.pc = pc; @@ -3602,6 +3692,7 @@ minsym_found (struct linespec_state *self, struct objfile *objfile, sal = find_pc_sect_line (MSYMBOL_VALUE_ADDRESS (objfile, msymbol), (struct obj_section *) 0, 0); sal.section = MSYMBOL_OBJ_SECTION (objfile, msymbol); + sal.msymbol = msymbol; /* The minimal symbol might point to a function descriptor; resolve it to the actual code address instead. */ @@ -3783,16 +3874,15 @@ add_minsym (struct minimal_symbol *minsym, void *d) VEC_safe_push (bound_minimal_symbol_d, info->msyms, &mo); } -/* Search for minimal symbols called NAME. If SEARCH_PSPACE - is not NULL, the search is restricted to just that program - space. +/* Search for minimal symbols called NAME. The search is restricted + to SEARCH_SCOPE. If SYMTAB is NULL, search all objfiles, otherwise restrict results to the given SYMTAB. */ static void search_minsyms_for_name (struct collect_info *info, const char *name, - struct program_space *search_pspace, + struct sym_search_scope *search_scope, struct symtab *symtab) { struct collect_minsyms local; @@ -3810,18 +3900,16 @@ search_minsyms_for_name (struct collect_info *info, const char *name, { struct program_space *pspace; - ALL_PSPACES (pspace) + ALL_SEARCH_PSPACES (search_scope->pspace, pspace) { struct objfile *objfile; - if (search_pspace != NULL && search_pspace != pspace) - continue; if (pspace->executing_startup) continue; set_current_program_space (pspace); - ALL_OBJFILES (objfile) + ALL_SEARCH_OBJFILES (pspace, search_scope->objfile, objfile) { local.objfile = objfile; iterate_over_minimal_symbols (objfile, name, add_minsym, &local); @@ -3830,7 +3918,8 @@ search_minsyms_for_name (struct collect_info *info, const char *name, } else { - if (search_pspace == NULL || SYMTAB_PSPACE (symtab) == search_pspace) + if (search_pspace_matches_pspace (search_scope->pspace, + SYMTAB_PSPACE (symtab))) { set_current_program_space (SYMTAB_PSPACE (symtab)); local.objfile = SYMTAB_OBJFILE(symtab); @@ -3873,14 +3962,13 @@ search_minsyms_for_name (struct collect_info *info, const char *name, do_cleanups (cleanup); } -/* A helper function to add all symbols matching NAME to INFO. If - PSPACE is not NULL, the search is restricted to just that program - space. */ +/* A helper function to add all symbols matching NAME to INFO. The + search is restricted to SEARCH_SCOPE. */ static void add_matching_symbols_to_info (const char *name, struct collect_info *info, - struct program_space *pspace) + struct sym_search_scope *search_scope) { int ix; struct symtab *elt; @@ -3891,10 +3979,11 @@ add_matching_symbols_to_info (const char *name, { iterate_over_all_matching_symtabs (info->state, name, VAR_DOMAIN, collect_symbols, info, - pspace, 1); - search_minsyms_for_name (info, name, pspace, NULL); + search_scope, 1); + search_minsyms_for_name (info, name, search_scope, NULL); } - else if (pspace == NULL || pspace == SYMTAB_PSPACE (elt)) + else if (search_pspace_matches_pspace (search_scope->pspace, + SYMTAB_PSPACE (elt))) { int prev_len = VEC_length (symbolp, info->result.symbols); @@ -3911,7 +4000,7 @@ add_matching_symbols_to_info (const char *name, this case. */ if (prev_len == VEC_length (symbolp, info->result.symbols) && elt->language == language_asm) - search_minsyms_for_name (info, name, pspace, elt); + search_minsyms_for_name (info, name, search_scope, elt); } } } @@ -3928,6 +4017,7 @@ symbol_to_sal (struct symtab_and_line *result, if (SYMBOL_CLASS (sym) == LOC_BLOCK) { *result = find_function_start_sal (sym, funfirstline); + result->symbol = sym; return 1; } else @@ -3939,6 +4029,7 @@ symbol_to_sal (struct symtab_and_line *result, result->line = SYMBOL_LINE (sym); result->pc = SYMBOL_VALUE_ADDRESS (sym); result->pspace = SYMTAB_PSPACE (result->symtab); + result->objfile = SYMTAB_OBJFILE (result->symtab); result->explicit_pc = 1; return 1; } @@ -3953,6 +4044,7 @@ symbol_to_sal (struct symtab_and_line *result, result->symtab = symbol_symtab (sym); result->line = SYMBOL_LINE (sym); result->pspace = SYMTAB_PSPACE (result->symtab); + result->objfile = SYMTAB_OBJFILE (result->symtab); return 1; } } diff --git a/gdb/linespec.h b/gdb/linespec.h index b802612d10d..856b9a98983 100644 --- a/gdb/linespec.h +++ b/gdb/linespec.h @@ -97,7 +97,7 @@ extern struct cleanup * extern struct symtabs_and_lines decode_line_1 (const struct event_location *location, int flags, - struct program_space *search_pspace, + struct sym_search_scope *search_scope, struct symtab *default_symtab, int default_line); /* Parse LOCATION and return results. This is the "full" @@ -140,7 +140,7 @@ extern struct symtabs_and_lines filtered out. */ extern void decode_line_full (const struct event_location *location, int flags, - struct program_space *search_pspace, + struct sym_search_scope *search_scope, struct symtab *default_symtab, int default_line, struct linespec_result *canonical, const char *select_mode, diff --git a/gdb/symtab.h b/gdb/symtab.h index 15fe6016708..9f7550741a4 100644 --- a/gdb/symtab.h +++ b/gdb/symtab.h @@ -1453,6 +1453,11 @@ struct symtab_and_line /* XXX If PROBE is not NULL, then this is the objfile in which the probe originated. */ struct objfile *objfile; + + /* If this SAL originated from a minsym, this is it. */ + struct minimal_symbol *msymbol; + /* If this SAL originated from a symbol, this is it. */ + struct symbol *symbol; }; extern void init_sal (struct symtab_and_line *sal); @@ -1664,4 +1669,7 @@ void initialize_objfile_symbol (struct symbol *); struct template_symbol *allocate_template_symbol (struct objfile *); +void validate_sals (struct symtabs_and_lines *result, + struct sym_search_scope *search_scope); + #endif /* !defined(SYMTAB_H) */ -- 2.47.2