blob: 5a49e9d2778db889480081617fb51baa16a04f12 [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
Petr Machataf789c9c2011-07-09 10:54:27 +02009#ifdef ARCH_HAVE_ENABLE_BREAKPOINT
10extern void arch_enable_breakpoint(pid_t, Breakpoint *);
11#else /* ARCH_HAVE_ENABLE_BREAKPOINT */
Juan Cespedesf1350522008-12-16 18:19:58 +010012void
Petr Machataf789c9c2011-07-09 10:54:27 +020013arch_enable_breakpoint(pid_t pid, Breakpoint *sbp)
14{
Petr Machata28e80f62011-08-09 23:33:52 +020015 static unsigned char break_insn[] = BREAKPOINT_VALUE;
Paul Gilliam3f1219f2006-04-24 18:25:38 +020016 unsigned int i, j;
Juan Cespedesa4850832002-03-03 02:37:50 +010017
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 }
Juan Cespedesa4850832002-03-03 02:37:50 +010023
Ian Wienand2d45b1a2006-02-20 22:48:07 +010024 for (i = 0; i < 1 + ((BREAKPOINT_LENGTH - 1) / sizeof(long)); i++) {
Petr Machata26627682011-07-08 18:15:32 +020025 long a = ptrace(PTRACE_PEEKTEXT, pid,
26 sbp->addr + i * sizeof(long), 0);
Ian Wienand2d45b1a2006-02-20 22:48:07 +010027 for (j = 0;
28 j < sizeof(long)
29 && i * sizeof(long) + j < BREAKPOINT_LENGTH; j++) {
30 unsigned char *bytes = (unsigned char *)&a;
Juan Cespedesa4850832002-03-03 02:37:50 +010031
Paul Gilliam76c61f12006-06-14 06:55:21 +020032 sbp->orig_value[i * sizeof(long) + j] = bytes[j];
Ian Wienand2d45b1a2006-02-20 22:48:07 +010033 bytes[j] = break_insn[i * sizeof(long) + j];
Juan Cespedesa4850832002-03-03 02:37:50 +010034 }
Ian Wienand2d45b1a2006-02-20 22:48:07 +010035 ptrace(PTRACE_POKETEXT, pid, sbp->addr + i * sizeof(long), a);
Juan Cespedesa4850832002-03-03 02:37:50 +010036 }
37}
Ian Wienand2d45b1a2006-02-20 22:48:07 +010038#endif /* ARCH_HAVE_ENABLE_BREAKPOINT */
Juan Cespedesa4850832002-03-03 02:37:50 +010039
Petr Machataf789c9c2011-07-09 10:54:27 +020040void
41enable_breakpoint(Process * proc, Breakpoint *sbp) {
42 if (sbp->libsym) {
43 debug(DEBUG_PROCESS, "enable_breakpoint: pid=%d, addr=%p, symbol=%s", proc->pid, sbp->addr, sbp->libsym->name);
44 } else {
45 debug(DEBUG_PROCESS, "enable_breakpoint: pid=%d, addr=%p", proc->pid, sbp->addr);
46 }
47 arch_enable_breakpoint(proc->pid, sbp);
48}
49
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);
Petr Machataf789c9c2011-07-09 10:54:27 +020052#else /* ARCH_HAVE_DISABLE_BREAKPOINT */
Juan Cespedesf1350522008-12-16 18:19:58 +010053void
Petr Machataf789c9c2011-07-09 10:54:27 +020054arch_disable_breakpoint(pid_t pid, const Breakpoint *sbp)
55{
Paul Gilliam3f1219f2006-04-24 18:25:38 +020056 unsigned int i, j;
Juan Cespedesa4850832002-03-03 02:37:50 +010057
Juan Cespedescd8976d2009-05-14 13:47:58 +020058 if (sbp->libsym) {
59 debug(DEBUG_PROCESS, "disable_breakpoint: pid=%d, addr=%p, symbol=%s", pid, sbp->addr, sbp->libsym->name);
60 } else {
61 debug(DEBUG_PROCESS, "disable_breakpoint: pid=%d, addr=%p", pid, sbp->addr);
62 }
Juan Cespedesa4850832002-03-03 02:37:50 +010063
Ian Wienand2d45b1a2006-02-20 22:48:07 +010064 for (i = 0; i < 1 + ((BREAKPOINT_LENGTH - 1) / sizeof(long)); i++) {
65 long a =
66 ptrace(PTRACE_PEEKTEXT, pid, sbp->addr + i * sizeof(long),
67 0);
68 for (j = 0;
69 j < sizeof(long)
70 && i * sizeof(long) + j < BREAKPOINT_LENGTH; j++) {
71 unsigned char *bytes = (unsigned char *)&a;
Juan Cespedesa4850832002-03-03 02:37:50 +010072
Ian Wienand2d45b1a2006-02-20 22:48:07 +010073 bytes[j] = sbp->orig_value[i * sizeof(long) + j];
Juan Cespedesa4850832002-03-03 02:37:50 +010074 }
Ian Wienand2d45b1a2006-02-20 22:48:07 +010075 ptrace(PTRACE_POKETEXT, pid, sbp->addr + i * sizeof(long), a);
Juan Cespedesa4850832002-03-03 02:37:50 +010076 }
77}
Ian Wienand2d45b1a2006-02-20 22:48:07 +010078#endif /* ARCH_HAVE_DISABLE_BREAKPOINT */
Petr Machataf789c9c2011-07-09 10:54:27 +020079
80void
81disable_breakpoint(Process * proc, Breakpoint *sbp) {
82 if (sbp->libsym) {
83 debug(DEBUG_PROCESS, "disable_breakpoint: pid=%d, addr=%p, symbol=%s", proc->pid, sbp->addr, sbp->libsym->name);
84 } else {
85 debug(DEBUG_PROCESS, "disable_breakpoint: pid=%d, addr=%p", proc->pid, sbp->addr);
86 }
87 arch_disable_breakpoint(proc->pid, sbp);
88}