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