breakpoint.c revision 366c2f46d844f040458df9b7e35fc3b8527ed2d3
1#include "config.h" 2 3#include <sys/ptrace.h> 4#include <string.h> 5 6#include "common.h" 7#include "arch.h" 8#include "breakpoint.h" 9#include "proc.h" 10 11#ifdef ARCH_HAVE_ENABLE_BREAKPOINT 12extern void arch_enable_breakpoint(pid_t, struct breakpoint *); 13#else /* ARCH_HAVE_ENABLE_BREAKPOINT */ 14void 15arch_enable_breakpoint(pid_t pid, struct breakpoint *sbp) 16{ 17 static unsigned char break_insn[] = BREAKPOINT_VALUE; 18 unsigned int i, j; 19 20 if (sbp->libsym) { 21 debug(DEBUG_PROCESS, "enable_breakpoint: pid=%d, addr=%p, symbol=%s", pid, sbp->addr, sbp->libsym->name); 22 } else { 23 debug(DEBUG_PROCESS, "enable_breakpoint: pid=%d, addr=%p", pid, sbp->addr); 24 } 25 26 for (i = 0; i < 1 + ((BREAKPOINT_LENGTH - 1) / sizeof(long)); i++) { 27 long a = ptrace(PTRACE_PEEKTEXT, pid, 28 sbp->addr + i * sizeof(long), 0); 29 for (j = 0; 30 j < sizeof(long) 31 && i * sizeof(long) + j < BREAKPOINT_LENGTH; j++) { 32 unsigned char *bytes = (unsigned char *)&a; 33 34 sbp->orig_value[i * sizeof(long) + j] = bytes[j]; 35 bytes[j] = break_insn[i * sizeof(long) + j]; 36 } 37 ptrace(PTRACE_POKETEXT, pid, sbp->addr + i * sizeof(long), a); 38 } 39} 40#endif /* ARCH_HAVE_ENABLE_BREAKPOINT */ 41 42void 43enable_breakpoint(Process *proc, struct breakpoint *sbp) 44{ 45 if (sbp->libsym) { 46 debug(DEBUG_PROCESS, "enable_breakpoint: pid=%d, addr=%p, symbol=%s", proc->pid, sbp->addr, sbp->libsym->name); 47 } else { 48 debug(DEBUG_PROCESS, "enable_breakpoint: pid=%d, addr=%p", proc->pid, sbp->addr); 49 } 50 arch_enable_breakpoint(proc->pid, sbp); 51} 52 53#ifdef ARCH_HAVE_DISABLE_BREAKPOINT 54extern void arch_disable_breakpoint(pid_t, const struct breakpoint *sbp); 55#else /* ARCH_HAVE_DISABLE_BREAKPOINT */ 56void 57arch_disable_breakpoint(pid_t pid, const struct breakpoint *sbp) 58{ 59 unsigned int i, j; 60 61 if (sbp->libsym) { 62 debug(DEBUG_PROCESS, "disable_breakpoint: pid=%d, addr=%p, symbol=%s", pid, sbp->addr, sbp->libsym->name); 63 } else { 64 debug(DEBUG_PROCESS, "disable_breakpoint: pid=%d, addr=%p", pid, sbp->addr); 65 } 66 67 for (i = 0; i < 1 + ((BREAKPOINT_LENGTH - 1) / sizeof(long)); i++) { 68 long a = 69 ptrace(PTRACE_PEEKTEXT, pid, sbp->addr + i * sizeof(long), 70 0); 71 for (j = 0; 72 j < sizeof(long) 73 && i * sizeof(long) + j < BREAKPOINT_LENGTH; j++) { 74 unsigned char *bytes = (unsigned char *)&a; 75 76 bytes[j] = sbp->orig_value[i * sizeof(long) + j]; 77 } 78 ptrace(PTRACE_POKETEXT, pid, sbp->addr + i * sizeof(long), a); 79 } 80} 81#endif /* ARCH_HAVE_DISABLE_BREAKPOINT */ 82 83void 84disable_breakpoint(Process *proc, struct breakpoint *sbp) 85{ 86 if (sbp->libsym) { 87 debug(DEBUG_PROCESS, "disable_breakpoint: pid=%d, addr=%p, symbol=%s", proc->pid, sbp->addr, sbp->libsym->name); 88 } else { 89 debug(DEBUG_PROCESS, "disable_breakpoint: pid=%d, addr=%p", proc->pid, sbp->addr); 90 } 91 arch_disable_breakpoint(proc->pid, sbp); 92} 93