src/runtime/sys_windows_amd64.s 255 lines View on github.com → Search inside
1// Copyright 2011 The Go Authors. All rights reserved.2// Use of this source code is governed by a BSD-style3// license that can be found in the LICENSE file.45#include "go_asm.h"6#include "go_tls.h"7#include "textflag.h"8#include "time_windows.h"9#include "cgo/abi_amd64.h"1011// Offsets into Thread Environment Block (pointer in GS)12#define TEB_TlsSlots 0x148013#define TEB_ArbitraryPtr 0x281415// faster get/set last error16TEXT runtime·getlasterror(SB),NOSPLIT,$017	MOVQ	0x30(GS), AX18	MOVL	0x68(AX), AX19	MOVL	AX, ret+0(FP)20	RET2122// Called by Windows as a Vectored Exception Handler (VEH).23// CX is pointer to struct containing24// 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-028	// Switch from the host ABI to the Go ABI.29	PUSH_REGS_HOST_TO_ABI0()3031	// Set up ABIInternal environment: cleared X15 and R14.32	// R14 is cleared in case there's a non-zero value in there33	// if called from a non-go thread.34	XORPS	X15, X1535#ifndef GOAMD64_v336#ifndef GOAMD64_v437	CMPB	internalcpu·X86+const_offsetX86HasAVX(SB), $138	JNE	2(PC)39#endif40#endif41	VXORPS	X15, X15, X1542	XORQ	R14, R144344	get_tls(AX)45	CMPQ	AX, $046	JE	2(PC)47	// Exception from Go thread, set R14.48	MOVQ	g(AX), R144950	// Reserve space for spill slots.51	ADJSP	$1652	MOVQ	CX, AX53	MOVQ	DX, BX54	// Calling ABIInternal because TLS might be nil.55	CALL	runtime·sigtrampgo<ABIInternal>(SB)56	// Return value is already stored in AX.5758	ADJSP	$-165960	POP_REGS_HOST_TO_ABI0()61	RET6263// Trampoline to resume execution from exception handler.64// This is part of the control flow guard workaround.65// It switches stacks and jumps to the continuation address.66// R8 and R9 are set above at the end of sigtrampgo67// in the context that starts executing at sigresume.68TEXT runtime·sigresume(SB),NOSPLIT|NOFRAME,$069	MOVQ	R8, SP70	JMP	R97172TEXT runtime·exceptiontramp(SB),NOSPLIT|NOFRAME,$073	// PExceptionPointers already on CX74	MOVQ	$const_callbackVEH, DX75	JMP	sigtramp<>(SB)7677TEXT runtime·firstcontinuetramp(SB),NOSPLIT|NOFRAME,$0-078	// PExceptionPointers already on CX79	MOVQ	$const_callbackFirstVCH, DX80	JMP	sigtramp<>(SB)8182TEXT runtime·lastcontinuetramp(SB),NOSPLIT|NOFRAME,$0-083	// PExceptionPointers already on CX84	MOVQ	$const_callbackLastVCH, DX85	JMP	sigtramp<>(SB)8687TEXT runtime·sehtramp(SB),NOSPLIT,$40-088	// CX: PEXCEPTION_RECORD ExceptionRecord89	// DX: ULONG64 EstablisherFrame90	// R8: PCONTEXT ContextRecord91	// R9: PDISPATCHER_CONTEXT DispatcherContext92	// Switch from the host ABI to the Go ABI.93	PUSH_REGS_HOST_TO_ABI0()9495	get_tls(AX)96	CMPQ	AX, $097	JNE	2(PC)98	// This shouldn't happen, sehtramp is only attached to functions99	// called from Go, and exception handlers are only called from100	// the thread that threw the exception.101	INT	$3102103	// Exception from Go thread, set R14.104	MOVQ	g(AX), R14105106	ADJSP	$40107	MOVQ	CX, 0(SP)108	MOVQ	DX, 8(SP)109	MOVQ	R8, 16(SP)110	MOVQ	R9, 24(SP)111	CALL	runtime·sehhandler(SB)112	MOVL	32(SP), AX113114	ADJSP	$-40115116	POP_REGS_HOST_TO_ABI0()117	RET118119TEXT runtime·callbackasm1(SB),NOSPLIT|NOFRAME,$0120	// Construct args vector for cgocallback().121	// By windows/amd64 calling convention first 4 args are in CX, DX, R8, R9122	// args from the 5th on are on the stack.123	// In any case, even if function has 0,1,2,3,4 args, there is reserved124	// but uninitialized "shadow space" for the first 4 args.125	// The values are in registers.126	MOVQ	CX, (16+0)(SP)127	MOVQ	DX, (16+8)(SP)128	MOVQ	R8, (16+16)(SP)129	MOVQ	R9, (16+24)(SP)130	// R8 = address of args vector131	LEAQ	(16+0)(SP), R8132133	// remove return address from stack, we are not returning to callbackasm, but to its caller.134	MOVQ	0(SP), AX135	ADDQ	$8, SP136137	// determine index into runtime·cbs table138	MOVQ	$runtime·callbackasm(SB), DX139	SUBQ	DX, AX140	MOVQ	$0, DX141	MOVQ	$5, CX	// divide by 5 because each call instruction in runtime·callbacks is 5 bytes long142	DIVL	CX143	SUBQ	$1, AX	// subtract 1 because return PC is to the next slot144145	// Switch from the host ABI to the Go ABI.146	PUSH_REGS_HOST_TO_ABI0()147148	// Create a struct callbackArgs on our stack to be passed as149	// the "frame" to cgocallback and on to callbackWrap.150	SUBQ	$(24+callbackArgs__size), SP151	MOVQ	AX, (24+callbackArgs_index)(SP) 	// callback index152	MOVQ	R8, (24+callbackArgs_args)(SP)  	// address of args vector153	MOVQ	$0, (24+callbackArgs_result)(SP)	// result154	LEAQ	24(SP), AX155	// Call cgocallback, which will call callbackWrap(frame).156	MOVQ	$0, 16(SP)	// context157	MOVQ	AX, 8(SP)	// frame (address of callbackArgs)158	LEAQ	·callbackWrap<ABIInternal>(SB), BX	// cgocallback takes an ABIInternal entry-point159	MOVQ	BX, 0(SP)	// PC of function value to call (callbackWrap)160	CALL	·cgocallback(SB)161	// Get callback result.162	MOVQ	(24+callbackArgs_result)(SP), AX163	ADDQ	$(24+callbackArgs__size), SP164165	POP_REGS_HOST_TO_ABI0()166167	// The return value was placed in AX above.168	RET169170// uint32 tstart_stdcall(M *newm);171TEXT runtime·tstart_stdcall(SB),NOSPLIT|NOFRAME,$0172	// Switch from the host ABI to the Go ABI.173	PUSH_REGS_HOST_TO_ABI0()174175	// CX contains first arg newm176	MOVQ	m_g0(CX), DX		// g177178	// Layout new m scheduler stack on os stack.179	MOVQ	SP, AX180	MOVQ	AX, (g_stack+stack_hi)(DX)181	SUBQ	$(64*1024), AX		// initial stack size (adjusted later)182	MOVQ	AX, (g_stack+stack_lo)(DX)183	ADDQ	$const_stackGuard, AX184	MOVQ	AX, g_stackguard0(DX)185	MOVQ	AX, g_stackguard1(DX)186187	// Set up tls.188	LEAQ	m_tls(CX), DI189	MOVQ	CX, g_m(DX)190	MOVQ	DX, g(DI)191	CALL	runtime·settls(SB) // clobbers CX192193	CALL	runtime·stackcheck(SB)	// clobbers AX,CX194	CALL	runtime·mstart(SB)195196	POP_REGS_HOST_TO_ABI0()197198	XORL	AX, AX			// return 0 == success199	RET200201// set tls base to DI202TEXT runtime·settls(SB),NOSPLIT,$0203	MOVQ	runtime·tls_g(SB), CX204	MOVQ	DI, 0(CX)(GS)205	RET206207TEXT runtime·nanotime1(SB),NOSPLIT,$0-8208	MOVQ	$_INTERRUPT_TIME, DI209	MOVQ	time_lo(DI), AX210	IMULQ	$100, AX211	MOVQ	AX, ret+0(FP)212	RET213214// func osSetupTLS(mp *m)215// Setup TLS. for use by needm on Windows.216TEXT runtime·osSetupTLS(SB),NOSPLIT,$0-8217	MOVQ	mp+0(FP), AX218	LEAQ	m_tls(AX), DI219	CALL	runtime·settls(SB)220	RET221222// This is called from rt0_go, which runs on the system stack223// using the initial stack allocated by the OS.224TEXT runtime·wintls(SB),NOSPLIT,$0225	// Allocate a TLS slot to hold g across calls to external code226	MOVQ	SP, AX227	ANDQ	$~15, SP	// alignment as per Windows requirement228	SUBQ	$48, SP	// room for SP and 4 args as per Windows requirement229			// plus one extra word to keep stack 16 bytes aligned230	MOVQ	AX, 32(SP)231	MOVQ	runtime·_TlsAlloc(SB), AX232	CALL	AX233	MOVQ	32(SP), SP234235	MOVQ	AX, CX	// TLS index236237	// Assert that slot is less than 64 so we can use _TEB->TlsSlots238	CMPQ	CX, $64239	JB	ok240241	// Fallback to the TEB arbitrary pointer.242	// TODO: don't use the arbitrary pointer (see go.dev/issue/59824)243	MOVQ	$TEB_ArbitraryPtr, CX244	JMP	settls245ok:246	// Convert the TLS index at CX into247	// an offset from TEB_TlsSlots.248	SHLQ	$3, CX249250	// Save offset from TLS into tls_g.251	ADDQ	$TEB_TlsSlots, CX252settls:253	MOVQ	CX, runtime·tls_g(SB)254	RET

Findings

✓ No findings reported for this file.

Get this view in your editor

Same data, no extra tab — call code_get_file + code_get_findings over MCP from Claude/Cursor/Copilot.