| #if HAVE_CONFIG_H |
| #include "config.h" |
| #endif |
| |
| #include <sys/ptrace.h> |
| #include "arch.h" |
| #include "options.h" |
| #include "output.h" |
| |
| static unsigned char break_insn[] = BREAKPOINT_VALUE; |
| |
| void enable_breakpoint(pid_t pid, struct breakpoint *sbp) |
| { |
| int i, j; |
| |
| if (opt_d > 1) { |
| output_line(0, "enable_breakpoint(%d,%p)", pid, sbp->addr); |
| } |
| |
| for (i = 0; i < 1 + ((BREAKPOINT_LENGTH - 1) / sizeof(long)); i++) { |
| long a = |
| ptrace(PTRACE_PEEKTEXT, pid, sbp->addr + i * sizeof(long), |
| 0); |
| for (j = 0; |
| j < sizeof(long) |
| && i * sizeof(long) + j < BREAKPOINT_LENGTH; j++) { |
| unsigned char *bytes = (unsigned char *)&a; |
| |
| sbp->orig_value[i * sizeof(long) + j] = bytes[+j]; |
| bytes[j] = break_insn[i * sizeof(long) + j]; |
| } |
| ptrace(PTRACE_POKETEXT, pid, sbp->addr + i * sizeof(long), a); |
| } |
| } |
| |
| void disable_breakpoint(pid_t pid, const struct breakpoint *sbp) |
| { |
| int i, j; |
| |
| if (opt_d > 1) { |
| output_line(0, "disable_breakpoint(%d,%p)", pid, sbp->addr); |
| } |
| |
| for (i = 0; i < 1 + ((BREAKPOINT_LENGTH - 1) / sizeof(long)); i++) { |
| long a = |
| ptrace(PTRACE_PEEKTEXT, pid, sbp->addr + i * sizeof(long), |
| 0); |
| for (j = 0; |
| j < sizeof(long) |
| && i * sizeof(long) + j < BREAKPOINT_LENGTH; j++) { |
| unsigned char *bytes = (unsigned char *)&a; |
| |
| bytes[j] = sbp->orig_value[i * sizeof(long) + j]; |
| } |
| ptrace(PTRACE_POKETEXT, pid, sbp->addr + i * sizeof(long), a); |
| } |
| } |