blob: 64b70e464542eb6cc26766e7c68a4a8beb5fa523 [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 Cespedesa4850832002-03-03 02:37:50 +01007#include "arch.h"
8#include "options.h"
9#include "output.h"
Ian Wienand9a2ad352006-02-20 22:44:45 +010010#include "debug.h"
Juan Cespedesa4850832002-03-03 02:37:50 +010011
12static unsigned char break_insn[] = BREAKPOINT_VALUE;
13
Ian Wienand5570a772006-02-17 02:00:00 +010014#ifdef ARCH_HAVE_ENABLE_BREAKPOINT
Juan Cespedes1dec2172009-05-07 10:12:10 +020015extern void arch_enable_breakpoint(pid_t, Breakpoint *);
Juan Cespedesf1350522008-12-16 18:19:58 +010016void
Juan Cespedes1dec2172009-05-07 10:12:10 +020017enable_breakpoint(pid_t pid, Breakpoint *sbp) {
Juan Cespedescd8976d2009-05-14 13:47:58 +020018 if (sbp->libsym) {
19 debug(DEBUG_PROCESS, "enable_breakpoint: pid=%d, addr=%p, symbol=%s", pid, sbp->addr, sbp->libsym->name);
20 } else {
21 debug(DEBUG_PROCESS, "enable_breakpoint: pid=%d, addr=%p", pid, sbp->addr);
22 }
Ian Wienand9a2ad352006-02-20 22:44:45 +010023 arch_enable_breakpoint(pid, sbp);
Ian Wienand5570a772006-02-17 02:00:00 +010024}
25#else
Juan Cespedesf1350522008-12-16 18:19:58 +010026void
Juan Cespedes1dec2172009-05-07 10:12:10 +020027enable_breakpoint(pid_t pid, Breakpoint *sbp) {
Paul Gilliam3f1219f2006-04-24 18:25:38 +020028 unsigned int i, j;
Juan Cespedesa4850832002-03-03 02:37:50 +010029
Juan Cespedescd8976d2009-05-14 13:47:58 +020030 if (sbp->libsym) {
31 debug(DEBUG_PROCESS, "enable_breakpoint: pid=%d, addr=%p, symbol=%s", pid, sbp->addr, sbp->libsym->name);
32 } else {
33 debug(DEBUG_PROCESS, "enable_breakpoint: pid=%d, addr=%p", pid, sbp->addr);
34 }
Juan Cespedesa4850832002-03-03 02:37:50 +010035
Ian Wienand2d45b1a2006-02-20 22:48:07 +010036 for (i = 0; i < 1 + ((BREAKPOINT_LENGTH - 1) / sizeof(long)); i++) {
37 long a =
38 ptrace(PTRACE_PEEKTEXT, pid, sbp->addr + i * sizeof(long),
39 0);
40 for (j = 0;
41 j < sizeof(long)
42 && i * sizeof(long) + j < BREAKPOINT_LENGTH; j++) {
43 unsigned char *bytes = (unsigned char *)&a;
Juan Cespedesa4850832002-03-03 02:37:50 +010044
Paul Gilliam76c61f12006-06-14 06:55:21 +020045 sbp->orig_value[i * sizeof(long) + j] = bytes[j];
Ian Wienand2d45b1a2006-02-20 22:48:07 +010046 bytes[j] = break_insn[i * sizeof(long) + j];
Juan Cespedesa4850832002-03-03 02:37:50 +010047 }
Ian Wienand2d45b1a2006-02-20 22:48:07 +010048 ptrace(PTRACE_POKETEXT, pid, sbp->addr + i * sizeof(long), a);
Juan Cespedesa4850832002-03-03 02:37:50 +010049 }
50}
Ian Wienand2d45b1a2006-02-20 22:48:07 +010051#endif /* ARCH_HAVE_ENABLE_BREAKPOINT */
Juan Cespedesa4850832002-03-03 02:37:50 +010052
Ian Wienand5570a772006-02-17 02:00:00 +010053#ifdef ARCH_HAVE_DISABLE_BREAKPOINT
Juan Cespedes1dec2172009-05-07 10:12:10 +020054extern void arch_disable_breakpoint(pid_t, const Breakpoint *sbp);
Juan Cespedesf1350522008-12-16 18:19:58 +010055void
Juan Cespedes1dec2172009-05-07 10:12:10 +020056disable_breakpoint(pid_t pid, const Breakpoint *sbp) {
Juan Cespedescd8976d2009-05-14 13:47:58 +020057 if (sbp->libsym) {
58 debug(DEBUG_PROCESS, "disable_breakpoint: pid=%d, addr=%p, symbol=%s", pid, sbp->addr, sbp->libsym->name);
59 } else {
60 debug(DEBUG_PROCESS, "disable_breakpoint: pid=%d, addr=%p", pid, sbp->addr);
61 }
Ian Wienand5570a772006-02-17 02:00:00 +010062 arch_disable_breakpoint(pid, sbp);
63}
64#else
Juan Cespedesf1350522008-12-16 18:19:58 +010065void
Juan Cespedes1dec2172009-05-07 10:12:10 +020066disable_breakpoint(pid_t pid, const Breakpoint *sbp) {
Paul Gilliam3f1219f2006-04-24 18:25:38 +020067 unsigned int i, j;
Juan Cespedesa4850832002-03-03 02:37:50 +010068
Juan Cespedescd8976d2009-05-14 13:47:58 +020069 if (sbp->libsym) {
70 debug(DEBUG_PROCESS, "disable_breakpoint: pid=%d, addr=%p, symbol=%s", pid, sbp->addr, sbp->libsym->name);
71 } else {
72 debug(DEBUG_PROCESS, "disable_breakpoint: pid=%d, addr=%p", pid, sbp->addr);
73 }
Juan Cespedesa4850832002-03-03 02:37:50 +010074
Ian Wienand2d45b1a2006-02-20 22:48:07 +010075 for (i = 0; i < 1 + ((BREAKPOINT_LENGTH - 1) / sizeof(long)); i++) {
76 long a =
77 ptrace(PTRACE_PEEKTEXT, pid, sbp->addr + i * sizeof(long),
78 0);
79 for (j = 0;
80 j < sizeof(long)
81 && i * sizeof(long) + j < BREAKPOINT_LENGTH; j++) {
82 unsigned char *bytes = (unsigned char *)&a;
Juan Cespedesa4850832002-03-03 02:37:50 +010083
Ian Wienand2d45b1a2006-02-20 22:48:07 +010084 bytes[j] = sbp->orig_value[i * sizeof(long) + j];
Juan Cespedesa4850832002-03-03 02:37:50 +010085 }
Ian Wienand2d45b1a2006-02-20 22:48:07 +010086 ptrace(PTRACE_POKETEXT, pid, sbp->addr + i * sizeof(long), a);
Juan Cespedesa4850832002-03-03 02:37:50 +010087 }
88}
Ian Wienand2d45b1a2006-02-20 22:48:07 +010089#endif /* ARCH_HAVE_DISABLE_BREAKPOINT */