diff options
Diffstat (limited to 'src/pkg/runtime/windows')
| -rw-r--r-- | src/pkg/runtime/windows/386/defs.h | 3 | ||||
| -rw-r--r-- | src/pkg/runtime/windows/386/signal.c | 7 | ||||
| -rw-r--r-- | src/pkg/runtime/windows/386/sys.s | 47 | ||||
| -rw-r--r-- | src/pkg/runtime/windows/defs.c | 6 | ||||
| -rw-r--r-- | src/pkg/runtime/windows/mem.c | 9 | ||||
| -rw-r--r-- | src/pkg/runtime/windows/os.h | 1 | ||||
| -rw-r--r-- | src/pkg/runtime/windows/thread.c | 47 | 
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) | 
