diff options
author | Ulrich Weigand <uweigand@de.ibm.com> | 2012-01-20 09:45:51 +0000 |
---|---|---|
committer | Ulrich Weigand <uweigand@de.ibm.com> | 2012-01-20 09:45:51 +0000 |
commit | 7313baad7c73664bed62b87481cbb078d71e84f4 (patch) | |
tree | 6b2214e0bc33bb629ea6abd5e4502ec494cc50b2 /gdb/inf-child.c | |
parent | 901f991244d02f62d4e7a9c903de9f05175de2ac (diff) | |
download | gdb-7313baad7c73664bed62b87481cbb078d71e84f4.zip gdb-7313baad7c73664bed62b87481cbb078d71e84f4.tar.gz gdb-7313baad7c73664bed62b87481cbb078d71e84f4.tar.bz2 |
2012-01-20 Pedro Alves <palves@redhat.com>
Ulrich Weigand <ulrich.weigand@linaro.org>
* configure.ac [AC_CHECK_FUNCS]: Check for pread and pwrite.
* config.in, configure: Regenerate.
* target.h (struct target_ops): Add to_fileio_open, to_fileio_pwrite,
to_fileio_pread, to_fileio_close, to_fileio_unlink.
(target_fileio_open): Add prototype.
(target_fileio_pwrite): Likewise.
(target_fileio_pread): Likewise.
(target_fileio_close): Likewise.
(target_fileio_unlink): Likewise.
(target_fileio_read_alloc): Likewise.
(target_fileio_read_stralloc): Likewise.
* target.c: Include "gdb/fileio.h".
(target_read_stralloc): Accept trailing, but not embedded NUL bytes.
(default_fileio_target): New function.
(target_fileio_open): Likewise.
(target_fileio_pwrite): Likewise.
(target_fileio_pread): Likewise.
(target_fileio_close): Likewise.
(target_fileio_unlink): Likewise.
(target_fileio_close_cleanup): Likewise.
(target_fileio_read_alloc_1): Likewise.
(target_fileio_read_alloc): Likewise.
(target_fileio_read_stralloc): Likewise.
* inf-child.c: Include "gdb/fileio.h", <sys/types.h>, <sys/stat.h>,
<fcntl.h>, and <unistd.h>.
(inf_child_fileio_open_flags_to_host): New function.
(inf_child_errno_to_fileio_error): Likewise.
(inf_child_fileio_open): Likewise.
(inf_child_fileio_pwrite): Likewise.
(inf_child_fileio_pread): Likewise.
(inf_child_fileio_close): Likewise.
(inf_child_fileio_unlink): Likewise.
(inf_child_target): Install to_fileio routines.
* remote.c (init_remote_ops): Install to_fileio routines.
Diffstat (limited to 'gdb/inf-child.c')
-rw-r--r-- | gdb/inf-child.c | 197 |
1 files changed, 197 insertions, 0 deletions
diff --git a/gdb/inf-child.c b/gdb/inf-child.c index c91a89b..0dda331 100644 --- a/gdb/inf-child.c +++ b/gdb/inf-child.c @@ -27,6 +27,12 @@ #include "inferior.h" #include "gdb_string.h" #include "inf-child.h" +#include "gdb/fileio.h" + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> /* Fetch register REGNUM from the inferior. If REGNUM is -1, do this for all registers. */ @@ -108,6 +114,192 @@ inf_child_pid_to_exec_file (int pid) return NULL; } + +/* Target file operations. */ + +static int +inf_child_fileio_open_flags_to_host (int fileio_open_flags, int *open_flags_p) +{ + int open_flags = 0; + + if (fileio_open_flags & ~FILEIO_O_SUPPORTED) + return -1; + + 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 + + *open_flags_p = open_flags; + return 0; +} + +static int +inf_child_errno_to_fileio_error (int errnum) +{ + switch (errnum) + { + case EPERM: + return FILEIO_EPERM; + case ENOENT: + return FILEIO_ENOENT; + case EINTR: + return FILEIO_EINTR; + case EIO: + return FILEIO_EIO; + case EBADF: + return FILEIO_EBADF; + case EACCES: + return FILEIO_EACCES; + case EFAULT: + return FILEIO_EFAULT; + case EBUSY: + return FILEIO_EBUSY; + case EEXIST: + return FILEIO_EEXIST; + case ENODEV: + return FILEIO_ENODEV; + case ENOTDIR: + return FILEIO_ENOTDIR; + case EISDIR: + return FILEIO_EISDIR; + case EINVAL: + return FILEIO_EINVAL; + case ENFILE: + return FILEIO_ENFILE; + case EMFILE: + return FILEIO_EMFILE; + case EFBIG: + return FILEIO_EFBIG; + case ENOSPC: + return FILEIO_ENOSPC; + case ESPIPE: + return FILEIO_ESPIPE; + case EROFS: + return FILEIO_EROFS; + case ENOSYS: + return FILEIO_ENOSYS; + case ENAMETOOLONG: + return FILEIO_ENAMETOOLONG; + } + return FILEIO_EUNKNOWN; +} + +/* Open FILENAME on the target, using FLAGS and MODE. Return a + target file descriptor, or -1 if an error occurs (and set + *TARGET_ERRNO). */ +static int +inf_child_fileio_open (const char *filename, int flags, int mode, + int *target_errno) +{ + int nat_flags; + int fd; + + if (inf_child_fileio_open_flags_to_host (flags, &nat_flags) == -1) + { + *target_errno = FILEIO_EINVAL; + return -1; + } + + /* We do not need to convert MODE, since the fileio protocol uses + the standard values. */ + fd = open (filename, nat_flags, mode); + if (fd == -1) + *target_errno = inf_child_errno_to_fileio_error (errno); + + return fd; +} + +/* Write up to LEN bytes from WRITE_BUF to FD on the target. + Return the number of bytes written, or -1 if an error occurs + (and set *TARGET_ERRNO). */ +static int +inf_child_fileio_pwrite (int fd, const gdb_byte *write_buf, int len, + ULONGEST offset, int *target_errno) +{ + int ret; + +#ifdef HAVE_PWRITE + ret = pwrite (fd, write_buf, len, (long) offset); +#else + ret = lseek (fd, (long) offset, SEEK_SET); + if (ret != -1) + ret = write (fd, write_buf, len); +#endif + + if (ret == -1) + *target_errno = inf_child_errno_to_fileio_error (errno); + + return ret; +} + +/* Read up to LEN bytes FD on the target into READ_BUF. + Return the number of bytes read, or -1 if an error occurs + (and set *TARGET_ERRNO). */ +static int +inf_child_fileio_pread (int fd, gdb_byte *read_buf, int len, + ULONGEST offset, int *target_errno) +{ + int ret; + +#ifdef HAVE_PREAD + ret = pread (fd, read_buf, len, (long) offset); +#else + ret = lseek (fd, (long) offset, SEEK_SET); + if (ret != -1) + ret = read (fd, read_buf, len); +#endif + + if (ret == -1) + *target_errno = inf_child_errno_to_fileio_error (errno); + + return ret; +} + +/* Close FD on the target. Return 0, or -1 if an error occurs + (and set *TARGET_ERRNO). */ +static int +inf_child_fileio_close (int fd, int *target_errno) +{ + int ret; + + ret = close (fd); + if (ret == -1) + *target_errno = inf_child_errno_to_fileio_error (errno); + + return ret; +} + +/* Unlink FILENAME on the target. Return 0, or -1 if an error + occurs (and set *TARGET_ERRNO). */ +static int +inf_child_fileio_unlink (const char *filename, int *target_errno) +{ + int ret; + + ret = unlink (filename); + if (ret == -1) + *target_errno = inf_child_errno_to_fileio_error (errno); + + return ret; +} + + struct target_ops * inf_child_target (void) { @@ -139,6 +331,11 @@ inf_child_target (void) t->to_has_stack = default_child_has_stack; t->to_has_registers = default_child_has_registers; t->to_has_execution = default_child_has_execution; + t->to_fileio_open = inf_child_fileio_open; + t->to_fileio_pwrite = inf_child_fileio_pwrite; + t->to_fileio_pread = inf_child_fileio_pread; + t->to_fileio_close = inf_child_fileio_close; + t->to_fileio_unlink = inf_child_fileio_unlink; t->to_magic = OPS_MAGIC; return t; } |