blob: ebd8d8af609ab06a75c130e65a2d341ef58b3f31 [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 Cespedesa4850832002-03-03 02:37:50 +01009
10static unsigned char break_insn[] = BREAKPOINT_VALUE;
11
Ian Wienand5570a772006-02-17 02:00:00 +010012#ifdef ARCH_HAVE_ENABLE_BREAKPOINT
Juan Cespedes1dec2172009-05-07 10:12:10 +020013extern void arch_enable_breakpoint(pid_t, Breakpoint *);
Juan Cespedesf1350522008-12-16 18:19:58 +010014void
Juan Cespedes1dec2172009-05-07 10:12:10 +020015enable_breakpoint(pid_t pid, Breakpoint *sbp) {
Juan Cespedescd8976d2009-05-14 13:47:58 +020016 if (sbp->libsym) {
17 debug(DEBUG_PROCESS, "enable_breakpoint: pid=%d, addr=%p, symbol=%s", pid, sbp->addr, sbp->libsym->name);
18 } else {
19 debug(DEBUG_PROCESS, "enable_breakpoint: pid=%d, addr=%p", pid, sbp->addr);
20 }
Ian Wienand9a2ad352006-02-20 22:44:45 +010021 arch_enable_breakpoint(pid, sbp);
Ian Wienand5570a772006-02-17 02:00:00 +010022}
23#else
Juan Cespedesf1350522008-12-16 18:19:58 +010024void
Juan Cespedes1dec2172009-05-07 10:12:10 +020025enable_breakpoint(pid_t pid, Breakpoint *sbp) {
Paul Gilliam3f1219f2006-04-24 18:25:38 +020026 unsigned int i, j;
Juan Cespedesa4850832002-03-03 02:37:50 +010027
Juan Cespedescd8976d2009-05-14 13:47:58 +020028 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 }
Juan Cespedesa4850832002-03-03 02:37:50 +010033
Ian Wienand2d45b1a2006-02-20 22:48:07 +010034 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;
Juan Cespedesa4850832002-03-03 02:37:50 +010042
Paul Gilliam76c61f12006-06-14 06:55:21 +020043 sbp->orig_value[i * sizeof(long) + j] = bytes[j];
Ian Wienand2d45b1a2006-02-20 22:48:07 +010044 bytes[j] = break_insn[i * sizeof(long) + j];
Juan Cespedesa4850832002-03-03 02:37:50 +010045 }
Ian Wienand2d45b1a2006-02-20 22:48:07 +010046 ptrace(PTRACE_POKETEXT, pid, sbp->addr + i * sizeof(long), a);
Juan Cespedesa4850832002-03-03 02:37:50 +010047 }
48}
Ian Wienand2d45b1a2006-02-20 22:48:07 +010049#endif /* ARCH_HAVE_ENABLE_BREAKPOINT */
Juan Cespedesa4850832002-03-03 02:37:50 +010050
Ian Wienand5570a772006-02-17 02:00:00 +010051#ifdef ARCH_HAVE_DISABLE_BREAKPOINT
Juan Cespedes1dec2172009-05-07 10:12:10 +020052extern void arch_disable_breakpoint(pid_t, const Breakpoint *sbp);
Juan Cespedesf1350522008-12-16 18:19:58 +010053void
Juan Cespedes1dec2172009-05-07 10:12:10 +020054disable_breakpoint(pid_t pid, const Breakpoint *sbp) {
Juan Cespedescd8976d2009-05-14 13:47:58 +020055 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 }
Ian Wienand5570a772006-02-17 02:00:00 +010060 arch_disable_breakpoint(pid, sbp);
61}
62#else
Juan Cespedesf1350522008-12-16 18:19:58 +010063void
Juan Cespedes1dec2172009-05-07 10:12:10 +020064disable_breakpoint(pid_t pid, const Breakpoint *sbp) {
Paul Gilliam3f1219f2006-04-24 18:25:38 +020065 unsigned int i, j;
Juan Cespedesa4850832002-03-03 02:37:50 +010066
Juan Cespedescd8976d2009-05-14 13:47:58 +020067 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 }
Juan Cespedesa4850832002-03-03 02:37:50 +010072
Ian Wienand2d45b1a2006-02-20 22:48:07 +010073 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;
Juan Cespedesa4850832002-03-03 02:37:50 +010081
Ian Wienand2d45b1a2006-02-20 22:48:07 +010082 bytes[j] = sbp->orig_value[i * sizeof(long) + j];
Juan Cespedesa4850832002-03-03 02:37:50 +010083 }
Ian Wienand2d45b1a2006-02-20 22:48:07 +010084 ptrace(PTRACE_POKETEXT, pid, sbp->addr + i * sizeof(long), a);
Juan Cespedesa4850832002-03-03 02:37:50 +010085 }
86}
Ian Wienand2d45b1a2006-02-20 22:48:07 +010087#endif /* ARCH_HAVE_DISABLE_BREAKPOINT */