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.
This commit is contained in:
parent
901f991244
commit
7313baad7c
8 changed files with 616 additions and 9 deletions
|
@ -1,3 +1,45 @@
|
||||||
|
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.
|
||||||
|
|
||||||
2012-01-20 Pedro Alves <palves@redhat.com>
|
2012-01-20 Pedro Alves <palves@redhat.com>
|
||||||
Ulrich Weigand <ulrich.weigand@linaro.org>
|
Ulrich Weigand <ulrich.weigand@linaro.org>
|
||||||
|
|
||||||
|
|
|
@ -324,6 +324,9 @@
|
||||||
/* Define to 1 if you have the `posix_madvise' function. */
|
/* Define to 1 if you have the `posix_madvise' function. */
|
||||||
#undef HAVE_POSIX_MADVISE
|
#undef HAVE_POSIX_MADVISE
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `pread' function. */
|
||||||
|
#undef HAVE_PREAD
|
||||||
|
|
||||||
/* Define to 1 if you have the `pread64' function. */
|
/* Define to 1 if you have the `pread64' function. */
|
||||||
#undef HAVE_PREAD64
|
#undef HAVE_PREAD64
|
||||||
|
|
||||||
|
@ -381,6 +384,9 @@
|
||||||
/* Define if sys/ptrace.h defines the PT_GETXMMREGS request. */
|
/* Define if sys/ptrace.h defines the PT_GETXMMREGS request. */
|
||||||
#undef HAVE_PT_GETXMMREGS
|
#undef HAVE_PT_GETXMMREGS
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `pwrite' function. */
|
||||||
|
#undef HAVE_PWRITE
|
||||||
|
|
||||||
/* Define if Python interpreter is being linked in. */
|
/* Define if Python interpreter is being linked in. */
|
||||||
#undef HAVE_PYTHON
|
#undef HAVE_PYTHON
|
||||||
|
|
||||||
|
|
5
gdb/configure
vendored
5
gdb/configure
vendored
|
@ -12931,8 +12931,9 @@ $as_echo "#define HAVE_WORKING_FORK 1" >>confdefs.h
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
for ac_func in canonicalize_file_name realpath getrusage getuid \
|
for ac_func in canonicalize_file_name realpath getrusage getuid getgid \
|
||||||
getgid pipe poll pread64 resize_term sbrk setpgid setpgrp setsid \
|
pipe poll pread pread64 pwrite resize_term \
|
||||||
|
sbrk setpgid setpgrp setsid \
|
||||||
sigaction sigprocmask sigsetmask socketpair syscall \
|
sigaction sigprocmask sigsetmask socketpair syscall \
|
||||||
ttrace wborder wresize setlocale iconvlist libiconvlist btowc \
|
ttrace wborder wresize setlocale iconvlist libiconvlist btowc \
|
||||||
setrlimit getrlimit posix_madvise waitpid lstat
|
setrlimit getrlimit posix_madvise waitpid lstat
|
||||||
|
|
|
@ -1063,8 +1063,9 @@ AC_C_BIGENDIAN
|
||||||
AC_FUNC_ALLOCA
|
AC_FUNC_ALLOCA
|
||||||
AC_FUNC_MMAP
|
AC_FUNC_MMAP
|
||||||
AC_FUNC_VFORK
|
AC_FUNC_VFORK
|
||||||
AC_CHECK_FUNCS([canonicalize_file_name realpath getrusage getuid \
|
AC_CHECK_FUNCS([canonicalize_file_name realpath getrusage getuid getgid \
|
||||||
getgid pipe poll pread64 resize_term sbrk setpgid setpgrp setsid \
|
pipe poll pread pread64 pwrite resize_term \
|
||||||
|
sbrk setpgid setpgrp setsid \
|
||||||
sigaction sigprocmask sigsetmask socketpair syscall \
|
sigaction sigprocmask sigsetmask socketpair syscall \
|
||||||
ttrace wborder wresize setlocale iconvlist libiconvlist btowc \
|
ttrace wborder wresize setlocale iconvlist libiconvlist btowc \
|
||||||
setrlimit getrlimit posix_madvise waitpid lstat])
|
setrlimit getrlimit posix_madvise waitpid lstat])
|
||||||
|
|
197
gdb/inf-child.c
197
gdb/inf-child.c
|
@ -27,6 +27,12 @@
|
||||||
#include "inferior.h"
|
#include "inferior.h"
|
||||||
#include "gdb_string.h"
|
#include "gdb_string.h"
|
||||||
#include "inf-child.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
|
/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this
|
||||||
for all registers. */
|
for all registers. */
|
||||||
|
@ -108,6 +114,192 @@ inf_child_pid_to_exec_file (int pid)
|
||||||
return NULL;
|
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 *
|
struct target_ops *
|
||||||
inf_child_target (void)
|
inf_child_target (void)
|
||||||
{
|
{
|
||||||
|
@ -139,6 +331,11 @@ inf_child_target (void)
|
||||||
t->to_has_stack = default_child_has_stack;
|
t->to_has_stack = default_child_has_stack;
|
||||||
t->to_has_registers = default_child_has_registers;
|
t->to_has_registers = default_child_has_registers;
|
||||||
t->to_has_execution = default_child_has_execution;
|
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;
|
t->to_magic = OPS_MAGIC;
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10674,6 +10674,11 @@ Specify the serial device it is connected to\n\
|
||||||
remote_ops.to_supports_multi_process = remote_supports_multi_process;
|
remote_ops.to_supports_multi_process = remote_supports_multi_process;
|
||||||
remote_ops.to_supports_disable_randomization
|
remote_ops.to_supports_disable_randomization
|
||||||
= remote_supports_disable_randomization;
|
= remote_supports_disable_randomization;
|
||||||
|
remote_ops.to_fileio_open = remote_hostio_open;
|
||||||
|
remote_ops.to_fileio_pwrite = remote_hostio_pwrite;
|
||||||
|
remote_ops.to_fileio_pread = remote_hostio_pread;
|
||||||
|
remote_ops.to_fileio_close = remote_hostio_close;
|
||||||
|
remote_ops.to_fileio_unlink = remote_hostio_unlink;
|
||||||
remote_ops.to_supports_enable_disable_tracepoint = remote_supports_enable_disable_tracepoint;
|
remote_ops.to_supports_enable_disable_tracepoint = remote_supports_enable_disable_tracepoint;
|
||||||
remote_ops.to_supports_string_tracing = remote_supports_string_tracing;
|
remote_ops.to_supports_string_tracing = remote_supports_string_tracing;
|
||||||
remote_ops.to_trace_init = remote_trace_init;
|
remote_ops.to_trace_init = remote_trace_init;
|
||||||
|
|
288
gdb/target.c
288
gdb/target.c
|
@ -42,6 +42,7 @@
|
||||||
#include "exec.h"
|
#include "exec.h"
|
||||||
#include "inline-frame.h"
|
#include "inline-frame.h"
|
||||||
#include "tracepoint.h"
|
#include "tracepoint.h"
|
||||||
|
#include "gdb/fileio.h"
|
||||||
|
|
||||||
static void target_info (char *, int);
|
static void target_info (char *, int);
|
||||||
|
|
||||||
|
@ -2344,7 +2345,7 @@ target_read_stralloc (struct target_ops *ops, enum target_object object,
|
||||||
const char *annex)
|
const char *annex)
|
||||||
{
|
{
|
||||||
gdb_byte *buffer;
|
gdb_byte *buffer;
|
||||||
LONGEST transferred;
|
LONGEST i, transferred;
|
||||||
|
|
||||||
transferred = target_read_alloc_1 (ops, object, annex, &buffer, 1);
|
transferred = target_read_alloc_1 (ops, object, annex, &buffer, 1);
|
||||||
|
|
||||||
|
@ -2355,10 +2356,16 @@ target_read_stralloc (struct target_ops *ops, enum target_object object,
|
||||||
return xstrdup ("");
|
return xstrdup ("");
|
||||||
|
|
||||||
buffer[transferred] = 0;
|
buffer[transferred] = 0;
|
||||||
if (strlen (buffer) < transferred)
|
|
||||||
warning (_("target object %d, annex %s, "
|
/* Check for embedded NUL bytes; but allow trailing NULs. */
|
||||||
"contained unexpected null characters"),
|
for (i = strlen (buffer); i < transferred; i++)
|
||||||
(int) object, annex ? annex : "(none)");
|
if (buffer[i] != 0)
|
||||||
|
{
|
||||||
|
warning (_("target object %d, annex %s, "
|
||||||
|
"contained unexpected null characters"),
|
||||||
|
(int) object, annex ? annex : "(none)");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return (char *) buffer;
|
return (char *) buffer;
|
||||||
}
|
}
|
||||||
|
@ -3159,6 +3166,277 @@ target_thread_address_space (ptid_t ptid)
|
||||||
return inf->aspace;
|
return inf->aspace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Target file operations. */
|
||||||
|
|
||||||
|
static struct target_ops *
|
||||||
|
default_fileio_target (void)
|
||||||
|
{
|
||||||
|
/* If we're already connected to something that can perform
|
||||||
|
file I/O, use it. Otherwise, try using the native target. */
|
||||||
|
if (current_target.to_stratum >= process_stratum)
|
||||||
|
return current_target.beneath;
|
||||||
|
else
|
||||||
|
return find_default_run_target ("file I/O");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Open FILENAME on the target, using FLAGS and MODE. Return a
|
||||||
|
target file descriptor, or -1 if an error occurs (and set
|
||||||
|
*TARGET_ERRNO). */
|
||||||
|
int
|
||||||
|
target_fileio_open (const char *filename, int flags, int mode,
|
||||||
|
int *target_errno)
|
||||||
|
{
|
||||||
|
struct target_ops *t;
|
||||||
|
|
||||||
|
for (t = default_fileio_target (); t != NULL; t = t->beneath)
|
||||||
|
{
|
||||||
|
if (t->to_fileio_open != NULL)
|
||||||
|
{
|
||||||
|
int fd = t->to_fileio_open (filename, flags, mode, target_errno);
|
||||||
|
|
||||||
|
if (targetdebug)
|
||||||
|
fprintf_unfiltered (gdb_stdlog,
|
||||||
|
"target_fileio_open (%s,0x%x,0%o) = %d (%d)\n",
|
||||||
|
filename, flags, mode,
|
||||||
|
fd, fd != -1 ? 0 : *target_errno);
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*target_errno = FILEIO_ENOSYS;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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). */
|
||||||
|
int
|
||||||
|
target_fileio_pwrite (int fd, const gdb_byte *write_buf, int len,
|
||||||
|
ULONGEST offset, int *target_errno)
|
||||||
|
{
|
||||||
|
struct target_ops *t;
|
||||||
|
|
||||||
|
for (t = default_fileio_target (); t != NULL; t = t->beneath)
|
||||||
|
{
|
||||||
|
if (t->to_fileio_pwrite != NULL)
|
||||||
|
{
|
||||||
|
int ret = t->to_fileio_pwrite (fd, write_buf, len, offset,
|
||||||
|
target_errno);
|
||||||
|
|
||||||
|
if (targetdebug)
|
||||||
|
fprintf_unfiltered (gdb_stdlog,
|
||||||
|
"target_fileio_pwrite (%d,%p,%d,%s) "
|
||||||
|
"= %d (%d)\n",
|
||||||
|
fd, write_buf, len, pulongest (offset),
|
||||||
|
ret, ret != -1 ? 0 : *target_errno);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*target_errno = FILEIO_ENOSYS;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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). */
|
||||||
|
int
|
||||||
|
target_fileio_pread (int fd, gdb_byte *read_buf, int len,
|
||||||
|
ULONGEST offset, int *target_errno)
|
||||||
|
{
|
||||||
|
struct target_ops *t;
|
||||||
|
|
||||||
|
for (t = default_fileio_target (); t != NULL; t = t->beneath)
|
||||||
|
{
|
||||||
|
if (t->to_fileio_pread != NULL)
|
||||||
|
{
|
||||||
|
int ret = t->to_fileio_pread (fd, read_buf, len, offset,
|
||||||
|
target_errno);
|
||||||
|
|
||||||
|
if (targetdebug)
|
||||||
|
fprintf_unfiltered (gdb_stdlog,
|
||||||
|
"target_fileio_pread (%d,%p,%d,%s) "
|
||||||
|
"= %d (%d)\n",
|
||||||
|
fd, read_buf, len, pulongest (offset),
|
||||||
|
ret, ret != -1 ? 0 : *target_errno);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*target_errno = FILEIO_ENOSYS;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close FD on the target. Return 0, or -1 if an error occurs
|
||||||
|
(and set *TARGET_ERRNO). */
|
||||||
|
int
|
||||||
|
target_fileio_close (int fd, int *target_errno)
|
||||||
|
{
|
||||||
|
struct target_ops *t;
|
||||||
|
|
||||||
|
for (t = default_fileio_target (); t != NULL; t = t->beneath)
|
||||||
|
{
|
||||||
|
if (t->to_fileio_close != NULL)
|
||||||
|
{
|
||||||
|
int ret = t->to_fileio_close (fd, target_errno);
|
||||||
|
|
||||||
|
if (targetdebug)
|
||||||
|
fprintf_unfiltered (gdb_stdlog,
|
||||||
|
"target_fileio_close (%d) = %d (%d)\n",
|
||||||
|
fd, ret, ret != -1 ? 0 : *target_errno);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*target_errno = FILEIO_ENOSYS;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unlink FILENAME on the target. Return 0, or -1 if an error
|
||||||
|
occurs (and set *TARGET_ERRNO). */
|
||||||
|
int
|
||||||
|
target_fileio_unlink (const char *filename, int *target_errno)
|
||||||
|
{
|
||||||
|
struct target_ops *t;
|
||||||
|
|
||||||
|
for (t = default_fileio_target (); t != NULL; t = t->beneath)
|
||||||
|
{
|
||||||
|
if (t->to_fileio_unlink != NULL)
|
||||||
|
{
|
||||||
|
int ret = t->to_fileio_unlink (filename, target_errno);
|
||||||
|
|
||||||
|
if (targetdebug)
|
||||||
|
fprintf_unfiltered (gdb_stdlog,
|
||||||
|
"target_fileio_unlink (%s) = %d (%d)\n",
|
||||||
|
filename, ret, ret != -1 ? 0 : *target_errno);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*target_errno = FILEIO_ENOSYS;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
target_fileio_close_cleanup (void *opaque)
|
||||||
|
{
|
||||||
|
int fd = *(int *) opaque;
|
||||||
|
int target_errno;
|
||||||
|
|
||||||
|
target_fileio_close (fd, &target_errno);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read target file FILENAME. Store the result in *BUF_P and
|
||||||
|
return the size of the transferred data. PADDING additional bytes are
|
||||||
|
available in *BUF_P. This is a helper function for
|
||||||
|
target_fileio_read_alloc; see the declaration of that function for more
|
||||||
|
information. */
|
||||||
|
|
||||||
|
static LONGEST
|
||||||
|
target_fileio_read_alloc_1 (const char *filename,
|
||||||
|
gdb_byte **buf_p, int padding)
|
||||||
|
{
|
||||||
|
struct cleanup *close_cleanup;
|
||||||
|
size_t buf_alloc, buf_pos;
|
||||||
|
gdb_byte *buf;
|
||||||
|
LONGEST n;
|
||||||
|
int fd;
|
||||||
|
int target_errno;
|
||||||
|
|
||||||
|
fd = target_fileio_open (filename, FILEIO_O_RDONLY, 0700, &target_errno);
|
||||||
|
if (fd == -1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
close_cleanup = make_cleanup (target_fileio_close_cleanup, &fd);
|
||||||
|
|
||||||
|
/* Start by reading up to 4K at a time. The target will throttle
|
||||||
|
this number down if necessary. */
|
||||||
|
buf_alloc = 4096;
|
||||||
|
buf = xmalloc (buf_alloc);
|
||||||
|
buf_pos = 0;
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
n = target_fileio_pread (fd, &buf[buf_pos],
|
||||||
|
buf_alloc - buf_pos - padding, buf_pos,
|
||||||
|
&target_errno);
|
||||||
|
if (n < 0)
|
||||||
|
{
|
||||||
|
/* An error occurred. */
|
||||||
|
do_cleanups (close_cleanup);
|
||||||
|
xfree (buf);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else if (n == 0)
|
||||||
|
{
|
||||||
|
/* Read all there was. */
|
||||||
|
do_cleanups (close_cleanup);
|
||||||
|
if (buf_pos == 0)
|
||||||
|
xfree (buf);
|
||||||
|
else
|
||||||
|
*buf_p = buf;
|
||||||
|
return buf_pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf_pos += n;
|
||||||
|
|
||||||
|
/* If the buffer is filling up, expand it. */
|
||||||
|
if (buf_alloc < buf_pos * 2)
|
||||||
|
{
|
||||||
|
buf_alloc *= 2;
|
||||||
|
buf = xrealloc (buf, buf_alloc);
|
||||||
|
}
|
||||||
|
|
||||||
|
QUIT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read target file FILENAME. Store the result in *BUF_P and return
|
||||||
|
the size of the transferred data. See the declaration in "target.h"
|
||||||
|
function for more information about the return value. */
|
||||||
|
|
||||||
|
LONGEST
|
||||||
|
target_fileio_read_alloc (const char *filename, gdb_byte **buf_p)
|
||||||
|
{
|
||||||
|
return target_fileio_read_alloc_1 (filename, buf_p, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read target file FILENAME. The result is NUL-terminated and
|
||||||
|
returned as a string, allocated using xmalloc. If an error occurs
|
||||||
|
or the transfer is unsupported, NULL is returned. Empty objects
|
||||||
|
are returned as allocated but empty strings. A warning is issued
|
||||||
|
if the result contains any embedded NUL bytes. */
|
||||||
|
|
||||||
|
char *
|
||||||
|
target_fileio_read_stralloc (const char *filename)
|
||||||
|
{
|
||||||
|
gdb_byte *buffer;
|
||||||
|
LONGEST i, transferred;
|
||||||
|
|
||||||
|
transferred = target_fileio_read_alloc_1 (filename, &buffer, 1);
|
||||||
|
|
||||||
|
if (transferred < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (transferred == 0)
|
||||||
|
return xstrdup ("");
|
||||||
|
|
||||||
|
buffer[transferred] = 0;
|
||||||
|
|
||||||
|
/* Check for embedded NUL bytes; but allow trailing NULs. */
|
||||||
|
for (i = strlen (buffer); i < transferred; i++)
|
||||||
|
if (buffer[i] != 0)
|
||||||
|
{
|
||||||
|
warning (_("target file %s "
|
||||||
|
"contained unexpected null characters"),
|
||||||
|
filename);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (char *) buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
default_region_ok_for_hw_watchpoint (CORE_ADDR addr, int len)
|
default_region_ok_for_hw_watchpoint (CORE_ADDR addr, int len)
|
||||||
{
|
{
|
||||||
|
|
77
gdb/target.h
77
gdb/target.h
|
@ -681,6 +681,35 @@ struct target_ops
|
||||||
struct address_space *(*to_thread_address_space) (struct target_ops *,
|
struct address_space *(*to_thread_address_space) (struct target_ops *,
|
||||||
ptid_t);
|
ptid_t);
|
||||||
|
|
||||||
|
/* Target file operations. */
|
||||||
|
|
||||||
|
/* Open FILENAME on the target, using FLAGS and MODE. Return a
|
||||||
|
target file descriptor, or -1 if an error occurs (and set
|
||||||
|
*TARGET_ERRNO). */
|
||||||
|
int (*to_fileio_open) (const char *filename, int flags, int mode,
|
||||||
|
int *target_errno);
|
||||||
|
|
||||||
|
/* 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). */
|
||||||
|
int (*to_fileio_pwrite) (int fd, const gdb_byte *write_buf, int len,
|
||||||
|
ULONGEST offset, int *target_errno);
|
||||||
|
|
||||||
|
/* 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). */
|
||||||
|
int (*to_fileio_pread) (int fd, gdb_byte *read_buf, int len,
|
||||||
|
ULONGEST offset, int *target_errno);
|
||||||
|
|
||||||
|
/* Close FD on the target. Return 0, or -1 if an error occurs
|
||||||
|
(and set *TARGET_ERRNO). */
|
||||||
|
int (*to_fileio_close) (int fd, int *target_errno);
|
||||||
|
|
||||||
|
/* Unlink FILENAME on the target. Return 0, or -1 if an error
|
||||||
|
occurs (and set *TARGET_ERRNO). */
|
||||||
|
int (*to_fileio_unlink) (const char *filename, int *target_errno);
|
||||||
|
|
||||||
|
|
||||||
/* Tracepoint-related operations. */
|
/* Tracepoint-related operations. */
|
||||||
|
|
||||||
/* Prepare the target for a tracing run. */
|
/* Prepare the target for a tracing run. */
|
||||||
|
@ -1489,6 +1518,54 @@ extern int target_search_memory (CORE_ADDR start_addr,
|
||||||
ULONGEST pattern_len,
|
ULONGEST pattern_len,
|
||||||
CORE_ADDR *found_addrp);
|
CORE_ADDR *found_addrp);
|
||||||
|
|
||||||
|
/* Target file operations. */
|
||||||
|
|
||||||
|
/* Open FILENAME on the target, using FLAGS and MODE. Return a
|
||||||
|
target file descriptor, or -1 if an error occurs (and set
|
||||||
|
*TARGET_ERRNO). */
|
||||||
|
extern int target_fileio_open (const char *filename, int flags, int mode,
|
||||||
|
int *target_errno);
|
||||||
|
|
||||||
|
/* 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). */
|
||||||
|
extern int target_fileio_pwrite (int fd, const gdb_byte *write_buf, int len,
|
||||||
|
ULONGEST offset, int *target_errno);
|
||||||
|
|
||||||
|
/* 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). */
|
||||||
|
extern int target_fileio_pread (int fd, gdb_byte *read_buf, int len,
|
||||||
|
ULONGEST offset, int *target_errno);
|
||||||
|
|
||||||
|
/* Close FD on the target. Return 0, or -1 if an error occurs
|
||||||
|
(and set *TARGET_ERRNO). */
|
||||||
|
extern int target_fileio_close (int fd, int *target_errno);
|
||||||
|
|
||||||
|
/* Unlink FILENAME on the target. Return 0, or -1 if an error
|
||||||
|
occurs (and set *TARGET_ERRNO). */
|
||||||
|
extern int target_fileio_unlink (const char *filename, int *target_errno);
|
||||||
|
|
||||||
|
/* Read target file FILENAME. The return value will be -1 if the transfer
|
||||||
|
fails or is not supported; 0 if the object is empty; or the length
|
||||||
|
of the object otherwise. If a positive value is returned, a
|
||||||
|
sufficiently large buffer will be allocated using xmalloc and
|
||||||
|
returned in *BUF_P containing the contents of the object.
|
||||||
|
|
||||||
|
This method should be used for objects sufficiently small to store
|
||||||
|
in a single xmalloc'd buffer, when no fixed bound on the object's
|
||||||
|
size is known in advance. */
|
||||||
|
extern LONGEST target_fileio_read_alloc (const char *filename,
|
||||||
|
gdb_byte **buf_p);
|
||||||
|
|
||||||
|
/* Read target file FILENAME. The result is NUL-terminated and
|
||||||
|
returned as a string, allocated using xmalloc. If an error occurs
|
||||||
|
or the transfer is unsupported, NULL is returned. Empty objects
|
||||||
|
are returned as allocated but empty strings. A warning is issued
|
||||||
|
if the result contains any embedded NUL bytes. */
|
||||||
|
extern char *target_fileio_read_stralloc (const char *filename);
|
||||||
|
|
||||||
|
|
||||||
/* Tracepoint-related operations. */
|
/* Tracepoint-related operations. */
|
||||||
|
|
||||||
#define target_trace_init() \
|
#define target_trace_init() \
|
||||||
|
|
Loading…
Reference in a new issue