aboutsummaryrefslogtreecommitdiff
path: root/gdb/inf-child.c
diff options
context:
space:
mode:
authorUlrich Weigand <uweigand@de.ibm.com>2012-01-20 09:45:51 +0000
committerUlrich Weigand <uweigand@de.ibm.com>2012-01-20 09:45:51 +0000
commit7313baad7c73664bed62b87481cbb078d71e84f4 (patch)
tree6b2214e0bc33bb629ea6abd5e4502ec494cc50b2 /gdb/inf-child.c
parent901f991244d02f62d4e7a9c903de9f05175de2ac (diff)
downloadgdb-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.c197
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;
}