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/rt0.s2
-rw-r--r--src/pkg/runtime/windows/386/signal.c9
-rw-r--r--src/pkg/runtime/windows/386/sys.s157
-rw-r--r--src/pkg/runtime/windows/mem.c47
-rw-r--r--src/pkg/runtime/windows/os.h34
-rw-r--r--src/pkg/runtime/windows/runtime_defs.go22
-rw-r--r--src/pkg/runtime/windows/syscall.goc54
-rw-r--r--src/pkg/runtime/windows/thread.c268
8 files changed, 301 insertions, 292 deletions
diff --git a/src/pkg/runtime/windows/386/rt0.s b/src/pkg/runtime/windows/386/rt0.s
index 4e6850416..e379830fb 100644
--- a/src/pkg/runtime/windows/386/rt0.s
+++ b/src/pkg/runtime/windows/386/rt0.s
@@ -2,5 +2,5 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-TEXT _rt0_386_windows(SB),7,$0
+TEXT _rt0_386_windows(SB),7,$0
JMP _rt0_386(SB)
diff --git a/src/pkg/runtime/windows/386/signal.c b/src/pkg/runtime/windows/386/signal.c
index 278bb7fc4..2ae79e5b5 100644
--- a/src/pkg/runtime/windows/386/signal.c
+++ b/src/pkg/runtime/windows/386/signal.c
@@ -5,6 +5,13 @@
#include "runtime.h"
void
-initsig(int32 queue)
+runtime·initsig(int32)
{
}
+
+String
+runtime·signame(int32)
+{
+ return runtime·emptystring;
+}
+
diff --git a/src/pkg/runtime/windows/386/sys.s b/src/pkg/runtime/windows/386/sys.s
index e36ef53e0..7f99b34de 100644
--- a/src/pkg/runtime/windows/386/sys.s
+++ b/src/pkg/runtime/windows/386/sys.s
@@ -4,105 +4,112 @@
#include "386/asm.h"
-TEXT get_kernel_module(SB),7,$0
- MOVL 0x30(FS), AX // get PEB
- MOVL 0x0c(AX), AX // get PEB_LDR_DATA
- MOVL 0x1c(AX), AX // get init order module list
- MOVL (AX), AX // get next entry (kernel module)
- MOVL 0x08(AX), AX // get base of module
- RET
-
-// void *stdcall_raw(void *fn, ...);
-// Call fn with stdcall calling convention.
-// fn parameters are on stack.
-TEXT stdcall_raw(SB),7,$0
- get_tls(CX)
- MOVL m(CX), CX
- POPL m_return_address(CX) // save return address
- POPL AX // first arg is function pointer
- MOVL SP, m_stack_pointer(CX) // save stack pointer
- CALL AX
- get_tls(CX)
- MOVL m(CX), CX
- MOVL m_stack_pointer(CX), SP
- PUSHL AX
- PUSHL m_return_address(CX)
- RET
+// void *stdcall_raw(void *fn, int32 count, uintptr *args)
+TEXT runtime·stdcall_raw(SB),7,$4
+ // Copy arguments from stack.
+ MOVL fn+0(FP), AX
+ MOVL count+4(FP), CX // words
+ MOVL args+8(FP), BP
-// void syscall(StdcallParams *p);
-// Call p.fn syscall + GetLastError on os stack.
-TEXT syscall(SB),7,$16
- MOVL p+0(FP), AX
- MOVL SP, CX
-
- // Figure out if we need to switch to m->g0 stack.
+ // Switch to m->g0 if needed.
get_tls(DI)
MOVL m(DI), DX
+ MOVL g(DI), SI
+ MOVL SI, 0(SP) // save g
+ MOVL SP, m_gostack(DX) // save SP
MOVL m_g0(DX), SI
CMPL g(DI), SI
- JEQ 2(PC)
+ JEQ 3(PC)
MOVL (m_sched+gobuf_sp)(DX), SP
-
- // Now on a scheduling stack (an os stack).
- MOVL g(DI), BP
- MOVL BP, 8(SP)
MOVL SI, g(DI)
- MOVL CX, 4(SP)
- MOVL AX, 0(SP)
- CALL call_syscall(SB)
-
- // Back; switch to original g and stack, re-establish
- // "DF is clear" invariant.
+
+ // Copy args to new stack.
+ SUBL $(10*4), SP // padding
+ MOVL CX, BX
+ SALL $2, BX
+ SUBL BX, SP // room for args
+ MOVL SP, DI
+ MOVL BP, SI
CLD
+ REP; MOVSL
+
+ // Call stdcall function.
+ CALL AX
+
+ // Restore original SP, g.
get_tls(DI)
- MOVL 8(SP), SI
+ MOVL m(DI), DX
+ MOVL m_gostack(DX), SP // restore SP
+ MOVL 0(SP), SI // restore g
MOVL SI, g(DI)
- MOVL 4(SP), SP
- RET
-TEXT threadstart(SB),7,$0
- MOVL 4(SP), AX // threadstart param
- MOVL 0(AX), BX // newosproc arg stack
- MOVL 0(BX), CX // m
- MOVL 4(BX), DX // g
+ // Someday the convention will be D is always cleared.
+ CLD
+
+ RET
+
+// void tstart(M *newm);
+TEXT runtime·tstart(SB),7,$0
+ MOVL newm+4(SP), CX // m
+ MOVL m_g0(CX), DX // g
+
+ MOVL SP, DI // remember stack
- // set up tls
+ // Layout new m scheduler stack on os stack.
+ MOVL SP, AX
+ SUBL $256, AX // just some space for ourselves
+ MOVL AX, g_stackbase(DX)
+ SUBL $8192, AX // stack size
+ MOVL AX, g_stackguard(DX)
+
+ // Set up tls.
LEAL m_tls(CX), SI
MOVL SI, 0x2c(FS)
MOVL CX, m(SI)
MOVL DX, g(SI)
- MOVL SP, m_os_stack_pointer(CX)
-
- PUSHL 8(BX) // stk
- PUSHL 12(BX) // fn
- PUSHL 4(AX) // event_handle
-
- // signal that we're done with thread args
- MOVL SetEvent(SB), BX
- CALL BX // SetEvent(event_handle)
- POPL BX // fn
- POPL SP // stk
-
- CALL stackcheck(SB) // clobbers AX,CX
- CALL BX // fn()
-
- // cleanup stack before returning as we are stdcall
- get_tls(CX)
- MOVL m(CX), CX
- MOVL m_os_stack_pointer(CX), SP
- POPL AX // return address
- MOVL AX, (SP)
- XORL AX, AX
+
+ // Use scheduler stack now.
+ MOVL g_stackbase(DX), SP
+
+ // Someday the convention will be D is always cleared.
+ CLD
+
+ PUSHL DI // original stack
+
+ CALL runtime·stackcheck(SB) // clobbers AX,CX
+
+ CALL runtime·mstart(SB)
+
+ POPL DI // original stack
+ MOVL DI, SP
+
+ RET
+
+// uint32 tstart_stdcall(M *newm);
+TEXT runtime·tstart_stdcall(SB),7,$0
+ MOVL newm+4(SP), BX
+
+ PUSHL BX
+ CALL runtime·tstart(SB)
+ POPL BX
+
+ // Adjust stack for stdcall to return properly.
+ MOVL (SP), AX // save return address
+ ADDL $4, SP // remove single parameter
+ MOVL AX, (SP) // restore return address
+
+ XORL AX, AX // return 0 == success
+
RET
// setldt(int entry, int address, int limit)
-TEXT setldt(SB),7,$0
+TEXT runtime·setldt(SB),7,$0
MOVL address+4(FP), CX
MOVL CX, 0x2c(FS)
RET
// for now, return 0,0. only used for internal performance monitoring.
-TEXT gettime(SB),7,$0
+TEXT runtime·gettime(SB),7,$0
MOVL sec+0(FP), DI
MOVL $0, (DI)
MOVL $0, 4(DI) // zero extend 32 -> 64 bits
diff --git a/src/pkg/runtime/windows/mem.c b/src/pkg/runtime/windows/mem.c
index 982344fa0..ba89887ea 100644
--- a/src/pkg/runtime/windows/mem.c
+++ b/src/pkg/runtime/windows/mem.c
@@ -7,23 +7,58 @@
#include "defs.h"
#include "malloc.h"
+enum {
+ MEM_COMMIT = 0x1000,
+ MEM_RESERVE = 0x2000,
+ MEM_RELEASE = 0x8000,
+
+ PAGE_EXECUTE_READWRITE = 0x40,
+};
+
+static void
+abort(int8 *name)
+{
+ uintptr errno;
+
+ errno = (uintptr)runtime·stdcall(runtime·GetLastError, 0);
+ runtime·printf("%s failed with errno=%d\n", name, errno);
+ runtime·throw(name);
+}
+
+#pragma dynimport runtime·VirtualAlloc VirtualAlloc "kernel32.dll"
+#pragma dynimport runtime·VirtualFree VirtualFree "kernel32.dll"
+extern void *runtime·VirtualAlloc;
+extern void *runtime·VirtualFree;
+
void*
-SysAlloc(uintptr n)
+runtime·SysAlloc(uintptr n)
{
- return stdcall(VirtualAlloc, 4, nil, n, 0x3000, 0x40);
+ void *v;
+
+ v = runtime·stdcall(runtime·VirtualAlloc, 4, nil, n, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
+ if(v == 0)
+ abort("VirtualAlloc");
+ return v;
}
void
-SysUnused(void *v, uintptr n)
+runtime·SysUnused(void *v, uintptr n)
{
USED(v);
USED(n);
}
void
-SysFree(void *v, uintptr n)
+runtime·SysFree(void *v, uintptr n)
{
- USED(v);
- USED(n);
+ uintptr r;
+
+ r = (uintptr)runtime·stdcall(runtime·VirtualFree, 3, v, 0, MEM_RELEASE);
+ if(r == 0)
+ abort("VirtualFree");
}
+void
+runtime·SysMemInit(void)
+{
+}
diff --git a/src/pkg/runtime/windows/os.h b/src/pkg/runtime/windows/os.h
index 931f4991c..77d0d32a0 100644
--- a/src/pkg/runtime/windows/os.h
+++ b/src/pkg/runtime/windows/os.h
@@ -2,28 +2,21 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// The following function allows one to dynamically
-// resolve DLL function names.
-// The arguments are strings.
-void *get_proc_addr(void *library, void *name);
-
-extern void *VirtualAlloc;
-extern void *LoadLibraryEx;
-extern void *GetProcAddress;
-extern void *GetLastError;
-
-#define goargs windows_goargs
-void windows_goargs(void);
+extern void *runtime·LoadLibraryEx;
+extern void *runtime·GetProcAddress;
+extern void *runtime·GetLastError;
// Get start address of symbol data in memory.
-void *get_symdat_addr(void);
-
-// Call a Windows function with stdcall conventions.
-void *stdcall_raw(void *fn, ...);
+void *runtime·get_symdat_addr(void);
// Call a Windows function with stdcall conventions,
// and switch to os stack during the call.
-void *stdcall(void *fn, int32 count, ...);
+void *runtime·stdcall_raw(void *fn, int32 count, uintptr *args);
+void *runtime·stdcall(void *fn, int32 count, ...);
+
+// Function to be called by windows CreateTread
+// to start new os thread.
+uint32 runtime·tstart_stdcall(M *newm);
// Call stdcall Windows function StdcallParams.fn
// with params StdcallParams.args,
@@ -34,9 +27,10 @@ typedef struct StdcallParams StdcallParams;
struct StdcallParams
{
void *fn;
- uintptr args[9];
+ uintptr args[12];
+ int32 n;
uintptr r;
uintptr err;
};
-void call_syscall(void *args);
-void syscall(StdcallParams *p);
+
+void runtime·syscall(StdcallParams *p);
diff --git a/src/pkg/runtime/windows/runtime_defs.go b/src/pkg/runtime/windows/runtime_defs.go
new file mode 100644
index 000000000..34a9b3259
--- /dev/null
+++ b/src/pkg/runtime/windows/runtime_defs.go
@@ -0,0 +1,22 @@
+// Copyright 2010 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.
+
+// Go definitions of internal structures. Master is runtime.h
+
+package runtime
+
+import "unsafe"
+
+const (
+ Windows = 1
+)
+
+// const ( Structrnd = sizeof(uintptr) )
+
+type lock struct {
+ key uint32
+ event unsafe.Pointer
+}
+
+type note lock
diff --git a/src/pkg/runtime/windows/syscall.goc b/src/pkg/runtime/windows/syscall.goc
index 362217e6b..d3057c540 100644
--- a/src/pkg/runtime/windows/syscall.goc
+++ b/src/pkg/runtime/windows/syscall.goc
@@ -8,24 +8,22 @@ package syscall
func loadlibraryex(filename uintptr) (handle uint32) {
StdcallParams p;
- p.fn = (void*)LoadLibraryEx;
+ p.fn = (void*)runtime·LoadLibraryEx;
p.args[0] = filename;
p.args[1] = 0;
p.args[2] = 0;
- ·entersyscall();
- syscall(&p);
- ·exitsyscall();
+ p.n = 3;
+ runtime·syscall(&p);
handle = p.r;
}
func getprocaddress(handle uint32, procname uintptr) (proc uintptr) {
StdcallParams p;
- p.fn = (void*)GetProcAddress;
+ p.fn = (void*)runtime·GetProcAddress;
p.args[0] = handle;
p.args[1] = procname;
- ·entersyscall();
- syscall(&p);
- ·exitsyscall();
+ p.n = 2;
+ runtime·syscall(&p);
proc = p.r;
}
@@ -35,9 +33,8 @@ func Syscall(trap uintptr, a1 uintptr, a2 uintptr, a3 uintptr) (r1 uintptr, r2 u
p.args[0] = a1;
p.args[1] = a2;
p.args[2] = a3;
- ·entersyscall();
- syscall(&p);
- ·exitsyscall();
+ p.n = 3;
+ runtime·syscall(&p);
r1 = p.r;
r2 = 0;
err = p.err;
@@ -52,9 +49,8 @@ func Syscall6(trap uintptr, a1 uintptr, a2 uintptr, a3 uintptr, a4 uintptr, a5 u
p.args[3] = a4;
p.args[4] = a5;
p.args[5] = a6;
- ·entersyscall();
- syscall(&p);
- ·exitsyscall();
+ p.n = 6;
+ runtime·syscall(&p);
r1 = p.r;
r2 = 0;
err = p.err;
@@ -72,9 +68,30 @@ func Syscall9(trap uintptr, a1 uintptr, a2 uintptr, a3 uintptr, a4 uintptr, a5 u
p.args[6] = a7;
p.args[7] = a8;
p.args[8] = a9;
- ·entersyscall();
- syscall(&p);
- ·exitsyscall();
+ p.n = 9;
+ runtime·syscall(&p);
+ r1 = p.r;
+ r2 = 0;
+ lasterr = p.err;
+}
+
+func Syscall12(trap uintptr, a1 uintptr, a2 uintptr, a3 uintptr, a4 uintptr, a5 uintptr, a6 uintptr, a7 uintptr, a8 uintptr, a9 uintptr, a10 uintptr, a11 uintptr, a12 uintptr) (r1 uintptr, r2 uintptr, lasterr uintptr) {
+ StdcallParams p;
+ p.fn = (void*)trap;
+ p.args[0] = a1;
+ p.args[1] = a2;
+ p.args[2] = a3;
+ p.args[3] = a4;
+ p.args[4] = a5;
+ p.args[5] = a6;
+ p.args[6] = a7;
+ p.args[7] = a8;
+ p.args[8] = a9;
+ p.args[9] = a10;
+ p.args[10] = a11;
+ p.args[11] = a12;
+ p.n = 12;
+ runtime·syscall(&p);
r1 = p.r;
r2 = 0;
lasterr = p.err;
@@ -86,7 +103,8 @@ func RawSyscall(trap uintptr, a1 uintptr, a2 uintptr, a3 uintptr) (r1 uintptr, r
p.args[0] = a1;
p.args[1] = a2;
p.args[2] = a3;
- syscall(&p);
+ p.n = 3;
+ runtime·syscall(&p);
r1 = p.r;
r2 = 0;
err = p.err;
diff --git a/src/pkg/runtime/windows/thread.c b/src/pkg/runtime/windows/thread.c
index c65f665b1..9b5181337 100644
--- a/src/pkg/runtime/windows/thread.c
+++ b/src/pkg/runtime/windows/thread.c
@@ -5,130 +5,84 @@
#include "runtime.h"
#include "os.h"
-extern void *get_kernel_module(void);
+#pragma dynimport runtime·LoadLibraryEx LoadLibraryExA "kernel32.dll"
+#pragma dynimport runtime·GetProcAddress GetProcAddress "kernel32.dll"
+#pragma dynimport runtime·CloseHandle CloseHandle "kernel32.dll"
+#pragma dynimport runtime·ExitProcess ExitProcess "kernel32.dll"
+#pragma dynimport runtime·GetStdHandle GetStdHandle "kernel32.dll"
+#pragma dynimport runtime·SetEvent SetEvent "kernel32.dll"
+#pragma dynimport runtime·WriteFile WriteFile "kernel32.dll"
+#pragma dynimport runtime·GetLastError GetLastError "kernel32.dll"
+#pragma dynimport runtime·SetLastError SetLastError "kernel32.dll"
// Also referenced by external packages
-void *CloseHandle;
-void *ExitProcess;
-void *GetStdHandle;
-void *SetEvent;
-void *WriteFile;
-void *VirtualAlloc;
-void *LoadLibraryEx;
-void *GetProcAddress;
-void *GetLastError;
-
-static void *CreateEvent;
-static void *CreateThread;
-static void *GetModuleHandle;
-static void *WaitForSingleObject;
-
-static void*
-get_proc_addr2(byte *base, byte *name)
-{
- byte *pe_header, *exports;
- uint32 entries, *addr, *names, i;
- uint16 *ordinals;
-
- pe_header = base+*(uint32*)(base+0x3c);
- exports = base+*(uint32*)(pe_header+0x78);
- entries = *(uint32*)(exports+0x18);
- addr = (uint32*)(base+*(uint32*)(exports+0x1c));
- names = (uint32*)(base+*(uint32*)(exports+0x20));
- ordinals = (uint16*)(base+*(uint32*)(exports+0x24));
- for(i=0; i<entries; i++) {
- byte *s = base+names[i];
- if(!strcmp(name, s))
- break;
- }
- if(i == entries)
- return 0;
- return base+addr[ordinals[i]];
-}
+extern void *runtime·CloseHandle;
+extern void *runtime·ExitProcess;
+extern void *runtime·GetStdHandle;
+extern void *runtime·SetEvent;
+extern void *runtime·WriteFile;
+extern void *runtime·LoadLibraryEx;
+extern void *runtime·GetProcAddress;
+extern void *runtime·GetLastError;
+extern void *runtime·SetLastError;
+
+#pragma dynimport runtime·CreateEvent CreateEventA "kernel32.dll"
+#pragma dynimport runtime·CreateThread CreateThread "kernel32.dll"
+#pragma dynimport runtime·WaitForSingleObject WaitForSingleObject "kernel32.dll"
+
+extern void *runtime·CreateEvent;
+extern void *runtime·CreateThread;
+extern void *runtime·WaitForSingleObject;
void
-osinit(void)
+runtime·osinit(void)
{
- void *base;
-
- base = get_kernel_module();
- GetProcAddress = get_proc_addr2(base, (byte*)"GetProcAddress");
- LoadLibraryEx = get_proc_addr2(base, (byte*)"LoadLibraryExA");
- CloseHandle = get_proc_addr("kernel32.dll", "CloseHandle");
- CreateEvent = get_proc_addr("kernel32.dll", "CreateEventA");
- CreateThread = get_proc_addr("kernel32.dll", "CreateThread");
- ExitProcess = get_proc_addr("kernel32.dll", "ExitProcess");
- GetModuleHandle = get_proc_addr("kernel32.dll", "GetModuleHandleA");
- GetStdHandle = get_proc_addr("kernel32.dll", "GetStdHandle");
- SetEvent = get_proc_addr("kernel32.dll", "SetEvent");
- VirtualAlloc = get_proc_addr("kernel32.dll", "VirtualAlloc");
- WaitForSingleObject = get_proc_addr("kernel32.dll", "WaitForSingleObject");
- WriteFile = get_proc_addr("kernel32.dll", "WriteFile");
- GetLastError = get_proc_addr("kernel32.dll", "GetLastError");
}
-// The arguments are strings.
-void*
-get_proc_addr(void *library, void *name)
-{
- void *base;
+#pragma dynimport runtime·GetEnvironmentStringsW GetEnvironmentStringsW "kernel32.dll"
+#pragma dynimport runtime·FreeEnvironmentStringsW FreeEnvironmentStringsW "kernel32.dll"
- base = stdcall_raw(LoadLibraryEx, library, 0, 0);
- return stdcall_raw(GetProcAddress, base, name);
-}
+extern void *runtime·GetEnvironmentStringsW;
+extern void *runtime·FreeEnvironmentStringsW;
void
-windows_goargs(void)
+runtime·goenvs(void)
{
- extern Slice os·Args;
extern Slice os·Envs;
- void *gcl, *clta, *ges;
- uint16 *cmd, *env, **argv;
- String *gargv;
- String *genvv;
- int32 i, argc, envc;
- uint16 *envp;
-
- gcl = get_proc_addr("kernel32.dll", "GetCommandLineW");
- clta = get_proc_addr("shell32.dll", "CommandLineToArgvW");
- ges = get_proc_addr("kernel32.dll", "GetEnvironmentStringsW");
-
- cmd = stdcall(gcl, 0);
- env = stdcall(ges, 0);
- argv = stdcall(clta, 2, cmd, &argc);
-
- envc = 0;
- for(envp=env; *envp; envc++)
- envp += findnullw(envp)+1;
-
- gargv = malloc(argc*sizeof gargv[0]);
- genvv = malloc(envc*sizeof genvv[0]);
-
- for(i=0; i<argc; i++)
- gargv[i] = gostringw(argv[i]);
- os·Args.array = (byte*)gargv;
- os·Args.len = argc;
- os·Args.cap = argc;
-
- envp = env;
- for(i=0; i<envc; i++) {
- genvv[i] = gostringw(envp);
- envp += findnullw(envp)+1;
+ uint16 *env;
+ String *s;
+ int32 i, n;
+ uint16 *p;
+
+ env = runtime·stdcall(runtime·GetEnvironmentStringsW, 0);
+
+ n = 0;
+ for(p=env; *p; n++)
+ p += runtime·findnullw(p)+1;
+
+ s = runtime·malloc(n*sizeof s[0]);
+
+ p = env;
+ for(i=0; i<n; i++) {
+ s[i] = runtime·gostringw(p);
+ p += runtime·findnullw(p)+1;
}
- os·Envs.array = (byte*)genvv;
- os·Envs.len = envc;
- os·Envs.cap = envc;
+ os·Envs.array = (byte*)s;
+ os·Envs.len = n;
+ os·Envs.cap = n;
+
+ runtime·stdcall(runtime·FreeEnvironmentStringsW, 1, env);
}
void
-exit(int32 code)
+runtime·exit(int32 code)
{
- stdcall(ExitProcess, 1, code);
+ runtime·stdcall(runtime·ExitProcess, 1, code);
}
int32
-write(int32 fd, void *buf, int32 n)
+runtime·write(int32 fd, void *buf, int32 n)
{
void *handle;
uint32 written;
@@ -136,46 +90,28 @@ write(int32 fd, void *buf, int32 n)
written = 0;
switch(fd) {
case 1:
- handle = stdcall(GetStdHandle, 1, -11);
+ handle = runtime·stdcall(runtime·GetStdHandle, 1, -11);
break;
case 2:
- handle = stdcall(GetStdHandle, 1, -12);
+ handle = runtime·stdcall(runtime·GetStdHandle, 1, -12);
break;
default:
return -1;
}
- stdcall(WriteFile, 5, handle, buf, n, &written, 0);
+ runtime·stdcall(runtime·WriteFile, 5, handle, buf, n, &written, 0);
return written;
}
-void*
-get_symdat_addr(void)
-{
- byte *mod, *p;
- uint32 peh, add;
- uint16 oph;
-
- mod = stdcall(GetModuleHandle, 1, 0);
- peh = *(uint32*)(mod+0x3c);
- p = mod+peh+4;
- oph = *(uint16*)(p+0x10);
- p += 0x14+oph;
- while(strcmp(p, (byte*)".symdat"))
- p += 40;
- add = *(uint32*)(p+0x0c);
- return mod+add;
-}
-
// Thread-safe allocation of an event.
static void
initevent(void **pevent)
{
void *event;
- event = stdcall(CreateEvent, 4, 0, 0, 0, 0);
- if(!casp(pevent, 0, event)) {
+ event = runtime·stdcall(runtime·CreateEvent, 4, 0, 0, 0, 0);
+ if(!runtime·casp(pevent, 0, event)) {
// Someone else filled it in. Use theirs.
- stdcall(CloseHandle, 1, event);
+ runtime·stdcall(runtime·CloseHandle, 1, event);
}
}
@@ -186,106 +122,96 @@ eventlock(Lock *l)
if(l->event == 0)
initevent(&l->event);
- if(xadd(&l->key, 1) > 1) // someone else has it; wait
- stdcall(WaitForSingleObject, 2, l->event, -1);
+ if(runtime·xadd(&l->key, 1) > 1) // someone else has it; wait
+ runtime·stdcall(runtime·WaitForSingleObject, 2, l->event, -1);
}
static void
eventunlock(Lock *l)
{
- if(xadd(&l->key, -1) > 0) // someone else is waiting
- stdcall(SetEvent, 1, l->event);
+ if(runtime·xadd(&l->key, -1) > 0) // someone else is waiting
+ runtime·stdcall(runtime·SetEvent, 1, l->event);
}
void
-lock(Lock *l)
+runtime·lock(Lock *l)
{
if(m->locks < 0)
- throw("lock count");
+ runtime·throw("lock count");
m->locks++;
eventlock(l);
}
void
-unlock(Lock *l)
+runtime·unlock(Lock *l)
{
m->locks--;
if(m->locks < 0)
- throw("lock count");
+ runtime·throw("lock count");
eventunlock(l);
}
void
-destroylock(Lock *l)
+runtime·destroylock(Lock *l)
{
if(l->event != 0)
- stdcall(CloseHandle, 1, l->event);
+ runtime·stdcall(runtime·CloseHandle, 1, l->event);
}
void
-noteclear(Note *n)
+runtime·noteclear(Note *n)
{
eventlock(&n->lock);
}
void
-notewakeup(Note *n)
+runtime·notewakeup(Note *n)
{
eventunlock(&n->lock);
}
void
-notesleep(Note *n)
+runtime·notesleep(Note *n)
{
eventlock(&n->lock);
eventunlock(&n->lock); // Let other sleepers find out too.
}
void
-newosproc(M *m, G *g, void *stk, void (*fn)(void))
+runtime·newosproc(M *m, G *g, void *stk, void (*fn)(void))
{
- struct {
- void *args;
- void *event_handle;
- } param = { &m };
- extern uint32 threadstart(void *p);
-
- USED(g, stk, fn);
- param.event_handle = stdcall(CreateEvent, 4, 0, 0, 0, 0);
- stdcall(CreateThread, 6, 0, 0, threadstart, &param, 0, 0);
- stdcall(WaitForSingleObject, 2, param.event_handle, -1);
- stdcall(CloseHandle, 1, param.event_handle);
+ 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);
}
// Called to initialize a new m (including the bootstrap m).
void
-minit(void)
+runtime·minit(void)
{
}
// Calling stdcall on os stack.
#pragma textflag 7
void *
-stdcall(void *fn, int32 count, ...)
+runtime·stdcall(void *fn, int32 count, ...)
{
- uintptr *a;
- StdcallParams p;
-
- p.fn = fn;
- a = (uintptr*)(&count + 1);
- while(count > 0) {
- count--;
- p.args[count] = a[count];
- }
- syscall(&p);
- return (void*)(p.r);
+ return runtime·stdcall_raw(fn, count, (uintptr*)(&count + 1));
}
void
-call_syscall(void *args)
-{
- StdcallParams *p = (StdcallParams*)args;
- p->r = (uintptr)stdcall_raw((void*)p->fn, p->args[0], p->args[1], p->args[2], p->args[3], p->args[4], p->args[5], p->args[6], p->args[7], p->args[8]);
- p->err = (uintptr)stdcall_raw(GetLastError);
- return;
+runtime·syscall(StdcallParams *p)
+{
+ uintptr a;
+
+ runtime·entersyscall();
+ // TODO(brainman): Move calls to SetLastError and GetLastError
+ // to stdcall_raw to speed up syscall.
+ a = 0;
+ runtime·stdcall_raw(runtime·SetLastError, 1, &a);
+ p->r = (uintptr)runtime·stdcall_raw((void*)p->fn, p->n, p->args);
+ p->err = (uintptr)runtime·stdcall_raw(runtime·GetLastError, 0, &a);
+ runtime·exitsyscall();
}