ChangeLog:
authorUlrich Weigand <uweigand@de.ibm.com>
Tue, 26 Aug 2008 17:30:35 +0000 (17:30 +0000)
committerUlrich Weigand <uweigand@de.ibm.com>
Tue, 26 Aug 2008 17:30:35 +0000 (17:30 +0000)
* remote.h (remote_filename_p, remote_bfd_open): Add prototypes.
* remote.c (remote_bfd_iovec_open, remote_bfd_iovec_close,
remote_bfd_iovec_pread, remote_bfd_iovec_stat, remote_filename_p,
remote_bfd_open): New functions.
(remote_hostio_send_command): Fail safely if remote connection
is not set up.

* solist.h (solib_open): Remove prototype.
(solib_bfd_open): Add prototype.
* solib.c: Include "remote.h".
(solib_open): Remove, replace by ...
(solib_bfd_open): ... this new function.  Handle remote BFDs.
(solib_map_sections): Replace solib_open by solib_bfd_open.
* solib-frv.c: Include "exceptions.h".
(enable_break2): Replace solib_open by solib_bfd_open.
* solib-svr4.c: Include "exceptions.h".
(enable_break): Replace solib_open by solib_bfd_open.

* symfile.c: Include "remote.h".
(build_id_verify): Handle remote BFDs.
(separate_debug_file_exists): Use BFD to access file.  Handle
remote BFDs.
(symfile_bfd_open): Handle remote BFDs.
(reread_symbols): Handle remote BFDs.

* NEWS: Mention "remote:" argument prefix to "set sysroot".

doc/ChangeLog:

* gdb.texinfo (Commands to Specify Files): Document "remote:"
argument prefix to "set sysroot".

gdb/ChangeLog
gdb/NEWS
gdb/doc/ChangeLog
gdb/doc/gdb.texinfo
gdb/remote.c
gdb/remote.h
gdb/solib-frv.c
gdb/solib-svr4.c
gdb/solib.c
gdb/solist.h
gdb/symfile.c

index 0ab3596d1d68d5fcb95bdb1d008d02a1350aef5c..cdc4c77088b9426ebca013f9812efe4eb77e1397 100644 (file)
@@ -1,3 +1,32 @@
+2008-08-26  Ulrich Weigand  <uweigand@de.ibm.com>
+
+       * remote.h (remote_filename_p, remote_bfd_open): Add prototypes.
+       * remote.c (remote_bfd_iovec_open, remote_bfd_iovec_close,
+       remote_bfd_iovec_pread, remote_bfd_iovec_stat, remote_filename_p,
+       remote_bfd_open): New functions.
+       (remote_hostio_send_command): Fail safely if remote connection
+       is not set up.
+
+       * solist.h (solib_open): Remove prototype.
+       (solib_bfd_open): Add prototype.
+       * solib.c: Include "remote.h".
+       (solib_open): Remove, replace by ...
+       (solib_bfd_open): ... this new function.  Handle remote BFDs.
+       (solib_map_sections): Replace solib_open by solib_bfd_open.
+       * solib-frv.c: Include "exceptions.h".
+       (enable_break2): Replace solib_open by solib_bfd_open.
+       * solib-svr4.c: Include "exceptions.h".
+       (enable_break): Replace solib_open by solib_bfd_open.
+
+       * symfile.c: Include "remote.h".
+       (build_id_verify): Handle remote BFDs.
+       (separate_debug_file_exists): Use BFD to access file.  Handle
+       remote BFDs.
+       (symfile_bfd_open): Handle remote BFDs.
+       (reread_symbols): Handle remote BFDs.
+
+       * NEWS: Mention "remote:" argument prefix to "set sysroot".
+
 2008-08-26  Ulrich Weigand  <uweigand@de.ibm.com>
 
        * gdbarch.sh (target_gdbarch): New global variable.
index 46d143829acc10400e9ca1801c1eec402109d8c9..4c9af8295a13bd1a370989af01e76d5aa50529aa 100644 (file)
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -3,6 +3,11 @@
 
 *** Changes since GDB 6.8
 
