breakpoint.c revision 3219f320604810532a4938dda8f9dfadb0e840f3
1#if HAVE_CONFIG_H
2#include "config.h"
3#endif
4
5#include <sys/ptrace.h>
6#include "arch.h"
7#include "options.h"
8#include "output.h"
9
10static unsigned char break_insn[] = BREAKPOINT_VALUE;
11
12void enable_breakpoint(pid_t pid, struct breakpoint *sbp)
13{
14	int i, j;
15
16	if (opt_d > 1) {
17		output_line(0, "enable_breakpoint(%d,%p)", pid, sbp->addr);
18	}
19
20	for (i = 0; i < 1 + ((BREAKPOINT_LENGTH - 1) / sizeof(long)); i++) {
21		long a =
22		    ptrace(PTRACE_PEEKTEXT, pid, sbp->addr + i * sizeof(long),
23			   0);
24		for (j = 0;
25		     j < sizeof(long)
26		     && i * sizeof(long) + j < BREAKPOINT_LENGTH; j++) {
27			unsigned char *bytes = (unsigned char *)&a;
28
29			sbp->orig_value[i * sizeof(long) + j] = bytes[+j];
30			bytes[j] = break_insn[i * sizeof(long) + j];
31		}
32		ptrace(PTRACE_POKETEXT, pid, sbp->addr + i * sizeof(long), a);
33	}
34}
35
36void disable_breakpoint(pid_t pid, const struct breakpoint *sbp)
37{
38	int i, j;
39
40	if (opt_d > 1) {
41		output_line(0, "disable_breakpoint(%d,%p)", pid, sbp->addr);
42	}
43
44	for (i = 0; i < 1 + ((BREAKPOINT_LENGTH - 1) / sizeof(long)); i++) {
45		long a =
46		    ptrace(PTRACE_PEEKTEXT, pid, sbp->addr + i * sizeof(long),
47			   0);
48		for (j = 0;
49		     j < sizeof(long)
50		     && i * sizeof(long) + j < BREAKPOINT_LENGTH; j++) {
51			unsigned char *bytes = (unsigned char *)&a;
52
53			bytes[j] = sbp->orig_value[i * sizeof(long) + j];
54		}
55		ptrace(PTRACE_POKETEXT, pid, sbp->addr + i * sizeof(long), a);
56	}
57}
58