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 internal∕cpu·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.