Blame SOURCES/gdb-rhbz1838777-debuginfod.patch

9093b4
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
9093b4
From: Keith Seitz <keiths@redhat.com>
9093b4
Date: Tue, 9 Jun 2020 08:29:41 -0700
9093b4
Subject: gdb-rhbz1838777-debuginfod.patch
9093b4
9093b4
;; Backport debuginofd support.
9093b4
;; (Aaron Merey, RH BZ 183877)
9093b4
9093b4
commit 0d79cdc494d5eb9db26a602d62c92d49f83f407e
9093b4
Author: Aaron Merey <amerey@redhat.com>
9093b4
Date:   Wed Feb 26 17:40:49 2020 -0500
9093b4
9093b4
    Add debuginfod support to GDB
9093b4
9093b4
    debuginfod is a lightweight web service that indexes ELF/DWARF debugging
9093b4
    resources by build-id and serves them over HTTP.
9093b4
9093b4
    This patch enables GDB to query debuginfod servers for separate debug
9093b4
    files and source code when it is otherwise not able to find them.
9093b4
9093b4
    GDB can be built with debuginfod using the --with-debuginfod configure
9093b4
    option.
9093b4
9093b4
    This requires that libdebuginfod be installed and found at configure time.
9093b4
9093b4
    debuginfod is packaged with elfutils, starting with version 0.178.
9093b4
9093b4
    For more information see https://sourceware.org/elfutils/.
9093b4
9093b4
    Tested on x86_64 Fedora 31.
9093b4
9093b4
    gdb/ChangeLog:
9093b4
    2020-02-26  Aaron Merey  <amerey@redhat.com>
9093b4
9093b4
            * Makefile.in: Handle optional debuginfod support.
9093b4
            * NEWS: Update.
9093b4
            * README: Add --with-debuginfod summary.
9093b4
            * config.in: Regenerate.
9093b4
            * configure: Regenerate.
9093b4
            * configure.ac: Handle optional debuginfod support.
9093b4
            * debuginfod-support.c: debuginfod helper functions.
9093b4
            * debuginfod-support.h: Ditto.
9093b4
            * doc/gdb.texinfo: Add --with-debuginfod to configure options
9093b4
            summary.
9093b4
            * dwarf2/read.c (dwarf2_get_dwz_file): Query debuginfod servers
9093b4
            when a dwz file cannot be found.
9093b4
            * elfread.c (elf_symfile_read): Query debuginfod servers when a
9093b4
            debuginfo file cannot be found.
9093b4
            * source.c (open_source_file): Query debuginfod servers when a
9093b4
            source file cannot be found.
9093b4
            * top.c (print_gdb_configuration): Include
9093b4
            --{with,without}-debuginfod in the output.
9093b4
9093b4
    gdb/testsuite/ChangeLog:
9093b4
    2020-02-26  Aaron Merey  <amerey@redhat.com>
9093b4
9093b4
            * gdb.debuginfod: New directory for debuginfod tests.
9093b4
            * gdb.debuginfod/main.c: New test file.
9093b4
            * gdb.debuginfod/fetch_src_and_symbols.exp: New tests.