+* GDB now supports automatic retrieval of shared library files from
+remote targets.  To use this feature, specify a system root that begins
+with the `remote:' prefix, either via the `set sysroot' command or via
+the `--with-sysroot' configure-time option.
+
 * Commands `set debug-file-directory', `set solib-search-path' and `set args'
 now complete on file names.
 
index 7e837706d9e4ebfd58a8a41d78547d10b9a8064d..bb1ac1f0c23c5df48b2a1e4bc833bae230e8791d 100644 (file)
@@ -1,3 +1,8 @@
+2008-08-26  Ulrich Weigand  <uweigand@de.ibm.com>
+
+       * gdb.texinfo (Commands to Specify Files): Document "remote:"
+       argument prefix to "set sysroot".
+
 2008-08-21  Paul N. Hilfinger  <hilfinger@adacore.com>
 
        * gdb.texinfo (Omissions from Ada): Describe new treatment of True
index 6760b71940a05ac800252642658f5e83cedcbc36..60fc4b96c6380c75ddbd92300b73ca4bbb23af75 100644 (file)
@@ -12605,8 +12605,11 @@ library events happen.
 @end table
 
 Shared libraries are also supported in many cross or remote debugging
-configurations.  A copy of the target's libraries need to be present on the
-host system; they need to be the same as the target libraries, although the
+configurations.  @value{GDBN} needs to have access to the target's libraries;
+this can be accomplished either by providing copies of the libraries
+on the host system, or by asking @value{GDBN} to automatically retrieve the
+libraries from the target.  If copies of the target libraries are
+provided, they need to be the same as the target libraries, although the
 copies on the target can be stripped as long as the copies on the host are
 not.
 
@@ -12630,6 +12633,16 @@ libraries, they need to be laid out in the same way that they are on
 the target, with e.g.@: a @file{/lib} and @file{/usr/lib} hierarchy
 under @var{path}.
 
+If @var{path} starts with the sequence @file{remote:}, @value{GDBN} will 
+retrieve the target libraries from the remote system.  This is only
+supported when using a remote target that supports the @code{remote get}
+command (@pxref{File Transfer,,Sending files to a remote system}).
+The part of @var{path} following the initial @file{remote:}
+(if present) is used as system root prefix on the remote file system.
+@footnote{If you want to specify a local system root using a directory
+that happens to be named @file{remote:}, you need to use some equivalent
+variant of the name like @file{./remote:}.}
+
 The @code{set solib-absolute-prefix} command is an alias for @code{set
 sysroot}.
 
index 0847d67602e56a3834b06f5d9c5ae573ea3789aa..1d972ec87fb41432d170b3f55f2fec218b134dda 100644 (file)
@@ -6668,7 +6668,8 @@ remote_hostio_send_command (int command_bytes, int which_packet,
   int ret, bytes_read;
   char *attachment_tmp;
 
-  if (remote_protocol_packets[which_packet].support == PACKET_DISABLE)
+  if (!remote_desc
+      || remote_protocol_packets[which_packet].support == PACKET_DISABLE)
     {
       *remote_errno = FILEIO_ENOSYS;
       return -1;
@@ -6932,6 +6933,97 @@ remote_hostio_close_cleanup (void *opaque)
   remote_hostio_close (fd, &remote_errno);
 }
 
+
+static void *
+remote_bfd_iovec_open (struct bfd *abfd, void *open_closure)
+{
+  const char *filename = bfd_get_filename (abfd);
+  int fd, remote_errno;
+  int *stream;
+
+  gdb_assert (remote_filename_p (filename));
+
+  fd = remote_hostio_open (filename + 7, FILEIO_O_RDONLY, 0, &remote_errno);
+  if (fd == -1)
+    {
+      errno = remote_fileio_errno_to_host (remote_errno);
+      bfd_set_error (bfd_error_system_call);
+      return NULL;
+    }
+
+  stream = xmalloc (sizeof (int));
+  *stream = fd;
+  return stream;
+}
+
+static int
+remote_bfd_iovec_close (struct bfd *abfd, void *stream)
+{
+  int fd = *(int *)stream;
+  int remote_errno;
+
+  xfree (stream);
+
+  /* Ignore errors on close; these may happen if the remote
+     connection was already torn down.  */
+  remote_hostio_close (fd, &remote_errno);
+
+  return 1;
+}
+
+static file_ptr
+remote_bfd_iovec_pread (struct bfd *abfd, void *stream, void *buf,
+                       file_ptr nbytes, file_ptr offset)
+{
+  int fd = *(int *)stream;
+  int remote_errno;
+  file_ptr pos, bytes;
+
+  pos = 0;
+  while (nbytes > pos)
+    {
+      bytes = remote_hostio_pread (fd, (char *)buf + pos, nbytes - pos,
+                                  offset + pos, &remote_errno);
+      if (bytes == 0)
+        /* Success, but no bytes, means end-of-file.  */
+        break;
+      if (bytes == -1)
+       {
+         errno = remote_fileio_errno_to_host (remote_errno);
+         bfd_set_error (bfd_error_system_call);
+         return -1;
+       }
+
+      pos += bytes;
+    }
+
+  return pos;
+}
+
+static int
+remote_bfd_iovec_stat (struct bfd *abfd, void *stream, struct stat *sb)
+{
+  /* FIXME: We should probably implement remote_hostio_stat.  */
+  sb->st_size = INT_MAX;
+  return 0;
+}
+
+int
+remote_filename_p (const char *filename)
+{
+  return strncmp (filename, "remote:", 7) == 0;
+}
+
+bfd *
+remote_bfd_open (const char *remote_file, const char *target)
+{
+  return bfd_openr_iovec (remote_file, target,
+                         remote_bfd_iovec_open, NULL,
+                         remote_bfd_iovec_pread,
+                         remote_bfd_iovec_close,
+                         remote_bfd_iovec_stat);
+}
+
 void
 remote_file_put (const char *local_file, const char *remote_file, int from_tty)
 {
index 25fe82617baccf77113fb87bb20173efadf40df8..e40a6c2ee9434e346b2f26069c43ba4ff68e52b4 100644 (file)
@@ -73,4 +73,8 @@ void remote_file_get (const char *remote_file, const char *local_file,
                      int from_tty);
 void remote_file_delete (const char *remote_file, int from_tty);
 
+bfd *remote_bfd_open (const char *remote_file, const char *target);
+
+int remote_filename_p (const char *filename);
+
 #endif
index 6b6ff15fddceade5f319e9dcbbf0e56e69ea1eb4..189fbe02224078d141c0c4b59f8dabb9ec6e18f8 100644 (file)
@@ -30,6 +30,7 @@
 #include "command.h"
 #include "gdbcmd.h"
 #include "elf/frv.h"
+#include "exceptions.h"
 
 /* Flag which indicates whether internal debug messages should be printed.  */
 static int solib_frv_debug;
@@ -645,12 +646,11 @@ enable_break2 (void)
       unsigned int interp_sect_size;
       gdb_byte *buf;
       bfd *tmp_bfd = NULL;
-      int tmp_fd = -1;
-      char *tmp_pathname = NULL;
       int status;
       CORE_ADDR addr, interp_loadmap_addr;
       gdb_byte addr_buf[FRV_PTR_SIZE];
       struct int_elf32_fdpic_loadmap *ldm;
+      volatile struct gdb_exception ex;
 
       /* Read the contents of the .interp section into a local buffer;
          the contents specify the dynamic linker this program uses.  */
@@ -668,25 +668,16 @@ enable_break2 (void)
          be trivial on GNU/Linux).  Therefore, we have to try an alternate
          mechanism to find the dynamic linker's base address.  */
 
-      tmp_fd  = solib_open (buf, &tmp_pathname);
-      if (tmp_fd >= 0)
-       tmp_bfd = bfd_fopen (tmp_pathname, gnutarget, FOPEN_RB, tmp_fd);
-
+      TRY_CATCH (ex, RETURN_MASK_ALL)
+        {
+          tmp_bfd = solib_bfd_open (buf);
+        }
       if (tmp_bfd == NULL)
        {
          enable_break_failure_warning ();
          return 0;
        }
 
-      /* Make sure the dynamic linker is really a useful object.  */
-      if (!bfd_check_format (tmp_bfd, bfd_object))
-       {
-         warning (_("Unable to grok dynamic linker %s as an object file"), buf);
-         enable_break_failure_warning ();
-         bfd_close (tmp_bfd);
-         return 0;
-       }
-
       status = frv_fdpic_loadmap_addresses (target_gdbarch,
                                             &interp_loadmap_addr, 0);
       if (status < 0)
index 654c90687e906a6fd25d09d7fd1dfafa79ca9f86..4aff3831a01ad9ee7815c8f7eb3a7fda93c377b8 100644 (file)
@@ -42,6 +42,7 @@
 #include "elf-bfd.h"
 #include "exec.h"
 #include "auxv.h"
+#include "exceptions.h"
 
 static struct link_map_offsets *svr4_fetch_link_map_offsets (void);
 static int svr4_have_link_map_offsets (void);
@@ -1038,8 +1039,7 @@ enable_break (void)
       struct so_list *so;
       bfd *tmp_bfd = NULL;
       struct target_ops *tmp_bfd_target;
-      int tmp_fd = -1;
-      char *tmp_pathname = NULL;
+      volatile struct gdb_exception ex;
 
       /* Read the contents of the .interp section into a local buffer;
          the contents specify the dynamic linker this program uses.  */
@@ -1058,21 +1058,13 @@ enable_break (void)
          be trivial on GNU/Linux).  Therefore, we have to try an alternate
          mechanism to find the dynamic linker's base address.  */
 
-      tmp_fd = solib_open (buf, &tmp_pathname);
-      if (tmp_fd >= 0)
-       tmp_bfd = bfd_fopen (tmp_pathname, gnutarget, FOPEN_RB, tmp_fd);
-
+      TRY_CATCH (ex, RETURN_MASK_ALL)
+        {
+         tmp_bfd = solib_bfd_open (buf);
+       }
       if (tmp_bfd == NULL)
        goto bkpt_at_symbol;
 
-      /* Make sure the dynamic linker's really a useful object.  */
-      if (!bfd_check_format (tmp_bfd, bfd_object))
-       {
-         warning (_("Unable to grok dynamic linker %s as an object file"), buf);
-         bfd_close (tmp_bfd);
-         goto bkpt_at_symbol;
-       }
-
       /* Now convert the TMP_BFD into a target.  That way target, as
          well as BFD operations can be used.  Note that closing the
          target will also close the underlying bfd.  */
@@ -1166,7 +1158,6 @@ enable_break (void)
       /* For whatever reason we couldn't set a breakpoint in the dynamic
          linker.  Warn and drop into the old code.  */
     bkpt_at_symbol:
-      xfree (tmp_pathname);
       warning (_("Unable to find dynamic linker breakpoint function.\n"
                "GDB will be unable to debug shared library initializers\n"
                "and track explicitly loaded dynamic code."));
index 1812eada138c8bc97d851bed574d632213eed257..7ca3a42021ae3e0bf5ef67082d502310db36c761 100644 (file)
@@ -44,6 +44,7 @@
 #include "solist.h"
 #include "observer.h"
 #include "readline/readline.h"
+#include "remote.h"
 
 /* Architecture-specific operations.  */
 
@@ -106,11 +107,11 @@ The search path for loading non-absolute shared library symbol files is %s.\n"),
 
    GLOBAL FUNCTION
 
-   solib_open -- Find a shared library file and open it.
+   solib_bfd_open -- Find a shared library file and open BFD for it.
 
    SYNOPSIS
 
-   int solib_open (char *in_patname, char **found_pathname);
+   struct bfd *solib_open (char *in_pathname);
 
    DESCRIPTION
 
@@ -137,16 +138,17 @@ The search path for loading non-absolute shared library symbol files is %s.\n"),
 
    RETURNS
 
-   file handle for opened solib, or -1 for failure.  */
+   BFD file handle for opened solib; throws error on failure.  */
 
-int
-solib_open (char *in_pathname, char **found_pathname)
+bfd *
+solib_bfd_open (char *in_pathname)
 {
   struct target_so_ops *ops = solib_ops (target_gdbarch);
   int found_file = -1;
   char *temp_pathname = NULL;
   char *p = in_pathname;
   int gdb_sysroot_is_empty;
+  bfd *abfd;
 
   gdb_sysroot_is_empty = (gdb_sysroot == NULL || *gdb_sysroot == 0);
 
@@ -168,6 +170,29 @@ solib_open (char *in_pathname, char **found_pathname)
       strcat (temp_pathname, in_pathname);
     }
 
+  /* Handle remote files.  */
+  if (remote_filename_p (temp_pathname))
+    {
+      temp_pathname = xstrdup (temp_pathname);
+      abfd = remote_bfd_open (temp_pathname, gnutarget);
+      if (!abfd)
+       {
+         make_cleanup (xfree, temp_pathname);
+         error (_("Could not open `%s' as an executable file: %s"),
+                temp_pathname, bfd_errmsg (bfd_get_error ()));
+       }
+
+      if (!bfd_check_format (abfd, bfd_object))
+       {
+         bfd_close (abfd);
+         make_cleanup (xfree, temp_pathname);
+         error (_("`%s': not in executable format: %s"),
+                temp_pathname, bfd_errmsg (bfd_get_error ()));
+       }
+
+      return abfd;
+    }
+
   /* Now see if we can open it.  */
   found_file = open (temp_pathname, O_RDONLY | O_BINARY, 0);
 
