/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
+/* Define to 1 if you have the <minix/config.h> header file. */
+#undef HAVE_MINIX_CONFIG_H
+
+/* Define to 1 if process_vm_readv is available. */
+#undef HAVE_PROCESS_VM
+
/* Define to 1 if stdbool.h conforms to C99. */
#undef HAVE_STDBOOL_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
+/* Define to 1 if you have the <sys/uio.h> header file. */
+#undef HAVE_SYS_UIO_H
+
/* Define to 1 if the system has the type `uintptr_t'. */
#undef HAVE_UINTPTR_T
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
+/* Define to 1 if you have the <wchar.h> header file. */
+#undef HAVE_WCHAR_H
+
/* Define to 1 if the system has the type `_Bool'. */
#undef HAVE__BOOL
/* Define to word type used by tracees. */
#undef USER_WORD
+/* Enable extensions on AIX 3, Interix. */
+#ifndef _ALL_SOURCE
+# undef _ALL_SOURCE
+#endif
+/* Enable general extensions on macOS. */
+#ifndef _DARWIN_C_SOURCE
+# undef _DARWIN_C_SOURCE
+#endif
+/* Enable general extensions on Solaris. */
+#ifndef __EXTENSIONS__
+# undef __EXTENSIONS__
+#endif
+/* Enable GNU extensions on systems that have them. */
+#ifndef _GNU_SOURCE
+# undef _GNU_SOURCE
+#endif
+/* Enable X/Open compliant socket functions that do not require linking
+ with -lxnet on HP-UX 11.11. */
+#ifndef _HPUX_ALT_XOPEN_SOCKET_API
+# undef _HPUX_ALT_XOPEN_SOCKET_API
+#endif
+/* Identify the host operating system as Minix.
+ This macro does not affect the system headers' behavior.
+ A future release of Autoconf may stop defining this macro. */
+#ifndef _MINIX
+# undef _MINIX
+#endif
+/* Enable general extensions on NetBSD.
+ Enable NetBSD compatibility extensions on Minix. */
+#ifndef _NETBSD_SOURCE
+# undef _NETBSD_SOURCE
+#endif
+/* Enable OpenBSD compatibility extensions on NetBSD.
+ Oddly enough, this does nothing on OpenBSD. */
+#ifndef _OPENBSD_SOURCE
+# undef _OPENBSD_SOURCE
+#endif
+/* Define to 1 if needed for POSIX-compatible behavior. */
+#ifndef _POSIX_SOURCE
+# undef _POSIX_SOURCE
+#endif
+/* Define to 2 if needed for POSIX-compatible behavior. */
+#ifndef _POSIX_1_SOURCE
+# undef _POSIX_1_SOURCE
+#endif
+/* Enable POSIX-compatible threading on Solaris. */
+#ifndef _POSIX_PTHREAD_SEMANTICS
+# undef _POSIX_PTHREAD_SEMANTICS
+#endif
+/* Enable extensions specified by ISO/IEC TS 18661-5:2014. */
+#ifndef __STDC_WANT_IEC_60559_ATTRIBS_EXT__
+# undef __STDC_WANT_IEC_60559_ATTRIBS_EXT__
+#endif
+/* Enable extensions specified by ISO/IEC TS 18661-1:2014. */
+#ifndef __STDC_WANT_IEC_60559_BFP_EXT__
+# undef __STDC_WANT_IEC_60559_BFP_EXT__
+#endif
+/* Enable extensions specified by ISO/IEC TS 18661-2:2015. */
+#ifndef __STDC_WANT_IEC_60559_DFP_EXT__
+# undef __STDC_WANT_IEC_60559_DFP_EXT__
+#endif
+/* Enable extensions specified by ISO/IEC TS 18661-4:2015. */
+#ifndef __STDC_WANT_IEC_60559_FUNCS_EXT__
+# undef __STDC_WANT_IEC_60559_FUNCS_EXT__
+#endif
+/* Enable extensions specified by ISO/IEC TS 18661-3:2015. */
+#ifndef __STDC_WANT_IEC_60559_TYPES_EXT__
+# undef __STDC_WANT_IEC_60559_TYPES_EXT__
+#endif
+/* Enable extensions specified by ISO/IEC TR 24731-2:2010. */
+#ifndef __STDC_WANT_LIB_EXT2__
+# undef __STDC_WANT_LIB_EXT2__
+#endif
+/* Enable extensions specified by ISO/IEC 24747:2009. */
+#ifndef __STDC_WANT_MATH_SPEC_FUNCS__
+# undef __STDC_WANT_MATH_SPEC_FUNCS__
+#endif
+/* Enable extensions on HP NonStop. */
+#ifndef _TANDEM_SOURCE
+# undef _TANDEM_SOURCE
+#endif
+/* Enable X/Open extensions. Define to 500 only if necessary
+ to make mbstate_t available. */
+#ifndef _XOPEN_SOURCE
+# undef _XOPEN_SOURCE
+#endif
+
+
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */
#if defined AC_APPLE_UNIVERSAL_BUILD
/* Define as a signed integer type capable of holding a process identifier. */
#undef pid_t
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+#undef size_t
+
+/* Define to `int' if <sys/types.h> does not define. */
+#undef ssize_t
+
/* Define to the type of an unsigned integer type of width exactly 16 bits if
such a type exists and the standard includes do not define it. */
#undef uint16_t
[Generate library which can be used within a signal handler.])],
[AC_DEFINE([REENTRANT], [1])])
+AC_USE_SYSTEM_EXTENSIONS
AC_PROG_CC
AC_PROG_CPP
AC_PROG_INSTALL
AC_TYPE_UINT32_T
AC_TYPE_UINT64_T
AC_TYPE_UINTPTR_T
+AC_TYPE_SIZE_T
+AC_TYPE_SSIZE_T
AC_TYPE_PID_T
AC_HEADER_STDBOOL
AC_CHECK_FUNCS([getpagesize stpcpy stpncpy])
AC_CHECK_DECLS([stpcpy, stpncpy])
-AC_CHECK_HEADERS([sys/param.h]) dnl for MIN and MAX
+AC_CHECK_FUNC([process_vm_readv],
+ [AC_CHECK_FUNC([process_vm_writev],
+ [AC_CHECK_DECL([process_vm_readv],
+ [AC_DEFINE([HAVE_PROCESS_VM], [1],
+ [Define to 1 if process_vm_readv is available.])],
+ [], [[
+#include <sys/uio.h>
+ ]])])])
+AC_CHECK_HEADERS([sys/param.h sys/uio.h])
AH_BOTTOM([
#ifdef HAVE_STDBOOL_H
#include <linux/elf.h> /* for NT_* */
#endif /* __aarch64__ */
+#ifdef HAVE_SYS_UIO_H
+#include <sys/uio.h> /* for process_vm_readv */
+#endif /* HAVE_SYS_UIO_H */
+
\f
/* Program tracing functions.
\f
/* Read N bytes from TRACEE's memory, starting at the specified user
- ADDRESS. Return its contents in BUFFER. */
+ ADDRESS. Return its contents in BUFFER.
+
+ If there are unreadable pages within ADDRESS + N, the contents of
+ BUFFER after the first such page becomes undefined. */
static void
read_memory (struct exec_tracee *tracee, char *buffer,
{
USER_WORD word, n_words, n_bytes, i;
long rc;
+#ifdef HAVE_PROCESS_VM
+ struct iovec iov, remote;
+
+ /* If `process_vm_readv' is available, use it instead. */
+
+ iov.iov_base = buffer;
+ iov.iov_len = n;
+ remote.iov_base = (void *) address;
+ remote.iov_len = n;
+
+ /* Return immediately if successful. As long as some bytes were
+ read, consider the read to have been a success. */
+
+ if (n <= SSIZE_MAX
+ && ((size_t) process_vm_readv (tracee->pid, &iov, 1,
+ &remote, 1, 0) != -1))
+ return;
+
+#endif /* HAVE_PROCESS_VM */
/* First, read entire words from the tracee. */
n_words = n & ~(sizeof (USER_WORD) - 1);
{
USER_WORD start, end, word;
unsigned char *bytes;
+#ifdef HAVE_PROCESS_VM
+ struct iovec iov, remote;
+
+ /* Try to use `process_vm_writev' if possible, but fall back to
+ ptrace if something bad happens. */
+
+ iov.iov_base = (void *) buffer;
+ iov.iov_len = n;
+ remote.iov_base = (void *) address;
+ remote.iov_len = n;
+
+ if (n <= SSIZE_MAX
+ && ((size_t) process_vm_writev (tracee->pid, &iov, 1,
+ &remote, 1, 0) == n))
+ return 0;
+#endif /* HAVE_PROCESS_VM */
/* Calculate the start and end positions for the write. */