9093b4
9093b4
diff --git a/config/debuginfod.m4 b/config/debuginfod.m4
9093b4
new file mode 100644
9093b4
--- /dev/null
9093b4
+++ b/config/debuginfod.m4
9093b4
@@ -0,0 +1,38 @@
9093b4
+dnl Copyright (C) 1997-2019 Free Software Foundation, Inc.
9093b4
+dnl This file is free software, distributed under the terms of the GNU
9093b4
+dnl General Public License.  As a special exception to the GNU General
9093b4
+dnl Public License, this file may be distributed as part of a program
9093b4
+dnl that contains a configuration script generated by Autoconf, under
9093b4
+dnl the same distribution terms as the rest of that program.
9093b4
+
9093b4
+AC_DEFUN([AC_DEBUGINFOD],
9093b4
+[
9093b4
+# Enable debuginfod
9093b4
+AC_ARG_WITH([debuginfod],
9093b4
+        AC_HELP_STRING([--with-debuginfod],
9093b4
+                       [Enable debuginfo lookups with debuginfod (auto/yes/no)]),
9093b4
+        [], [with_debuginfod=auto])
9093b4
+AC_MSG_CHECKING([whether to use debuginfod])
9093b4
+AC_MSG_RESULT([$with_debuginfod])
9093b4
+
9093b4
+if test "${with_debuginfod}" = no; then
9093b4
+  AC_MSG_WARN([debuginfod support disabled; some features may be unavailable.])
9093b4
+else
9093b4
+  AC_CHECK_LIB([debuginfod], [debuginfod_begin], [have_debuginfod_lib=yes])
9093b4
+  AC_CHECK_DECL([debuginfod_begin], [have_debuginfod_h=yes], [],
9093b4
+                [#include <elfutils/debuginfod.h>])
9093b4
+  if test "x$have_debuginfod_lib" = "xyes" -a \
9093b4
+          "x$have_debuginfod_h" = "xyes"; then
9093b4
+    AC_DEFINE([HAVE_LIBDEBUGINFOD], [1],
9093b4
+              [Define to 1 if debuginfod is enabled.])
9093b4
+    AC_SUBST([LIBDEBUGINFOD], ["-ldebuginfod"])
9093b4
+  else
9093b4
+    AC_SUBST([LIBDEBUGINFOD], [])
9093b4
+    if test "$with_debuginfod" = yes; then
9093b4
+      AC_MSG_ERROR([debuginfod is missing or unusable])
9093b4
+    else
9093b4
+      AC_MSG_WARN([debuginfod is missing or unusable; some features may be unavailable.])
9093b4
+    fi
9093b4
+  fi
9093b4
+fi
9093b4
+])
9093b4
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
9093b4
--- a/gdb/Makefile.in
9093b4
+++ b/gdb/Makefile.in
9093b4
@@ -612,7 +612,8 @@ CLIBS = $(SIM) $(READLINE) $(OPCODES) $(BFD) $(LIBCTF) $(ZLIB) \
9093b4
 	@LIBS@ @GUILE_LIBS@ @PYTHON_LIBS@ \
9093b4
 	$(LIBEXPAT) $(LIBLZMA) $(LIBBABELTRACE) $(LIBIPT) \
9093b4
 	$(LIBIBERTY) $(WIN32LIBS) $(LIBGNU) $(LIBICONV) $(LIBMPFR) \
9093b4
-	$(SRCHIGH_LIBS) $(LIBXXHASH) $(PTHREAD_LIBS)
9093b4
+	$(SRCHIGH_LIBS) $(LIBXXHASH) $(PTHREAD_LIBS) \
9093b4
+	@LIBDEBUGINFOD@
9093b4
 CDEPS = $(NAT_CDEPS) $(SIM) $(BFD) $(READLINE_DEPS) $(LIBCTF) \
9093b4
 	$(OPCODES) $(INTL_DEPS) $(LIBIBERTY) $(CONFIG_DEPS) $(LIBGNU)
9093b4
 
9093b4
@@ -1016,6 +1017,7 @@ COMMON_SFILES = \
9093b4
 	dbxread.c \
9093b4
 	dcache.c \
9093b4
 	debug.c \
9093b4
+	debuginfod-support.c \
9093b4
 	dictionary.c \
9093b4
 	disasm.c \
9093b4
 	disasm-selftests.c \
9093b4
diff --git a/gdb/NEWS b/gdb/NEWS
9093b4
--- a/gdb/NEWS
9093b4
+++ b/gdb/NEWS
9093b4
@@ -932,6 +932,20 @@ SH-5/SH64 running OpenBSD 	SH-5/SH64 support in sh*-*-openbsd*
9093b4
      manual for a further description of this feature.
9093b4
 
9093b4
 
9093b4
+* GDB now supports debuginfod, an HTTP server for distributing ELF/DWARF
9093b4
+  debugging information as well as source code.
9093b4
+
9093b4
+  When built with debuginfod, GDB can automatically query debuginfod
9093b4
+  servers for the separate debug files and source code of the executable
9093b4
+  being debugged.
9093b4
+
9093b4
+  To build GDB with debuginfod, pass --with-debuginfod to configure (this
9093b4
+  requires libdebuginfod, the debuginfod client library).
9093b4
+
9093b4
+  debuginfod is distributed with elfutils, starting with version 0.178.
9093b4
+
9093b4
+  You can get the latest version from https://sourceware.org/elfutils.
9093b4
+
9093b4
 * New features in the GDB remote stub, GDBserver
9093b4
 
9093b4
   ** GDBserver is now able to start inferior processes with a
9093b4
diff --git a/gdb/README b/gdb/README
9093b4
--- a/gdb/README
9093b4
+++ b/gdb/README
9093b4
@@ -432,6 +432,15 @@ more obscure GDB `configure' options are not listed here.
9093b4
      Use the curses library instead of the termcap library, for
9093b4
      text-mode terminal operations.
9093b4
 
9093b4
+`--with-debuginfod'
9093b4
+     Build GDB with libdebuginfod, the debuginfod client library.  Used
9093b4
+     to automatically fetch source files and separate debug files from
9093b4
+     debuginfod servers using the associated executable's build ID.
9093b4
+     Enabled by default if libdebuginfod is installed and found at
9093b4
+     configure time.  debuginfod is packaged with elfutils, starting
9093b4
+     with version 0.178.  You can get the latest version from
9093b4
+     'https://sourceware.org/elfutils/'.
9093b4
+
9093b4
 `--with-libunwind-ia64'
9093b4
      Use the libunwind library for unwinding function call stack on ia64
9093b4
      target platforms.
9093b4
diff --git a/gdb/config.in b/gdb/config.in
9093b4
--- a/gdb/config.in
9093b4
+++ b/gdb/config.in
9093b4
@@ -230,6 +230,9 @@
9093b4
 /* Define if you have the babeltrace library. */
9093b4
 #undef HAVE_LIBBABELTRACE
9093b4
 
9093b4
+/* Define to 1 if debuginfod is enabled. */
9093b4
+#undef HAVE_LIBDEBUGINFOD
9093b4
+
9093b4
 /* Define if you have the expat library. */
9093b4
 #undef HAVE_LIBEXPAT
9093b4
 
9093b4
diff --git a/gdb/configure b/gdb/configure
9093b4
--- a/gdb/configure
9093b4
+++ b/gdb/configure
9093b4
@@ -758,6 +758,7 @@ REPORT_BUGS_TEXI
9093b4
 REPORT_BUGS_TO
9093b4
 PKGVERSION
9093b4
 CODESIGN_CERT
9093b4
+LIBDEBUGINFOD
9093b4
 HAVE_NATIVE_GCORE_TARGET
9093b4
 TARGET_OBS
9093b4
 subdirs
9093b4
@@ -875,6 +876,7 @@ enable_64_bit_bfd
9093b4
 enable_gdbmi
9093b4
 enable_tui
9093b4
 enable_gdbtk
9093b4
+with_debuginfod
9093b4
 with_libunwind_ia64
9093b4
 with_curses
9093b4
 enable_profiling
9093b4
@@ -1611,6 +1613,8 @@ Optional Packages:
9093b4
                           do not restrict auto-loaded files locations
9093b4
   --with-rpm              query rpm database for missing debuginfos (yes/no,
9093b4
                           def. auto=librpm.so)
9093b4
+  --with-debuginfod       Enable debuginfo lookups with debuginfod
9093b4
+                          (auto/yes/no)
9093b4
   --with-libunwind-ia64   use libunwind frame unwinding for ia64 targets
9093b4
   --with-curses           use the curses library instead of the termcap
9093b4
                           library
9093b4
@@ -2271,6 +2275,52 @@ rm -f conftest.val
9093b4
 
9093b4
 } # ac_fn_c_compute_int
9093b4
 
9093b4
+# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES
9093b4
+# ---------------------------------------------
9093b4
+# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR
9093b4
+# accordingly.
9093b4
+ac_fn_c_check_decl ()
9093b4
+{
9093b4
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
9093b4
+  as_decl_name=`echo $2|sed 's/ *(.*//'`
9093b4
+  as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'`
9093b4
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5
9093b4
+$as_echo_n "checking whether $as_decl_name is declared... " >&6; }
9093b4
+if eval \${$3+:} false; then :
9093b4
+  $as_echo_n "(cached) " >&6
9093b4
+else
9093b4
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
9093b4
+/* end confdefs.h.  */
9093b4
+$4
9093b4
+int
9093b4
+main ()
9093b4
+{
9093b4
+#ifndef $as_decl_name
9093b4
+#ifdef __cplusplus
9093b4
+  (void) $as_decl_use;
9093b4
+#else
9093b4
+  (void) $as_decl_name;
9093b4
+#endif
9093b4
+#endif
9093b4
+
9093b4
+  ;
9093b4
+  return 0;
9093b4
+}
9093b4
+_ACEOF
9093b4
+if ac_fn_c_try_compile "$LINENO"; then :
9093b4
+  eval "$3=yes"
9093b4
+else
9093b4
+  eval "$3=no"
9093b4
+fi
9093b4
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
9093b4
+fi
9093b4
+eval ac_res=\$$3
9093b4
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
9093b4
+$as_echo "$ac_res" >&6; }
9093b4
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
9093b4
+
9093b4
+} # ac_fn_c_check_decl
9093b4
+
9093b4
 # ac_fn_c_check_func LINENO FUNC VAR
9093b4
 # ----------------------------------
9093b4
 # Tests whether FUNC exists, setting the cache variable VAR accordingly
9093b4
@@ -2449,52 +2499,6 @@ $as_echo "$ac_res" >&6; }
9093b4
 
9093b4
 } # ac_fn_c_check_type
9093b4
 
9093b4
-# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES
9093b4
-# ---------------------------------------------
9093b4
-# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR
9093b4
-# accordingly.
9093b4
-ac_fn_c_check_decl ()
9093b4
-{
9093b4
-  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
9093b4
-  as_decl_name=`echo $2|sed 's/ *(.*//'`
9093b4
-  as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'`
9093b4
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5
9093b4
-$as_echo_n "checking whether $as_decl_name is declared... " >&6; }
9093b4
-if eval \${$3+:} false; then :
9093b4
-  $as_echo_n "(cached) " >&6
9093b4
-else
9093b4
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
9093b4
-/* end confdefs.h.  */
9093b4
-$4
9093b4
-int
9093b4
-main ()
9093b4
-{
9093b4
-#ifndef $as_decl_name
9093b4
-#ifdef __cplusplus
9093b4
-  (void) $as_decl_use;
9093b4
-#else
9093b4
-  (void) $as_decl_name;
9093b4
-#endif
9093b4
-#endif
9093b4
-
9093b4
-  ;
9093b4
-  return 0;
9093b4
-}
9093b4
-_ACEOF
9093b4
-if ac_fn_c_try_compile "$LINENO"; then :
9093b4
-  eval "$3=yes"
9093b4
-else
9093b4
-  eval "$3=no"
9093b4
-fi
9093b4
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
9093b4
-fi
9093b4
-eval ac_res=\$$3
9093b4
-	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
9093b4
-$as_echo "$ac_res" >&6; }
9093b4
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
9093b4
-
9093b4
-} # ac_fn_c_check_decl
9093b4
-
9093b4
 # ac_fn_cxx_try_link LINENO
