blob: f005c6b64ee1c6ac6ecf4b46d0f0ef8425d0a24a [file] [log] [blame]
Juan Cespedesa4850832002-03-03 02:37:50 +01001#if HAVE_CONFIG_H
2#include "config.h"
3#endif
4
5#include <sys/ptrace.h>
Ian Wienand5570a772006-02-17 02:00:00 +01006#include <string.h>
Juan Cespedes61da3372009-07-03 11:55:44 +02007
Juan Cespedes8d1b92b2009-07-03 10:39:34 +02008#include "common.h"
Juan Cespedes2a61d192009-07-04 11:29:27 +02009#include "arch.h"
Juan Cespedesa4850832002-03-03 02:37:50 +010010
11static unsigned char break_insn[] = BREAKPOINT_VALUE;
12
Ian Wienand5570a772006-02-17 02:00:00 +010013#ifdef ARCH_HAVE_ENABLE_BREAKPOINT
Juan Cespedes1dec2172009-05-07 10:12:10 +020014extern void arch_enable_breakpoint(pid_t, Breakpoint *);
Juan Cespedesf1350522008-12-16 18:19:58 +010015void
Juan Cespedes1dec2172009-05-07 10:12:10 +020016enable_breakpoint(pid_t pid, Breakpoint *sbp) {
Juan Cespedescd8976d2009-05-14 13:47:58 +020017 if (sbp->libsym) {
18 debug(DEBUG_PROCESS, "enable_breakpoint: pid=%d, addr=%p, symbol=%s", pid, sbp->addr, sbp->libsym->name);
19 } else {
20 debug(DEBUG_PROCESS, "enable_breakpoint: pid=%d, addr=%p", pid, sbp->addr);
21 }
Ian Wienand9a2ad352006-02-20 22:44:45 +010022 arch_enable_breakpoint(pid, sbp);
Ian Wienand5570a772006-02-17 02:00:00 +010023}
24#else
Juan Cespedesf1350522008-12-16 18:19:58 +010025void
Juan Cespedes1dec2172009-05-07 10:12:10 +020026enable_breakpoint(pid_t pid, Breakpoint *sbp) {
Paul Gilliam3f1219f2006-04-24 18:25:38 +020027 unsigned int i, j;
Juan Cespedesa4850832002-03-03 02:37:50 +010028
Juan Cespedescd8976d2009-05-14 13:47:58 +020029 if (sbp->libsym) {
30 debug(DEBUG_PROCESS, "enable_breakpoint: pid=%d, addr=%p, symbol=%s", pid, sbp->addr, sbp->libsym->name);
31 } else {
32 debug(DEBUG_PROCESS, "enable_breakpoint: pid=%d, addr=%p", pid, sbp->addr);
33 }
Juan Cespedesa4850832002-03-03 02:37:50 +010034
Ian Wienand2d45b1a2006-02-20 22:48:07 +010035 for (i = 0; i < 1 + ((BREAKPOINT_LENGTH - 1) / sizeof(long)); i++) {
36 long a =
37 ptrace(PTRACE_PEEKTEXT, pid, sbp->addr + i * sizeof(long),
38 0);
39 for (j = 0;
40 j < sizeof(long)
41 && i * sizeof(long) + j < BREAKPOINT_LENGTH; j++) {
42 unsigned char *bytes = (unsigned char *)&a;
Juan Cespedesa4850832002-03-03 02:37:50 +010043
Paul Gilliam76c61f12006-06-14 06:55:21 +020044 sbp->orig_value[i * sizeof(long) + j] = bytes[j];
Ian Wienand2d45b1a2006-02-20 22:48:07 +010045 bytes[j] = break_insn[i * sizeof(long) + j];
Juan Cespedesa4850832002-03-03 02:37:50 +010046 }
Ian Wienand2d45b1a2006-02-20 22:48:07 +010047 ptrace(PTRACE_POKETEXT, pid, sbp->addr + i * sizeof(long), a);
Juan Cespedesa4850832002-03-03 02:37:50 +010048 }
49}
Ian Wienand2d45b1a2006-02-20 22:48:07 +010050#endif /* ARCH_HAVE_ENABLE_BREAKPOINT */
Juan Cespedesa4850832002-03-03 02:37:50 +010051
Ian Wienand5570a772006-02-17 02:00:00 +010052#ifdef ARCH_HAVE_DISABLE_BREAKPOINT
Juan Cespedes1dec2172009-05-07 10:12:10 +020053extern void arch_disable_breakpoint(pid_t, const Breakpoint *sbp);
Juan Cespedesf1350522008-12-16 18:19:58 +010054void
Juan Cespedes1dec2172009-05-07 10:12:10 +020055disable_breakpoint(pid_t pid, const Breakpoint *sbp) {
Juan Cespedescd8976d2009-05-14 13:47:58 +020056 if (sbp->libsym) {
57 debug(DEBUG_PROCESS, "disable_breakpoint: pid=%d, addr=%p, symbol=%s", pid, sbp->addr, sbp->libsym->name);
58 } else {
59 debug(DEBUG_PROCESS, "disable_breakpoint: pid=%d, addr=%p", pid, sbp->addr);
60 }
Ian Wienand5570a772006-02-17 02:00:00 +010061 arch_disable_breakpoint(pid, sbp);
62}
63#else
Juan Cespedesf1350522008-12-16 18:19:58 +010064void
Juan Cespedes1dec2172009-05-07 10:12:10 +020065disable_breakpoint(pid_t pid, const Breakpoint *sbp) {
Paul Gilliam3f1219f2006-04-24 18:25:38 +020066 unsigned int i, j;
Juan Cespedesa4850832002-03-03 02:37:50 +010067
Juan Cespedescd8976d2009-05-14 13:47:58 +020068 if (sbp->libsym) {
69 debug(DEBUG_PROCESS, "disable_breakpoint: pid=%d, addr=%p, symbol=%s", pid, sbp->addr, sbp->libsym->name);
70 } else {
71 debug(DEBUG_PROCESS, "disable_breakpoint: pid=%d, addr=%p", pid, sbp->addr);
72 }
Juan Cespedesa4850832002-03-03 02:37:50 +010073
Ian Wienand2d45b1a2006-02-20 22:48:07 +010074 for (i = 0; i < 1 + ((BREAKPOINT_LENGTH - 1) / sizeof(long)); i++) {
75 long a =
76 ptrace(PTRACE_PEEKTEXT, pid, sbp->addr + i * sizeof(long),
77 0);
78 for (j = 0;
79 j < sizeof(long)
80 && i * sizeof(long) + j < BREAKPOINT_LENGTH; j++) {
81 unsigned char *bytes = (unsigned char *)&a;
Juan Cespedesa4850832002-03-03 02:37:50 +010082
Ian Wienand2d45b1a2006-02-20 22:48:07 +010083 bytes[j] = sbp->orig_value[i * sizeof(long) + j];
Juan Cespedesa4850832002-03-03 02:37:50 +010084 }
Ian Wienand2d45b1a2006-02-20 22:48:07 +010085 ptrace(PTRACE_POKETEXT, pid, sbp->addr + i * sizeof(long), a);
Juan Cespedesa4850832002-03-03 02:37:50 +010086 }
87}
Ian Wienand2d45b1a2006-02-20 22:48:07 +010088#endif /* ARCH_HAVE_DISABLE_BREAKPOINT */