aboutsummaryrefslogtreecommitdiffstats
path: root/exec/trace.c
diff options
context:
space:
mode:
authorPo Lu2023-05-03 16:00:13 +0800
committerPo Lu2023-05-03 16:00:13 +0800
commit7b3c774bcee29fa0a13f38a60ddebc6fbdbedd0e (patch)
tree2a541d968f9e3d0c90997621dc41f580d4e5f9e1 /exec/trace.c
parent35eae084bcd2ece057e2e5fa89a11281c40e51f7 (diff)
downloademacs-7b3c774bcee29fa0a13f38a60ddebc6fbdbedd0e.tar.gz
emacs-7b3c774bcee29fa0a13f38a60ddebc6fbdbedd0e.zip
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/trace.c')
-rw-r--r--exec/trace.c44
1 files changed, 43 insertions, 1 deletions
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/>. */
42#include <linux/elf.h> /* for NT_* */ 42#include <linux/elf.h> /* for NT_* */
43#endif /* __aarch64__ */ 43#endif /* __aarch64__ */
44 44
45#ifdef HAVE_SYS_UIO_H
46#include <sys/uio.h> /* for process_vm_readv */
47#endif /* HAVE_SYS_UIO_H */
48
45 49
46 50
47/* Program tracing functions. 51/* Program tracing functions.
@@ -122,7 +126,10 @@ static struct exec_tracee *tracing_processes;
122 126
123 127
124/* Read N bytes from TRACEE's memory, starting at the specified user 128/* Read N bytes from TRACEE's memory, starting at the specified user
125 ADDRESS. Return its contents in BUFFER. */ 129 ADDRESS. Return its contents in BUFFER.
130
131 If there are unreadable pages within ADDRESS + N, the contents of
132 BUFFER after the first such page becomes undefined. */
126 133
127static void 134static void
128read_memory (struct exec_tracee *tracee, char *buffer, 135read_memory (struct exec_tracee *tracee, char *buffer,
@@ -130,6 +137,25 @@ read_memory (struct exec_tracee *tracee, char *buffer,
130{ 137{
131 USER_WORD word, n_words, n_bytes, i; 138 USER_WORD word, n_words, n_bytes, i;
132 long rc; 139 long rc;
140#ifdef HAVE_PROCESS_VM
141 struct iovec iov, remote;
142
143 /* If `process_vm_readv' is available, use it instead. */
144
145 iov.iov_base = buffer;
146 iov.iov_len = n;
147 remote.iov_base = (void *) address;
148 remote.iov_len = n;
149
150 /* Return immediately if successful. As long as some bytes were
151 read, consider the read to have been a success. */
152
153 if (n <= SSIZE_MAX
154 && ((size_t) process_vm_readv (tracee->pid, &iov, 1,
155 &remote, 1, 0) != -1))
156 return;
157
158#endif /* HAVE_PROCESS_VM */
133 159
134 /* First, read entire words from the tracee. */ 160 /* First, read entire words from the tracee. */
135 n_words = n & ~(sizeof (USER_WORD) - 1); 161 n_words = n & ~(sizeof (USER_WORD) - 1);
@@ -248,6 +274,22 @@ user_copy (struct exec_tracee *tracee, const unsigned char *buffer,
248{ 274{
249 USER_WORD start, end, word; 275 USER_WORD start, end, word;
250 unsigned char *bytes; 276 unsigned char *bytes;
277#ifdef HAVE_PROCESS_VM
278 struct iovec iov, remote;
279
280 /* Try to use `process_vm_writev' if possible, but fall back to
281 ptrace if something bad happens. */
282
283 iov.iov_base = (void *) buffer;
284 iov.iov_len = n;
285 remote.iov_base = (void *) address;
286 remote.iov_len = n;
287
288 if (n <= SSIZE_MAX
289 && ((size_t) process_vm_writev (tracee->pid, &iov, 1,
290 &remote, 1, 0) == n))
291 return 0;
292#endif /* HAVE_PROCESS_VM */
251 293
252 /* Calculate the start and end positions for the write. */ 294 /* Calculate the start and end positions for the write. */
253 295