X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fgdbserver%2Fhostio.c;h=8af4fbf4087aa8866c21990529492ea3bbac002a;hb=4f83758119ddf0f114477760d79bdde7bbc76835;hp=b03b5ad11bf831b4e14445d70ddadd83add11b48;hpb=7823a9415b2919241f7a7425d9dcc3c62ada0779;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/gdbserver/hostio.c b/gdb/gdbserver/hostio.c index b03b5ad11b..8af4fbf408 100644 --- a/gdb/gdbserver/hostio.c +++ b/gdb/gdbserver/hostio.c @@ -1,5 +1,5 @@ /* Host file transfer support for gdbserver. - Copyright (C) 2007-2015 Free Software Foundation, Inc. + Copyright (C) 2007-2020 Free Software Foundation, Inc. Contributed by CodeSourcery. @@ -27,9 +27,7 @@ #include #include #include -#include "fileio.h" - -extern int remote_debug; +#include "gdbsupport/fileio.h" struct fd_list { @@ -96,22 +94,27 @@ static int require_int (char **pp, int *value) { char *p; - int count; + int count, firstdigit; p = *pp; *value = 0; count = 0; + firstdigit = -1; while (*p && *p != ',') { int nib; - /* Don't allow overflow. */ - if (count >= 7) + if (safe_fromhex (p[0], &nib)) return -1; - if (safe_fromhex (p[0], &nib)) + if (firstdigit == -1) + firstdigit = nib; + + /* Don't allow overflow. */ + if (count >= 8 || (count == 7 && firstdigit >= 0x8)) return -1; + *value = *value * 16 + nib; p++; count++; @@ -126,7 +129,7 @@ require_data (char *p, int p_len, char **data, int *data_len) { int input_index, output_index, escaped; - *data = xmalloc (p_len); + *data = (char *) xmalloc (p_len); output_index = 0; escaped = 0; @@ -243,36 +246,53 @@ hostio_reply_with_data (char *own_buf, char *buffer, int len, return input_index; } -static int -fileio_open_flags_to_host (int fileio_open_flags, int *open_flags_p) +/* Process ID of inferior whose filesystem hostio functions + that take FILENAME arguments will use. Zero means to use + our own filesystem. */ + +static int hostio_fs_pid; + +/* See hostio.h. */ + +void +hostio_handle_new_gdb_connection (void) { - int open_flags = 0; + hostio_fs_pid = 0; +} - if (fileio_open_flags & ~FILEIO_O_SUPPORTED) - return -1; +/* Handle a "vFile:setfs:" packet. */ - if (fileio_open_flags & FILEIO_O_CREAT) - open_flags |= O_CREAT; - if (fileio_open_flags & FILEIO_O_EXCL) - open_flags |= O_EXCL; - if (fileio_open_flags & FILEIO_O_TRUNC) - open_flags |= O_TRUNC; - if (fileio_open_flags & FILEIO_O_APPEND) - open_flags |= O_APPEND; - if (fileio_open_flags & FILEIO_O_RDONLY) - open_flags |= O_RDONLY; - if (fileio_open_flags & FILEIO_O_WRONLY) - open_flags |= O_WRONLY; - if (fileio_open_flags & FILEIO_O_RDWR) - open_flags |= O_RDWR; -/* On systems supporting binary and text mode, always open files in - binary mode. */ -#ifdef O_BINARY - open_flags |= O_BINARY; -#endif +static void +handle_setfs (char *own_buf) +{ + char *p; + int pid; + + /* If the target doesn't have any of the in-filesystem-of methods + then there's no point in GDB sending "vFile:setfs:" packets. We + reply with an empty packet (i.e. we pretend we don't understand + "vFile:setfs:") and that should stop GDB sending any more. */ + if (the_target->multifs_open == NULL + && the_target->multifs_unlink == NULL + && the_target->multifs_readlink == NULL) + { + own_buf[0] = '\0'; + return; + } - *open_flags_p = open_flags; - return 0; + p = own_buf + strlen ("vFile:setfs:"); + + if (require_int (&p, &pid) + || pid < 0 + || require_end (p)) + { + hostio_packet_error (own_buf); + return; + } + + hostio_fs_pid = pid; + + hostio_reply (own_buf, 0); } static void @@ -280,7 +300,8 @@ handle_open (char *own_buf) { char filename[HOSTIO_PATH_MAX]; char *p; - int fileio_flags, mode, flags, fd; + int fileio_flags, fileio_mode, flags, fd; + mode_t mode; struct fd_list *new_fd; p = own_buf + strlen ("vFile:open:"); @@ -289,9 +310,10 @@ handle_open (char *own_buf) || require_comma (&p) || require_int (&p, &fileio_flags) || require_comma (&p) - || require_int (&p, &mode) + || require_int (&p, &fileio_mode) || require_end (p) - || fileio_open_flags_to_host (fileio_flags, &flags)) + || fileio_to_host_openflags (fileio_flags, &flags) + || fileio_to_host_mode (fileio_mode, &mode)) { hostio_packet_error (own_buf); return; @@ -299,7 +321,11 @@ handle_open (char *own_buf) /* We do not need to convert MODE, since the fileio protocol uses the standard values. */ - fd = open (filename, flags, mode); + if (hostio_fs_pid != 0 && the_target->multifs_open != NULL) + fd = the_target->multifs_open (hostio_fs_pid, filename, + flags, mode); + else + fd = open (filename, flags, mode); if (fd == -1) { @@ -308,7 +334,7 @@ handle_open (char *own_buf) } /* Record the new file descriptor. */ - new_fd = xmalloc (sizeof (struct fd_list)); + new_fd = XNEW (struct fd_list); new_fd->fd = fd; new_fd->next = open_fds; open_fds = new_fd; @@ -321,6 +347,7 @@ handle_pread (char *own_buf, int *new_packet_len) { int fd, ret, len, offset, bytes_sent; char *p, *data; + static int max_reply_size = -1; p = own_buf + strlen ("vFile:pread:"); @@ -336,7 +363,18 @@ handle_pread (char *own_buf, int *new_packet_len) return; } - data = xmalloc (len); + /* Do not attempt to read more than the maximum number of bytes + hostio_reply_with_data can fit in a packet. We may still read + too much because of escaping, but this is handled below. */ + if (max_reply_size == -1) + { + sprintf (own_buf, "F%x;", PBUFSIZ); + max_reply_size = PBUFSIZ - strlen (own_buf); + } + if (len > max_reply_size) + len = max_reply_size; + + data = (char *) xmalloc (len); #ifdef HAVE_PREAD ret = pread (fd, data, len, offset); #else @@ -503,7 +541,10 @@ handle_unlink (char *own_buf) return; } - ret = unlink (filename); + if (hostio_fs_pid != 0 && the_target->multifs_unlink != NULL) + ret = the_target->multifs_unlink (hostio_fs_pid, filename); + else + ret = unlink (filename); if (ret == -1) { @@ -530,7 +571,13 @@ handle_readlink (char *own_buf, int *new_packet_len) return; } - ret = readlink (filename, linkname, sizeof (linkname) - 1); + if (hostio_fs_pid != 0 && the_target->multifs_readlink != NULL) + ret = the_target->multifs_readlink (hostio_fs_pid, filename, + linkname, + sizeof (linkname) - 1); + else + ret = readlink (filename, linkname, sizeof (linkname) - 1); + if (ret == -1) { hostio_error (own_buf); @@ -564,6 +611,8 @@ handle_vFile (char *own_buf, int packet_len, int *new_packet_len) handle_unlink (own_buf); else if (startswith (own_buf, "vFile:readlink:")) handle_readlink (own_buf, new_packet_len); + else if (startswith (own_buf, "vFile:setfs:")) + handle_setfs (own_buf); else return 0;