summaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2008-09-16 19:41:07 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2008-09-16 19:41:07 +0000
commita2576e00952250b7829946bc40bcf23768502974 (patch)
tree2d5720bcc0565cf270a25d43241478c105a09b53 /sys/kern
parentfb6ae06dc5a8218bd9fb19798e4adcce4e2d8b28 (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.c58
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