breakpoint.c revision 3f1219f7803599df8556e7fc096a6a239f9a04fd
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 enable_breakpoint(pid_t pid, struct breakpoint *sbp)
17{
18	arch_enable_breakpoint(pid, sbp);
19}
20#else
21void enable_breakpoint(pid_t pid, struct breakpoint *sbp)
22{
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 disable_breakpoint(pid_t pid, const struct breakpoint *sbp)
47{
48	arch_disable_breakpoint(pid, sbp);
49}
50#else
51void disable_breakpoint(pid_t pid, const struct breakpoint *sbp)
52{
53	unsigned int i, j;
54
55	if (opt_d > 1) {
56		output_line(0, "disable_breakpoint(%d,%p)", pid, sbp->addr);
57	}
58
59	for (i = 0; i < 1 + ((BREAKPOINT_LENGTH - 1) / sizeof(long)); i++) {
60		long a =
61		    ptrace(PTRACE_PEEKTEXT, pid, sbp->addr + i * sizeof(long),
62			   0);
63		for (j = 0;
64		     j < sizeof(long)
65		     && i * sizeof(long) + j < BREAKPOINT_LENGTH; j++) {
66			unsigned char *bytes = (unsigned char *)&a;
67
68			bytes[j] = sbp->orig_value[i * sizeof(long) + j];
69		}
70		ptrace(PTRACE_POKETEXT, pid, sbp->addr + i * sizeof(long), a);
71	}
72}
73#endif				/* ARCH_HAVE_DISABLE_BREAKPOINT */
74