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