/* ** Breakpoints with ptrace() ** ** (c) Rainer Schnitker 1994 */ #include #include #ifndef __GO32__ #include #include #include #include #else /* go32 */ #include #include #include #include #endif #include "breakp.h" struct breakpoint bp[MAX_BP]; static void insert_int3(struct breakpoint * bp, int pid) { int r; errno = 0; r = ptrace(PTRACE_PEEKTEXT, pid, bp->addr, 0); if (errno != 0) return; bp->save = (unsigned char) r; r = (r & ~0xff) | 0xcc; ptrace(PTRACE_POKETEXT, pid, bp->addr, r); } static void remove_int3(struct breakpoint * bp, int pid) { int r; errno = 0; r = ptrace(PTRACE_PEEKTEXT, pid, bp->addr, 0); if (errno != 0) return; r = (r & ~0xff) | bp->save; ptrace(PTRACE_POKETEXT, pid, bp->addr, r); } void insert_breakpoints(int pid) { int i; for (i = 0; i < MAX_BP; i++) if (bp[i].status == BP_ENABLE) insert_int3(bp+i, pid); } void remove_breakpoints(int pid) { int i; for (i = 0; i < MAX_BP; i++) if (bp[i].status == BP_ENABLE) remove_int3(bp+i, pid); } int set_bp(int addr) { int i; for (i = 1; i < MAX_BP; i++) if (!(bp[i].status)) break; if (i == MAX_BP) { printf("no break free\n"); return -1; } bp[i].addr = addr; bp[i].status = BP_ENABLE; return i; } int delete_bp(int no) { if (no >= MAX_BP || bp[no].status == 0) { printf("invalid break-no\n"); return -1; } bp[no].addr = 0; bp[no].status = BP_UNDEF; return 0; } int disable_bp(int no) { if (no <= 1 && no >= MAX_BP) { printf("ivalid break-no\n"); return -1; } if (bp[no].status == BP_DISABLE) { printf("already disabled\n"); return -1; } bp[no].status = BP_DISABLE; return 0; } int enable_bp(int no) { if (no <= 1 && no >= MAX_BP) { printf("ivalid break-no\n"); return -1; } if (bp[no].status == BP_ENABLE) { printf("already enabled\n"); return -1; } bp[no].status = BP_ENABLE; return 0; }