diff --git a/gdb/exec.c b/gdb/exec.c
index c8c32ecc27..15f85a278f 100644
--- a/gdb/exec.c
+++ b/gdb/exec.c
@@ -190,8 +190,7 @@ try_open_exec_file (const char *exec_file_host, struct inferior *inf,
 void
 exec_file_locate_attach (int pid, int defer_bp_reset, int from_tty)
 {
-  char *exec_file_target, *exec_file_host;
-  struct cleanup *old_chain;
+  char *exec_file_target;
   symfile_add_flags add_flags = 0;
 
   /* Do nothing if we already have an executable filename.  */
@@ -209,8 +208,8 @@ exec_file_locate_attach (int pid, int defer_bp_reset, int from_tty)
       return;
     }
 
-  exec_file_host = exec_file_find (exec_file_target, NULL);
-  old_chain = make_cleanup (xfree, exec_file_host);
+  gdb::unique_xmalloc_ptr<char> exec_file_host
+    = exec_file_find (exec_file_target, NULL);
 
   if (defer_bp_reset)
     add_flags |= SYMFILE_DEFER_BP_RESET;
@@ -219,8 +218,7 @@ exec_file_locate_attach (int pid, int defer_bp_reset, int from_tty)
     add_flags |= SYMFILE_VERBOSE;
 
   /* Attempt to open the exec file.  */
-  try_open_exec_file (exec_file_host, current_inferior (), add_flags);
-  do_cleanups (old_chain);
+  try_open_exec_file (exec_file_host.get (), current_inferior (), add_flags);
 }
 
 /* Set FILENAME as the new exec file.
diff --git a/gdb/infrun.c b/gdb/infrun.c
index 45fe36a717..1bc860b6f3 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -1081,8 +1081,6 @@ follow_exec (ptid_t ptid, char *exec_file_target)
   struct inferior *inf = current_inferior ();
   int pid = ptid_get_pid (ptid);
   ptid_t process_ptid;
-  char *exec_file_host;
-  struct cleanup *old_chain;
 
   /* This is an exec event that we actually wish to pay attention to.
      Refresh our symbol table to the newly exec'd program, remove any
@@ -1161,8 +1159,8 @@ follow_exec (ptid_t ptid, char *exec_file_target)
 
   breakpoint_init_inferior (inf_execd);
 
-  exec_file_host = exec_file_find (exec_file_target, NULL);
-  old_chain = make_cleanup (xfree, exec_file_host);
+  gdb::unique_xmalloc_ptr<char> exec_file_host
+    = exec_file_find (exec_file_target, NULL);
 
   /* If we were unable to map the executable target pathname onto a host
      pathname, tell the user that.  Otherwise GDB's subsequent behavior
@@ -1216,9 +1214,7 @@ follow_exec (ptid_t ptid, char *exec_file_target)
      Executable) main symbol file will only be computed by
      solib_create_inferior_hook below.  breakpoint_re_set would fail
      to insert the breakpoints with the zero displacement.  */
-  try_open_exec_file (exec_file_host, inf, SYMFILE_DEFER_BP_RESET);
-
-  do_cleanups (old_chain);
+  try_open_exec_file (exec_file_host.get (), inf, SYMFILE_DEFER_BP_RESET);
 
   /* If the target can specify a description, read it.  Must do this
      after flipping to the new executable (because the target supplied
diff --git a/gdb/solib-aix.c b/gdb/solib-aix.c
index 463f060845..aa0e0d2dfb 100644
--- a/gdb/solib-aix.c
+++ b/gdb/solib-aix.c
@@ -614,7 +614,6 @@ solib_aix_bfd_open (char *pathname)
   char *sep;
   int filename_len;
   int found_file;
-  char *found_pathname;
 
   if (pathname[path_len - 1] != ')')
     return solib_bfd_open (pathname);
@@ -638,10 +637,12 @@ solib_aix_bfd_open (char *pathname)
   /* Calling solib_find makes certain that sysroot path is set properly
      if program has a dependency on .a archive and sysroot is set via
      set sysroot command.  */
