aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/sys_windows_386.s
diff options
context:
space:
mode:
Diffstat (limited to 'src/runtime/sys_windows_386.s')
-rw-r--r--src/runtime/sys_windows_386.s83
1 files changed, 27 insertions, 56 deletions
diff --git a/src/runtime/sys_windows_386.s b/src/runtime/sys_windows_386.s
index 8713f7d0d9..0983cc7b1f 100644
--- a/src/runtime/sys_windows_386.s
+++ b/src/runtime/sys_windows_386.s
@@ -72,13 +72,20 @@ TEXT runtime·getlasterror(SB),NOSPLIT,$0
MOVL AX, ret+0(FP)
RET
+TEXT runtime·sigFetchGSafe<ABIInternal>(SB),NOSPLIT|NOFRAME,$0
+ get_tls(AX)
+ CMPL AX, $0
+ JE 2(PC)
+ MOVL g(AX), AX
+ MOVL AX, ret+0(FP)
+ RET
+
// Called by Windows as a Vectored Exception Handler (VEH).
-// First argument is pointer to struct containing
+// AX is pointer to struct containing
// exception record and context pointers.
-// Handler function is stored in AX.
-// Return 0 for 'not handled', -1 for handled.
+// CX is the kind of sigtramp function.
+// Return value of sigtrampgo is stored in AX.
TEXT sigtramp<>(SB),NOSPLIT,$0-0
- MOVL ptrs+0(FP), CX
SUBL $40, SP
// save callee-saved registers
@@ -87,58 +94,11 @@ TEXT sigtramp<>(SB),NOSPLIT,$0-0
MOVL SI, 20(SP)
MOVL DI, 24(SP)
- MOVL AX, SI // save handler address
-
- // find g
- get_tls(DX)
- CMPL DX, $0
- JNE 3(PC)
- MOVL $0, AX // continue
- JMP done
- MOVL g(DX), DX
- CMPL DX, $0
- JNE 2(PC)
- CALL runtime·badsignal2(SB)
-
- // save g in case of stack switch
- MOVL DX, 32(SP) // g
- MOVL SP, 36(SP)
-
- // do we need to switch to the g0 stack?
- MOVL g_m(DX), BX
- MOVL m_g0(BX), BX
- CMPL DX, BX
- JEQ g0
-
- // switch to the g0 stack
- get_tls(BP)
- MOVL BX, g(BP)
- MOVL (g_sched+gobuf_sp)(BX), DI
- // make room for sighandler arguments
- // and re-save old SP for restoring later.
- // (note that the 36(DI) here must match the 36(SP) above.)
- SUBL $40, DI
- MOVL SP, 36(DI)
- MOVL DI, SP
-
-g0:
- MOVL 0(CX), BX // ExceptionRecord*
- MOVL 4(CX), CX // Context*
- MOVL BX, 0(SP)
+ MOVL AX, 0(SP)
MOVL CX, 4(SP)
- MOVL DX, 8(SP)
- CALL SI // call handler
- // AX is set to report result back to Windows
- MOVL 12(SP), AX
+ CALL runtime·sigtrampgo(SB)
+ MOVL 8(SP), AX
- // switch back to original stack and g
- // no-op if we never left.
- MOVL 36(SP), SP
- MOVL 32(SP), DX // note: different SP
- get_tls(BP)
- MOVL DX, g(BP)
-
-done:
// restore callee-saved registers
MOVL 24(SP), DI
MOVL 20(SP), SI
@@ -150,8 +110,18 @@ done:
BYTE $0xC2; WORD $4
RET // unreached; make assembler happy
+// 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.
+// DX and CX are set above at the end of sigtrampgo
+// in the context that starts executing at sigresume.
+TEXT runtime·sigresume(SB),NOSPLIT|NOFRAME,$0
+ MOVL DX, SP
+ JMP CX
+
TEXT runtime·exceptiontramp(SB),NOSPLIT,$0
- MOVL $runtime·exceptionhandler(SB), AX
+ MOVL argframe+0(FP), AX
+ MOVL $const_callbackVEH, CX
JMP sigtramp<>(SB)
TEXT runtime·firstcontinuetramp(SB),NOSPLIT,$0-0
@@ -159,7 +129,8 @@ TEXT runtime·firstcontinuetramp(SB),NOSPLIT,$0-0
INT $3
TEXT runtime·lastcontinuetramp(SB),NOSPLIT,$0-0
- MOVL $runtime·lastcontinuehandler(SB), AX
+ MOVL argframe+0(FP), AX
+ MOVL $const_callbackLastVCH, CX
JMP sigtramp<>(SB)
GLOBL runtime·cbctxts(SB), NOPTR, $4