/* * fill in the user structure for a core dump.. */ static void dump_thread32(struct pt_regs *regs, struct user32 *dump) { u32 fs, gs; memset(dump, 0, sizeof(*dump)); /* changed the size calculations - should hopefully work better. lbt */ dump->magic = CMAGIC; dump->start_code = 0; dump->start_stack = regs->sp & ~(PAGE_SIZE - 1); dump->u_tsize = ((unsigned long) current->mm->end_code) >> PAGE_SHIFT; dump->u_dsize = ((unsigned long) (current->mm->brk + (PAGE_SIZE-1))) >> PAGE_SHIFT; dump->u_dsize -= dump->u_tsize; dump->u_debugreg[0] = get_dr(0); dump->u_debugreg[1] = get_dr(1); dump->u_debugreg[2] = get_dr(2); dump->u_debugreg[3] = get_dr(3); dump->u_debugreg[6] = current->thread.debugreg6; dump->u_debugreg[7] = current->thread.ptrace_dr7; if (dump->start_stack < 0xc0000000) { unsigned long tmp; tmp = (unsigned long) (0xc0000000 - dump->start_stack); dump->u_ssize = tmp >> PAGE_SHIFT; }
int dbg_hard_brk_event(ctrl_evt_hdl_t *hdlr) { uint8_t n; if(!dbg_hard_brk_enabled()) return VM_IGNORE; debug(DBG_HARD_BRK, "hard brk event\n"); for(n=0 ; n<DBG_HARD_BRK_NR ; n++) if(__hbrk_raised(n) && __hbrk_enabled(n)) { dbg_evt_t *evt = &info->vmm.ctrl.dbg.evt; evt->type = __hbrk_get_type(n); evt->hard = n; evt->addr = get_dr(n); *hdlr = dbg_hard_brk_get_hdlr(n); dbg_hard_set_dr6_dirty(1); debug(DBG_HARD_BRK, "prepared hard brk ctrl event for 0x%X\n", evt->addr); return VM_DONE; } return VM_IGNORE; }
asmlinkage void my_do_debug(struct pt_regs *regs, long error_code) { unsigned long dr6; bp_handler handler; get_dr(6, &dr6); if (dr6 & DR_BD) { dr6 &= ~DR_BD; emulate_cpu(regs); } if (dr6 & DR_TRAP0) { dr6 &= ~DR_TRAP0; handler = bp.handlers[0]; goto trap; } else if (dr6 & DR_TRAP1) { dr6 &= ~DR_TRAP1; handler = bp.handlers[1]; goto trap; } else if (dr6 & DR_TRAP2) { dr6 &= ~DR_TRAP2; handler = bp.handlers[2]; goto trap; } else if (dr6 & DR_TRAP3) { dr6 &= ~DR_TRAP3; handler = bp.handlers[3]; goto trap; } return; trap: regs->flags |= X86_EFLAGS_RF; regs->flags &= ~X86_EFLAGS_TF; handler(regs); }
/* ** Hardware Breakpoints Services */ int dbg_hard_brk_set(offset_t addr, uint8_t type, uint8_t len, ctrl_evt_hdl_t hdlr) { uint8_t n; for(n=0 ; n<DBG_HARD_BRK_NR ; n++) if(!__hbrk_enabled(n)) { __hbrk_setup_bp(n, type, len); dbg_hard_brk_set_hdlr(n, hdlr); set_dr(n, addr); if(type == DR7_COND_X && !dbg_hard_brk_insn_enabled()) dbg_hard_brk_insn_enable(); dbg_hard_brk_enable(); debug(DBG_HARD_BRK, "set hard bp @ 0x%X\n", get_dr(n)); return VM_DONE; } return VM_IGNORE; }
int dbg_hard_brk_del(offset_t addr, uint8_t type, uint8_t len) { uint8_t n, more, more_x, check, rc = VM_IGNORE; more = more_x = 0; check = __hbrk_mke_conf(type,len); for(n=0 ; n<DBG_HARD_BRK_NR ; n++) if(__hbrk_enabled(n)) { uint8_t conf = __hbrk_get_config(n); if(conf == check && addr == get_dr(n)) { __hbrk_delete_bp(n); rc = VM_DONE; debug(DBG_HARD_BRK, "del hard bp @ 0x%X\n", addr); } else if(!more_x || !more) { if(__hbrk_type_of(conf) == DR7_COND_X) more_x = 1; more = 1; } } if(!more_x) { dbg_hard_brk_insn_disable(); debug(DBG_HARD_BRK, "no more hard insn bp\n"); if(!more) { dbg_hard_brk_disable(); debug(DBG_HARD_BRK, "no more hard bp\n"); } } return rc; }