blob: fe6ac6920eb6bfc66be8cc54fcd0802a6fcb34a9 [file] [log] [blame]
Juan Cespedesa4850832002-03-03 02:37:50 +01001#if HAVE_CONFIG_H
2#include "config.h"
3#endif
4
5#include <sys/ptrace.h>
Ian Wienand5570a772006-02-17 02:00:00 +01006#include <string.h>
Juan Cespedesa4850832002-03-03 02:37:50 +01007#include "arch.h"
8#include "options.h"
9#include "output.h"
10
11static unsigned char break_insn[] = BREAKPOINT_VALUE;
12
Ian Wienand5570a772006-02-17 02:00:00 +010013#ifdef ARCH_HAVE_ENABLE_BREAKPOINT
14extern void arch_enable_breakpoint(pid_t, struct breakpoint*);
15void enable_breakpoint(pid_t pid, struct breakpoint *sbp)
16{
17 arch_enable_breakpoint(pid, sbp);
18}
19#else
Ian Wienand3219f322006-02-16 06:00:00 +010020void enable_breakpoint(pid_t pid, struct breakpoint *sbp)
21{
22 int i, j;
Juan Cespedesa4850832002-03-03 02:37:50 +010023
Ian Wienand3219f322006-02-16 06:00:00 +010024 if (opt_d > 1) {
Juan Cespedesefe85f02004-04-04 01:31:38 +020025 output_line(0, "enable_breakpoint(%d,%p)", pid, sbp->addr);
Juan Cespedesa4850832002-03-03 02:37:50 +010026 }
27
Ian Wienand3219f322006-02-16 06:00:00 +010028 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 Cespedesa4850832002-03-03 02:37:50 +010036
Ian Wienand3219f322006-02-16 06:00:00 +010037 sbp->orig_value[i * sizeof(long) + j] = bytes[+j];
38 bytes[j] = break_insn[i * sizeof(long) + j];
Juan Cespedesa4850832002-03-03 02:37:50 +010039 }
Ian Wienand3219f322006-02-16 06:00:00 +010040 ptrace(PTRACE_POKETEXT, pid, sbp->addr + i * sizeof(long), a);
Juan Cespedesa4850832002-03-03 02:37:50 +010041 }
42}
Ian Wienand5570a772006-02-17 02:00:00 +010043#endif /* ARCH_HAVE_ENABLE_BREAKPOINT */
Juan Cespedesa4850832002-03-03 02:37:50 +010044
Ian Wienand5570a772006-02-17 02:00:00 +010045#ifdef ARCH_HAVE_DISABLE_BREAKPOINT
46extern void arch_disable_breakpoint(pid_t, const struct breakpoint * sbp);
47void
48disable_breakpoint(pid_t pid, const struct breakpoint * sbp) {
49 arch_disable_breakpoint(pid, sbp);
50}
51#else
Ian Wienand3219f322006-02-16 06:00:00 +010052void disable_breakpoint(pid_t pid, const struct breakpoint *sbp)
53{
54 int i, j;
Juan Cespedesa4850832002-03-03 02:37:50 +010055
Ian Wienand3219f322006-02-16 06:00:00 +010056 if (opt_d > 1) {
Juan Cespedesefe85f02004-04-04 01:31:38 +020057 output_line(0, "disable_breakpoint(%d,%p)", pid, sbp->addr);
Juan Cespedesa4850832002-03-03 02:37:50 +010058 }
59
Ian Wienand3219f322006-02-16 06:00:00 +010060 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 Cespedesa4850832002-03-03 02:37:50 +010068
Ian Wienand3219f322006-02-16 06:00:00 +010069 bytes[j] = sbp->orig_value[i * sizeof(long) + j];
Juan Cespedesa4850832002-03-03 02:37:50 +010070 }
Ian Wienand3219f322006-02-16 06:00:00 +010071 ptrace(PTRACE_POKETEXT, pid, sbp->addr + i * sizeof(long), a);
Juan Cespedesa4850832002-03-03 02:37:50 +010072 }
73}
Ian Wienand5570a772006-02-17 02:00:00 +010074#endif /* ARCH_HAVE_DISABLE_BREAKPOINT */