2 * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
3 * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
5 * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
6 * Copyright (c) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
7 * Linux for s390 port by D.J. Barrow
8 * <barrow_dj@mail.yahoo.com,djbarrow@de.ibm.com>
9 * Copyright (c) 1999-2018 The strace developers.
10 * All rights reserved.
12 * SPDX-License-Identifier: LGPL-2.1-or-later
21 static bool process_vm_readv_not_supported;
23 #ifndef HAVE_PROCESS_VM_READV
25 * Need to do this since process_vm_readv() is not yet available in libc.
26 * When libc is updated, only "static bool process_vm_readv_not_supported"
28 * The name is different to avoid potential collision with OS headers.
30 static ssize_t strace_process_vm_readv(pid_t pid,
31 const struct iovec *lvec,
32 unsigned long liovcnt,
33 const struct iovec *rvec,
34 unsigned long riovcnt,
37 return syscall(__NR_process_vm_readv,
38 (long) pid, lvec, liovcnt, rvec, riovcnt, flags);
40 # define process_vm_readv strace_process_vm_readv
41 #endif /* !HAVE_PROCESS_VM_READV */
44 process_read_mem(const pid_t pid, void *const laddr,
45 void *const raddr, const size_t len)
47 const struct iovec local = {
51 const struct iovec remote = {
56 const ssize_t rc = process_vm_readv(pid, &local, 1, &remote, 1, 0);
57 if (rc < 0 && errno == ENOSYS)
58 process_vm_readv_not_supported = true;
63 static int cached_idx = -1;
64 static unsigned long cached_raddr[2];
67 invalidate_umove_cache(void)
73 vm_read_mem(const pid_t pid, void *const laddr,
74 const kernel_ulong_t raddr, const size_t len)
79 const unsigned long taddr = raddr;
81 #if SIZEOF_LONG < SIZEOF_KERNEL_LONG_T
82 if (raddr != (kernel_ulong_t) taddr) {
88 const size_t page_size = get_pagesize();
89 const size_t page_mask = page_size - 1;
90 const unsigned long raddr_page_start =
92 const unsigned long raddr_page_next =
93 (taddr + len + page_mask) & ~page_mask;
95 if (!raddr_page_start ||
96 raddr_page_next < raddr_page_start ||
97 raddr_page_next - raddr_page_start != page_size)
98 return process_read_mem(pid, laddr, (void *) taddr, len);
101 if (cached_idx >= 0) {
102 if (raddr_page_start == cached_raddr[cached_idx])
104 else if (raddr_page_start == cached_raddr[!cached_idx])
114 buf[idx] = xmalloc(page_size);
117 process_read_mem(pid, buf[idx],
118 (void *) raddr_page_start, page_size);
122 cached_raddr[idx] = raddr_page_start;
124 cached_raddr[!idx] = 0;
128 memcpy(laddr, buf[idx] + (taddr - cached_raddr[idx]), len);
133 tracee_addr_is_invalid(kernel_ulong_t addr)
136 #if ANY_WORDSIZE_LESS_THAN_KERNEL_LONG
137 current_wordsize < sizeof(addr) && addr & ~(kernel_ulong_t) -1U;
143 /* legacy method of copying from tracee */
145 umoven_peekdata(const int pid, kernel_ulong_t addr, unsigned int len,
148 unsigned int nread = 0;
149 unsigned int residue = addr & (sizeof(long) - 1);
152 addr &= -sizeof(long); /* aligned address */
157 char x[sizeof(long)];
158 } u = { .val = ptrace(PTRACE_PEEKDATA, pid, addr, 0) };
163 case ESRCH: case EINVAL:
164 /* these could be seen if the process is gone */
166 case EFAULT: case EIO: case EPERM:
167 /* address space is inaccessible */
169 perror_func_msg("short read (%u < %u)"
176 /* all the rest is strange and should be reported */
177 perror_func_msg("pid:%d @0x%" PRI_klx,
182 unsigned int m = MIN(sizeof(long) - residue, len);
183 memcpy(laddr, &u.x[residue], m);
185 addr += sizeof(long);
195 * Copy `len' bytes of data from process `pid'
196 * at address `addr' to our space at `our_addr'.
199 umoven(struct tcb *const tcp, kernel_ulong_t addr, unsigned int len,
200 void *const our_addr)
202 if (tracee_addr_is_invalid(addr))
205 const int pid = tcp->pid;
207 if (process_vm_readv_not_supported)
208 return umoven_peekdata(pid, addr, len, our_addr);
210 int r = vm_read_mem(pid, our_addr, addr, len);
211 if ((unsigned int) r == len)
214 error_func_msg("short read (%u < %u) @0x%" PRI_klx,
215 (unsigned int) r, len, addr);
221 /* try PTRACE_PEEKDATA */
222 return umoven_peekdata(pid, addr, len, our_addr);
224 /* the process is gone */
226 case EFAULT: case EIO:
227 /* address space is inaccessible */
230 /* all the rest is strange and should be reported */
231 perror_func_msg("pid:%d @0x%" PRI_klx, pid, addr);
237 * Like umoven_peekdata but make the additional effort of looking
238 * for a terminating zero byte.
241 umovestr_peekdata(const int pid, kernel_ulong_t addr, unsigned int len,
244 unsigned int nread = 0;
245 unsigned int residue = addr & (sizeof(long) - 1);
246 void *const orig_addr = laddr;
249 addr &= -sizeof(long); /* aligned address */
254 char x[sizeof(long)];
255 } u = { .val = ptrace(PTRACE_PEEKDATA, pid, addr, 0) };
260 case ESRCH: case EINVAL:
261 /* these could be seen if the process is gone */
263 case EFAULT: case EIO: case EPERM:
264 /* address space is inaccessible */
266 perror_func_msg("short read (%d < %d)"
273 /* all the rest is strange and should be reported */
274 perror_func_msg("pid:%d @0x%" PRI_klx,
279 unsigned int m = MIN(sizeof(long) - residue, len);
280 memcpy(laddr, &u.x[residue], m);
281 while (residue < sizeof(long))
282 if (u.x[residue++] == '\0')
283 return (laddr - orig_addr) + residue;
285 addr += sizeof(long);
295 * Like `umove' but make the additional effort of looking
296 * for a terminating zero byte.
298 * Returns < 0 on error, strlen + 1 if NUL was seen,
299 * else 0 if len bytes were read but no NUL byte seen.
301 * Note: there is no guarantee we won't overwrite some bytes
302 * in laddr[] _after_ terminating NUL (but, of course,
303 * we never write past laddr[len-1]).
306 umovestr(struct tcb *const tcp, kernel_ulong_t addr, unsigned int len,
309 if (tracee_addr_is_invalid(addr))
312 const int pid = tcp->pid;
314 if (process_vm_readv_not_supported)
315 return umovestr_peekdata(pid, addr, len, laddr);
317 const size_t page_size = get_pagesize();
318 const size_t page_mask = page_size - 1;
319 unsigned int nread = 0;
323 * Don't cross pages, otherwise we can get EFAULT
324 * and fail to notice that terminating NUL lies
325 * in the existing (first) page.
327 unsigned int chunk_len = len > page_size ? page_size : len;
328 unsigned int end_in_page = (addr + chunk_len) & page_mask;
329 if (chunk_len > end_in_page) /* crosses to the next page */
330 chunk_len -= end_in_page;
332 int r = vm_read_mem(pid, laddr, addr, chunk_len);
334 char *nul_addr = memchr(laddr, '\0', r);
337 return (nul_addr - laddr) + 1;
347 /* try PTRACE_PEEKDATA */
349 return umovestr_peekdata(pid, addr,
351 ATTRIBUTE_FALLTHROUGH;
352 case EFAULT: case EIO:
353 /* address space is inaccessible */
355 perror_func_msg("short read (%d < %d)"
361 /* the process is gone */
364 /* all the rest is strange and should be reported */
365 perror_func_msg("pid:%d @0x%" PRI_klx, pid, addr);