[gdb/testsuite] Fix silent timeout in gdb.multi/multi-target.exp
[binutils-gdb.git] / gdb / source.c
index f5cd2a37e4aa37e6bd753b746453158f6e021b2a..50de93952bb04a2568830b9224129786b6312695 100644 (file)
@@ -1,5 +1,5 @@
 /* List lines of source files for GDB, the GNU debugger.
-   Copyright (C) 1986-2019 Free Software Foundation, Inc.
+   Copyright (C) 1986-2020 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -48,6 +48,8 @@
 #include "source-cache.h"
 #include "cli/cli-style.h"
 #include "observable.h"
+#include "build-id.h"
+#include "debuginfod-support.h"
 
 #define OPEN_MODE (O_RDONLY | O_BINARY)
 #define FDOPEN_MODE FOPEN_RB
@@ -1051,10 +1053,7 @@ find_and_open_source (const char *filename,
       result = gdb_open_cloexec (fullname->get (), OPEN_MODE, 0);
       if (result >= 0)
        {
-         if (basenames_may_differ)
-           *fullname = gdb_realpath (fullname->get ());
-         else
-           *fullname = gdb_abspath (fullname->get ());
+         *fullname = gdb_realpath (fullname->get ());
          return scoped_fd (result);
        }
 
@@ -1098,12 +1097,9 @@ find_and_open_source (const char *filename,
   if (rewritten_filename != NULL)
     filename = rewritten_filename.get ();
 
-  openp_flags flags = OPF_SEARCH_IN_PATH;
-  if (basenames_may_differ)
-    flags |= OPF_RETURN_REALPATH;
-
   /* Try to locate file using filename.  */
-  result = openp (path, flags, filename, OPEN_MODE, fullname);
+  result = openp (path, OPF_SEARCH_IN_PATH | OPF_RETURN_REALPATH, filename,
+                 OPEN_MODE, fullname);
   if (result < 0 && dirname != NULL)
     {
       /* Remove characters from the start of PATH that we don't need when
@@ -1124,15 +1120,16 @@ find_and_open_source (const char *filename,
       cdir_filename.append (SLASH_STRING);
       cdir_filename.append (filename_start);
 
-      result = openp (path, flags, cdir_filename.c_str (), OPEN_MODE,
-                     fullname);
+      result = openp (path, OPF_SEARCH_IN_PATH | OPF_RETURN_REALPATH,
+                     cdir_filename.c_str (), OPEN_MODE, fullname);
     }
   if (result < 0)
     {
       /* Didn't work.  Try using just the basename.  */
       p = lbasename (filename);
       if (p != filename)
-       result = openp (path, flags, p, OPEN_MODE, fullname);
+       result = openp (path, OPF_SEARCH_IN_PATH | OPF_RETURN_REALPATH, p,
+                       OPEN_MODE, fullname);
     }
 
   return scoped_fd (result);
@@ -1153,6 +1150,34 @@ open_source_file (struct symtab *s)
   s->fullname = NULL;
   scoped_fd fd = find_and_open_source (s->filename, SYMTAB_DIRNAME (s),
                                       &fullname);
+
+  if (fd.get () < 0)
+    {
+      if (SYMTAB_COMPUNIT (s) != nullptr)
+       {
+         const objfile *ofp = COMPUNIT_OBJFILE (SYMTAB_COMPUNIT (s));
+
+         std::string srcpath;
+         if (IS_ABSOLUTE_PATH (s->filename))
+           srcpath = s->filename;
+         else if (SYMTAB_DIRNAME (s) != nullptr)
+           {
+             srcpath = SYMTAB_DIRNAME (s);
+             srcpath += SLASH_STRING;
+             srcpath += s->filename;
+           }
+
+         const struct bfd_build_id *build_id = build_id_bfd_get (ofp->obfd);
+
+         /* Query debuginfod for the source file.  */
+         if (build_id != nullptr && !srcpath.empty ())
+           fd = debuginfod_source_query (build_id->data,
+                                         build_id->size,
+                                         srcpath.c_str (),
+                                         &fullname);
+       }
+    }
+
   s->fullname = fullname.release ();
   return fd;
 }
@@ -1232,6 +1257,7 @@ print_source_lines_base (struct symtab *s, int line, int stopline,
 
   loc->set (s, line);
   first_line_listed = line;
+  last_line_listed = line;
 
   /* If printing of source lines is disabled, just print file and line
      number.  */
@@ -1864,8 +1890,9 @@ source_lines_range::source_lines_range (int startline,
 }
 
 \f
+void _initialize_source ();
 void
-_initialize_source (void)
+_initialize_source ()
 {
   struct cmd_list_element *c;