diff --git a/gdb/bsd-kvm.c b/gdb/bsd-kvm.c
index 21f978728d..895686ef62 100644
--- a/gdb/bsd-kvm.c
+++ b/gdb/bsd-kvm.c
@@ -114,14 +114,13 @@ bsd_kvm_target_open (const char *arg, int from_tty)
 
   if (arg)
     {
-      char *temp;
-
       filename = tilde_expand (arg);
       if (filename[0] != '/')
 	{
-	  temp = concat (current_directory, "/", filename, (char *)NULL);
+	  gdb::unique_xmalloc_ptr<char> temp (gdb_abspath (filename));
+
 	  xfree (filename);
-	  filename = temp;
+	  filename = temp.release ();
 	}
     }
 
diff --git a/gdb/corelow.c b/gdb/corelow.c
index fa1661ee61..c656306fe5 100644
--- a/gdb/corelow.c
+++ b/gdb/corelow.c
@@ -43,6 +43,7 @@
 #include "gdb_bfd.h"
 #include "completer.h"
 #include "gdbsupport/filestuff.h"
+#include "gdbsupport/pathstuff.h"
 
 #ifndef O_LARGEFILE
 #define O_LARGEFILE 0
@@ -373,8 +374,7 @@ core_target_open (const char *arg, int from_tty)
 
   gdb::unique_xmalloc_ptr<char> filename (tilde_expand (arg));
   if (!IS_ABSOLUTE_PATH (filename.get ()))
-    filename.reset (concat (current_directory, "/",
-			    filename.get (), (char *) NULL));
+    filename = gdb_abspath (filename.get ());
 
   flags = O_BINARY | O_LARGEFILE;
   if (write_files)
diff --git a/gdb/gdbsupport/pathstuff.c b/gdb/gdbsupport/pathstuff.c
index fafecd543d..aa51e8f36e 100644
--- a/gdb/gdbsupport/pathstuff.c
+++ b/gdb/gdbsupport/pathstuff.c
@@ -134,7 +134,7 @@ gdb_abspath (const char *path)
   if (path[0] == '~')
     return gdb_tilde_expand_up (path);
 
-  if (IS_ABSOLUTE_PATH (path))
+  if (IS_ABSOLUTE_PATH (path) || current_directory == NULL)
     return make_unique_xstrdup (path);
 
   /* Beware the // my son, the Emacs barfs, the botch that catch...  */
diff --git a/gdb/gdbsupport/pathstuff.h b/gdb/gdbsupport/pathstuff.h
index 7d7c8cd028..e84685b654 100644
--- a/gdb/gdbsupport/pathstuff.h
+++ b/gdb/gdbsupport/pathstuff.h
@@ -44,7 +44,10 @@ extern gdb::unique_xmalloc_ptr<char>
 
    Contrary to "gdb_realpath", this function uses CURRENT_DIRECTORY
    for the path expansion.  This may lead to scenarios the current
-   working directory (CWD) is different than CURRENT_DIRECTORY.  */
+   working directory (CWD) is different than CURRENT_DIRECTORY.
+
+   If CURRENT_DIRECTORY is NULL, this function returns a copy of
+   PATH.  */
 
 extern gdb::unique_xmalloc_ptr<char> gdb_abspath (const char *path);
 
diff --git a/gdb/go32-nat.c b/gdb/go32-nat.c
index 8c71bd7650..94972a2f5c 100644
--- a/gdb/go32-nat.c
+++ b/gdb/go32-nat.c
@@ -507,7 +507,8 @@ go32_nat_target::wait (ptid_t ptid, struct target_waitstatus *status,
     }
 
   getcwd (child_cwd, sizeof (child_cwd)); /* in case it has changed */
-  chdir (current_directory);
+  if (current_directory != NULL)
+    chdir (current_directory);
 
   if (a_tss.tss_irqn == 0x21)
     {
diff --git a/gdb/source.c b/gdb/source.c
index d9cd5f32ca..b456a517e3 100644
--- a/gdb/source.c
+++ b/gdb/source.c
@@ -540,8 +540,7 @@ add_path (const char *dirname, char **which_path, int parse_separators)
 	new_name_holder.reset (concat (name, ".", (char *) NULL));
 #endif
       else if (!IS_ABSOLUTE_PATH (name) && name[0] != '$')
-	new_name_holder.reset (concat (current_directory, SLASH_STRING, name,
-				       (char *) NULL));
+	new_name_holder = gdb_abspath (name);
       else
 	new_name_holder.reset (savestring (name, p - name));
       name = new_name_holder.get ();
diff --git a/gdb/top.c b/gdb/top.c
index 2953eac819..0893fe057f 100644
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -54,6 +54,7 @@
 #include "gdb_select.h"
 #include "gdbsupport/scope-exit.h"
 #include "gdbarch.h"
+#include "gdbsupport/pathstuff.h"
 
 /* readline include files.  */
 #include "readline/readline.h"
@@ -1982,12 +1983,13 @@ init_history (void)
          that was read.  */
 #ifdef __MSDOS__
       /* No leading dots in file names are allowed on MSDOS.  */
-      history_filename = concat (current_directory, "/_gdb_history",
-				 (char *)NULL);
+      const char *fname = "_gdb_history";
 #else
-      history_filename = concat (current_directory, "/.gdb_history",
-				 (char *)NULL);
+      const char *fname = ".gdb_history";
 #endif
+
+      gdb::unique_xmalloc_ptr<char> temp (gdb_abspath (fname));
+      history_filename = temp.release ();
     }
   read_history (history_filename);
 }
@@ -2065,8 +2067,12 @@ set_history_filename (const char *args,
      directories the file written will be the same as the one
      that was read.  */
   if (!IS_ABSOLUTE_PATH (history_filename))
-    history_filename = reconcat (history_filename, current_directory, "/", 
-				 history_filename, (char *) NULL);
+    {
+      gdb::unique_xmalloc_ptr<char> temp (gdb_abspath (history_filename));
+
+      xfree (history_filename);
+      history_filename = temp.release ();
+    }
 }
 
 static void
diff --git a/gdb/tracefile-tfile.c b/gdb/tracefile-tfile.c
index 5c3837ec5b..0953b03781 100644
--- a/gdb/tracefile-tfile.c
+++ b/gdb/tracefile-tfile.c
@@ -32,6 +32,7 @@
 #include "xml-tdesc.h"
 #include "target-descriptions.h"
 #include "gdbsupport/buffer.h"
+#include "gdbsupport/pathstuff.h"
 #include <algorithm>
 
 #ifndef O_LARGEFILE
@@ -470,8 +471,7 @@ tfile_target_open (const char *arg, int from_tty)
 
   gdb::unique_xmalloc_ptr<char> filename (tilde_expand (arg));
   if (!IS_ABSOLUTE_PATH (filename.get ()))
-    filename.reset (concat (current_directory, "/", filename.get (),
-			    (char *) NULL));
+    filename = gdb_abspath (filename.get ());
 
   flags = O_BINARY | O_LARGEFILE;
   flags |= O_RDONLY;