-  found_pathname = solib_find (filename.c_str (), &found_file);
+  gdb::unique_xmalloc_ptr<char> found_pathname
+    = solib_find (filename.c_str (), &found_file);
   if (found_pathname == NULL)
       perror_with_name (pathname);
-  gdb_bfd_ref_ptr archive_bfd (solib_bfd_fopen (found_pathname, found_file));
+  gdb_bfd_ref_ptr archive_bfd (solib_bfd_fopen (found_pathname.get (),
+						found_file));
   if (archive_bfd == NULL)
     {
       warning (_("Could not open `%s' as an executable file: %s"),
diff --git a/gdb/solib-darwin.c b/gdb/solib-darwin.c
index 121a7135c0..ed8f9da257 100644
--- a/gdb/solib-darwin.c
+++ b/gdb/solib-darwin.c
@@ -619,16 +619,16 @@ darwin_lookup_lib_symbol (struct objfile *objfile,
 static gdb_bfd_ref_ptr
 darwin_bfd_open (char *pathname)
 {
-  char *found_pathname;
   int found_file;
 
   /* Search for shared library file.  */
-  found_pathname = solib_find (pathname, &found_file);
+  gdb::unique_xmalloc_ptr<char> found_pathname
+    = solib_find (pathname, &found_file);
   if (found_pathname == NULL)
     perror_with_name (pathname);
 
   /* Open bfd for shared library.  */
-  gdb_bfd_ref_ptr abfd (solib_bfd_fopen (found_pathname, found_file));
+  gdb_bfd_ref_ptr abfd (solib_bfd_fopen (found_pathname.get (), found_file));
 
   gdb_bfd_ref_ptr res
     (gdb_bfd_mach_o_fat_extract (abfd.get (), bfd_object,
diff --git a/gdb/solib.c b/gdb/solib.c
index 40fdfc59e6..46f2324c48 100644
--- a/gdb/solib.c
+++ b/gdb/solib.c
@@ -148,7 +148,7 @@ show_solib_search_path (struct ui_file *file, int from_tty,
    * machines since a sysroot will almost always be set.
 */
 
-static char *
+static gdb::unique_xmalloc_ptr<char>
 solib_find_1 (const char *in_pathname, int *fd, int is_solib)
 {
   const struct target_so_ops *ops = solib_ops (target_gdbarch ());
@@ -251,7 +251,7 @@ solib_find_1 (const char *in_pathname, int *fd, int is_solib)
     {
       if (fd != NULL)
 	*fd = -1;
-      return temp_pathname;
+      return gdb::unique_xmalloc_ptr<char> (temp_pathname);
     }
 
   /* Now see if we can open it.  */
@@ -367,7 +367,7 @@ solib_find_1 (const char *in_pathname, int *fd, int is_solib)
   else
     *fd = found_file;
 
-  return temp_pathname;
+  return gdb::unique_xmalloc_ptr<char> (temp_pathname);
 }
 
 /* Return the full pathname of the main executable, or NULL if not
@@ -375,10 +375,10 @@ solib_find_1 (const char *in_pathname, int *fd, int is_solib)
    the caller.  If FD is non-NULL, *FD is set to either -1 or an open
    file handle for the main executable.  */
 
-char *
+gdb::unique_xmalloc_ptr<char>
 exec_file_find (const char *in_pathname, int *fd)
 {
-  char *result;
+  gdb::unique_xmalloc_ptr<char> result;
   const char *fskind = effective_target_file_system_kind ();
 
   if (in_pathname == NULL)
@@ -409,8 +409,11 @@ exec_file_find (const char *in_pathname, int *fd)
 	 (If that fails, we'll just fall back on the original
 	 filename.  Not much more we can do...)  */
 
-      if (!source_full_path_of (in_pathname, &result))
-	result = xstrdup (in_pathname);
+      char *full_path = NULL;
+      if (source_full_path_of (in_pathname, &full_path))
+	result.reset (full_path);
+      else
+	result.reset (xstrdup (in_pathname));
       if (fd != NULL)
 	*fd = -1;
     }
@@ -426,7 +429,7 @@ exec_file_find (const char *in_pathname, int *fd)
    The search algorithm used is described in solib_find_1's comment
    above.  */
 
-char *
+gdb::unique_xmalloc_ptr<char>
 solib_find (const char *in_pathname, int *fd)
 {
   const char *solib_symbols_extension
@@ -463,12 +466,10 @@ solib_find (const char *in_pathname, int *fd)
    it is used as file handle to open the file.  Throws an error if the file
    could not be opened.  Handles both local and remote file access.
 
-   PATHNAME must be malloc'ed by the caller.  It will be freed by this
-   function.  If unsuccessful, the FD will be closed (unless FD was
-   -1).  */
+   If unsuccessful, the FD will be closed (unless FD was -1).  */
 
 gdb_bfd_ref_ptr
-solib_bfd_fopen (char *pathname, int fd)
+solib_bfd_fopen (const char *pathname, int fd)
 {
   gdb_bfd_ref_ptr abfd (gdb_bfd_open (pathname, gnutarget, fd));
 
@@ -478,13 +479,10 @@ solib_bfd_fopen (char *pathname, int fd)
   if (abfd == NULL)
     {
       /* Arrange to free PATHNAME when the error is thrown.  */
-      gdb::unique_xmalloc_ptr<char> free_pathname (pathname);
       error (_("Could not open `%s' as an executable file: %s"),
 	     pathname, bfd_errmsg (bfd_get_error ()));
     }
 
-  xfree (pathname);
-
   return abfd;
 }
 
@@ -493,12 +491,12 @@ solib_bfd_fopen (char *pathname, int fd)
 gdb_bfd_ref_ptr
 solib_bfd_open (char *pathname)
 {
-  char *found_pathname;
   int found_file;
   const struct bfd_arch_info *b;
 
   /* Search for shared library file.  */
-  found_pathname = solib_find (pathname, &found_file);
+  gdb::unique_xmalloc_ptr<char> found_pathname
+    = solib_find (pathname, &found_file);
   if (found_pathname == NULL)
     {
       /* Return failure if the file could not be found, so that we can
@@ -510,7 +508,7 @@ solib_bfd_open (char *pathname)
     }
 
   /* Open bfd for shared library.  */
-  gdb_bfd_ref_ptr abfd (solib_bfd_fopen (found_pathname, found_file));
+  gdb_bfd_ref_ptr abfd (solib_bfd_fopen (found_pathname.get (), found_file));
 
   /* Check bfd format.  */
   if (!bfd_check_format (abfd.get (), bfd_object))
diff --git a/gdb/solist.h b/gdb/solist.h
index 14459139e5..aba00ebb21 100644
--- a/gdb/solist.h
+++ b/gdb/solist.h
@@ -192,13 +192,15 @@ typedef std::unique_ptr<so_list, so_deleter> so_list_up;
 struct so_list *master_so_list (void);
 
 /* Find main executable binary file.  */
-extern char *exec_file_find (const char *in_pathname, int *fd);
+extern gdb::unique_xmalloc_ptr<char> exec_file_find (const char *in_pathname,
+						     int *fd);
 
 /* Find shared library binary file.  */
-extern char *solib_find (const char *in_pathname, int *fd);
+extern gdb::unique_xmalloc_ptr<char> solib_find (const char *in_pathname,
+						 int *fd);
 
 /* Open BFD for shared library file.  */
-extern gdb_bfd_ref_ptr solib_bfd_fopen (char *pathname, int fd);
+extern gdb_bfd_ref_ptr solib_bfd_fopen (const char *pathname, int fd);
 
 /* Find solib binary file and open it.  */
 extern gdb_bfd_ref_ptr solib_bfd_open (char *in_pathname);