@@ -228,16 +253,30 @@ solib_open (char *in_pathname, char **found_pathname)
                        OPF_TRY_CWD_FIRST, in_pathname, O_RDONLY | O_BINARY, 0,
                        &temp_pathname);
 
-  /* Done.  If not found, tough luck.  Return found_file and 
-     (optionally) found_pathname.  */
-  if (temp_pathname)
+  /* Done.  If still not found, error.  */
+  if (found_file < 0)
+    perror_with_name (in_pathname);
+
+  /* Leave temp_pathname allocated.  abfd->name will point to it.  */
+  abfd = bfd_fopen (temp_pathname, gnutarget, FOPEN_RB, found_file);
+  if (!abfd)
     {
-      if (found_pathname != NULL)
-       *found_pathname = temp_pathname;
-      else
-       xfree (temp_pathname);
+      close (found_file);
+      make_cleanup (xfree, temp_pathname);
+      error (_("Could not open `%s' as an executable file: %s"),
+            temp_pathname, bfd_errmsg (bfd_get_error ()));
+    }
+
+  if (!bfd_check_format (abfd, bfd_object))
+    {
+      bfd_close (abfd);
+      make_cleanup (xfree, temp_pathname);
+      error (_("`%s': not in executable format: %s"),
+            temp_pathname, bfd_errmsg (bfd_get_error ()));
     }
