summaryrefslogtreecommitdiff
path: root/src/pkg/runtime/cgo/gcc_openbsd_amd64.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/runtime/cgo/gcc_openbsd_amd64.c')
-rw-r--r--src/pkg/runtime/cgo/gcc_openbsd_amd64.c21
1 files changed, 9 insertions, 12 deletions
diff --git a/src/pkg/runtime/cgo/gcc_openbsd_amd64.c b/src/pkg/runtime/cgo/gcc_openbsd_amd64.c
index d3a5e36b0..5a5a17114 100644
--- a/src/pkg/runtime/cgo/gcc_openbsd_amd64.c
+++ b/src/pkg/runtime/cgo/gcc_openbsd_amd64.c
@@ -11,6 +11,7 @@
#include "libcgo.h"
static void* threadentry(void*);
+static void (*setmg_gcc)(void*, void*);
// TCB_SIZE is sizeof(struct thread_control_block),
// as defined in /usr/src/lib/librthread/tcb.h
@@ -48,9 +49,9 @@ tcb_fixup(int mainthread)
bcopy(oldtcb, newtcb + TLS_SIZE, TCB_SIZE);
__set_tcb(newtcb + TLS_SIZE);
- // The main thread TCB is a static allocation - do not try to free it.
- if(!mainthread)
- free(oldtcb);
+ // NOTE(jsing, minux): we can't free oldtcb without causing double-free
+ // problem. so newtcb will be memory leaks. Get rid of this when OpenBSD
+ // has proper support for PT_TLS.
}
static void *
@@ -82,12 +83,13 @@ pthread_create(pthread_t *thread, const pthread_attr_t *attr,
}
void
-x_cgo_init(G *g)
+x_cgo_init(G *g, void (*setmg)(void*, void*))
{
pthread_attr_t attr;
size_t size;
void *handle;
+ setmg_gcc = setmg;
pthread_attr_init(&attr);
pthread_attr_getstacksize(&attr, &size);
g->stackguard = (uintptr)&attr - size + 4096;
@@ -155,15 +157,10 @@ threadentry(void *v)
ts.g->stackguard = (uintptr)&ts - ts.g->stackguard + 4096;
/*
- * Set specific keys. On OpenBSD/ELF, the thread local storage
- * is just before %fs:0. Our dynamic 6.out's reserve 16 bytes
- * for the two words g and m at %fs:-16 and %fs:-8.
+ * Set specific keys.
*/
- asm volatile (
- "movq %0, %%fs:-16\n" // MOVL g, -16(FS)
- "movq %1, %%fs:-8\n" // MOVL m, -8(FS)
- :: "r"(ts.g), "r"(ts.m)
- );
+ setmg_gcc((void*)ts.m, (void*)ts.g);
+
crosscall_amd64(ts.fn);
return nil;
}