X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Flinespec.c;h=8a2c8e35ed19460ddd0cb4a51c079c578856ae36;hb=b67a2c6fd4862b79c04c254fe2ba37c180b73d60;hp=2f2a1a391045ea2d331a3da824990f396e6db8b1;hpb=ec94af83262061ee559ed6a7d575dd6d81cda3af;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/linespec.c b/gdb/linespec.c index 2f2a1a3910..8a2c8e35ed 100644 --- a/gdb/linespec.c +++ b/gdb/linespec.c @@ -1,6 +1,6 @@ /* Parser for linespec for the GNU debugger, GDB. - Copyright (C) 1986-2013 Free Software Foundation, Inc. + Copyright (C) 1986-2014 Free Software Foundation, Inc. This file is part of GDB. @@ -61,16 +61,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 @@ -132,7 +125,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. */ @@ -220,7 +213,7 @@ struct collect_info struct { VEC (symbolp) *symbols; - VEC (minsym_and_objfile_d) *minimal_symbols; + VEC (bound_minimal_symbol_d) *minimal_symbols; } result; }; @@ -285,10 +278,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. */ @@ -327,7 +320,7 @@ 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_ptr) *symtabs_from_filename (const char *); @@ -340,7 +333,7 @@ static void find_linespec_symbols (struct linespec_state *self, VEC (symtab_ptr) *file_symtabs, const char *name, VEC (symbolp) **symbols, - VEC (minsym_and_objfile_d) **minsyms); + VEC (bound_minimal_symbol_d) **minsyms); static struct line_offset linespec_parse_variable (struct linespec_state *self, @@ -522,12 +515,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 == '(') @@ -564,7 +557,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; @@ -614,7 +607,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, @@ -628,7 +621,7 @@ 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, @@ -688,7 +681,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) @@ -740,7 +733,7 @@ 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, they end the linespec. */ keyword = NULL; @@ -826,7 +819,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); @@ -892,7 +885,7 @@ add_sal_to_sals (struct linespec_state *self, if (symname != NULL) canonical->suffix = xstrdup (symname); else - canonical->suffix = NULL; + canonical->suffix = xstrdup (""); canonical->symtab = NULL; } } @@ -1065,10 +1058,10 @@ iterate_over_all_matching_symtabs (struct linespec_state *state, /* Returns the block to be used for symbol searches from the current location. */ -static struct block * +static const struct block * get_current_search_block (void) { - struct block *block; + const struct block *block; enum language save_language; /* get_selected_block can change the current language when there is @@ -1587,7 +1580,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. */ @@ -1646,7 +1639,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) @@ -1657,6 +1650,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 @@ -1884,7 +1897,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; @@ -1912,7 +1925,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) @@ -1996,7 +2009,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); } @@ -2007,7 +2023,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) @@ -2032,12 +2048,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; @@ -2131,7 +2148,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; @@ -2388,7 +2405,7 @@ linespec_parser_delete (void *arg) 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); @@ -2413,6 +2430,7 @@ decode_line_full (char **argptr, int flags, 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'. */ @@ -2428,7 +2446,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); @@ -2483,13 +2503,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; @@ -2589,12 +2612,12 @@ linespec_expression_to_pc (const 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); @@ -2617,7 +2640,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; @@ -2775,8 +2798,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; @@ -2853,7 +2876,7 @@ static void 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); @@ -2926,7 +2949,7 @@ find_method (struct linespec_state *self, VEC (symtab_ptr) *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; @@ -3027,7 +3050,7 @@ static void find_function_symbols (struct linespec_state *state, 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; @@ -3040,7 +3063,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 @@ -3056,9 +3079,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 @@ -3073,7 +3096,7 @@ find_linespec_symbols (struct linespec_state *state, VEC (symtab_ptr) *file_symtabs, const char *name, VEC (symbolp) **symbols, - VEC (minsym_and_objfile_d) **minsyms) + VEC (bound_minimal_symbol_d) **minsyms) { struct cleanup *cleanup; char *canon; @@ -3113,7 +3136,7 @@ find_linespec_symbols (struct linespec_state *state, the name into class and method names and searching the class and its baseclasses. */ if (VEC_empty (symbolp, *symbols) - && VEC_empty (minsym_and_objfile_d, *minsyms)) + && VEC_empty (bound_minimal_symbol_d, *minsyms)) { char *klass, *method; const char *last, *p, *scope_op; @@ -3191,7 +3214,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; @@ -3398,9 +3421,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 (objfile, 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. */ @@ -3412,7 +3435,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 @@ -3430,7 +3453,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 @@ -3462,8 +3485,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); @@ -3477,7 +3500,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) @@ -3492,19 +3518,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 @@ -3534,7 +3558,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) @@ -3543,31 +3567,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); } }