diff --git a/gdb/coffread.c b/gdb/coffread.c
index e1415d6b258..5898b3a8e08 100644
--- a/gdb/coffread.c
+++ b/gdb/coffread.c
@@ -40,8 +40,6 @@
 
 #include "coff-pe-read.h"
 
-#include "build-id.h"
-
 /* The objfile we are currently reading.  */
 
 static struct objfile *coffread_objfile;
@@ -729,26 +727,8 @@ coff_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags)
 	   && objfile->separate_debug_objfile == NULL
 	   && objfile->separate_debug_objfile_backlink == NULL)
     {
-      deferred_warnings warnings;
-      std::string debugfile
-	= find_separate_debug_file_by_buildid (objfile, &warnings);
-
-      if (debugfile.empty ())
-	debugfile
-	  = find_separate_debug_file_by_debuglink (objfile, &warnings);
-
-      if (!debugfile.empty ())
-	{
-	  gdb_bfd_ref_ptr debug_bfd (symfile_bfd_open (debugfile.c_str ()));
-
-	  symbol_file_add_separate (debug_bfd, debugfile.c_str (),
-				    symfile_flags, objfile);
-	}
-      /* If all the methods to collect the debuginfo failed, print any
-	 warnings that were collected, this is a no-op if there are no
-	 warnings.  */
-      if (debugfile.empty ())
-	warnings.emit ();
+      if (objfile->find_and_add_separate_symbol_file (symfile_flags))
+	gdb_assert (objfile->separate_debug_objfile != nullptr);
     }
 }
 
diff --git a/gdb/elfread.c b/gdb/elfread.c
index 7900dfbc388..86e7f61586e 100644
--- a/gdb/elfread.c
+++ b/gdb/elfread.c
@@ -41,14 +41,12 @@
 #include "regcache.h"
 #include "bcache.h"
 #include "gdb_bfd.h"
-#include "build-id.h"
 #include "location.h"
 #include "auxv.h"
 #include "mdebugread.h"
 #include "ctfread.h"
 #include "gdbsupport/gdb_string_view.h"
 #include "gdbsupport/scoped_fd.h"
-#include "debuginfod-support.h"
 #include "dwarf2/public.h"
 #include "cli/cli-cmds.h"
 
@@ -1218,59 +1216,10 @@ elf_symfile_read_dwarf2 (struct objfile *objfile,
 	   && objfile->separate_debug_objfile == NULL
 	   && objfile->separate_debug_objfile_backlink == NULL)
     {
-      deferred_warnings warnings;
-
-      std::string debugfile
-	= find_separate_debug_file_by_buildid (objfile, &warnings);
-
-      if (debugfile.empty ())
-	debugfile = find_separate_debug_file_by_debuglink (objfile, &warnings);
-
-      if (!debugfile.empty ())
-	{
-	  gdb_bfd_ref_ptr debug_bfd
-	    (symfile_bfd_open_no_error (debugfile.c_str ()));
-
-	  if (debug_bfd != nullptr)
-	    symbol_file_add_separate (debug_bfd, debugfile.c_str (),
-				      symfile_flags, objfile);
-	}
+      if (objfile->find_and_add_separate_symbol_file (symfile_flags))
+	gdb_assert (objfile->separate_debug_objfile != nullptr);
       else
-	{
-	  has_dwarf2 = false;
-	  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))
-		    {
-		      symbol_file_add_separate (debug_bfd, symfile_path.get (),
-						symfile_flags, objfile);
-		      has_dwarf2 = 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)
-	warnings.emit ();
+	has_dwarf2 = false;
     }
 
   return has_dwarf2;
diff --git a/gdb/objfiles.h b/gdb/objfiles.h
index 4b8aa9bfcec..ec9d354e4a7 100644
--- a/gdb/objfiles.h
+++ b/gdb/objfiles.h
@@ -513,6 +513,16 @@ struct objfile
 
   bool has_partial_symbols ();
 
+  /* Look for a separate debug symbol file for this objfile, make use of
+     build-id, debug-link, and debuginfod as necessary.  If a suitable
+     separate debug symbol file is found then it is loaded using a call to
+     symbol_file_add_separate (SYMFILE_FLAGS is passed through unmodified
+     to this call) and this function returns true.  If no suitable separate
+     debug symbol file is found and loaded then this function returns
+     false.  */
+
+  bool find_and_add_separate_symbol_file (symfile_add_flags symfile_flags);
+
   /* Return true if this objfile has any unexpanded symbols.  A return
      value of false indicates either, that this objfile has all its
      symbols fully expanded (i.e. fully read in), or that this objfile has
diff --git a/gdb/symfile-debug.c b/gdb/symfile-debug.c
index 850da4147a3..961ae2327f7 100644
--- a/gdb/symfile-debug.c
+++ b/gdb/symfile-debug.c
@@ -35,6 +35,8 @@
 #include "block.h"
 #include "filenames.h"
 #include "cli/cli-style.h"
+#include "build-id.h"
+#include "debuginfod-support.h"
 
 /* We need to save a pointer to the real symbol functions.
    Plus, the debug versions are malloc'd because we have to NULL out the
@@ -558,6 +560,70 @@ objfile::require_partial_symbols (bool verbose)
     }
 }
 
+/* See objfiles.h.  */
+
+bool
+objfile::find_and_add_separate_symbol_file (symfile_add_flags symfile_flags)
+{
+  bool has_dwarf2 = true;
+
+  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);
+
+  if (!debugfile.empty ())
+    {
+      gdb_bfd_ref_ptr debug_bfd
+	(symfile_bfd_open_no_error (debugfile.c_str ()));
+
+      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 (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))
+		{
+		  symbol_file_add_separate (debug_bfd, symfile_path.get (),
+					    symfile_flags, this);
+		  has_dwarf2 = 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)
+    warnings.emit ();
+
+  return has_dwarf2;
+}
+
 
 /* Debugging version of struct sym_probe_fns.  */
 
