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