diff options
| author | qmuntal <quimmuntal@gmail.com> | 2022-12-16 16:54:03 +0100 |
|---|---|---|
| committer | Quim Muntal <quimmuntal@gmail.com> | 2023-01-24 12:05:07 +0000 |
| commit | cf9263dee1bb160f013a080bbda3532a7d35da15 (patch) | |
| tree | c6743f75c942150fb1685ec1da9f6e874762eae3 /src/runtime/sys_windows_arm.s | |
| parent | e39c7a37f0f1a992eb65202d05c3148524c5c0ef (diff) | |
| download | go-cf9263dee1bb160f013a080bbda3532a7d35da15.tar.xz | |
runtime: factor out windows sigtramp
This CL factors out part of the Windows sigtramp implementation, which
was duplicated in all four architectures. The new common code is
implemented in Go rather than in assembly, which will make Windows
error handling easier to reason and maintain.
While here, implement the control flow guard workaround on
windows/386, which almost comes for free.
Change-Id: I0bf38c28c54793225126e161bd95527a62de05e0
Reviewed-on: https://go-review.googlesource.com/c/go/+/458135
Run-TryBot: Quim Muntal <quimmuntal@gmail.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Bryan Mills <bcmills@google.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
Diffstat (limited to 'src/runtime/sys_windows_arm.s')
| -rw-r--r-- | src/runtime/sys_windows_arm.s | 121 |
1 files changed, 18 insertions, 103 deletions
diff --git a/src/runtime/sys_windows_arm.s b/src/runtime/sys_windows_arm.s index db6d8f1a08..a00fd16670 100644 --- a/src/runtime/sys_windows_arm.s +++ b/src/runtime/sys_windows_arm.s @@ -107,121 +107,36 @@ TEXT runtime·getlasterror(SB),NOSPLIT,$0 RET // Called by Windows as a Vectored Exception Handler (VEH). -// First argument is pointer to struct containing +// R0 is pointer to struct containing // exception record and context pointers. -// Handler function is stored in R1 -// Return 0 for 'not handled', -1 for handled. -// int32_t sigtramp( -// PEXCEPTION_POINTERS ExceptionInfo, -// func *GoExceptionHandler); +// R1 is the kind of sigtramp function. +// Return value of sigtrampgo is stored in R0. TEXT sigtramp<>(SB),NOSPLIT|NOFRAME,$0 - MOVM.DB.W [R0, R4-R11, R14], (R13) // push {r0, r4-r11, lr} (SP-=40) - SUB $(8+20), R13 // reserve space for g, sp, and - // parameters/retval to go call + MOVM.DB.W [R4-R11, R14], (R13) // push {r4-r11, lr} (SP-=40) + SUB $(16), R13 // reserve space for parameters/retval to go call MOVW R0, R6 // Save param0 MOVW R1, R7 // Save param1 - - BL runtime·load_g(SB) - CMP $0, g // is there a current g? - BNE g_ok - ADD $(8+20), R13 // free locals - MOVM.IA.W (R13), [R3, R4-R11, R14] // pop {r3, r4-r11, lr} - MOVW $0, R0 // continue - BEQ return - -g_ok: - - // save g and SP in case of stack switch - MOVW R13, 24(R13) - MOVW g, 20(R13) - - // do we need to switch to the g0 stack? - MOVW g, R5 // R5 = g - MOVW g_m(R5), R2 // R2 = m - MOVW m_g0(R2), R4 // R4 = g0 - CMP R5, R4 // if curg == g0 - BEQ g0 - - // switch to g0 stack - MOVW R4, g // g = g0 - MOVW (g_sched+gobuf_sp)(g), R3 // R3 = g->gobuf.sp - BL runtime·save_g(SB) - - // make room for sighandler arguments - // and re-save old SP for restoring later. - // (note that the 24(R3) here must match the 24(R13) above.) - SUB $40, R3 - MOVW R13, 24(R3) // save old stack pointer - MOVW R3, R13 // switch stack - -g0: - MOVW 0(R6), R2 // R2 = ExceptionPointers->ExceptionRecord - MOVW 4(R6), R3 // R3 = ExceptionPointers->ContextRecord + BL runtime·load_g(SB) // Clobbers R0 MOVW $0, R4 MOVW R4, 0(R13) // No saved link register. - MOVW R2, 4(R13) // Move arg0 (ExceptionRecord) into position - MOVW R3, 8(R13) // Move arg1 (ContextRecord) into position - MOVW R5, 12(R13) // Move arg2 (original g) into position - BL (R7) // Call the goroutine - MOVW 16(R13), R4 // Fetch return value from stack - - // Save system stack pointer for sigresume setup below. - // The exact value does not matter - nothing is read or written - // from this address. It just needs to be on the system stack. - MOVW R13, R12 - - // switch back to original stack and g - MOVW 24(R13), R13 - MOVW 20(R13), g - BL runtime·save_g(SB) - -done: - MOVW R4, R0 // move retval into position - ADD $(8 + 20), R13 // free locals - MOVM.IA.W (R13), [R3, R4-R11, R14] // pop {r3, r4-r11, lr} - - // if return value is CONTINUE_SEARCH, do not set up control - // flow guard workaround - CMP $0, R0 - BEQ return - - // 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 on the g0 stack, - // and return to sigresume on the g0 stack. sigresume - // pops the saved PC and SP from the g0 stack, resuming execution - // at the desired location. - // If sigresume has already been set up by a previous exception - // handler, don't clobber the stored SP and PC on the stack. - MOVW 4(R3), R3 // PEXCEPTION_POINTERS->Context - MOVW context_pc(R3), R2 // load PC from context record - MOVW $sigresume<>(SB), R1 - CMP R1, R2 - B.EQ return // do not clobber saved SP/PC - - // Save resume SP and PC into R0, R1. - MOVW context_spr(R3), R2 - MOVW R2, context_r0(R3) - MOVW context_pc(R3), R2 - MOVW R2, context_r1(R3) + MOVW R6, 4(R13) // Move arg0 into position + MOVW R7, 8(R13) // Move arg1 into position + BL runtime·sigtrampgo(SB) + MOVW 12(R13), R0 // Fetch return value from stack - // Set up context record to return to sigresume on g0 stack - MOVW R12, context_spr(R3) - MOVW $sigresume<>(SB), R2 - MOVW R2, context_pc(R3) + ADD $(16), R13 // free locals + MOVM.IA.W (R13), [R4-R11, R14] // pop {r4-r11, lr} -return: B (R14) // return // 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. -// R0 and R1 are set above at the end of sigtramp<> -// in the context that starts executing at sigresume<>. -TEXT sigresume<>(SB),NOSPLIT|NOFRAME,$0 +// R0 and R1 are set above at the end of sigtrampgo +// in the context that starts executing at sigresume. +TEXT runtime·sigresume(SB),NOSPLIT|NOFRAME,$0 // Important: do not smash LR, // which is set to a live value when handling // a signal by pushing a call to sigpanic onto the stack. @@ -229,15 +144,15 @@ TEXT sigresume<>(SB),NOSPLIT|NOFRAME,$0 B (R1) TEXT runtime·exceptiontramp(SB),NOSPLIT|NOFRAME,$0 - MOVW $runtime·exceptionhandler(SB), R1 + MOVW $const_callbackVEH, R1 B sigtramp<>(SB) TEXT runtime·firstcontinuetramp(SB),NOSPLIT|NOFRAME,$0 - MOVW $runtime·firstcontinuehandler(SB), R1 + MOVW $const_callbackFirstVCH, R1 B sigtramp<>(SB) TEXT runtime·lastcontinuetramp(SB),NOSPLIT|NOFRAME,$0 - MOVW $runtime·lastcontinuehandler(SB), R1 + MOVW $const_callbackLastVCH, R1 B sigtramp<>(SB) GLOBL runtime·cbctxts(SB), NOPTR, $4 |
