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