9093b4
 # -------------------------
9093b4
 # Try to link conftest.$ac_ext, and return whether this succeeded.
9093b4
@@ -6658,8 +6662,8 @@ $as_echo_n "checking specific librpm version... " >&6; }
9093b4
   if test "$cross_compiling" = yes; then :
9093b4
   { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
9093b4
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
9093b4
-as_fn_error "cannot run test program while cross compiling
9093b4
-See \`config.log' for more details." "$LINENO" 5; }
9093b4
+as_fn_error $? "cannot run test program while cross compiling
9093b4
+See \`config.log' for more details" "$LINENO" 5; }
9093b4
 else
9093b4
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
9093b4
 /* end confdefs.h.  */
9093b4
@@ -6830,7 +6834,7 @@ $as_echo "#define HAVE_LIBRPM 1" >>confdefs.h
9093b4
 $as_echo "no" >&6; }
9093b4
     LIBS="$save_LIBS"
9093b4
     if $DLOPEN_REQUIRE; then
9093b4
-      as_fn_error "Specific name $LIBRPM was requested but it could not be opened." "$LINENO" 5
9093b4
+      as_fn_error $? "Specific name $LIBRPM was requested but it could not be opened." "$LINENO" 5
9093b4
     fi
9093b4
 
9093b4
 
9093b4
@@ -6845,7 +6849,7 @@ if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
9093b4
 set dummy ${ac_tool_prefix}pkg-config; ac_word=$2
9093b4
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
9093b4
 $as_echo_n "checking for $ac_word... " >&6; }
9093b4
-if test "${ac_cv_path_PKG_CONFIG+set}" = set; then :
9093b4
+if ${ac_cv_path_PKG_CONFIG+:} false; then :
9093b4
   $as_echo_n "(cached) " >&6
9093b4
 else
9093b4
   case $PKG_CONFIG in
9093b4
@@ -6859,7 +6863,7 @@ do
9093b4
   IFS=$as_save_IFS
9093b4
   test -z "$as_dir" && as_dir=.
9093b4
     for ac_exec_ext in '' $ac_executable_extensions; do
9093b4
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
9093b4
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
9093b4
     ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
9093b4
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
9093b4
     break 2
9093b4
@@ -6888,7 +6892,7 @@ if test -z "$ac_cv_path_PKG_CONFIG"; then
9093b4
 set dummy pkg-config; ac_word=$2
9093b4
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
9093b4
 $as_echo_n "checking for $ac_word... " >&6; }
9093b4
-if test "${ac_cv_path_ac_pt_PKG_CONFIG+set}" = set; then :
9093b4
+if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then :
9093b4
   $as_echo_n "(cached) " >&6
9093b4
 else
9093b4
   case $ac_pt_PKG_CONFIG in
9093b4
@@ -6902,7 +6906,7 @@ do
9093b4
   IFS=$as_save_IFS
9093b4
   test -z "$as_dir" && as_dir=.
9093b4
     for ac_exec_ext in '' $ac_executable_extensions; do
9093b4
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
9093b4
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
9093b4
     ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
9093b4
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
9093b4
     break 2
9093b4
@@ -7086,7 +7090,7 @@ $as_echo "#define HAVE_LIBRPM 1" >>confdefs.h
9093b4
       LIBS="$LIBS $RPM_LIBS"
9093b4
     else
9093b4
       if $RPM_REQUIRE; then
9093b4
-	as_fn_error "$RPM_PKG_ERRORS" "$LINENO" 5
9093b4
+	as_fn_error $? "$RPM_PKG_ERRORS" "$LINENO" 5
9093b4
       else
9093b4
 	{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $RPM_PKG_ERRORS" >&5
9093b4
 $as_echo "$as_me: WARNING: $RPM_PKG_ERRORS" >&2;}
9093b4
@@ -7332,8 +7336,92 @@ $as_echo "$as_me: WARNING: gdbtk isn't supported on $host; disabling" >&2;}
9093b4
     enable_gdbtk=no ;;
9093b4
 esac
9093b4
 
9093b4
-# Libunwind support for ia64.
9093b4
+# Handle optional debuginfod support
9093b4
+
9093b4
+# Enable debuginfod
9093b4
+
9093b4
+# Check whether --with-debuginfod was given.
9093b4
+if test "${with_debuginfod+set}" = set; then :
9093b4
+  withval=$with_debuginfod;
9093b4
+else
9093b4
+  with_debuginfod=auto
9093b4
+fi
9093b4
+
9093b4
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use debuginfod" >&5
9093b4
+$as_echo_n "checking whether to use debuginfod... " >&6; }
9093b4
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_debuginfod" >&5
9093b4
+$as_echo "$with_debuginfod" >&6; }
9093b4
+
9093b4
+if test "${with_debuginfod}" = no; then
9093b4
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: debuginfod support disabled; some features may be unavailable." >&5
9093b4
+$as_echo "$as_me: WARNING: debuginfod support disabled; some features may be unavailable." >&2;}
9093b4
+else
9093b4
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for debuginfod_begin in -ldebuginfod" >&5
9093b4
+$as_echo_n "checking for debuginfod_begin in -ldebuginfod... " >&6; }
9093b4
+if ${ac_cv_lib_debuginfod_debuginfod_begin+:} false; then :
9093b4
+  $as_echo_n "(cached) " >&6
9093b4
+else
9093b4
+  ac_check_lib_save_LIBS=$LIBS
9093b4
+LIBS="-ldebuginfod  $LIBS"
9093b4
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
9093b4
+/* end confdefs.h.  */
9093b4
+
9093b4
+/* Override any GCC internal prototype to avoid an error.
9093b4
+   Use char because int might match the return type of a GCC
9093b4
+   builtin and then its argument prototype would still apply.  */
9093b4
+#ifdef __cplusplus
9093b4
+extern "C"
9093b4
+#endif
9093b4
+char debuginfod_begin ();
9093b4
+int
9093b4
+main ()
9093b4
+{
9093b4
+return debuginfod_begin ();
9093b4
+  ;
9093b4
+  return 0;
9093b4
+}
9093b4
+_ACEOF
9093b4
+if ac_fn_c_try_link "$LINENO"; then :
9093b4
+  ac_cv_lib_debuginfod_debuginfod_begin=yes
9093b4
+else
9093b4
+  ac_cv_lib_debuginfod_debuginfod_begin=no
9093b4
+fi
9093b4
+rm -f core conftest.err conftest.$ac_objext \
9093b4
+    conftest$ac_exeext conftest.$ac_ext
9093b4
+LIBS=$ac_check_lib_save_LIBS
9093b4
+fi
9093b4
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_debuginfod_debuginfod_begin" >&5
9093b4
+$as_echo "$ac_cv_lib_debuginfod_debuginfod_begin" >&6; }
9093b4
+if test "x$ac_cv_lib_debuginfod_debuginfod_begin" = xyes; then :
9093b4
+  have_debuginfod_lib=yes
9093b4
+fi
9093b4
+
9093b4
+  ac_fn_c_check_decl "$LINENO" "debuginfod_begin" "ac_cv_have_decl_debuginfod_begin" "#include <elfutils/debuginfod.h>
9093b4
+"
9093b4
+if test "x$ac_cv_have_decl_debuginfod_begin" = xyes; then :
9093b4
+  have_debuginfod_h=yes
9093b4
+fi
9093b4
+
9093b4
+  if test "x$have_debuginfod_lib" = "xyes" -a \
9093b4
+          "x$have_debuginfod_h" = "xyes"; then
9093b4
+
9093b4
+$as_echo "#define HAVE_LIBDEBUGINFOD 1" >>confdefs.h
9093b4
+
9093b4
+    LIBDEBUGINFOD="-ldebuginfod"
9093b4
 
9093b4
+  else
9093b4
+
9093b4
+    if test "$with_debuginfod" = yes; then
9093b4
+      as_fn_error $? "debuginfod is missing or unusable" "$LINENO" 5
9093b4
+    else
9093b4
+      { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: debuginfod is missing or unusable; some features may be unavailable." >&5
9093b4
+$as_echo "$as_me: WARNING: debuginfod is missing or unusable; some features may be unavailable." >&2;}
9093b4
+    fi
9093b4
+  fi
9093b4
+fi
9093b4
+
9093b4
+
9093b4
+# Libunwind support for ia64.
9093b4
 
9093b4
 # Check whether --with-libunwind-ia64 was given.
9093b4
 if test "${with_libunwind_ia64+set}" = set; then :
9093b4
@@ -16441,7 +16529,7 @@ _ACEOF
9093b4
 for ac_header in selinux/selinux.h
9093b4
 do :
9093b4
   ac_fn_c_check_header_mongrel "$LINENO" "selinux/selinux.h" "ac_cv_header_selinux_selinux_h" "$ac_includes_default"
9093b4
-if test "x$ac_cv_header_selinux_selinux_h" = x""yes; then :
9093b4
+if test "x$ac_cv_header_selinux_selinux_h" = xyes; then :
9093b4
   cat >>confdefs.h <<_ACEOF
9093b4
 #define HAVE_SELINUX_SELINUX_H 1
9093b4
 _ACEOF
9093b4
@@ -16452,7 +16540,7 @@ done
9093b4
 
9093b4
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for security_get_boolean_active in -lselinux" >&5
9093b4
 $as_echo_n "checking for security_get_boolean_active in -lselinux... " >&6; }
9093b4
-if test "${ac_cv_lib_selinux_security_get_boolean_active+set}" = set; then :
9093b4
+if ${ac_cv_lib_selinux_security_get_boolean_active+:} false; then :
9093b4
   $as_echo_n "(cached) " >&6
9093b4
 else
9093b4
   ac_check_lib_save_LIBS=$LIBS
9093b4
@@ -16486,7 +16574,7 @@ LIBS=$ac_check_lib_save_LIBS
9093b4
 fi
9093b4
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_selinux_security_get_boolean_active" >&5
9093b4
 $as_echo "$ac_cv_lib_selinux_security_get_boolean_active" >&6; }
9093b4
-if test "x$ac_cv_lib_selinux_security_get_boolean_active" = x""yes; then :
9093b4
+if test "x$ac_cv_lib_selinux_security_get_boolean_active" = xyes; then :
9093b4
   cat >>confdefs.h <<_ACEOF
9093b4
 #define HAVE_LIBSELINUX 1
9093b4
 _ACEOF
9093b4
diff --git a/gdb/configure.ac b/gdb/configure.ac
9093b4
--- a/gdb/configure.ac
9093b4
+++ b/gdb/configure.ac
9093b4
@@ -18,6 +18,8 @@ dnl along with this program.  If not, see <http://www.gnu.org/licenses/>.
9093b4
 
9093b4
 dnl Process this file with autoconf to produce a configure script.
9093b4
 
9093b4
+m4_include(../config/debuginfod.m4)
9093b4
+
9093b4
 AC_INIT(main.c)
9093b4
 AC_CONFIG_HEADERS(config.h:config.in, [echo > stamp-h])
9093b4
 AM_MAINTAINER_MODE
9093b4
@@ -516,8 +518,10 @@ case $host_os in
9093b4
     enable_gdbtk=no ;;
9093b4
 esac
9093b4
 
9093b4
-# Libunwind support for ia64.
9093b4
+# Handle optional debuginfod support
9093b4
+AC_DEBUGINFOD
9093b4
 
9093b4
+# Libunwind support for ia64.
9093b4
 AC_ARG_WITH(libunwind-ia64,
9093b4
 AS_HELP_STRING([--with-libunwind-ia64],
9093b4
 	       [use libunwind frame unwinding for ia64 targets]),,
9093b4
diff --git a/gdb/debuginfod-support.c b/gdb/debuginfod-support.c
9093b4
new file mode 100644
9093b4
--- /dev/null
9093b4
+++ b/gdb/debuginfod-support.c
9093b4
@@ -0,0 +1,155 @@
9093b4
+/* debuginfod utilities for GDB.
9093b4
+   Copyright (C) 2020 Free Software Foundation, Inc.
9093b4
+
9093b4
+   This file is part of GDB.
9093b4
+
9093b4
+   This program is free software; you can redistribute it and/or modify
9093b4
+   it under the terms of the GNU General Public License as published by
9093b4
+   the Free Software Foundation; either version 3 of the License, or
9093b4
+   (at your option) any later version.
9093b4
+
9093b4
+   This program is distributed in the hope that it will be useful,
9093b4
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
9093b4
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9093b4
+   GNU General Public License for more details.
9093b4
+
9093b4
+   You should have received a copy of the GNU General Public License
9093b4
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
9093b4
+
9093b4
+#include "defs.h"
9093b4
+#include <errno.h>
9093b4
+#include "cli/cli-style.h"
9093b4
+#include "gdbsupport/scoped_fd.h"
9093b4
+#include "debuginfod-support.h"
9093b4
+
9093b4
+#ifndef HAVE_LIBDEBUGINFOD
9093b4
+scoped_fd
9093b4
+debuginfod_source_query (const unsigned char *build_id,
9093b4
+			 int build_id_len,
9093b4
+			 const char *srcpath,
9093b4
+			 gdb::unique_xmalloc_ptr<char> *destname)
9093b4
+{
9093b4
+  return scoped_fd (-ENOSYS);
9093b4
+}
9093b4
+
9093b4
+scoped_fd
9093b4
+debuginfod_debuginfo_query (const unsigned char *build_id,
9093b4
+			    int build_id_len,
9093b4
+			    const char *filename,
9093b4
+			    gdb::unique_xmalloc_ptr<char> *destname)
9093b4
+{
9093b4
+  return scoped_fd (-ENOSYS);
9093b4
+}
9093b4
+#else
9093b4
+#include <elfutils/debuginfod.h>
9093b4
+
9093b4
+/* TODO: Use debuginfod API extensions instead of these globals.  */
9093b4
+static std::string desc;
9093b4
+static std::string fname;
9093b4
+static bool has_printed;
9093b4
+
9093b4
+static int
9093b4
+progressfn (debuginfod_client *c, long cur, long total)
9093b4
+{
9093b4
+  if (check_quit_flag ())
9093b4
+    {
9093b4
+      printf_filtered ("Cancelling download of %s %ps...\n",
9093b4
+		       desc.c_str (),
9093b4
+		       styled_string (file_name_style.style (), fname.c_str ()));
9093b4
+      return 1;
9093b4
+    }
9093b4
+
9093b4
+  if (!has_printed && total != 0)
9093b4
+    {
9093b4
+      /* Print this message only once.  */
9093b4
+      has_printed = true;
9093b4
+      printf_filtered ("Downloading %s %ps...\n",
9093b4
+		       desc.c_str (),
9093b4
+		       styled_string (file_name_style.style (), fname.c_str ()));
9093b4
+    }
9093b4
+
9093b4
+  return 0;
9093b4
+}
9093b4
+
9093b4
+static debuginfod_client *
9093b4
+debuginfod_init ()
9093b4
+{
9093b4
+  debuginfod_client *c = debuginfod_begin ();
9093b4
+
9093b4
+  if (c != nullptr)
9093b4
+    debuginfod_set_progressfn (c, progressfn);
9093b4
+
9093b4
+  return c;
9093b4
+}
9093b4
+
9093b4
+/* See debuginfod-support.h  */
9093b4
+
9093b4
+scoped_fd
9093b4
+debuginfod_source_query (const unsigned char *build_id,
9093b4
+			 int build_id_len,
9093b4
+			 const char *srcpath,
9093b4
+			 gdb::unique_xmalloc_ptr<char> *destname)
9093b4
+{
9093b4
+  if (getenv (DEBUGINFOD_URLS_ENV_VAR) == NULL)
9093b4
+    return scoped_fd (-ENOSYS);
9093b4
+
9093b4
+  debuginfod_client *c = debuginfod_init ();
9093b4
+
9093b4
+  if (c == nullptr)
9093b4
+    return scoped_fd (-ENOMEM);
9093b4
+
9093b4
+  desc = std::string ("source file");
9093b4
+  fname = std::string (srcpath);
9093b4
+  has_printed = false;
9093b4
+
9093b4
+  scoped_fd fd (debuginfod_find_source (c,
9093b4
+					build_id,
9093b4
+					build_id_len,
9093b4
+					srcpath,
9093b4
+					nullptr));
9093b4
+
9093b4
+  /* TODO: Add 'set debug debuginfod' command to control when error messages are shown.  */
9093b4
+  if (fd.get () < 0 && fd.get () != -ENOENT)
9093b4
+    printf_filtered (_("Download failed: %s.  Continuing without source file %ps.\n"),
9093b4
+		     safe_strerror (-fd.get ()),
9093b4
+		     styled_string (file_name_style.style (),  srcpath));
9093b4
+  else
9093b4
+    destname->reset (xstrdup (srcpath));
9093b4
+
9093b4
+  debuginfod_end (c);
9093b4
+  return fd;
9093b4
+}
9093b4
+
9093b4
+/* See debuginfod-support.h  */
9093b4
+
9093b4
+scoped_fd
9093b4
+debuginfod_debuginfo_query (const unsigned char *build_id,
9093b4
+			    int build_id_len,
9093b4
+			    const char *filename,
9093b4
+			    gdb::unique_xmalloc_ptr<char> *destname)
9093b4
+{
9093b4
+  if (getenv (DEBUGINFOD_URLS_ENV_VAR) == NULL)
9093b4
+    return scoped_fd (-ENOSYS);
9093b4
+
9093b4
+  debuginfod_client *c = debuginfod_init ();
9093b4
+
9093b4
+  if (c == nullptr)
9093b4
+    return scoped_fd (-ENOMEM);
9093b4
+
9093b4
+  desc = std::string ("separate debug info for");
9093b4
+  fname = std::string (filename);
9093b4
+  has_printed = false;
9093b4
+  char *dname = nullptr;
9093b4
+
9093b4
+  scoped_fd fd (debuginfod_find_debuginfo (c, build_id, build_id_len, &dname));
9093b4
+
9093b4
+  if (fd.get () < 0 && fd.get () != -ENOENT)
9093b4
+    printf_filtered (_("Download failed: %s.  Continuing without debug info for %ps.\n"),
9093b4
+		     safe_strerror (-fd.get ()),
9093b4
+		     styled_string (file_name_style.style (),  filename));
9093b4
+
9093b4
+  destname->reset (dname);
9093b4
+  debuginfod_end (c);
9093b4
+  return fd;
9093b4
+}
9093b4
+#endif
9093b4
diff --git a/gdb/debuginfod-support.h b/gdb/debuginfod-support.h
9093b4
new file mode 100644
9093b4
--- /dev/null
9093b4
+++ b/gdb/debuginfod-support.h
9093b4
@@ -0,0 +1,62 @@
9093b4
+/* debuginfod utilities for GDB.
9093b4
+   Copyright (C) 2020 Free Software Foundation, Inc.
9093b4
+
9093b4
+   This file is part of GDB.
9093b4
+
9093b4
+   This program is free software; you can redistribute it and/or modify
9093b4
+   it under the terms of the GNU General Public License as published by
9093b4
+   the Free Software Foundation; either version 3 of the License, or
9093b4
+   (at your option) any later version.
9093b4
+
9093b4
+   This program is distributed in the hope that it will be useful,
9093b4
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
9093b4
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9093b4
+   GNU General Public License for more details.
9093b4
+
9093b4
+   You should have received a copy of the GNU General Public License
9093b4
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
9093b4
+
9093b4
+#ifndef DEBUGINFOD_SUPPORT_H
9093b4
+#define DEBUGINFOD_SUPPORT_H
9093b4
+
9093b4
+/* Query debuginfod servers for a source file associated with an
9093b4
+   executable with BUILD_ID.  BUILD_ID can be given as a binary blob or
9093b4
+   a null-terminated string.  If given as a binary blob, BUILD_ID_LEN
9093b4
+   should be the number of bytes.  If given as a null-terminated string,
9093b4
+   BUILD_ID_LEN should be 0.
9093b4
+
9093b4
+   SRC_PATH should be the source file's absolute path that includes the
9093b4
+   compilation directory of the CU associated with the source file.
9093b4
+   For example if a CU's compilation directory is `/my/build` and the
9093b4
+   source file path is `/my/source/foo.c`, then SRC_PATH should be
9093b4
+   `/my/build/../source/foo.c`.
9093b4
+
9093b4
+   If the file is successfully retrieved, its path on the local machine
9093b4
+   is stored in DESTNAME.  If GDB is not built with debuginfod, this
9093b4
+   function returns -ENOSYS.  */
9093b4
+
9093b4
+extern scoped_fd
9093b4
+debuginfod_source_query (const unsigned char *build_id,
9093b4
+			 int build_id_len,
9093b4
+			 const char *src_path,
9093b4
+			 gdb::unique_xmalloc_ptr<char> *destname);
9093b4
+
9093b4
+/* Query debuginfod servers for a debug info file with BUILD_ID.
9093b4
+   BUILD_ID can be given as a binary blob or a null-terminated string.
9093b4
+   If given as a binary blob, BUILD_ID_LEN should be the number of bytes.
9093b4
+   If given as a null-terminated string, BUILD_ID_LEN should be 0.
9093b4
+
9093b4
+   FILENAME should be the name or path of the main binary associated with
9093b4
+   the separate debug info.  It is used for printing messages to the user.
9093b4
+
9093b4
+   If the file is successfully retrieved, its path on the local machine
9093b4
+   is stored in DESTNAME.  If GDB is not built with debuginfod, this
9093b4
+   function returns -ENOSYS.  */
9093b4
+
9093b4
+extern scoped_fd
9093b4
+debuginfod_debuginfo_query (const unsigned char *build_id,
9093b4
+			    int build_id_len,
9093b4
+			    const char *filename,
9093b4
+			    gdb::unique_xmalloc_ptr<char> *destname);
9093b4
+
9093b4
+#endif /* DEBUGINFOD_SUPPORT_H */
9093b4
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
9093b4
--- a/gdb/doc/gdb.texinfo
9093b4
+++ b/gdb/doc/gdb.texinfo
9093b4
@@ -37726,6 +37726,14 @@ supported).
9093b4
 Use the curses library instead of the termcap library, for text-mode
9093b4
 terminal operations.
9093b4
 
9093b4
+@item --with-debuginfod
9093b4
+Build @value{GDBN} with libdebuginfod, the debuginfod client library.
9093b4
+Used to automatically fetch source files and separate debug files from
9093b4
+debuginfod servers using the associated executable's build ID. Enabled
9093b4
+by default if libdebuginfod is installed and found at configure time.
9093b4
+debuginfod is packaged with elfutils, starting with version 0.178. You
9093b4
+can get the latest version from `https://sourceware.org/elfutils/'.
9093b4
+
9093b4
 @item --with-libunwind-ia64
9093b4
 Use the libunwind library for unwinding function call stack on ia64
9093b4
 target platforms.  See http://www.nongnu.org/libunwind/index.html for
9093b4
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
9093b4
--- a/gdb/dwarf2read.c
9093b4
+++ b/gdb/dwarf2read.c
9093b4
@@ -77,6 +77,7 @@
9093b4
 #include "gdbsupport/selftest.h"
9093b4
 #include "rust-lang.h"
9093b4
 #include "gdbsupport/pathstuff.h"
9093b4
+#include "debuginfod-support.h"
9093b4
 
9093b4
 /* When == 1, print basic high level tracing messages.
9093b4
    When > 1, be more verbose.
9093b4
@@ -2717,6 +2718,29 @@ dwarf2_get_dwz_file (struct dwarf2_per_objfile *dwarf2_per_objfile)
9093b4
 	dwz_bfd.reset (nullptr);
9093b4
     }
9093b4
 
9093b4
+  if (dwz_bfd == nullptr)
9093b4
+    {
9093b4
+      gdb::unique_xmalloc_ptr<char> alt_filename;
9093b4
+      const char *origname = dwarf2_per_objfile->objfile->original_name;
9093b4
+
9093b4
+      scoped_fd fd (debuginfod_debuginfo_query (buildid,
9093b4
+						buildid_len,
9093b4
+						origname,
9093b4
+						&alt_filename));
9093b4
+
9093b4
+      if (fd.get () >= 0)
9093b4
+	{
9093b4
+	  /* File successfully retrieved from server.  */
9093b4
+	  dwz_bfd = gdb_bfd_open (alt_filename.get (), gnutarget, -1);
9093b4
+
9093b4
+	  if (dwz_bfd == nullptr)
9093b4
+	    warning (_("File \"%s\" from debuginfod cannot be opened as bfd"),
9093b4
+		     alt_filename.get ());
9093b4
+	  else if (!build_id_verify (dwz_bfd.get (), buildid_len, buildid))
9093b4
+	    dwz_bfd.reset (nullptr);
9093b4
+	}
9093b4
+    }
9093b4
+
9093b4
   if (dwz_bfd == NULL)
