diff options
Diffstat (limited to 'gdb/remote.c')
-rw-r--r-- | gdb/remote.c | 94 |
1 files changed, 93 insertions, 1 deletions
diff --git a/gdb/remote.c b/gdb/remote.c index 0847d67..1d972ec 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -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) { |