diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2008-09-16 19:41:07 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2008-09-16 19:41:07 +0000 |
commit | a2576e00952250b7829946bc40bcf23768502974 (patch) | |
tree | 2d5720bcc0565cf270a25d43241478c105a09b53 /sys/kern | |
parent | fb6ae06dc5a8218bd9fb19798e4adcce4e2d8b28 (diff) |
Add PIOD_READ_AUXV, a way to get the ELF auxilliary vector through ptrace(2).
ok miod@
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/sys_process.c | 58 |
1 files changed, 57 insertions, 1 deletions
diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c index 748e07bf99f..6759fd8c15c 100644 --- a/sys/kern/sys_process.c +++ b/sys/kern/sys_process.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sys_process.c,v 1.39 2007/04/10 17:47:55 miod Exp $ */ +/* $OpenBSD: sys_process.c,v 1.40 2008/09/16 19:41:06 kettenis Exp $ */ /* $NetBSD: sys_process.c,v 1.55 1996/05/15 06:17:47 tls Exp $ */ /*- @@ -51,6 +51,7 @@ #include <sys/param.h> #include <sys/systm.h> +#include <sys/exec.h> #include <sys/proc.h> #include <sys/signalvar.h> #include <sys/errno.h> @@ -67,6 +68,8 @@ #include <machine/reg.h> +int process_auxv_offset(struct proc *, struct proc *, struct uio *); + #ifdef PTRACE /* * Process debugging system call. @@ -289,6 +292,19 @@ sys_ptrace(struct proc *p, void *v, register_t *retval) req = PT_WRITE_D; uio.uio_rw = UIO_WRITE; break; + case PIOD_READ_AUXV: + req = PT_READ_D; + uio.uio_rw = UIO_READ; + temp = t->p_emul->e_arglen * sizeof(char *); + if (uio.uio_offset > temp) + return (EIO); + if (uio.uio_resid > temp - uio.uio_offset) + uio.uio_resid = temp - uio.uio_offset; + piod.piod_len = iov.iov_len = uio.uio_resid; + error = process_auxv_offset(p, t, &uio); + if (error) + return (error); + break; default: return (EINVAL); } @@ -598,3 +614,43 @@ process_domem(struct proc *curp, struct proc *p, struct uio *uio, int req) return (error); } + +#ifdef PTRACE +int +process_auxv_offset(struct proc *curp, struct proc *p, struct uio *uiop) +{ + struct ps_strings pss; + struct iovec iov; + struct uio uio; + int error; + + iov.iov_base = &pss; + iov.iov_len = sizeof(pss); + uio.uio_iov = &iov; + uio.uio_iovcnt = 1; + uio.uio_offset = (off_t)PS_STRINGS; + uio.uio_resid = sizeof(pss); + uio.uio_segflg = UIO_SYSSPACE; + uio.uio_rw = UIO_READ; + uio.uio_procp = curp; + + if ((error = uvm_io(&p->p_vmspace->vm_map, &uio, 0)) != 0) + return (error); + + if (pss.ps_envstr == NULL) + return (EIO); + + uiop->uio_offset += (off_t)(long)(pss.ps_envstr + pss.ps_nenvstr + 1); +#ifdef MACHINE_STACK_GROWS_UP + if (uiop->uio_offset < (off_t)PS_STRINGS) + return (EIO); +#else + if (uiop->uio_offset > (off_t)PS_STRINGS) + return (EIO); + if ((uiop->uio_offset + uiop->uio_resid) > (off_t)PS_STRINGS) + uiop->uio_resid = (off_t)PS_STRINGS - uiop->uio_offset; +#endif + + return (0); +} +#endif |