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