diff --git a/src/runtime/asm_386.s b/src/runtime/asm_386.s index 062a668e3e..37ad092414 100644 --- a/src/runtime/asm_386.s +++ b/src/runtime/asm_386.s @@ -684,15 +684,19 @@ TEXT asmcgocall<>(SB),NOSPLIT,$0-12 SUBL $32, SP ANDL $~15, SP // alignment, perhaps unnecessary MOVL DI, 8(SP) // save g - MOVL DX, 4(SP) // save SP + MOVL (g_stack+stack_hi)(DI), DI + SUBL DX, DI + MOVL DI, 4(SP) // save depth in stack (can't just save SP, as stack might be copied during a callback) MOVL BX, 0(SP) // first argument in x86-32 ABI CALL AX // Restore registers, g, stack pointer. get_tls(CX) MOVL 8(SP), DI + MOVL (g_stack+stack_hi)(DI), SI + SUBL 4(SP), SI MOVL DI, g(CX) - MOVL 4(SP), SP + MOVL SI, SP RET // cgocallback(void (*fn)(void*), void *frame, uintptr framesize) diff --git a/src/runtime/asm_amd64.s b/src/runtime/asm_amd64.s index bf0f490ae3..241d5feebf 100644 --- a/src/runtime/asm_amd64.s +++ b/src/runtime/asm_amd64.s @@ -670,7 +670,9 @@ nosave: SUBQ $64, SP ANDQ $~15, SP // alignment for gcc ABI MOVQ DI, 48(SP) // save g - MOVQ DX, 40(SP) // save SP + MOVQ (g_stack+stack_hi)(DI), DI + SUBQ DX, DI + MOVQ DI, 40(SP) // save depth in stack (can't just save SP, as stack might be copied during a callback) MOVQ BX, DI // DI = first argument in AMD64 ABI MOVQ BX, CX // CX = first argument in Win64 CALL AX @@ -678,8 +680,10 @@ nosave: // Restore registers, g, stack pointer. get_tls(CX) MOVQ 48(SP), DI + MOVQ (g_stack+stack_hi)(DI), SI + SUBQ 40(SP), SI MOVQ DI, g(CX) - MOVQ 40(SP), SP + MOVQ SI, SP RET // cgocallback(void (*fn)(void*), void *frame, uintptr framesize) diff --git a/src/runtime/asm_arm.s b/src/runtime/asm_arm.s index bddffc9e77..a4524f919b 100644 --- a/src/runtime/asm_arm.s +++ b/src/runtime/asm_arm.s @@ -520,15 +520,20 @@ asmcgocall_g0: SUB $24, R13 BIC $0x7, R13 // alignment for gcc ABI MOVW R4, 20(R13) // save old g - MOVW R2, 16(R13) // save old SP + MOVW (g_stack+stack_hi)(R4), R4 + SUB R2, R4 + MOVW R4, 16(R13) // save depth in stack (can't just save SP, as stack might be copied during a callback) BL (R1) // Restore registers, g, stack pointer. MOVW R0, R5 MOVW 20(R13), R0 BL setg<>(SB) + MOVW (g_stack+stack_hi)(g), R1 + MOVW 16(R13), R2 + SUB R2, R1 MOVW R5, R0 - MOVW 16(R13), R13 + MOVW R1, R13 RET // cgocallback(void (*fn)(void*), void *frame, uintptr framesize)