9093b4
     dwz_bfd = build_id_to_debug_bfd (buildid_len, buildid, NULL);
9093b4
 
9093b4
diff --git a/gdb/elfread.c b/gdb/elfread.c
9093b4
--- a/gdb/elfread.c
9093b4
+++ b/gdb/elfread.c
9093b4
@@ -49,6 +49,8 @@
9093b4
 #include "mdebugread.h"
9093b4
 #include "ctfread.h"
9093b4
 #include "gdbsupport/gdb_string_view.h"
9093b4
+#include "gdbsupport/scoped_fd.h"
9093b4
+#include "debuginfod-support.h"
9093b4
 
9093b4
 /* Forward declarations.  */
9093b4
 extern const struct sym_fns elf_sym_fns_gdb_index;
9093b4
@@ -1313,12 +1315,42 @@ elf_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags)
9093b4
 	  symbol_file_add_separate (debug_bfd.get (), debugfile.c_str (),
9093b4
 				    symfile_flags, objfile);
9093b4
 	}
9093b4
-      /* Check if any separate debug info has been extracted out.  */
9093b4
-      else if (bfd_get_section_by_name (objfile->obfd, ".gnu_debuglink")
9093b4
-	       != NULL)
9093b4
-	debug_print_missing (objfile_name (objfile), build_id_filename.get ());
9093b4
       else
