summaryrefslogtreecommitdiff
path: root/src/pkg/runtime/windows
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/runtime/windows')
-rw-r--r--src/pkg/runtime/windows/386/defs.h3
-rw-r--r--src/pkg/runtime/windows/386/signal.c7
-rw-r--r--src/pkg/runtime/windows/386/sys.s47
-rw-r--r--src/pkg/runtime/windows/defs.c6
-rw-r--r--src/pkg/runtime/windows/mem.c9
-rw-r--r--src/pkg/runtime/windows/os.h1
-rw-r--r--src/pkg/runtime/windows/thread.c47
7 files changed, 111 insertions, 9 deletions
diff --git a/src/pkg/runtime/windows/386/defs.h b/src/pkg/runtime/windows/386/defs.h
index a2a882103..49fc19504 100644
--- a/src/pkg/runtime/windows/386/defs.h
+++ b/src/pkg/runtime/windows/386/defs.h
@@ -10,6 +10,9 @@ enum {
PROT_EXEC = 0x4,
MAP_ANON = 0x1,
MAP_PRIVATE = 0x2,
+ SIGINT = 0x2,
+ CTRL_C_EVENT = 0,
+ CTRL_BREAK_EVENT = 0x1,
EXCEPTION_ACCESS_VIOLATION = 0xc0000005,
EXCEPTION_BREAKPOINT = 0x80000003,
EXCEPTION_FLT_DENORMAL_OPERAND = 0xc000008d,
diff --git a/src/pkg/runtime/windows/386/signal.c b/src/pkg/runtime/windows/386/signal.c
index 69178cdd0..903636910 100644
--- a/src/pkg/runtime/windows/386/signal.c
+++ b/src/pkg/runtime/windows/386/signal.c
@@ -27,12 +27,7 @@ runtime·dumpregs(Context *r)
void
runtime·initsig(int32)
{
-}
-
-String
-runtime·signame(int32)
-{
- return runtime·emptystring;
+ runtime·siginit();
}
uint32
diff --git a/src/pkg/runtime/windows/386/sys.s b/src/pkg/runtime/windows/386/sys.s
index d1a8a49a9..bca48febe 100644
--- a/src/pkg/runtime/windows/386/sys.s
+++ b/src/pkg/runtime/windows/386/sys.s
@@ -99,6 +99,45 @@ TEXT runtime·sigtramp1(SB),0,$16-28
sigdone:
RET
+// Windows runs the ctrl handler in a new thread.
+TEXT runtime·ctrlhandler(SB),7,$0
+ PUSHL BP
+ MOVL SP, BP
+ PUSHL BX
+ PUSHL SI
+ PUSHL DI
+ PUSHL 0x2c(FS)
+ MOVL SP, BX
+
+ // setup dummy m, g
+ SUBL $(m_sehframe+4), SP // at least space for m_sehframe
+ LEAL m_tls(SP), CX
+ MOVL CX, 0x2c(FS)
+ MOVL SP, m(CX)
+ MOVL SP, DX
+ SUBL $8, SP // space for g_stack{guard,base}
+ MOVL SP, g(CX)
+ MOVL SP, m_g0(DX)
+ LEAL -4096(SP), CX
+ MOVL CX, g_stackguard(SP)
+ MOVL BX, g_stackbase(SP)
+
+ PUSHL 8(BP)
+ CALL runtime·ctrlhandler1(SB)
+ POPL CX
+
+ get_tls(CX)
+ MOVL g(CX), CX
+ MOVL g_stackbase(CX), SP
+ POPL 0x2c(FS)
+ POPL DI
+ POPL SI
+ POPL BX
+ POPL BP
+ MOVL 0(SP), CX
+ ADDL $8, SP
+ JMP CX
+
// Called from dynamic function created by ../thread.c compilecallback,
// running on Windows stack (not Go stack).
// BX, BP, SI, DI registers and DF flag are preserved
@@ -107,7 +146,11 @@ sigdone:
// DX = total size of arguments
//
TEXT runtime·callbackasm+0(SB),7,$0
+ // preserve whatever's at the memory location that
+ // the callback will use to store the return value
LEAL 8(SP), CX
+ PUSHL 0(CX)(DX*1)
+ ADDL $4, DX // extend argsize by size of return value
// save registers as required for windows callback
PUSHL 0(FS)
@@ -129,7 +172,7 @@ TEXT runtime·callbackasm+0(SB),7,$0
CALL runtime·cgocallback(SB)
// restore registers as required for windows callback
- POPL CX
+ POPL AX
POPL CX
POPL DX
POPL BX
@@ -139,6 +182,8 @@ TEXT runtime·callbackasm+0(SB),7,$0
POPL 0(FS)
CLD
+ MOVL -4(CX)(DX*1), AX
+ POPL -4(CX)(DX*1)
RET
// void tstart(M *newm);
diff --git a/src/pkg/runtime/windows/defs.c b/src/pkg/runtime/windows/defs.c
index 5aac03c81..3b2824940 100644
--- a/src/pkg/runtime/windows/defs.c
+++ b/src/pkg/runtime/windows/defs.c
@@ -2,9 +2,11 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+#include <signal.h>
#include <stdarg.h>
#include <windef.h>
#include <winbase.h>
+#include <wincon.h>
enum {
$PROT_NONE = 0,
@@ -15,6 +17,10 @@ enum {
$MAP_ANON = 1,
$MAP_PRIVATE = 2,
+ $SIGINT = SIGINT,
+ $CTRL_C_EVENT = CTRL_C_EVENT,
+ $CTRL_BREAK_EVENT = CTRL_BREAK_EVENT,
+
$EXCEPTION_ACCESS_VIOLATION = STATUS_ACCESS_VIOLATION,
$EXCEPTION_BREAKPOINT = STATUS_BREAKPOINT,
$EXCEPTION_FLT_DENORMAL_OPERAND = STATUS_FLOAT_DENORMAL_OPERAND,
diff --git a/src/pkg/runtime/windows/mem.c b/src/pkg/runtime/windows/mem.c
index 19d11ce8d..54d77da37 100644
--- a/src/pkg/runtime/windows/mem.c
+++ b/src/pkg/runtime/windows/mem.c
@@ -48,7 +48,14 @@ runtime·SysFree(void *v, uintptr n)
void*
runtime·SysReserve(void *v, uintptr n)
{
- return runtime·stdcall(runtime·VirtualAlloc, 4, v, n, MEM_RESERVE, 0);
+ // v is just a hint.
+ // First try at v.
+ v = runtime·stdcall(runtime·VirtualAlloc, 4, v, n, MEM_RESERVE, PAGE_EXECUTE_READWRITE);
+ if(v != nil)
+ return v;
+
+ // Next let the kernel choose the address.
+ return runtime·stdcall(runtime·VirtualAlloc, 4, nil, n, MEM_RESERVE, PAGE_EXECUTE_READWRITE);
}
void
diff --git a/src/pkg/runtime/windows/os.h b/src/pkg/runtime/windows/os.h
index 391eace5a..77881e86e 100644
--- a/src/pkg/runtime/windows/os.h
+++ b/src/pkg/runtime/windows/os.h
@@ -20,6 +20,7 @@ uint32 runtime·tstart_stdcall(M *newm);
uint32 runtime·issigpanic(uint32);
void runtime·sigpanic(void);
+uint32 runtime·ctrlhandler(uint32 type);
// Windows dll function to go callback entry.
byte *runtime·compilecallback(Eface fn, bool cleanstack);
diff --git a/src/pkg/runtime/windows/thread.c b/src/pkg/runtime/windows/thread.c
index 278a5da69..aedd24200 100644
--- a/src/pkg/runtime/windows/thread.c
+++ b/src/pkg/runtime/windows/thread.c
@@ -18,6 +18,7 @@
#pragma dynimport runtime·LoadLibraryEx LoadLibraryExA "kernel32.dll"
#pragma dynimport runtime·QueryPerformanceCounter QueryPerformanceCounter "kernel32.dll"
#pragma dynimport runtime·QueryPerformanceFrequency QueryPerformanceFrequency "kernel32.dll"
+#pragma dynimport runtime·SetConsoleCtrlHandler SetConsoleCtrlHandler "kernel32.dll"
#pragma dynimport runtime·SetEvent SetEvent "kernel32.dll"
#pragma dynimport runtime·WaitForSingleObject WaitForSingleObject "kernel32.dll"
#pragma dynimport runtime·WriteFile WriteFile "kernel32.dll"
@@ -33,6 +34,7 @@ extern void *runtime·GetStdHandle;
extern void *runtime·LoadLibraryEx;
extern void *runtime·QueryPerformanceCounter;
extern void *runtime·QueryPerformanceFrequency;
+extern void *runtime·SetConsoleCtrlHandler;
extern void *runtime·SetEvent;
extern void *runtime·WaitForSingleObject;
extern void *runtime·WriteFile;
@@ -43,6 +45,7 @@ void
runtime·osinit(void)
{
runtime·stdcall(runtime·QueryPerformanceFrequency, 1, &timerfreq);
+ runtime·stdcall(runtime·SetConsoleCtrlHandler, 2, runtime·ctrlhandler, 1);
}
void
@@ -161,6 +164,7 @@ runtime·destroylock(Lock *l)
void
runtime·noteclear(Note *n)
{
+ n->lock.key = 0; // memset(n, 0, sizeof *n)
eventlock(&n->lock);
}
@@ -180,11 +184,17 @@ runtime·notesleep(Note *n)
void
runtime·newosproc(M *m, G *g, void *stk, void (*fn)(void))
{
+ void *thandle;
+
USED(stk);
USED(g); // assuming g = m->g0
USED(fn); // assuming fn = mstart
- runtime·stdcall(runtime·CreateThread, 6, 0, 0, runtime·tstart_stdcall, m, 0, 0);
+ thandle = runtime·stdcall(runtime·CreateThread, 6, 0, 0, runtime·tstart_stdcall, m, 0, 0);
+ if(thandle == 0) {
+ runtime·printf("runtime: failed to create new OS thread (have %d already; errno=%d)\n", runtime·mcount(), runtime·getlasterror());
+ runtime·throw("runtime.newosproc");
+ }
}
// Called to initialize a new m (including the bootstrap m).
@@ -279,6 +289,41 @@ runtime·sigpanic(void)
runtime·throw("fault");
}
+String
+runtime·signame(int32 sig)
+{
+ int8 *s;
+
+ switch(sig) {
+ case SIGINT:
+ s = "SIGINT: interrupt";
+ break;
+ default:
+ return runtime·emptystring;
+ }
+ return runtime·gostringnocopy((byte*)s);
+}
+
+uint32
+runtime·ctrlhandler1(uint32 type)
+{
+ int32 s;
+
+ switch(type) {
+ case CTRL_C_EVENT:
+ case CTRL_BREAK_EVENT:
+ s = SIGINT;
+ break;
+ default:
+ return 0;
+ }
+
+ if(runtime·sigsend(s))
+ return 1;
+ runtime·exit(2); // SIGINT, SIGTERM, etc
+ return 0;
+}
+
// Call back from windows dll into go.
byte *
runtime·compilecallback(Eface fn, bool cleanstack)