diff options
| author | manu <manu@NetBSD.org> | 2001-05-27 21:15:07 +0000 |
|---|---|---|
| committer | manu <manu@NetBSD.org> | 2001-05-27 21:15:07 +0000 |
| commit | befe23c1192db2c6b4dfaea6ee86048f8a8cd0d7 (patch) | |
| tree | fa4747e382d6ac3b2940ffed2bdb92452ae65909 /sys/compat/linux | |
| parent | 0dd67e03be34f6078a328e4c9462ad3f7e5fbb44 (diff) | |
Implements correctly PEEKUSER and fixes various serious bugs. The status
of this file is not "officially broken" any more (gdb works).
Diffstat (limited to 'sys/compat/linux')
| -rw-r--r-- | sys/compat/linux/arch/powerpc/linux_ptrace.c | 128 |
1 files changed, 96 insertions, 32 deletions
diff --git a/sys/compat/linux/arch/powerpc/linux_ptrace.c b/sys/compat/linux/arch/powerpc/linux_ptrace.c index 4e4325077ba..0569ea61843 100644 --- a/sys/compat/linux/arch/powerpc/linux_ptrace.c +++ b/sys/compat/linux/arch/powerpc/linux_ptrace.c @@ -1,4 +1,4 @@ -/* $NetBSD: linux_ptrace.c,v 1.4 2001/05/22 21:09:20 manu Exp $ */ +/* $NetBSD: linux_ptrace.c,v 1.5 2001/05/27 21:15:07 manu Exp $ */ /*- * Copyright (c) 1999, 2001 The NetBSD Foundation, Inc. @@ -36,12 +36,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -/* - * Function linux_sys_ptrace_arch() is taken from NetBSD/i386 - * with some stuff deleted to get it compiling. It is not expected to - * work, and it should be checked with care or re-writen. - */ - #include <sys/types.h> #include <sys/param.h> #include <sys/malloc.h> @@ -102,6 +96,7 @@ struct linux_user { }; #define LUSR_OFF(member) offsetof(struct linux_user, member) +#define LUSR_REG_OFF(member) offsetof(struct linux_pt_regs, member) #define ISSET(t, f) ((t) & (f)) int @@ -126,15 +121,15 @@ linux_sys_ptrace_arch(p, v, retval) /* XXX Check me! (From NetBSD/i386) */ int i; switch (request = SCARG(uap, request)) { - case LINUX_PTRACE_PEEKUSR: - case LINUX_PTRACE_POKEUSR: - case LINUX_PTRACE_GETREGS: - case LINUX_PTRACE_SETREGS: - case LINUX_PTRACE_GETFPREGS: - case LINUX_PTRACE_SETFPREGS: - break; - default: - return EIO; + case LINUX_PTRACE_PEEKUSR: + case LINUX_PTRACE_POKEUSR: + case LINUX_PTRACE_GETREGS: + case LINUX_PTRACE_SETREGS: + case LINUX_PTRACE_GETFPREGS: + case LINUX_PTRACE_SETFPREGS: + break; + default: + return EIO; } /* Find the process we're supposed to be operating on. */ @@ -259,13 +254,17 @@ linux_sys_ptrace_arch(p, v, retval) /* XXX Check me! (From NetBSD/i386) */ case LINUX_PTRACE_PEEKUSR: addr = SCARG(uap, addr); + MALLOC(regs, struct reg*, sizeof(struct reg), M_TEMP, M_WAITOK); + error = process_read_regs(t, regs); + if (error) + goto out; PHOLD(t); /* need full process info */ error = 0; if ((addr < LUSR_OFF(lusr_startgdb)) || - (addr > LUSR_OFF(lu_comm_end))) { + (addr > LUSR_OFF(lu_comm_end))) error = 1; - } else if (addr == LUSR_OFF(u_tsize)) + else if (addr == LUSR_OFF(u_tsize)) *retval = p->p_vmspace->vm_tsize; else if (addr == LUSR_OFF(u_dsize)) *retval = p->p_vmspace->vm_dsize; @@ -275,17 +274,28 @@ linux_sys_ptrace_arch(p, v, retval) /* XXX Check me! (From NetBSD/i386) */ *retval = (register_t) p->p_vmspace->vm_taddr; else if (addr == LUSR_OFF(start_stack)) *retval = (register_t) p->p_vmspace->vm_minsaddr; - else if ((addr >=0 ) && (addr < LUSR_OFF(u_tsize))) - *retval = LUSR_OFF(regs); - else if (addr == LUSR_OFF(signal)) { + else if ((addr >= LUSR_REG_OFF(lpt_regs_fixreg_begin)) && + (addr <= LUSR_REG_OFF(lpt_regs_fixreg_end))) + *retval = regs->fixreg[addr / sizeof (register_t)]; + else if (addr == LUSR_REG_OFF(lnip)) + *retval = regs->pc; + else if (addr == LUSR_REG_OFF(lctr)) + *retval = regs->ctr; + else if (addr == LUSR_REG_OFF(llink)) + *retval = regs->lr; + else if (addr == LUSR_REG_OFF(lxer)) + *retval = regs->xer; + else if (addr == LUSR_REG_OFF(lccr)) + *retval = regs->cr; + else if (addr == LUSR_OFF(signal)) error = 1; - } else if (addr == LUSR_OFF(signal)) { + else if (addr == LUSR_OFF(signal)) error = 1; - } else if (addr == LUSR_OFF(magic)) { + else if (addr == LUSR_OFF(magic)) error = 1; - } else if (addr == LUSR_OFF(u_comm)) { + else if (addr == LUSR_OFF(u_comm)) error = 1; - } else { + else { #ifdef DEBUG_LINUX printf("linux_ptrace: unsupported address: %d\n", addr); #endif @@ -294,14 +304,68 @@ linux_sys_ptrace_arch(p, v, retval) /* XXX Check me! (From NetBSD/i386) */ PRELE(t); - if (!error) - return 0; + error = copyout (retval, + (caddr_t)SCARG(uap, data), sizeof retval); + *retval = SCARG(uap, data); + goto out; + + break; + + case LINUX_PTRACE_POKEUSR: /* XXX Not tested */ + addr = SCARG(uap, addr); + MALLOC(regs, struct reg*, sizeof(struct reg), M_TEMP, M_WAITOK); + error = process_read_regs(t, regs); + if (error) + goto out; + + PHOLD(t); /* need full process info */ + error = 0; + if ((addr < LUSR_OFF(lusr_startgdb)) || + (addr > LUSR_OFF(lu_comm_end))) + error = 1; + else if (addr == LUSR_OFF(u_tsize)) + error = 1; + else if (addr == LUSR_OFF(u_dsize)) + error = 1; + else if (addr == LUSR_OFF(u_ssize)) + error = 1; + else if (addr == LUSR_OFF(start_code)) + error = 1; + else if (addr == LUSR_OFF(start_stack)) + error = 1; + else if ((addr >= LUSR_REG_OFF(lpt_regs_fixreg_begin)) && + (addr <= LUSR_REG_OFF(lpt_regs_fixreg_end))) + regs->fixreg[addr / sizeof (register_t)] = + (register_t)SCARG(uap, data); + else if (addr == LUSR_REG_OFF(lnip)) + regs->pc = (register_t)SCARG(uap, data); + else if (addr == LUSR_REG_OFF(lctr)) + regs->ctr = (register_t)SCARG(uap, data); + else if (addr == LUSR_REG_OFF(llink)) + regs->lr = (register_t)SCARG(uap, data); + else if (addr == LUSR_REG_OFF(lxer)) + regs->xer = (register_t)SCARG(uap, data); + else if (addr == LUSR_REG_OFF(lccr)) + regs->cr = (register_t)SCARG(uap, data); + else if (addr == LUSR_OFF(signal)) + error = 1; + else if (addr == LUSR_OFF(magic)) + error = 1; + else if (addr == LUSR_OFF(u_comm)) + error = 1; + else { +#ifdef DEBUG_LINUX + printf("linux_ptrace: unsupported address: %d\n", addr); +#endif + error = 1; + } + + PRELE(t); + + error = process_write_regs(t,regs); + if (error) + goto out; - case LINUX_PTRACE_POKEUSR: - /* - * XXX NetBSD/i386 only handle debugregs here. It seems these - * debugregs are not availlable on powerpc. Hence we do nothing. - */ break; default: /* never reached */ |
