summaryrefslogtreecommitdiff
path: root/src/pkg/runtime/windows/386
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/runtime/windows/386')
-rw-r--r--src/pkg/runtime/windows/386/defs.h81
-rw-r--r--src/pkg/runtime/windows/386/rt0.s14
-rw-r--r--src/pkg/runtime/windows/386/signal.c98
-rw-r--r--src/pkg/runtime/windows/386/sys.s256
4 files changed, 449 insertions, 0 deletions
diff --git a/src/pkg/runtime/windows/386/defs.h b/src/pkg/runtime/windows/386/defs.h
new file mode 100644
index 000000000..49fc19504
--- /dev/null
+++ b/src/pkg/runtime/windows/386/defs.h
@@ -0,0 +1,81 @@
+// c:\Users\Hector\Code\go\bin\godefs.exe 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;
+ uint32 ExceptionInformation[15];
+};
+
+typedef struct FloatingSaveArea FloatingSaveArea;
+struct FloatingSaveArea {
+ uint32 ControlWord;
+ uint32 StatusWord;
+ uint32 TagWord;
+ uint32 ErrorOffset;
+ uint32 ErrorSelector;
+ uint32 DataOffset;
+ uint32 DataSelector;
+ uint8 RegisterArea[80];
+ uint32 Cr0NpxState;
+};
+
+typedef struct Context Context;
+struct Context {
+ uint32 ContextFlags;
+ uint32 Dr0;
+ uint32 Dr1;
+ uint32 Dr2;
+ uint32 Dr3;
+ uint32 Dr6;
+ uint32 Dr7;
+ FloatingSaveArea FloatSave;
+ uint32 SegGs;
+ uint32 SegFs;
+ uint32 SegEs;
+ uint32 SegDs;
+ uint32 Edi;
+ uint32 Esi;
+ uint32 Ebx;
+ uint32 Edx;
+ uint32 Ecx;
+ uint32 Eax;
+ uint32 Ebp;
+ uint32 Eip;
+ uint32 SegCs;
+ uint32 EFlags;
+ uint32 Esp;
+ uint32 SegSs;
+ uint8 ExtendedRegisters[512];
+};
+#pragma pack off
diff --git a/src/pkg/runtime/windows/386/rt0.s b/src/pkg/runtime/windows/386/rt0.s
new file mode 100644
index 000000000..3b023de2f
--- /dev/null
+++ b/src/pkg/runtime/windows/386/rt0.s
@@ -0,0 +1,14 @@
+// Copyright 2009 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.
+
+TEXT _rt0_386_windows(SB),7,$0
+ // Set up SEH frame for bootstrap m
+ PUSHL $runtime·sigtramp(SB)
+ PUSHL 0(FS)
+ MOVL SP, 0(FS)
+
+ JMP _rt0_386(SB)
+
+DATA runtime·iswindows(SB)/4, $1
+GLOBL runtime·iswindows(SB), $4
diff --git a/src/pkg/runtime/windows/386/signal.c b/src/pkg/runtime/windows/386/signal.c
new file mode 100644
index 000000000..cc6a2302f
--- /dev/null
+++ b/src/pkg/runtime/windows/386/signal.c
@@ -0,0 +1,98 @@
+// Copyright 2009 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·dumpregs(Context *r)
+{
+ runtime·printf("eax %x\n", r->Eax);
+ runtime·printf("ebx %x\n", r->Ebx);
+ runtime·printf("ecx %x\n", r->Ecx);
+ runtime·printf("edx %x\n", r->Edx);
+ runtime·printf("edi %x\n", r->Edi);
+ runtime·printf("esi %x\n", r->Esi);
+ runtime·printf("ebp %x\n", r->Ebp);
+ runtime·printf("esp %x\n", r->Esp);
+ runtime·printf("eip %x\n", r->Eip);
+ runtime·printf("eflags %x\n", r->EFlags);
+ runtime·printf("cs %x\n", r->SegCs);
+ runtime·printf("fs %x\n", r->SegFs);
+ runtime·printf("gs %x\n", r->SegGs);
+}
+
+void
+runtime·initsig(int32)
+{
+ runtime·siginit();
+}
+
+uint32
+runtime·sighandler(ExceptionRecord *info, void *frame, Context *r)
+{
+ uintptr *sp;
+ G *gp;
+
+ USED(frame);
+
+ switch(info->ExceptionCode) {
+ case EXCEPTION_BREAKPOINT:
+ r->Eip--; // because 8l generates 2 bytes for INT3
+ return 1;
+ }
+
+ if((gp = m->curg) != nil && runtime·issigpanic(info->ExceptionCode)) {
+ // Make it look like a call to the signal func.
+ // Have to pass arguments out of band since
+ // augmenting the stack frame would break
+ // the unwinding code.
+ gp->sig = info->ExceptionCode;
+ gp->sigcode0 = info->ExceptionInformation[0];
+ gp->sigcode1 = info->ExceptionInformation[1];
+ gp->sigpc = r->Eip;
+
+ // Only push runtime·sigpanic if r->eip != 0.
+ // If r->eip == 0, probably panicked because of a
+ // call to a nil func. Not pushing that onto sp will
+ // make the trace look like a call to runtime·sigpanic instead.
+ // (Otherwise the trace will end at runtime·sigpanic and we
+ // won't get to see who faulted.)
+ if(r->Eip != 0) {
+ sp = (uintptr*)r->Esp;
+ *--sp = r->Eip;
+ r->Esp = (uintptr)sp;
+ }
+ r->Eip = (uintptr)runtime·sigpanic;
+ return 0;
+ }
+
+ if(runtime·panicking) // traceback already printed
+ runtime·exit(2);
+ runtime·panicking = 1;
+
+ runtime·printf("Exception %x %p %p\n", info->ExceptionCode,
+ info->ExceptionInformation[0], info->ExceptionInformation[1]);
+
+ runtime·printf("PC=%x\n", r->Eip);
+ runtime·printf("\n");
+
+ if(runtime·gotraceback()){
+ runtime·traceback((void*)r->Eip, (void*)r->Esp, 0, m->curg);
+ runtime·tracebackothers(m->curg);
+ runtime·dumpregs(r);
+ }
+
+ runtime·exit(2);
+ return 0;
+}
+
+void
+runtime·resetcpuprofiler(int32 hz)
+{
+ // TODO: Enable profiling interrupts.
+
+ m->profilehz = hz;
+}
diff --git a/src/pkg/runtime/windows/386/sys.s b/src/pkg/runtime/windows/386/sys.s
new file mode 100644
index 000000000..703f77d55
--- /dev/null
+++ b/src/pkg/runtime/windows/386/sys.s
@@ -0,0 +1,256 @@
+// Copyright 2009 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 "386/asm.h"
+
+// void *stdcall_raw(void *fn, int32 count, uintptr *args)
+TEXT runtime·stdcall_raw(SB),7,$0
+ // Copy arguments from stack.
+ MOVL fn+0(FP), AX
+ MOVL count+4(FP), CX // words
+ MOVL args+8(FP), BP
+
+ // Switch to m->g0 if needed.
+ get_tls(DI)
+ MOVL m(DI), DX
+ MOVL m_g0(DX), SI
+ CMPL g(DI), SI
+ MOVL SP, BX
+ JEQ 2(PC)
+ MOVL (g_sched+gobuf_sp)(SI), SP
+ PUSHL BX
+ PUSHL g(DI)
+ MOVL SI, g(DI)
+
+ // Copy args to new stack.
+ 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)
+ POPL g(DI)
+ POPL SP
+
+ // Someday the convention will be D is always cleared.
+ CLD
+
+ RET
+
+// faster get/set last error
+TEXT runtime·getlasterror(SB),7,$0
+ MOVL 0x34(FS), AX
+ RET
+
+TEXT runtime·setlasterror(SB),7,$0
+ MOVL err+0(FP), AX
+ MOVL AX, 0x34(FS)
+ RET
+
+TEXT runtime·sigtramp(SB),7,$0
+ PUSHL BP // cdecl
+ PUSHL BX
+ PUSHL SI
+ PUSHL DI
+ PUSHL 0(FS)
+ CALL runtime·sigtramp1(SB)
+ POPL 0(FS)
+ POPL DI
+ POPL SI
+ POPL BX
+ POPL BP
+ RET
+
+TEXT runtime·sigtramp1(SB),0,$16-40
+ // unwinding?
+ MOVL info+24(FP), BX
+ MOVL 4(BX), CX // exception flags
+ ANDL $6, CX
+ MOVL $1, AX
+ JNZ sigdone
+
+ // place ourselves at the top of the SEH chain to
+ // ensure SEH frames lie within thread stack bounds
+ MOVL frame+28(FP), CX // our SEH frame
+ MOVL CX, 0(FS)
+
+ // copy arguments for call to sighandler
+ MOVL BX, 0(SP)
+ MOVL CX, 4(SP)
+ MOVL context+32(FP), BX
+ MOVL BX, 8(SP)
+ MOVL dispatcher+36(FP), BX
+ MOVL BX, 12(SP)
+
+ CALL runtime·sighandler(SB)
+ TESTL AX, AX
+ JZ sigdone
+
+ // call windows default handler early
+ MOVL 4(SP), BX // our SEH frame
+ MOVL 0(BX), BX // SEH frame of default handler
+ MOVL BX, 4(SP) // set establisher frame
+ CALL 4(BX)
+
+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_fflag+4), SP // at least space for m_fflag
+ 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
+// as required by windows callback convention.
+// AX = address of go func we need to call
+// 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 DI
+ PUSHL SI
+ PUSHL BP
+ PUSHL BX
+
+ // set up SEH frame again
+ PUSHL $runtime·sigtramp(SB)
+ PUSHL 0(FS)
+ MOVL SP, 0(FS)
+
+ // callback parameters
+ PUSHL DX
+ PUSHL CX
+ PUSHL AX
+
+ CLD
+
+ CALL runtime·cgocallback(SB)
+
+ POPL AX
+ POPL CX
+ POPL DX
+
+ // pop SEH frame
+ POPL 0(FS)
+ POPL BX
+
+ // restore registers as required for windows callback
+ POPL BX
+ POPL BP
+ POPL SI
+ POPL DI
+
+ CLD
+
+ MOVL -4(CX)(DX*1), AX
+ POPL -4(CX)(DX*1)
+ RET
+
+// void tstart(M *newm);
+TEXT runtime·tstart(SB),7,$0
+ MOVL newm+4(SP), CX // m
+ MOVL m_g0(CX), DX // g
+
+ // Set up SEH frame
+ PUSHL $runtime·sigtramp(SB)
+ PUSHL 0(FS)
+ MOVL SP, 0(FS)
+
+ // Layout new m scheduler stack on os stack.
+ MOVL SP, AX
+ MOVL AX, g_stackbase(DX)
+ SUBL $(64*1024), 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)
+
+ // Someday the convention will be D is always cleared.
+ CLD
+
+ CALL runtime·stackcheck(SB) // clobbers AX,CX
+
+ CALL runtime·mstart(SB)
+
+ // Pop SEH frame
+ MOVL 0(FS), SP
+ POPL 0(FS)
+ POPL CX
+
+ 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 runtime·setldt(SB),7,$0
+ MOVL address+4(FP), CX
+ MOVL CX, 0x2c(FS)
+ RET