diff options
-rw-r--r-- | gdb/symfile-debug.c | 135 |
1 files changed, 88 insertions, 47 deletions
diff --git a/gdb/symfile-debug.c b/gdb/symfile-debug.c index 961ae23..0b6dc47 100644 --- a/gdb/symfile-debug.c +++ b/gdb/symfile-debug.c @@ -560,68 +560,109 @@ objfile::require_partial_symbols (bool verbose) } } +/* Call LOOKUP_FUNC to find the filename of a file containing the separate + debug information matching OBJFILE. If LOOKUP_FUNC does return a + filename then open this file and return a std::pair containing the + gdb_bfd_ref_ptr of the open file and the filename returned by + LOOKUP_FUNC, otherwise this function returns an empty pair; the first + item will be nullptr, and the second will be an empty string. + + Any warnings generated by this function, or by calling LOOKUP_FUNC are + placed into WARNINGS, these warnings are only displayed to the user if + GDB is unable to find the separate debug information via any route. */ +static std::pair<gdb_bfd_ref_ptr, std::string> +simple_find_and_open_separate_symbol_file + (struct objfile *objfile, + std::string (*lookup_func) (struct objfile *, deferred_warnings *), + deferred_warnings *warnings) +{ + std::string filename = lookup_func (objfile, warnings); + + if (!filename.empty ()) + { + gdb_bfd_ref_ptr symfile_bfd + = symfile_bfd_open_no_error (filename.c_str ()); + if (symfile_bfd != nullptr) + return { symfile_bfd, filename }; + } + + return {}; +} + +/* Lookup separate debug information for OBJFILE via debuginfod. If + successful the debug information will be have been downloaded into the + debuginfod cache and this function will return a std::pair containing a + gdb_bfd_ref_ptr of the open debug information file and the filename for + the file within the debuginfod cache. If no debug information could be + found then this function returns an empty pair; the first item will be + nullptr, and the second will be an empty string. */ + +static std::pair<gdb_bfd_ref_ptr, std::string> +debuginfod_find_and_open_separate_symbol_file (struct objfile * objfile) +{ + const struct bfd_build_id *build_id + = build_id_bfd_get (objfile->obfd.get ()); + const char *filename = bfd_get_filename (objfile->obfd.get ()); + + if (build_id != nullptr) + { + gdb::unique_xmalloc_ptr<char> symfile_path; + scoped_fd fd (debuginfod_debuginfo_query (build_id->data, build_id->size, + filename, &symfile_path)); + + if (fd.get () >= 0) + { + /* File successfully retrieved from server. */ + gdb_bfd_ref_ptr debug_bfd + (symfile_bfd_open_no_error (symfile_path.get ())); + + if (debug_bfd != nullptr + && build_id_verify (debug_bfd.get (), + build_id->size, build_id->data)) + return { debug_bfd, std::string (symfile_path.get ()) }; + } + } + + return {}; +} + /* See objfiles.h. */ bool objfile::find_and_add_separate_symbol_file (symfile_add_flags symfile_flags) { - bool has_dwarf2 = true; + bool has_dwarf = false; deferred_warnings warnings; - std::string debugfile - = find_separate_debug_file_by_buildid (this, &warnings); - - if (debugfile.empty ()) - debugfile = find_separate_debug_file_by_debuglink (this, &warnings); + gdb_bfd_ref_ptr debug_bfd; + std::string filename; - if (!debugfile.empty ()) - { - gdb_bfd_ref_ptr debug_bfd - (symfile_bfd_open_no_error (debugfile.c_str ())); + std::tie (debug_bfd, filename) = simple_find_and_open_separate_symbol_file + (this, find_separate_debug_file_by_buildid, &warnings); - if (debug_bfd != nullptr) - symbol_file_add_separate (debug_bfd, debugfile.c_str (), - symfile_flags, this); - } - else - { - has_dwarf2 = false; - const struct bfd_build_id *build_id - = build_id_bfd_get (this->obfd.get ()); - const char *filename = bfd_get_filename (this->obfd.get ()); - - if (build_id != nullptr) - { - gdb::unique_xmalloc_ptr<char> symfile_path; - scoped_fd fd (debuginfod_debuginfo_query (build_id->data, - build_id->size, - filename, - &symfile_path)); + if (debug_bfd == nullptr) + std::tie (debug_bfd, filename) + = simple_find_and_open_separate_symbol_file + (this, find_separate_debug_file_by_debuglink, &warnings); - if (fd.get () >= 0) - { - /* File successfully retrieved from server. */ - gdb_bfd_ref_ptr debug_bfd - (symfile_bfd_open_no_error (symfile_path.get ())); + if (debug_bfd == nullptr) + std::tie (debug_bfd, filename) + = debuginfod_find_and_open_separate_symbol_file (this); - if (debug_bfd != nullptr - && build_id_verify (debug_bfd.get (), build_id->size, - build_id->data)) - { - symbol_file_add_separate (debug_bfd, symfile_path.get (), - symfile_flags, this); - has_dwarf2 = true; - } - } - } + if (debug_bfd != nullptr) + { + symbol_file_add_separate (debug_bfd, filename.c_str (), symfile_flags, + this); + has_dwarf = true; } - /* If all the methods to collect the debuginfo failed, print the - warnings, this is a no-op if there are no warnings. */ - if (debugfile.empty () && !has_dwarf2) + + /* If we still have not got a separate debug symbol file, then + emit any warnings we've collected so far. */ + if (!has_dwarf) warnings.emit (); - return has_dwarf2; + return has_dwarf; } |