summaryrefslogtreecommitdiffstats
path: root/sys/compat/linux/linux_exec.c
diff options
context:
space:
mode:
authorpirofti <pirofti@openbsd.org>2011-04-05 15:44:40 +0000
committerpirofti <pirofti@openbsd.org>2011-04-05 15:44:40 +0000
commit3595609c45e61ad71974f17cd71ac52905aef42c (patch)
treef0e0cf6790fa13a8c9f90fe1d95cbfc870ceda03 /sys/compat/linux/linux_exec.c
parentBye bye, kern.emul.freebsd (diff)
downloadwireguard-openbsd-3595609c45e61ad71974f17cd71ac52905aef42c.tar.xz
wireguard-openbsd-3595609c45e61ad71974f17cd71ac52905aef42c.zip
Add set_tid_address() syscall. Lots of help from and okay guenther@.
This is more than a simple syscall.This expands TLS support quite a bit. Also linux_sys_clone() handles CLONE_CHILD_CLEARTID, CLONE_CHILD_SETTID, CLONE_PARENT_SETTID flags as well as the CLONE_SETTLS by doing what set_thread_area() is doing. Next on the list is futex support which should allow compat to cope with newer Linux kernels.
Diffstat (limited to 'sys/compat/linux/linux_exec.c')
-rw-r--r--sys/compat/linux/linux_exec.c28
1 files changed, 22 insertions, 6 deletions
diff --git a/sys/compat/linux/linux_exec.c b/sys/compat/linux/linux_exec.c
index 6eba69a0d41..f9944ab5307 100644
--- a/sys/compat/linux/linux_exec.c
+++ b/sys/compat/linux/linux_exec.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: linux_exec.c,v 1.32 2011/04/05 01:41:03 pirofti Exp $ */
+/* $OpenBSD: linux_exec.c,v 1.33 2011/04/05 15:44:40 pirofti Exp $ */
/* $NetBSD: linux_exec.c,v 1.13 1996/04/05 00:01:10 christos Exp $ */
/*-
@@ -46,6 +46,7 @@
#include <sys/mman.h>
#include <sys/syscallargs.h>
+#include <sys/signalvar.h>
#include <uvm/uvm_extern.h>
@@ -173,6 +174,18 @@ linux_e_proc_exec(struct proc *p, struct exec_package *epp)
void
linux_e_proc_exit(struct proc *p)
{
+ struct linux_emuldata *emul = p->p_emuldata;
+
+ if (emul->my_clear_tid) {
+ pid_t zero = 0;
+
+ if (copyout(&zero, emul->my_clear_tid, sizeof(zero)))
+ psignal(p, SIGSEGV);
+ /*
+ * not yet: futex(my_clear_tid, FUTEX_WAKE, 1, NULL, NULL, 0)
+ */
+ }
+
/* free Linux emuldata and set the pointer to null */
free(p->p_emuldata, M_EMULDATA);
p->p_emuldata = NULL;
@@ -184,15 +197,18 @@ linux_e_proc_exit(struct proc *p)
void
linux_e_proc_fork(struct proc *p, struct proc *parent)
{
- /*
- * It could be desirable to copy some stuff from parent's
- * emuldata. We don't need anything like that for now.
- * So just allocate new emuldata for the new process.
- */
+ struct linux_emuldata *emul = p->p_emuldata;
+ struct linux_emuldata *p_emul = parent->p_emuldata;
+
+ /* Allocate new emuldata for the new process. */
p->p_emuldata = NULL;
/* fork, use parent's vmspace (our vmspace may not be setup yet) */
linux_e_proc_init(p, parent->p_vmspace);
+
+ emul->my_set_tid = p_emul->child_set_tid;
+ emul->my_clear_tid = p_emul->child_clear_tid;
+ emul->my_tls_base = p_emul->child_tls_base;
}
static void *