From: Dave A. <ai...@us...> - 2001-11-09 23:48:44
|
Update of /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel In directory usw-pr-cvs1:/tmp/cvs-serv15389 Modified Files: interrupt.c interrupt.h ptrace.c Log Message: DA: ptrace singlestep and trace exception support Index: interrupt.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel/interrupt.c,v retrieving revision 1.21 retrieving revision 1.22 diff -u -r1.21 -r1.22 --- interrupt.c 2001/10/28 23:54:18 1.21 +++ interrupt.c 2001/11/09 23:48:40 1.22 @@ -196,6 +196,11 @@ printk("Panic: unable to register breakpoint handler\n"); machine_halt(); } + + if (register_excep_handler(SCB_TPEND,"Trace Pending (tpend_handler)", tpend_handler, 0, 0)) { + printk("Panic: unable to register trace pending handler\n"); + machine_halt(); + } } @@ -256,21 +261,56 @@ /* This is the handler for break points */ void bpt_handler(struct pt_regs *regs, void *unused) { + siginfo_t info; +#if 0 printk("\nbp sending SIGTRAP\n"); + + printk("\nBreakpoint at PC=%08lx at %08lX\n", regs->pc, ®s->pc); + + printk("\nStack dump\n"); + hex_dump((void *)(regs->sp), 256); + show_regs(regs); + show_cpu_regs(); +#endif + if (user_mode(regs)) { + info.si_signo = SIGTRAP; + info.si_errno = 0; + info.si_code = TRAP_BRKPT; + info.si_addr = regs->pc; + force_sig_info(SIGTRAP,&info,current); + return; + } + machine_halt(); + + force_sig(SIGTRAP, current); +} + +/* This is the handler for break points */ +void tpend_handler(struct pt_regs *regs, void *unused) +{ + siginfo_t info; + + regs->psl.t=0; + #if 0 - printk("\nBreakpoint at PC=%08lx\n", regs->pc); + printk("\ntpend sending SIGTRAP\n"); + printk("\nTrace Pending at PC=%08lx at %08lX\n", regs->pc, ®s->pc); printk("\nStack dump\n"); hex_dump((void *)(regs->sp), 256); show_regs(regs); show_cpu_regs(); +#endif if (user_mode(regs)) { - force_sig(SIGTRAP,current); + info.si_signo = SIGTRAP; + info.si_errno = 0; + info.si_code = TRAP_BRKPT; + info.si_addr = regs->pc; + force_sig_info(SIGTRAP,&info,current); return; } machine_halt(); -#endif force_sig(SIGTRAP, current); } @@ -386,9 +426,10 @@ status = 1; /* Force the "do bottom halves" bit */ + action = &vec->action; vec_num = vec->vec_num; - + status |= action->flags; action->handler(vec_num, action->dev_id, regs); @@ -403,7 +444,7 @@ static inline void do_irq(struct pt_regs *regs, struct irqvector *vec) { - int flags; + int flags; int status; int cpu; /* Fake a single-priority-level interrupt system by raising IPL Index: interrupt.h =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel/interrupt.h,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- interrupt.h 2001/10/28 23:54:18 1.7 +++ interrupt.h 2001/11/09 23:48:40 1.8 @@ -68,3 +68,4 @@ extern void resam_handler(struct pt_regs *regs, void *unused); extern void arith_handler(struct pt_regs *regs, void *excep_info); extern void bpt_handler(struct pt_regs *regs, void *excep_info); +extern void tpend_handler(struct pt_regs *regs, void *excep_info); Index: ptrace.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel/ptrace.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- ptrace.c 2001/11/08 22:17:16 1.3 +++ ptrace.c 2001/11/09 23:48:40 1.4 @@ -40,7 +40,6 @@ regs_ptr = stack_top - 16 - sizeof(struct pt_regs); - printk("putreg called with regno %d\n", regno>>2); switch(regno >> 2) { case 0 ... 16: // retval = *(((unsigned long *)regs_ptr) + (regno>>2)); @@ -82,7 +81,6 @@ retval=0; break; } - printk("getreg returning %8lX\n", retval); return retval; } @@ -93,7 +91,7 @@ extern void save_fp(void*); lock_kernel(); -#if 1 +#if 0 printk("ptrace(r=%d,pid=%d,addr=%08lx,data=%08lx)\n", (int) request, (int) pid, (unsigned long) addr, (unsigned long) data); @@ -182,7 +180,6 @@ unsigned long tmp; res = -EIO; - printk("Addr is %8lX, sizeof is %8lX\n", addr, sizeof(struct user)); if ((addr & 3) || addr < 0 || addr > sizeof(struct user)-3) break; @@ -204,7 +201,7 @@ goto out; case PTRACE_POKEUSR: { - struct pt_regs *regs; + // struct pt_regs *regs; int res = 0; res = -EIO; if ((addr & 3) || addr < 0 || @@ -250,6 +247,29 @@ wake_up_process(child); break; + case PTRACE_SINGLESTEP: + { + unsigned long tmp; + struct psl_fields *psl; + res = -EIO; + if ((unsigned long) data > _NSIG) + break; + child->ptrace &= ~ PT_TRACESYS; + if ((child->ptrace & PT_DTRACE)==0) + child->ptrace |= PT_DTRACE; + + tmp = getreg(child, PT_PSL<<2); + psl = &tmp; + psl->t=1; + putreg(child, PT_PSL<<2, *(unsigned long *)psl); + // printk("tmp is %8lX, psl is now %8lX\n", tmp, *(unsigned long *)psl); + + + child->exit_code=data; + wake_up_process(child); + res = 0; + break; + } case PTRACE_DETACH: /* detach a process that was attached. */ res = -EIO; if ((unsigned long) data > _NSIG) |