xref: /minix3/minix/usr.bin/trace/mem.c (revision 521fa314e2aaec3c192c15f2aaa4c677a544e62a)
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