From: Tom Tromey Date: Sun, 28 Sep 2025 04:29:24 +0000 (-0600) Subject: Clean up iterate_over_symtabs X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a736ff7d886dbcc85026264c3ce11c125a8409b2;p=thirdparty%2Fbinutils-gdb.git Clean up iterate_over_symtabs After the "search via psyms" series, there's no need for iterate_over_symtabs to first check the expanded symtabs -- the callback will now be called for every relevant symtab, including ones that were already expanded before the search. Cleaning this up enables some other cleanups. In particular, iterate_over_some_symtabs is not needed in its current form, so here I've renamed it, made it static, and made it search just a single compunit symtab. While there I cleaned up the "invert" logic in objfile::map_symtabs_matching_filename. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30738 Reviewed-By: Guinevere Larsen --- diff --git a/gdb/symfile-debug.c b/gdb/symfile-debug.c index 7e7851ab72c..55e8a5e2a59 100644 --- a/gdb/symfile-debug.c +++ b/gdb/symfile-debug.c @@ -159,6 +159,74 @@ objfile::forget_cached_source_info () iter->forget_cached_source_info (this); } +/* Check for a symtab of a specific name by searching some symtabs. + + If NAME is not absolute, then REAL_PATH is NULL + If NAME is absolute, then REAL_PATH is the gdb_realpath form of NAME. + + The return value, NAME, REAL_PATH and CALLBACK are identical to the + `map_symtabs_matching_filename' method of quick_symbol_functions. + + CUST indicates which compunit symtab to search. Each symtab within + the specified compunit symtab is also searched. */ + +static bool +iterate_over_one_compunit_symtab (const char *name, + const char *real_path, + compunit_symtab *cust, + gdb::function_view callback) +{ + const char *base_name = lbasename (name); + + /* Skip included compunits. */ + if (cust->user != nullptr) + return false; + + for (symtab *s : cust->filetabs ()) + { + if (compare_filenames_for_search (s->filename, name)) + { + if (callback (s)) + return true; + continue; + } + + /* Before we invoke realpath, which can get expensive when many + files are involved, do a quick comparison of the basenames. */ + if (! basenames_may_differ + && FILENAME_CMP (base_name, lbasename (s->filename)) != 0) + continue; + + if (compare_filenames_for_search (symtab_to_fullname (s), name)) + { + if (callback (s)) + return true; + continue; + } + + /* If the user gave us an absolute path, try to find the file in + this symtab and use its absolute path. */ + if (real_path != NULL) + { + const char *fullname = symtab_to_fullname (s); + + gdb_assert (IS_ABSOLUTE_PATH (real_path)); + gdb_assert (IS_ABSOLUTE_PATH (name)); + gdb::unique_xmalloc_ptr fullname_real_path + = gdb_realpath (fullname); + fullname = fullname_real_path.get (); + if (FILENAME_CMP (real_path, fullname) == 0) + { + if (callback (s)) + return true; + continue; + } + } + } + + return false; +} + bool objfile::map_symtabs_matching_filename (const char *name, const char *real_path, @@ -172,7 +240,7 @@ objfile::map_symtabs_matching_filename real_path ? real_path : NULL, host_address_to_string (&callback)); - bool retval = true; + bool retval = false; const char *name_basename = lbasename (name); auto match_one_filename = [&] (const char *filename, bool basenames) @@ -187,29 +255,22 @@ objfile::map_symtabs_matching_filename return false; }; - compunit_symtab *last_made = this->compunit_symtabs; - - auto on_expansion = [&] (compunit_symtab *symtab) + auto listener = [&] (compunit_symtab *symtab) { - /* The callback to iterate_over_some_symtabs returns false to keep - going and true to continue, so we have to invert the result - here, for search. */ - bool result = !iterate_over_some_symtabs (name, real_path, - this->compunit_symtabs, - last_made, + /* CALLBACK returns false to keep going and true to continue, so + we have to invert the result here, for search. */ + return !iterate_over_one_compunit_symtab (name, real_path, symtab, callback); - last_made = this->compunit_symtabs; - return result; }; for (const auto &iter : qf) { if (!iter->search (this, match_one_filename, nullptr, nullptr, - on_expansion, + listener, SEARCH_GLOBAL_BLOCK | SEARCH_STATIC_BLOCK, SEARCH_ALL_DOMAINS)) { - retval = false; + retval = true; break; } } @@ -219,9 +280,7 @@ objfile::map_symtabs_matching_filename "qf->map_symtabs_matching_filename (...) = %d\n", retval); - /* We must re-invert the return value here to match the caller's - expectations. */ - return !retval; + return retval; } struct compunit_symtab * diff --git a/gdb/symtab.c b/gdb/symtab.c index 05a1fd0ba68..aefa1881fe5 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -586,82 +586,6 @@ compare_filenames_for_search (const char *filename, const char *search_name) && STRIP_DRIVE_SPEC (filename) == &filename[len - search_len])); } -/* Check for a symtab of a specific name by searching some symtabs. - This is a helper function for callbacks of iterate_over_symtabs. - - If NAME is not absolute, then REAL_PATH is NULL - If NAME is absolute, then REAL_PATH is the gdb_realpath form of NAME. - - The return value, NAME, REAL_PATH and CALLBACK are identical to the - `map_symtabs_matching_filename' method of quick_symbol_functions. - - FIRST and AFTER_LAST indicate the range of compunit symtabs to search. - Each symtab within the specified compunit symtab is also searched. - AFTER_LAST is one past the last compunit symtab to search; NULL means to - search until the end of the list. */ - -bool -iterate_over_some_symtabs (const char *name, - const char *real_path, - struct compunit_symtab *first, - struct compunit_symtab *after_last, - gdb::function_view callback) -{ - struct compunit_symtab *cust; - const char* base_name = lbasename (name); - - for (cust = first; cust != NULL && cust != after_last; cust = cust->next) - { - /* Skip included compunits. */ - if (cust->user != nullptr) - continue; - - for (symtab *s : cust->filetabs ()) - { - if (compare_filenames_for_search (s->filename, name)) - { - if (callback (s)) - return true; - continue; - } - - /* Before we invoke realpath, which can get expensive when many - files are involved, do a quick comparison of the basenames. */ - if (! basenames_may_differ - && FILENAME_CMP (base_name, lbasename (s->filename)) != 0) - continue; - - if (compare_filenames_for_search (symtab_to_fullname (s), name)) - { - if (callback (s)) - return true; - continue; - } - - /* If the user gave us an absolute path, try to find the file in - this symtab and use its absolute path. */ - if (real_path != NULL) - { - const char *fullname = symtab_to_fullname (s); - - gdb_assert (IS_ABSOLUTE_PATH (real_path)); - gdb_assert (IS_ABSOLUTE_PATH (name)); - gdb::unique_xmalloc_ptr fullname_real_path - = gdb_realpath (fullname); - fullname = fullname_real_path.get (); - if (FILENAME_CMP (real_path, fullname) == 0) - { - if (callback (s)) - return true; - continue; - } - } - } - } - - return false; -} - /* See symtab.h. */ void @@ -678,17 +602,9 @@ iterate_over_symtabs (program_space *pspace, const char *name, gdb_assert (IS_ABSOLUTE_PATH (real_path.get ())); } - 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 through the - psymtabs. */ for (objfile &objfile : pspace->objfiles ()) if (objfile.map_symtabs_matching_filename (name, real_path.get (), - callback)) + callback)) return; } diff --git a/gdb/symtab.h b/gdb/symtab.h index 254b425a8e2..5be7edb07b0 100644 --- a/gdb/symtab.h +++ b/gdb/symtab.h @@ -2807,12 +2807,6 @@ bool compare_filenames_for_search (const char *filename, bool compare_glob_filenames_for_search (const char *filename, const char *search_name); -bool iterate_over_some_symtabs (const char *name, - const char *real_path, - struct compunit_symtab *first, - struct compunit_symtab *after_last, - gdb::function_view callback); - /* Check in PSPACE 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.