From patchwork Fri Jan 20 18:14:10 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ulrich Weigand X-Patchwork-Id: 6326 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 097D223F8D for ; Fri, 20 Jan 2012 18:14:20 +0000 (UTC) Received: from mail-bk0-f52.google.com (mail-bk0-f52.google.com [209.85.214.52]) by fiordland.canonical.com (Postfix) with ESMTP id D9BE0A18202 for ; Fri, 20 Jan 2012 18:14:19 +0000 (UTC) Received: by bkar19 with SMTP id r19so767889bka.11 for ; Fri, 20 Jan 2012 10:14:19 -0800 (PST) Received: by 10.204.153.27 with SMTP id i27mr12407405bkw.81.1327083259525; Fri, 20 Jan 2012 10:14:19 -0800 (PST) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.205.82.144 with SMTP id ac16cs13071bkc; Fri, 20 Jan 2012 10:14:17 -0800 (PST) Received: by 10.14.16.23 with SMTP id g23mr3643512eeg.5.1327083255661; Fri, 20 Jan 2012 10:14:15 -0800 (PST) Received: from e06smtp16.uk.ibm.com (e06smtp16.uk.ibm.com. [195.75.94.112]) by mx.google.com with ESMTPS id u56si2319947eef.211.2012.01.20.10.14.15 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 20 Jan 2012 10:14:15 -0800 (PST) Received-SPF: pass (google.com: domain of uweigand@de.ibm.com designates 195.75.94.112 as permitted sender) client-ip=195.75.94.112; Authentication-Results: mx.google.com; spf=pass (google.com: domain of uweigand@de.ibm.com designates 195.75.94.112 as permitted sender) smtp.mail=uweigand@de.ibm.com Received: from /spool/local by e06smtp16.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Fri, 20 Jan 2012 18:14:15 -0000 Received: from d06nrmr1806.portsmouth.uk.ibm.com (9.149.39.193) by e06smtp16.uk.ibm.com (192.168.101.146) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Fri, 20 Jan 2012 18:14:12 -0000 Received: from d06av02.portsmouth.uk.ibm.com (d06av02.portsmouth.uk.ibm.com [9.149.37.228]) by d06nrmr1806.portsmouth.uk.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id q0KIECpR2932884 for ; Fri, 20 Jan 2012 18:14:12 GMT Received: from d06av02.portsmouth.uk.ibm.com (loopback [127.0.0.1]) by d06av02.portsmouth.uk.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id q0KIEBTh032204 for ; Fri, 20 Jan 2012 11:14:12 -0700 Received: from tuxmaker.boeblingen.de.ibm.com (tuxmaker.boeblingen.de.ibm.com [9.152.85.9]) by d06av02.portsmouth.uk.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with SMTP id q0KIEAlS032145 for ; Fri, 20 Jan 2012 11:14:10 -0700 Message-Id: <201201201814.q0KIEAlS032145@d06av02.portsmouth.uk.ibm.com> Received: by tuxmaker.boeblingen.de.ibm.com (sSMTP sendmail emulation); Fri, 20 Jan 2012 19:14:10 +0100 Subject: [rfc v4][3/6] File I/O target operations To: patches@linaro.org Date: Fri, 20 Jan 2012 19:14:10 +0100 (CET) From: "Ulrich Weigand" X-Mailer: ELM [version 2.5 PL2] MIME-Version: 1.0 x-cbid: 12012018-3548-0000-0000-000000D082A9 http://sourceware.org/ml/gdb-patches/2012-01/msg00688.html ChangeLog: * 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. Index: gdb-head/gdb/inf-child.c =================================================================== --- gdb-head.orig/gdb/inf-child.c 2012-01-19 10:35:59.000000000 +0100 +++ gdb-head/gdb/inf-child.c 2012-01-19 10:39:32.000000000 +0100 @@ -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; } Index: gdb-head/gdb/remote.c =================================================================== --- gdb-head.orig/gdb/remote.c 2012-01-19 10:39:30.000000000 +0100 +++ gdb-head/gdb/remote.c 2012-01-19 10:39:32.000000000 +0100 @@ -10674,6 +10674,11 @@ Specify the serial device it is connecte 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; Index: gdb-head/gdb/target.c =================================================================== --- gdb-head.orig/gdb/target.c 2012-01-19 10:35:58.000000000 +0100 +++ gdb-head/gdb/target.c 2012-01-19 10:39:32.000000000 +0100 @@ -42,6 +42,7 @@ #include "exec.h" #include "inline-frame.h" #include "tracepoint.h" +#include "gdb/fileio.h" static void target_info (char *, int); @@ -2345,7 +2346,7 @@ target_read_stralloc (struct target_ops const char *annex) { gdb_byte *buffer; - LONGEST transferred; + LONGEST i, transferred; transferred = target_read_alloc_1 (ops, object, annex, &buffer, 1); @@ -2356,10 +2357,16 @@ target_read_stralloc (struct target_ops 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; } @@ -3160,6 +3167,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) { Index: gdb-head/gdb/target.h =================================================================== --- gdb-head.orig/gdb/target.h 2012-01-19 10:35:58.000000000 +0100 +++ gdb-head/gdb/target.h 2012-01-19 10:39:32.000000000 +0100 @@ -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_AD 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() \ Index: gdb-head/gdb/config.in =================================================================== --- gdb-head.orig/gdb/config.in 2012-01-19 10:38:28.000000000 +0100 +++ gdb-head/gdb/config.in 2012-01-19 10:39:32.000000000 +0100 @@ -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 Index: gdb-head/gdb/configure =================================================================== --- gdb-head.orig/gdb/configure 2012-01-19 10:38:28.000000000 +0100 +++ gdb-head/gdb/configure 2012-01-19 10:40:05.000000000 +0100 @@ -12931,8 +12931,9 @@ $as_echo "#define HAVE_WORKING_FORK 1" > 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 Index: gdb-head/gdb/configure.ac =================================================================== --- gdb-head.orig/gdb/configure.ac 2012-01-19 10:38:28.000000000 +0100 +++ gdb-head/gdb/configure.ac 2012-01-19 10:39:32.000000000 +0100 @@ -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])