|
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)
|