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