X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fsymtab.c;h=a082ee21a90898cc3f1b3310940175ccf12fceac;hb=c1b5c1ebc938b6dc0277363b8c47d75b0b5a621f;hp=5c33fbf9ab742371ac8ac6ac952484ee278c36ab;hpb=82f910ea9cce04b0faabfcd022d9d8949567541e;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/symtab.c b/gdb/symtab.c index 5c33fbf9ab..a082ee21a9 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -675,7 +675,7 @@ symbol_set_demangled_name (struct general_symbol_info *gsymbol, const char *name, struct obstack *obstack) { - if (gsymbol->language == language_ada) + if (gsymbol->language () == language_ada) { if (name == NULL) { @@ -697,7 +697,7 @@ symbol_set_demangled_name (struct general_symbol_info *gsymbol, const char * symbol_get_demangled_name (const struct general_symbol_info *gsymbol) { - if (gsymbol->language == language_ada) + if (gsymbol->language () == language_ada) { if (!gsymbol->ada_mangled) return NULL; @@ -716,16 +716,16 @@ symbol_set_language (struct general_symbol_info *gsymbol, enum language language, struct obstack *obstack) { - gsymbol->language = language; - if (gsymbol->language == language_cplus - || gsymbol->language == language_d - || gsymbol->language == language_go - || gsymbol->language == language_objc - || gsymbol->language == language_fortran) + gsymbol->m_language = language; + if (language == language_cplus + || language == language_d + || language == language_go + || language == language_objc + || language == language_fortran) { symbol_set_demangled_name (gsymbol, NULL, obstack); } - else if (gsymbol->language == language_ada) + else if (language == language_ada) { gdb_assert (gsymbol->ada_mangled == 0); gsymbol->language_specific.obstack = obstack; @@ -819,12 +819,12 @@ symbol_find_demangled_name (struct general_symbol_info *gsymbol, char *demangled = NULL; int i; - if (gsymbol->language == language_unknown) - gsymbol->language = language_auto; + if (gsymbol->language () == language_unknown) + gsymbol->m_language = language_auto; - if (gsymbol->language != language_auto) + if (gsymbol->language () != language_auto) { - const struct language_defn *lang = language_def (gsymbol->language); + const struct language_defn *lang = language_def (gsymbol->language ()); language_sniff_from_mangled_name (lang, mangled, &demangled); return demangled; @@ -837,7 +837,7 @@ symbol_find_demangled_name (struct general_symbol_info *gsymbol, if (language_sniff_from_mangled_name (lang, mangled, &demangled)) { - gsymbol->language = l; + gsymbol->m_language = l; return demangled; } } @@ -864,7 +864,7 @@ symbol_set_names (struct general_symbol_info *gsymbol, { struct demangled_name_entry **slot; - if (gsymbol->language == language_ada) + if (gsymbol->language () == language_ada) { /* In Ada, we do the symbol lookups using the mangled name, so we can save some space by not storing the demangled name. */ @@ -898,7 +898,7 @@ symbol_set_names (struct general_symbol_info *gsymbol, if (*slot == NULL /* A C version of the symbol may have already snuck into the table. This happens to, e.g., main.init (__go_init_main). Cope. */ - || (gsymbol->language == language_go && (*slot)->demangled == nullptr)) + || (gsymbol->language () == language_go && (*slot)->demangled == nullptr)) { /* A 0-terminated copy of the linkage name. Callers must set COPY_NAME to true if the string might not be nullterminated. We have to make @@ -959,11 +959,11 @@ symbol_set_names (struct general_symbol_info *gsymbol, (gdb::string_view (mangled_ptr, linkage_name.length ())); } (*slot)->demangled = std::move (demangled_name); - (*slot)->language = gsymbol->language; + (*slot)->language = gsymbol->language (); } - else if (gsymbol->language == language_unknown - || gsymbol->language == language_auto) - gsymbol->language = (*slot)->language; + else if (gsymbol->language () == language_unknown + || gsymbol->language () == language_auto) + gsymbol->m_language = (*slot)->language; gsymbol->name = (*slot)->mangled.data (); if ((*slot)->demangled != nullptr) @@ -978,7 +978,7 @@ symbol_set_names (struct general_symbol_info *gsymbol, const char * general_symbol_info::natural_name () const { - switch (language) + switch (language ()) { case language_cplus: case language_d: @@ -1003,7 +1003,7 @@ general_symbol_info::demangled_name () const { const char *dem_name = NULL; - switch (language) + switch (language ()) { case language_cplus: case language_d: @@ -1026,7 +1026,7 @@ general_symbol_info::demangled_name () const const char * general_symbol_info::search_name () const { - if (language == language_ada) + if (language () == language_ada) return name; else return natural_name (); @@ -1039,7 +1039,7 @@ symbol_matches_search_name (const struct general_symbol_info *gsymbol, const lookup_name_info &name) { symbol_name_matcher_ftype *name_match - = get_symbol_name_matcher (language_def (gsymbol->language), name); + = get_symbol_name_matcher (language_def (gsymbol->language ()), name); return name_match (gsymbol->search_name (), name, NULL); } @@ -1219,8 +1219,7 @@ eq_symbol_entry (const struct symbol_cache_slot *slot, if (!SYMBOL_MATCHES_SEARCH_NAME (sym, lookup_name)) return 0; - if (!symbol_matches_domain (SYMBOL_LANGUAGE (sym), - slot_domain, domain)) + if (!symbol_matches_domain (sym->language (), slot_domain, domain)) return 0; } } @@ -2846,8 +2845,7 @@ iterate_over_symbols (const struct block *block, ALL_BLOCK_SYMBOLS_WITH_NAME (block, name, iter, sym) { - if (symbol_matches_domain (SYMBOL_LANGUAGE (sym), - SYMBOL_DOMAIN (sym), domain)) + if (symbol_matches_domain (sym->language (), SYMBOL_DOMAIN (sym), domain)) { struct block_symbol block_sym = {sym, block}; @@ -4383,8 +4381,8 @@ file_matches (const char *file, const std::vector &filenames, return false; } -/* Helper function for sort_search_symbols_remove_dups and qsort. Can only - sort symbols, not minimal symbols. */ +/* Helper function for std::sort on symbol_search objects. Can only sort + symbols, not minimal symbols. */ int symbol_search::compare_search_syms (const symbol_search &sym_a, @@ -4445,15 +4443,233 @@ treg_matches_sym_type_name (const compiled_regex &treg, return treg.exec (printed_sym_type_name.c_str (), 0, NULL, 0) == 0; } +/* See symtab.h. */ + +bool +global_symbol_searcher::is_suitable_msymbol + (const enum search_domain kind, const minimal_symbol *msymbol) +{ + switch (MSYMBOL_TYPE (msymbol)) + { + case mst_data: + case mst_bss: + case mst_file_data: + case mst_file_bss: + return kind == VARIABLES_DOMAIN; + case mst_text: + case mst_file_text: + case mst_solib_trampoline: + case mst_text_gnu_ifunc: + return kind == FUNCTIONS_DOMAIN; + default: + return false; + } +} -/* Sort the symbols in RESULT and remove duplicates. */ +/* See symtab.h. */ -static void -sort_search_symbols_remove_dups (std::vector *result) +bool +global_symbol_searcher::expand_symtabs + (objfile *objfile, const gdb::optional &preg) const +{ + enum search_domain kind = m_kind; + bool found_msymbol = false; + + if (objfile->sf) + objfile->sf->qf->expand_symtabs_matching + (objfile, + [&] (const char *filename, bool basenames) + { + return file_matches (filename, filenames, basenames); + }, + lookup_name_info::match_any (), + [&] (const char *symname) + { + return (!preg.has_value () + || preg->exec (symname, 0, NULL, 0) == 0); + }, + NULL, + kind); + + /* Here, we search through the minimal symbol tables for functions and + variables that match, and force their symbols to be read. This is in + particular necessary for demangled variable names, which are no longer + put into the partial symbol tables. The symbol will then be found + during the scan of symtabs later. + + For functions, find_pc_symtab should succeed if we have debug info for + the function, for variables we have to call + lookup_symbol_in_objfile_from_linkage_name to determine if the + variable has debug info. If the lookup fails, set found_msymbol so + that we will rescan to print any matching symbols without debug info. + We only search the objfile the msymbol came from, we no longer search + all objfiles. In large programs (1000s of shared libs) searching all + objfiles is not worth the pain. */ + if (filenames.empty () + && (kind == VARIABLES_DOMAIN || kind == FUNCTIONS_DOMAIN)) + { + for (minimal_symbol *msymbol : objfile->msymbols ()) + { + QUIT; + + if (msymbol->created_by_gdb) + continue; + + if (is_suitable_msymbol (kind, msymbol)) + { + if (!preg.has_value () + || preg->exec (msymbol->natural_name (), 0, + NULL, 0) == 0) + { + /* An important side-effect of these lookup functions is + to expand the symbol table if msymbol is found, later + in the process we will add matching symbols or + msymbols to the results list, and that requires that + the symbols tables are expanded. */ + if (kind == FUNCTIONS_DOMAIN + ? (find_pc_compunit_symtab + (MSYMBOL_VALUE_ADDRESS (objfile, msymbol)) + == NULL) + : (lookup_symbol_in_objfile_from_linkage_name + (objfile, msymbol->linkage_name (), + VAR_DOMAIN) + .symbol == NULL)) + found_msymbol = true; + } + } + } + } + + return found_msymbol; +} + +/* See symtab.h. */ + +bool +global_symbol_searcher::add_matching_symbols + (objfile *objfile, + const gdb::optional &preg, + const gdb::optional &treg, + std::set *result_set) const { - std::sort (result->begin (), result->end ()); - result->erase (std::unique (result->begin (), result->end ()), - result->end ()); + enum search_domain kind = m_kind; + + /* Add matching symbols (if not already present). */ + for (compunit_symtab *cust : objfile->compunits ()) + { + const struct blockvector *bv = COMPUNIT_BLOCKVECTOR (cust); + + for (block_enum block : { GLOBAL_BLOCK, STATIC_BLOCK }) + { + struct block_iterator iter; + struct symbol *sym; + const struct block *b = BLOCKVECTOR_BLOCK (bv, block); + + ALL_BLOCK_SYMBOLS (b, iter, sym) + { + struct symtab *real_symtab = symbol_symtab (sym); + + QUIT; + + /* Check first sole REAL_SYMTAB->FILENAME. It does + not need to be a substring of symtab_to_fullname as + it may contain "./" etc. */ + if ((file_matches (real_symtab->filename, filenames, false) + || ((basenames_may_differ + || file_matches (lbasename (real_symtab->filename), + filenames, true)) + && file_matches (symtab_to_fullname (real_symtab), + filenames, false))) + && ((!preg.has_value () + || preg->exec (sym->natural_name (), 0, + NULL, 0) == 0) + && ((kind == VARIABLES_DOMAIN + && SYMBOL_CLASS (sym) != LOC_TYPEDEF + && SYMBOL_CLASS (sym) != LOC_UNRESOLVED + && SYMBOL_CLASS (sym) != LOC_BLOCK + /* LOC_CONST can be used for more than + just enums, e.g., c++ static const + members. We only want to skip enums + here. */ + && !(SYMBOL_CLASS (sym) == LOC_CONST + && (TYPE_CODE (SYMBOL_TYPE (sym)) + == TYPE_CODE_ENUM)) + && (!treg.has_value () + || treg_matches_sym_type_name (*treg, sym))) + || (kind == FUNCTIONS_DOMAIN + && SYMBOL_CLASS (sym) == LOC_BLOCK + && (!treg.has_value () + || treg_matches_sym_type_name (*treg, + sym))) + || (kind == TYPES_DOMAIN + && SYMBOL_CLASS (sym) == LOC_TYPEDEF + && SYMBOL_DOMAIN (sym) != MODULE_DOMAIN) + || (kind == MODULES_DOMAIN + && SYMBOL_DOMAIN (sym) == MODULE_DOMAIN + && SYMBOL_LINE (sym) != 0)))) + { + if (result_set->size () < m_max_search_results) + { + /* Match, insert if not already in the results. */ + symbol_search ss (block, sym); + if (result_set->find (ss) == result_set->end ()) + result_set->insert (ss); + } + else + return false; + } + } + } + } + + return true; +} + +/* See symtab.h. */ + +bool +global_symbol_searcher::add_matching_msymbols + (objfile *objfile, const gdb::optional &preg, + std::vector *results) const +{ + enum search_domain kind = m_kind; + + for (minimal_symbol *msymbol : objfile->msymbols ()) + { + QUIT; + + if (msymbol->created_by_gdb) + continue; + + if (is_suitable_msymbol (kind, msymbol)) + { + if (!preg.has_value () + || preg->exec (msymbol->natural_name (), 0, + NULL, 0) == 0) + { + /* For functions we can do a quick check of whether the + symbol might be found via find_pc_symtab. */ + if (kind != FUNCTIONS_DOMAIN + || (find_pc_compunit_symtab + (MSYMBOL_VALUE_ADDRESS (objfile, msymbol)) + == NULL)) + { + if (lookup_symbol_in_objfile_from_linkage_name + (objfile, msymbol->linkage_name (), + VAR_DOMAIN).symbol == NULL) + { + /* Matching msymbol, add it to the results list. */ + if (results->size () < m_max_search_results) + results->emplace_back (GLOBAL_BLOCK, msymbol, objfile); + else + return false; + } + } + } + } + } + + return true; } /* See symtab.h. */ @@ -4461,35 +4677,11 @@ sort_search_symbols_remove_dups (std::vector *result) std::vector global_symbol_searcher::search () const { - const struct blockvector *bv; - const struct block *b; - int i = 0; - struct block_iterator iter; - struct symbol *sym; - int found_misc = 0; - static const enum minimal_symbol_type types[] - = {mst_data, mst_text, mst_unknown}; - static const enum minimal_symbol_type types2[] - = {mst_bss, mst_file_text, mst_unknown}; - static const enum minimal_symbol_type types3[] - = {mst_file_data, mst_solib_trampoline, mst_unknown}; - static const enum minimal_symbol_type types4[] - = {mst_file_bss, mst_text_gnu_ifunc, mst_unknown}; - enum minimal_symbol_type ourtype; - enum minimal_symbol_type ourtype2; - enum minimal_symbol_type ourtype3; - enum minimal_symbol_type ourtype4; - std::vector result; gdb::optional preg; gdb::optional treg; gdb_assert (m_kind != ALL_DOMAIN); - ourtype = types[m_kind]; - ourtype2 = types2[m_kind]; - ourtype3 = types3[m_kind]; - ourtype4 = types4[m_kind]; - if (m_symbol_name_regexp != NULL) { const char *symbol_name_regexp = m_symbol_name_regexp; @@ -4542,187 +4734,38 @@ global_symbol_searcher::search () const _("Invalid regexp")); } - /* Search through the partial symtabs *first* for all symbols matching - the m_symbol_name_regexp (in preg). That way we don't have to - reproduce all of the machinery below. */ - expand_symtabs_matching ([&] (const char *filename, bool basenames) - { - return file_matches (filename, filenames, - basenames); - }, - lookup_name_info::match_any (), - [&] (const char *symname) - { - return (!preg.has_value () - || preg->exec (symname, - 0, NULL, 0) == 0); - }, - NULL, - m_kind); - - /* Here, we search through the minimal symbol tables for functions - and variables that match, and force their symbols to be read. - This is in particular necessary for demangled variable names, - which are no longer put into the partial symbol tables. - The symbol will then be found during the scan of symtabs below. - - For functions, find_pc_symtab should succeed if we have debug info - for the function, for variables we have to call - lookup_symbol_in_objfile_from_linkage_name to determine if the variable - has debug info. - If the lookup fails, set found_misc so that we will rescan to print - any matching symbols without debug info. - We only search the objfile the msymbol came from, we no longer search - all objfiles. In large programs (1000s of shared libs) searching all - objfiles is not worth the pain. */ - - if (filenames.empty () && (m_kind == VARIABLES_DOMAIN - || m_kind == FUNCTIONS_DOMAIN)) - { - for (objfile *objfile : current_program_space->objfiles ()) - { - for (minimal_symbol *msymbol : objfile->msymbols ()) - { - QUIT; - - if (msymbol->created_by_gdb) - continue; - - if (MSYMBOL_TYPE (msymbol) == ourtype - || MSYMBOL_TYPE (msymbol) == ourtype2 - || MSYMBOL_TYPE (msymbol) == ourtype3 - || MSYMBOL_TYPE (msymbol) == ourtype4) - { - if (!preg.has_value () - || preg->exec (msymbol->natural_name (), 0, - NULL, 0) == 0) - { - /* Note: An important side-effect of these - lookup functions is to expand the symbol - table if msymbol is found, for the benefit of - the next loop on compunits. */ - if (m_kind == FUNCTIONS_DOMAIN - ? (find_pc_compunit_symtab - (MSYMBOL_VALUE_ADDRESS (objfile, msymbol)) - == NULL) - : (lookup_symbol_in_objfile_from_linkage_name - (objfile, msymbol->linkage_name (), VAR_DOMAIN) - .symbol == NULL)) - found_misc = 1; - } - } - } - } - } - + bool found_msymbol = false; + std::set result_set; for (objfile *objfile : current_program_space->objfiles ()) { - for (compunit_symtab *cust : objfile->compunits ()) - { - bv = COMPUNIT_BLOCKVECTOR (cust); - for (i = GLOBAL_BLOCK; i <= STATIC_BLOCK; i++) - { - b = BLOCKVECTOR_BLOCK (bv, i); - ALL_BLOCK_SYMBOLS (b, iter, sym) - { - struct symtab *real_symtab = symbol_symtab (sym); - - QUIT; - - /* Check first sole REAL_SYMTAB->FILENAME. It does - not need to be a substring of symtab_to_fullname as - it may contain "./" etc. */ - if ((file_matches (real_symtab->filename, filenames, false) - || ((basenames_may_differ - || file_matches (lbasename (real_symtab->filename), - filenames, true)) - && file_matches (symtab_to_fullname (real_symtab), - filenames, false))) - && ((!preg.has_value () - || preg->exec (sym->natural_name (), 0, - NULL, 0) == 0) - && ((m_kind == VARIABLES_DOMAIN - && SYMBOL_CLASS (sym) != LOC_TYPEDEF - && SYMBOL_CLASS (sym) != LOC_UNRESOLVED - && SYMBOL_CLASS (sym) != LOC_BLOCK - /* LOC_CONST can be used for more than - just enums, e.g., c++ static const - members. We only want to skip enums - here. */ - && !(SYMBOL_CLASS (sym) == LOC_CONST - && (TYPE_CODE (SYMBOL_TYPE (sym)) - == TYPE_CODE_ENUM)) - && (!treg.has_value () - || treg_matches_sym_type_name (*treg, sym))) - || (m_kind == FUNCTIONS_DOMAIN - && SYMBOL_CLASS (sym) == LOC_BLOCK - && (!treg.has_value () - || treg_matches_sym_type_name (*treg, - sym))) - || (m_kind == TYPES_DOMAIN - && SYMBOL_CLASS (sym) == LOC_TYPEDEF - && SYMBOL_DOMAIN (sym) != MODULE_DOMAIN) - || (m_kind == MODULES_DOMAIN - && SYMBOL_DOMAIN (sym) == MODULE_DOMAIN - && SYMBOL_LINE (sym) != 0)))) - { - /* match */ - result.emplace_back (i, sym); - } - } - } - } + /* Expand symtabs within objfile that possibly contain matching + symbols. */ + found_msymbol |= expand_symtabs (objfile, preg); + + /* Find matching symbols within OBJFILE and add them in to the + RESULT_SET set. Use a set here so that we can easily detect + duplicates as we go, and can therefore track how many unique + matches we have found so far. */ + if (!add_matching_symbols (objfile, preg, treg, &result_set)) + break; } - if (!result.empty ()) - sort_search_symbols_remove_dups (&result); + /* Convert the result set into a sorted result list, as std::set is + defined to be sorted then no explicit call to std::sort is needed. */ + std::vector result (result_set.begin (), result_set.end ()); /* If there are no debug symbols, then add matching minsyms. But if the - user wants to see symbols matching a type m_symbol_type_regexp, then - never give a minimal symbol, as we assume that a minimal symbol does - not have a type. */ - - if ((found_misc || (filenames.empty () && m_kind != FUNCTIONS_DOMAIN)) + user wants to see symbols matching a type regexp, then never give a + minimal symbol, as we assume that a minimal symbol does not have a + type. */ + if ((found_msymbol || (filenames.empty () && m_kind == VARIABLES_DOMAIN)) && !m_exclude_minsyms && !treg.has_value ()) { + gdb_assert (m_kind == VARIABLES_DOMAIN || m_kind == FUNCTIONS_DOMAIN); for (objfile *objfile : current_program_space->objfiles ()) - { - for (minimal_symbol *msymbol : objfile->msymbols ()) - { - QUIT; - - if (msymbol->created_by_gdb) - continue; - - if (MSYMBOL_TYPE (msymbol) == ourtype - || MSYMBOL_TYPE (msymbol) == ourtype2 - || MSYMBOL_TYPE (msymbol) == ourtype3 - || MSYMBOL_TYPE (msymbol) == ourtype4) - { - if (!preg.has_value () - || preg->exec (msymbol->natural_name (), 0, - NULL, 0) == 0) - { - /* For functions we can do a quick check of whether the - symbol might be found via find_pc_symtab. */ - if (m_kind != FUNCTIONS_DOMAIN - || (find_pc_compunit_symtab - (MSYMBOL_VALUE_ADDRESS (objfile, msymbol)) - == NULL)) - { - if (lookup_symbol_in_objfile_from_linkage_name - (objfile, msymbol->linkage_name (), VAR_DOMAIN) - .symbol == NULL) - { - /* match */ - result.emplace_back (i, msymbol, objfile); - } - } - } - } - } - } + if (!add_matching_msymbols (objfile, preg, &result)) + break; } return result; @@ -5217,7 +5260,7 @@ completion_list_add_symbol (completion_tracker &tracker, const lookup_name_info &lookup_name, const char *text, const char *word) { - completion_list_add_name (tracker, SYMBOL_LANGUAGE (sym), + completion_list_add_name (tracker, sym->language (), sym->natural_name (), lookup_name, text, word); } @@ -5230,7 +5273,7 @@ completion_list_add_msymbol (completion_tracker &tracker, const lookup_name_info &lookup_name, const char *text, const char *word) { - completion_list_add_name (tracker, MSYMBOL_LANGUAGE (sym), + completion_list_add_name (tracker, sym->language (), sym->natural_name (), lookup_name, text, word); } @@ -5364,7 +5407,7 @@ completion_list_add_fields (completion_tracker &tracker, if (c == TYPE_CODE_UNION || c == TYPE_CODE_STRUCT) for (j = TYPE_N_BASECLASSES (t); j < TYPE_NFIELDS (t); j++) if (TYPE_FIELD_NAME (t, j)) - completion_list_add_name (tracker, SYMBOL_LANGUAGE (sym), + completion_list_add_name (tracker, sym->language (), TYPE_FIELD_NAME (t, j), lookup_name, text, word); }