9093b4
-	has_dwarf2 = false;
9093b4
+	{
9093b4
+	  has_dwarf2 = false;
9093b4
+	  const struct bfd_build_id *build_id = build_id_bfd_shdr_get (objfile->obfd);
9093b4
+
9093b4
+	  if (build_id != nullptr)
9093b4
+	    {
9093b4
+	      gdb::unique_xmalloc_ptr<char> symfile_path;
9093b4
+	      scoped_fd fd (debuginfod_debuginfo_query (build_id->data,
9093b4
+							build_id->size,
9093b4
+							objfile->original_name,
9093b4
+							&symfile_path));
9093b4
+
9093b4
+	      if (fd.get () >= 0)
9093b4
+		{
9093b4
+		  /* File successfully retrieved from server.  */
9093b4
+		  gdb_bfd_ref_ptr debug_bfd (symfile_bfd_open (symfile_path.get ()));
9093b4
+
9093b4
+		  if (debug_bfd == nullptr)
9093b4
+		    warning (_("File \"%s\" from debuginfod cannot be opened as bfd"),
9093b4
+			     objfile->original_name);
9093b4
+		  else if (build_id_verify (debug_bfd.get (), build_id->size, build_id->data))
9093b4
+		    {
9093b4
+		      symbol_file_add_separate (debug_bfd.get (), symfile_path.get (),
9093b4
+						symfile_flags, objfile);
9093b4
+		      has_dwarf2 = true;
9093b4
+		    }
9093b4
+		}
46818e
+	      /* Check if any separate debug info has been extracted out.  */
46818e
+	      else if (bfd_get_section_by_name (objfile->obfd, ".gnu_debuglink")
46818e
+		       != NULL)
46818e
+		debug_print_missing (objfile_name (objfile), build_id_filename.get ());
46818e
+	      else
46818e
+		has_dwarf2 = false;
9093b4
+	    }
9093b4
+	}
9093b4
     }
