diff options
Diffstat (limited to 'src/runtime/sys_windows_amd64.s')
| -rw-r--r-- | src/runtime/sys_windows_amd64.s | 129 |
1 files changed, 29 insertions, 100 deletions
diff --git a/src/runtime/sys_windows_amd64.s b/src/runtime/sys_windows_amd64.s index 777726f7c1..04e649539c 100644 --- a/src/runtime/sys_windows_amd64.s +++ b/src/runtime/sys_windows_amd64.s @@ -107,132 +107,61 @@ TEXT runtime·getlasterror(SB),NOSPLIT,$0 RET // Called by Windows as a Vectored Exception Handler (VEH). -// First argument is pointer to struct containing +// CX is pointer to struct containing // exception record and context pointers. -// Handler function is stored in AX. -// Return 0 for 'not handled', -1 for handled. +// DX is the kind of sigtramp function. +// Return value of sigtrampgo is stored in AX. TEXT sigtramp<>(SB),NOSPLIT|NOFRAME,$0-0 - // CX: PEXCEPTION_POINTERS ExceptionInfo - // Switch from the host ABI to the Go ABI. PUSH_REGS_HOST_TO_ABI0() - // Make stack space for the rest of the function. - ADJSP $48 - - MOVQ CX, R13 // save exception address - MOVQ AX, R15 // save handler address - - // find g - get_tls(DX) - CMPQ DX, $0 - JNE 3(PC) - MOVQ $0, AX // continue - JMP done - MOVQ g(DX), DX - CMPQ DX, $0 - JNE 2(PC) - CALL runtime·badsignal2(SB) - - // save g and SP in case of stack switch - MOVQ DX, 32(SP) // g - MOVQ SP, 40(SP) - - // do we need to switch to the g0 stack? - MOVQ g_m(DX), BX - MOVQ m_g0(BX), BX - CMPQ DX, BX - JEQ g0 - - // switch to g0 stack - get_tls(BP) - MOVQ BX, g(BP) - MOVQ (g_sched+gobuf_sp)(BX), DI - // make room for sighandler arguments - // and re-save old SP for restoring later. - // Adjust g0 stack by the space we're using and - // save SP at the same place on the g0 stack. - // The 40(DI) here must match the 40(SP) above. - SUBQ $(REGS_HOST_TO_ABI0_STACK + 48), DI - MOVQ SP, 40(DI) - MOVQ DI, SP -g0: - MOVQ 0(R13), BX // ExceptionRecord* - MOVQ 8(R13), CX // Context* - MOVQ BX, 0(SP) - MOVQ CX, 8(SP) - MOVQ DX, 16(SP) - CALL R15 // call handler - // AX is set to report result back to Windows - MOVL 24(SP), AX + // Set up ABIInternal environment: cleared X15 and R14. + // R14 is cleared in case there's a non-zero value in there + // if called from a non-go thread. + XORPS X15, X15 + XORQ R14, R14 - MOVQ SP, DI // save g0 SP - - // switch back to original stack and g - // no-op if we never left. - MOVQ 40(SP), SP - MOVQ 32(SP), DX - get_tls(BP) - MOVQ DX, g(BP) - - // if return value is CONTINUE_SEARCH, do not set up control - // flow guard workaround. + get_tls(AX) CMPQ AX, $0 - JEQ done + JE 2(PC) + // Exception from Go thread, set R14. + MOVQ g(AX), R14 - // Check if we need to set up the control flow guard workaround. - // On Windows, the stack pointer in the context must lie within - // system stack limits when we resume from exception. - // Store the resume SP and PC in alternate registers - // and return to sigresume on the g0 stack. - // sigresume makes no use of the stack at all, - // loading SP from R8 and jumping to R9. - // Note that smashing R8 and R9 is only safe because we know sigpanic - // will not actually return to the original frame, so the registers - // are effectively dead. But this does mean we can't use the - // same mechanism for async preemption. - MOVQ 8(R13), CX - MOVQ $sigresume<>(SB), BX - CMPQ BX, context_rip(CX) - JEQ done // do not clobber saved SP/PC + // Reserve space for spill slots. + ADJSP $16 + MOVQ CX, AX + MOVQ DX, BX + // Calling ABIInternal because TLS might be nil. + CALL runtime·sigtrampgo<ABIInternal>(SB) + // Return value is already stored in AX. - // Save resume SP and PC into R8, R9. - MOVQ context_rsp(CX), BX - MOVQ BX, context_r8(CX) - MOVQ context_rip(CX), BX - MOVQ BX, context_r9(CX) + ADJSP $-16 - // Set up context record to return to sigresume on g0 stack - MOVD DI, BX - MOVD BX, context_rsp(CX) - MOVD $sigresume<>(SB), BX - MOVD BX, context_rip(CX) - -done: - ADJSP $-48 POP_REGS_HOST_TO_ABI0() - RET // Trampoline to resume execution from exception handler. // This is part of the control flow guard workaround. // It switches stacks and jumps to the continuation address. -// R8 and R9 are set above at the end of sigtramp<> -// in the context that starts executing at sigresume<>. -TEXT sigresume<>(SB),NOSPLIT|NOFRAME,$0 +// R8 and R9 are set above at the end of sigtrampgo +// in the context that starts executing at sigresume. +TEXT runtime·sigresume(SB),NOSPLIT|NOFRAME,$0 MOVQ R8, SP JMP R9 TEXT runtime·exceptiontramp(SB),NOSPLIT|NOFRAME,$0 - MOVQ $runtime·exceptionhandler(SB), AX + // PExceptionPointers already on CX + MOVQ $const_callbackVEH, DX JMP sigtramp<>(SB) TEXT runtime·firstcontinuetramp(SB),NOSPLIT|NOFRAME,$0-0 - MOVQ $runtime·firstcontinuehandler(SB), AX + // PExceptionPointers already on CX + MOVQ $const_callbackFirstVCH, DX JMP sigtramp<>(SB) TEXT runtime·lastcontinuetramp(SB),NOSPLIT|NOFRAME,$0-0 - MOVQ $runtime·lastcontinuehandler(SB), AX + // PExceptionPointers already on CX + MOVQ $const_callbackLastVCH, DX JMP sigtramp<>(SB) GLOBL runtime·cbctxts(SB), NOPTR, $8 |
