blob: 051ac0097cc52611508b97db8893cc9be685e240 [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"
Ian Wienand9a2ad352006-02-20 22:44:45 +010010#include "debug.h"
Juan Cespedesa4850832002-03-03 02:37:50 +010011
12static unsigned char break_insn[] = BREAKPOINT_VALUE;
13
Ian Wienand5570a772006-02-17 02:00:00 +010014#ifdef ARCH_HAVE_ENABLE_BREAKPOINT
Ian Wienand2d45b1a2006-02-20 22:48:07 +010015extern void arch_enable_breakpoint(pid_t, struct breakpoint *);
Ian Wienand5570a772006-02-17 02:00:00 +010016void enable_breakpoint(pid_t pid, struct breakpoint *sbp)
17{
Ian Wienand9a2ad352006-02-20 22:44:45 +010018 arch_enable_breakpoint(pid, sbp);
Ian Wienand5570a772006-02-17 02:00:00 +010019}
20#else
Ian Wienand2d45b1a2006-02-20 22:48:07 +010021void enable_breakpoint(pid_t pid, struct breakpoint *sbp)
22{
Paul Gilliam3f1219f2006-04-24 18:25:38 +020023 unsigned int i, j;
Juan Cespedesa4850832002-03-03 02:37:50 +010024
Ian Wienand9a2ad352006-02-20 22:44:45 +010025 debug(1, "enable_breakpoint(%d,%p)", pid, sbp->addr);
Juan Cespedesa4850832002-03-03 02:37:50 +010026
Ian Wienand2d45b1a2006-02-20 22:48:07 +010027 for (i = 0; i < 1 + ((BREAKPOINT_LENGTH - 1) / sizeof(long)); i++) {
28 long a =
29 ptrace(PTRACE_PEEKTEXT, pid, sbp->addr + i * sizeof(long),
30 0);
31 for (j = 0;
32 j < sizeof(long)
33 && i * sizeof(long) + j < BREAKPOINT_LENGTH; j++) {
34 unsigned char *bytes = (unsigned char *)&a;
Juan Cespedesa4850832002-03-03 02:37:50 +010035
Ian Wienand2d45b1a2006-02-20 22:48:07 +010036 sbp->orig_value[i * sizeof(long) + j] = bytes[+j];
37 bytes[j] = break_insn[i * sizeof(long) + j];
Juan Cespedesa4850832002-03-03 02:37:50 +010038 }
Ian Wienand2d45b1a2006-02-20 22:48:07 +010039 ptrace(PTRACE_POKETEXT, pid, sbp->addr + i * sizeof(long), a);
Juan Cespedesa4850832002-03-03 02:37:50 +010040 }
41}
Ian Wienand2d45b1a2006-02-20 22:48:07 +010042#endif /* ARCH_HAVE_ENABLE_BREAKPOINT */
Juan Cespedesa4850832002-03-03 02:37:50 +010043
Ian Wienand5570a772006-02-17 02:00:00 +010044#ifdef ARCH_HAVE_DISABLE_BREAKPOINT
Ian Wienand2d45b1a2006-02-20 22:48:07 +010045extern void arch_disable_breakpoint(pid_t, const struct breakpoint *sbp);
46void disable_breakpoint(pid_t pid, const struct breakpoint *sbp)
47{
Ian Wienand5570a772006-02-17 02:00:00 +010048 arch_disable_breakpoint(pid, sbp);
49}
50#else
Ian Wienand2d45b1a2006-02-20 22:48:07 +010051void disable_breakpoint(pid_t pid, const struct breakpoint *sbp)
52{
Paul Gilliam3f1219f2006-04-24 18:25:38 +020053 unsigned int i, j;
Juan Cespedesa4850832002-03-03 02:37:50 +010054
Ian Wienand2d45b1a2006-02-20 22:48:07 +010055 if (opt_d > 1) {
Juan Cespedesefe85f02004-04-04 01:31:38 +020056 output_line(0, "disable_breakpoint(%d,%p)", pid, sbp->addr);
Juan Cespedesa4850832002-03-03 02:37:50 +010057 }
58
Ian Wienand2d45b1a2006-02-20 22:48:07 +010059 for (i = 0; i < 1 + ((BREAKPOINT_LENGTH - 1) / sizeof(long)); i++) {
60 long a =
61 ptrace(PTRACE_PEEKTEXT, pid, sbp->addr + i * sizeof(long),
62 0);
63 for (j = 0;
64 j < sizeof(long)
65 && i * sizeof(long) + j < BREAKPOINT_LENGTH; j++) {
66 unsigned char *bytes = (unsigned char *)&a;
Juan Cespedesa4850832002-03-03 02:37:50 +010067
Ian Wienand2d45b1a2006-02-20 22:48:07 +010068 bytes[j] = sbp->orig_value[i * sizeof(long) + j];
Juan Cespedesa4850832002-03-03 02:37:50 +010069 }
Ian Wienand2d45b1a2006-02-20 22:48:07 +010070 ptrace(PTRACE_POKETEXT, pid, sbp->addr + i * sizeof(long), a);
Juan Cespedesa4850832002-03-03 02:37:50 +010071 }
72}
Ian Wienand2d45b1a2006-02-20 22:48:07 +010073#endif /* ARCH_HAVE_DISABLE_BREAKPOINT */