9093b4
 
9093b4
   /* Read the CTF section only if there is no DWARF info.  */
9093b4
diff --git a/gdb/source.c b/gdb/source.c
9093b4
--- a/gdb/source.c
9093b4
+++ b/gdb/source.c
9093b4
@@ -47,6 +47,8 @@
9093b4
 #include "gdbsupport/pathstuff.h"
9093b4
 #include "source-cache.h"
9093b4
 #include "cli/cli-style.h"
9093b4
+#include "build-id.h"
9093b4
+#include "debuginfod-support.h"
9093b4
 
9093b4
 #define OPEN_MODE (O_RDONLY | O_BINARY)
9093b4
 #define FDOPEN_MODE FOPEN_RB
9093b4
@@ -1122,6 +1124,34 @@ open_source_file (struct symtab *s)
9093b4
   s->fullname = NULL;
9093b4
   scoped_fd fd = find_and_open_source (s->filename, SYMTAB_DIRNAME (s),
9093b4
 				       &fullname);
9093b4
+
9093b4
+  if (fd.get () < 0)
9093b4
+    {
9093b4
+      if (SYMTAB_COMPUNIT (s) != nullptr)
9093b4
+	{
9093b4
+	  const objfile *ofp = COMPUNIT_OBJFILE (SYMTAB_COMPUNIT (s));
9093b4
+
9093b4
+	  std::string srcpath;
9093b4
+	  if (IS_ABSOLUTE_PATH (s->filename))
9093b4
+	    srcpath = s->filename;
9093b4
+	  else if (SYMTAB_DIRNAME (s) != nullptr)
9093b4
+	    {
9093b4
+	      srcpath = SYMTAB_DIRNAME (s);
9093b4
+	      srcpath += SLASH_STRING;
9093b4
+	      srcpath += s->filename;
9093b4
+	    }
9093b4
+
9093b4
+	  const struct bfd_build_id *build_id = build_id_bfd_shdr_get (ofp->obfd);
9093b4
+
9093b4
+	  /* Query debuginfod for the source file.  */
9093b4
+	  if (build_id != nullptr)
9093b4
+	    fd = debuginfod_source_query (build_id->data,
9093b4
+					  build_id->size,
9093b4
+					  srcpath.c_str (),
9093b4
+					  &fullname);
9093b4
+	}
9093b4
+    }
9093b4
+
9093b4
   s->fullname = fullname.release ();
