aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/symfile-debug.c135
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;
}