-  return found_file;
+
+  bfd_set_cacheable (abfd, 1);
+  return abfd;
 }
 
 
@@ -273,46 +312,24 @@ solib_map_sections (void *arg)
 {
   struct so_list *so = (struct so_list *) arg; /* catch_errors bogon */
   char *filename;
-  char *scratch_pathname;
-  int scratch_chan;
   struct section_table *p;
   struct cleanup *old_chain;
   bfd *abfd;
 
   filename = tilde_expand (so->so_name);
-
   old_chain = make_cleanup (xfree, filename);
-  scratch_chan = solib_open (filename, &scratch_pathname);
-
-  if (scratch_chan < 0)
-    {
-      perror_with_name (filename);
-    }
-
-  /* Leave scratch_pathname allocated.  abfd->name will point to it.  */
-  abfd = bfd_fopen (scratch_pathname, gnutarget, FOPEN_RB, scratch_chan);
-  if (!abfd)
-    {
-      close (scratch_chan);
-      error (_("Could not open `%s' as an executable file: %s"),
-            scratch_pathname, bfd_errmsg (bfd_get_error ()));
-    }
+  abfd = solib_bfd_open (filename);
+  do_cleanups (old_chain);
 
   /* Leave bfd open, core_xfer_memory and "info files" need it.  */
   so->abfd = abfd;
-  bfd_set_cacheable (abfd, 1);
 
   /* copy full path name into so_name, so that later symbol_file_add
      can find it */
-  if (strlen (scratch_pathname) >= SO_NAME_MAX_PATH_SIZE)
-    error (_("Full path name length of shared library exceeds SO_NAME_MAX_PATH_SIZE in so_list structure."));
-  strcpy (so->so_name, scratch_pathname);
+  if (strlen (bfd_get_filename (abfd)) >= SO_NAME_MAX_PATH_SIZE)
+    error (_("Shared library file name is too long."));
+  strcpy (so->so_name, bfd_get_filename (abfd));
 
-  if (!bfd_check_format (abfd, bfd_object))
-    {
-      error (_("\"%s\": not in executable format: %s."),
-            scratch_pathname, bfd_errmsg (bfd_get_error ()));
-    }
   if (build_section_table (abfd, &so->sections, &so->sections_end))
     {
       error (_("Can't find the file sections in `%s': %s"),
@@ -339,9 +356,6 @@ solib_map_sections (void *arg)
        }
     }
 
-  /* Free the file names, close the file now.  */
-  do_cleanups (old_chain);
-
   return (1);
 }
 
