1
2 #include "inc.h"
3
4 /*
5 * Retrieve 'len' bytes from the memory of the traced process 'pid' at address
6 * 'addr' and put the result in the buffer pointed to by 'ptr'. Return 0 on
7 * success, or otherwise -1 with errno set appropriately.
8 */
9 int
mem_get_data(pid_t pid,vir_bytes addr,void * ptr,size_t len)10 mem_get_data(pid_t pid, vir_bytes addr, void * ptr, size_t len)
11 {
12 struct ptrace_range pr;
13
14 if (len == 0) return 0;
15
16 pr.pr_space = TS_DATA;
17 pr.pr_addr = addr;
18 pr.pr_size = len;
19 pr.pr_ptr = ptr;
20
21 return ptrace(T_GETRANGE, pid, &pr, 0);
22 }
23
24 /*
25 * Retrieve 'len' bytes from the kernel structure memory of the traced process
26 * 'pid' at offset 'addr' and put the result in the buffer pointed to by 'ptr'.
27 * Return 0 on success, or otherwise -1 with errno set appropriately.
28 */
29 int
mem_get_user(pid_t pid,vir_bytes addr,void * ptr,size_t len)30 mem_get_user(pid_t pid, vir_bytes addr, void * ptr, size_t len)
31 {
32 long data;
33 char *p;
34 size_t off, chunk;
35
36 if (len == 0) return 0;
37
38 /* Align access to address. */
39 off = addr & (sizeof(data) - 1);
40 addr -= off;
41
42 p = ptr;
43
44 while (len > 0) {
45 errno = 0;
46 data = ptrace(T_GETUSER, pid, (void *)addr, 0);
47 if (errno != 0) return -1;
48
49 chunk = sizeof(data) - off;
50 if (chunk > len)
51 chunk = len;
52
53 memcpy(p, (char *)&data + off, chunk);
54 p += chunk;
55 addr += chunk;
56 len -= chunk;
57 off = 0;
58 }
59
60 return 0;
61 }
62