X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gdb%2Flinespec.c;h=53257021f3cf14132c888821a2d107b56f091f11;hb=012d8ebc4bd1a1afb95d902604007b04762207f0;hp=3d7f62fd348b5b88a8d564ed18b3f3fd0826bad4;hpb=dd3818c82cb19570b6b7ddaac277d5f212a432c2;p=platform%2Fupstream%2Fbinutils.git diff --git a/gdb/linespec.c b/gdb/linespec.c index 3d7f62f..5325702 100644 --- a/gdb/linespec.c +++ b/gdb/linespec.c @@ -1,6 +1,6 @@ /* Parser for linespec for the GNU debugger, GDB. - Copyright (C) 1986-2005, 2007-2012 Free Software Foundation, Inc. + Copyright (C) 1986-2014 Free Software Foundation, Inc. This file is part of GDB. @@ -33,7 +33,6 @@ #include "block.h" #include "objc-lang.h" #include "linespec.h" -#include "exceptions.h" #include "language.h" #include "interps.h" #include "mi/mi-cmds.h" @@ -45,9 +44,6 @@ #include "ada-lang.h" #include "stack.h" -typedef struct symtab *symtab_p; -DEF_VEC_P (symtab_p); - typedef struct symbol *symbolp; DEF_VEC_P (symbolp); @@ -64,16 +60,9 @@ struct address_entry CORE_ADDR addr; }; -/* A helper struct which just holds a minimal symbol and the object - file from which it came. */ +typedef struct bound_minimal_symbol bound_minimal_symbol_d; -typedef struct minsym_and_objfile -{ - struct minimal_symbol *minsym; - struct objfile *objfile; -} minsym_and_objfile_d; - -DEF_VEC_O (minsym_and_objfile_d); +DEF_VEC_O (bound_minimal_symbol_d); /* An enumeration of possible signs for a line offset. */ enum offset_relative_sign @@ -124,7 +113,7 @@ struct linespec be NULL. If SOURCE_FILENAME is NULL (no user-specified filename), FILE_SYMTABS should contain one single NULL member. This will cause the code to use the default symtab. */ - VEC (symtab_p) *file_symtabs; + VEC (symtab_ptr) *file_symtabs; /* The name of a function or method and any matching symbols. */ @@ -135,7 +124,7 @@ struct linespec /* A list of matching function symbols and minimal symbols. Both lists may be NULL if no matching symbols were found. */ VEC (symbolp) *function_symbols; - VEC (minsym_and_objfile_d) *minimal_symbols; + VEC (bound_minimal_symbol_d) *minimal_symbols; /* The name of a label and matching symbols. */ @@ -157,6 +146,21 @@ struct linespec }; typedef struct linespec *linespec_p; +/* A canonical linespec represented as a symtab-related string. + + Each entry represents the "SYMTAB:SUFFIX" linespec string. + SYMTAB can be converted for example by symtab_to_fullname or + symtab_to_filename_for_display as needed. */ + +struct linespec_canonical_name +{ + /* Remaining text part of the linespec string. */ + char *suffix; + + /* If NULL then SUFFIX is the whole linespec string. */ + struct symtab *symtab; +}; + /* An instance of this is used to keep all state while linespec operates. This instance is passed around as a 'this' pointer to the various implementation methods. */ @@ -186,7 +190,7 @@ struct linespec_state struct linespec_result *canonical; /* Canonical strings that mirror the symtabs_and_lines result. */ - char **canonical_names; + struct linespec_canonical_name *canonical_names; /* This is a set of address_entry objects which is used to prevent duplicate symbols from being entered into the result. */ @@ -202,13 +206,13 @@ struct collect_info struct linespec_state *state; /* A list of symtabs to which to restrict matches. */ - VEC (symtab_p) *file_symtabs; + VEC (symtab_ptr) *file_symtabs; /* The result being accumulated. */ struct { VEC (symbolp) *symbols; - VEC (minsym_and_objfile_d) *minimal_symbols; + VEC (bound_minimal_symbol_d) *minimal_symbols; } result; }; @@ -273,10 +277,10 @@ struct ls_parser struct { /* Save head of input stream. */ - char *saved_arg; + const char *saved_arg; /* Head of the input stream. */ - char **stream; + const char **stream; #define PARSER_STREAM(P) (*(P)->lexer.stream) /* The current token. */ @@ -286,6 +290,11 @@ struct ls_parser /* Is the entire linespec quote-enclosed? */ int is_quote_enclosed; + /* Is a keyword syntactically valid at this point? + In, e.g., "break thread thread 1", the leading "keyword" must not + be interpreted as such. */ + int keyword_ok; + /* The state of the parse. */ struct linespec_state state; #define PARSER_STATE(PPTR) (&(PPTR)->state) @@ -298,27 +307,32 @@ typedef struct ls_parser linespec_parser; /* Prototypes for local functions. */ +static void iterate_over_file_blocks (struct symtab *symtab, + const char *name, domain_enum domain, + symbol_found_callback_ftype *callback, + void *data); + static void initialize_defaults (struct symtab **default_symtab, int *default_line); -static CORE_ADDR linespec_expression_to_pc (char **exp_ptr); +static CORE_ADDR linespec_expression_to_pc (const char **exp_ptr); static struct symtabs_and_lines decode_objc (struct linespec_state *self, linespec_p ls, - char **argptr); + const char **argptr); -static VEC (symtab_p) *symtabs_from_filename (const char *); +static VEC (symtab_ptr) *symtabs_from_filename (const char *); static VEC (symbolp) *find_label_symbols (struct linespec_state *self, VEC (symbolp) *function_symbols, VEC (symbolp) **label_funcs_ret, const char *name); -void find_linespec_symbols (struct linespec_state *self, - VEC (symtab_p) *file_symtabs, - const char *name, - VEC (symbolp) **symbols, - VEC (minsym_and_objfile_d) **minsyms); +static void find_linespec_symbols (struct linespec_state *self, + VEC (symtab_ptr) *file_symtabs, + const char *name, + VEC (symbolp) **symbols, + VEC (bound_minimal_symbol_d) **minsyms); static struct line_offset linespec_parse_variable (struct linespec_state *self, @@ -335,7 +349,7 @@ static void add_all_symbol_names_from_pspace (struct collect_info *info, struct program_space *pspace, VEC (const_char_ptr) *names); -static VEC (symtab_p) *collect_symtabs_from_filename (const char *file); +static VEC (symtab_ptr) *collect_symtabs_from_filename (const char *file); static void decode_digits_ordinary (struct linespec_state *self, linespec_p ls, @@ -391,10 +405,11 @@ linespec_lexer_lex_number (linespec_parser *parser, linespec_token *tokenp) } /* If the next character in the input buffer is not a space, comma, - or colon, this input does not represent a number. */ + quote, or colon, this input does not represent a number. */ if (*PARSER_STREAM (parser) != '\0' && !isspace (*PARSER_STREAM (parser)) && *PARSER_STREAM (parser) != ',' - && *PARSER_STREAM (parser) != ':') + && *PARSER_STREAM (parser) != ':' + && !strchr (linespec_quote_characters, *PARSER_STREAM (parser))) { PARSER_STREAM (parser) = LS_TOKEN_STOKEN (*tokenp).ptr; return 0; @@ -499,12 +514,12 @@ is_closing_quote_enclosed (const char *p) This helper function assists with lexing string segments which might contain valid (non-terminating) commas. */ -static char * -find_parameter_list_end (char *input) +static const char * +find_parameter_list_end (const char *input) { char end_char, start_char; int depth; - char *p; + const char *p; start_char = *input; if (start_char == '(') @@ -541,7 +556,7 @@ static linespec_token linespec_lexer_lex_string (linespec_parser *parser) { linespec_token token; - char *start = PARSER_STREAM (parser); + const char *start = PARSER_STREAM (parser); token.type = LSTOKEN_STRING; @@ -591,7 +606,7 @@ linespec_lexer_lex_string (linespec_parser *parser) } else { - char *p; + const char *p; /* Otherwise, only identifier characters are permitted. Spaces are the exception. In general, we keep spaces, @@ -605,7 +620,11 @@ linespec_lexer_lex_string (linespec_parser *parser) { if (isspace (*PARSER_STREAM (parser))) { - p = skip_spaces (PARSER_STREAM (parser)); + p = skip_spaces_const (PARSER_STREAM (parser)); + /* When we get here we know we've found something followed by + a space (we skip over parens and templates below). + So if we find a keyword now, we know it is a keyword and not, + say, a function name. */ if (linespec_lexer_lex_keyword (p) != NULL) { LS_TOKEN_STOKEN (token).ptr = start; @@ -661,7 +680,7 @@ linespec_lexer_lex_string (linespec_parser *parser) else if (*PARSER_STREAM (parser) == '<' || *PARSER_STREAM (parser) == '(') { - char *p; + const char *p; p = find_parameter_list_end (PARSER_STREAM (parser)); if (p != NULL) @@ -713,10 +732,12 @@ linespec_lexer_lex_one (linespec_parser *parser) if (parser->lexer.current.type == LSTOKEN_CONSUMED) { /* Skip any whitespace. */ - PARSER_STREAM (parser) = skip_spaces (PARSER_STREAM (parser)); + PARSER_STREAM (parser) = skip_spaces_const (PARSER_STREAM (parser)); - /* Check for a keyword. */ - keyword = linespec_lexer_lex_keyword (PARSER_STREAM (parser)); + /* Check for a keyword, they end the linespec. */ + keyword = NULL; + if (parser->keyword_ok) + keyword = linespec_lexer_lex_keyword (PARSER_STREAM (parser)); if (keyword != NULL) { parser->lexer.current.type = LSTOKEN_KEYWORD; @@ -797,7 +818,7 @@ static linespec_token linespec_lexer_peek_token (linespec_parser *parser) { linespec_token next; - char *saved_stream = PARSER_STREAM (parser); + const char *saved_stream = PARSER_STREAM (parser); linespec_token saved_token = parser->lexer.current; next = linespec_lexer_consume_token (parser); @@ -836,30 +857,36 @@ add_sal_to_sals (struct linespec_state *self, if (self->canonical) { - char *canonical_name = NULL; + struct linespec_canonical_name *canonical; self->canonical_names = xrealloc (self->canonical_names, - sals->nelts * sizeof (char *)); - if (!literal_canonical && sal->symtab && sal->symtab->filename) + (sals->nelts + * sizeof (*self->canonical_names))); + canonical = &self->canonical_names[sals->nelts - 1]; + if (!literal_canonical && sal->symtab) { - char *filename = sal->symtab->filename; + const char *fullname = symtab_to_fullname (sal->symtab); /* Note that the filter doesn't have to be a valid linespec input. We only apply the ":LINE" treatment to Ada for the time being. */ if (symname != NULL && sal->line != 0 && self->language->la_language == language_ada) - canonical_name = xstrprintf ("%s:%s:%d", filename, symname, - sal->line); + canonical->suffix = xstrprintf ("%s:%d", symname, sal->line); else if (symname != NULL) - canonical_name = xstrprintf ("%s:%s", filename, symname); + canonical->suffix = xstrdup (symname); else - canonical_name = xstrprintf ("%s:%d", filename, sal->line); + canonical->suffix = xstrprintf ("%d", sal->line); + canonical->symtab = sal->symtab; + } + else + { + if (symname != NULL) + canonical->suffix = xstrdup (symname); + else + canonical->suffix = xstrdup (""); + canonical->symtab = NULL; } - else if (symname != NULL) - canonical_name = xstrdup (symname); - - self->canonical_names[sals->nelts - 1] = canonical_name; } } @@ -1006,22 +1033,20 @@ iterate_over_all_matching_symtabs (struct linespec_state *state, ALL_OBJFILE_PRIMARY_SYMTABS (objfile, symtab) { - struct block *block; - - block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), STATIC_BLOCK); - LA_ITERATE_OVER_SYMBOLS (block, name, domain, callback, data); + iterate_over_file_blocks (symtab, name, domain, callback, data); if (include_inline) { struct symbol_and_data_callback cad = { callback, data }; + struct block *block; int i; for (i = FIRST_LOCAL_BLOCK; i < BLOCKVECTOR_NBLOCKS (BLOCKVECTOR (symtab)); i++) { block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), i); - LA_ITERATE_OVER_SYMBOLS (block, name, domain, - iterate_inline_only, &cad); + state->language->la_iterate_over_symbols + (block, name, domain, iterate_inline_only, &cad); } } } @@ -1029,30 +1054,39 @@ iterate_over_all_matching_symtabs (struct linespec_state *state, } } -/* Returns the block to be used for symbol searches for the given SYMTAB, - which may be NULL. */ +/* Returns the block to be used for symbol searches from + the current location. */ -static struct block * -get_search_block (struct symtab *symtab) +static const struct block * +get_current_search_block (void) { - struct block *block; - - if (symtab != NULL) - block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), STATIC_BLOCK); - else - { - enum language save_language; + const struct block *block; + enum language save_language; - /* get_selected_block can change the current language when there is - no selected frame yet. */ - save_language = current_language->la_language; - block = get_selected_block (0); - set_language (save_language); - } + /* get_selected_block can change the current language when there is + no selected frame yet. */ + save_language = current_language->la_language; + block = get_selected_block (0); + set_language (save_language); return block; } +/* Iterate over static and global blocks. */ + +static void +iterate_over_file_blocks (struct symtab *symtab, + const char *name, domain_enum domain, + symbol_found_callback_ftype *callback, void *data) +{ + struct block *block; + + for (block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), STATIC_BLOCK); + block != NULL; + block = BLOCK_SUPERBLOCK (block)) + LA_ITERATE_OVER_SYMBOLS (block, name, domain, callback, data); +} + /* A helper for find_method. This finds all methods in type T which match NAME. It adds matching symbol names to RESULT_NAMES, and adds T's direct superclasses to SUPERCLASSES. */ @@ -1062,7 +1096,6 @@ find_methods (struct type *t, const char *name, VEC (const_char_ptr) **result_names, VEC (typep) **superclasses) { - int i1 = 0; int ibase; const char *class_name = type_name_no_tag (t); @@ -1072,7 +1105,6 @@ find_methods (struct type *t, const char *name, if (class_name) { int method_counter; - int name_len = strlen (name); CHECK_TYPEDEF (t); @@ -1189,6 +1221,19 @@ find_toplevel_string (const char *haystack, const char *needle) return NULL; } +/* Convert CANONICAL to its string representation using + symtab_to_fullname for SYMTAB. The caller must xfree the result. */ + +static char * +canonical_to_fullform (const struct linespec_canonical_name *canonical) +{ + if (canonical->symtab == NULL) + return xstrdup (canonical->suffix); + else + return xstrprintf ("%s:%s", symtab_to_fullname (canonical->symtab), + canonical->suffix); +} + /* Given FILTERS, a list of canonical names, filter the sals in RESULT and store the result in SELF->CANONICAL. */ @@ -1209,8 +1254,18 @@ filter_results (struct linespec_state *self, for (j = 0; j < result->nelts; ++j) { - if (strcmp (name, self->canonical_names[j]) == 0) + const struct linespec_canonical_name *canonical; + char *fullform; + struct cleanup *cleanup; + + canonical = &self->canonical_names[j]; + fullform = canonical_to_fullform (canonical); + cleanup = make_cleanup (xfree, fullform); + + if (strcmp (name, fullform) == 0) add_sal_to_sals_basic (&lsal.sals, &result->sals[j]); + + do_cleanups (cleanup); } if (lsal.sals.nelts > 0) @@ -1236,6 +1291,44 @@ convert_results_to_lsals (struct linespec_state *self, VEC_safe_push (linespec_sals, self->canonical->sals, &lsal); } +/* A structure that contains two string representations of a struct + linespec_canonical_name: + - one where the the symtab's fullname is used; + - one where the filename followed the "set filename-display" + setting. */ + +struct decode_line_2_item +{ + /* The form using symtab_to_fullname. + It must be xfree'ed after use. */ + char *fullform; + + /* The form using symtab_to_filename_for_display. + It must be xfree'ed after use. */ + char *displayform; + + /* Field is initialized to zero and it is set to one if the user + requested breakpoint for this entry. */ + unsigned int selected : 1; +}; + +/* Helper for qsort to sort decode_line_2_item entries by DISPLAYFORM and + secondarily by FULLFORM. */ + +static int +decode_line_2_compare_items (const void *ap, const void *bp) +{ + const struct decode_line_2_item *a = ap; + const struct decode_line_2_item *b = bp; + int retval; + + retval = strcmp (a->displayform, b->displayform); + if (retval != 0) + return retval; + + return strcmp (a->fullform, b->fullform); +} + /* Handle multiple results in RESULT depending on SELECT_MODE. This will either return normally, throw an exception on multiple results, or present a menu to the user. On return, the SALS vector @@ -1246,58 +1339,80 @@ decode_line_2 (struct linespec_state *self, struct symtabs_and_lines *result, const char *select_mode) { - const char *iter; char *args, *prompt; int i; struct cleanup *old_chain; - VEC (const_char_ptr) *item_names = NULL, *filters = NULL; + VEC (const_char_ptr) *filters = NULL; struct get_number_or_range_state state; + struct decode_line_2_item *items; + int items_count; gdb_assert (select_mode != multiple_symbols_all); gdb_assert (self->canonical != NULL); + gdb_assert (result->nelts >= 1); + + old_chain = make_cleanup (VEC_cleanup (const_char_ptr), &filters); - old_chain = make_cleanup (VEC_cleanup (const_char_ptr), &item_names); - make_cleanup (VEC_cleanup (const_char_ptr), &filters); - for (i = 0; i < result->nelts; ++i) + /* Prepare ITEMS array. */ + items_count = result->nelts; + items = xmalloc (sizeof (*items) * items_count); + make_cleanup (xfree, items); + for (i = 0; i < items_count; ++i) { - int j, found = 0; - const char *iter; + const struct linespec_canonical_name *canonical; + struct decode_line_2_item *item; + + canonical = &self->canonical_names[i]; + gdb_assert (canonical->suffix != NULL); + item = &items[i]; + + item->fullform = canonical_to_fullform (canonical); + make_cleanup (xfree, item->fullform); - gdb_assert (self->canonical_names[i] != NULL); - for (j = 0; VEC_iterate (const_char_ptr, item_names, j, iter); ++j) + if (canonical->symtab == NULL) + item->displayform = canonical->suffix; + else { - if (strcmp (iter, self->canonical_names[i]) == 0) - { - found = 1; - break; - } + const char *fn_for_display; + + fn_for_display = symtab_to_filename_for_display (canonical->symtab); + item->displayform = xstrprintf ("%s:%s", fn_for_display, + canonical->suffix); + make_cleanup (xfree, item->displayform); } - if (!found) - VEC_safe_push (const_char_ptr, item_names, self->canonical_names[i]); + item->selected = 0; } - if (select_mode == multiple_symbols_cancel - && VEC_length (const_char_ptr, item_names) > 1) + /* Sort the list of method names. */ + qsort (items, items_count, sizeof (*items), decode_line_2_compare_items); + + /* Remove entries with the same FULLFORM. */ + if (items_count >= 2) + { + struct decode_line_2_item *dst, *src; + + dst = items; + for (src = &items[1]; src < &items[items_count]; src++) + if (strcmp (src->fullform, dst->fullform) != 0) + *++dst = *src; + items_count = dst + 1 - items; + } + + if (select_mode == multiple_symbols_cancel && items_count > 1) error (_("canceled because the command is ambiguous\n" "See set/show multiple-symbol.")); - if (select_mode == multiple_symbols_all - || VEC_length (const_char_ptr, item_names) == 1) + if (select_mode == multiple_symbols_all || items_count == 1) { do_cleanups (old_chain); convert_results_to_lsals (self, result); return; } - /* Sort the list of method names alphabetically. */ - qsort (VEC_address (const_char_ptr, item_names), - VEC_length (const_char_ptr, item_names), - sizeof (const_char_ptr), compare_strings); - printf_unfiltered (_("[0] cancel\n[1] all\n")); - for (i = 0; VEC_iterate (const_char_ptr, item_names, i, iter); ++i) - printf_unfiltered ("[%d] %s\n", i + 2, iter); + for (i = 0; i < items_count; i++) + printf_unfiltered ("[%d] %s\n", i + 2, items[i].displayform); prompt = getenv ("PS2"); if (prompt == NULL) @@ -1332,21 +1447,21 @@ decode_line_2 (struct linespec_state *self, } num -= 2; - if (num >= VEC_length (const_char_ptr, item_names)) + if (num >= items_count) printf_unfiltered (_("No choice number %d.\n"), num); else { - const char *elt = VEC_index (const_char_ptr, item_names, num); + struct decode_line_2_item *item = &items[num]; - if (elt != NULL) + if (!item->selected) { - VEC_safe_push (const_char_ptr, filters, elt); - VEC_replace (const_char_ptr, item_names, num, NULL); + VEC_safe_push (const_char_ptr, filters, item->fullform); + item->selected = 1; } else { printf_unfiltered (_("duplicate request for %d ignored.\n"), - num); + num + 2); } } } @@ -1464,7 +1579,7 @@ linespec_parse_basic (linespec_parser *parser) char *name; linespec_token token; VEC (symbolp) *symbols, *labels; - VEC (minsym_and_objfile_d) *minimal_symbols; + VEC (bound_minimal_symbol_d) *minimal_symbols; struct cleanup *cleanup; /* Get the next token. */ @@ -1523,7 +1638,7 @@ linespec_parse_basic (linespec_parser *parser) else { /* NAME was not a function or a method. So it must be a label - name. */ + name or user specified variable like "break foo.c:$zippo". */ labels = find_label_symbols (PARSER_STATE (parser), NULL, &symbols, name); if (labels != NULL) @@ -1534,6 +1649,26 @@ linespec_parse_basic (linespec_parser *parser) symbols = NULL; discard_cleanups (cleanup); } + else if (token.type == LSTOKEN_STRING + && *LS_TOKEN_STOKEN (token).ptr == '$') + { + /* User specified a convenience variable or history value. */ + PARSER_RESULT (parser)->line_offset + = linespec_parse_variable (PARSER_STATE (parser), name); + + if (PARSER_RESULT (parser)->line_offset.sign == LINE_OFFSET_UNKNOWN) + { + /* The user-specified variable was not valid. Do not + throw an error here. parse_linespec will do it for us. */ + PARSER_RESULT (parser)->function_name = name; + discard_cleanups (cleanup); + return; + } + + /* The convenience variable/history value parsed correctly. + NAME is no longer needed. */ + do_cleanups (cleanup); + } else { /* The name is also not a label. Abort parsing. Do not throw @@ -1711,22 +1846,24 @@ create_sals_line_offset (struct linespec_state *self, /* This is where we need to make sure we have good defaults. We must guarantee that this section of code is never executed - when we are called with just a function anme, since + when we are called with just a function name, since set_default_source_symtab_and_line uses select_source_symtab that calls us with such an argument. */ - if (VEC_length (symtab_p, ls->file_symtabs) == 1 - && VEC_index (symtab_p, ls->file_symtabs, 0) == NULL) + if (VEC_length (symtab_ptr, ls->file_symtabs) == 1 + && VEC_index (symtab_ptr, ls->file_symtabs, 0) == NULL) { + const char *fullname; + set_current_program_space (self->program_space); /* Make sure we have at least a default source line. */ set_default_source_symtab_and_line (); initialize_defaults (&self->default_symtab, &self->default_line); - VEC_pop (symtab_p, ls->file_symtabs); - VEC_free (symtab_p, ls->file_symtabs); - ls->file_symtabs - = collect_symtabs_from_filename (self->default_symtab->filename); + fullname = symtab_to_fullname (self->default_symtab); + VEC_pop (symtab_ptr, ls->file_symtabs); + VEC_free (symtab_ptr, ls->file_symtabs); + ls->file_symtabs = collect_symtabs_from_filename (fullname); use_default = 1; } @@ -1759,7 +1896,7 @@ create_sals_line_offset (struct linespec_state *self, { struct linetable_entry *best_entry = NULL; int *filter; - struct block **blocks; + const struct block **blocks; struct cleanup *cleanup; struct symtabs_and_lines intermediate_results; int i, j; @@ -1787,7 +1924,7 @@ create_sals_line_offset (struct linespec_state *self, filter = XNEWVEC (int, intermediate_results.nelts); make_cleanup (xfree, filter); - blocks = XNEWVEC (struct block *, intermediate_results.nelts); + blocks = XNEWVEC (const struct block *, intermediate_results.nelts); make_cleanup (xfree, blocks); for (i = 0; i < intermediate_results.nelts; ++i) @@ -1871,7 +2008,10 @@ convert_linespec_to_sals (struct linespec_state *state, linespec_p ls) for (i = 0; VEC_iterate (symbolp, ls->labels.label_symbols, i, sym); ++i) { - if (symbol_to_sal (&sal, state->funfirstline, sym)) + struct program_space *pspace = SYMTAB_PSPACE (SYMBOL_SYMTAB (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, SYMBOL_NATURAL_NAME (sym), 0); } @@ -1882,7 +2022,7 @@ convert_linespec_to_sals (struct linespec_state *state, linespec_p ls) int i; struct symtab_and_line sal; struct symbol *sym; - minsym_and_objfile_d *elem; + bound_minimal_symbol_d *elem; struct program_space *pspace; if (ls->function_symbols != NULL) @@ -1907,12 +2047,13 @@ convert_linespec_to_sals (struct linespec_state *state, linespec_p ls) if (ls->minimal_symbols != NULL) { /* Sort minimal symbols by program space, too. */ - qsort (VEC_address (minsym_and_objfile_d, ls->minimal_symbols), - VEC_length (minsym_and_objfile_d, ls->minimal_symbols), - sizeof (minsym_and_objfile_d), compare_msymbols); + qsort (VEC_address (bound_minimal_symbol_d, ls->minimal_symbols), + VEC_length (bound_minimal_symbol_d, ls->minimal_symbols), + sizeof (bound_minimal_symbol_d), compare_msymbols); for (i = 0; - VEC_iterate (minsym_and_objfile_d, ls->minimal_symbols, i, elem); + VEC_iterate (bound_minimal_symbol_d, ls->minimal_symbols, + i, elem); ++i) { pspace = elem->objfile->pspace; @@ -1928,7 +2069,15 @@ convert_linespec_to_sals (struct linespec_state *state, linespec_p ls) /* Make sure we have a filename for canonicalization. */ if (ls->source_filename == NULL) - ls->source_filename = xstrdup (state->default_symtab->filename); + { + const char *fullname = symtab_to_fullname (state->default_symtab); + + /* It may be more appropriate to keep DEFAULT_SYMTAB in its symtab + form so that displaying SOURCE_FILENAME can follow the current + FILENAME_DISPLAY_STRING setting. But as it is used only rarely + it has been kept for code simplicity only in absolute form. */ + ls->source_filename = xstrdup (fullname); + } } else { @@ -1998,7 +2147,7 @@ convert_linespec_to_sals (struct linespec_state *state, linespec_p ls) /* Parse the linespec in ARGPTR. */ static struct symtabs_and_lines -parse_linespec (linespec_parser *parser, char **argptr) +parse_linespec (linespec_parser *parser, const char **argptr) { linespec_token token; struct symtabs_and_lines values; @@ -2024,6 +2173,10 @@ parse_linespec (linespec_parser *parser, char **argptr) } } + /* A keyword at the start cannot be interpreted as such. + Consider "b thread thread 42". */ + parser->keyword_ok = 0; + parser->lexer.saved_arg = *argptr; parser->lexer.stream = argptr; file_exception.reason = 0; @@ -2045,7 +2198,8 @@ parse_linespec (linespec_parser *parser, char **argptr) /* It must be either LSTOKEN_STRING or LSTOKEN_NUMBER. */ if (token.type == LSTOKEN_STRING && *LS_TOKEN_STOKEN (token).ptr == '*') { - char *expr, *copy; + char *expr; + const char *copy; /* User specified an expression, *EXPR. */ copy = expr = copy_token_string (token); @@ -2073,31 +2227,31 @@ parse_linespec (linespec_parser *parser, char **argptr) char *var; /* A NULL entry means to use GLOBAL_DEFAULT_SYMTAB. */ - VEC_safe_push (symtab_p, PARSER_RESULT (parser)->file_symtabs, NULL); + VEC_safe_push (symtab_ptr, PARSER_RESULT (parser)->file_symtabs, NULL); /* User specified a convenience variable or history value. */ var = copy_token_string (token); cleanup = make_cleanup (xfree, var); PARSER_RESULT (parser)->line_offset = linespec_parse_variable (PARSER_STATE (parser), var); + do_cleanups (cleanup); /* If a line_offset wasn't found (VAR is the name of a user variable/function), then skip to normal symbol processing. */ if (PARSER_RESULT (parser)->line_offset.sign != LINE_OFFSET_UNKNOWN) { - discard_cleanups (cleanup); - /* Consume this token. */ linespec_lexer_consume_token (parser); goto convert_to_sals; } - - do_cleanups (cleanup); } else if (token.type != LSTOKEN_STRING && token.type != LSTOKEN_NUMBER) unexpected_linespec_error (parser); + /* Now we can recognize keywords. */ + parser->keyword_ok = 1; + /* Shortcut: If the next token is not LSTOKEN_COLON, we know that this token cannot represent a filename. */ token = linespec_lexer_peek_token (parser); @@ -2134,7 +2288,7 @@ parse_linespec (linespec_parser *parser, char **argptr) xfree (user_filename); /* A NULL entry means to use GLOBAL_DEFAULT_SYMTAB. */ - VEC_safe_push (symtab_p, PARSER_RESULT (parser)->file_symtabs, NULL); + VEC_safe_push (symtab_ptr, PARSER_RESULT (parser)->file_symtabs, NULL); } } /* If the next token is not EOI, KEYWORD, or COMMA, issue an error. */ @@ -2149,7 +2303,7 @@ parse_linespec (linespec_parser *parser, char **argptr) else { /* A NULL entry means to use GLOBAL_DEFAULT_SYMTAB. */ - VEC_safe_push (symtab_p, PARSER_RESULT (parser)->file_symtabs, NULL); + VEC_safe_push (symtab_ptr, PARSER_RESULT (parser)->file_symtabs, NULL); } /* Parse the rest of the linespec. */ @@ -2244,13 +2398,13 @@ linespec_parser_delete (void *arg) xfree ((char *) PARSER_RESULT (parser)->function_name); if (PARSER_RESULT (parser)->file_symtabs != NULL) - VEC_free (symtab_p, PARSER_RESULT (parser)->file_symtabs); + VEC_free (symtab_ptr, PARSER_RESULT (parser)->file_symtabs); if (PARSER_RESULT (parser)->function_symbols != NULL) VEC_free (symbolp, PARSER_RESULT (parser)->function_symbols); if (PARSER_RESULT (parser)->minimal_symbols != NULL) - VEC_free (minsym_and_objfile_d, PARSER_RESULT (parser)->minimal_symbols); + VEC_free (bound_minimal_symbol_d, PARSER_RESULT (parser)->minimal_symbols); if (PARSER_RESULT (parser)->labels.label_symbols != NULL) VEC_free (symbolp, PARSER_RESULT (parser)->labels.label_symbols); @@ -2272,10 +2426,10 @@ decode_line_full (char **argptr, int flags, { struct symtabs_and_lines result; struct cleanup *cleanups; - char *arg_start = *argptr; VEC (const_char_ptr) *filters = NULL; linespec_parser parser; struct linespec_state *state; + const char *copy, *orig; gdb_assert (canonical != NULL); /* The filter only makes sense for 'all'. */ @@ -2291,7 +2445,9 @@ decode_line_full (char **argptr, int flags, cleanups = make_cleanup (linespec_parser_delete, &parser); save_current_program_space (); - result = parse_linespec (&parser, argptr); + orig = copy = *argptr; + result = parse_linespec (&parser, ©); + *argptr += copy - orig; state = PARSER_STATE (&parser); gdb_assert (result.nelts == 1 || canonical->pre_expanded); @@ -2306,8 +2462,8 @@ decode_line_full (char **argptr, int flags, make_cleanup (xfree, state->canonical_names); for (i = 0; i < result.nelts; ++i) { - gdb_assert (state->canonical_names[i] != NULL); - make_cleanup (xfree, state->canonical_names[i]); + gdb_assert (state->canonical_names[i].suffix != NULL); + make_cleanup (xfree, state->canonical_names[i].suffix); } } @@ -2346,13 +2502,16 @@ decode_line_1 (char **argptr, int flags, struct symtabs_and_lines result; linespec_parser parser; struct cleanup *cleanups; + const char *copy, *orig; linespec_parser_new (&parser, flags, current_language, default_symtab, default_line, NULL); cleanups = make_cleanup (linespec_parser_delete, &parser); save_current_program_space (); - result = parse_linespec (&parser, argptr); + orig = copy = *argptr; + result = parse_linespec (&parser, ©); + *argptr += copy - orig; do_cleanups (cleanups); return result; @@ -2430,7 +2589,7 @@ initialize_defaults (struct symtab **default_symtab, int *default_line) advancing EXP_PTR past any parsed text. */ static CORE_ADDR -linespec_expression_to_pc (char **exp_ptr) +linespec_expression_to_pc (const char **exp_ptr) { if (current_program_space->executing_startup) /* The error message doesn't really matter, because this case @@ -2452,19 +2611,19 @@ linespec_expression_to_pc (char **exp_ptr) the existing C++ code to let the user choose one. */ static struct symtabs_and_lines -decode_objc (struct linespec_state *self, linespec_p ls, char **argptr) +decode_objc (struct linespec_state *self, linespec_p ls, const char **argptr) { struct collect_info info; VEC (const_char_ptr) *symbol_names = NULL; struct symtabs_and_lines values; - char *new_argptr; + const char *new_argptr; struct cleanup *cleanup = make_cleanup (VEC_cleanup (const_char_ptr), &symbol_names); info.state = self; info.file_symtabs = NULL; - VEC_safe_push (symtab_p, info.file_symtabs, NULL); - make_cleanup (VEC_cleanup (symtab_p), &info.file_symtabs); + VEC_safe_push (symtab_ptr, info.file_symtabs, NULL); + make_cleanup (VEC_cleanup (symtab_ptr), &info.file_symtabs); info.result.symbols = NULL; info.result.minimal_symbols = NULL; values.nelts = 0; @@ -2480,7 +2639,7 @@ decode_objc (struct linespec_state *self, linespec_p ls, char **argptr) add_all_symbol_names_from_pspace (&info, NULL, symbol_names); if (!VEC_empty (symbolp, info.result.symbols) - || !VEC_empty (minsym_and_objfile_d, info.result.minimal_symbols)) + || !VEC_empty (bound_minimal_symbol_d, info.result.minimal_symbols)) { char *saved_arg; @@ -2557,7 +2716,7 @@ collect_one_symbol (struct symbol *sym, void *d) /* Return any symbols corresponding to CLASS_NAME in FILE_SYMTABS. */ static VEC (symbolp) * -lookup_prefix_sym (struct linespec_state *state, VEC (symtab_p) *file_symtabs, +lookup_prefix_sym (struct linespec_state *state, VEC (symtab_ptr) *file_symtabs, const char *class_name) { int ix; @@ -2574,7 +2733,7 @@ lookup_prefix_sym (struct linespec_state *state, VEC (symtab_p) *file_symtabs, xcalloc, xfree); cleanup = make_cleanup_htab_delete (collector.unique_syms); - for (ix = 0; VEC_iterate (symtab_p, file_symtabs, ix, elt); ++ix) + for (ix = 0; VEC_iterate (symtab_ptr, file_symtabs, ix, elt); ++ix) { if (elt == NULL) { @@ -2587,17 +2746,14 @@ lookup_prefix_sym (struct linespec_state *state, VEC (symtab_p) *file_symtabs, } else { - struct block *search_block; - /* Program spaces that are executing startup should have been filtered out earlier. */ gdb_assert (!SYMTAB_PSPACE (elt)->executing_startup); set_current_program_space (SYMTAB_PSPACE (elt)); - search_block = get_search_block (elt); - LA_ITERATE_OVER_SYMBOLS (search_block, class_name, STRUCT_DOMAIN, - collect_one_symbol, &collector); - LA_ITERATE_OVER_SYMBOLS (search_block, class_name, VAR_DOMAIN, - collect_one_symbol, &collector); + iterate_over_file_blocks (elt, class_name, STRUCT_DOMAIN, + collect_one_symbol, &collector); + iterate_over_file_blocks (elt, class_name, VAR_DOMAIN, + collect_one_symbol, &collector); } } @@ -2641,8 +2797,8 @@ compare_symbols (const void *a, const void *b) static int compare_msymbols (const void *a, const void *b) { - const struct minsym_and_objfile *sa = a; - const struct minsym_and_objfile *sb = b; + const struct bound_minimal_symbol *sa = a; + const struct bound_minimal_symbol *sb = b; uintptr_t uia, uib; uia = (uintptr_t) sa->objfile->pspace; @@ -2716,10 +2872,10 @@ find_superclass_methods (VEC (typep) *superclasses, in SYMBOLS (for debug symbols) and MINSYMS (for minimal symbols). */ static void -find_method (struct linespec_state *self, VEC (symtab_p) *file_symtabs, +find_method (struct linespec_state *self, VEC (symtab_ptr) *file_symtabs, const char *class_name, const char *method_name, VEC (symbolp) *sym_classes, VEC (symbolp) **symbols, - VEC (minsym_and_objfile_d) **minsyms) + VEC (bound_minimal_symbol_d) **minsyms) { struct symbol *sym; struct cleanup *cleanup = make_cleanup (null_cleanup, NULL); @@ -2792,7 +2948,7 @@ find_method (struct linespec_state *self, VEC (symtab_p) *file_symtabs, } if (!VEC_empty (symbolp, info.result.symbols) - || !VEC_empty (minsym_and_objfile_d, info.result.minimal_symbols)) + || !VEC_empty (bound_minimal_symbol_d, info.result.minimal_symbols)) { *symbols = info.result.symbols; *minsyms = info.result.minimal_symbols; @@ -2812,7 +2968,7 @@ find_method (struct linespec_state *self, VEC (symtab_p) *file_symtabs, struct symtab_collector { /* The result vector of symtabs. */ - VEC (symtab_p) *symtabs; + VEC (symtab_ptr) *symtabs; /* This is used to ensure the symtabs are unique. */ htab_t symtab_table; @@ -2830,7 +2986,7 @@ add_symtabs_to_list (struct symtab *symtab, void *d) if (!*slot) { *slot = symtab; - VEC_safe_push (symtab_p, data->symtabs, symtab); + VEC_safe_push (symtab_ptr, data->symtabs, symtab); } return 0; @@ -2838,7 +2994,7 @@ add_symtabs_to_list (struct symtab *symtab, void *d) /* Given a file name, return a VEC of all matching symtabs. */ -static VEC (symtab_p) * +static VEC (symtab_ptr) * collect_symtabs_from_filename (const char *file) { struct symtab_collector collector; @@ -2866,14 +3022,14 @@ collect_symtabs_from_filename (const char *file) /* Return all the symtabs associated to the FILENAME. */ -static VEC (symtab_p) * +static VEC (symtab_ptr) * symtabs_from_filename (const char *filename) { - VEC (symtab_p) *result; + VEC (symtab_ptr) *result; result = collect_symtabs_from_filename (filename); - if (VEC_empty (symtab_p, result)) + if (VEC_empty (symtab_ptr, result)) { if (!have_full_symbols () && !have_partial_symbols ()) throw_error (NOT_FOUND_ERROR, @@ -2891,9 +3047,9 @@ symtabs_from_filename (const char *filename) static void find_function_symbols (struct linespec_state *state, - VEC (symtab_p) *file_symtabs, const char *name, + VEC (symtab_ptr) *file_symtabs, const char *name, VEC (symbolp) **symbols, - VEC (minsym_and_objfile_d) **minsyms) + VEC (bound_minimal_symbol_d) **minsyms) { struct collect_info info; VEC (const_char_ptr) *symbol_names = NULL; @@ -2906,7 +3062,7 @@ find_function_symbols (struct linespec_state *state, info.file_symtabs = file_symtabs; /* Try NAME as an Objective-C selector. */ - find_imps ((char *) name, &symbol_names); + find_imps (name, &symbol_names); if (!VEC_empty (const_char_ptr, symbol_names)) add_all_symbol_names_from_pspace (&info, NULL, symbol_names); else @@ -2922,9 +3078,9 @@ find_function_symbols (struct linespec_state *state, else *symbols = info.result.symbols; - if (VEC_empty (minsym_and_objfile_d, info.result.minimal_symbols)) + if (VEC_empty (bound_minimal_symbol_d, info.result.minimal_symbols)) { - VEC_free (minsym_and_objfile_d, info.result.minimal_symbols); + VEC_free (bound_minimal_symbol_d, info.result.minimal_symbols); *minsyms = NULL; } else @@ -2934,17 +3090,16 @@ find_function_symbols (struct linespec_state *state, /* Find all symbols named NAME in FILE_SYMTABS, returning debug symbols in SYMBOLS and minimal symbols in MINSYMS. */ -void +static void find_linespec_symbols (struct linespec_state *state, - VEC (symtab_p) *file_symtabs, + VEC (symtab_ptr) *file_symtabs, const char *name, VEC (symbolp) **symbols, - VEC (minsym_and_objfile_d) **minsyms) + VEC (bound_minimal_symbol_d) **minsyms) { - char *klass, *method, *canon; - const char *lookup_name, *last, *p, *scope_op; struct cleanup *cleanup; - VEC (symbolp) *classes; + char *canon; + const char *lookup_name; volatile struct gdb_exception except; cleanup = demangle_for_lookup (name, state->language->la_language, @@ -2961,78 +3116,92 @@ find_linespec_symbols (struct linespec_state *state, if (canon != NULL) { lookup_name = canon; - cleanup = make_cleanup (xfree, canon); - } - - /* See if we can find a scope operator and break this symbol - name into namespaces${SCOPE_OPERATOR}class_name and method_name. */ - scope_op = "::"; - p = find_toplevel_string (lookup_name, scope_op); - if (p == NULL) - { - /* No C++ scope operator. Try Java. */ - scope_op = "."; + make_cleanup (xfree, canon); + } + + /* It's important to not call expand_symtabs_matching unnecessarily + as it can really slow things down (by unnecessarily expanding + potentially 1000s of symtabs, which when debugging some apps can + cost 100s of seconds). Avoid this to some extent by *first* calling + find_function_symbols, and only if that doesn't find anything + *then* call find_method. This handles two important cases: + 1) break (anonymous namespace)::foo + 2) break class::method where method is in class (and not a baseclass) */ + + find_function_symbols (state, file_symtabs, lookup_name, + symbols, minsyms); + + /* If we were unable to locate a symbol of the same name, try dividing + the name into class and method names and searching the class and its + baseclasses. */ + if (VEC_empty (symbolp, *symbols) + && VEC_empty (bound_minimal_symbol_d, *minsyms)) + { + char *klass, *method; + const char *last, *p, *scope_op; + VEC (symbolp) *classes; + + /* See if we can find a scope operator and break this symbol + name into namespaces${SCOPE_OPERATOR}class_name and method_name. */ + scope_op = "::"; p = find_toplevel_string (lookup_name, scope_op); - } - - last = NULL; - while (p != NULL) - { - last = p; - p = find_toplevel_string (p + strlen (scope_op), scope_op); - } - - /* If no scope operator was found, lookup the name as a symbol. */ - if (last == NULL) - { - find_function_symbols (state, file_symtabs, lookup_name, - symbols, minsyms); - do_cleanups (cleanup); - return; - } - - /* NAME points to the class name. - LAST points to the method name. */ - klass = xmalloc ((last - lookup_name + 1) * sizeof (char)); - make_cleanup (xfree, klass); - strncpy (klass, lookup_name, last - lookup_name); - klass[last - lookup_name] = '\0'; - - /* Skip past the scope operator. */ - last += strlen (scope_op); - method = xmalloc ((strlen (last) + 1) * sizeof (char)); - make_cleanup (xfree, method); - strcpy (method, last); + if (p == NULL) + { + /* No C++ scope operator. Try Java. */ + scope_op = "."; + p = find_toplevel_string (lookup_name, scope_op); + } - /* Find a list of classes named KLASS. */ - classes = lookup_prefix_sym (state, file_symtabs, klass); - make_cleanup (VEC_cleanup (symbolp), &classes); - if (!VEC_empty (symbolp, classes)) - { - /* Now locate a list of suitable methods named METHOD. */ - TRY_CATCH (except, RETURN_MASK_ERROR) + last = NULL; + while (p != NULL) { - find_method (state, file_symtabs, klass, method, classes, - symbols, minsyms); + last = p; + p = find_toplevel_string (p + strlen (scope_op), scope_op); } - /* If successful, we're done. If NOT_FOUND_ERROR - was not thrown, rethrow the exception that we did get. - Otherwise, fall back to looking up the entire name as a symbol. - This can happen with namespace::function. */ - if (except.reason >= 0) + /* If no scope operator was found, there is nothing more we can do; + we already attempted to lookup the entire name as a symbol + and failed. */ + if (last == NULL) { do_cleanups (cleanup); return; } - else if (except.error != NOT_FOUND_ERROR) - throw_exception (except); + + /* LOOKUP_NAME points to the class name. + LAST points to the method name. */ + klass = xmalloc ((last - lookup_name + 1) * sizeof (char)); + make_cleanup (xfree, klass); + strncpy (klass, lookup_name, last - lookup_name); + klass[last - lookup_name] = '\0'; + + /* Skip past the scope operator. */ + last += strlen (scope_op); + method = xmalloc ((strlen (last) + 1) * sizeof (char)); + make_cleanup (xfree, method); + strcpy (method, last); + + /* Find a list of classes named KLASS. */ + classes = lookup_prefix_sym (state, file_symtabs, klass); + make_cleanup (VEC_cleanup (symbolp), &classes); + + if (!VEC_empty (symbolp, classes)) + { + /* Now locate a list of suitable methods named METHOD. */ + TRY_CATCH (except, RETURN_MASK_ERROR) + { + find_method (state, file_symtabs, klass, method, classes, + symbols, minsyms); + } + + /* If successful, we're done. If NOT_FOUND_ERROR + was not thrown, rethrow the exception that we did get. */ + if (except.reason < 0 && except.error != NOT_FOUND_ERROR) + throw_exception (except); + } } - /* We couldn't find a class, so we check the entire name as a symbol - instead. */ - find_function_symbols (state, file_symtabs, lookup_name, symbols, minsyms); - do_cleanups (cleanup); + do_cleanups (cleanup); } /* Return all labels named NAME in FUNCTION_SYMBOLS. Return the @@ -3044,7 +3213,7 @@ find_label_symbols (struct linespec_state *self, VEC (symbolp) **label_funcs_ret, const char *name) { int ix; - struct block *block; + const struct block *block; struct symbol *sym; struct symbol *fn_sym; VEC (symbolp) *result = NULL; @@ -3052,7 +3221,7 @@ find_label_symbols (struct linespec_state *self, if (function_symbols == NULL) { set_current_program_space (self->program_space); - block = get_search_block (NULL); + block = get_current_search_block (); for (; block && !BLOCK_FUNCTION (block); @@ -3105,7 +3274,7 @@ decode_digits_list_mode (struct linespec_state *self, gdb_assert (self->list_mode); - for (ix = 0; VEC_iterate (symtab_p, ls->file_symtabs, ix, elt); + for (ix = 0; VEC_iterate (symtab_ptr, ls->file_symtabs, ix, elt); ++ix) { /* The logic above should ensure this. */ @@ -3138,7 +3307,7 @@ decode_digits_ordinary (struct linespec_state *self, int ix; struct symtab *elt; - for (ix = 0; VEC_iterate (symtab_p, ls->file_symtabs, ix, elt); ++ix) + for (ix = 0; VEC_iterate (symtab_ptr, ls->file_symtabs, ix, elt); ++ix) { int i; VEC (CORE_ADDR) *pcs; @@ -3251,9 +3420,9 @@ minsym_found (struct linespec_state *self, struct objfile *objfile, CORE_ADDR pc; struct symtab_and_line sal; - sal = find_pc_sect_line (SYMBOL_VALUE_ADDRESS (msymbol), + sal = find_pc_sect_line (MSYMBOL_VALUE_ADDRESS (objfile, msymbol), (struct obj_section *) 0, 0); - sal.section = SYMBOL_OBJ_SECTION (msymbol); + sal.section = MSYMBOL_OBJ_SECTION (objfile, msymbol); /* The minimal symbol might point to a function descriptor; resolve it to the actual code address instead. */ @@ -3265,7 +3434,7 @@ minsym_found (struct linespec_state *self, struct objfile *objfile, skip_prologue_sal (&sal); if (maybe_add_address (self->addr_set, objfile->pspace, sal.pc)) - add_sal_to_sals (self, result, &sal, SYMBOL_NATURAL_NAME (msymbol), 0); + add_sal_to_sals (self, result, &sal, MSYMBOL_NATURAL_NAME (msymbol), 0); } /* A helper struct to pass some data through @@ -3283,7 +3452,7 @@ struct collect_minsyms int list_mode; /* The resulting symbols. */ - VEC (minsym_and_objfile_d) *msyms; + VEC (bound_minimal_symbol_d) *msyms; }; /* A helper function to classify a minimal_symbol_type according to @@ -3315,8 +3484,8 @@ classify_mtype (enum minimal_symbol_type t) static int compare_msyms (const void *a, const void *b) { - const minsym_and_objfile_d *moa = a; - const minsym_and_objfile_d *mob = b; + const bound_minimal_symbol_d *moa = a; + const bound_minimal_symbol_d *mob = b; enum minimal_symbol_type ta = MSYMBOL_TYPE (moa->minsym); enum minimal_symbol_type tb = MSYMBOL_TYPE (mob->minsym); @@ -3330,7 +3499,10 @@ static void add_minsym (struct minimal_symbol *minsym, void *d) { struct collect_minsyms *info = d; - minsym_and_objfile_d mo; + bound_minimal_symbol_d mo; + + mo.minsym = minsym; + mo.objfile = info->objfile; /* Exclude data symbols when looking for breakpoint locations. */ if (!info->list_mode) @@ -3345,19 +3517,17 @@ add_minsym (struct minimal_symbol *minsym, void *d) { /* Make sure this minsym is not a function descriptor before we decide to discard it. */ - struct gdbarch *gdbarch = info->objfile->gdbarch; + struct gdbarch *gdbarch = get_objfile_arch (info->objfile); CORE_ADDR addr = gdbarch_convert_from_func_ptr_addr - (gdbarch, SYMBOL_VALUE_ADDRESS (minsym), + (gdbarch, BMSYMBOL_VALUE_ADDRESS (mo), ¤t_target); - if (addr == SYMBOL_VALUE_ADDRESS (minsym)) + if (addr == BMSYMBOL_VALUE_ADDRESS (mo)) return; } } - mo.minsym = minsym; - mo.objfile = info->objfile; - VEC_safe_push (minsym_and_objfile_d, info->msyms, &mo); + VEC_safe_push (bound_minimal_symbol_d, info->msyms, &mo); } /* Search minimal symbols in all objfiles for NAME. If SEARCH_PSPACE @@ -3387,7 +3557,7 @@ search_minsyms_for_name (struct collect_info *info, const char *name, local.funfirstline = info->state->funfirstline; local.list_mode = info->state->list_mode; - cleanup = make_cleanup (VEC_cleanup (minsym_and_objfile_d), + cleanup = make_cleanup (VEC_cleanup (bound_minimal_symbol_d), &local.msyms); ALL_OBJFILES (objfile) @@ -3396,31 +3566,31 @@ search_minsyms_for_name (struct collect_info *info, const char *name, iterate_over_minimal_symbols (objfile, name, add_minsym, &local); } - if (!VEC_empty (minsym_and_objfile_d, local.msyms)) + if (!VEC_empty (bound_minimal_symbol_d, local.msyms)) { int classification; int ix; - minsym_and_objfile_d *item; + bound_minimal_symbol_d *item; - qsort (VEC_address (minsym_and_objfile_d, local.msyms), - VEC_length (minsym_and_objfile_d, local.msyms), - sizeof (minsym_and_objfile_d), + qsort (VEC_address (bound_minimal_symbol_d, local.msyms), + VEC_length (bound_minimal_symbol_d, local.msyms), + sizeof (bound_minimal_symbol_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); + item = VEC_index (bound_minimal_symbol_d, local.msyms, 0); classification = classify_mtype (MSYMBOL_TYPE (item->minsym)); for (ix = 0; - VEC_iterate (minsym_and_objfile_d, local.msyms, ix, item); + VEC_iterate (bound_minimal_symbol_d, local.msyms, ix, item); ++ix) { if (classify_mtype (MSYMBOL_TYPE (item->minsym)) != classification) break; - VEC_safe_push (minsym_and_objfile_d, + VEC_safe_push (bound_minimal_symbol_d, info->result.minimal_symbols, item); } } @@ -3441,7 +3611,7 @@ add_matching_symbols_to_info (const char *name, int ix; struct symtab *elt; - for (ix = 0; VEC_iterate (symtab_p, info->file_symtabs, ix, elt); ++ix) + for (ix = 0; VEC_iterate (symtab_ptr, info->file_symtabs, ix, elt); ++ix) { if (elt == NULL) { @@ -3456,9 +3626,8 @@ add_matching_symbols_to_info (const char *name, been filtered out earlier. */ gdb_assert (!SYMTAB_PSPACE (elt)->executing_startup); set_current_program_space (SYMTAB_PSPACE (elt)); - LA_ITERATE_OVER_SYMBOLS (get_search_block (elt), name, - VAR_DOMAIN, collect_symbols, - info); + iterate_over_file_blocks (elt, name, VAR_DOMAIN, + collect_symbols, info); } } }