9093b4
   return fd;
9093b4
 }
9093b4
diff --git a/gdb/testsuite/gdb.debuginfod/fetch_src_and_symbols.exp b/gdb/testsuite/gdb.debuginfod/fetch_src_and_symbols.exp
9093b4
new file mode 100644
9093b4
--- /dev/null
9093b4
+++ b/gdb/testsuite/gdb.debuginfod/fetch_src_and_symbols.exp
46818e
@@ -0,0 +1,246 @@
9093b4
+# Copyright 2020 Free Software Foundation, Inc.
9093b4
+
9093b4
+# This program is free software; you can redistribute it and/or modify
9093b4
+# it under the terms of the GNU General Public License as published by
9093b4
+# the Free Software Foundation; either version 3 of the License, or
9093b4
+# (at your option) any later version.
9093b4
+#
9093b4
+# This program is distributed in the hope that it will be useful,
9093b4
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
9093b4
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9093b4
+# GNU General Public License for more details.
9093b4
+#
9093b4
+# You should have received a copy of the GNU General Public License
9093b4
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
9093b4
+
9093b4
+# Test debuginfod functionality
9093b4
+
9093b4
+standard_testfile main.c
9093b4
+
9093b4
+load_lib dwarf.exp
9093b4
+
9093b4
+if { [which debuginfod] == 0 } {
9093b4
+    untested "cannot find debuginfod"
9093b4
+    return -1
9093b4
+}
9093b4
+
9093b4
+if { [which curl] == 0 } {
9093b4
+    untested "cannot find curl"
9093b4
+    return -1
9093b4
+}
9093b4
+
9093b4
+# Skip testing if gdb was not configured with debuginfod
46818e
+if { [string first "with-debuginfod" \
46818e
+	 [eval exec $GDB $INTERNAL_GDBFLAGS --configuration]] == -1 } {
9093b4
+    untested "gdb not configured with debuginfod"
9093b4
+    return -1
9093b4
+}
9093b4
+
9093b4
+set cache [standard_output_file ".client_cache"]
9093b4
+set db [standard_output_file ".debuginfod.db"]
9093b4
+
9093b4
+# Delete any preexisting test files
9093b4
+file delete -force $cache
9093b4
+file delete -force $db
9093b4
+
9093b4
+set sourcetmp [standard_output_file tmp-${srcfile}]
9093b4
+set outputdir [standard_output_file {}]
9093b4
+
9093b4
+# Make a copy source file that we can move around
9093b4
+if { [catch {file copy -force ${srcdir}/${subdir}/${srcfile} \
9093b4
+	     [standard_output_file ${sourcetmp}]}] != 0 } {
9093b4
+    error "create temporary file"
9093b4
+    return -1
9093b4
+}
9093b4
+
9093b4
+if { [gdb_compile "$sourcetmp" "$binfile" executable {debug}] != "" } {
9093b4
+    fail "compile"
9093b4
+    return -1
9093b4
+}
9093b4
+
9093b4
+# Write some assembly that just has a .gnu_debugaltlink section.
9093b4
+# Copied from testsuite/gdb.dwarf2/dwzbuildid.exp.
9093b4
+proc write_just_debugaltlink {filename dwzname buildid} {
9093b4
+    set asm_file [standard_output_file $filename]
9093b4
+
9093b4
+    Dwarf::assemble $asm_file {
9093b4
+	upvar dwzname dwzname
9093b4
+	upvar buildid buildid
9093b4
+
9093b4
+	gnu_debugaltlink $dwzname $buildid
9093b4
+
9093b4
+	# Only the DWARF reader checks .gnu_debugaltlink, so make sure
9093b4
+	# there is a bit of DWARF in here.
9093b4
+	cu {} {
9093b4
+	    compile_unit {{language @DW_LANG_C}} {
9093b4
+	    }
9093b4
+	}
9093b4
+    }
9093b4
+}
9093b4
+
9093b4
+# Write some DWARF that also sets the buildid.
9093b4
+# Copied from testsuite/gdb.dwarf2/dwzbuildid.exp.
9093b4
+proc write_dwarf_file {filename buildid {value 99}} {
9093b4
+    set asm_file [standard_output_file $filename]
9093b4
+
9093b4
+    Dwarf::assemble $asm_file {
9093b4
+	declare_labels int_label int_label2
9093b4
+
9093b4
+	upvar buildid buildid
9093b4
+	upvar value value
9093b4
+
9093b4
+	build_id $buildid
9093b4
+
9093b4
+	cu {} {
9093b4
+	    compile_unit {{language @DW_LANG_C}} {
46818e
+		int_label2: base_type {
9093b4
+		    {name int}
9093b4
+		    {byte_size 4 sdata}
9093b4
+		    {encoding @DW_ATE_signed}
9093b4
+		}
9093b4
+
9093b4
+		constant {
9093b4
+		    {name the_int}
9093b4
+		    {type :$int_label2}
9093b4
+		    {const_value $value data1}
9093b4
+		}
9093b4
+	    }
9093b4
+	}
9093b4
+    }
9093b4
+}
9093b4
+
46818e
+proc no_url { } {
46818e
+    global binfile outputdir debugdir
9093b4
+
46818e
+    setenv DEBUGINFOD_URLS ""
9093b4
+
46818e
+    # Test that gdb cannot find source without debuginfod
46818e
+    clean_restart $binfile
46818e
+    gdb_test_no_output "set substitute-path $outputdir /dev/null" \
46818e
+	"set substitute-path"
46818e
+    gdb_test "list" ".*No such file or directory.*"
9093b4
+
46818e
+    # Strip symbols into separate file and move it so gdb cannot find it \
46818e
+	without debuginfod
46818e
+    if { [gdb_gnu_strip_debug $binfile ""] != 0 } {
46818e
+	fail "strip debuginfo"
46818e
+	return -1
46818e
+    }
9093b4
+
46818e
+    set debugdir [standard_output_file "debug"]
46818e
+    set debuginfo [standard_output_file "fetch_src_and_symbols.debug"]
9093b4
+
46818e
+    file mkdir $debugdir
46818e
+    file rename -force $debuginfo $debugdir
9093b4
+
46818e
+    # Test that gdb cannot find symbols without debuginfod
46818e
+    clean_restart $binfile
46818e
+    gdb_test "file" ".*No symbol file.*"
46818e
+
46818e
+    set buildid "01234567890abcdef0123456"
46818e
+
46818e
+    write_just_debugaltlink ${binfile}_has_altlink.S ${binfile}_dwz.o \
46818e
+	$buildid
46818e
+    write_dwarf_file ${binfile}_dwz.S $buildid
46818e
+
46818e
+    if {[gdb_compile ${binfile}_has_altlink.S ${binfile}_alt.o object \
46818e
+	     nodebug] != ""} {
46818e
+	fail "compile main with altlink"
46818e
+	return -1
9093b4
+    }
9093b4
+
46818e
+    if {[gdb_compile ${binfile}_dwz.S ${binfile}_dwz.o object \
46818e
+	     nodebug] != ""} {
46818e
+	fail "compile altlink"
46818e
+	return -1
46818e
+    }
46818e
+
46818e
+    file rename -force ${binfile}_dwz.o $debugdir
9093b4
+
46818e
+    # Test that gdb cannot find dwz without debuginfod.
46818e
+    clean_restart
46818e
+    gdb_test "file ${binfile}_alt.o" \
46818e
+	".*could not find '.gnu_debugaltlink'.*" \
46818e
+	"file [file tail ${binfile}_alt.o]"
46818e
+}
46818e
+
46818e
+proc local_url { } {
46818e
+    global binfile outputdir db debugdir
46818e
+
46818e
+    # Find an unused port
46818e
+    set port 7999
46818e
+    set found 0
46818e
+    while { ! $found } {
46818e
+	incr port
46818e
+	if { $port == 65536 } {
46818e
+	    fail "no available ports"
46818e
+	    return -1
46818e
+	}
9093b4
+
46818e
+	spawn debuginfod -vvvv -d $db -p $port -F $debugdir
46818e
+	expect {
46818e
+	    "started http server on IPv4 IPv6 port=$port" { set found 1 }
46818e
+	    "failed to bind to port" { kill_wait_spawned_process $spawn_id }
46818e
+	    timeout {
46818e
+		fail "find port timeout"
46818e
+		return -1
46818e
+	    }
46818e
+	}
9093b4
+    }
9093b4
+
46818e
+    set metrics [list "ready 1" \
46818e
+		     "thread_work_total{role=\"traverse\"} 1" \
46818e
+		     "thread_work_pending{role=\"scan\"} 0" \
46818e
+		     "thread_busy{role=\"scan\"} 0"]
9093b4
+
46818e
+    # Check server metrics to confirm init has completed.
46818e
+    foreach m $metrics {
46818e
+	set timelim 20
46818e
+	while { $timelim != 0 } {
46818e
+	    sleep 0.5
46818e
+	    catch {exec curl -s http://127.0.0.1:$port/metrics} got
46818e
+
46818e
+	    if { [regexp $m $got] } {
46818e
+		break
46818e
+	    }
46818e
+
46818e
+	    incr timelim -1
46818e
+	}
46818e
+
46818e
+	if { $timelim == 0 } {
46818e
+	    fail "server init timeout"
46818e
+	    return -1
46818e
+	}
46818e
+    }
46818e
+
46818e
+    # Point the client to the server
46818e
+    setenv DEBUGINFOD_URLS http://127.0.0.1:$port
46818e
+
46818e
+    # gdb should now find the symbol and source files
46818e
+    clean_restart $binfile
46818e
+    gdb_test_no_output "set substitute-path $outputdir /dev/null" \
46818e
+	"set substitute-path"
46818e
+    gdb_test "br main" "Breakpoint 1 at.*file.*"
46818e
+    gdb_test "l" ".*This program is distributed in the hope.*"
46818e
+
46818e
+    # gdb should now find the debugaltlink file
46818e
+    clean_restart
46818e
+    gdb_test "file ${binfile}_alt.o" \
46818e
+	".*Reading symbols from ${binfile}_alt.o\.\.\.*" \
46818e
+	"file [file tail ${binfile}_alt.o]"
9093b4
+}
9093b4
+
46818e
+set envlist \
46818e
+    [list \
46818e
+	 env(DEBUGINFOD_URLS) \
46818e
+	 env(DEBUGINFOD_TIMEOUT) \
46818e
+	 env(DEBUGINFOD_CACHE_PATH)]
9093b4
+
46818e
+save_vars $envlist {
46818e
+    setenv DEBUGINFOD_TIMEOUT 30
46818e
+    setenv DEBUGINFOD_CACHE_PATH $cache
9093b4
+
46818e
+    with_test_prefix no_url no_url
46818e
+
46818e
+    with_test_prefix local_url local_url
46818e
+}
9093b4
diff --git a/gdb/testsuite/gdb.debuginfod/main.c b/gdb/testsuite/gdb.debuginfod/main.c
9093b4
new file mode 100644
9093b4
--- /dev/null
9093b4
+++ b/gdb/testsuite/gdb.debuginfod/main.c
9093b4
@@ -0,0 +1,25 @@
9093b4
+/* This testcase is part of GDB, the GNU debugger.
9093b4
+
9093b4
+   Copyright 2020 Free Software Foundation, Inc.
9093b4
+
9093b4
+   This program is free software; you can redistribute it and/or modify
9093b4
+   it under the terms of the GNU General Public License as published by
9093b4
+   the Free Software Foundation; either version 3 of the License, or
9093b4
+   (at your option) any later version.
9093b4
+
9093b4
+   This program is distributed in the hope that it will be useful,
9093b4
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
9093b4
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9093b4
+   GNU General Public License for more details.
9093b4
+
9093b4
+   You should have received a copy of the GNU General Public License
9093b4
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
9093b4
+
9093b4
+/* Dummy main function.  */
9093b4
+
9093b4
+int
9093b4
+main()
9093b4
+{
9093b4
+  asm ("main_label: .globl main_label");
9093b4
+  return 0;
9093b4
+}
9093b4
diff --git a/gdb/top.c b/gdb/top.c
9093b4
--- a/gdb/top.c
9093b4
+++ b/gdb/top.c
9093b4
@@ -1513,6 +1513,17 @@ This GDB was configured as follows:\n\
9093b4
              --without-python\n\
9093b4
 "));
9093b4
 #endif
9093b4
+
9093b4
+#if HAVE_LIBDEBUGINFOD
9093b4
+  fprintf_filtered (stream, _("\
9093b4
+             --with-debuginfod\n\
9093b4
+"));
9093b4
+#else
9093b4
+   fprintf_filtered (stream, _("\
9093b4
+             --without-debuginfod\n\
9093b4
+"));
9093b4
+#endif
9093b4
+
9093b4
 #if HAVE_GUILE
9093b4
   fprintf_filtered (stream, _("\
9093b4
              --with-guile\n\