From: Ulrich Weigand Date: Fri, 20 Jan 2012 09:45:51 +0000 (+0000) Subject: 2012-01-20 Pedro Alves X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=7313baad7c73664bed62b87481cbb078d71e84f4;p=binutils-gdb.git 2012-01-20 Pedro Alves Ulrich Weigand * 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", , , , and . (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. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 6a94f5de392..65cfb170968 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,45 @@ +2012-01-20 Pedro Alves + Ulrich Weigand + + * 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", , , + , and . + (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 Ulrich Weigand diff --git a/gdb/config.in b/gdb/config.in index 45c2c73ff0a..540234fbb2a 100644 --- a/gdb/config.in +++ b/gdb/config.in @@ -324,6 +324,9 @@ /* Define to 1 if you have the `posix_madvise' function. */ #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. */ #undef HAVE_PREAD64 @@ -381,6 +384,9 @@ /* Define if sys/ptrace.h defines the PT_GETXMMREGS request. */ #undef HAVE_PT_GETXMMREGS +/* Define to 1 if you have the `pwrite' function. */ +#undef HAVE_PWRITE + /* Define if Python interpreter is being linked in. */ #undef HAVE_PYTHON diff --git a/gdb/configure b/gdb/configure index 2ced763c10a..5dd99fbc9fd 100755 --- a/gdb/configure +++ b/gdb/configure @@ -12931,8 +12931,9 @@ $as_echo "#define HAVE_WORKING_FORK 1" >>confdefs.h fi -for ac_func in canonicalize_file_name realpath getrusage getuid \ - getgid pipe poll pread64 resize_term sbrk setpgid setpgrp setsid \ +for ac_func in canonicalize_file_name realpath getrusage getuid getgid \ + pipe poll pread pread64 pwrite resize_term \ + sbrk setpgid setpgrp setsid \ sigaction sigprocmask sigsetmask socketpair syscall \ ttrace wborder wresize setlocale iconvlist libiconvlist btowc \ setrlimit getrlimit posix_madvise waitpid lstat diff --git a/gdb/configure.ac b/gdb/configure.ac index 66844ed614a..aca96b8ce34 100644 --- a/gdb/configure.ac +++ b/gdb/configure.ac @@ -1063,8 +1063,9 @@ AC_C_BIGENDIAN AC_FUNC_ALLOCA AC_FUNC_MMAP AC_FUNC_VFORK -AC_CHECK_FUNCS([canonicalize_file_name realpath getrusage getuid \ - getgid pipe poll pread64 resize_term sbrk setpgid setpgrp setsid \ +AC_CHECK_FUNCS([canonicalize_file_name realpath getrusage getuid getgid \ + pipe poll pread pread64 pwrite resize_term \ + sbrk setpgid setpgrp setsid \ sigaction sigprocmask sigsetmask socketpair syscall \ ttrace wborder wresize setlocale iconvlist libiconvlist btowc \ setrlimit getrlimit posix_madvise waitpid lstat]) diff --git a/gdb/inf-child.c b/gdb/inf-child.c index c91a89b0c99..0dda3315187 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 +#include +#include +#include /* 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; } diff --git a/gdb/remote.c b/gdb/remote.c index 2b46c43c065..89d491ee3be 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -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_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_string_tracing = remote_supports_string_tracing; remote_ops.to_trace_init = remote_trace_init; diff --git a/gdb/target.c b/gdb/target.c index 6af4620ddf7..595c2ced6c3 100644 --- a/gdb/target.c +++ b/gdb/target.c @@ -42,6 +42,7 @@ #include "exec.h" #include "inline-frame.h" #include "tracepoint.h" +#include "gdb/fileio.h" static void target_info (char *, int); @@ -2344,7 +2345,7 @@ target_read_stralloc (struct target_ops *ops, enum target_object object, const char *annex) { gdb_byte *buffer; - LONGEST transferred; + LONGEST i, transferred; 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 (""); buffer[transferred] = 0; - if (strlen (buffer) < transferred) - warning (_("target object %d, annex %s, " - "contained unexpected null characters"), - (int) object, annex ? annex : "(none)"); + + /* Check for embedded NUL bytes; but allow trailing NULs. */ + for (i = strlen (buffer); i < transferred; i++) + if (buffer[i] != 0) + { + warning (_("target object %d, annex %s, " + "contained unexpected null characters"), + (int) object, annex ? annex : "(none)"); + break; + } return (char *) buffer; } @@ -3159,6 +3166,277 @@ target_thread_address_space (ptid_t ptid) 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 default_region_ok_for_hw_watchpoint (CORE_ADDR addr, int len) { diff --git a/gdb/target.h b/gdb/target.h index 425c877077c..4bbf4de88d1 100644 --- a/gdb/target.h +++ b/gdb/target.h @@ -681,6 +681,35 @@ struct target_ops struct address_space *(*to_thread_address_space) (struct target_ops *, 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. */ /* Prepare the target for a tracing run. */ @@ -1489,6 +1518,54 @@ extern int target_search_memory (CORE_ADDR start_addr, ULONGEST pattern_len, 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. */ #define target_trace_init() \