...

Text file src/runtime/sys_windows_amd64.s

Documentation: runtime

     1// Copyright 2011 The Go Authors. All rights reserved.
     2// Use of this source code is governed by a BSD-style
     3// license that can be found in the LICENSE file.
     4
     5#include "go_asm.h"
     6#include "go_tls.h"
     7#include "textflag.h"
     8#include "time_windows.h"
     9#include "cgo/abi_amd64.h"
    10
    11// Offsets into Thread Environment Block (pointer in GS)
    12#define TEB_TlsSlots 0x1480
    13#define TEB_ArbitraryPtr 0x28
    14
    15// faster get/set last error
    16TEXT runtime·getlasterror(SB),NOSPLIT,$0
    17	MOVQ	0x30(GS), AX
    18	MOVL	0x68(AX), AX
    19	MOVL	AX, ret+0(FP)
    20	RET
    21
    22// Called by Windows as a Vectored Exception Handler (VEH).
    23// CX is pointer to struct containing
    24// exception record and context pointers.
    25// DX is the kind of sigtramp function.
    26// Return value of sigtrampgo is stored in AX.
    27TEXT sigtramp<>(SB),NOSPLIT,$0-0
    28	// Switch from the host ABI to the Go ABI.
    29	PUSH_REGS_HOST_TO_ABI0()
    30
    31	// Set up ABIInternal environment: cleared X15 and R14.
    32	// R14 is cleared in case there's a non-zero value in there
    33	// if called from a non-go thread.
    34	XORPS	X15, X15
    35	XORQ	R14, R14
    36
    37	get_tls(AX)
    38	CMPQ	AX, $0
    39	JE	2(PC)
    40	// Exception from Go thread, set R14.
    41	MOVQ	g(AX), R14
    42
    43	// Reserve space for spill slots.
    44	ADJSP	$16
    45	MOVQ	CX, AX
    46	MOVQ	DX, BX
    47	// Calling ABIInternal because TLS might be nil.
    48	CALL	runtime·sigtrampgo<ABIInternal>(SB)
    49	// Return value is already stored in AX.
    50
    51	ADJSP	$-16
    52
    53	POP_REGS_HOST_TO_ABI0()
    54	RET
    55
    56// Trampoline to resume execution from exception handler.
    57// This is part of the control flow guard workaround.
    58// It switches stacks and jumps to the continuation address.
    59// R8 and R9 are set above at the end of sigtrampgo
    60// in the context that starts executing at sigresume.
    61TEXT runtime·sigresume(SB),NOSPLIT|NOFRAME,$0
    62	MOVQ	R8, SP
    63	JMP	R9
    64
    65TEXT runtime·exceptiontramp(SB),NOSPLIT|NOFRAME,$0
    66	// PExceptionPointers already on CX
    67	MOVQ	$const_callbackVEH, DX
    68	JMP	sigtramp<>(SB)
    69
    70TEXT runtime·firstcontinuetramp(SB),NOSPLIT|NOFRAME,$0-0
    71	// PExceptionPointers already on CX
    72	MOVQ	$const_callbackFirstVCH, DX
    73	JMP	sigtramp<>(SB)
    74
    75TEXT runtime·lastcontinuetramp(SB),NOSPLIT|NOFRAME,$0-0
    76	// PExceptionPointers already on CX
    77	MOVQ	$const_callbackLastVCH, DX
    78	JMP	sigtramp<>(SB)
    79
    80TEXT runtime·sehtramp(SB),NOSPLIT,$40-0
    81	// CX: PEXCEPTION_RECORD ExceptionRecord
    82	// DX: ULONG64 EstablisherFrame
    83	// R8: PCONTEXT ContextRecord
    84	// R9: PDISPATCHER_CONTEXT DispatcherContext
    85	// Switch from the host ABI to the Go ABI.
    86	PUSH_REGS_HOST_TO_ABI0()
    87
    88	get_tls(AX)
    89	CMPQ	AX, $0
    90	JNE	2(PC)
    91	// This shouldn't happen, sehtramp is only attached to functions
    92	// called from Go, and exception handlers are only called from
    93	// the thread that threw the exception.
    94	INT	$3
    95
    96	// Exception from Go thread, set R14.
    97	MOVQ	g(AX), R14
    98
    99	ADJSP	$40
   100	MOVQ	CX, 0(SP)
   101	MOVQ	DX, 8(SP)
   102	MOVQ	R8, 16(SP)
   103	MOVQ	R9, 24(SP)
   104	CALL	runtime·sehhandler(SB)
   105	MOVL	32(SP), AX
   106
   107	ADJSP	$-40
   108
   109	POP_REGS_HOST_TO_ABI0()
   110	RET
   111
   112TEXT runtime·callbackasm1(SB),NOSPLIT|NOFRAME,$0
   113	// Construct args vector for cgocallback().
   114	// By windows/amd64 calling convention first 4 args are in CX, DX, R8, R9
   115	// args from the 5th on are on the stack.
   116	// In any case, even if function has 0,1,2,3,4 args, there is reserved
   117	// but uninitialized "shadow space" for the first 4 args.
   118	// The values are in registers.
   119	MOVQ	CX, (16+0)(SP)
   120	MOVQ	DX, (16+8)(SP)
   121	MOVQ	R8, (16+16)(SP)
   122	MOVQ	R9, (16+24)(SP)
   123	// R8 = address of args vector
   124	LEAQ	(16+0)(SP), R8
   125
   126	// remove return address from stack, we are not returning to callbackasm, but to its caller.
   127	MOVQ	0(SP), AX
   128	ADDQ	$8, SP
   129
   130	// determine index into runtime·cbs table
   131	MOVQ	$runtime·callbackasm(SB), DX
   132	SUBQ	DX, AX
   133	MOVQ	$0, DX
   134	MOVQ	$5, CX	// divide by 5 because each call instruction in runtime·callbacks is 5 bytes long
   135	DIVL	CX
   136	SUBQ	$1, AX	// subtract 1 because return PC is to the next slot
   137
   138	// Switch from the host ABI to the Go ABI.
   139	PUSH_REGS_HOST_TO_ABI0()
   140
   141	// Create a struct callbackArgs on our stack to be passed as
   142	// the "frame" to cgocallback and on to callbackWrap.
   143	SUBQ	$(24+callbackArgs__size), SP
   144	MOVQ	AX, (24+callbackArgs_index)(SP) 	// callback index
   145	MOVQ	R8, (24+callbackArgs_args)(SP)  	// address of args vector
   146	MOVQ	$0, (24+callbackArgs_result)(SP)	// result
   147	LEAQ	24(SP), AX
   148	// Call cgocallback, which will call callbackWrap(frame).
   149	MOVQ	$0, 16(SP)	// context
   150	MOVQ	AX, 8(SP)	// frame (address of callbackArgs)
   151	LEAQ	·callbackWrap<ABIInternal>(SB), BX	// cgocallback takes an ABIInternal entry-point
   152	MOVQ	BX, 0(SP)	// PC of function value to call (callbackWrap)
   153	CALL	·cgocallback(SB)
   154	// Get callback result.
   155	MOVQ	(24+callbackArgs_result)(SP), AX
   156	ADDQ	$(24+callbackArgs__size), SP
   157
   158	POP_REGS_HOST_TO_ABI0()
   159
   160	// The return value was placed in AX above.
   161	RET
   162
   163// uint32 tstart_stdcall(M *newm);
   164TEXT runtime·tstart_stdcall(SB),NOSPLIT|NOFRAME,$0
   165	// Switch from the host ABI to the Go ABI.
   166	PUSH_REGS_HOST_TO_ABI0()
   167
   168	// CX contains first arg newm
   169	MOVQ	m_g0(CX), DX		// g
   170
   171	// Layout new m scheduler stack on os stack.
   172	MOVQ	SP, AX
   173	MOVQ	AX, (g_stack+stack_hi)(DX)
   174	SUBQ	$(64*1024), AX		// initial stack size (adjusted later)
   175	MOVQ	AX, (g_stack+stack_lo)(DX)
   176	ADDQ	$const_stackGuard, AX
   177	MOVQ	AX, g_stackguard0(DX)
   178	MOVQ	AX, g_stackguard1(DX)
   179
   180	// Set up tls.
   181	LEAQ	m_tls(CX), DI
   182	MOVQ	CX, g_m(DX)
   183	MOVQ	DX, g(DI)
   184	CALL	runtime·settls(SB) // clobbers CX
   185
   186	CALL	runtime·stackcheck(SB)	// clobbers AX,CX
   187	CALL	runtime·mstart(SB)
   188
   189	POP_REGS_HOST_TO_ABI0()
   190
   191	XORL	AX, AX			// return 0 == success
   192	RET
   193
   194// set tls base to DI
   195TEXT runtime·settls(SB),NOSPLIT,$0
   196	MOVQ	runtime·tls_g(SB), CX
   197	MOVQ	DI, 0(CX)(GS)
   198	RET
   199
   200TEXT runtime·nanotime1(SB),NOSPLIT,$0-8
   201	MOVQ	$_INTERRUPT_TIME, DI
   202	MOVQ	time_lo(DI), AX
   203	IMULQ	$100, AX
   204	MOVQ	AX, ret+0(FP)
   205	RET
   206
   207// func osSetupTLS(mp *m)
   208// Setup TLS. for use by needm on Windows.
   209TEXT runtime·osSetupTLS(SB),NOSPLIT,$0-8
   210	MOVQ	mp+0(FP), AX
   211	LEAQ	m_tls(AX), DI
   212	CALL	runtime·settls(SB)
   213	RET
   214
   215// This is called from rt0_go, which runs on the system stack
   216// using the initial stack allocated by the OS.
   217TEXT runtime·wintls(SB),NOSPLIT,$0
   218	// Allocate a TLS slot to hold g across calls to external code
   219	MOVQ	SP, AX
   220	ANDQ	$~15, SP	// alignment as per Windows requirement
   221	SUBQ	$48, SP	// room for SP and 4 args as per Windows requirement
   222			// plus one extra word to keep stack 16 bytes aligned
   223	MOVQ	AX, 32(SP)
   224	MOVQ	runtime·_TlsAlloc(SB), AX
   225	CALL	AX
   226	MOVQ	32(SP), SP
   227
   228	MOVQ	AX, CX	// TLS index
   229
   230	// Assert that slot is less than 64 so we can use _TEB->TlsSlots
   231	CMPQ	CX, $64
   232	JB	ok
   233
   234	// Fallback to the TEB arbitrary pointer.
   235	// TODO: don't use the arbitrary pointer (see go.dev/issue/59824)
   236	MOVQ	$TEB_ArbitraryPtr, CX
   237	JMP	settls
   238ok:
   239	// Convert the TLS index at CX into
   240	// an offset from TEB_TlsSlots.
   241	SHLQ	$3, CX
   242
   243	// Save offset from TLS into tls_g.
   244	ADDQ	$TEB_TlsSlots, CX
   245settls:
   246	MOVQ	CX, runtime·tls_g(SB)
   247	RET

View as plain text