index fb104b49db85d0af9a88e1f30de67fc99bab3b61..4a40a2d191d0b472e9810359a6f585c415588b92 100644 (file)
@@ -127,7 +127,7 @@ void free_so (struct so_list *so);
 struct so_list *master_so_list (void);
 
 /* Find solib binary file and open it.  */
-extern int solib_open (char *in_pathname, char **found_pathname);
+extern bfd *solib_bfd_open (char *in_pathname);
 
 /* FIXME: gdbarch needs to control this variable */
 extern struct target_so_ops *current_target_so_ops;
index faa375b7e24f6cdd725fc98fe79b6815f6a108e4..8d22005eda6a7363abab072ff20e864b77b40c5c 100644 (file)
@@ -53,6 +53,7 @@
 #include "varobj.h"
 #include "elf-bfd.h"
 #include "solib.h"
+#include "remote.h"
 
 #include <sys/types.h>
 #include <fcntl.h>
@@ -1216,7 +1217,10 @@ build_id_verify (const char *filename, struct build_id *check)
   int retval = 0;
 
   /* We expect to be silent on the non-existing files.  */
-  abfd = bfd_openr (filename, gnutarget);
+  if (remote_filename_p (filename))
+    abfd = remote_bfd_open (filename, gnutarget);
+  else
+    abfd = bfd_openr (filename, gnutarget);
   if (abfd == NULL)
     return 0;
 
