breakpoint.c revision 28e80f65e2c808f715e466cdb8c0c53cfe78c756
1#include "config.h" 2 3#include <sys/ptrace.h> 4#include <string.h> 5 6#include "common.h" 7#include "arch.h" 8 9#ifdef ARCH_HAVE_ENABLE_BREAKPOINT 10extern void arch_enable_breakpoint(pid_t, Breakpoint *); 11#else /* ARCH_HAVE_ENABLE_BREAKPOINT */ 12void 13arch_enable_breakpoint(pid_t pid, Breakpoint *sbp) 14{ 15 static unsigned char break_insn[] = BREAKPOINT_VALUE; 16 unsigned int i, j; 17 18 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 } 23 24 for (i = 0; i < 1 + ((BREAKPOINT_LENGTH - 1) / sizeof(long)); i++) { 25 long a = ptrace(PTRACE_PEEKTEXT, pid, 26 sbp->addr + i * sizeof(long), 0); 27 for (j = 0; 28 j < sizeof(long) 29 && i * sizeof(long) + j < BREAKPOINT_LENGTH; j++) { 30 unsigned char *bytes = (unsigned char *)&a; 31 32 sbp->orig_value[i * sizeof(long) + j] = bytes[j]; 33 bytes[j] = break_insn[i * sizeof(long) + j]; 34 } 35 ptrace(PTRACE_POKETEXT, pid, sbp->addr + i * sizeof(long), a); 36 } 37} 38#endif /* ARCH_HAVE_ENABLE_BREAKPOINT */ 39 40void 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 50#ifdef ARCH_HAVE_DISABLE_BREAKPOINT 51extern void arch_disable_breakpoint(pid_t, const Breakpoint *sbp); 52#else /* ARCH_HAVE_DISABLE_BREAKPOINT */ 53void 54arch_disable_breakpoint(pid_t pid, const Breakpoint *sbp) 55{ 56 unsigned int i, j; 57 58 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 } 63 64 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; 72 73 bytes[j] = sbp->orig_value[i * sizeof(long) + j]; 74 } 75 ptrace(PTRACE_POKETEXT, pid, sbp->addr + i * sizeof(long), a); 76 } 77} 78#endif /* ARCH_HAVE_DISABLE_BREAKPOINT */ 79 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} 89