summaryrefslogtreecommitdiff
path: root/src/pkg/runtime/cgo
diff options
context:
space:
mode:
authorMichael Stapelberg <stapelberg@debian.org>2013-12-03 09:43:15 +0100
committerMichael Stapelberg <stapelberg@debian.org>2013-12-03 09:43:15 +0100
commit64d2a7c8945ba05af859901f5e248f1befdd8621 (patch)
tree013fcb7e9e3296ecdda876012252c36bd6bcb063 /src/pkg/runtime/cgo
parentb901efe83e212f0c34c769c079e41373da12d723 (diff)
downloadgolang-64d2a7c8945ba05af859901f5e248f1befdd8621.tar.gz
Imported Upstream version 1.2upstream/1.2
Diffstat (limited to 'src/pkg/runtime/cgo')
-rw-r--r--src/pkg/runtime/cgo/asm_386.s4
-rw-r--r--src/pkg/runtime/cgo/asm_amd64.s4
-rw-r--r--src/pkg/runtime/cgo/asm_arm.s13
-rw-r--r--src/pkg/runtime/cgo/callbacks.c3
-rw-r--r--src/pkg/runtime/cgo/cgo.go1
-rw-r--r--src/pkg/runtime/cgo/cgo_arm.c12
-rw-r--r--src/pkg/runtime/cgo/dragonfly.c13
-rw-r--r--src/pkg/runtime/cgo/gcc_arm.S21
-rw-r--r--src/pkg/runtime/cgo/gcc_dragonfly_386.c77
-rw-r--r--src/pkg/runtime/cgo/gcc_dragonfly_amd64.c77
-rw-r--r--src/pkg/runtime/cgo/gcc_freebsd_arm.c64
-rw-r--r--src/pkg/runtime/cgo/gcc_linux_arm.c55
-rw-r--r--src/pkg/runtime/cgo/gcc_netbsd_arm.c59
-rw-r--r--src/pkg/runtime/cgo/gcc_setenv.c2
-rw-r--r--src/pkg/runtime/cgo/gcc_util.c2
-rw-r--r--src/pkg/runtime/cgo/iscgo.c1
-rw-r--r--src/pkg/runtime/cgo/setenv.c2
17 files changed, 222 insertions, 188 deletions
diff --git a/src/pkg/runtime/cgo/asm_386.s b/src/pkg/runtime/cgo/asm_386.s
index 7faaa4097..ab2f1d17a 100644
--- a/src/pkg/runtime/cgo/asm_386.s
+++ b/src/pkg/runtime/cgo/asm_386.s
@@ -2,11 +2,13 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+#include "../../../cmd/ld/textflag.h"
+
/*
* void crosscall2(void (*fn)(void*, int32), void*, int32)
* Save registers and call fn with two arguments.
*/
-TEXT crosscall2(SB),7,$0
+TEXT crosscall2(SB),NOSPLIT,$0
PUSHL BP
MOVL SP, BP
PUSHL BX
diff --git a/src/pkg/runtime/cgo/asm_amd64.s b/src/pkg/runtime/cgo/asm_amd64.s
index 53f7148a2..64f719ab1 100644
--- a/src/pkg/runtime/cgo/asm_amd64.s
+++ b/src/pkg/runtime/cgo/asm_amd64.s
@@ -2,11 +2,13 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+#include "../../../cmd/ld/textflag.h"
+
/*
* void crosscall2(void (*fn)(void*, int32), void*, int32)
* Save registers and call fn with two arguments.
*/
-TEXT crosscall2(SB),7,$0
+TEXT crosscall2(SB),NOSPLIT,$0
SUBQ $0x58, SP /* keeps stack pointer 32-byte aligned */
MOVQ BX, 0x10(SP)
MOVQ BP, 0x18(SP)
diff --git a/src/pkg/runtime/cgo/asm_arm.s b/src/pkg/runtime/cgo/asm_arm.s
index a6ea0dc07..850b1c6b6 100644
--- a/src/pkg/runtime/cgo/asm_arm.s
+++ b/src/pkg/runtime/cgo/asm_arm.s
@@ -2,22 +2,23 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+#include "../../../cmd/ld/textflag.h"
+
/*
* void crosscall2(void (*fn)(void*, int32), void*, int32)
* Save registers and call fn with two arguments.
*/
-TEXT crosscall2(SB),7,$-4
+TEXT crosscall2(SB),NOSPLIT,$-4
/*
* We still need to save all callee save register as before, and then
* push 2 args for fn (R1 and R2).
* Also note that at procedure entry in 5c/5g world, 4(R13) will be the
* first arg, so we must push another dummy reg (R0) for 0(R13).
- * Additionally, cgo_tls_set_gm will clobber R0, so we need to save R0
+ * Additionally, runtime·load_gm will clobber R0, so we need to save R0
* nevertheless.
*/
- MOVM.WP [R0, R1, R2, R4, R5, R6, R7, R8, R9, R10, R11, R12, R14], (R13)
- MOVW _cgo_load_gm(SB), R0
- BL (R0)
+ MOVM.WP [R0, R1, R2, R4, R5, R6, R7, R8, m, g, R11, R12, R14], (R13)
+ BL runtime·load_gm(SB)
MOVW PC, R14
MOVW 0(R13), PC
- MOVM.IAW (R13), [R0, R1, R2, R4, R5, R6, R7, R8, R9, R10, R11, R12, PC]
+ MOVM.IAW (R13), [R0, R1, R2, R4, R5, R6, R7, R8, m, g, R11, R12, PC]
diff --git a/src/pkg/runtime/cgo/callbacks.c b/src/pkg/runtime/cgo/callbacks.c
index 524f30428..e91c8bf8a 100644
--- a/src/pkg/runtime/cgo/callbacks.c
+++ b/src/pkg/runtime/cgo/callbacks.c
@@ -4,6 +4,7 @@
#include "../runtime.h"
#include "../cgocall.h"
+#include "../../../cmd/ld/textflag.h"
// These utility functions are available to be called from code
// compiled with gcc via crosscall2.
@@ -47,6 +48,7 @@ _cgo_allocate_internal(uintptr len, byte *ret)
#pragma cgo_export_static _cgo_allocate
#pragma cgo_export_dynamic _cgo_allocate
+#pragma textflag NOSPLIT
void
_cgo_allocate(void *a, int32 n)
{
@@ -76,6 +78,7 @@ _cgo_panic_internal(byte *p)
#pragma cgo_export_static _cgo_panic
#pragma cgo_export_dynamic _cgo_panic
+#pragma textflag NOSPLIT
void
_cgo_panic(void *a, int32 n)
{
diff --git a/src/pkg/runtime/cgo/cgo.go b/src/pkg/runtime/cgo/cgo.go
index e0d538668..258b6fba1 100644
--- a/src/pkg/runtime/cgo/cgo.go
+++ b/src/pkg/runtime/cgo/cgo.go
@@ -12,6 +12,7 @@ package cgo
/*
#cgo darwin LDFLAGS: -lpthread
+#cgo dragonfly LDFLAGS: -lpthread
#cgo freebsd LDFLAGS: -lpthread
#cgo linux LDFLAGS: -lpthread
#cgo netbsd LDFLAGS: -lpthread
diff --git a/src/pkg/runtime/cgo/cgo_arm.c b/src/pkg/runtime/cgo/cgo_arm.c
deleted file mode 100644
index d23f53e77..000000000
--- a/src/pkg/runtime/cgo/cgo_arm.c
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#pragma cgo_import_static x_cgo_load_gm
-extern void x_cgo_load_gm(void);
-void (*_cgo_load_gm)(void) = x_cgo_load_gm;
-
-#pragma cgo_import_static x_cgo_save_gm
-extern void x_cgo_save_gm(void);
-void (*_cgo_save_gm)(void) = x_cgo_save_gm;
-
diff --git a/src/pkg/runtime/cgo/dragonfly.c b/src/pkg/runtime/cgo/dragonfly.c
new file mode 100644
index 000000000..acf53e265
--- /dev/null
+++ b/src/pkg/runtime/cgo/dragonfly.c
@@ -0,0 +1,13 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Supply environ and __progname, because we don't
+// link against the standard DragonFly crt0.o and the
+// libc dynamic library needs them.
+
+char *environ[1];
+char *__progname;
+
+#pragma dynexport environ environ
+#pragma dynexport __progname __progname
diff --git a/src/pkg/runtime/cgo/gcc_arm.S b/src/pkg/runtime/cgo/gcc_arm.S
index 3ec6e5d97..17e98d91f 100644
--- a/src/pkg/runtime/cgo/gcc_arm.S
+++ b/src/pkg/runtime/cgo/gcc_arm.S
@@ -12,7 +12,14 @@
#endif
/*
- * void crosscall_arm2(void (*fn)(void), void *g, void *m)
+ * Because the assembler might target an earlier revision of the ISA
+ * by default, we must explicitly specify the ISA revision to ensure
+ * BLX is recognized as a valid instruction.
+ */
+.arch armv5t
+
+/*
+ * void crosscall_arm2(void (*fn)(void), void (*setmg_gcc)(void *m, void *g), void *m, void *g)
*
* Calling into the 5c tool chain, where all registers are caller save.
* Called from standard ARM EABI, where r4-r11 are callee-save, so they
@@ -21,12 +28,12 @@
.globl EXT(crosscall_arm2)
EXT(crosscall_arm2):
push {r4, r5, r6, r7, r8, r9, r10, r11, ip, lr}
- mov r10, r1 // g
- mov r9, r2 // m
- mov r3, r0 // save r0, cgo_tls_set_gm will clobber it
- bl EXT(x_cgo_save_gm) // save current g and m into TLS variable
- mov lr, pc
- mov pc, r3
+ mov r4, r0
+ mov r5, r1
+ mov r0, r2
+ mov r1, r3
+ blx r5 // setmg(m, g)
+ blx r4 // fn()
pop {r4, r5, r6, r7, r8, r9, r10, r11, ip, pc}
.globl EXT(__stack_chk_fail_local)
diff --git a/src/pkg/runtime/cgo/gcc_dragonfly_386.c b/src/pkg/runtime/cgo/gcc_dragonfly_386.c
new file mode 100644
index 000000000..6797824c6
--- /dev/null
+++ b/src/pkg/runtime/cgo/gcc_dragonfly_386.c
@@ -0,0 +1,77 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include <sys/types.h>
+#include <sys/signalvar.h>
+#include <pthread.h>
+#include <signal.h>
+#include <string.h>
+#include "libcgo.h"
+
+static void* threadentry(void*);
+static void (*setmg_gcc)(void*, void*);
+
+void
+x_cgo_init(G *g, void (*setmg)(void*, void*))
+{
+ pthread_attr_t attr;
+ size_t size;
+
+ setmg_gcc = setmg;
+ pthread_attr_init(&attr);
+ pthread_attr_getstacksize(&attr, &size);
+ g->stackguard = (uintptr)&attr - size + 4096;
+ pthread_attr_destroy(&attr);
+}
+
+
+void
+_cgo_sys_thread_start(ThreadStart *ts)
+{
+ pthread_attr_t attr;
+ sigset_t ign, oset;
+ pthread_t p;
+ size_t size;
+ int err;
+
+ SIGFILLSET(ign);
+ sigprocmask(SIG_SETMASK, &ign, &oset);
+
+ pthread_attr_init(&attr);
+ pthread_attr_getstacksize(&attr, &size);
+ ts->g->stackguard = size;
+ err = pthread_create(&p, &attr, threadentry, ts);
+
+ sigprocmask(SIG_SETMASK, &oset, nil);
+
+ if (err != 0) {
+ fprintf(stderr, "runtime/cgo: pthread_create failed: %s\n", strerror(err));
+ abort();
+ }
+}
+
+static void*
+threadentry(void *v)
+{
+ ThreadStart ts;
+
+ ts = *(ThreadStart*)v;
+ free(v);
+
+ ts.g->stackbase = (uintptr)&ts;
+
+ /*
+ * _cgo_sys_thread_start set stackguard to stack size;
+ * change to actual guard pointer.
+ */
+ ts.g->stackguard = (uintptr)&ts - ts.g->stackguard + 4096;
+
+ /*
+ * Set specific keys.
+ */
+ setmg_gcc((void*)ts.m, (void*)ts.g);
+
+ crosscall_386(ts.fn);
+ return nil;
+}
diff --git a/src/pkg/runtime/cgo/gcc_dragonfly_amd64.c b/src/pkg/runtime/cgo/gcc_dragonfly_amd64.c
new file mode 100644
index 000000000..eb342a2ff
--- /dev/null
+++ b/src/pkg/runtime/cgo/gcc_dragonfly_amd64.c
@@ -0,0 +1,77 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include <sys/types.h>
+#include <sys/signalvar.h>
+#include <pthread.h>
+#include <signal.h>
+#include <string.h>
+#include "libcgo.h"
+
+static void* threadentry(void*);
+static void (*setmg_gcc)(void*, void*);
+
+void
+x_cgo_init(G *g, void (*setmg)(void*, void*))
+{
+ pthread_attr_t attr;
+ size_t size;
+
+ setmg_gcc = setmg;
+ pthread_attr_init(&attr);
+ pthread_attr_getstacksize(&attr, &size);
+ g->stackguard = (uintptr)&attr - size + 4096;
+ pthread_attr_destroy(&attr);
+}
+
+void
+_cgo_sys_thread_start(ThreadStart *ts)
+{
+ pthread_attr_t attr;
+ sigset_t ign, oset;
+ pthread_t p;
+ size_t size;
+ int err;
+
+ SIGFILLSET(ign);
+ sigprocmask(SIG_SETMASK, &ign, &oset);
+
+ pthread_attr_init(&attr);
+ pthread_attr_getstacksize(&attr, &size);
+
+ ts->g->stackguard = size;
+ err = pthread_create(&p, &attr, threadentry, ts);
+
+ sigprocmask(SIG_SETMASK, &oset, nil);
+
+ if (err != 0) {
+ fprintf(stderr, "runtime/cgo: pthread_create failed: %s\n", strerror(err));
+ abort();
+ }
+}
+
+static void*
+threadentry(void *v)
+{
+ ThreadStart ts;
+
+ ts = *(ThreadStart*)v;
+ free(v);
+
+ ts.g->stackbase = (uintptr)&ts;
+
+ /*
+ * _cgo_sys_thread_start set stackguard to stack size;
+ * change to actual guard pointer.
+ */
+ ts.g->stackguard = (uintptr)&ts - ts.g->stackguard + 4096;
+
+ /*
+ * Set specific keys.
+ */
+ setmg_gcc((void*)ts.m, (void*)ts.g);
+
+ crosscall_amd64(ts.fn);
+ return nil;
+}
diff --git a/src/pkg/runtime/cgo/gcc_freebsd_arm.c b/src/pkg/runtime/cgo/gcc_freebsd_arm.c
index 73c990c28..211dca75c 100644
--- a/src/pkg/runtime/cgo/gcc_freebsd_arm.c
+++ b/src/pkg/runtime/cgo/gcc_freebsd_arm.c
@@ -8,72 +8,26 @@
#include <string.h>
#include "libcgo.h"
-static void *threadentry(void*);
-
-// We have to resort to TLS variable to save g(R10) and
-// m(R9). One reason is that external code might trigger
-// SIGSEGV, and our runtime.sigtramp don't even know we
-// are in external code, and will continue to use R10/R9,
-// this might as well result in another SIGSEGV.
-// Note: all three functions will clobber R0, and the last
-// two can be called from 5c ABI code.
-void __aeabi_read_tp(void) __attribute__((naked));
-void x_cgo_save_gm(void) __attribute__((naked));
-void x_cgo_load_gm(void) __attribute__((naked));
-
-void
-__aeabi_read_tp(void)
-{
- __asm__ __volatile__ (
#ifdef ARM_TP_ADDRESS
- // ARM_TP_ADDRESS is (ARM_VECTORS_HIGH + 0x1000) or 0xffff1000
- // GCC inline asm doesn't provide a way to provide a constant
- // to "ldr r0, =??" pseudo instruction, so we hardcode the value
- // and check it with cpp.
+// ARM_TP_ADDRESS is (ARM_VECTORS_HIGH + 0x1000) or 0xffff1000
+// and is known to runtime.read_tls_fallback. Verify it with
+// cpp.
#if ARM_TP_ADDRESS != 0xffff1000
#error Wrong ARM_TP_ADDRESS!
#endif
- "ldr r0, =0xffff1000\n\t"
- "ldr r0, [r0]\n\t"
-#else
- "mrc p15, 0, r0, c13, c0, 3\n\t"
#endif
- "mov pc, lr\n\t"
- );
-}
-// g (R10) at 8(TP), m (R9) at 12(TP)
-void
-x_cgo_load_gm(void)
-{
- __asm__ __volatile__ (
- "push {lr}\n\t"
- "bl __aeabi_read_tp\n\t"
- "ldr r10, [r0, #8]\n\t"
- "ldr r9, [r0, #12]\n\t"
- "pop {pc}\n\t"
- );
-}
+static void *threadentry(void*);
-void
-x_cgo_save_gm(void)
-{
- __asm__ __volatile__ (
- "push {lr}\n\t"
- "bl __aeabi_read_tp\n\t"
- "str r10, [r0, #8]\n\t"
- "str r9, [r0, #12]\n\t"
- "pop {pc}\n\t"
- );
-}
+static void (*setmg_gcc)(void*, void*);
void
-x_cgo_init(G *g)
+x_cgo_init(G *g, void (*setmg)(void*, void*))
{
pthread_attr_t attr;
size_t size;
- x_cgo_save_gm(); // save g and m for the initial thread
+ setmg_gcc = setmg;
pthread_attr_init(&attr);
pthread_attr_getstacksize(&attr, &size);
g->stackguard = (uintptr)&attr - size + 4096;
@@ -104,7 +58,7 @@ _cgo_sys_thread_start(ThreadStart *ts)
}
}
-extern void crosscall_arm2(void (*fn)(void), void *g, void *m);
+extern void crosscall_arm2(void (*fn)(void), void (*setmg_gcc)(void*, void*), void *g, void *m);
static void*
threadentry(void *v)
{
@@ -121,6 +75,6 @@ threadentry(void *v)
*/
ts.g->stackguard = (uintptr)&ts - ts.g->stackguard + 4096 * 2;
- crosscall_arm2(ts.fn, (void *)ts.g, (void *)ts.m);
+ crosscall_arm2(ts.fn, setmg_gcc, (void*)ts.m, (void*)ts.g);
return nil;
}
diff --git a/src/pkg/runtime/cgo/gcc_linux_arm.c b/src/pkg/runtime/cgo/gcc_linux_arm.c
index 46a1126ad..9a6e58594 100644
--- a/src/pkg/runtime/cgo/gcc_linux_arm.c
+++ b/src/pkg/runtime/cgo/gcc_linux_arm.c
@@ -8,60 +8,15 @@
static void *threadentry(void*);
-// We have to resort to TLS variable to save g(R10) and
-// m(R9). One reason is that external code might trigger
-// SIGSEGV, and our runtime.sigtramp don't even know we
-// are in external code, and will continue to use R10/R9,
-// this might as well result in another SIGSEGV.
-// Note: all three functions will clobber R0, and the last
-// two can be called from 5c ABI code.
-void __aeabi_read_tp(void) __attribute__((naked));
-void x_cgo_save_gm(void) __attribute__((naked));
-void x_cgo_load_gm(void) __attribute__((naked));
+static void (*setmg_gcc)(void*, void*);
void
-__aeabi_read_tp(void)
-{
- // b __kuser_get_tls @ 0xffff0fe0
- __asm__ __volatile__ (
- "mvn r0, #0xf000\n\t"
- "sub pc, r0, #31\n\t"
- "nop\n\tnop\n\t"
- );
-}
-
-// g (R10) at 8(TP), m (R9) at 12(TP)
-void
-x_cgo_load_gm(void)
-{
- __asm__ __volatile__ (
- "push {lr}\n\t"
- "bl __aeabi_read_tp\n\t"
- "ldr r10, [r0, #8]\n\t"
- "ldr r9, [r0, #12]\n\t"
- "pop {pc}\n\t"
- );
-}
-
-void
-x_cgo_save_gm(void)
-{
- __asm__ __volatile__ (
- "push {lr}\n\t"
- "bl __aeabi_read_tp\n\t"
- "str r10, [r0, #8]\n\t"
- "str r9, [r0, #12]\n\t"
- "pop {pc}\n\t"
- );
-}
-
-void
-x_cgo_init(G *g)
+x_cgo_init(G *g, void (*setmg)(void*, void*))
{
pthread_attr_t attr;
size_t size;
- x_cgo_save_gm(); // save g and m for the initial thread
+ setmg_gcc = setmg;
pthread_attr_init(&attr);
pthread_attr_getstacksize(&attr, &size);
g->stackguard = (uintptr)&attr - size + 4096;
@@ -92,7 +47,7 @@ _cgo_sys_thread_start(ThreadStart *ts)
}
}
-extern void crosscall_arm2(void (*fn)(void), void *g, void *m);
+extern void crosscall_arm2(void (*fn)(void), void (*setmg_gcc)(void*, void*), void*, void*);
static void*
threadentry(void *v)
{
@@ -109,6 +64,6 @@ threadentry(void *v)
*/
ts.g->stackguard = (uintptr)&ts - ts.g->stackguard + 4096 * 2;
- crosscall_arm2(ts.fn, (void *)ts.g, (void *)ts.m);
+ crosscall_arm2(ts.fn, setmg_gcc, (void*)ts.m, (void*)ts.g);
return nil;
}
diff --git a/src/pkg/runtime/cgo/gcc_netbsd_arm.c b/src/pkg/runtime/cgo/gcc_netbsd_arm.c
index d93b531e7..68c8b6e71 100644
--- a/src/pkg/runtime/cgo/gcc_netbsd_arm.c
+++ b/src/pkg/runtime/cgo/gcc_netbsd_arm.c
@@ -10,64 +10,15 @@
static void *threadentry(void*);
-// We have to resort to TLS variable to save g(R10) and
-// m(R9). One reason is that external code might trigger
-// SIGSEGV, and our runtime.sigtramp don't even know we
-// are in external code, and will continue to use R10/R9,
-// this might as well result in another SIGSEGV.
-// Note: all three functions will clobber R0, and the last
-// two can be called from 5c ABI code.
-void __aeabi_read_tp(void) __attribute__((naked));
-void x_cgo_save_gm(void) __attribute__((naked));
-void x_cgo_load_gm(void) __attribute__((naked));
+static void (*setmg_gcc)(void*, void*);
void
-__aeabi_read_tp(void)
-{
- // this function is only allowed to clobber r0
- __asm__ __volatile__ (
- "mrc p15, 0, r0, c13, c0, 3\n\t"
- "cmp r0, #0\n\t"
- "movne pc, lr\n\t"
- "push {r1,r2,r3,r12}\n\t"
- "svc 0x00a0013c\n\t" // _lwp_getprivate
- "pop {r1,r2,r3,r12}\n\t"
- "mov pc, lr\n\t"
- );
-}
-
-// g (R10) at 8(TP), m (R9) at 12(TP)
-void
-x_cgo_load_gm(void)
-{
- __asm__ __volatile__ (
- "push {lr}\n\t"
- "bl __aeabi_read_tp\n\t"
- "ldr r10, [r0, #8]\n\t"
- "ldr r9, [r0, #12]\n\t"
- "pop {pc}\n\t"
- );
-}
-
-void
-x_cgo_save_gm(void)
-{
- __asm__ __volatile__ (
- "push {lr}\n\t"
- "bl __aeabi_read_tp\n\t"
- "str r10, [r0, #8]\n\t"
- "str r9, [r0, #12]\n\t"
- "pop {pc}\n\t"
- );
-}
-
-void
-x_cgo_init(G *g)
+x_cgo_init(G *g, void (*setmg)(void*, void*))
{
pthread_attr_t attr;
size_t size;
- x_cgo_save_gm(); // save g and m for the initial thread
+ setmg_gcc = setmg;
pthread_attr_init(&attr);
pthread_attr_getstacksize(&attr, &size);
g->stackguard = (uintptr)&attr - size + 4096;
@@ -100,7 +51,7 @@ _cgo_sys_thread_start(ThreadStart *ts)
}
}
-extern void crosscall_arm2(void (*fn)(void), void *g, void *m);
+extern void crosscall_arm2(void (*fn)(void), void (*setmg_gcc)(void*, void*), void *g, void *m);
static void*
threadentry(void *v)
{
@@ -117,6 +68,6 @@ threadentry(void *v)
*/
ts.g->stackguard = (uintptr)&ts - ts.g->stackguard + 4096 * 2;
- crosscall_arm2(ts.fn, (void *)ts.g, (void *)ts.m);
+ crosscall_arm2(ts.fn, setmg_gcc, (void*)ts.m, (void*)ts.g);
return nil;
}
diff --git a/src/pkg/runtime/cgo/gcc_setenv.c b/src/pkg/runtime/cgo/gcc_setenv.c
index a0938166d..8b128b946 100644
--- a/src/pkg/runtime/cgo/gcc_setenv.c
+++ b/src/pkg/runtime/cgo/gcc_setenv.c
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build darwin freebsd linux netbsd openbsd
+// +build darwin dragonfly freebsd linux netbsd openbsd
#include "libcgo.h"
diff --git a/src/pkg/runtime/cgo/gcc_util.c b/src/pkg/runtime/cgo/gcc_util.c
index 20913d736..143734e94 100644
--- a/src/pkg/runtime/cgo/gcc_util.c
+++ b/src/pkg/runtime/cgo/gcc_util.c
@@ -14,6 +14,8 @@ x_cgo_malloc(void *p)
} *a = p;
a->ret = malloc(a->n);
+ if(a->ret == NULL && a->n == 0)
+ a->ret = malloc(1);
}
/* Stub for calling free from Go */
diff --git a/src/pkg/runtime/cgo/iscgo.c b/src/pkg/runtime/cgo/iscgo.c
index eb6f5c09d..0907a1958 100644
--- a/src/pkg/runtime/cgo/iscgo.c
+++ b/src/pkg/runtime/cgo/iscgo.c
@@ -12,3 +12,4 @@
#include "../runtime.h"
bool runtime·iscgo = 1;
+uint32 runtime·needextram = 1; // create an extra M on first cgo call
diff --git a/src/pkg/runtime/cgo/setenv.c b/src/pkg/runtime/cgo/setenv.c
index 4c47cdb00..2d03db09f 100644
--- a/src/pkg/runtime/cgo/setenv.c
+++ b/src/pkg/runtime/cgo/setenv.c
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build darwin freebsd linux netbsd openbsd
+// +build darwin dragonfly freebsd linux netbsd openbsd
#pragma cgo_import_static x_cgo_setenv