From: Dave A. <ai...@us...> - 2001-11-13 23:31:21
|
Update of /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel In directory usw-pr-cvs1:/tmp/cvs-serv5459 Modified Files: ptrace.c Log Message: DA: ptrace fixes for segfault Index: ptrace.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel/ptrace.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- ptrace.c 2001/11/09 23:48:40 1.4 +++ ptrace.c 2001/11/13 23:31:16 1.5 @@ -28,17 +28,49 @@ #include <asm/system.h> #include <asm/uaccess.h> +#define VAX_MAX_DIST_BETWEEN_PC 20 +/* + * search out does damn regs.. that variable length exception info is evil I + * tell you evil. + */ +static struct pt_regs *ptrace_find_vax_regs(struct task_struct *child) +{ + struct pt_regs *regs_ptr; + unsigned long *pc1, *pc2; + void *stack_top; + + stack_top = ((union task_union *)child)+1; + stack_top -= 4; + + + pc1 = (unsigned long *)stack_top - 2; + pc2 = pc1; + + //printk("pc1 is %8lX at %8lX\n", *pc1, pc1); + /* back step looking for second copy of PC */ + do { + pc2 -= 1; + } while (*pc1!=*pc2 && pc1-pc2<VAX_MAX_DIST_BETWEEN_PC); + + //printk("difference is %d\n", pc1-pc2); + + if (pc1-pc2>=VAX_MAX_DIST_BETWEEN_PC) + return NULL; + + regs_ptr = ((void *)pc2) + 8 - sizeof(struct pt_regs); + + return regs_ptr; +} + static int putreg(struct task_struct *child, unsigned long regno, unsigned long value) { unsigned long retval = ~0UL; - void *stack_top; struct pt_regs *regs_ptr; - - stack_top = ((union task_union *)child)+1; - stack_top -= 4; - regs_ptr = stack_top - 16 - sizeof(struct pt_regs); + regs_ptr = ptrace_find_vax_regs(child); + if (!regs_ptr) + return 0; switch(regno >> 2) { case 0 ... 16: @@ -59,18 +91,12 @@ unsigned long regno) { unsigned long retval = ~0UL; - void *stack_top; struct pt_regs *regs_ptr; - stack_top = ((union task_union *)child)+1; - stack_top -= 4; - - /* get the registers from where we shoved them on the stack at the last - exception for this process.. not sure if this is always correct but - will do for now - 4 longwords back from end of stack is end of regs */ - - regs_ptr = stack_top - 16 - sizeof(struct pt_regs); - + /* call helper function to get registers for the VAX */ + regs_ptr = ptrace_find_vax_regs(child); + if (!regs_ptr) + return 0; switch(regno >> 2) { case 0 ... 16: @@ -81,6 +107,7 @@ retval=0; break; } +// printk("getreg for %d returned %8lX\n", regno>>2, retval); return retval; } |