@@ -1307,18 +1311,22 @@ static int
 separate_debug_file_exists (const char *name, unsigned long crc)
 {
   unsigned long file_crc = 0;
-  int fd;
+  bfd *abfd;
   gdb_byte buffer[8*1024];
   int count;
 
-  fd = open (name, O_RDONLY | O_BINARY);
-  if (fd < 0)
+  if (remote_filename_p (name))
+    abfd = remote_bfd_open (name, gnutarget);
+  else
+    abfd = bfd_openr (name, gnutarget);
+
+  if (!abfd)
     return 0;
 
-  while ((count = read (fd, buffer, sizeof (buffer))) > 0)
+  while ((count = bfd_bread (buffer, sizeof (buffer), abfd)) > 0)
     file_crc = gnu_debuglink_crc32 (file_crc, buffer, count);
 
-  close (fd);
+  bfd_close (abfd);
 
   return crc == file_crc;
 }
@@ -1564,6 +1572,28 @@ symfile_bfd_open (char *name)
   int desc;
   char *absolute_name;
 
+  if (remote_filename_p (name))
+    {
+      name = xstrdup (name);
+      sym_bfd = remote_bfd_open (name, gnutarget);
+      if (!sym_bfd)
+       {
+         make_cleanup (xfree, name);
+         error (_("`%s': can't open to read symbols: %s."), name,
+                bfd_errmsg (bfd_get_error ()));
+       }
+
+      if (!bfd_check_format (sym_bfd, bfd_object))
+       {
+         bfd_close (sym_bfd);
+         make_cleanup (xfree, name);
+         error (_("`%s': can't read symbols: %s."), name,
+                bfd_errmsg (bfd_get_error ()));
+       }
+
+      return sym_bfd;
+    }
+
   name = tilde_expand (name);  /* Returns 1st new malloc'd copy.  */
 
   /* Look down path for it, allocate 2nd new malloc'd copy.  */
@@ -1594,7 +1624,7 @@ symfile_bfd_open (char *name)
     {
       close (desc);
       make_cleanup (xfree, name);
-      error (_("\"%s\": can't open to read symbols: %s."), name,
+      error (_("`%s': can't open to read symbols: %s."), name,
             bfd_errmsg (bfd_get_error ()));
     }
   bfd_set_cacheable (sym_bfd, 1);
@@ -1606,7 +1636,7 @@ symfile_bfd_open (char *name)
          with the bfd).  */
       bfd_close (sym_bfd);     /* This also closes desc.  */
       make_cleanup (xfree, name);
-      error (_("\"%s\": can't read symbols: %s."), name,
+      error (_("`%s': can't read symbols: %s."), name,
             bfd_errmsg (bfd_get_error ()));
     }
 
@@ -2307,7 +2337,10 @@ reread_symbols (void)
              if (!bfd_close (objfile->obfd))
                error (_("Can't close BFD for %s: %s"), objfile->name,
                       bfd_errmsg (bfd_get_error ()));
-             objfile->obfd = bfd_openr (obfd_filename, gnutarget);
+             if (remote_filename_p (obfd_filename))
+               objfile->obfd = remote_bfd_open (obfd_filename, gnutarget);
+             else
+               objfile->obfd = bfd_openr (obfd_filename, gnutarget);
              if (objfile->obfd == NULL)
                error (_("Can't open %s to read symbols."), objfile->name);
              /* bfd_openr sets cacheable to true, which is what we want.  */