/* callback routine for handling exceptions. */ int arch_uprobe_exception_notify(struct notifier_block *self, unsigned long val, void *data) { struct die_args *args = data; struct pt_regs *regs = args->regs; int ret = NOTIFY_DONE; /* We are only interested in userspace traps */ if (regs && !user_mode_vm(regs)) return NOTIFY_DONE; switch (val) { case DIE_INT3: if (uprobe_pre_sstep_notifier(regs)) ret = NOTIFY_STOP; break; case DIE_DEBUG: if (uprobe_post_sstep_notifier(regs)) ret = NOTIFY_STOP; default: break; } return ret; }
int arch_uprobe_exception_notify(struct notifier_block *self, unsigned long val, void *data) { struct die_args *args = data; struct pt_regs *regs = args->regs; /* regs == NULL is a kernel bug */ if (WARN_ON(!regs)) return NOTIFY_DONE; /* We are only interested in userspace traps */ if (!user_mode(regs)) return NOTIFY_DONE; switch (val) { case DIE_UPROBE: if (uprobe_pre_sstep_notifier(regs)) return NOTIFY_STOP; break; case DIE_UPROBE_XOL: if (uprobe_post_sstep_notifier(regs)) return NOTIFY_STOP; default: break; } return 0; }
static int uprobe_breakpoint_handler(struct pt_regs *regs, unsigned int esr) { if (user_mode(regs) && uprobe_pre_sstep_notifier(regs)) return DBG_HOOK_HANDLED; return DBG_HOOK_ERROR; }