diff --git a/src/pkg/runtime/sys_windows_386.s b/src/pkg/runtime/sys_windows_386.s index 5290f60934..c62715dbd7 100644 --- a/src/pkg/runtime/sys_windows_386.s +++ b/src/pkg/runtime/sys_windows_386.s @@ -38,6 +38,46 @@ TEXT runtime·asmstdcall(SB),7,$0 RET +TEXT runtime·write(SB),7,$24 + // write only writes to stderr; ignore fd + MOVL $-12, 0(SP) + MOVL SP, BP + CALL *runtime·GetStdHandle(SB) + MOVL BP, SP + + MOVL AX, 0(SP) // handle + MOVL buf+4(FP), DX // pointer + MOVL DX, 4(SP) + MOVL count+8(FP), DX // count + MOVL DX, 8(SP) + LEAL 20(SP), DX // written count + MOVL $0, 0(DX) + MOVL DX, 12(SP) + MOVL $0, 16(SP) // overlapped + CALL *runtime·WriteFile(SB) + MOVL BP, SI + RET + +TEXT runtime·badcallback(SB),7,$24 + // write only writes to stderr; ignore fd + MOVL $-12, 0(SP) + MOVL SP, BP + CALL *runtime·GetStdHandle(SB) + MOVL BP, SP + + MOVL AX, 0(SP) // handle + MOVL $runtime·badcallbackmsg(SB), DX // pointer + MOVL DX, 4(SP) + MOVL runtime·badcallbacklen(SB), DX // count + MOVL DX, 8(SP) + LEAL 20(SP), DX // written count + MOVL $0, 0(DX) + MOVL DX, 12(SP) + MOVL $0, 16(SP) // overlapped + CALL *runtime·WriteFile(SB) + MOVL BP, SI + RET + // faster get/set last error TEXT runtime·getlasterror(SB),7,$0 MOVL 0x34(FS), AX diff --git a/src/pkg/runtime/sys_windows_amd64.s b/src/pkg/runtime/sys_windows_amd64.s index fa8d4221e2..73dc542aac 100644 --- a/src/pkg/runtime/sys_windows_amd64.s +++ b/src/pkg/runtime/sys_windows_amd64.s @@ -60,6 +60,49 @@ loadregs: RET +TEXT runtime·write(SB),7,$48 + // write only ever writes to stderr; ignore fd + MOVQ $-12, CX // stderr + MOVQ CX, 0(SP) + MOVQ runtime·GetStdHandle(SB), AX + CALL AX + + MOVQ AX, CX // handle + MOVQ CX, 0(SP) + MOVQ buf+8(FP), DX // pointer + MOVQ DX, 8(SP) + MOVL count+16(FP), R8 // count + MOVQ R8, 16(SP) + LEAQ 40(SP), R9 // written count + MOVQ $0, 0(R9) + MOVQ R9, 24(SP) + MOVQ $0, 32(SP) // overlapped + MOVQ runtime·WriteFile(SB), AX + CALL AX + + RET + +TEXT runtime·badcallback(SB),7,$48 + MOVQ $-12, CX // stderr + MOVQ CX, 0(SP) + MOVQ runtime·GetStdHandle(SB), AX + CALL AX + + MOVQ AX, CX // handle + MOVQ CX, 0(SP) + MOVQ $runtime·badcallbackmsg(SB), DX // pointer + MOVQ DX, 8(SP) + MOVL $runtime·badcallbacklen(SB), R8 // count + MOVQ R8, 16(SP) + LEAQ 40(SP), R9 // written count + MOVQ $0, 0(R9) + MOVQ R9, 24(SP) + MOVQ $0, 32(SP) // overlapped + MOVQ runtime·WriteFile(SB), AX + CALL AX + + RET + // faster get/set last error TEXT runtime·getlasterror(SB),7,$0 MOVQ 0x30(GS), AX @@ -207,15 +250,18 @@ TEXT runtime·callbackasm(SB),7,$0 MOVQ R14, 8(SP) MOVQ R15, 0(SP) + // prepare call stack. use SUBQ to hide from stack frame checks // cgocallback(void (*fn)(void*), void *frame, uintptr framesize) - PUSHQ DX // uintptr framesize - PUSHQ CX // void *frame - PUSHQ AX // void (*fn)(void*) + SUBQ $24, SP + MOVQ DX, 16(SP) // uintptr framesize + MOVQ CX, 8(SP) // void *frame + MOVQ AX, 0(SP) // void (*fn)(void*) CLD CALL runtime·cgocallback(SB) - POPQ AX - POPQ CX - POPQ DX + MOVQ 0(SP), AX + MOVQ 8(SP), CX + MOVQ 16(SP), DX + ADDQ $24, SP // restore registers as required for windows callback // 6l does not allow writing many POPs here issuing a warning "nosplit stack overflow" diff --git a/src/pkg/runtime/thread_windows.c b/src/pkg/runtime/thread_windows.c index e75e0c1569..49beba5dc1 100644 --- a/src/pkg/runtime/thread_windows.c +++ b/src/pkg/runtime/thread_windows.c @@ -114,27 +114,6 @@ runtime·exit(int32 code) runtime·stdcall(runtime·ExitProcess, 1, (uintptr)code); } -int32 -runtime·write(int32 fd, void *buf, int32 n) -{ - void *handle; - uint32 written; - - written = 0; - switch(fd) { - case 1: - handle = runtime·stdcall(runtime·GetStdHandle, 1, (uintptr)-11); - break; - case 2: - handle = runtime·stdcall(runtime·GetStdHandle, 1, (uintptr)-12); - break; - default: - return -1; - } - runtime·stdcall(runtime·WriteFile, 5, handle, buf, (uintptr)n, &written, (uintptr)0); - return written; -} - void runtime·osyield(void) { @@ -423,21 +402,5 @@ runtime·setprof(bool on) USED(on); } -static int8 badcallback[] = "runtime: cgo callback on thread not created by Go.\n"; - -// This runs on a foreign stack, without an m or a g. No stack split. -#pragma textflag 7 -void -runtime·badcallback(void) -{ - uint32 written; - - runtime·stdcall( - runtime·WriteFile, 5, - runtime·stdcall(runtime·GetStdHandle, 1, (uintptr)-12), // stderr - badcallback, - (uintptr)(sizeof badcallback - 1), - &written, - nil - ); -} +int8 runtime·badcallbackmsg[] = "runtime: cgo callback on thread not created by Go.\n"; +int32 runtime·badcallbacklen = sizeof runtime·badcallbackmsg - 1;