X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Flinespec.c;h=84258ad007a4c243f67d96d474e4b243f606a218;hb=e98ee8c458f3a8405eb93e71b00f801b4bbe3635;hp=b2deabe3af0a1adf9d4c4ea16ddd9babc79edadb;hpb=76af0f26356580771a18c37de4ebccdfbc449356;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/linespec.c b/gdb/linespec.c index b2deabe3af..84258ad007 100644 --- a/gdb/linespec.c +++ b/gdb/linespec.c @@ -77,8 +77,9 @@ enum class linespec_complete_what KEYWORD, }; -typedef struct symbol *symbolp; -DEF_VEC_P (symbolp); +/* Typedef for unique_ptrs of vectors of symtabs. */ + +typedef std::unique_ptr> symtab_vector_up; /* An address entry is used to ensure that any given location is only added to the result a single time. It holds an address and the @@ -90,10 +91,6 @@ struct address_entry CORE_ADDR addr; }; -typedef struct bound_minimal_symbol bound_minimal_symbol_d; - -DEF_VEC_O (bound_minimal_symbol_d); - /* A linespec. Elements of this structure are filled in by a parser (either parse_linespec or some other function). The structure is then converted into SALs by convert_linespec_to_sals. */ @@ -107,20 +104,20 @@ struct linespec be NULL. If explicit.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_ptr) *file_symtabs; + std::vector *file_symtabs; /* 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 (bound_minimal_symbol_d) *minimal_symbols; + may be NULL (or empty) if no matching symbols were found. */ + std::vector *function_symbols; + std::vector *minimal_symbols; /* A structure of matching label symbols and the corresponding function symbol in which the label was found. Both may be NULL or both must be non-NULL. */ struct { - VEC (symbolp) *label_symbols; - VEC (symbolp) *function_symbols; + std::vector *label_symbols; + std::vector *function_symbols; } labels; }; typedef struct linespec *linespec_p; @@ -192,31 +189,46 @@ struct collect_info struct linespec_state *state; /* A list of symtabs to which to restrict matches. */ - VEC (symtab_ptr) *file_symtabs; + std::vector *file_symtabs; /* The result being accumulated. */ struct { - VEC (symbolp) *symbols; - VEC (bound_minimal_symbol_d) *minimal_symbols; + std::vector *symbols; + std::vector *minimal_symbols; } result; /* Possibly add a symbol to the results. */ - bool add_symbol (symbol *sym); + virtual bool add_symbol (block_symbol *bsym); }; bool -collect_info::add_symbol (symbol *sym) +collect_info::add_symbol (block_symbol *bsym) { /* In list mode, add all matching symbols, regardless of class. This allows the user to type "list a_global_variable". */ - if (SYMBOL_CLASS (sym) == LOC_BLOCK || this->state->list_mode) - VEC_safe_push (symbolp, this->result.symbols, sym); + if (SYMBOL_CLASS (bsym->symbol) == LOC_BLOCK || this->state->list_mode) + this->result.symbols->push_back (*bsym); /* Continue iterating. */ return true; } +/* Custom collect_info for symbol_searcher. */ + +struct symbol_searcher_collect_info + : collect_info +{ + bool add_symbol (block_symbol *bsym) override + { + /* Add everything. */ + this->result.symbols->push_back (*bsym); + + /* Continue iterating. */ + return true; + } +}; + /* Token types */ enum ls_token_type @@ -345,21 +357,20 @@ static std::vector decode_objc (struct linespec_state *self, linespec_p ls, const char *arg); -static VEC (symtab_ptr) *symtabs_from_filename (const char *, - struct program_space *pspace); +static symtab_vector_up symtabs_from_filename + (const char *, struct program_space *pspace); -static VEC (symbolp) *find_label_symbols (struct linespec_state *self, - VEC (symbolp) *function_symbols, - VEC (symbolp) **label_funcs_ret, - const char *name, - bool completion_mode = false); +static std::vector *find_label_symbols + (struct linespec_state *self, std::vector *function_symbols, + std::vector *label_funcs_ret, const char *name, + bool completion_mode = false); static void find_linespec_symbols (struct linespec_state *self, - VEC (symtab_ptr) *file_symtabs, + std::vector *file_symtabs, const char *name, symbol_name_match_type name_match_type, - VEC (symbolp) **symbols, - VEC (bound_minimal_symbol_d) **minsyms); + std::vector *symbols, + std::vector *minsyms); static struct line_offset linespec_parse_variable (struct linespec_state *self, @@ -378,7 +389,7 @@ static void add_all_symbol_names_from_pspace (struct collect_info *info, struct program_space *pspace, const std::vector &names, enum search_domain search_domain); -static VEC (symtab_ptr) * +static symtab_vector_up collect_symtabs_from_filename (const char *file, struct program_space *pspace); @@ -397,9 +408,10 @@ static void minsym_found (struct linespec_state *self, struct objfile *objfile, struct minimal_symbol *msymbol, std::vector *result); -static int compare_symbols (const void *a, const void *b); +static bool compare_symbols (const block_symbol &a, const block_symbol &b); -static int compare_msymbols (const void *a, const void *b); +static bool compare_msymbols (const bound_minimal_symbol &a, + const bound_minimal_symbol &b); /* Permitted quote characters for the parser. This is different from the completer's quote characters to allow backward compatibility with the @@ -1153,12 +1165,12 @@ iterate_over_all_matching_symtabs { block = BLOCKVECTOR_BLOCK (SYMTAB_BLOCKVECTOR (symtab), i); state->language->la_iterate_over_symbols - (block, lookup_name, name_domain, [&] (symbol *sym) + (block, lookup_name, name_domain, [&] (block_symbol *bsym) { /* Restrict calls to CALLBACK to symbols representing inline symbols only. */ - if (SYMBOL_INLINED (sym)) - return callback (sym); + if (SYMBOL_INLINED (bsym->symbol)) + return callback (bsym); return true; }); } @@ -1211,7 +1223,7 @@ find_methods (struct type *t, enum language t_lang, const char *name, std::vector *superclasses) { int ibase; - const char *class_name = type_name_no_tag (t); + const char *class_name = TYPE_NAME (t); /* Ignore this class if it doesn't have a name. This is ugly, but unless we figure out how to get the physname without the name of @@ -1501,8 +1513,6 @@ decode_line_2 (struct linespec_state *self, for (i = 0; i < result->size (); ++i) { const struct linespec_canonical_name *canonical; - struct decode_line_2_item *item; - std::string displayform; canonical = &self->canonical_names[i]; @@ -1556,7 +1566,7 @@ decode_line_2 (struct linespec_state *self, { prompt = "> "; } - args = command_line_input (prompt, 0, "overload-choice"); + args = command_line_input (prompt, "overload-choice"); if (args == 0 || *args == 0) error_no_arg (_("one or more choice numbers")); @@ -1765,8 +1775,9 @@ linespec_parse_basic (linespec_parser *parser) { gdb::unique_xmalloc_ptr name; linespec_token token; - VEC (symbolp) *symbols, *labels; - VEC (bound_minimal_symbol_d) *minimal_symbols; + std::vector symbols; + std::vector *labels; + std::vector minimal_symbols; /* Get the next token. */ token = linespec_lexer_lex_one (parser); @@ -1869,12 +1880,14 @@ linespec_parse_basic (linespec_parser *parser) PARSER_EXPLICIT (parser)->func_name_match_type, &symbols, &minimal_symbols); - if (symbols != NULL || minimal_symbols != NULL) + if (!symbols.empty () || !minimal_symbols.empty ()) { - PARSER_RESULT (parser)->function_symbols = symbols; - PARSER_RESULT (parser)->minimal_symbols = minimal_symbols; + PARSER_RESULT (parser)->function_symbols + = new std::vector (std::move (symbols)); + PARSER_RESULT (parser)->minimal_symbols + = new std::vector + (std::move (minimal_symbols)); PARSER_EXPLICIT (parser)->function_name = name.release (); - symbols = NULL; } else { @@ -1885,9 +1898,9 @@ linespec_parse_basic (linespec_parser *parser) if (labels != NULL) { PARSER_RESULT (parser)->labels.label_symbols = labels; - PARSER_RESULT (parser)->labels.function_symbols = symbols; + PARSER_RESULT (parser)->labels.function_symbols + = new std::vector (std::move (symbols)); PARSER_EXPLICIT (parser)->label_name = name.release (); - symbols = NULL; } else if (token.type == LSTOKEN_STRING && *LS_TOKEN_STOKEN (token).ptr == '$') @@ -1991,9 +2004,9 @@ linespec_parse_basic (linespec_parser *parser) if (labels != NULL) { PARSER_RESULT (parser)->labels.label_symbols = labels; - PARSER_RESULT (parser)->labels.function_symbols = symbols; + PARSER_RESULT (parser)->labels.function_symbols + = new std::vector (std::move (symbols)); PARSER_EXPLICIT (parser)->label_name = name.release (); - symbols = NULL; } else { @@ -2059,14 +2072,12 @@ canonicalize_linespec (struct linespec_state *state, const linespec_p ls) if (explicit_loc->function_name == NULL) { - struct symbol *s; - /* No function was specified, so add the symbol name. */ - gdb_assert (ls->labels.function_symbols != NULL - && (VEC_length (symbolp, ls->labels.function_symbols) - == 1)); - s = VEC_index (symbolp, ls->labels.function_symbols, 0); - explicit_loc->function_name = xstrdup (SYMBOL_NATURAL_NAME (s)); + gdb_assert (!ls->labels.function_symbols->empty () + && (ls->labels.function_symbols->size () == 1)); + block_symbol s = ls->labels.function_symbols->front (); + explicit_loc->function_name + = xstrdup (SYMBOL_NATURAL_NAME (s.symbol)); } } @@ -2095,8 +2106,8 @@ create_sals_line_offset (struct linespec_state *self, set_default_source_symtab_and_line uses select_source_symtab that calls us with such an argument. */ - if (VEC_length (symtab_ptr, ls->file_symtabs) == 1 - && VEC_index (symtab_ptr, ls->file_symtabs, 0) == NULL) + if (ls->file_symtabs->size () == 1 + && ls->file_symtabs->front () == nullptr) { const char *fullname; @@ -2106,10 +2117,9 @@ create_sals_line_offset (struct linespec_state *self, set_default_source_symtab_and_line (); initialize_defaults (&self->default_symtab, &self->default_line); 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, - self->search_pspace); + symtab_vector_up r = + collect_symtabs_from_filename (fullname, self->search_pspace); + ls->file_symtabs = r.release (); use_default = 1; } @@ -2196,6 +2206,7 @@ create_sals_line_offset (struct linespec_state *self, if (self->funfirstline) skip_prologue_sal (&intermediate_results[i]); + intermediate_results[i].symbol = sym; add_sal_to_sals (self, &values, &intermediate_results[i], sym ? SYMBOL_NATURAL_NAME (sym) : NULL, 0); } @@ -2224,6 +2235,7 @@ convert_address_location_to_sals (struct linespec_state *self, sal.pc = address; sal.section = find_pc_overlay (address); sal.explicit_pc = 1; + sal.symbol = find_pc_sect_containing_function (sal.pc, sal.section); std::vector sals; add_sal_to_sals (self, &sals, &sal, core_addr_to_string (address), 1); @@ -2241,18 +2253,17 @@ convert_linespec_to_sals (struct linespec_state *state, linespec_p ls) if (ls->labels.label_symbols != NULL) { /* We have just a bunch of functions/methods or labels. */ - int i; struct symtab_and_line sal; - struct symbol *sym; - for (i = 0; VEC_iterate (symbolp, ls->labels.label_symbols, i, sym); ++i) + for (const auto &sym : *ls->labels.label_symbols) { - struct program_space *pspace = SYMTAB_PSPACE (symbol_symtab (sym)); + struct program_space *pspace + = SYMTAB_PSPACE (symbol_symtab (sym.symbol)); - if (symbol_to_sal (&sal, state->funfirstline, sym) + if (symbol_to_sal (&sal, state->funfirstline, sym.symbol) && maybe_add_address (state->addr_set, pspace, sal.pc)) add_sal_to_sals (state, &sals, &sal, - SYMBOL_NATURAL_NAME (sym), 0); + SYMBOL_NATURAL_NAME (sym.symbol), 0); } } else if (ls->function_symbols != NULL || ls->minimal_symbols != NULL) @@ -2262,14 +2273,14 @@ convert_linespec_to_sals (struct linespec_state *state, linespec_p ls) { /* Sort symbols so that symbols with the same program space are next to each other. */ - qsort (VEC_address (symbolp, ls->function_symbols), - VEC_length (symbolp, ls->function_symbols), - sizeof (symbolp), compare_symbols); + std::sort (ls->function_symbols->begin (), + ls->function_symbols->end (), + compare_symbols); - struct symbol *sym; - for (int i = 0; VEC_iterate (symbolp, ls->function_symbols, i, sym); ++i) + for (const auto &sym : *ls->function_symbols) { - program_space *pspace = SYMTAB_PSPACE (symbol_symtab (sym)); + program_space *pspace + = SYMTAB_PSPACE (symbol_symtab (sym.symbol)); set_current_program_space (pspace); /* Don't skip to the first line of the function if we @@ -2280,22 +2291,33 @@ convert_linespec_to_sals (struct linespec_state *state, linespec_p ls) if (state->funfirstline && ls->minimal_symbols != NULL - && SYMBOL_CLASS (sym) == LOC_BLOCK) + && SYMBOL_CLASS (sym.symbol) == LOC_BLOCK) { const CORE_ADDR addr - = BLOCK_START (SYMBOL_BLOCK_VALUE (sym)); + = BLOCK_ENTRY_PC (SYMBOL_BLOCK_VALUE (sym.symbol)); - bound_minimal_symbol_d *elem; - for (int m = 0; - VEC_iterate (bound_minimal_symbol_d, ls->minimal_symbols, - m, elem); - ++m) + for (const auto &elem : *ls->minimal_symbols) { - if (MSYMBOL_TYPE (elem->minsym) == mst_text_gnu_ifunc - && BMSYMBOL_VALUE_ADDRESS (*elem) == addr) + if (MSYMBOL_TYPE (elem.minsym) == mst_text_gnu_ifunc + || MSYMBOL_TYPE (elem.minsym) == mst_data_gnu_ifunc) { - found_ifunc = true; - break; + CORE_ADDR msym_addr = BMSYMBOL_VALUE_ADDRESS (elem); + if (MSYMBOL_TYPE (elem.minsym) == mst_data_gnu_ifunc) + { + struct gdbarch *gdbarch + = get_objfile_arch (elem.objfile); + msym_addr + = (gdbarch_convert_from_func_ptr_addr + (gdbarch, + msym_addr, + current_top_target ())); + } + + if (msym_addr == addr) + { + found_ifunc = true; + break; + } } } } @@ -2303,10 +2325,10 @@ convert_linespec_to_sals (struct linespec_state *state, linespec_p ls) if (!found_ifunc) { symtab_and_line sal; - if (symbol_to_sal (&sal, state->funfirstline, sym) + if (symbol_to_sal (&sal, state->funfirstline, sym.symbol) && maybe_add_address (state->addr_set, pspace, sal.pc)) add_sal_to_sals (state, &sals, &sal, - SYMBOL_NATURAL_NAME (sym), 0); + SYMBOL_NATURAL_NAME (sym.symbol), 0); } } } @@ -2314,20 +2336,15 @@ 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 (bound_minimal_symbol_d, ls->minimal_symbols), - VEC_length (bound_minimal_symbol_d, ls->minimal_symbols), - sizeof (bound_minimal_symbol_d), compare_msymbols); + std::sort (ls->minimal_symbols->begin (), + ls->minimal_symbols->end (), + compare_msymbols); - bound_minimal_symbol_d *elem; - - for (int i = 0; - VEC_iterate (bound_minimal_symbol_d, ls->minimal_symbols, - i, elem); - ++i) + for (const auto &elem : *ls->minimal_symbols) { - program_space *pspace = elem->objfile->pspace; + program_space *pspace = elem.objfile->pspace; set_current_program_space (pspace); - minsym_found (state, elem->objfile, elem->minsym, &sals); + minsym_found (state, elem.objfile, elem.minsym, &sals); } } } @@ -2374,8 +2391,9 @@ convert_explicit_location_to_linespec (struct linespec_state *self, const char *label_name, struct line_offset line_offset) { - VEC (symbolp) *symbols, *labels; - VEC (bound_minimal_symbol_d) *minimal_symbols; + std::vector symbols; + std::vector *labels; + std::vector minimal_symbols; result->explicit_loc.func_name_match_type = fname_match_type; @@ -2384,7 +2402,8 @@ convert_explicit_location_to_linespec (struct linespec_state *self, TRY { result->file_symtabs - = symtabs_from_filename (source_filename, self->search_pspace); + = symtabs_from_filename (source_filename, + self->search_pspace).release (); } CATCH (except, RETURN_MASK_ERROR) { @@ -2396,7 +2415,7 @@ convert_explicit_location_to_linespec (struct linespec_state *self, else { /* A NULL entry means to use the default symtab. */ - VEC_safe_push (symtab_ptr, result->file_symtabs, NULL); + result->file_symtabs->push_back (nullptr); } if (function_name != NULL) @@ -2405,18 +2424,19 @@ convert_explicit_location_to_linespec (struct linespec_state *self, function_name, fname_match_type, &symbols, &minimal_symbols); - if (symbols == NULL && minimal_symbols == NULL) + if (symbols.empty () && minimal_symbols.empty ()) symbol_not_found_error (function_name, result->explicit_loc.source_filename); result->explicit_loc.function_name = xstrdup (function_name); - result->function_symbols = symbols; - result->minimal_symbols = minimal_symbols; + result->function_symbols + = new std::vector (std::move (symbols)); + result->minimal_symbols + = new std::vector (std::move (minimal_symbols)); } if (label_name != NULL) { - symbols = NULL; labels = find_label_symbols (self, result->function_symbols, &symbols, label_name); @@ -2426,7 +2446,8 @@ convert_explicit_location_to_linespec (struct linespec_state *self, result->explicit_loc.label_name = xstrdup (label_name); result->labels.label_symbols = labels; - result->labels.function_symbols = symbols; + result->labels.function_symbols + = new std::vector (std::move (symbols)); } if (line_offset.sign != LINE_OFFSET_UNKNOWN) @@ -2565,7 +2586,7 @@ parse_linespec (linespec_parser *parser, const char *arg, { /* A NULL entry means to use GLOBAL_DEFAULT_SYMTAB. */ if (parser->completion_tracker == NULL) - VEC_safe_push (symtab_ptr, PARSER_RESULT (parser)->file_symtabs, NULL); + PARSER_RESULT (parser)->file_symtabs->push_back (nullptr); /* User specified a convenience variable or history value. */ gdb::unique_xmalloc_ptr var = copy_token_string (token); @@ -2606,9 +2627,10 @@ parse_linespec (linespec_parser *parser, const char *arg, /* Check if the input is a filename. */ TRY { - PARSER_RESULT (parser)->file_symtabs + symtab_vector_up r = symtabs_from_filename (user_filename.get (), PARSER_STATE (parser)->search_pspace); + PARSER_RESULT (parser)->file_symtabs = r.release (); } CATCH (ex, RETURN_MASK_ERROR) { @@ -2630,7 +2652,7 @@ parse_linespec (linespec_parser *parser, const char *arg, else { /* A NULL entry means to use GLOBAL_DEFAULT_SYMTAB. */ - VEC_safe_push (symtab_ptr, PARSER_RESULT (parser)->file_symtabs, NULL); + PARSER_RESULT (parser)->file_symtabs->push_back (nullptr); } } /* If the next token is not EOI, KEYWORD, or COMMA, issue an error. */ @@ -2646,7 +2668,7 @@ parse_linespec (linespec_parser *parser, const char *arg, else { /* A NULL entry means to use GLOBAL_DEFAULT_SYMTAB. */ - VEC_safe_push (symtab_ptr, PARSER_RESULT (parser)->file_symtabs, NULL); + PARSER_RESULT (parser)->file_symtabs->push_back (nullptr); } /* Parse the rest of the linespec. */ @@ -2731,6 +2753,7 @@ linespec_parser_new (linespec_parser *parser, memset (parser, 0, sizeof (linespec_parser)); parser->lexer.current.type = LSTOKEN_CONSUMED; memset (PARSER_RESULT (parser), 0, sizeof (struct linespec)); + PARSER_RESULT (parser)->file_symtabs = new std::vector (); PARSER_EXPLICIT (parser)->func_name_match_type = symbol_name_match_type::WILD; PARSER_EXPLICIT (parser)->line_offset.sign = LINE_OFFSET_UNKNOWN; @@ -2758,20 +2781,11 @@ linespec_parser_delete (void *arg) xfree (PARSER_EXPLICIT (parser)->label_name); xfree (PARSER_EXPLICIT (parser)->function_name); - if (PARSER_RESULT (parser)->file_symtabs != NULL) - 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 (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); - - if (PARSER_RESULT (parser)->labels.function_symbols != NULL) - VEC_free (symbolp, PARSER_RESULT (parser)->labels.function_symbols); + delete PARSER_RESULT (parser)->file_symtabs; + delete PARSER_RESULT (parser)->function_symbols; + delete PARSER_RESULT (parser)->minimal_symbols; + delete PARSER_RESULT (parser)->labels.label_symbols; + delete PARSER_RESULT (parser)->labels.function_symbols; linespec_state_destructor (PARSER_STATE (parser)); } @@ -2879,7 +2893,7 @@ complete_linespec_component (linespec_parser *parser, new "quote" char. */ if (tracker.quote_char ()) { - char quote_char_str[2] = { tracker.quote_char () }; + char quote_char_str[2] = { (char) tracker.quote_char () }; fn = reconcat (fn, fn, quote_char_str, (char *) NULL); tracker.set_quote_char (':'); @@ -2904,21 +2918,22 @@ complete_label (completion_tracker &tracker, linespec_parser *parser, const char *label_name) { - VEC (symbolp) *label_function_symbols = NULL; - VEC (symbolp) *labels + std::vector label_function_symbols; + std::vector *labels = find_label_symbols (PARSER_STATE (parser), PARSER_RESULT (parser)->function_symbols, &label_function_symbols, label_name, true); - symbol *label; - for (int ix = 0; - VEC_iterate (symbolp, labels, ix, label); ++ix) + if (labels != nullptr) { - char *match = xstrdup (SYMBOL_SEARCH_NAME (label)); - tracker.add_completion (gdb::unique_xmalloc_ptr (match)); + for (const auto &label : *labels) + { + char *match = xstrdup (SYMBOL_SEARCH_NAME (label.symbol)); + tracker.add_completion (gdb::unique_xmalloc_ptr (match)); + } + delete labels; } - VEC_free (symbolp, labels); } /* See linespec.h. */ @@ -3027,15 +3042,17 @@ linespec_complete (completion_tracker &tracker, const char *text, const char *func_name = PARSER_EXPLICIT (&parser)->function_name; - VEC (symbolp) *function_symbols; - VEC (bound_minimal_symbol_d) *minimal_symbols; + std::vector function_symbols; + std::vector minimal_symbols; find_linespec_symbols (PARSER_STATE (&parser), PARSER_RESULT (&parser)->file_symtabs, func_name, match_type, &function_symbols, &minimal_symbols); - PARSER_RESULT (&parser)->function_symbols = function_symbols; - PARSER_RESULT (&parser)->minimal_symbols = minimal_symbols; + PARSER_RESULT (&parser)->function_symbols + = new std::vector (std::move (function_symbols)); + PARSER_RESULT (&parser)->minimal_symbols + = new std::vector (std::move (minimal_symbols)); complete_label (tracker, &parser, parser.completion_word); } @@ -3278,7 +3295,7 @@ decode_line_full (const struct event_location *location, int flags, if (select_mode == NULL) { - if (interp_ui_out (top_level_interpreter ())->is_mi_like_p ()) + if (top_level_interpreter ()->interp_ui_out ()->is_mi_like_p ()) select_mode = multiple_symbols_all; else select_mode = multiple_symbols_select_mode (); @@ -3428,26 +3445,25 @@ decode_objc (struct linespec_state *self, linespec_p ls, const char *arg) const char *new_argptr; info.state = self; - info.file_symtabs = NULL; - VEC_safe_push (symtab_ptr, info.file_symtabs, NULL); - struct cleanup *cleanup = make_cleanup (VEC_cleanup (symtab_ptr), - &info.file_symtabs); - info.result.symbols = NULL; - info.result.minimal_symbols = NULL; + std::vector symtabs; + symtabs.push_back (nullptr); + + info.file_symtabs = &symtabs; + + std::vector symbols; + info.result.symbols = &symbols; + std::vector minimal_symbols; + info.result.minimal_symbols = &minimal_symbols; new_argptr = find_imps (arg, &symbol_names); if (symbol_names.empty ()) - { - do_cleanups (cleanup); - return {}; - } + return {}; add_all_symbol_names_from_pspace (&info, NULL, symbol_names, FUNCTIONS_DOMAIN); std::vector values; - if (!VEC_empty (symbolp, info.result.symbols) - || !VEC_empty (bound_minimal_symbol_d, info.result.minimal_symbols)) + if (!symbols.empty () || !minimal_symbols.empty ()) { char *saved_arg; @@ -3456,8 +3472,10 @@ decode_objc (struct linespec_state *self, linespec_p ls, const char *arg) saved_arg[new_argptr - arg] = '\0'; ls->explicit_loc.function_name = xstrdup (saved_arg); - ls->function_symbols = info.result.symbols; - ls->minimal_symbols = info.result.minimal_symbols; + ls->function_symbols + = new std::vector (std::move (symbols)); + ls->minimal_symbols + = new std::vector (std::move (minimal_symbols)); values = convert_linespec_to_sals (self, ls); if (self->canonical) @@ -3482,8 +3500,6 @@ decode_objc (struct linespec_state *self, linespec_p ls, const char *arg) } } - do_cleanups (cleanup); - return values; } @@ -3496,7 +3512,6 @@ class decode_compound_collector { public: decode_compound_collector () - : m_symbols (NULL) { m_unique_syms = htab_create_alloc (1, htab_hash_pointer, htab_eq_pointer, NULL, @@ -3509,16 +3524,14 @@ public: htab_delete (m_unique_syms); } - /* Releases ownership of the collected symbols and returns them. */ - VEC (symbolp) *release_symbols () + /* Return all symbols collected. */ + std::vector release_symbols () { - VEC (symbolp) *res = m_symbols; - m_symbols = NULL; - return res; + return std::move (m_symbols); } /* Callable as a symbol_found_callback_ftype callback. */ - bool operator () (symbol *sym); + bool operator () (block_symbol *bsym); private: /* A hash table of all symbols we found. We use this to avoid @@ -3526,14 +3539,15 @@ private: htab_t m_unique_syms; /* The result vector. */ - VEC (symbolp) *m_symbols; + std::vector m_symbols; }; bool -decode_compound_collector::operator () (symbol *sym) +decode_compound_collector::operator () (block_symbol *bsym) { void **slot; struct type *t; + struct symbol *sym = bsym->symbol; if (SYMBOL_CLASS (sym) != LOC_TYPEDEF) return true; /* Continue iterating. */ @@ -3549,7 +3563,7 @@ decode_compound_collector::operator () (symbol *sym) if (!*slot) { *slot = sym; - VEC_safe_push (symbolp, m_symbols, sym); + m_symbols.push_back (*bsym); } return true; /* Continue iterating. */ @@ -3559,19 +3573,18 @@ decode_compound_collector::operator () (symbol *sym) /* Return any symbols corresponding to CLASS_NAME in FILE_SYMTABS. */ -static VEC (symbolp) * -lookup_prefix_sym (struct linespec_state *state, VEC (symtab_ptr) *file_symtabs, +static std::vector +lookup_prefix_sym (struct linespec_state *state, + std::vector *file_symtabs, const char *class_name) { - int ix; - struct symtab *elt; decode_compound_collector collector; lookup_name_info lookup_name (class_name, symbol_name_match_type::FULL); - for (ix = 0; VEC_iterate (symtab_ptr, file_symtabs, ix, elt); ++ix) + for (const auto &elt : *file_symtabs) { - if (elt == NULL) + if (elt == nullptr) { iterate_over_all_matching_symtabs (state, lookup_name, STRUCT_DOMAIN, ALL_DOMAIN, @@ -3594,64 +3607,54 @@ lookup_prefix_sym (struct linespec_state *state, VEC (symtab_ptr) *file_symtabs, return collector.release_symbols (); } -/* A qsort comparison function for symbols. The resulting order does +/* A std::sort comparison function for symbols. The resulting order does not actually matter; we just need to be able to sort them so that symbols with the same program space end up next to each other. */ -static int -compare_symbols (const void *a, const void *b) +static bool +compare_symbols (const block_symbol &a, const block_symbol &b) { - struct symbol * const *sa = (struct symbol * const*) a; - struct symbol * const *sb = (struct symbol * const*) b; uintptr_t uia, uib; - uia = (uintptr_t) SYMTAB_PSPACE (symbol_symtab (*sa)); - uib = (uintptr_t) SYMTAB_PSPACE (symbol_symtab (*sb)); + uia = (uintptr_t) SYMTAB_PSPACE (symbol_symtab (a.symbol)); + uib = (uintptr_t) SYMTAB_PSPACE (symbol_symtab (b.symbol)); if (uia < uib) - return -1; + return true; if (uia > uib) - return 1; + return false; - uia = (uintptr_t) *sa; - uib = (uintptr_t) *sb; + uia = (uintptr_t) a.symbol; + uib = (uintptr_t) b.symbol; if (uia < uib) - return -1; - if (uia > uib) - return 1; + return true; - return 0; + return false; } /* Like compare_symbols but for minimal symbols. */ -static int -compare_msymbols (const void *a, const void *b) +static bool +compare_msymbols (const bound_minimal_symbol &a, const bound_minimal_symbol &b) { - const struct bound_minimal_symbol *sa - = (const struct bound_minimal_symbol *) a; - const struct bound_minimal_symbol *sb - = (const struct bound_minimal_symbol *) b; uintptr_t uia, uib; - uia = (uintptr_t) sa->objfile->pspace; - uib = (uintptr_t) sa->objfile->pspace; + uia = (uintptr_t) a.objfile->pspace; + uib = (uintptr_t) a.objfile->pspace; if (uia < uib) - return -1; + return true; if (uia > uib) - return 1; + return false; - uia = (uintptr_t) sa->minsym; - uib = (uintptr_t) sb->minsym; + uia = (uintptr_t) a.minsym; + uib = (uintptr_t) b.minsym; if (uia < uib) - return -1; - if (uia > uib) - return 1; + return true; - return 0; + return false; } /* Look for all the matching instances of each symbol in NAMES. Only @@ -3682,7 +3685,7 @@ find_superclass_methods (std::vector &&superclasses, { std::vector new_supers; - for (struct type *t : superclasses) + for (type *t : superclasses) find_methods (t, name_lang, name, result_names, &new_supers); if (result_names->size () != old_len || new_supers.empty ()) @@ -3697,13 +3700,12 @@ find_superclass_methods (std::vector &&superclasses, in SYMBOLS (for debug symbols) and MINSYMS (for minimal symbols). */ static void -find_method (struct linespec_state *self, VEC (symtab_ptr) *file_symtabs, +find_method (struct linespec_state *self, std::vector *file_symtabs, const char *class_name, const char *method_name, - VEC (symbolp) *sym_classes, VEC (symbolp) **symbols, - VEC (bound_minimal_symbol_d) **minsyms) + std::vector *sym_classes, + std::vector *symbols, + std::vector *minsyms) { - struct symbol *sym; - int ix; size_t last_result_len; std::vector superclass_vec; std::vector result_names; @@ -3711,15 +3713,13 @@ find_method (struct linespec_state *self, VEC (symtab_ptr) *file_symtabs, /* Sort symbols so that symbols with the same program space are next to each other. */ - qsort (VEC_address (symbolp, sym_classes), - VEC_length (symbolp, sym_classes), - sizeof (symbolp), - compare_symbols); + std::sort (sym_classes->begin (), sym_classes->end (), + compare_symbols); info.state = self; info.file_symtabs = file_symtabs; - info.result.symbols = NULL; - info.result.minimal_symbols = NULL; + info.result.symbols = symbols; + info.result.minimal_symbols = minsyms; /* Iterate over all the types, looking for the names of existing methods matching METHOD_NAME. If we cannot find a direct method in a @@ -3731,10 +3731,12 @@ find_method (struct linespec_state *self, VEC (symtab_ptr) *file_symtabs, because we collect data across the program space before deciding what to do. */ last_result_len = 0; - for (ix = 0; VEC_iterate (symbolp, sym_classes, ix, sym); ++ix) + unsigned int ix = 0; + for (const auto &elt : *sym_classes) { struct type *t; struct program_space *pspace; + struct symbol *sym = elt.symbol; /* Program spaces that are executing startup should have been filtered out earlier. */ @@ -3747,10 +3749,9 @@ find_method (struct linespec_state *self, VEC (symtab_ptr) *file_symtabs, /* Handle all items from a single program space at once; and be sure not to miss the last batch. */ - if (ix == VEC_length (symbolp, sym_classes) - 1 + if (ix == sym_classes->size () - 1 || (pspace - != SYMTAB_PSPACE (symbol_symtab (VEC_index (symbolp, sym_classes, - ix + 1))))) + != SYMTAB_PSPACE (symbol_symtab (sym_classes->at (ix + 1).symbol)))) { /* If we did not find a direct implementation anywhere in this program space, consider superclasses. */ @@ -3766,16 +3767,12 @@ find_method (struct linespec_state *self, VEC (symtab_ptr) *file_symtabs, superclass_vec.clear (); last_result_len = result_names.size (); + ++ix; } } - if (!VEC_empty (symbolp, info.result.symbols) - || !VEC_empty (bound_minimal_symbol_d, info.result.minimal_symbols)) - { - *symbols = info.result.symbols; - *minsyms = info.result.minimal_symbols; - return; - } + if (!symbols->empty () || !minsyms->empty ()) + return; /* Throw an NOT_FOUND_ERROR. This will be caught by the caller and other attempts to locate the symbol will be made. */ @@ -3793,8 +3790,8 @@ class symtab_collector { public: symtab_collector () + : m_symtabs (new std::vector ()) { - m_symtabs = NULL; m_symtab_table = htab_create (1, htab_hash_pointer, htab_eq_pointer, NULL); } @@ -3809,16 +3806,14 @@ public: bool operator () (symtab *sym); /* Releases ownership of the collected symtabs and returns them. */ - VEC (symtab_ptr) *release_symtabs () + symtab_vector_up release_symtabs () { - VEC (symtab_ptr) *res = m_symtabs; - m_symtabs = NULL; - return res; + return std::move (m_symtabs); } private: /* The result vector of symtabs. */ - VEC (symtab_ptr) *m_symtabs; + symtab_vector_up m_symtabs; /* This is used to ensure the symtabs are unique. */ htab_t m_symtab_table; @@ -3833,7 +3828,7 @@ symtab_collector::operator () (struct symtab *symtab) if (!*slot) { *slot = symtab; - VEC_safe_push (symtab_ptr, m_symtabs, symtab); + m_symtabs->push_back (symtab); } return false; @@ -3841,11 +3836,11 @@ symtab_collector::operator () (struct symtab *symtab) } // namespace -/* Given a file name, return a VEC of all matching symtabs. If +/* Given a file name, return a list of all matching symtabs. If SEARCH_PSPACE is not NULL, the search is restricted to just that program space. */ -static VEC (symtab_ptr) * +static symtab_vector_up collect_symtabs_from_filename (const char *file, struct program_space *search_pspace) { @@ -3877,15 +3872,14 @@ collect_symtabs_from_filename (const char *file, /* Return all the symtabs associated to the FILENAME. If SEARCH_PSPACE is not NULL, the search is restricted to just that program space. */ -static VEC (symtab_ptr) * +static symtab_vector_up symtabs_from_filename (const char *filename, struct program_space *search_pspace) { - VEC (symtab_ptr) *result; - - result = collect_symtabs_from_filename (filename, search_pspace); + symtab_vector_up result + = collect_symtabs_from_filename (filename, search_pspace); - if (VEC_empty (symtab_ptr, result)) + if (result->empty ()) { if (!have_full_symbols () && !have_partial_symbols ()) throw_error (NOT_FOUND_ERROR, @@ -3897,23 +3891,53 @@ symtabs_from_filename (const char *filename, return result; } +/* See symtab.h. */ + +void +symbol_searcher::find_all_symbols (const std::string &name, + const struct language_defn *language, + enum search_domain search_domain, + std::vector *search_symtabs, + struct program_space *search_pspace) +{ + symbol_searcher_collect_info info; + struct linespec_state state; + + memset (&state, 0, sizeof (state)); + state.language = language; + info.state = &state; + + info.result.symbols = &m_symbols; + info.result.minimal_symbols = &m_minimal_symbols; + std::vector all_symtabs; + if (search_symtabs == nullptr) + { + all_symtabs.push_back (nullptr); + search_symtabs = &all_symtabs; + } + info.file_symtabs = search_symtabs; + + add_matching_symbols_to_info (name.c_str (), symbol_name_match_type::WILD, + search_domain, &info, search_pspace); +} + /* Look up a function symbol named NAME in symtabs FILE_SYMTABS. Matching debug symbols are returned in SYMBOLS. Matching minimal symbols are returned in MINSYMS. */ static void find_function_symbols (struct linespec_state *state, - VEC (symtab_ptr) *file_symtabs, const char *name, + std::vector *file_symtabs, const char *name, symbol_name_match_type name_match_type, - VEC (symbolp) **symbols, - VEC (bound_minimal_symbol_d) **minsyms) + std::vector *symbols, + std::vector *minsyms) { struct collect_info info; std::vector symbol_names; info.state = state; - info.result.symbols = NULL; - info.result.minimal_symbols = NULL; + info.result.symbols = symbols; + info.result.minimal_symbols = minsyms; info.file_symtabs = file_symtabs; /* Try NAME as an Objective-C selector. */ @@ -3924,22 +3948,6 @@ find_function_symbols (struct linespec_state *state, else add_matching_symbols_to_info (name, name_match_type, FUNCTIONS_DOMAIN, &info, state->search_pspace); - - if (VEC_empty (symbolp, info.result.symbols)) - { - VEC_free (symbolp, info.result.symbols); - *symbols = NULL; - } - else - *symbols = info.result.symbols; - - if (VEC_empty (bound_minimal_symbol_d, info.result.minimal_symbols)) - { - VEC_free (bound_minimal_symbol_d, info.result.minimal_symbols); - *minsyms = NULL; - } - else - *minsyms = info.result.minimal_symbols; } /* Find all symbols named NAME in FILE_SYMTABS, returning debug symbols @@ -3947,11 +3955,11 @@ find_function_symbols (struct linespec_state *state, static void find_linespec_symbols (struct linespec_state *state, - VEC (symtab_ptr) *file_symtabs, + std::vector *file_symtabs, const char *lookup_name, symbol_name_match_type name_match_type, - VEC (symbolp) **symbols, - VEC (bound_minimal_symbol_d) **minsyms) + std::vector *symbols, + std::vector *minsyms) { std::string canon = cp_canonicalize_string_no_typedefs (lookup_name); if (!canon.empty ()) @@ -3967,18 +3975,15 @@ find_linespec_symbols (struct linespec_state *state, 2) break class::method where method is in class (and not a baseclass) */ find_function_symbols (state, file_symtabs, lookup_name, - name_match_type, - symbols, minsyms); + name_match_type, 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)) + if (symbols->empty () && minsyms->empty ()) { std::string 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. */ @@ -4007,18 +4012,16 @@ find_linespec_symbols (struct linespec_state *state, method = last; /* Find a list of classes named KLASS. */ - classes = lookup_prefix_sym (state, file_symtabs, klass.c_str ()); - struct cleanup *old_chain - = make_cleanup (VEC_cleanup (symbolp), &classes); - - if (!VEC_empty (symbolp, classes)) + std::vector classes + = lookup_prefix_sym (state, file_symtabs, klass.c_str ()); + if (!classes.empty ()) { /* Now locate a list of suitable methods named METHOD. */ TRY { find_method (state, file_symtabs, klass.c_str (), method.c_str (), - classes, symbols, minsyms); + &classes, symbols, minsyms); } /* If successful, we're done. If NOT_FOUND_ERROR @@ -4030,8 +4033,6 @@ find_linespec_symbols (struct linespec_state *state, } END_CATCH } - - do_cleanups (old_chain); } } @@ -4046,8 +4047,8 @@ static void find_label_symbols_in_block (const struct block *block, const char *name, struct symbol *fn_sym, bool completion_mode, - VEC (symbolp) **result, - VEC (symbolp) **label_funcs_ret) + std::vector *result, + std::vector *label_funcs_ret) { if (completion_mode) { @@ -4064,39 +4065,43 @@ find_label_symbols_in_block (const struct block *block, SYMBOL_DOMAIN (sym), LABEL_DOMAIN) && cmp (SYMBOL_SEARCH_NAME (sym), name, name_len) == 0) { - VEC_safe_push (symbolp, *result, sym); - VEC_safe_push (symbolp, *label_funcs_ret, fn_sym); + result->push_back ({sym, block}); + label_funcs_ret->push_back ({fn_sym, block}); } } } else { - struct symbol *sym = lookup_symbol (name, block, LABEL_DOMAIN, 0).symbol; + struct block_symbol label_sym + = lookup_symbol (name, block, LABEL_DOMAIN, 0); - if (sym != NULL) + if (label_sym.symbol != NULL) { - VEC_safe_push (symbolp, *result, sym); - VEC_safe_push (symbolp, *label_funcs_ret, fn_sym); + result->push_back (label_sym); + label_funcs_ret->push_back ({fn_sym, block}); } } } -/* Return all labels that match name NAME in FUNCTION_SYMBOLS. Return - the actual function symbol in which the label was found in +/* Return all labels that match name NAME in FUNCTION_SYMBOLS or NULL + if no matches were found. + + Return the actual function symbol in which the label was found in LABEL_FUNC_RET. If COMPLETION_MODE is true, then NAME is interpreted as a label name prefix. Otherwise, only labels named exactly NAME match. */ -static VEC (symbolp) * + +static std::vector * find_label_symbols (struct linespec_state *self, - VEC (symbolp) *function_symbols, - VEC (symbolp) **label_funcs_ret, const char *name, + std::vector *function_symbols, + std::vector *label_funcs_ret, + const char *name, bool completion_mode) { - int ix; const struct block *block; struct symbol *fn_sym; - VEC (symbolp) *result = NULL; + std::vector result; if (function_symbols == NULL) { @@ -4116,9 +4121,9 @@ find_label_symbols (struct linespec_state *self, } else { - for (ix = 0; - VEC_iterate (symbolp, function_symbols, ix, fn_sym); ++ix) + for (const auto &elt : *function_symbols) { + fn_sym = elt.symbol; set_current_program_space (SYMTAB_PSPACE (symbol_symtab (fn_sym))); block = SYMBOL_BLOCK_VALUE (fn_sym); @@ -4127,7 +4132,9 @@ find_label_symbols (struct linespec_state *self, } } - return result; + if (!result.empty ()) + return new std::vector (std::move (result)); + return nullptr; } @@ -4139,15 +4146,11 @@ decode_digits_list_mode (struct linespec_state *self, linespec_p ls, struct symtab_and_line val) { - int ix; - struct symtab *elt; - gdb_assert (self->list_mode); std::vector values; - for (ix = 0; VEC_iterate (symtab_ptr, ls->file_symtabs, ix, elt); - ++ix) + for (const auto &elt : *ls->file_symtabs) { /* The logic above should ensure this. */ gdb_assert (elt != NULL); @@ -4177,11 +4180,8 @@ decode_digits_ordinary (struct linespec_state *self, int line, struct linetable_entry **best_entry) { - int ix; - struct symtab *elt; - std::vector sals; - for (ix = 0; VEC_iterate (symtab_ptr, ls->file_symtabs, ix, elt); ++ix) + for (const auto &elt : *ls->file_symtabs) { std::vector pcs; @@ -4283,7 +4283,8 @@ minsym_found (struct linespec_state *self, struct objfile *objfile, { const char *msym_name = MSYMBOL_LINKAGE_NAME (msymbol); - if (MSYMBOL_TYPE (msymbol) == mst_text_gnu_ifunc) + if (MSYMBOL_TYPE (msymbol) == mst_text_gnu_ifunc + || MSYMBOL_TYPE (msymbol) == mst_data_gnu_ifunc) want_start_sal = gnu_ifunc_resolve_name (msym_name, &func_addr); else want_start_sal = true; @@ -4292,25 +4293,7 @@ minsym_found (struct linespec_state *self, struct objfile *objfile, symtab_and_line sal; if (is_function && want_start_sal) - { - sal = find_pc_sect_line (func_addr, NULL, 0); - - if (self->funfirstline) - { - if (sal.symtab != NULL - && (COMPUNIT_LOCATIONS_VALID (SYMTAB_COMPUNIT (sal.symtab)) - || SYMTAB_LANGUAGE (sal.symtab) == language_asm)) - { - struct gdbarch *gdbarch = get_objfile_arch (objfile); - - sal.pc = func_addr; - if (gdbarch_skip_entrypoint_p (gdbarch)) - sal.pc = gdbarch_skip_entrypoint (gdbarch, sal.pc); - } - else - skip_prologue_sal (&sal); - } - } + sal = find_function_start_sal (func_addr, NULL, self->funfirstline); else { sal.objfile = objfile; @@ -4466,13 +4449,12 @@ search_minsyms_for_name (struct collect_info *info, classification as the very first minsym in the list. */ classification = classify_mtype (MSYMBOL_TYPE (minsyms[0].minsym)); - for (const struct bound_minimal_symbol &item : minsyms) + for (const bound_minimal_symbol &item : minsyms) { if (classify_mtype (MSYMBOL_TYPE (item.minsym)) != classification) break; - VEC_safe_push (bound_minimal_symbol_d, - info->result.minimal_symbols, &item); + info->result.minimal_symbols->push_back (item); } } } @@ -4488,38 +4470,36 @@ add_matching_symbols_to_info (const char *name, struct collect_info *info, struct program_space *pspace) { - int ix; - struct symtab *elt; - lookup_name_info lookup_name (name, name_match_type); - for (ix = 0; VEC_iterate (symtab_ptr, info->file_symtabs, ix, elt); ++ix) + for (const auto &elt : *info->file_symtabs) { - if (elt == NULL) + if (elt == nullptr) { iterate_over_all_matching_symtabs (info->state, lookup_name, VAR_DOMAIN, search_domain, - pspace, true, [&] (symbol *sym) - { return info->add_symbol (sym); }); + pspace, true, + [&] (block_symbol *bsym) + { return info->add_symbol (bsym); }); search_minsyms_for_name (info, lookup_name, pspace, NULL); } else if (pspace == NULL || pspace == SYMTAB_PSPACE (elt)) { - int prev_len = VEC_length (symbolp, info->result.symbols); + int prev_len = info->result.symbols->size (); /* 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)); iterate_over_file_blocks (elt, lookup_name, VAR_DOMAIN, - [&] (symbol *sym) - { return info->add_symbol (sym); }); + [&] (block_symbol *bsym) + { return info->add_symbol (bsym); }); /* If no new symbols were found in this iteration and this symtab is in assembler, we might actually be looking for a label for which we don't have debug info. Check for a minimal symbol in this case. */ - if (prev_len == VEC_length (symbolp, info->result.symbols) + if (prev_len == info->result.symbols->size () && elt->language == language_asm) search_minsyms_for_name (info, lookup_name, pspace, elt); }