From 4584f33d68b79c362ce9f3543052027b1676f30e Mon Sep 17 00:00:00 2001
From: Tom Tromey <tom@tromey.com>
Date: Sun, 4 Jul 2021 13:26:15 -0600
Subject: [PATCH] Introduce find_source_or_rewrite

The final bug fix in this series would duplicate the logic in
psymtab_to_fullname, so this patch extracts the body of this function
into a new function.
---
 gdb/psymtab.c | 21 ++-------------------
 gdb/source.c  | 28 ++++++++++++++++++++++++++++
 gdb/source.h  |  7 +++++++
 3 files changed, 37 insertions(+), 19 deletions(-)

diff --git a/gdb/psymtab.c b/gdb/psymtab.c
index 7c3017d36d2..4c5b10012ce 100644
--- a/gdb/psymtab.c
+++ b/gdb/psymtab.c
@@ -953,26 +953,9 @@ psymtab_to_fullname (struct partial_symtab *ps)
      to handle cases like the file being moved.  */
   if (ps->fullname == NULL)
     {
-      gdb::unique_xmalloc_ptr<char> fullname;
-      scoped_fd fd = find_and_open_source (ps->filename, ps->dirname,
-					   &fullname);
+      gdb::unique_xmalloc_ptr<char> fullname
+	= find_source_or_rewrite (ps->filename, ps->dirname);
       ps->fullname = fullname.release ();
-
-      if (fd.get () < 0)
-	{
-	  /* rewrite_source_path would be applied by find_and_open_source, we
-	     should report the pathname where GDB tried to find the file.  */
-
-	  if (ps->dirname == NULL || IS_ABSOLUTE_PATH (ps->filename))
-	    fullname.reset (xstrdup (ps->filename));
-	  else
-	    fullname.reset (concat (ps->dirname, SLASH_STRING,
-				    ps->filename, (char *) NULL));
-
-	  ps->fullname = rewrite_source_path (fullname.get ()).release ();
-	  if (ps->fullname == NULL)
-	    ps->fullname = fullname.release ();
-	}
     }
 
   return ps->fullname;
diff --git a/gdb/source.c b/gdb/source.c
index c993e25a892..7d1934bd6c9 100644
--- a/gdb/source.c
+++ b/gdb/source.c
@@ -1193,6 +1193,34 @@ open_source_file (struct symtab *s)
   return fd;
 }
 
+/* See source.h.  */
+
+gdb::unique_xmalloc_ptr<char>
+find_source_or_rewrite (const char *filename, const char *dirname)
+{
+  gdb::unique_xmalloc_ptr<char> fullname;
+
+  scoped_fd fd = find_and_open_source (filename, dirname, &fullname);
+  if (fd.get () < 0)
+    {
+      /* rewrite_source_path would be applied by find_and_open_source, we
+	 should report the pathname where GDB tried to find the file.  */
+
+      if (dirname == nullptr || IS_ABSOLUTE_PATH (filename))
+	fullname.reset (xstrdup (filename));
+      else
+	fullname.reset (concat (dirname, SLASH_STRING,
+				filename, (char *) nullptr));
+
+      gdb::unique_xmalloc_ptr<char> rewritten
+	= rewrite_source_path (fullname.get ());
+      if (rewritten != nullptr)
+	fullname = std::move (rewritten);
+    }
+
+  return fullname;
+}
+
 /* Finds the fullname that a symtab represents.
 
    This functions finds the fullname and saves it in s->fullname.
diff --git a/gdb/source.h b/gdb/source.h
index e4f6129c3e3..6c383efbbb2 100644
--- a/gdb/source.h
+++ b/gdb/source.h
@@ -72,6 +72,13 @@ extern scoped_fd find_and_open_source (const char *filename,
 				       const char *dirname,
 				       gdb::unique_xmalloc_ptr<char> *fullname);
 
+/* A wrapper for find_and_open_source that returns the full name.  If
+   the full name cannot be found, a full name is constructed based on
+   the parameters, passing them through rewrite_source_path.  */
+
+extern gdb::unique_xmalloc_ptr<char> find_source_or_rewrite
+     (const char *filename, const char *dirname);
+
 /* Open a source file given a symtab S.  Returns a file descriptor or
    negative number for error.  */
 extern scoped_fd open_source_file (struct symtab *s);