diff options
Diffstat (limited to 'gdb/linespec.c')
-rw-r--r-- | gdb/linespec.c | 201 |
1 files changed, 101 insertions, 100 deletions
diff --git a/gdb/linespec.c b/gdb/linespec.c index d42420c..7489af0 100644 --- a/gdb/linespec.c +++ b/gdb/linespec.c @@ -35,7 +35,6 @@ #include "interps.h" #include "target.h" #include "arch-utils.h" -#include <ctype.h> #include "cli/cli-utils.h" #include "filenames.h" #include "ada-lang.h" @@ -230,7 +229,7 @@ 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 (bsym->symbol->aclass () == LOC_BLOCK || this->state->list_mode) + if (bsym->symbol->loc_class () == LOC_BLOCK || this->state->list_mode) this->result.symbols->push_back (*bsym); /* Continue iterating. */ @@ -459,7 +458,7 @@ linespec_lexer_lex_number (linespec_parser *parser, linespec_token *tokenp) ++(parser->lexer.stream); } - while (isdigit (*parser->lexer.stream)) + while (c_isdigit (*parser->lexer.stream)) { ++tokenp->data.string.length; ++(parser->lexer.stream); @@ -468,7 +467,7 @@ linespec_lexer_lex_number (linespec_parser *parser, linespec_token *tokenp) /* If the next character in the input buffer is not a space, comma, quote, or colon, this input does not represent a number. */ if (*parser->lexer.stream != '\0' - && !isspace (*parser->lexer.stream) && *parser->lexer.stream != ',' + && !c_isspace (*parser->lexer.stream) && *parser->lexer.stream != ',' && *parser->lexer.stream != ':' && !strchr (linespec_quote_characters, *parser->lexer.stream)) { @@ -512,7 +511,7 @@ linespec_lexer_lex_keyword (const char *p) if (i == FORCE_KEYWORD_INDEX && p[len] == '\0') return linespec_keywords[i]; - if (!isspace (p[len])) + if (!c_isspace (p[len])) continue; if (i == FORCE_KEYWORD_INDEX) @@ -524,7 +523,7 @@ linespec_lexer_lex_keyword (const char *p) int nextlen = strlen (linespec_keywords[j]); if (strncmp (p, linespec_keywords[j], nextlen) == 0 - && isspace (p[nextlen])) + && c_isspace (p[nextlen])) return linespec_keywords[i]; } } @@ -538,7 +537,7 @@ linespec_lexer_lex_keyword (const char *p) int nextlen = strlen (linespec_keywords[j]); if (strncmp (p, linespec_keywords[j], nextlen) == 0 - && isspace (p[nextlen])) + && c_isspace (p[nextlen])) return NULL; } } @@ -763,7 +762,7 @@ linespec_lexer_lex_string (linespec_parser *parser) while (1) { - if (isspace (*parser->lexer.stream)) + if (c_isspace (*parser->lexer.stream)) { p = skip_spaces (parser->lexer.stream); /* When we get here we know we've found something followed by @@ -841,14 +840,14 @@ linespec_lexer_lex_string (linespec_parser *parser) { const char *op = parser->lexer.stream; - while (op > start && isspace (op[-1])) + while (op > start && c_isspace (op[-1])) op--; if (op - start >= CP_OPERATOR_LEN) { op -= CP_OPERATOR_LEN; if (strncmp (op, CP_OPERATOR_STR, CP_OPERATOR_LEN) == 0 && (op == start - || !(isalnum (op[-1]) || op[-1] == '_'))) + || !(c_isalnum (op[-1]) || op[-1] == '_'))) { /* This is an operator name. Keep going. */ ++(parser->lexer.stream); @@ -1016,7 +1015,7 @@ linespec_lexer_consume_token (linespec_parser *parser) if (*parser->lexer.stream != '\0') { parser->completion_quote_char = '\0'; - parser->completion_quote_end = NULL;; + parser->completion_quote_end = NULL; } } @@ -1074,6 +1073,12 @@ add_sal_to_sals (struct linespec_state *self, struct symtab_and_line *sal, const char *symname, bool literal_canonical) { + /* We don't want two SALs with the same PC from the + same program space. */ + for (const auto &s : *sals) + if (sal->pc == s.pc && sal->pspace == s.pspace) + return; + sals->push_back (*sal); if (self->canonical) @@ -1132,14 +1137,9 @@ iterate_over_all_matching_symtabs set_current_program_space (pspace); - for (objfile *objfile : pspace->objfiles ()) + for (objfile &objfile : pspace->objfiles ()) { - objfile->expand_symtabs_matching (NULL, &lookup_name, NULL, NULL, - (SEARCH_GLOBAL_BLOCK - | SEARCH_STATIC_BLOCK), - domain); - - for (compunit_symtab *cu : objfile->compunits ()) + auto expand_callback = [&] (compunit_symtab *cu) { struct symtab *symtab = cu->primary_filetab (); @@ -1166,7 +1166,12 @@ iterate_over_all_matching_symtabs }); } } - } + + return true; + }; + + objfile.search (nullptr, &lookup_name, nullptr, expand_callback, + SEARCH_GLOBAL_BLOCK | SEARCH_STATIC_BLOCK, domain); } } } @@ -1636,7 +1641,7 @@ linespec_parse_line_offset (const char *string) else line_offset.sign = LINE_OFFSET_NONE; - if (*string != '\0' && !isdigit (*string)) + if (*string != '\0' && !c_isdigit (*string)) error (_("malformed line offset: \"%s\""), start); /* Right now, we only allow base 10 for offsets. */ @@ -2123,7 +2128,7 @@ create_sals_line_offset (struct linespec_state *self, line 16 will also result in a breakpoint in main, at line 17. */ if (!was_exact && sym != nullptr - && sym->aclass () == LOC_BLOCK + && sym->loc_class () == LOC_BLOCK && sal.pc == sym->value_block ()->entry_pc () && val.line < sym->line ()) continue; @@ -2218,7 +2223,7 @@ convert_linespec_to_sals (struct linespec_state *state, linespec *ls) if (state->funfirstline && !ls->minimal_symbols.empty () - && sym.symbol->aclass () == LOC_BLOCK) + && sym.symbol->loc_class () == LOC_BLOCK) { const CORE_ADDR addr = sym.symbol->value_block ()->entry_pc (); @@ -3355,7 +3360,7 @@ decode_compound_collector::operator () (block_symbol *bsym) struct type *t; struct symbol *sym = bsym->symbol; - if (sym->aclass () != LOC_TYPEDEF) + if (sym->loc_class () != LOC_TYPEDEF) return true; /* Continue iterating. */ t = sym->type (); @@ -3407,30 +3412,52 @@ lookup_prefix_sym (struct linespec_state *state, return collector.release_symbols (); } -/* 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. */ +/* Compare pspace A and B based on program space ID. Return 0 if equal, + 1 if A->num > B->num, -1 otherwise (modeled on strcmp). */ -static bool -compare_symbols (const block_symbol &a, const block_symbol &b) +static int +compare_pspace (const struct program_space *a, const struct program_space *b) { - uintptr_t uia, uib; + if (a->num > b->num) + return 1; - uia = (uintptr_t) a.symbol->symtab ()->compunit ()->objfile ()->pspace (); - uib = (uintptr_t) b.symbol->symtab ()->compunit ()->objfile ()->pspace (); + if (a->num < b->num) + return -1; - if (uia < uib) - return true; - if (uia > uib) - return false; + return 0; +} + +/* An std::sort comparison function for pointers. Don't use this if stable + sorting results are required. */ - uia = (uintptr_t) a.symbol; - uib = (uintptr_t) b.symbol; +static bool +compare_pointers (void *a, void *b) +{ + return (uintptr_t)a < (uintptr_t)b; +} - if (uia < uib) +/* An std::sort comparison function for symbols. The requirement is that + symbols with the same program space end up next to each other. This is for + the purpose of iterating over the symbols and doing something once for each + program space. */ + +static bool +compare_symbols (const block_symbol &a, const block_symbol &b) +{ + /* To check for same program space, we could just use a pointer comparison, + which gives unstable sorting results. While the assumption is that this + doesn't matter, play it safe and compare program space IDs instead. */ + int cmp + = compare_pspace (a.symbol->symtab ()->compunit ()->objfile ()->pspace (), + b.symbol->symtab ()->compunit ()->objfile ()->pspace ()); + if (cmp == -1) return true; + if (cmp == 1) + return false; - return false; + /* This gives unstable sorting results. We assume that this doesn't + matter. */ + return compare_pointers (a.symbol, b.symbol); } /* Like compare_symbols but for minimal symbols. */ @@ -3438,23 +3465,16 @@ compare_symbols (const block_symbol &a, const block_symbol &b) static bool compare_msymbols (const bound_minimal_symbol &a, const bound_minimal_symbol &b) { - uintptr_t uia, uib; - - uia = (uintptr_t) a.objfile->pspace (); - uib = (uintptr_t) a.objfile->pspace (); - - if (uia < uib) + /* See comment in compare_symbols for use of compare_pspace. */ + int cmp = compare_pspace (a.objfile->pspace (), a.objfile->pspace ()); + if (cmp == -1) return true; - if (uia > uib) + if (cmp == 1) return false; - uia = (uintptr_t) a.minsym; - uib = (uintptr_t) b.minsym; - - if (uia < uib) - return true; - - return false; + /* This gives unstable sorting results. We assume that this doesn't + matter. */ + return compare_pointers (a.minsym, b.minsym); } /* Look for all the matching instances of each symbol in NAMES. Only @@ -3582,43 +3602,6 @@ find_method (struct linespec_state *self, -namespace { - -/* This function object is a callback for iterate_over_symtabs, used - when collecting all matching symtabs. */ - -class symtab_collector -{ -public: - symtab_collector () = default; - - DISABLE_COPY_AND_ASSIGN (symtab_collector); - - /* Callable as a symbol_found_callback_ftype callback. */ - bool operator () (struct symtab *symtab) - { - if (m_symtab_table.insert (symtab).second) - m_symtabs.push_back (symtab); - - return false; - } - - /* Return an rvalue reference to the collected symtabs. */ - std::vector<symtab *> &&release_symtabs () - { - return std::move (m_symtabs); - } - -private: - /* The result vector of symtabs. */ - std::vector<symtab *> m_symtabs; - - /* This is used to ensure the symtabs are unique. */ - gdb::unordered_set<const symtab *> m_symtab_table; -}; - -} // namespace - /* 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. */ @@ -3627,7 +3610,17 @@ static std::vector<symtab *> collect_symtabs_from_filename (const char *file, struct program_space *search_pspace) { - symtab_collector collector; + /* The result vector of symtabs. */ + std::vector<symtab *> symtabs; + /* This is used to ensure the symtabs are unique. */ + gdb::unordered_set<const symtab *> symtab_table; + + auto collector = [&] (struct symtab *symtab) + { + if (symtab_table.insert (symtab).second) + symtabs.push_back (symtab); + return false; + }; /* Find that file's data. */ if (search_pspace == NULL) @@ -3643,7 +3636,10 @@ collect_symtabs_from_filename (const char *file, else iterate_over_symtabs (search_pspace, file, collector); - return collector.release_symtabs (); + /* It is tempting to use the unordered_dense 'extract' method here, + and remove the separate vector -- but it's unclear if ordering + matters. */ + return symtabs; } /* Return all the symtabs associated to the FILENAME. If SEARCH_PSPACE is @@ -3747,7 +3743,7 @@ find_linespec_symbols (struct linespec_state *state, if (canon != nullptr) lookup_name = canon.get (); - /* It's important to not call expand_symtabs_matching unnecessarily + /* It's important to not call search 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 @@ -4078,7 +4074,7 @@ minsym_found (struct linespec_state *self, struct objfile *objfile, symtab_and_line sal; if (is_function && want_start_sal) - sal = find_function_start_sal (func_addr, NULL, self->funfirstline); + sal = find_function_start_sal (func_addr, self->funfirstline); else { sal.objfile = objfile; @@ -4092,7 +4088,12 @@ minsym_found (struct linespec_state *self, struct objfile *objfile, sal.pspace = current_program_space; } - sal.section = msymbol->obj_section (objfile); + /* Don't use the section from the msymbol, the code above might have + adjusted FUNC_ADDR, in which case the msymbol's section might not be + the section containing FUNC_ADDR. It might not even be in the same + objfile. As the section is primarily to assist with overlay + debugging, it should reflect the SAL's pc value. */ + sal.section = find_pc_overlay (sal.pc); if (self->maybe_add_address (objfile->pspace (), sal.pc)) add_sal_to_sals (self, result, &sal, msymbol->natural_name (), false); @@ -4151,12 +4152,12 @@ search_minsyms_for_name (struct collect_info *info, set_current_program_space (pspace); - for (objfile *objfile : pspace->objfiles ()) + for (objfile &objfile : pspace->objfiles ()) { - iterate_over_minimal_symbols (objfile, name, + iterate_over_minimal_symbols (&objfile, name, [&] (struct minimal_symbol *msym) { - add_minsym (msym, objfile, nullptr, + add_minsym (msym, &objfile, nullptr, info->state->list_mode, &minsyms); return false; @@ -4295,14 +4296,14 @@ static bool symbol_to_sal (struct symtab_and_line *result, bool funfirstline, struct symbol *sym) { - if (sym->aclass () == LOC_BLOCK) + if (sym->loc_class () == LOC_BLOCK) { *result = find_function_start_sal (sym, funfirstline); return true; } else { - if (sym->aclass () == LOC_LABEL && sym->value_address () != 0) + if (sym->loc_class () == LOC_LABEL && sym->value_address () != 0) { *result = {}; result->symtab = sym->symtab (); |