summaryrefslogtreecommitdiff
path: root/minix/usr.bin/trace/mem.c
blob: e0b67270b8e535cd654577af4be54c6a47fa9586 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61

#include "inc.h"

/*
 * Retrieve 'len' bytes from the memory of the traced process 'pid' at address
 * 'addr' and put the result in the buffer pointed to by 'ptr'.  Return 0 on
 * success, or otherwise -1 with errno set appropriately.
 */
int
mem_get_data(pid_t pid, vir_bytes addr, void * ptr, size_t len)
{
	struct ptrace_range pr;

	if (len == 0) return 0;

	pr.pr_space = TS_DATA;
	pr.pr_addr = addr;
	pr.pr_size = len;
	pr.pr_ptr = ptr;

	return ptrace(T_GETRANGE, pid, &pr, 0);
}

/*
 * Retrieve 'len' bytes from the kernel structure memory of the traced process
 * 'pid' at offset 'addr' and put the result in the buffer pointed to by 'ptr'.
 * Return 0 on success, or otherwise -1 with errno set appropriately.
 */
int
mem_get_user(pid_t pid, vir_bytes addr, void * ptr, size_t len)
{
	long data;
	char *p;
	size_t off, chunk;

	if (len == 0) return 0;

	/* Align access to address. */
	off = addr & (sizeof(data) - 1);
	addr -= off;

	p = ptr;

	while (len > 0) {
		errno = 0;
		data = ptrace(T_GETUSER, pid, (void *)addr, 0);
		if (errno != 0) return -1;

		chunk = sizeof(data) - off;
		if (chunk > len)
			chunk = len;

		memcpy(p, (char *)&data + off, chunk);
		p += chunk;
		addr += chunk;
		len -= chunk;
		off = 0;
	}

	return 0;
}