blob: 576a26d2a284958c167ee8adf759b2630f0ba5f3 [file] [log] [blame]
Juan Cespedesa4850832002-03-03 02:37:50 +01001#include "config.h"
Juan Cespedesa4850832002-03-03 02:37:50 +01002
3#include <sys/ptrace.h>
Ian Wienand5570a772006-02-17 02:00:00 +01004#include <string.h>
Juan Cespedes61da3372009-07-03 11:55:44 +02005
Juan Cespedes8d1b92b2009-07-03 10:39:34 +02006#include "common.h"
Juan Cespedes2a61d192009-07-04 11:29:27 +02007#include "arch.h"
Juan Cespedesa4850832002-03-03 02:37:50 +01008
Ian Wienand5570a772006-02-17 02:00:00 +01009#ifdef ARCH_HAVE_ENABLE_BREAKPOINT
Juan Cespedes1dec2172009-05-07 10:12:10 +020010extern void arch_enable_breakpoint(pid_t, Breakpoint *);
Juan Cespedesf1350522008-12-16 18:19:58 +010011void
Juan Cespedes1dec2172009-05-07 10:12:10 +020012enable_breakpoint(pid_t pid, Breakpoint *sbp) {
Juan Cespedescd8976d2009-05-14 13:47:58 +020013 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 }
Ian Wienand9a2ad352006-02-20 22:44:45 +010018 arch_enable_breakpoint(pid, sbp);
Ian Wienand5570a772006-02-17 02:00:00 +010019}
20#else
Juan Cespedesa7af00d2009-07-26 13:23:18 +020021
22static unsigned char break_insn[] = BREAKPOINT_VALUE;
23
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++) {
Petr Machata26627682011-07-08 18:15:32 +020035 long a = ptrace(PTRACE_PEEKTEXT, pid,
36 sbp->addr + i * sizeof(long), 0);
Ian Wienand2d45b1a2006-02-20 22:48:07 +010037 for (j = 0;
38 j < sizeof(long)
39 && i * sizeof(long) + j < BREAKPOINT_LENGTH; j++) {
40 unsigned char *bytes = (unsigned char *)&a;
Juan Cespedesa4850832002-03-03 02:37:50 +010041
Paul Gilliam76c61f12006-06-14 06:55:21 +020042 sbp->orig_value[i * sizeof(long) + j] = bytes[j];
Ian Wienand2d45b1a2006-02-20 22:48:07 +010043 bytes[j] = break_insn[i * sizeof(long) + j];
Juan Cespedesa4850832002-03-03 02:37:50 +010044 }
Ian Wienand2d45b1a2006-02-20 22:48:07 +010045 ptrace(PTRACE_POKETEXT, pid, sbp->addr + i * sizeof(long), a);
Juan Cespedesa4850832002-03-03 02:37:50 +010046 }
47}
Ian Wienand2d45b1a2006-02-20 22:48:07 +010048#endif /* ARCH_HAVE_ENABLE_BREAKPOINT */
Juan Cespedesa4850832002-03-03 02:37:50 +010049
Ian Wienand5570a772006-02-17 02:00:00 +010050#ifdef ARCH_HAVE_DISABLE_BREAKPOINT
Juan Cespedes1dec2172009-05-07 10:12:10 +020051extern void arch_disable_breakpoint(pid_t, const Breakpoint *sbp);
Juan Cespedesf1350522008-12-16 18:19:58 +010052void
Juan Cespedes1dec2172009-05-07 10:12:10 +020053disable_breakpoint(pid_t pid, const Breakpoint *sbp) {
Juan Cespedescd8976d2009-05-14 13:47:58 +020054 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 }
Ian Wienand5570a772006-02-17 02:00:00 +010059 arch_disable_breakpoint(pid, sbp);
60}
61#else
Juan Cespedesf1350522008-12-16 18:19:58 +010062void
Juan Cespedes1dec2172009-05-07 10:12:10 +020063disable_breakpoint(pid_t pid, const Breakpoint *sbp) {
Paul Gilliam3f1219f2006-04-24 18:25:38 +020064 unsigned int i, j;
Juan Cespedesa4850832002-03-03 02:37:50 +010065
Juan Cespedescd8976d2009-05-14 13:47:58 +020066 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 }
Juan Cespedesa4850832002-03-03 02:37:50 +010071
Ian Wienand2d45b1a2006-02-20 22:48:07 +010072 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;
Juan Cespedesa4850832002-03-03 02:37:50 +010080
Ian Wienand2d45b1a2006-02-20 22:48:07 +010081 bytes[j] = sbp->orig_value[i * sizeof(long) + j];
Juan Cespedesa4850832002-03-03 02:37:50 +010082 }
Ian Wienand2d45b1a2006-02-20 22:48:07 +010083 ptrace(PTRACE_POKETEXT, pid, sbp->addr + i * sizeof(long), a);
Juan Cespedesa4850832002-03-03 02:37:50 +010084 }
85}
Ian Wienand2d45b1a2006-02-20 22:48:07 +010086#endif /* ARCH_HAVE_DISABLE_BREAKPOINT */