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