void
x_cgo_init(G *g, void (*setg)(void*), void **tlsg, void **tlsbase)
{
- size_t size;
-
setg_gcc = setg;
-
- size = pthread_get_stacksize_np(pthread_self());
- g->stacklo = (uintptr)&size - size + 4096;
+ _cgo_set_stacklo(g, NULL);
}
void
x_cgo_init(G *g, void (*setg)(void*))
{
- size_t size;
-
//fprintf(stderr, "x_cgo_init = %p\n", &x_cgo_init); // aid debugging in presence of ASLR
setg_gcc = setg;
- size = pthread_get_stacksize_np(pthread_self());
- g->stacklo = (uintptr)&size - size + 4096;
+ _cgo_set_stacklo(g, NULL);
#if TARGET_OS_IPHONE
darwin_arm_init_mach_exception_handler();
void
x_cgo_init(G *g, void (*setg)(void*))
{
- pthread_attr_t attr;
- size_t size;
-
setg_gcc = setg;
- pthread_attr_init(&attr);
- pthread_attr_getstacksize(&attr, &size);
- g->stacklo = (uintptr)&attr - size + 4096;
- pthread_attr_destroy(&attr);
+ _cgo_set_stacklo(g, NULL);
}
void
void
x_cgo_init(G *g, void (*setg)(void*))
{
- pthread_attr_t attr;
- size_t size;
-
setg_gcc = setg;
- pthread_attr_init(&attr);
- pthread_attr_getstacksize(&attr, &size);
- g->stacklo = (uintptr)&attr - size + 4096;
- pthread_attr_destroy(&attr);
+ _cgo_set_stacklo(g, NULL);
}
x_cgo_init(G *g, void (*setg)(void*))
{
pthread_attr_t *attr;
- size_t size;
// Deal with memory sanitizer/clang interaction.
// See gcc_linux_amd64.c for details.
if (attr == NULL) {
fatalf("malloc failed: %s", strerror(errno));
}
- pthread_attr_init(attr);
- pthread_attr_getstacksize(attr, &size);
- g->stacklo = (uintptr)&attr - size + 4096;
- pthread_attr_destroy(attr);
+ _cgo_set_stacklo(g, attr);
free(attr);
}
void
x_cgo_init(G *g, void (*setg)(void*))
{
- pthread_attr_t attr;
- size_t size;
-
setg_gcc = setg;
- pthread_attr_init(&attr);
- pthread_attr_getstacksize(&attr, &size);
- g->stacklo = (uintptr)&attr - size + 4096;
- pthread_attr_destroy(&attr);
+ _cgo_set_stacklo(g, NULL);
}
void
void
x_cgo_init(G *g, void (*setg)(void*))
{
- pthread_attr_t attr;
- size_t size;
-
setg_gcc = setg;
- pthread_attr_init(&attr);
- pthread_attr_getstacksize(&attr, &size);
- g->stacklo = (uintptr)&attr - size + 4096;
- pthread_attr_destroy(&attr);
+ _cgo_set_stacklo(g, NULL);
}
void
void
x_cgo_init(G *g, void (*setg)(void*))
{
- pthread_attr_t attr;
- size_t size;
-
setg_gcc = setg;
- pthread_attr_init(&attr);
- pthread_attr_getstacksize(&attr, &size);
- g->stacklo = (uintptr)&attr - size + 4096;
- pthread_attr_destroy(&attr);
+ _cgo_set_stacklo(g, NULL);
}
void
return 0;
}
+// _cgo_set_stacklo sets g->stacklo based on the stack size.
+// This is common code called from x_cgo_init, which is itself
+// called by rt0_go in the runtime package.
+void _cgo_set_stacklo(G *g, pthread_attr_t *pattr)
+{
+ pthread_attr_t attr;
+ size_t size;
+
+ // pattr can be passed in by the caller; see gcc_linux_amd64.c.
+ if (pattr == NULL) {
+ pattr = &attr;
+ }
+
+ pthread_attr_init(pattr);
+ pthread_attr_getstacksize(pattr, &size);
+
+ g->stacklo = (uintptr)(__builtin_frame_address(0)) - size + 4096;
+
+ // Sanity check the results now, rather than getting a
+ // morestack on g0 crash.
+ if (g->stacklo >= g->stackhi) {
+ fprintf(stderr, "runtime/cgo: bad stack bounds: lo=%p hi=%p\n", (void*)(g->stacklo), (void*)(g->stackhi));
+ abort();
+ }
+
+ pthread_attr_destroy(pattr);
+}
+
// Store the g into a thread-specific value associated with the pthread key pthread_g.
// And pthread_key_destructor will dropm when the thread is exiting.
void x_cgo_bindm(void* g) {
void
x_cgo_init(G *g, void (*setg)(void*), void **tlsg, void **tlsbase)
{
- pthread_attr_t attr;
- size_t size;
-
setg_gcc = setg;
- pthread_attr_init(&attr);
- pthread_attr_getstacksize(&attr, &size);
- g->stacklo = (uintptr)&attr - size + 4096;
- pthread_attr_destroy(&attr);
+ _cgo_set_stacklo(g, NULL);
if (x_cgo_inittls) {
x_cgo_inittls(tlsg, tlsbase);
x_cgo_init(G *g, void (*setg)(void*), void **tlsg, void **tlsbase)
{
pthread_attr_t *attr;
- size_t size;
/* The memory sanitizer distributed with versions of clang
before 3.8 has a bug: if you call mmap before malloc, mmap
if (attr == NULL) {
fatalf("malloc failed: %s", strerror(errno));
}
- pthread_attr_init(attr);
- pthread_attr_getstacksize(attr, &size);
- g->stacklo = (uintptr)__builtin_frame_address(0) - size + 4096;
- if (g->stacklo >= g->stackhi)
- fatalf("bad stack bounds: lo=%p hi=%p\n", g->stacklo, g->stackhi);
- pthread_attr_destroy(attr);
+ _cgo_set_stacklo(g, attr);
free(attr);
if (x_cgo_inittls) {
void
x_cgo_init(G *g, void (*setg)(void*), void **tlsg, void **tlsbase)
{
- pthread_attr_t attr;
- size_t size;
-
setg_gcc = setg;
- pthread_attr_init(&attr);
- pthread_attr_getstacksize(&attr, &size);
- g->stacklo = (uintptr)&attr - size + 4096;
- pthread_attr_destroy(&attr);
+ _cgo_set_stacklo(g, NULL);
if (x_cgo_inittls) {
x_cgo_inittls(tlsg, tlsbase);
x_cgo_init(G *g, void (*setg)(void*), void **tlsg, void **tlsbase)
{
pthread_attr_t *attr;
- size_t size;
/* The memory sanitizer distributed with versions of clang
before 3.8 has a bug: if you call mmap before malloc, mmap
if (attr == NULL) {
fatalf("malloc failed: %s", strerror(errno));
}
- pthread_attr_init(attr);
- pthread_attr_getstacksize(attr, &size);
- g->stacklo = (uintptr)&size - size + 4096;
- pthread_attr_destroy(attr);
+ _cgo_set_stacklo(g, attr);
free(attr);
if (x_cgo_inittls) {
void
x_cgo_init(G *g, void (*setg)(void*), void **tlsg, void **tlsbase)
{
- pthread_attr_t attr;
- size_t size;
-
setg_gcc = setg;
- pthread_attr_init(&attr);
- pthread_attr_getstacksize(&attr, &size);
- g->stacklo = (uintptr)&attr - size + 4096;
- pthread_attr_destroy(&attr);
+ _cgo_set_stacklo(g, NULL);
if (x_cgo_inittls) {
x_cgo_inittls(tlsg, tlsbase);
void
x_cgo_init(G *g, void (*setg)(void*), void **tlsg, void **tlsbase)
{
- pthread_attr_t attr;
- size_t size;
-
setg_gcc = setg;
- pthread_attr_init(&attr);
- pthread_attr_getstacksize(&attr, &size);
- g->stacklo = (uintptr)&attr - size + 4096;
- pthread_attr_destroy(&attr);
+ _cgo_set_stacklo(g, NULL);
if (x_cgo_inittls) {
x_cgo_inittls(tlsg, tlsbase);
void
x_cgo_init(G *g, void (*setg)(void*), void **tlsg, void **tlsbase)
{
- pthread_attr_t attr;
- size_t size;
-
setg_gcc = setg;
- pthread_attr_init(&attr);
- pthread_attr_getstacksize(&attr, &size);
- g->stacklo = (uintptr)&attr - size + 4096;
- pthread_attr_destroy(&attr);
+ _cgo_set_stacklo(g, NULL);
if (x_cgo_inittls) {
x_cgo_inittls(tlsg, tlsbase);
void
x_cgo_init(G *g, void (*setg)(void*), void **tlsg, void **tlsbase)
{
- pthread_attr_t attr;
- size_t size;
-
setg_gcc = setg;
- pthread_attr_init(&attr);
- pthread_attr_getstacksize(&attr, &size);
- g->stacklo = (uintptr)&attr - size + 4096;
- pthread_attr_destroy(&attr);
+ _cgo_set_stacklo(g, NULL);
if (x_cgo_inittls) {
x_cgo_inittls(tlsg, tlsbase);
void
x_cgo_init(G *g, void (*setg)(void*), void **tlsbase)
{
- pthread_attr_t attr;
- size_t size;
-
setg_gcc = setg;
- pthread_attr_init(&attr);
- pthread_attr_getstacksize(&attr, &size);
- g->stacklo = (uintptr)&attr - size + 4096;
- pthread_attr_destroy(&attr);
+ _cgo_set_stacklo(g, NULL);
}
void
void
x_cgo_init(G *g, void (*setg)(void*))
{
- pthread_attr_t attr;
- size_t size;
-
setg_gcc = setg;
- pthread_attr_init(&attr);
- pthread_attr_getstacksize(&attr, &size);
- g->stacklo = (uintptr)&attr - size + 4096;
- pthread_attr_destroy(&attr);
+ _cgo_set_stacklo(g, NULL);
}
void
x_cgo_init(G *g, void (*setg)(void*))
{
- pthread_attr_t attr;
- size_t size;
-
setg_gcc = setg;
- pthread_attr_init(&attr);
- pthread_attr_getstacksize(&attr, &size);
- g->stacklo = (uintptr)&attr - size + 4096;
- pthread_attr_destroy(&attr);
+ _cgo_set_stacklo(g, NULL);
}
void
x_cgo_init(G *g, void (*setg)(void*))
{
- pthread_attr_t attr;
- size_t size;
-
setg_gcc = setg;
- pthread_attr_init(&attr);
- pthread_attr_getstacksize(&attr, &size);
- g->stacklo = (uintptr)&attr - size + 4096;
- pthread_attr_destroy(&attr);
+ _cgo_set_stacklo(g, NULL);
}
void
x_cgo_init(G *g, void (*setg)(void*))
{
- pthread_attr_t attr;
- size_t size;
-
setg_gcc = setg;
- pthread_attr_init(&attr);
- pthread_attr_getstacksize(&attr, &size);
- g->stacklo = (uintptr)&attr - size + 4096;
- pthread_attr_destroy(&attr);
+ _cgo_set_stacklo(g, NULL);
}
void
x_cgo_init(G *g, void (*setg)(void*))
{
- pthread_attr_t attr;
- size_t size;
-
setg_gcc = setg;
- pthread_attr_init(&attr);
- pthread_attr_getstacksize(&attr, &size);
- g->stacklo = (uintptr)&attr - size + 4096;
- pthread_attr_destroy(&attr);
+ _cgo_set_stacklo(g, NULL);
}
void
void
x_cgo_init(G *g, void (*setg)(void*))
{
- pthread_attr_t attr;
- size_t size;
-
setg_gcc = setg;
- pthread_attr_init(&attr);
- pthread_attr_getstacksize(&attr, &size);
- g->stacklo = (uintptr)&attr - size + 4096;
- pthread_attr_destroy(&attr);
+ _cgo_set_stacklo(g, NULL);
}
void
void
x_cgo_init(G *g, void (*setg)(void*))
{
- pthread_attr_t attr;
- size_t size;
-
setg_gcc = setg;
- pthread_attr_init(&attr);
- pthread_attr_getstacksize(&attr, &size);
- g->stacklo = (uintptr)&attr - size + 4096;
- pthread_attr_destroy(&attr);
+ _cgo_set_stacklo(g, NULL);
}
void
void
x_cgo_init(G *g, void (*setg)(void*))
{
- pthread_attr_t attr;
- size_t size;
-
setg_gcc = setg;
- pthread_attr_init(&attr);
- pthread_attr_getstacksize(&attr, &size);
- g->stacklo = (uintptr)&attr - size + 4096;
- pthread_attr_destroy(&attr);
+ _cgo_set_stacklo(g, NULL);
}
void
void
x_cgo_init(G *g, void (*setg)(void*))
{
- pthread_attr_t attr;
- size_t size;
-
setg_gcc = setg;
- pthread_attr_init(&attr);
- pthread_attr_getstacksize(&attr, &size);
- g->stacklo = (uintptr)&attr - size + 4096;
- pthread_attr_destroy(&attr);
+ _cgo_set_stacklo(g, NULL);
}
void
void
x_cgo_init(G *g, void (*setg)(void*), void **tlsbase)
{
- pthread_attr_t attr;
- size_t size;
-
setg_gcc = setg;
- pthread_attr_init(&attr);
- pthread_attr_getstacksize(&attr, &size);
- g->stacklo = (uintptr)&attr - size + 4096;
- pthread_attr_destroy(&attr);
+ _cgo_set_stacklo(g, NULL);
}
void
// See golang.org/issue/12210.
if(ctx.uc_stack.ss_size < 1024*1024)
g->stacklo -= 1024*1024 - ctx.uc_stack.ss_size;
+
+ // Sanity check the results now, rather than getting a
+ // morestack on g0 crash.
+ if (g->stacklo >= g->stackhi) {
+ fprintf(stderr, "runtime/cgo: bad stack bounds: lo=%p hi=%p\n", (void*)(g->stacklo), (void*)(g->stackhi));
+ abort();
+ }
}
void
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+/*
+ * Initialize g->stacklo.
+ */
+extern void _cgo_set_stacklo(G *, pthread_attr_t*);
+
/*
* Call pthread_create, retrying on EAGAIN.
*/