summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2018-04-22 19:29:39 -0700
committerOri Bernstein <ori@eigenstate.org>2018-04-22 19:29:39 -0700
commit4ac578a191635f9728dc66dd99b22cc54692b4ef (patch)
tree3dc934a23ce92cd52f53a566c49569778eddc73b
parent3d71446ecb6569add0d9eaf2e7e4a05d99bd2625 (diff)
downloadmc-4ac578a191635f9728dc66dd99b22cc54692b4ef.tar.gz
Add a special exit stack to our thread library.
Because OpenBSD wants a valid stack pointer in any code that enters the kernel, unmapping our stack as part of exiting the process is rather unreliable. This change allocates a stack page that we can switch to when a thread is deallocating itself, which keeps the kernel happy.
-rw-r--r--6/insns.def2
-rw-r--r--lib/sys/sys+openbsd:6.1-x64.myr1
-rw-r--r--lib/thread/exit+openbsd-x64.s7
-rw-r--r--lib/thread/spawn+openbsd.myr6
-rw-r--r--lib/thread/test/spawn.myr1
5 files changed, 16 insertions, 1 deletions
diff --git a/6/insns.def b/6/insns.def
index cc80adf..f7125fc 100644
--- a/6/insns.def
+++ b/6/insns.def
@@ -287,7 +287,7 @@ Insn(Ixorp,
/* branch instructions */
Insn(Icall,
- "\tcall %v\n",
+ "\tcall %v@PLT\n",
"\tCALL %V\n",
Use(.l={1}, .r={
Rrdi, Rrsi, Rrdx, Rrcx, Rr8, Rr9,
diff --git a/lib/sys/sys+openbsd:6.1-x64.myr b/lib/sys/sys+openbsd:6.1-x64.myr
index 64cc453..32f5da0 100644
--- a/lib/sys/sys+openbsd:6.1-x64.myr
+++ b/lib/sys/sys+openbsd:6.1-x64.myr
@@ -272,6 +272,7 @@ pkg sys =
const Mfixed : mopt = 0x10
const Mfile : mopt = 0x0
const Manon : mopt = 0x1000
+ const Mstack : mopt = 0x4000
const Mnoreplace : mopt = 0x0800
/* file types */
diff --git a/lib/thread/exit+openbsd-x64.s b/lib/thread/exit+openbsd-x64.s
index 23f92b5..6421cc3 100644
--- a/lib/thread/exit+openbsd-x64.s
+++ b/lib/thread/exit+openbsd-x64.s
@@ -10,6 +10,13 @@ thread$exit:
andq $~0xfff,%rdi /* align it */
addq $0x1000,%rdi
+ /*
+ Because OpenBSD wants a valid stack whenever
+ we enter the kernel, we need to toss a preallocated
+ stack pointer into %rsp.
+ */
+ movq thread$exitstk,%rsp
+
/* munmap(base, size) */
movq $73,%rax /* munmap */
movq -8(%rdi),%rsi /* size */
diff --git a/lib/thread/spawn+openbsd.myr b/lib/thread/spawn+openbsd.myr
index c925349..d02bd5c 100644
--- a/lib/thread/spawn+openbsd.myr
+++ b/lib/thread/spawn+openbsd.myr
@@ -5,11 +5,17 @@ pkg thread =
type tid = uint64
const spawn : (fn : (-> void) -> std.result(tid, byte[:]))
+ pkglocal var exitstk : byte#
;;
const Stacksz = 8*std.MiB
extern const exit : (-> void)
+var exitstk
+const __init__ = {
+ exitstk = getstk(16)
+}
+
const spawn = {fn;
-> spawnstk(fn, Stacksz)
}
diff --git a/lib/thread/test/spawn.myr b/lib/thread/test/spawn.myr
index 2bd3b24..9fd0580 100644
--- a/lib/thread/test/spawn.myr
+++ b/lib/thread/test/spawn.myr
@@ -21,5 +21,6 @@ const main = {
;;
std.assert(capture == 333, "capture wasn't written to correctly\n")
+ std.usleep(100_000)
}