summaryrefslogtreecommitdiff
path: root/exec
diff options
context:
space:
mode:
authorPo Lu <luangruo@yahoo.com>2023-05-03 16:00:13 +0800
committerPo Lu <luangruo@yahoo.com>2023-05-03 16:00:13 +0800
commit7b3c774bcee29fa0a13f38a60ddebc6fbdbedd0e (patch)
tree2a541d968f9e3d0c90997621dc41f580d4e5f9e1 /exec
parent35eae084bcd2ece057e2e5fa89a11281c40e51f7 (diff)
downloademacs-7b3c774bcee29fa0a13f38a60ddebc6fbdbedd0e.tar.gz
Update Android port
* exec/config.h.in: Autoheader. * exec/configure.ac: Use system extensions. (HAVE_PROCESS_VM): Define if process_vm_readv and process_vm_writev are available. * exec/trace.c (read_memory, user_copy): Implement in terms of process_vm if possible.
Diffstat (limited to 'exec')
-rw-r--r--exec/config.h.in106
-rw-r--r--exec/configure.ac13
-rw-r--r--exec/trace.c44
3 files changed, 161 insertions, 2 deletions
diff --git a/exec/config.h.in b/exec/config.h.in
index c360e54a4ba..6301275fd8a 100644
--- a/exec/config.h.in
+++ b/exec/config.h.in
@@ -52,6 +52,12 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
/* 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
@@ -85,12 +91,18 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
/* 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
@@ -168,6 +180,94 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
/* 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
@@ -198,6 +298,12 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
/* 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
diff --git a/exec/configure.ac b/exec/configure.ac
index b948e184896..efefc6c7dbc 100644
--- a/exec/configure.ac
+++ b/exec/configure.ac
@@ -47,6 +47,7 @@ AC_ARG_WITH([reentrancy],
[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
@@ -56,12 +57,22 @@ AC_TYPE_UINT16_T
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
diff --git a/exec/trace.c b/exec/trace.c
index cb0839c9cd9..8d107696423 100644
--- a/exec/trace.c
+++ b/exec/trace.c
@@ -42,6 +42,10 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#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 */
+
/* Program tracing functions.
@@ -122,7 +126,10 @@ static struct exec_tracee *tracing_processes;
/* 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,
@@ -130,6 +137,25 @@ 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);
@@ -248,6 +274,22 @@ user_copy (struct exec_tracee *tracee, const unsigned char *buffer,
{
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. */