summaryrefslogtreecommitdiff
path: root/src/pkg/runtime/windows
diff options
context:
space:
mode:
authorOndřej Surý <ondrej@sury.org>2011-08-03 16:54:30 +0200
committerOndřej Surý <ondrej@sury.org>2011-08-03 16:54:30 +0200
commit28592ee1ea1f5cdffcf85472f9de0285d928cf12 (patch)
tree32944e18b23f7fe4a0818a694aa2a6dfb1835463 /src/pkg/runtime/windows
parente836bee4716dc0d4d913537ad3ad1925a7ac32d0 (diff)
downloadgolang-upstream/59.tar.gz
Imported Upstream version 59upstream/59
Diffstat (limited to 'src/pkg/runtime/windows')
-rw-r--r--src/pkg/runtime/windows/amd64/defs.h40
-rw-r--r--src/pkg/runtime/windows/amd64/rt0.s10
-rw-r--r--src/pkg/runtime/windows/amd64/signal.c20
-rw-r--r--src/pkg/runtime/windows/amd64/sys.s129
-rw-r--r--src/pkg/runtime/windows/mem.c10
-rw-r--r--src/pkg/runtime/windows/os.h3
-rw-r--r--src/pkg/runtime/windows/thread.c18
7 files changed, 216 insertions, 14 deletions
diff --git a/src/pkg/runtime/windows/amd64/defs.h b/src/pkg/runtime/windows/amd64/defs.h
new file mode 100644
index 000000000..830c6a855
--- /dev/null
+++ b/src/pkg/runtime/windows/amd64/defs.h
@@ -0,0 +1,40 @@
+// g:\opensource\go\bin\godefs.exe -f -m64 defs.c
+
+// MACHINE GENERATED - DO NOT EDIT.
+
+// Constants
+enum {
+ PROT_NONE = 0,
+ PROT_READ = 0x1,
+ PROT_WRITE = 0x2,
+ 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,
+ EXCEPTION_FLT_DIVIDE_BY_ZERO = 0xc000008e,
+ EXCEPTION_FLT_INEXACT_RESULT = 0xc000008f,
+ EXCEPTION_FLT_OVERFLOW = 0xc0000091,
+ EXCEPTION_FLT_UNDERFLOW = 0xc0000093,
+ EXCEPTION_INT_DIVIDE_BY_ZERO = 0xc0000094,
+ EXCEPTION_INT_OVERFLOW = 0xc0000095,
+};
+
+// Types
+#pragma pack on
+
+typedef struct ExceptionRecord ExceptionRecord;
+struct ExceptionRecord {
+ uint32 ExceptionCode;
+ uint32 ExceptionFlags;
+ ExceptionRecord *ExceptionRecord;
+ void *ExceptionAddress;
+ uint32 NumberParameters;
+ byte pad_godefs_0[4];
+ uint64 ExceptionInformation[15];
+};
+#pragma pack off
diff --git a/src/pkg/runtime/windows/amd64/rt0.s b/src/pkg/runtime/windows/amd64/rt0.s
new file mode 100644
index 000000000..e54e7edeb
--- /dev/null
+++ b/src/pkg/runtime/windows/amd64/rt0.s
@@ -0,0 +1,10 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "amd64/asm.h"
+
+TEXT _rt0_amd64_windows(SB),7,$-8
+ MOVQ $_rt0_amd64(SB), AX
+ MOVQ SP, DI
+ JMP AX
diff --git a/src/pkg/runtime/windows/amd64/signal.c b/src/pkg/runtime/windows/amd64/signal.c
new file mode 100644
index 000000000..1fc3eb060
--- /dev/null
+++ b/src/pkg/runtime/windows/amd64/signal.c
@@ -0,0 +1,20 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "runtime.h"
+#include "defs.h"
+#include "os.h"
+
+void
+runtime·initsig(int32 queue)
+{
+}
+
+void
+runtime·resetcpuprofiler(int32 hz)
+{
+ // TODO: Enable profiling interrupts.
+
+ m->profilehz = hz;
+}
diff --git a/src/pkg/runtime/windows/amd64/sys.s b/src/pkg/runtime/windows/amd64/sys.s
new file mode 100644
index 000000000..b1eacfc82
--- /dev/null
+++ b/src/pkg/runtime/windows/amd64/sys.s
@@ -0,0 +1,129 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "amd64/asm.h"
+
+// void *stdcall_raw(void *fn, uintptr nargs, void *args)
+TEXT runtime·stdcall_raw(SB),7,$8
+ MOVQ fn+0(FP), AX
+ MOVQ nargs+8(FP), CX
+ MOVQ args+16(FP), R11
+
+ // Switch to m->g0 if needed.
+ get_tls(DI)
+ MOVQ m(DI), DX
+ MOVQ g(DI), SI
+ MOVQ SI, 0(SP) // save g
+ MOVQ SP, m_gostack(DX) // save SP
+ MOVQ m_g0(DX), SI
+ CMPQ g(DI), SI
+ JEQ 3(PC)
+ MOVQ (g_sched+gobuf_sp)(SI), SP
+ MOVQ SI, g(DI)
+
+ SUBQ $0x60, SP
+
+ // Copy args to new stack.
+ MOVQ SP, DI
+ MOVQ R11, SI
+ CLD
+ REP; MOVSQ
+ MOVQ 0(R11), CX
+ MOVQ 8(R11), DX
+ MOVQ 16(R11), R8
+ MOVQ 24(R11), R9
+
+ // Call stdcall function.
+ CALL AX
+
+ // Restore original SP, g.
+ get_tls(DI)
+ MOVQ m(DI), DX
+ MOVQ m_gostack(DX), SP // restore SP
+ MOVQ 0(SP), SI // restore g
+ MOVQ SI, g(DI)
+
+ RET
+
+// faster get/set last error
+TEXT runtime·getlasterror(SB),7,$0
+ MOVQ 0x30(GS), AX
+ MOVL 0x68(AX), AX
+ RET
+
+TEXT runtime·setlasterror(SB),7,$0
+ MOVL err+0(FP), AX
+ MOVQ 0x30(GS), CX
+ MOVL AX, 0x68(CX)
+ RET
+
+// Windows runs the ctrl handler in a new thread.
+TEXT runtime·ctrlhandler(SB),7,$0
+ // TODO
+ RET
+
+TEXT runtime·callbackasm(SB),7,$0
+ // TODO
+ RET
+
+// void tstart(M *newm);
+TEXT runtime·tstart(SB),7,$0
+ MOVQ newm+8(SP), CX // m
+ MOVQ m_g0(CX), DX // g
+
+ MOVQ SP, DI // remember stack
+
+ // Layout new m scheduler stack on os stack.
+ MOVQ SP, AX
+ MOVQ AX, g_stackbase(DX)
+ SUBQ $(64*1024), AX // stack size
+ MOVQ AX, g_stackguard(DX)
+
+ // Set up tls.
+ LEAQ m_tls(CX), SI
+ MOVQ SI, 0x58(GS)
+ MOVQ CX, m(SI)
+ MOVQ DX, g(SI)
+
+ // Someday the convention will be D is always cleared.
+ CLD
+
+ PUSHQ DI // original stack
+
+ CALL runtime·stackcheck(SB) // clobbers AX,CX
+
+ CALL runtime·mstart(SB)
+
+ POPQ DI // original stack
+ MOVQ DI, SP
+
+ RET
+
+// uint32 tstart_stdcall(M *newm);
+TEXT runtime·tstart_stdcall(SB),7,$0
+ MOVQ CX, BX // stdcall first arg in RCX
+
+ PUSHQ BX
+ CALL runtime·tstart+0(SB)
+ POPQ BX
+
+ // Adjust stack for stdcall to return properly.
+ MOVQ (SP), AX // save return address
+ ADDQ $8, SP // remove single parameter
+ MOVQ AX, (SP) // restore return address
+
+ XORL AX, AX // return 0 == success
+
+ RET
+
+TEXT runtime·notok(SB),7,$0
+ MOVQ $0xf1, BP
+ MOVQ BP, (BP)
+ RET
+
+// set tls base to DI
+TEXT runtime·settls(SB),7,$0
+ MOVQ DI, 0x58(GS)
+ RET
+
diff --git a/src/pkg/runtime/windows/mem.c b/src/pkg/runtime/windows/mem.c
index 54d77da37..5d2291fa3 100644
--- a/src/pkg/runtime/windows/mem.c
+++ b/src/pkg/runtime/windows/mem.c
@@ -24,7 +24,7 @@ void*
runtime·SysAlloc(uintptr n)
{
mstats.sys += n;
- return runtime·stdcall(runtime·VirtualAlloc, 4, nil, n, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
+ return runtime·stdcall(runtime·VirtualAlloc, 4, nil, n, (uintptr)(MEM_COMMIT|MEM_RESERVE), (uintptr)PAGE_EXECUTE_READWRITE);
}
void
@@ -40,7 +40,7 @@ runtime·SysFree(void *v, uintptr n)
uintptr r;
mstats.sys -= n;
- r = (uintptr)runtime·stdcall(runtime·VirtualFree, 3, v, 0, MEM_RELEASE);
+ r = (uintptr)runtime·stdcall(runtime·VirtualFree, 3, v, (uintptr)0, (uintptr)MEM_RELEASE);
if(r == 0)
runtime·throw("runtime: failed to release pages");
}
@@ -50,12 +50,12 @@ runtime·SysReserve(void *v, uintptr n)
{
// v is just a hint.
// First try at v.
- v = runtime·stdcall(runtime·VirtualAlloc, 4, v, n, MEM_RESERVE, PAGE_EXECUTE_READWRITE);
+ v = runtime·stdcall(runtime·VirtualAlloc, 4, v, n, (uintptr)MEM_RESERVE, (uintptr)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);
+ return runtime·stdcall(runtime·VirtualAlloc, 4, nil, n, (uintptr)MEM_RESERVE, (uintptr)PAGE_EXECUTE_READWRITE);
}
void
@@ -64,7 +64,7 @@ runtime·SysMap(void *v, uintptr n)
void *p;
mstats.sys += n;
- p = runtime·stdcall(runtime·VirtualAlloc, 4, v, n, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
+ p = runtime·stdcall(runtime·VirtualAlloc, 4, v, n, (uintptr)MEM_COMMIT, (uintptr)PAGE_EXECUTE_READWRITE);
if(p != v)
runtime·throw("runtime: cannot map pages in arena address space");
}
diff --git a/src/pkg/runtime/windows/os.h b/src/pkg/runtime/windows/os.h
index 77881e86e..bc9678733 100644
--- a/src/pkg/runtime/windows/os.h
+++ b/src/pkg/runtime/windows/os.h
@@ -7,6 +7,9 @@ extern void *runtime·GetProcAddress;
// Call a Windows function with stdcall conventions,
// and switch to os stack during the call.
+#pragma varargck countpos runtime·stdcall 2
+#pragma varargck type runtime·stdcall void*
+#pragma varargck type runtime·stdcall uintptr
void *runtime·stdcall_raw(void *fn, uintptr nargs, void *args);
void *runtime·stdcall(void *fn, int32 count, ...);
uintptr runtime·syscall(void *fn, uintptr nargs, void *args, uintptr *err);
diff --git a/src/pkg/runtime/windows/thread.c b/src/pkg/runtime/windows/thread.c
index 81ad68033..5644fd5dd 100644
--- a/src/pkg/runtime/windows/thread.c
+++ b/src/pkg/runtime/windows/thread.c
@@ -45,7 +45,7 @@ void
runtime·osinit(void)
{
runtime·stdcall(runtime·QueryPerformanceFrequency, 1, &timerfreq);
- runtime·stdcall(runtime·SetConsoleCtrlHandler, 2, runtime·ctrlhandler, 1);
+ runtime·stdcall(runtime·SetConsoleCtrlHandler, 2, runtime·ctrlhandler, (uintptr)1);
}
void
@@ -81,7 +81,7 @@ runtime·goenvs(void)
void
runtime·exit(int32 code)
{
- runtime·stdcall(runtime·ExitProcess, 1, code);
+ runtime·stdcall(runtime·ExitProcess, 1, (uintptr)code);
}
int32
@@ -93,15 +93,15 @@ runtime·write(int32 fd, void *buf, int32 n)
written = 0;
switch(fd) {
case 1:
- handle = runtime·stdcall(runtime·GetStdHandle, 1, -11);
+ handle = runtime·stdcall(runtime·GetStdHandle, 1, (uintptr)-11);
break;
case 2:
- handle = runtime·stdcall(runtime·GetStdHandle, 1, -12);
+ handle = runtime·stdcall(runtime·GetStdHandle, 1, (uintptr)-12);
break;
default:
return -1;
}
- runtime·stdcall(runtime·WriteFile, 5, handle, buf, n, &written, 0);
+ runtime·stdcall(runtime·WriteFile, 5, handle, buf, (uintptr)n, &written, (uintptr)0);
return written;
}
@@ -111,7 +111,7 @@ initevent(void **pevent)
{
void *event;
- event = runtime·stdcall(runtime·CreateEvent, 4, 0, 0, 0, 0);
+ event = runtime·stdcall(runtime·CreateEvent, 4, (uintptr)0, (uintptr)0, (uintptr)0, (uintptr)0);
if(!runtime·casp(pevent, 0, event)) {
// Someone else filled it in. Use theirs.
runtime·stdcall(runtime·CloseHandle, 1, event);
@@ -126,7 +126,7 @@ eventlock(Lock *l)
initevent(&l->event);
if(runtime·xadd(&l->key, 1) > 1) // someone else has it; wait
- runtime·stdcall(runtime·WaitForSingleObject, 2, l->event, -1);
+ runtime·stdcall(runtime·WaitForSingleObject, 2, l->event, (uintptr)-1);
}
static void
@@ -190,7 +190,7 @@ runtime·newosproc(M *m, G *g, void *stk, void (*fn)(void))
USED(g); // assuming g = m->g0
USED(fn); // assuming fn = mstart
- thandle = runtime·stdcall(runtime·CreateThread, 6, 0, 0, runtime·tstart_stdcall, m, 0, 0);
+ thandle = runtime·stdcall(runtime·CreateThread, 6, (uintptr)0, (uintptr)0, runtime·tstart_stdcall, m, (uintptr)0, (uintptr)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");
@@ -219,7 +219,7 @@ runtime·gettime(int64 *sec, int32 *usec)
void *
runtime·stdcall(void *fn, int32 count, ...)
{
- return runtime·stdcall_raw(fn, count, (uintptr*)(&count + 1));
+ return runtime·stdcall_raw(fn, count, (uintptr*)&count + 1);
}
uintptr