diff options
Diffstat (limited to 'gdb/symtab.c')
-rw-r--r-- | gdb/symtab.c | 308 |
1 files changed, 176 insertions, 132 deletions
diff --git a/gdb/symtab.c b/gdb/symtab.c index 41d71be..c8bcab7 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -18,6 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include "dwarf2/call-site.h" +#include "exceptions.h" #include "symtab.h" #include "event-top.h" #include "gdbtypes.h" @@ -46,6 +47,7 @@ #include "fnmatch.h" #include "hashtab.h" #include "typeprint.h" +#include "exceptions.h" #include "gdbsupport/gdb_obstack.h" #include "block.h" @@ -73,6 +75,7 @@ #include "gdbsupport/pathstuff.h" #include "gdbsupport/common-utils.h" #include <optional> +#include <unordered_set> /* Forward declarations for local functions. */ @@ -121,6 +124,41 @@ struct main_info static const registry<program_space>::key<main_info> main_progspace_key; +/* Symbol lookup is not reentrant (though this is not an intrinsic + restriction). Keep track of whether a symbol lookup is active, to be able + to detect reentrancy. */ +static bool in_symbol_lookup; + +/* Struct to mark that a symbol lookup is active for the duration of its + lifetime. */ + +struct enter_symbol_lookup +{ + enter_symbol_lookup () + { + /* Ensure that the current language has been set. Normally the + language is set lazily. However, when performing a symbol lookup, + this could result in a recursive call into the lookup code in some + cases. Set it now to ensure that this does not happen. */ + get_current_language (); + + /* Detect symbol lookup reentrance. */ + gdb_assert (!in_symbol_lookup); + + in_symbol_lookup = true; + } + + ~enter_symbol_lookup () + { + /* Sanity check. */ + gdb_assert (in_symbol_lookup); + + in_symbol_lookup = false; + } + + DISABLE_COPY_AND_ASSIGN (enter_symbol_lookup); +}; + /* The default symbol cache size. There is no extra cpu cost for large N (except when flushing the cache, which is rare). The value here is just a first attempt. A better default @@ -400,38 +438,34 @@ compunit_symtab::find_call_site (CORE_ADDR pc) const return nullptr; CORE_ADDR delta = this->objfile ()->text_section_offset (); - unrelocated_addr unrelocated_pc = (unrelocated_addr) (pc - delta); - struct call_site call_site_local (unrelocated_pc, nullptr, nullptr); - void **slot - = htab_find_slot (m_call_site_htab, &call_site_local, NO_INSERT); - if (slot != nullptr) - return (call_site *) *slot; + if (auto it = m_call_site_htab->find (static_cast<unrelocated_addr> (pc - delta)); + it != m_call_site_htab->end ()) + return *it; /* See if the arch knows another PC we should try. On some platforms, GCC emits a DWARF call site that is offset from the actual return location. */ struct gdbarch *arch = objfile ()->arch (); CORE_ADDR new_pc = gdbarch_update_call_site_pc (arch, pc); + if (pc == new_pc) return nullptr; - unrelocated_pc = (unrelocated_addr) (new_pc - delta); - call_site new_call_site_local (unrelocated_pc, nullptr, nullptr); - slot = htab_find_slot (m_call_site_htab, &new_call_site_local, NO_INSERT); - if (slot == nullptr) - return nullptr; + if (auto it = m_call_site_htab->find (static_cast<unrelocated_addr> (new_pc - delta)); + it != m_call_site_htab->end ()) + return *it; - return (call_site *) *slot; + return nullptr; } /* See symtab.h. */ void -compunit_symtab::set_call_site_htab (htab_up call_site_htab) +compunit_symtab::set_call_site_htab (call_site_htab_t &&call_site_htab) { gdb_assert (m_call_site_htab == nullptr); - m_call_site_htab = call_site_htab.release (); + m_call_site_htab = new call_site_htab_t (std::move (call_site_htab)); } /* See symtab.h. */ @@ -500,8 +534,7 @@ void compunit_symtab::finalize () { this->forget_cached_source_info (); - if (m_call_site_htab != nullptr) - htab_delete (m_call_site_htab); + delete m_call_site_htab; } /* The relocated address of the minimal symbol, using the section @@ -590,40 +623,6 @@ compare_filenames_for_search (const char *filename, const char *search_name) && STRIP_DRIVE_SPEC (filename) == &filename[len - search_len])); } -/* Same as compare_filenames_for_search, but for glob-style patterns. - Heads up on the order of the arguments. They match the order of - compare_filenames_for_search, but it's the opposite of the order of - arguments to gdb_filename_fnmatch. */ - -bool -compare_glob_filenames_for_search (const char *filename, - const char *search_name) -{ - /* We rely on the property of glob-style patterns with FNM_FILE_NAME that - all /s have to be explicitly specified. */ - int file_path_elements = count_path_elements (filename); - int search_path_elements = count_path_elements (search_name); - - if (search_path_elements > file_path_elements) - return false; - - if (IS_ABSOLUTE_PATH (search_name)) - { - return (search_path_elements == file_path_elements - && gdb_filename_fnmatch (search_name, filename, - FNM_FILE_NAME | FNM_NOESCAPE) == 0); - } - - { - const char *file_to_compare - = strip_leading_path_elements (filename, - file_path_elements - search_path_elements); - - return gdb_filename_fnmatch (search_name, file_to_compare, - FNM_FILE_NAME | FNM_NOESCAPE) == 0; - } -} - /* Check for a symtab of a specific name by searching some symtabs. This is a helper function for callbacks of iterate_over_symtabs. @@ -700,15 +699,10 @@ iterate_over_some_symtabs (const char *name, return false; } -/* Check for a symtab of a specific name; first in symtabs, then in - psymtabs. *If* there is no '/' in the name, a match after a '/' - in the symtab filename will also work. - - Calls CALLBACK with each symtab that is found. If CALLBACK returns - true, the search stops. */ +/* See symtab.h. */ void -iterate_over_symtabs (const char *name, +iterate_over_symtabs (program_space *pspace, const char *name, gdb::function_view<bool (symtab *)> callback) { gdb::unique_xmalloc_ptr<char> real_path; @@ -721,34 +715,28 @@ iterate_over_symtabs (const char *name, gdb_assert (IS_ABSOLUTE_PATH (real_path.get ())); } - for (objfile *objfile : current_program_space->objfiles ()) - { - if (iterate_over_some_symtabs (name, real_path.get (), - objfile->compunit_symtabs, NULL, - callback)) + for (objfile *objfile : pspace->objfiles ()) + if (iterate_over_some_symtabs (name, real_path.get (), + objfile->compunit_symtabs, nullptr, + callback)) return; - } - /* Same search rules as above apply here, but now we look thru the + /* Same search rules as above apply here, but now we look through the psymtabs. */ - - for (objfile *objfile : current_program_space->objfiles ()) - { - if (objfile->map_symtabs_matching_filename (name, real_path.get (), - callback)) - return; - } + for (objfile *objfile : pspace->objfiles ()) + if (objfile->map_symtabs_matching_filename (name, real_path.get (), + callback)) + return; } -/* A wrapper for iterate_over_symtabs that returns the first matching - symtab, or NULL. */ +/* See symtab.h. */ -struct symtab * -lookup_symtab (const char *name) +symtab * +lookup_symtab (program_space *pspace, const char *name) { struct symtab *result = NULL; - iterate_over_symtabs (name, [&] (symtab *symtab) + iterate_over_symtabs (pspace, name, [&] (symtab *symtab) { result = symtab; return true; @@ -1563,6 +1551,7 @@ symbol_cache_mark_not_found (struct block_symbol_cache *bsc, static void symbol_cache_flush (struct program_space *pspace) { + ada_clear_symbol_cache (pspace); struct symbol_cache *cache = symbol_cache_key.get (pspace); int pass; @@ -1755,7 +1744,7 @@ maintenance_print_symbol_cache_statistics (const char *args, int from_tty) static void symtab_new_objfile_observer (struct objfile *objfile) { - symbol_cache_flush (objfile->pspace); + symbol_cache_flush (objfile->pspace ()); } /* This module's 'all_objfiles_removed' observer. */ @@ -1766,7 +1755,7 @@ symtab_all_objfiles_removed (program_space *pspace) symbol_cache_flush (pspace); /* Forget everything we know about the main function. */ - set_main_name (pspace, nullptr, language_unknown); + main_progspace_key.clear (pspace); } /* This module's 'free_objfile' observer. */ @@ -1774,7 +1763,7 @@ symtab_all_objfiles_removed (program_space *pspace) static void symtab_free_objfile_observer (struct objfile *objfile) { - symbol_cache_flush (objfile->pspace); + symbol_cache_flush (objfile->pspace ()); } /* See symtab.h. */ @@ -1928,6 +1917,28 @@ lookup_name_info::match_any () return lookup_name; } +/* See symtab.h. */ + +unsigned int +lookup_name_info::search_name_hash (language lang) const +{ + /* This works around an obscure problem. If currently in Ada mode, + and the name is wrapped in '<...>' (indicating verbatim mode), + force the use of the Ada language here so that the '<' and '>' + will be removed. */ + if (current_language->la_language == language_ada && ada ().verbatim_p ()) + lang = language_ada; + + /* Only compute each language's hash once. */ + if (!m_demangled_hashes_p[lang]) + { + m_demangled_hashes[lang] + = ::search_name_hash (lang, language_lookup_name (lang)); + m_demangled_hashes_p[lang] = true; + } + return m_demangled_hashes[lang]; +} + /* Compute the demangled form of NAME as used by the various symbol lookup functions. The result can either be the input NAME directly, or a pointer to a buffer owned by the STORAGE object. @@ -2283,6 +2294,8 @@ lookup_symbol_in_block (const char *name, symbol_name_match_type match_type, const struct block *block, const domain_search_flags domain) { + enter_symbol_lookup tmp; + struct symbol *sym; if (symbol_lookup_debug) @@ -2318,6 +2331,8 @@ lookup_global_symbol_from_objfile (struct objfile *main_objfile, const char *name, const domain_search_flags domain) { + enter_symbol_lookup tmp; + gdb_assert (block_index == GLOBAL_BLOCK || block_index == STATIC_BLOCK); for (objfile *objfile : main_objfile->separate_debug_objfiles ()) @@ -2439,7 +2454,7 @@ lookup_symbol_in_objfile_from_linkage_name (struct objfile *objfile, /* A helper function that throws an exception when a symbol was found in a psymtab but not in a symtab. */ -static void ATTRIBUTE_NORETURN +[[noreturn]] static void error_in_psymtab_expansion (enum block_enum block_index, const char *name, struct compunit_symtab *cust) { @@ -2643,6 +2658,8 @@ lookup_global_or_static_symbol (const char *name, return result; } + enter_symbol_lookup tmp; + /* Do a global search (of global blocks, heh). */ if (result.symbol == NULL) gdbarch_iterate_over_objfiles_in_search_order @@ -2892,14 +2909,14 @@ find_pc_sect_compunit_symtab (CORE_ADDR pc, struct obj_section *section) { struct compunit_symtab *best_cust = NULL; CORE_ADDR best_cust_range = 0; - struct bound_minimal_symbol msymbol; /* If we know that this is not a text address, return failure. This is necessary because we loop based on the block's high and low code addresses, which do not include the data ranges, and because we call find_pc_sect_psymtab which has a similar restriction based on the partial_symtab's texthigh and textlow. */ - msymbol = lookup_minimal_symbol_by_pc_section (pc, section); + bound_minimal_symbol msymbol + = lookup_minimal_symbol_by_pc_section (pc, section); if (msymbol.minsym && msymbol.minsym->data_p ()) return NULL; @@ -2980,7 +2997,7 @@ find_pc_sect_compunit_symtab (CORE_ADDR pc, struct obj_section *section) section. */ } - /* Cust is best found sofar, save it. */ + /* Cust is best found so far, save it. */ best_cust = cust; best_cust_range = range; } @@ -3091,7 +3108,6 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent) int len; const linetable_entry *item; const struct blockvector *bv; - struct bound_minimal_symbol msymbol; /* Info on best line seen so far, and where it starts, and its file. */ @@ -3170,13 +3186,14 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent) * check for the address being the same, to avoid an * infinite recursion. */ - msymbol = lookup_minimal_symbol_by_pc (pc); + bound_minimal_symbol msymbol = lookup_minimal_symbol_by_pc (pc); if (msymbol.minsym != NULL) if (msymbol.minsym->type () == mst_solib_trampoline) { - struct bound_minimal_symbol mfunsym - = lookup_minimal_symbol_text (msymbol.minsym->linkage_name (), - NULL); + bound_minimal_symbol mfunsym + = lookup_minimal_symbol_text (current_program_space, + msymbol.minsym->linkage_name (), + nullptr); if (mfunsym.minsym == NULL) /* I eliminated this warning since it is coming out @@ -3443,19 +3460,10 @@ find_pc_line_symtab (CORE_ADDR pc) return sal.symtab; } -/* Find line number LINE in any symtab whose name is the same as - SYMTAB. - - If found, return the symtab that contains the linetable in which it was - found, set *INDEX to the index in the linetable of the best entry - found, and set *EXACT_MATCH to true if the value returned is an - exact match. - - If not found, return NULL. */ +/* See symtab.h. */ -struct symtab * -find_line_symtab (struct symtab *sym_tab, int line, - int *index, bool *exact_match) +symtab * +find_line_symtab (symtab *sym_tab, int line, int *index) { int exact = 0; /* Initialized here to avoid a compiler warning. */ @@ -3535,8 +3543,6 @@ done: if (index) *index = best_index; - if (exact_match) - *exact_match = (exact != 0); return best_symtab; } @@ -3597,7 +3603,7 @@ find_line_pc (struct symtab *symtab, int line, CORE_ADDR *pc) if (symtab == 0) return false; - symtab = find_line_symtab (symtab, line, &ind, NULL); + symtab = find_line_symtab (symtab, line, &ind); if (symtab != NULL) { l = symtab->linetable (); @@ -3919,7 +3925,7 @@ skip_prologue_sal (struct symtab_and_line *sal) } else { - struct bound_minimal_symbol msymbol + bound_minimal_symbol msymbol = lookup_minimal_symbol_by_pc_section (sal->pc, sal->section); if (msymbol.minsym == NULL) @@ -4257,7 +4263,7 @@ find_epilogue_using_linetable (CORE_ADDR func_addr) /* Move to the last linetable entry of the current function. */ if (it == &linetable->item[0]) { - /* Doing it-- would introduce undefined behaviour, avoid it by + /* Doing it-- would introduce undefined behavior, avoid it by explicitly handling this case. */ return {}; } @@ -4291,7 +4297,7 @@ find_epilogue_using_linetable (CORE_ADDR func_addr) if (it == &linetable->item[0]) { /* No more entries in the current function. - Doing it-- would introduce undefined behaviour, avoid it by + Doing it-- would introduce undefined behavior, avoid it by explicitly handling this case. */ break; } @@ -4764,8 +4770,9 @@ info_sources_worker (struct ui_out *uiout, static void info_sources_command (const char *args, int from_tty) { - if (!have_full_symbols () && !have_partial_symbols ()) - error (_("No symbol table is loaded. Use the \"file\" command.")); + if (!have_full_symbols (current_program_space) + && !have_partial_symbols (current_program_space)) + error (_ ("No symbol table is loaded. Use the \"file\" command.")); filename_partial_match_opts match_opts; auto group = make_info_sources_options_def_group (&match_opts); @@ -5289,7 +5296,7 @@ print_symbol_info (struct symbol *sym, int block, const char *last) for non-debugging symbols to gdb_stdout. */ static void -print_msymbol_info (struct bound_minimal_symbol msymbol) +print_msymbol_info (bound_minimal_symbol msymbol) { struct gdbarch *gdbarch = msymbol.objfile->arch (); const char *tmp; @@ -5589,7 +5596,6 @@ info_main_command (const char *args, int from_tty) static void rbreak_command (const char *regexp, int from_tty) { - std::string string; gdb::unique_xmalloc_ptr<char> file_name; if (regexp != nullptr) @@ -5617,29 +5623,62 @@ rbreak_command (const char *regexp, int from_tty) spec.add_filename (std::move (file_name)); std::vector<symbol_search> symbols = spec.search (); + std::unordered_set<std::string> seen_names; scoped_rbreak_breakpoints finalize; + int err_count = 0; + for (const symbol_search &p : symbols) { - if (p.msymbol.minsym == NULL) + std::string name; + if (p.msymbol.minsym == nullptr) { - struct symtab *symtab = p.symbol->symtab (); - const char *fullname = symtab_to_fullname (symtab); - - string = string_printf ("%s:'%s'", fullname, - p.symbol->linkage_name ()); - break_command (&string[0], from_tty); - print_symbol_info (p.symbol, p.block, nullptr); + if (file_name != nullptr) + { + struct symtab *symtab = p.symbol->symtab (); + const char *fullname = symtab_to_fullname (symtab); + name = string_printf ("%s:'%s'", fullname, + p.symbol->linkage_name ()); + } + else + name = p.symbol->linkage_name (); } else - { - string = string_printf ("'%s'", - p.msymbol.minsym->linkage_name ()); + name = p.msymbol.minsym->linkage_name (); + + if (!seen_names.insert (name).second) + continue; - break_command (&string[0], from_tty); - gdb_printf ("<function, no debug info> %s;\n", - p.msymbol.minsym->print_name ()); + try + { + break_command (name.c_str (), from_tty); + } + catch (const gdb_exception_error &ex) + { + exception_print (gdb_stderr, ex); + ++err_count; + continue; } + + if (p.msymbol.minsym == nullptr) + print_symbol_info (p.symbol, p.block, nullptr); + else + gdb_printf ("<function, no debug info> %s;\n", name.c_str ()); } + + int first_bp = finalize.first_breakpoint (); + int last_bp = finalize.last_breakpoint (); + + if (last_bp == -1) + gdb_printf (_("No breakpoints made.\n")); + else if (first_bp == last_bp) + gdb_printf (_("Successfully created breakpoint %d.\n"), first_bp); + else + gdb_printf (_("Successfully created breakpoints %d-%d.\n"), + first_bp, last_bp); + + if (err_count > 0) + gdb_printf (_("%d breakpoints failed due to errors, see above.\n"), + err_count); } @@ -6293,7 +6332,7 @@ collect_file_symbol_completion_matches (completion_tracker &tracker, /* Go through symtabs for SRCFILE and check the externs and statics for symbols which match. */ - iterate_over_symtabs (srcfile, [&] (symtab *s) + iterate_over_symtabs (current_program_space, srcfile, [&] (symtab *s) { add_symtab_completions (s->compunit (), tracker, mode, lookup_name, @@ -6381,7 +6420,8 @@ make_source_files_completion_list (const char *text, const char *word) const char *base_name; struct add_partial_filename_data datum; - if (!have_full_symbols () && !have_partial_symbols ()) + if (!have_full_symbols (current_program_space) + && !have_partial_symbols (current_program_space)) return list; filename_seen_cache filenames_seen; @@ -6775,10 +6815,12 @@ symbol::get_maybe_copied_address () const gdb_assert (this->aclass () == LOC_STATIC); const char *linkage_name = this->linkage_name (); - bound_minimal_symbol minsym = lookup_minimal_symbol_linkage (linkage_name, - false); + bound_minimal_symbol minsym + = lookup_minimal_symbol_linkage (this->objfile ()->pspace (), linkage_name, + false, false); if (minsym.minsym != nullptr) return minsym.value_address (); + return this->m_value.address; } @@ -6791,10 +6833,12 @@ minimal_symbol::get_maybe_copied_address (objfile *objf) const gdb_assert ((objf->flags & OBJF_MAINLINE) == 0); const char *linkage_name = this->linkage_name (); - bound_minimal_symbol found = lookup_minimal_symbol_linkage (linkage_name, - true); + bound_minimal_symbol found + = lookup_minimal_symbol_linkage (objf->pspace (), linkage_name, + false, true); if (found.minsym != nullptr) return found.value_address (); + return (this->m_value.address + objf->section_offsets[this->section_index ()]); } @@ -7253,8 +7297,8 @@ If zero then the symbol cache is disabled."), _("Set if the PROLOGUE-END flag is ignored."), _("Show if the PROLOGUE-END flag is ignored."), _("\ -The PROLOGUE-END flag from the line-table entries is used to place \ -breakpoints past the prologue of functions. Disabling its use forces \ +The PROLOGUE-END flag from the line-table entries is used to place\n\ +breakpoints past the prologue of functions. Disabling its use forces\n\ the use of prologue scanners."), nullptr, nullptr, &maintenance_set_cmdlist, |