[dev.regabi] runtime/cgo: call setg_gcc in crosscall_amd64

Currently, when using cgo, the g pointer is set via a separate
call to setg_gcc or with inline assembly in threadentry. This CL
changes it to call setg_gcc in crosscall_amd64, like other g-
register platforms. When we have an actual g register on AMD64,
we'll need to set the register immediately before calling into
Go.

Change-Id: Ib1171e05cd0dabba3b7d12e072084d141051cf3d
Reviewed-on: https://go-review.googlesource.com/c/go/+/289192
Trust: Cherry Zhang <cherryyz@google.com>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
This commit is contained in:
Cherry Zhang 2021-02-02 17:26:57 -05:00
parent 120b819f45
commit 63de211014
10 changed files with 23 additions and 49 deletions

View file

@ -30,9 +30,14 @@ EXT(crosscall_amd64):
pushq %r15 pushq %r15
#if defined(_WIN64) #if defined(_WIN64)
movq %r8, %rdi /* arg of setg_gcc */
call *%rdx /* setg_gcc */
call *%rcx /* fn */ call *%rcx /* fn */
#else #else
call *%rdi /* fn */ movq %rdi, %rbx
movq %rdx, %rdi /* arg of setg_gcc */
call *%rsi /* setg_gcc */
call *%rbx /* fn */
#endif #endif
popq %r15 popq %r15

View file

@ -9,13 +9,16 @@
#include "libcgo_unix.h" #include "libcgo_unix.h"
static void* threadentry(void*); static void* threadentry(void*);
static void (*setg_gcc)(void*);
void void
x_cgo_init(G *g) x_cgo_init(G *g, void (*setg)(void*), void **tlsg, void **tlsbase)
{ {
pthread_attr_t attr; pthread_attr_t attr;
size_t size; size_t size;
setg_gcc = setg;
pthread_attr_init(&attr); pthread_attr_init(&attr);
pthread_attr_getstacksize(&attr, &size); pthread_attr_getstacksize(&attr, &size);
g->stacklo = (uintptr)&attr - size + 4096; g->stacklo = (uintptr)&attr - size + 4096;
@ -57,10 +60,6 @@ threadentry(void *v)
ts = *(ThreadStart*)v; ts = *(ThreadStart*)v;
free(v); free(v);
// Move the g pointer into the slot reserved in thread local storage. crosscall_amd64(ts.fn, setg_gcc, (void*)ts.g);
// Constant must match the one in cmd/link/internal/ld/sym.go.
asm volatile("movq %0, %%gs:0x30" :: "r"(ts.g));
crosscall_amd64(ts.fn);
return nil; return nil;
} }

View file

@ -61,11 +61,6 @@ threadentry(void *v)
ts = *(ThreadStart*)v; ts = *(ThreadStart*)v;
free(v); free(v);
/* crosscall_amd64(ts.fn, setg_gcc, (void*)ts.g);
* Set specific keys.
*/
setg_gcc((void*)ts.g);
crosscall_amd64(ts.fn);
return nil; return nil;
} }

View file

@ -69,11 +69,6 @@ threadentry(void *v)
free(v); free(v);
_cgo_tsan_release(); _cgo_tsan_release();
/* crosscall_amd64(ts.fn, setg_gcc, (void*)ts.g);
* Set specific keys.
*/
setg_gcc((void*)ts.g);
crosscall_amd64(ts.fn);
return nil; return nil;
} }

View file

@ -89,11 +89,6 @@ threadentry(void *v)
free(v); free(v);
_cgo_tsan_release(); _cgo_tsan_release();
/* crosscall_amd64(ts.fn, setg_gcc, (void*)ts.g);
* Set specific keys.
*/
setg_gcc((void*)ts.g);
crosscall_amd64(ts.fn);
return nil; return nil;
} }

View file

@ -62,11 +62,6 @@ threadentry(void *v)
ts = *(ThreadStart*)v; ts = *(ThreadStart*)v;
free(v); free(v);
/*
* Set specific keys.
*/
setg_gcc((void*)ts.g);
// On NetBSD, a new thread inherits the signal stack of the // On NetBSD, a new thread inherits the signal stack of the
// creating thread. That confuses minit, so we remove that // creating thread. That confuses minit, so we remove that
// signal stack here before calling the regular mstart. It's // signal stack here before calling the regular mstart. It's
@ -78,6 +73,6 @@ threadentry(void *v)
ss.ss_flags = SS_DISABLE; ss.ss_flags = SS_DISABLE;
sigaltstack(&ss, nil); sigaltstack(&ss, nil);
crosscall_amd64(ts.fn); crosscall_amd64(ts.fn, setg_gcc, (void*)ts.g);
return nil; return nil;
} }

View file

@ -60,11 +60,6 @@ threadentry(void *v)
ts = *(ThreadStart*)v; ts = *(ThreadStart*)v;
free(v); free(v);
/* crosscall_amd64(ts.fn, setg_gcc, (void*)ts.g);
* Set specific keys.
*/
setg_gcc((void*)ts.g);
crosscall_amd64(ts.fn);
return nil; return nil;
} }

View file

@ -72,11 +72,6 @@ threadentry(void *v)
ts = *(ThreadStart*)v; ts = *(ThreadStart*)v;
free(v); free(v);
/* crosscall_amd64(ts.fn, setg_gcc, (void*)ts.g);
* Set specific keys.
*/
setg_gcc((void*)ts.g);
crosscall_amd64(ts.fn);
return nil; return nil;
} }

View file

@ -12,10 +12,12 @@
#include "libcgo_windows.h" #include "libcgo_windows.h"
static void threadentry(void*); static void threadentry(void*);
static void (*setg_gcc)(void*);
void void
x_cgo_init(G *g) x_cgo_init(G *g, void (*setg)(void*), void **tlsg, void **tlsbase)
{ {
setg_gcc = setg;
} }
@ -46,10 +48,8 @@ threadentry(void *v)
*/ */
asm volatile ( asm volatile (
"movq %0, %%gs:0x28\n" // MOVL tls0, 0x28(GS) "movq %0, %%gs:0x28\n" // MOVL tls0, 0x28(GS)
"movq %%gs:0x28, %%rax\n" // MOVQ 0x28(GS), tmp :: "r"(ts.tls)
"movq %1, 0(%%rax)\n" // MOVQ g, 0(GS)
:: "r"(ts.tls), "r"(ts.g) : "%rax"
); );
crosscall_amd64(ts.fn); crosscall_amd64(ts.fn, setg_gcc, (void*)ts.g);
} }

View file

@ -66,7 +66,7 @@ uintptr_t _cgo_wait_runtime_init_done(void);
/* /*
* Call fn in the 6c world. * Call fn in the 6c world.
*/ */
void crosscall_amd64(void (*fn)(void)); void crosscall_amd64(void (*fn)(void), void (*setg_gcc)(void*), void *g);
/* /*
* Call fn in the 8c world. * Call fn in the 8c world.