Juan Cespedes | a485083 | 2002-03-03 02:37:50 +0100 | [diff] [blame] | 1 | #if HAVE_CONFIG_H |
| 2 | #include "config.h" |
| 3 | #endif |
| 4 | |
| 5 | #include <sys/ptrace.h> |
Ian Wienand | 5570a77 | 2006-02-17 02:00:00 +0100 | [diff] [blame^] | 6 | #include <string.h> |
Juan Cespedes | a485083 | 2002-03-03 02:37:50 +0100 | [diff] [blame] | 7 | #include "arch.h" |
| 8 | #include "options.h" |
| 9 | #include "output.h" |
| 10 | |
| 11 | static unsigned char break_insn[] = BREAKPOINT_VALUE; |
| 12 | |
Ian Wienand | 5570a77 | 2006-02-17 02:00:00 +0100 | [diff] [blame^] | 13 | #ifdef ARCH_HAVE_ENABLE_BREAKPOINT |
| 14 | extern void arch_enable_breakpoint(pid_t, struct breakpoint*); |
| 15 | void enable_breakpoint(pid_t pid, struct breakpoint *sbp) |
| 16 | { |
| 17 | arch_enable_breakpoint(pid, sbp); |
| 18 | } |
| 19 | #else |
Ian Wienand | 3219f32 | 2006-02-16 06:00:00 +0100 | [diff] [blame] | 20 | void enable_breakpoint(pid_t pid, struct breakpoint *sbp) |
| 21 | { |
| 22 | int i, j; |
Juan Cespedes | a485083 | 2002-03-03 02:37:50 +0100 | [diff] [blame] | 23 | |
Ian Wienand | 3219f32 | 2006-02-16 06:00:00 +0100 | [diff] [blame] | 24 | if (opt_d > 1) { |
Juan Cespedes | efe85f0 | 2004-04-04 01:31:38 +0200 | [diff] [blame] | 25 | output_line(0, "enable_breakpoint(%d,%p)", pid, sbp->addr); |
Juan Cespedes | a485083 | 2002-03-03 02:37:50 +0100 | [diff] [blame] | 26 | } |
| 27 | |
Ian Wienand | 3219f32 | 2006-02-16 06:00:00 +0100 | [diff] [blame] | 28 | for (i = 0; i < 1 + ((BREAKPOINT_LENGTH - 1) / sizeof(long)); i++) { |
| 29 | long a = |
| 30 | ptrace(PTRACE_PEEKTEXT, pid, sbp->addr + i * sizeof(long), |
| 31 | 0); |
| 32 | for (j = 0; |
| 33 | j < sizeof(long) |
| 34 | && i * sizeof(long) + j < BREAKPOINT_LENGTH; j++) { |
| 35 | unsigned char *bytes = (unsigned char *)&a; |
Juan Cespedes | a485083 | 2002-03-03 02:37:50 +0100 | [diff] [blame] | 36 | |
Ian Wienand | 3219f32 | 2006-02-16 06:00:00 +0100 | [diff] [blame] | 37 | sbp->orig_value[i * sizeof(long) + j] = bytes[+j]; |
| 38 | bytes[j] = break_insn[i * sizeof(long) + j]; |
Juan Cespedes | a485083 | 2002-03-03 02:37:50 +0100 | [diff] [blame] | 39 | } |
Ian Wienand | 3219f32 | 2006-02-16 06:00:00 +0100 | [diff] [blame] | 40 | ptrace(PTRACE_POKETEXT, pid, sbp->addr + i * sizeof(long), a); |
Juan Cespedes | a485083 | 2002-03-03 02:37:50 +0100 | [diff] [blame] | 41 | } |
| 42 | } |
Ian Wienand | 5570a77 | 2006-02-17 02:00:00 +0100 | [diff] [blame^] | 43 | #endif /* ARCH_HAVE_ENABLE_BREAKPOINT */ |
Juan Cespedes | a485083 | 2002-03-03 02:37:50 +0100 | [diff] [blame] | 44 | |
Ian Wienand | 5570a77 | 2006-02-17 02:00:00 +0100 | [diff] [blame^] | 45 | #ifdef ARCH_HAVE_DISABLE_BREAKPOINT |
| 46 | extern void arch_disable_breakpoint(pid_t, const struct breakpoint * sbp); |
| 47 | void |
| 48 | disable_breakpoint(pid_t pid, const struct breakpoint * sbp) { |
| 49 | arch_disable_breakpoint(pid, sbp); |
| 50 | } |
| 51 | #else |
Ian Wienand | 3219f32 | 2006-02-16 06:00:00 +0100 | [diff] [blame] | 52 | void disable_breakpoint(pid_t pid, const struct breakpoint *sbp) |
| 53 | { |
| 54 | int i, j; |
Juan Cespedes | a485083 | 2002-03-03 02:37:50 +0100 | [diff] [blame] | 55 | |
Ian Wienand | 3219f32 | 2006-02-16 06:00:00 +0100 | [diff] [blame] | 56 | if (opt_d > 1) { |
Juan Cespedes | efe85f0 | 2004-04-04 01:31:38 +0200 | [diff] [blame] | 57 | output_line(0, "disable_breakpoint(%d,%p)", pid, sbp->addr); |
Juan Cespedes | a485083 | 2002-03-03 02:37:50 +0100 | [diff] [blame] | 58 | } |
| 59 | |
Ian Wienand | 3219f32 | 2006-02-16 06:00:00 +0100 | [diff] [blame] | 60 | for (i = 0; i < 1 + ((BREAKPOINT_LENGTH - 1) / sizeof(long)); i++) { |
| 61 | long a = |
| 62 | ptrace(PTRACE_PEEKTEXT, pid, sbp->addr + i * sizeof(long), |
| 63 | 0); |
| 64 | for (j = 0; |
| 65 | j < sizeof(long) |
| 66 | && i * sizeof(long) + j < BREAKPOINT_LENGTH; j++) { |
| 67 | unsigned char *bytes = (unsigned char *)&a; |
Juan Cespedes | a485083 | 2002-03-03 02:37:50 +0100 | [diff] [blame] | 68 | |
Ian Wienand | 3219f32 | 2006-02-16 06:00:00 +0100 | [diff] [blame] | 69 | bytes[j] = sbp->orig_value[i * sizeof(long) + j]; |
Juan Cespedes | a485083 | 2002-03-03 02:37:50 +0100 | [diff] [blame] | 70 | } |
Ian Wienand | 3219f32 | 2006-02-16 06:00:00 +0100 | [diff] [blame] | 71 | ptrace(PTRACE_POKETEXT, pid, sbp->addr + i * sizeof(long), a); |
Juan Cespedes | a485083 | 2002-03-03 02:37:50 +0100 | [diff] [blame] | 72 | } |
| 73 | } |
Ian Wienand | 5570a77 | 2006-02-17 02:00:00 +0100 | [diff] [blame^] | 74 | #endif /* ARCH_HAVE_DISABLE_BREAKPOINT */ |