]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: move Windows types and consts to internal/runtime/syscall/windows
authorqmuntal <quimmuntal@gmail.com>
Thu, 21 Aug 2025 19:23:03 +0000 (21:23 +0200)
committerQuim Muntal <quimmuntal@gmail.com>
Fri, 12 Sep 2025 19:00:33 +0000 (12:00 -0700)
This CL doesn't change any behavior, it just moves code around to reduce
the size of the runtime package and remove some duplicated symbols.

Updates #51087.

Cq-Include-Trybots: luci.golang.try:gotip-windows-arm64
Change-Id: I3d3e5f214f045c24fb5d4050d56e7b0822a6e4b5
Reviewed-on: https://go-review.googlesource.com/c/go/+/698098
Reviewed-by: Cherry Mui <cherryyz@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
19 files changed:
src/internal/runtime/syscall/windows/defs_windows.go [new file with mode: 0644]
src/internal/runtime/syscall/windows/defs_windows_386.go [new file with mode: 0644]
src/internal/runtime/syscall/windows/defs_windows_amd64.go [new file with mode: 0644]
src/internal/runtime/syscall/windows/defs_windows_arm64.go [new file with mode: 0644]
src/internal/syscall/windows/memory_windows.go [deleted file]
src/internal/syscall/windows/types_windows.go
src/runtime/defs_windows.go [deleted file]
src/runtime/defs_windows_386.go [deleted file]
src/runtime/defs_windows_amd64.go [deleted file]
src/runtime/defs_windows_arm64.go [deleted file]
src/runtime/export_windows_test.go
src/runtime/netpoll_windows.go
src/runtime/os_windows.go
src/runtime/os_windows_arm64.go
src/runtime/runtime-seh_windows_test.go
src/runtime/signal_windows.go
src/runtime/signal_windows_386.go [new file with mode: 0644]
src/runtime/signal_windows_amd64.go [new file with mode: 0644]
src/runtime/signal_windows_arm64.go [new file with mode: 0644]

diff --git a/src/internal/runtime/syscall/windows/defs_windows.go b/src/internal/runtime/syscall/windows/defs_windows.go
new file mode 100644 (file)
index 0000000..6b10980
--- /dev/null
@@ -0,0 +1,159 @@
+// Copyright 2025 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.
+
+// Architecture-independent definitions.
+
+package windows
+
+// Pseudo handles.
+const (
+       CurrentProcess = ^uintptr(0) // -1 = current process
+       CurrentThread  = ^uintptr(1) // -2 = current thread
+)
+
+const INVALID_HANDLE_VALUE = ^uintptr(0)
+
+const DWORD_MAX = 0xffffffff
+
+const (
+       PROT_NONE  = 0
+       PROT_READ  = 1
+       PROT_WRITE = 2
+       PROT_EXEC  = 4
+)
+
+const (
+       MAP_ANON    = 1
+       MAP_PRIVATE = 2
+)
+
+const DUPLICATE_SAME_ACCESS = 0x2
+
+const THREAD_PRIORITY_HIGHEST = 0x2
+
+const (
+       SIGINT  = 0x2
+       SIGTERM = 0xF
+)
+
+const (
+       CTRL_C_EVENT        = 0x0
+       CTRL_BREAK_EVENT    = 0x1
+       CTRL_CLOSE_EVENT    = 0x2
+       CTRL_LOGOFF_EVENT   = 0x5
+       CTRL_SHUTDOWN_EVENT = 0x6
+)
+
+const (
+       EXCEPTION_ACCESS_VIOLATION     = 0xc0000005
+       EXCEPTION_IN_PAGE_ERROR        = 0xc0000006
+       EXCEPTION_BREAKPOINT           = 0x80000003
+       EXCEPTION_ILLEGAL_INSTRUCTION  = 0xc000001d
+       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
+)
+
+const (
+       SEM_FAILCRITICALERRORS = 0x0001
+       SEM_NOGPFAULTERRORBOX  = 0x0002
+       SEM_NOOPENFILEERRORBOX = 0x8000
+)
+
+const WER_FAULT_REPORTING_NO_UI = 0x0020
+
+const INFINITE = 0xffffffff
+
+const WAIT_TIMEOUT = 258
+
+const FAIL_FAST_GENERATE_EXCEPTION_ADDRESS = 0x1
+
+const (
+       EXCEPTION_CONTINUE_EXECUTION  = -0x1
+       EXCEPTION_CONTINUE_SEARCH     = 0x0
+       EXCEPTION_CONTINUE_SEARCH_SEH = 0x1
+)
+
+const CREATE_WAITABLE_TIMER_HIGH_RESOLUTION = 0x00000002
+
+const (
+       SYNCHRONIZE        = 0x00100000
+       TIMER_QUERY_STATE  = 0x0001
+       TIMER_MODIFY_STATE = 0x0002
+)
+
+// https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/596a1078-e883-4972-9bbc-49e60bebca55
+const (
+       STATUS_SUCCESS   = 0x00000000
+       STATUS_PENDING   = 0x00000103
+       STATUS_CANCELLED = 0xC0000120
+)
+
+// https://learn.microsoft.com/en-us/windows/win32/api/sysinfoapi/ns-sysinfoapi-system_info
+type SystemInfo struct {
+       ProcessorArchitecture     uint16
+       Reserved                  uint16
+       PageSize                  uint32
+       MinimumApplicationAddress *byte
+       MaximumApplicationAddress *byte
+       ActiveProcessorMask       uintptr
+       NumberOfProcessors        uint32
+       ProcessorType             uint32
+       AllocationGranularity     uint32
+       ProcessorLevel            uint16
+       ProcessorRevision         uint16
+}
+
+// https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-exception_pointers
+type ExceptionPointers struct {
+       Record  *ExceptionRecord
+       Context *Context
+}
+
+// https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-exception_record
+type ExceptionRecord struct {
+       ExceptionCode        uint32
+       ExceptionFlags       uint32
+       ExceptionRecord      *ExceptionRecord
+       ExceptionAddress     uintptr
+       NumberParameters     uint32
+       ExceptionInformation [15]uintptr
+}
+
+type Handle uintptr
+
+// https://learn.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-overlapped
+type Overlapped struct {
+       Internal     uintptr
+       InternalHigh uintptr
+       Offset       uint32
+       OffsetHigh   uint32
+       HEvent       Handle
+}
+
+// https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-memory_basic_information
+type MemoryBasicInformation struct {
+       BaseAddress       uintptr
+       AllocationBase    uintptr
+       AllocationProtect uint32
+       PartitionId       uint16
+       RegionSize        uintptr
+       State             uint32
+       Protect           uint32
+       Type              uint32
+}
+
+// https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/ns-wdm-_osversioninfow
+type OSVERSIONINFOW struct {
+       OSVersionInfoSize uint32
+       MajorVersion      uint32
+       MinorVersion      uint32
+       BuildNumber       uint32
+       PlatformID        uint32
+       CSDVersion        [128]uint16
+}
diff --git a/src/internal/runtime/syscall/windows/defs_windows_386.go b/src/internal/runtime/syscall/windows/defs_windows_386.go
new file mode 100644 (file)
index 0000000..6c2271e
--- /dev/null
@@ -0,0 +1,79 @@
+// Copyright 2025 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.
+
+package windows
+
+import (
+       "internal/goarch"
+       "unsafe"
+)
+
+const CONTEXT_CONTROL = 0x10001
+
+type FloatingSaveArea struct {
+       ControlWord   uint32
+       StatusWord    uint32
+       TagWord       uint32
+       ErrorOffset   uint32
+       ErrorSelector uint32
+       DataOffset    uint32
+       DataSelector  uint32
+       RegisterArea  [80]uint8
+       Cr0NpxState   uint32
+}
+
+type Context struct {
+       ContextFlags      uint32
+       Dr0               uint32
+       Dr1               uint32
+       Dr2               uint32
+       Dr3               uint32
+       Dr6               uint32
+       Dr7               uint32
+       FloatingSaveArea  FloatingSaveArea
+       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             uint32
+       ExtendedRegisters [512]uint8
+}
+
+func (c *Context) PC() uintptr { return uintptr(c.Eip) }
+func (c *Context) SP() uintptr { return uintptr(c.Esp) }
+
+// 386 does not have link register, so this returns 0.
+func (c *Context) LR() uintptr     { return 0 }
+func (c *Context) SetLR(x uintptr) {}
+
+func (c *Context) SetPC(x uintptr) { c.Eip = uint32(x) }
+func (c *Context) SetSP(x uintptr) { c.Esp = uint32(x) }
+
+// 386 does not have frame pointer register.
+func (c *Context) SetFP(x uintptr) {}
+
+func (c *Context) PushCall(targetPC, resumePC uintptr) {
+       sp := c.SP() - goarch.StackAlign
+       *(*uintptr)(unsafe.Pointer(sp)) = resumePC
+       c.SetSP(sp)
+       c.SetPC(targetPC)
+}
+
+// DISPATCHER_CONTEXT is not defined on 386.
+type DISPATCHER_CONTEXT struct{}
+
+func (c *DISPATCHER_CONTEXT) Ctx() *Context {
+       return nil
+}
diff --git a/src/internal/runtime/syscall/windows/defs_windows_amd64.go b/src/internal/runtime/syscall/windows/defs_windows_amd64.go
new file mode 100644 (file)
index 0000000..0181244
--- /dev/null
@@ -0,0 +1,99 @@
+// Copyright 2025 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.
+
+package windows
+
+import (
+       "internal/goarch"
+       "unsafe"
+)
+
+const CONTEXT_CONTROL = 0x100001
+
+type M128 struct {
+       Low  uint64
+       High int64
+}
+
+type Context struct {
+       P1Home               uint64
+       P2Home               uint64
+       P3Home               uint64
+       P4Home               uint64
+       P5Home               uint64
+       P6Home               uint64
+       ContextFlags         uint32
+       MxCsr                uint32
+       SegCs                uint16
+       SegDs                uint16
+       SegEs                uint16
+       SegFs                uint16
+       SegGs                uint16
+       SegSs                uint16
+       EFlags               uint32
+       DR0                  uint64
+       DR1                  uint64
+       DR2                  uint64
+       DR3                  uint64
+       DR6                  uint64
+       DR7                  uint64
+       Rax                  uint64
+       Rcx                  uint64
+       Rdx                  uint64
+       Rbx                  uint64
+       Rsp                  uint64
+       Rbp                  uint64
+       Rsi                  uint64
+       Rdi                  uint64
+       R8                   uint64
+       R9                   uint64
+       R10                  uint64
+       R11                  uint64
+       R12                  uint64
+       R13                  uint64
+       R14                  uint64
+       R15                  uint64
+       Rip                  uint64
+       _                    [512]byte
+       VectorRegister       [26]M128
+       VectorControl        uint64
+       DebugControl         uint64
+       LastBranchToRip      uint64
+       LastBranchFromRip    uint64
+       LastExceptionToRip   uint64
+       LastExceptionFromRip uint64
+}
+
+func (c *Context) PC() uintptr { return uintptr(c.Rip) }
+func (c *Context) SP() uintptr { return uintptr(c.Rsp) }
+
+// AMD64 does not have link register, so this returns 0.
+func (c *Context) LR() uintptr     { return 0 }
+func (c *Context) SetLR(x uintptr) {}
+
+func (c *Context) SetPC(x uintptr) { c.Rip = uint64(x) }
+func (c *Context) SetSP(x uintptr) { c.Rsp = uint64(x) }
+func (c *Context) SetFP(x uintptr) { c.Rbp = uint64(x) }
+
+func (c *Context) PushCall(targetPC, resumePC uintptr) {
+       sp := c.SP() - goarch.StackAlign
+       *(*uintptr)(unsafe.Pointer(sp)) = resumePC
+       c.SetSP(sp)
+       c.SetPC(targetPC)
+}
+
+type DISPATCHER_CONTEXT struct {
+       ControlPc        uint64
+       ImageBase        uint64
+       FunctionEntry    uintptr
+       EstablisherFrame uint64
+       TargetIp         uint64
+       Context          *Context
+       LanguageHandler  uintptr
+       HandlerData      uintptr
+}
+
+func (c *DISPATCHER_CONTEXT) Ctx() *Context {
+       return c.Context
+}
diff --git a/src/internal/runtime/syscall/windows/defs_windows_arm64.go b/src/internal/runtime/syscall/windows/defs_windows_arm64.go
new file mode 100644 (file)
index 0000000..c05573a
--- /dev/null
@@ -0,0 +1,75 @@
+// Copyright 2025 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.
+
+package windows
+
+import (
+       "internal/goarch"
+       "unsafe"
+)
+
+// NOTE(rsc): CONTEXT_CONTROL is actually 0x400001 and should include PC, SP, and LR.
+// However, empirically, LR doesn't come along on Windows 10
+// unless you also set CONTEXT_INTEGER (0x400002).
+// Without LR, we skip over the next-to-bottom function in profiles
+// when the bottom function is frameless.
+// So we set both here, to make a working CONTEXT_CONTROL.
+const CONTEXT_CONTROL = 0x400003
+
+type Neon128 struct {
+       Low  uint64
+       High int64
+}
+
+// See https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-arm64_nt_context
+type Context struct {
+       ContextFlags uint32
+       Cpsr         uint32
+       X            [31]uint64 // fp is x[29], lr is x[30]
+       XSp          uint64
+       Pc           uint64
+       V            [32]Neon128
+       Fpcr         uint32
+       Fpsr         uint32
+       Bcr          [8]uint32
+       Bvr          [8]uint64
+       Wcr          [2]uint32
+       Wvr          [2]uint64
+}
+
+func (c *Context) PC() uintptr { return uintptr(c.Pc) }
+func (c *Context) SP() uintptr { return uintptr(c.XSp) }
+func (c *Context) LR() uintptr { return uintptr(c.X[30]) }
+
+func (c *Context) SetPC(x uintptr) { c.Pc = uint64(x) }
+func (c *Context) SetSP(x uintptr) { c.XSp = uint64(x) }
+func (c *Context) SetLR(x uintptr) { c.X[30] = uint64(x) }
+func (c *Context) SetFP(x uintptr) { c.X[29] = uint64(x) }
+
+func (c *Context) PushCall(targetPC, resumePC uintptr) {
+       // Push LR. The injected call is responsible
+       // for restoring LR. gentraceback is aware of
+       // this extra slot. See sigctxt.pushCall in
+       // signal_arm64.go.
+       sp := c.SP() - goarch.StackAlign
+       c.SetSP(sp)
+       *(*uint64)(unsafe.Pointer(sp)) = uint64(c.LR())
+       c.SetLR(resumePC)
+       c.SetPC(targetPC)
+}
+
+type DISPATCHER_CONTEXT struct {
+       ControlPc        uint64
+       ImageBase        uint64
+       FunctionEntry    uintptr
+       EstablisherFrame uint64
+       TargetIp         uint64
+       Context          *Context
+       LanguageHandler  uintptr
+       HandlerData      uintptr
+}
+
+func (c *DISPATCHER_CONTEXT) Ctx() *Context {
+       return c.Context
+}
diff --git a/src/internal/syscall/windows/memory_windows.go b/src/internal/syscall/windows/memory_windows.go
deleted file mode 100644 (file)
index 8fb34cf..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2017 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.
-
-package windows
-
-type MemoryBasicInformation struct {
-       // A pointer to the base address of the region of pages.
-       BaseAddress uintptr
-       // A pointer to the base address of a range of pages allocated by the VirtualAlloc function.
-       // The page pointed to by the BaseAddress member is contained within this allocation range.
-       AllocationBase uintptr
-       // The memory protection option when the region was initially allocated
-       AllocationProtect uint32
-       PartitionId       uint16
-       // The size of the region beginning at the base address in which all pages have identical attributes, in bytes.
-       RegionSize uintptr
-       // The state of the pages in the region.
-       State uint32
-       // The access protection of the pages in the region.
-       Protect uint32
-       // The type of pages in the region.
-       Type uint32
-}
index 33767391434a32fd603796b6fb7ab56951e1aa9f..fe9e41f2f866bfdb8db29edbf24151cac5c8865e 100644 (file)
@@ -5,6 +5,7 @@
 package windows
 
 import (
+       "internal/runtime/syscall/windows"
        "syscall"
        "unsafe"
 )
@@ -276,3 +277,7 @@ type FILE_COMPLETION_INFORMATION struct {
 // https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-osversioninfoexa
 // https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/ns-wdm-_osversioninfoexw
 const VER_NT_WORKSTATION = 0x0000001
+
+type MemoryBasicInformation = windows.MemoryBasicInformation
+
+type Context = windows.Context
diff --git a/src/runtime/defs_windows.go b/src/runtime/defs_windows.go
deleted file mode 100644 (file)
index 2f09afb..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-// 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.
-
-// Windows architecture-independent definitions.
-
-package runtime
-
-const (
-       _PROT_NONE  = 0
-       _PROT_READ  = 1
-       _PROT_WRITE = 2
-       _PROT_EXEC  = 4
-
-       _MAP_ANON    = 1
-       _MAP_PRIVATE = 2
-
-       _DUPLICATE_SAME_ACCESS   = 0x2
-       _THREAD_PRIORITY_HIGHEST = 0x2
-
-       _SIGINT              = 0x2
-       _SIGTERM             = 0xF
-       _CTRL_C_EVENT        = 0x0
-       _CTRL_BREAK_EVENT    = 0x1
-       _CTRL_CLOSE_EVENT    = 0x2
-       _CTRL_LOGOFF_EVENT   = 0x5
-       _CTRL_SHUTDOWN_EVENT = 0x6
-
-       _EXCEPTION_ACCESS_VIOLATION     = 0xc0000005
-       _EXCEPTION_IN_PAGE_ERROR        = 0xc0000006
-       _EXCEPTION_BREAKPOINT           = 0x80000003
-       _EXCEPTION_ILLEGAL_INSTRUCTION  = 0xc000001d
-       _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
-
-       _INFINITE     = 0xffffffff
-       _WAIT_TIMEOUT = 0x102
-
-       _EXCEPTION_CONTINUE_EXECUTION  = -0x1
-       _EXCEPTION_CONTINUE_SEARCH     = 0x0
-       _EXCEPTION_CONTINUE_SEARCH_SEH = 0x1
-)
-
-type systeminfo struct {
-       anon0                       [4]byte
-       dwpagesize                  uint32
-       lpminimumapplicationaddress *byte
-       lpmaximumapplicationaddress *byte
-       dwactiveprocessormask       uintptr
-       dwnumberofprocessors        uint32
-       dwprocessortype             uint32
-       dwallocationgranularity     uint32
-       wprocessorlevel             uint16
-       wprocessorrevision          uint16
-}
-
-type exceptionpointers struct {
-       record  *exceptionrecord
-       context *context
-}
-
-type exceptionrecord struct {
-       exceptioncode        uint32
-       exceptionflags       uint32
-       exceptionrecord      *exceptionrecord
-       exceptionaddress     uintptr
-       numberparameters     uint32
-       exceptioninformation [15]uintptr
-}
-
-type overlapped struct {
-       internal     uintptr
-       internalhigh uintptr
-       anon0        [8]byte
-       hevent       *byte
-}
-
-type memoryBasicInformation struct {
-       baseAddress       uintptr
-       allocationBase    uintptr
-       allocationProtect uint32
-       regionSize        uintptr
-       state             uint32
-       protect           uint32
-       type_             uint32
-}
-
-// https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/ns-wdm-_osversioninfow
-type _OSVERSIONINFOW struct {
-       osVersionInfoSize uint32
-       majorVersion      uint32
-       minorVersion      uint32
-       buildNumber       uint32
-       platformId        uint32
-       csdVersion        [128]uint16
-}
diff --git a/src/runtime/defs_windows_386.go b/src/runtime/defs_windows_386.go
deleted file mode 100644 (file)
index 12cd442..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-// 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.
-
-package runtime
-
-import (
-       "internal/goarch"
-       "unsafe"
-)
-
-const _CONTEXT_CONTROL = 0x10001
-
-type floatingsavearea struct {
-       controlword   uint32
-       statusword    uint32
-       tagword       uint32
-       erroroffset   uint32
-       errorselector uint32
-       dataoffset    uint32
-       dataselector  uint32
-       registerarea  [80]uint8
-       cr0npxstate   uint32
-}
-
-type context struct {
-       contextflags      uint32
-       dr0               uint32
-       dr1               uint32
-       dr2               uint32
-       dr3               uint32
-       dr6               uint32
-       dr7               uint32
-       floatsave         floatingsavearea
-       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             uint32
-       extendedregisters [512]uint8
-}
-
-func (c *context) ip() uintptr { return uintptr(c.eip) }
-func (c *context) sp() uintptr { return uintptr(c.esp) }
-
-// 386 does not have link register, so this returns 0.
-func (c *context) lr() uintptr      { return 0 }
-func (c *context) set_lr(x uintptr) {}
-
-func (c *context) set_ip(x uintptr) { c.eip = uint32(x) }
-func (c *context) set_sp(x uintptr) { c.esp = uint32(x) }
-
-// 386 does not have frame pointer register.
-func (c *context) set_fp(x uintptr) {}
-
-func (c *context) pushCall(targetPC, resumePC uintptr) {
-       sp := c.sp() - goarch.StackAlign
-       *(*uintptr)(unsafe.Pointer(sp)) = resumePC
-       c.set_sp(sp)
-       c.set_ip(targetPC)
-}
-
-func prepareContextForSigResume(c *context) {
-       c.edx = c.esp
-       c.ecx = c.eip
-}
-
-func dumpregs(r *context) {
-       print("eax     ", hex(r.eax), "\n")
-       print("ebx     ", hex(r.ebx), "\n")
-       print("ecx     ", hex(r.ecx), "\n")
-       print("edx     ", hex(r.edx), "\n")
-       print("edi     ", hex(r.edi), "\n")
-       print("esi     ", hex(r.esi), "\n")
-       print("ebp     ", hex(r.ebp), "\n")
-       print("esp     ", hex(r.esp), "\n")
-       print("eip     ", hex(r.eip), "\n")
-       print("eflags  ", hex(r.eflags), "\n")
-       print("cs      ", hex(r.segcs), "\n")
-       print("fs      ", hex(r.segfs), "\n")
-       print("gs      ", hex(r.seggs), "\n")
-}
-
-// _DISPATCHER_CONTEXT is not defined on 386.
-type _DISPATCHER_CONTEXT struct{}
-
-func (c *_DISPATCHER_CONTEXT) ctx() *context {
-       return nil
-}
diff --git a/src/runtime/defs_windows_amd64.go b/src/runtime/defs_windows_amd64.go
deleted file mode 100644 (file)
index 9bb7ee8..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-// 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.
-
-package runtime
-
-import (
-       "internal/goarch"
-       "unsafe"
-)
-
-const _CONTEXT_CONTROL = 0x100001
-
-type m128a struct {
-       low  uint64
-       high int64
-}
-
-type context struct {
-       p1home               uint64
-       p2home               uint64
-       p3home               uint64
-       p4home               uint64
-       p5home               uint64
-       p6home               uint64
-       contextflags         uint32
-       mxcsr                uint32
-       segcs                uint16
-       segds                uint16
-       seges                uint16
-       segfs                uint16
-       seggs                uint16
-       segss                uint16
-       eflags               uint32
-       dr0                  uint64
-       dr1                  uint64
-       dr2                  uint64
-       dr3                  uint64
-       dr6                  uint64
-       dr7                  uint64
-       rax                  uint64
-       rcx                  uint64
-       rdx                  uint64
-       rbx                  uint64
-       rsp                  uint64
-       rbp                  uint64
-       rsi                  uint64
-       rdi                  uint64
-       r8                   uint64
-       r9                   uint64
-       r10                  uint64
-       r11                  uint64
-       r12                  uint64
-       r13                  uint64
-       r14                  uint64
-       r15                  uint64
-       rip                  uint64
-       anon0                [512]byte
-       vectorregister       [26]m128a
-       vectorcontrol        uint64
-       debugcontrol         uint64
-       lastbranchtorip      uint64
-       lastbranchfromrip    uint64
-       lastexceptiontorip   uint64
-       lastexceptionfromrip uint64
-}
-
-func (c *context) ip() uintptr { return uintptr(c.rip) }
-func (c *context) sp() uintptr { return uintptr(c.rsp) }
-
-// AMD64 does not have link register, so this returns 0.
-func (c *context) lr() uintptr      { return 0 }
-func (c *context) set_lr(x uintptr) {}
-
-func (c *context) set_ip(x uintptr) { c.rip = uint64(x) }
-func (c *context) set_sp(x uintptr) { c.rsp = uint64(x) }
-func (c *context) set_fp(x uintptr) { c.rbp = uint64(x) }
-
-func (c *context) pushCall(targetPC, resumePC uintptr) {
-       sp := c.sp() - goarch.StackAlign
-       *(*uintptr)(unsafe.Pointer(sp)) = resumePC
-       c.set_sp(sp)
-       c.set_ip(targetPC)
-}
-
-func prepareContextForSigResume(c *context) {
-       c.r8 = c.rsp
-       c.r9 = c.rip
-}
-
-func dumpregs(r *context) {
-       print("rax     ", hex(r.rax), "\n")
-       print("rbx     ", hex(r.rbx), "\n")
-       print("rcx     ", hex(r.rcx), "\n")
-       print("rdx     ", hex(r.rdx), "\n")
-       print("rdi     ", hex(r.rdi), "\n")
-       print("rsi     ", hex(r.rsi), "\n")
-       print("rbp     ", hex(r.rbp), "\n")
-       print("rsp     ", hex(r.rsp), "\n")
-       print("r8      ", hex(r.r8), "\n")
-       print("r9      ", hex(r.r9), "\n")
-       print("r10     ", hex(r.r10), "\n")
-       print("r11     ", hex(r.r11), "\n")
-       print("r12     ", hex(r.r12), "\n")
-       print("r13     ", hex(r.r13), "\n")
-       print("r14     ", hex(r.r14), "\n")
-       print("r15     ", hex(r.r15), "\n")
-       print("rip     ", hex(r.rip), "\n")
-       print("rflags  ", hex(r.eflags), "\n")
-       print("cs      ", hex(r.segcs), "\n")
-       print("fs      ", hex(r.segfs), "\n")
-       print("gs      ", hex(r.seggs), "\n")
-}
-
-type _DISPATCHER_CONTEXT struct {
-       controlPc        uint64
-       imageBase        uint64
-       functionEntry    uintptr
-       establisherFrame uint64
-       targetIp         uint64
-       context          *context
-       languageHandler  uintptr
-       handlerData      uintptr
-}
-
-func (c *_DISPATCHER_CONTEXT) ctx() *context {
-       return c.context
-}
diff --git a/src/runtime/defs_windows_arm64.go b/src/runtime/defs_windows_arm64.go
deleted file mode 100644 (file)
index 077bed2..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright 2018 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.
-
-package runtime
-
-import (
-       "internal/goarch"
-       "unsafe"
-)
-
-// NOTE(rsc): _CONTEXT_CONTROL is actually 0x400001 and should include PC, SP, and LR.
-// However, empirically, LR doesn't come along on Windows 10
-// unless you also set _CONTEXT_INTEGER (0x400002).
-// Without LR, we skip over the next-to-bottom function in profiles
-// when the bottom function is frameless.
-// So we set both here, to make a working _CONTEXT_CONTROL.
-const _CONTEXT_CONTROL = 0x400003
-
-type neon128 struct {
-       low  uint64
-       high int64
-}
-
-// See https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-arm64_nt_context
-type context struct {
-       contextflags uint32
-       cpsr         uint32
-       x            [31]uint64 // fp is x[29], lr is x[30]
-       xsp          uint64
-       pc           uint64
-       v            [32]neon128
-       fpcr         uint32
-       fpsr         uint32
-       bcr          [8]uint32
-       bvr          [8]uint64
-       wcr          [2]uint32
-       wvr          [2]uint64
-}
-
-func (c *context) ip() uintptr { return uintptr(c.pc) }
-func (c *context) sp() uintptr { return uintptr(c.xsp) }
-func (c *context) lr() uintptr { return uintptr(c.x[30]) }
-
-func (c *context) set_ip(x uintptr) { c.pc = uint64(x) }
-func (c *context) set_sp(x uintptr) { c.xsp = uint64(x) }
-func (c *context) set_lr(x uintptr) { c.x[30] = uint64(x) }
-func (c *context) set_fp(x uintptr) { c.x[29] = uint64(x) }
-
-func (c *context) pushCall(targetPC, resumePC uintptr) {
-       // Push LR. The injected call is responsible
-       // for restoring LR. gentraceback is aware of
-       // this extra slot. See sigctxt.pushCall in
-       // signal_arm64.go.
-       sp := c.sp() - goarch.StackAlign
-       c.set_sp(sp)
-       *(*uint64)(unsafe.Pointer(sp)) = uint64(c.lr())
-       c.set_lr(resumePC)
-       c.set_ip(targetPC)
-}
-
-func prepareContextForSigResume(c *context) {
-       c.x[0] = c.xsp
-       c.x[1] = c.pc
-}
-
-func dumpregs(r *context) {
-       print("r0   ", hex(r.x[0]), "\n")
-       print("r1   ", hex(r.x[1]), "\n")
-       print("r2   ", hex(r.x[2]), "\n")
-       print("r3   ", hex(r.x[3]), "\n")
-       print("r4   ", hex(r.x[4]), "\n")
-       print("r5   ", hex(r.x[5]), "\n")
-       print("r6   ", hex(r.x[6]), "\n")
-       print("r7   ", hex(r.x[7]), "\n")
-       print("r8   ", hex(r.x[8]), "\n")
-       print("r9   ", hex(r.x[9]), "\n")
-       print("r10  ", hex(r.x[10]), "\n")
-       print("r11  ", hex(r.x[11]), "\n")
-       print("r12  ", hex(r.x[12]), "\n")
-       print("r13  ", hex(r.x[13]), "\n")
-       print("r14  ", hex(r.x[14]), "\n")
-       print("r15  ", hex(r.x[15]), "\n")
-       print("r16  ", hex(r.x[16]), "\n")
-       print("r17  ", hex(r.x[17]), "\n")
-       print("r18  ", hex(r.x[18]), "\n")
-       print("r19  ", hex(r.x[19]), "\n")
-       print("r20  ", hex(r.x[20]), "\n")
-       print("r21  ", hex(r.x[21]), "\n")
-       print("r22  ", hex(r.x[22]), "\n")
-       print("r23  ", hex(r.x[23]), "\n")
-       print("r24  ", hex(r.x[24]), "\n")
-       print("r25  ", hex(r.x[25]), "\n")
-       print("r26  ", hex(r.x[26]), "\n")
-       print("r27  ", hex(r.x[27]), "\n")
-       print("r28  ", hex(r.x[28]), "\n")
-       print("r29  ", hex(r.x[29]), "\n")
-       print("lr   ", hex(r.x[30]), "\n")
-       print("sp   ", hex(r.xsp), "\n")
-       print("pc   ", hex(r.pc), "\n")
-       print("cpsr ", hex(r.cpsr), "\n")
-}
-
-func stackcheck() {
-       // TODO: not implemented on ARM
-}
-
-type _DISPATCHER_CONTEXT struct {
-       controlPc        uint64
-       imageBase        uint64
-       functionEntry    uintptr
-       establisherFrame uint64
-       targetIp         uint64
-       context          *context
-       languageHandler  uintptr
-       handlerData      uintptr
-}
-
-func (c *_DISPATCHER_CONTEXT) ctx() *context {
-       return c.context
-}
index caaf2dae51ce27ff07bb43004077877d95b9b9aa..f44e24bbacf396bb20da9628afdab69c7dec11b0 100644 (file)
@@ -7,7 +7,7 @@
 package runtime
 
 import (
-       "internal/runtime/sys"
+       "internal/runtime/syscall/windows"
        "unsafe"
 )
 
@@ -17,23 +17,11 @@ var (
 )
 
 func NumberOfProcessors() int32 {
-       var info systeminfo
+       var info windows.SystemInfo
        stdcall(_GetSystemInfo, uintptr(unsafe.Pointer(&info)))
-       return int32(info.dwnumberofprocessors)
+       return int32(info.NumberOfProcessors)
 }
 
-type ContextStub struct {
-       context
-}
-
-func (c ContextStub) GetPC() uintptr {
-       return c.ip()
-}
-
-func NewContextStub() *ContextStub {
-       var ctx context
-       ctx.set_ip(sys.GetCallerPC())
-       ctx.set_sp(sys.GetCallerSP())
-       ctx.set_fp(getcallerfp())
-       return &ContextStub{ctx}
+func GetCallerFp() uintptr {
+       return getcallerfp()
 }
index 93137e47097f65a2e921c83b076230b3fbefed3b..db5d043506a78c393fe02f9b2c6629c160bc5ae3 100644 (file)
@@ -7,13 +7,10 @@ package runtime
 import (
        "internal/goarch"
        "internal/runtime/atomic"
+       "internal/runtime/syscall/windows"
        "unsafe"
 )
 
-const _DWORD_MAX = 0xffffffff
-
-const _INVALID_HANDLE_VALUE = ^uintptr(0)
-
 // Sources are used to identify the event that created an overlapped entry.
 // The source values are arbitrary. There is no risk of collision with user
 // defined values because the only way to set the key of an overlapped entry
@@ -59,7 +56,7 @@ func unpackNetpollSource(key uintptr) uint8 {
 // Keep these in sync.
 type pollOperation struct {
        // used by windows
-       _ overlapped
+       _ windows.Overlapped
        // used by netpoll
        pd   *pollDesc
        mode int32
@@ -90,19 +87,19 @@ func pollOperationFromOverlappedEntry(e *overlappedEntry) *pollOperation {
 // https://learn.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-overlapped_entry
 type overlappedEntry struct {
        key      uintptr
-       ov       *overlapped
+       ov       *windows.Overlapped
        internal uintptr
        qty      uint32
 }
 
 var (
-       iocphandle uintptr = _INVALID_HANDLE_VALUE // completion port io handle
+       iocphandle uintptr = windows.INVALID_HANDLE_VALUE // completion port io handle
 
        netpollWakeSig atomic.Uint32 // used to avoid duplicate calls of netpollBreak
 )
 
 func netpollinit() {
-       iocphandle = stdcall(_CreateIoCompletionPort, _INVALID_HANDLE_VALUE, 0, 0, _DWORD_MAX)
+       iocphandle = stdcall(_CreateIoCompletionPort, windows.INVALID_HANDLE_VALUE, 0, 0, windows.DWORD_MAX)
        if iocphandle == 0 {
                println("runtime: CreateIoCompletionPort failed (errno=", getlasterror(), ")")
                throw("runtime: netpollinit failed")
@@ -152,7 +149,7 @@ func netpollBreak() {
 // delay == 0: does not block, just polls
 // delay > 0: block for up to that many nanoseconds
 func netpoll(delay int64) (gList, int32) {
-       if iocphandle == _INVALID_HANDLE_VALUE {
+       if iocphandle == windows.INVALID_HANDLE_VALUE {
                return gList{}, 0
        }
 
@@ -182,7 +179,7 @@ func netpoll(delay int64) (gList, int32) {
                }
        }
        if delay < 0 {
-               wait = _INFINITE
+               wait = windows.INFINITE
        } else if delay == 0 {
                wait = 0
        } else if delay < 1e6 {
@@ -200,7 +197,7 @@ func netpoll(delay int64) (gList, int32) {
        if stdcall(_GetQueuedCompletionStatusEx, iocphandle, uintptr(unsafe.Pointer(&entries[0])), uintptr(n), uintptr(unsafe.Pointer(&n)), uintptr(wait), 0) == 0 {
                mp.blocked = false
                errno := getlasterror()
-               if errno == _WAIT_TIMEOUT {
+               if errno == windows.WAIT_TIMEOUT {
                        return gList{}, 0
                }
                println("runtime: GetQueuedCompletionStatusEx failed (errno=", errno, ")")
@@ -243,11 +240,6 @@ func netpoll(delay int64) (gList, int32) {
 // netpollQueueTimer queues a timer to wake up the poller after the given delay.
 // It returns true if the timer expired during this call.
 func netpollQueueTimer(delay int64) (signaled bool) {
-       const (
-               STATUS_SUCCESS   = 0x00000000
-               STATUS_PENDING   = 0x00000103
-               STATUS_CANCELLED = 0xC0000120
-       )
        mp := getg().m
        // A wait completion packet can only be associated with one timer at a time,
        // so we need to cancel the previous one if it exists. This wouldn't be necessary
@@ -258,11 +250,11 @@ func netpollQueueTimer(delay int64) (signaled bool) {
        // another thread, so defer the cancellation until it is really necessary.
        errno := stdcall(_NtCancelWaitCompletionPacket, mp.waitIocpHandle, 1)
        switch errno {
-       case STATUS_CANCELLED:
+       case windows.STATUS_CANCELLED:
                // STATUS_CANCELLED is returned when the associated timer has already expired,
                // in which automatically cancels the wait completion packet.
                fallthrough
-       case STATUS_SUCCESS:
+       case windows.STATUS_SUCCESS:
                dt := -delay / 100 // relative sleep (negative), 100ns units
                if stdcall(_SetWaitableTimer, mp.waitIocpTimer, uintptr(unsafe.Pointer(&dt)), 0, 0, 0, 0) == 0 {
                        println("runtime: SetWaitableTimer failed; errno=", getlasterror())
@@ -273,7 +265,7 @@ func netpollQueueTimer(delay int64) (signaled bool) {
                        println("runtime: NtAssociateWaitCompletionPacket failed; errno=", errno)
                        throw("runtime: netpoll failed")
                }
-       case STATUS_PENDING:
+       case windows.STATUS_PENDING:
                // STATUS_PENDING is returned if the wait operation can't be canceled yet.
                // This can happen if this thread was woken up by another event, such as a netpollBreak,
                // and the timer expired just while calling NtCancelWaitCompletionPacket, in which case
index ab4e165baecfb06859c490488dc08b57852522cd..f47419cf7dfe0df6c6138719f126610dc3ad504f 100644 (file)
@@ -323,7 +323,7 @@ func monitorSuspendResume() {
 
 func getCPUCount() int32 {
        var mask, sysmask uintptr
-       ret := stdcall(_GetProcessAffinityMask, currentProcess, uintptr(unsafe.Pointer(&mask)), uintptr(unsafe.Pointer(&sysmask)))
+       ret := stdcall(_GetProcessAffinityMask, windows.CurrentProcess, uintptr(unsafe.Pointer(&mask)), uintptr(unsafe.Pointer(&sysmask)))
        if ret != 0 {
                n := 0
                maskbits := int(unsafe.Sizeof(mask) * 8)
@@ -337,22 +337,17 @@ func getCPUCount() int32 {
                }
        }
        // use GetSystemInfo if GetProcessAffinityMask fails
-       var info systeminfo
+       var info windows.SystemInfo
        stdcall(_GetSystemInfo, uintptr(unsafe.Pointer(&info)))
-       return int32(info.dwnumberofprocessors)
+       return int32(info.NumberOfProcessors)
 }
 
 func getPageSize() uintptr {
-       var info systeminfo
+       var info windows.SystemInfo
        stdcall(_GetSystemInfo, uintptr(unsafe.Pointer(&info)))
-       return uintptr(info.dwpagesize)
+       return uintptr(info.PageSize)
 }
 
-const (
-       currentProcess = ^uintptr(0) // -1 = current process
-       currentThread  = ^uintptr(1) // -2 = current thread
-)
-
 // in sys_windows_386.s and sys_windows_amd64.s:
 func getlasterror() uint32
 
@@ -405,18 +400,11 @@ var haveHighResSleep = false
 // resolution timer. createHighResTimer returns new timer
 // handle or 0, if CreateWaitableTimerEx failed.
 func createHighResTimer() uintptr {
-       const (
-               // As per @jstarks, see
-               // https://github.com/golang/go/issues/8687#issuecomment-656259353
-               _CREATE_WAITABLE_TIMER_HIGH_RESOLUTION = 0x00000002
-
-               _SYNCHRONIZE        = 0x00100000
-               _TIMER_QUERY_STATE  = 0x0001
-               _TIMER_MODIFY_STATE = 0x0002
-       )
+       // As per @jstarks, see
+       // https://github.com/golang/go/issues/8687#issuecomment-656259353
        return stdcall(_CreateWaitableTimerExW, 0, 0,
-               _CREATE_WAITABLE_TIMER_HIGH_RESOLUTION,
-               _SYNCHRONIZE|_TIMER_QUERY_STATE|_TIMER_MODIFY_STATE)
+               windows.CREATE_WAITABLE_TIMER_HIGH_RESOLUTION,
+               windows.SYNCHRONIZE|windows.TIMER_QUERY_STATE|windows.TIMER_MODIFY_STATE)
 }
 
 func initHighResTimer() {
@@ -454,10 +442,10 @@ func initLongPathSupport() {
        )
 
        // Check that we're ≥ 10.0.15063.
-       info := _OSVERSIONINFOW{}
-       info.osVersionInfoSize = uint32(unsafe.Sizeof(info))
+       info := windows.OSVERSIONINFOW{}
+       info.OSVersionInfoSize = uint32(unsafe.Sizeof(info))
        stdcall(_RtlGetVersion, uintptr(unsafe.Pointer(&info)))
-       if info.majorVersion < 10 || (info.majorVersion == 10 && info.minorVersion == 0 && info.buildNumber < 15063) {
+       if info.MajorVersion < 10 || (info.MajorVersion == 10 && info.MinorVersion == 0 && info.BuildNumber < 15063) {
                return
        }
 
@@ -493,7 +481,7 @@ func osinit() {
        // of dedicated threads -- GUI, IO, computational, etc. Go processes use
        // equivalent threads that all do a mix of GUI, IO, computations, etc.
        // In such context dynamic priority boosting does nothing but harm, so we turn it off.
-       stdcall(_SetProcessPriorityBoost, currentProcess, 1)
+       stdcall(_SetProcessPriorityBoost, windows.CurrentProcess, 1)
 }
 
 //go:nosplit
@@ -671,7 +659,7 @@ func semasleep(ns int64) int32 {
 
        var result uintptr
        if ns < 0 {
-               result = stdcall(_WaitForSingleObject, getg().m.waitsema, uintptr(_INFINITE))
+               result = stdcall(_WaitForSingleObject, getg().m.waitsema, uintptr(windows.INFINITE))
        } else {
                start := nanotime()
                elapsed := int64(0)
@@ -828,7 +816,7 @@ func sigblock(exiting bool) {
 // Called on the new thread, cannot allocate Go memory.
 func minit() {
        var thandle uintptr
-       if stdcall(_DuplicateHandle, currentProcess, currentThread, currentProcess, uintptr(unsafe.Pointer(&thandle)), 0, 0, _DUPLICATE_SAME_ACCESS) == 0 {
+       if stdcall(_DuplicateHandle, windows.CurrentProcess, windows.CurrentThread, windows.CurrentProcess, uintptr(unsafe.Pointer(&thandle)), 0, 0, windows.DUPLICATE_SAME_ACCESS) == 0 {
                print("runtime.minit: duplicatehandle failed; errno=", getlasterror(), "\n")
                throw("runtime.minit: duplicatehandle failed")
        }
@@ -863,7 +851,7 @@ func minit() {
 
        // Query the true stack base from the OS. Currently we're
        // running on a small assumed stack.
-       var mbi memoryBasicInformation
+       var mbi windows.MemoryBasicInformation
        res := stdcall(_VirtualQuery, uintptr(unsafe.Pointer(&mbi)), uintptr(unsafe.Pointer(&mbi)), unsafe.Sizeof(mbi))
        if res == 0 {
                print("runtime: VirtualQuery failed; errno=", getlasterror(), "\n")
@@ -875,7 +863,7 @@ func minit() {
        // calling C functions that don't have stack checks and for
        // lastcontinuehandler. We shouldn't be anywhere near this
        // bound anyway.
-       base := mbi.allocationBase + 16<<10
+       base := mbi.AllocationBase + 16<<10
        // Sanity check the stack bounds.
        g0 := getg()
        if base > g0.stack.hi || g0.stack.hi-base > 64<<20 {
@@ -1000,7 +988,7 @@ func osyield() {
 //go:nosplit
 func usleep_no_g(us uint32) {
        timeout := uintptr(us) / 1000 // ms units
-       stdcall_no_g(_WaitForSingleObject, _INVALID_HANDLE_VALUE, timeout)
+       stdcall_no_g(_WaitForSingleObject, windows.INVALID_HANDLE_VALUE, timeout)
 }
 
 //go:nosplit
@@ -1013,9 +1001,9 @@ func usleep(us uint32) {
                        h = getg().m.highResTimer
                        dt := -10 * int64(us) // relative sleep (negative), 100ns units
                        stdcall(_SetWaitableTimer, h, uintptr(unsafe.Pointer(&dt)), 0, 0, 0, 0)
-                       timeout = _INFINITE
+                       timeout = windows.INFINITE
                } else {
-                       h = _INVALID_HANDLE_VALUE
+                       h = windows.INVALID_HANDLE_VALUE
                        timeout = uintptr(us) / 1000 // ms units
                }
                stdcall(_WaitForSingleObject, h, timeout)
@@ -1026,16 +1014,16 @@ func ctrlHandler(_type uint32) uintptr {
        var s uint32
 
        switch _type {
-       case _CTRL_C_EVENT, _CTRL_BREAK_EVENT:
-               s = _SIGINT
-       case _CTRL_CLOSE_EVENT, _CTRL_LOGOFF_EVENT, _CTRL_SHUTDOWN_EVENT:
-               s = _SIGTERM
+       case windows.CTRL_C_EVENT, windows.CTRL_BREAK_EVENT:
+               s = windows.SIGINT
+       case windows.CTRL_CLOSE_EVENT, windows.CTRL_LOGOFF_EVENT, windows.CTRL_SHUTDOWN_EVENT:
+               s = windows.SIGTERM
        default:
                return 0
        }
 
        if sigsend(s) {
-               if s == _SIGTERM {
+               if s == windows.SIGTERM {
                        // Windows terminates the process after this handler returns.
                        // Block indefinitely to give signal handlers a chance to clean up,
                        // but make sure to be properly parked first, so the rest of the
@@ -1054,16 +1042,16 @@ var profiletimer uintptr
 
 func profilem(mp *m, thread uintptr) {
        // Align Context to 16 bytes.
-       var c *context
+       var c *windows.Context
        var cbuf [unsafe.Sizeof(*c) + 15]byte
-       c = (*context)(unsafe.Pointer((uintptr(unsafe.Pointer(&cbuf[15]))) &^ 15))
+       c = (*windows.Context)(unsafe.Pointer((uintptr(unsafe.Pointer(&cbuf[15]))) &^ 15))
 
-       c.contextflags = _CONTEXT_CONTROL
+       c.ContextFlags = windows.CONTEXT_CONTROL
        stdcall(_GetThreadContext, thread, uintptr(unsafe.Pointer(c)))
 
-       gp := gFromSP(mp, c.sp())
+       gp := gFromSP(mp, c.SP())
 
-       sigprof(c.ip(), c.sp(), c.lr(), gp, mp)
+       sigprof(c.PC(), c.SP(), c.LR(), gp, mp)
 }
 
 func gFromSP(mp *m, sp uintptr) *g {
@@ -1080,10 +1068,10 @@ func gFromSP(mp *m, sp uintptr) *g {
 }
 
 func profileLoop() {
-       stdcall(_SetThreadPriority, currentThread, _THREAD_PRIORITY_HIGHEST)
+       stdcall(_SetThreadPriority, windows.CurrentThread, windows.THREAD_PRIORITY_HIGHEST)
 
        for {
-               stdcall(_WaitForSingleObject, profiletimer, _INFINITE)
+               stdcall(_WaitForSingleObject, profiletimer, windows.INFINITE)
                first := (*m)(atomic.Loadp(unsafe.Pointer(&allm)))
                for mp := first; mp != nil; mp = mp.alllink {
                        if mp == getg().m {
@@ -1101,7 +1089,7 @@ func profileLoop() {
                        }
                        // Acquire our own handle to the thread.
                        var thread uintptr
-                       if stdcall(_DuplicateHandle, currentProcess, mp.thread, currentProcess, uintptr(unsafe.Pointer(&thread)), 0, 0, _DUPLICATE_SAME_ACCESS) == 0 {
+                       if stdcall(_DuplicateHandle, windows.CurrentProcess, mp.thread, windows.CurrentProcess, uintptr(unsafe.Pointer(&thread)), 0, 0, windows.DUPLICATE_SAME_ACCESS) == 0 {
                                print("runtime: duplicatehandle failed; errno=", getlasterror(), "\n")
                                throw("duplicatehandle failed")
                        }
@@ -1183,17 +1171,17 @@ func preemptM(mp *m) {
                return
        }
        var thread uintptr
-       if stdcall(_DuplicateHandle, currentProcess, mp.thread, currentProcess, uintptr(unsafe.Pointer(&thread)), 0, 0, _DUPLICATE_SAME_ACCESS) == 0 {
+       if stdcall(_DuplicateHandle, windows.CurrentProcess, mp.thread, windows.CurrentProcess, uintptr(unsafe.Pointer(&thread)), 0, 0, windows.DUPLICATE_SAME_ACCESS) == 0 {
                print("runtime.preemptM: duplicatehandle failed; errno=", getlasterror(), "\n")
                throw("runtime.preemptM: duplicatehandle failed")
        }
        unlock(&mp.threadLock)
 
        // Prepare thread context buffer. This must be aligned to 16 bytes.
-       var c *context
+       var c *windows.Context
        var cbuf [unsafe.Sizeof(*c) + 15]byte
-       c = (*context)(unsafe.Pointer((uintptr(unsafe.Pointer(&cbuf[15]))) &^ 15))
-       c.contextflags = _CONTEXT_CONTROL
+       c = (*windows.Context)(unsafe.Pointer((uintptr(unsafe.Pointer(&cbuf[15]))) &^ 15))
+       c.ContextFlags = windows.CONTEXT_CONTROL
 
        // Serialize thread suspension. SuspendThread is asynchronous,
        // so it's otherwise possible for two threads to suspend each
@@ -1227,12 +1215,12 @@ func preemptM(mp *m) {
        unlock(&suspendLock)
 
        // Does it want a preemption and is it safe to preempt?
-       gp := gFromSP(mp, c.sp())
+       gp := gFromSP(mp, c.SP())
        if gp != nil && wantAsyncPreempt(gp) {
-               if ok, resumePC := isAsyncSafePoint(gp, c.ip(), c.sp(), c.lr()); ok {
+               if ok, resumePC := isAsyncSafePoint(gp, c.PC(), c.SP(), c.LR()); ok {
                        // Inject call to asyncPreempt
                        targetPC := abi.FuncPCABI0(asyncPreempt)
-                       c.pushCall(targetPC, resumePC)
+                       c.PushCall(targetPC, resumePC)
                        stdcall(_SetThreadContext, thread, uintptr(unsafe.Pointer(c)))
                }
        }
index bd80c08b0e34f730d93b325eafee3b0cfbeaca9f..62caea7c2c6ca3d7725049dd4aba30a5ec8c6dfd 100644 (file)
@@ -12,3 +12,7 @@ func cputicks() int64 {
        stdcall(_QueryPerformanceCounter, uintptr(unsafe.Pointer(&counter)))
        return counter
 }
+
+func stackcheck() {
+       // TODO: not implemented
+}
index ca92d7f178f7329f9104a3b74d3c93b5c849bdfe..8503a0550c4b25e6d6fd8561d54605107b5eba34 100644 (file)
@@ -6,6 +6,7 @@ package runtime_test
 
 import (
        "internal/abi"
+       "internal/runtime/sys"
        "internal/syscall/windows"
        "runtime"
        "slices"
@@ -47,7 +48,7 @@ func TestSehLookupFunctionEntry(t *testing.T) {
                {"func in prologue", sehf1pc + 1, true},
                {"anonymous func with frame", abi.FuncPCABIInternal(fnwithframe), true},
                {"anonymous func without frame", abi.FuncPCABIInternal(fnwithoutframe), false},
-               {"pc at func body", runtime.NewContextStub().GetPC(), true},
+               {"pc at func body", sys.GetCallerPC(), true},
        }
        for _, tt := range tests {
                var base uintptr
@@ -68,19 +69,22 @@ func sehCallers() []uintptr {
        // We don't need a real context,
        // RtlVirtualUnwind just needs a context with
        // valid a pc, sp and fp (aka bp).
-       ctx := runtime.NewContextStub()
+       var ctx windows.Context
+       ctx.SetPC(sys.GetCallerPC())
+       ctx.SetSP(sys.GetCallerSP())
+       ctx.SetFP(runtime.GetCallerFp())
 
        pcs := make([]uintptr, 15)
        var base, frame uintptr
        var n int
        for i := 0; i < len(pcs); i++ {
-               fn := windows.RtlLookupFunctionEntry(ctx.GetPC(), &base, nil)
+               fn := windows.RtlLookupFunctionEntry(ctx.PC(), &base, nil)
                if fn == nil {
                        break
                }
-               pcs[i] = ctx.GetPC()
+               pcs[i] = ctx.PC()
                n++
-               windows.RtlVirtualUnwind(0, base, ctx.GetPC(), fn, unsafe.Pointer(ctx), nil, &frame, nil)
+               windows.RtlVirtualUnwind(0, base, ctx.PC(), fn, unsafe.Pointer(&ctx), nil, &frame, nil)
        }
        return pcs[:n]
 }
@@ -129,15 +133,14 @@ func TestSehUnwind(t *testing.T) {
                t.Skip("skipping amd64-only test")
        }
        pcs := sehf3(false)
-       testSehCallersEqual(t, pcs, []string{"runtime_test.sehCallers", "runtime_test.sehf4",
-               "runtime_test.sehf3", "runtime_test.TestSehUnwind"})
+       testSehCallersEqual(t, pcs, []string{"runtime_test.sehf4", "runtime_test.sehf3", "runtime_test.TestSehUnwind"})
 }
 
 func TestSehUnwindPanic(t *testing.T) {
        if runtime.GOARCH != "amd64" {
                t.Skip("skipping amd64-only test")
        }
-       want := []string{"runtime_test.sehCallers", "runtime_test.TestSehUnwindPanic.func1", "runtime.gopanic",
+       want := []string{"runtime_test.TestSehUnwindPanic.func1", "runtime.gopanic",
                "runtime_test.sehf4", "runtime_test.sehf3", "runtime_test.TestSehUnwindPanic"}
        defer func() {
                if r := recover(); r == nil {
@@ -153,7 +156,7 @@ func TestSehUnwindDoublePanic(t *testing.T) {
        if runtime.GOARCH != "amd64" {
                t.Skip("skipping amd64-only test")
        }
-       want := []string{"runtime_test.sehCallers", "runtime_test.TestSehUnwindDoublePanic.func1.1", "runtime.gopanic",
+       want := []string{"runtime_test.TestSehUnwindDoublePanic.func1.1", "runtime.gopanic",
                "runtime_test.TestSehUnwindDoublePanic.func1", "runtime.gopanic", "runtime_test.TestSehUnwindDoublePanic"}
        defer func() {
                defer func() {
@@ -175,7 +178,7 @@ func TestSehUnwindNilPointerPanic(t *testing.T) {
        if runtime.GOARCH != "amd64" {
                t.Skip("skipping amd64-only test")
        }
-       want := []string{"runtime_test.sehCallers", "runtime_test.TestSehUnwindNilPointerPanic.func1", "runtime.gopanic",
+       want := []string{"runtime_test.TestSehUnwindNilPointerPanic.func1", "runtime.gopanic",
                "runtime.sigpanic", "runtime_test.TestSehUnwindNilPointerPanic"}
        defer func() {
                if r := recover(); r == nil {
index f7628a0165b2edd502f292928bff93359ecfaac5..40547b8113fffb5a27aa9a2e02af5efebd6090f2 100644 (file)
@@ -6,36 +6,29 @@ package runtime
 
 import (
        "internal/abi"
+       "internal/runtime/syscall/windows"
        "unsafe"
 )
 
-const (
-       _SEM_FAILCRITICALERRORS = 0x0001
-       _SEM_NOGPFAULTERRORBOX  = 0x0002
-       _SEM_NOOPENFILEERRORBOX = 0x8000
-
-       _WER_FAULT_REPORTING_NO_UI = 0x0020
-)
-
 func preventErrorDialogs() {
        errormode := stdcall(_GetErrorMode)
-       stdcall(_SetErrorMode, errormode|_SEM_FAILCRITICALERRORS|_SEM_NOGPFAULTERRORBOX|_SEM_NOOPENFILEERRORBOX)
+       stdcall(_SetErrorMode, errormode|windows.SEM_FAILCRITICALERRORS|windows.SEM_NOGPFAULTERRORBOX|windows.SEM_NOOPENFILEERRORBOX)
 
        // Disable WER fault reporting UI.
        // Do this even if WER is disabled as a whole,
        // as WER might be enabled later with setTraceback("wer")
        // and we still want the fault reporting UI to be disabled if this happens.
        var werflags uintptr
-       stdcall(_WerGetFlags, currentProcess, uintptr(unsafe.Pointer(&werflags)))
-       stdcall(_WerSetFlags, werflags|_WER_FAULT_REPORTING_NO_UI)
+       stdcall(_WerGetFlags, windows.CurrentProcess, uintptr(unsafe.Pointer(&werflags)))
+       stdcall(_WerSetFlags, werflags|windows.WER_FAULT_REPORTING_NO_UI)
 }
 
 // enableWER re-enables Windows error reporting without fault reporting UI.
 func enableWER() {
        // re-enable Windows Error Reporting
        errormode := stdcall(_GetErrorMode)
-       if errormode&_SEM_NOGPFAULTERRORBOX != 0 {
-               stdcall(_SetErrorMode, errormode^_SEM_NOGPFAULTERRORBOX)
+       if errormode&windows.SEM_NOGPFAULTERRORBOX != 0 {
+               stdcall(_SetErrorMode, errormode^windows.SEM_NOGPFAULTERRORBOX)
        }
 }
 
@@ -62,8 +55,8 @@ func initExceptionHandler() {
 // by calling runtime.abort function.
 //
 //go:nosplit
-func isAbort(r *context) bool {
-       pc := r.ip()
+func isAbort(r *windows.Context) bool {
+       pc := r.PC()
        if GOARCH == "386" || GOARCH == "amd64" {
                // In the case of an abort, the exception IP is one byte after
                // the INT3 (this differs from UNIX OSes).
@@ -79,29 +72,29 @@ func isAbort(r *context) bool {
 // because of a stack overflow.
 //
 //go:nosplit
-func isgoexception(info *exceptionrecord, r *context) bool {
+func isgoexception(info *windows.ExceptionRecord, r *windows.Context) bool {
        // Only handle exception if executing instructions in Go binary
        // (not Windows library code).
        // TODO(mwhudson): needs to loop to support shared libs
-       if r.ip() < firstmoduledata.text || firstmoduledata.etext < r.ip() {
+       if r.PC() < firstmoduledata.text || firstmoduledata.etext < r.PC() {
                return false
        }
 
        // Go will only handle some exceptions.
-       switch info.exceptioncode {
+       switch info.ExceptionCode {
        default:
                return false
-       case _EXCEPTION_ACCESS_VIOLATION:
-       case _EXCEPTION_IN_PAGE_ERROR:
-       case _EXCEPTION_INT_DIVIDE_BY_ZERO:
-       case _EXCEPTION_INT_OVERFLOW:
-       case _EXCEPTION_FLT_DENORMAL_OPERAND:
-       case _EXCEPTION_FLT_DIVIDE_BY_ZERO:
-       case _EXCEPTION_FLT_INEXACT_RESULT:
-       case _EXCEPTION_FLT_OVERFLOW:
-       case _EXCEPTION_FLT_UNDERFLOW:
-       case _EXCEPTION_BREAKPOINT:
-       case _EXCEPTION_ILLEGAL_INSTRUCTION: // breakpoint arrives this way on arm64
+       case windows.EXCEPTION_ACCESS_VIOLATION:
+       case windows.EXCEPTION_IN_PAGE_ERROR:
+       case windows.EXCEPTION_INT_DIVIDE_BY_ZERO:
+       case windows.EXCEPTION_INT_OVERFLOW:
+       case windows.EXCEPTION_FLT_DENORMAL_OPERAND:
+       case windows.EXCEPTION_FLT_DIVIDE_BY_ZERO:
+       case windows.EXCEPTION_FLT_INEXACT_RESULT:
+       case windows.EXCEPTION_FLT_OVERFLOW:
+       case windows.EXCEPTION_FLT_UNDERFLOW:
+       case windows.EXCEPTION_BREAKPOINT:
+       case windows.EXCEPTION_ILLEGAL_INSTRUCTION: // breakpoint arrives this way on arm64
        }
        return true
 }
@@ -134,13 +127,13 @@ func sigFetchG() *g {
 // It is nosplit for the same reason as exceptionhandler.
 //
 //go:nosplit
-func sigtrampgo(ep *exceptionpointers, kind int) int32 {
+func sigtrampgo(ep *windows.ExceptionPointers, kind int) int32 {
        gp := sigFetchG()
        if gp == nil {
-               return _EXCEPTION_CONTINUE_SEARCH
+               return windows.EXCEPTION_CONTINUE_SEARCH
        }
 
-       var fn func(info *exceptionrecord, r *context, gp *g) int32
+       var fn func(info *windows.ExceptionRecord, r *windows.Context, gp *g) int32
        switch kind {
        case callbackVEH:
                fn = exceptionhandler
@@ -169,12 +162,12 @@ func sigtrampgo(ep *exceptionpointers, kind int) int32 {
        var ret int32
        if gp != gp.m.g0 {
                systemstack(func() {
-                       ret = fn(ep.record, ep.context, gp)
+                       ret = fn(ep.Record, ep.Context, gp)
                })
        } else {
-               ret = fn(ep.record, ep.context, gp)
+               ret = fn(ep.Record, ep.Context, gp)
        }
-       if ret == _EXCEPTION_CONTINUE_SEARCH {
+       if ret == windows.EXCEPTION_CONTINUE_SEARCH {
                return ret
        }
 
@@ -189,13 +182,13 @@ func sigtrampgo(ep *exceptionpointers, kind int) int32 {
        // will not actually return to the original frame, so the registers
        // are effectively dead. But this does mean we can't use the
        // same mechanism for async preemption.
-       if ep.context.ip() == abi.FuncPCABI0(sigresume) {
+       if ep.Context.PC() == abi.FuncPCABI0(sigresume) {
                // sigresume has already been set up by a previous exception.
                return ret
        }
-       prepareContextForSigResume(ep.context)
-       ep.context.set_sp(gp.m.g0.sched.sp)
-       ep.context.set_ip(abi.FuncPCABI0(sigresume))
+       prepareContextForSigResume(ep.Context)
+       ep.Context.SetSP(gp.m.g0.sched.sp)
+       ep.Context.SetPC(abi.FuncPCABI0(sigresume))
        return ret
 }
 
@@ -207,9 +200,9 @@ func sigtrampgo(ep *exceptionpointers, kind int) int32 {
 // _EXCEPTION_BREAKPOINT, which is raised by abort() if we overflow the g0 stack.
 //
 //go:nosplit
-func exceptionhandler(info *exceptionrecord, r *context, gp *g) int32 {
+func exceptionhandler(info *windows.ExceptionRecord, r *windows.Context, gp *g) int32 {
        if !isgoexception(info, r) {
-               return _EXCEPTION_CONTINUE_SEARCH
+               return windows.EXCEPTION_CONTINUE_SEARCH
        }
 
        if gp.throwsplit || isAbort(r) {
@@ -226,10 +219,10 @@ func exceptionhandler(info *exceptionrecord, r *context, gp *g) int32 {
        // 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.ip()
+       gp.sig = info.ExceptionCode
+       gp.sigcode0 = info.ExceptionInformation[0]
+       gp.sigcode1 = info.ExceptionInformation[1]
+       gp.sigpc = r.PC()
 
        // Only push runtime·sigpanic if r.ip() != 0.
        // If r.ip() == 0, probably panicked because of a
@@ -244,13 +237,13 @@ func exceptionhandler(info *exceptionrecord, r *context, gp *g) int32 {
        // The exception is not from asyncPreempt, so not to push a
        // sigpanic call to make it look like that. Instead, just
        // overwrite the PC. (See issue #35773)
-       if r.ip() != 0 && r.ip() != abi.FuncPCABI0(asyncPreempt) {
-               r.pushCall(abi.FuncPCABI0(sigpanic0), r.ip())
+       if r.PC() != 0 && r.PC() != abi.FuncPCABI0(asyncPreempt) {
+               r.PushCall(abi.FuncPCABI0(sigpanic0), r.PC())
        } else {
                // Not safe to push the call. Just clobber the frame.
-               r.set_ip(abi.FuncPCABI0(sigpanic0))
+               r.SetPC(abi.FuncPCABI0(sigpanic0))
        }
-       return _EXCEPTION_CONTINUE_EXECUTION
+       return windows.EXCEPTION_CONTINUE_EXECUTION
 }
 
 // sehhandler is reached as part of the SEH chain.
@@ -258,11 +251,11 @@ func exceptionhandler(info *exceptionrecord, r *context, gp *g) int32 {
 // It is nosplit for the same reason as exceptionhandler.
 //
 //go:nosplit
-func sehhandler(_ *exceptionrecord, _ uint64, _ *context, dctxt *_DISPATCHER_CONTEXT) int32 {
+func sehhandler(_ *windows.ExceptionRecord, _ uint64, _ *windows.Context, dctxt *windows.DISPATCHER_CONTEXT) int32 {
        g0 := getg()
        if g0 == nil || g0.m.curg == nil {
                // No g available, nothing to do here.
-               return _EXCEPTION_CONTINUE_SEARCH_SEH
+               return windows.EXCEPTION_CONTINUE_SEARCH_SEH
        }
        // The Windows SEH machinery will unwind the stack until it finds
        // a frame with a handler for the exception or until the frame is
@@ -275,19 +268,19 @@ func sehhandler(_ *exceptionrecord, _ uint64, _ *context, dctxt *_DISPATCHER_CON
        // To work around this, manually unwind the stack until the top of the goroutine
        // stack is reached, and then pass the control back to Windows.
        gp := g0.m.curg
-       ctxt := dctxt.ctx()
+       ctxt := dctxt.Ctx()
        var base, sp uintptr
        for {
-               entry := stdcall(_RtlLookupFunctionEntry, ctxt.ip(), uintptr(unsafe.Pointer(&base)), 0)
+               entry := stdcall(_RtlLookupFunctionEntry, ctxt.PC(), uintptr(unsafe.Pointer(&base)), 0)
                if entry == 0 {
                        break
                }
-               stdcall(_RtlVirtualUnwind, 0, base, ctxt.ip(), entry, uintptr(unsafe.Pointer(ctxt)), 0, uintptr(unsafe.Pointer(&sp)), 0)
+               stdcall(_RtlVirtualUnwind, 0, base, ctxt.PC(), entry, uintptr(unsafe.Pointer(ctxt)), 0, uintptr(unsafe.Pointer(&sp)), 0)
                if sp < gp.stack.lo || gp.stack.hi <= sp {
                        break
                }
        }
-       return _EXCEPTION_CONTINUE_SEARCH_SEH
+       return windows.EXCEPTION_CONTINUE_SEARCH_SEH
 }
 
 // It seems Windows searches ContinueHandler's list even
@@ -298,11 +291,11 @@ func sehhandler(_ *exceptionrecord, _ uint64, _ *context, dctxt *_DISPATCHER_CON
 // It is nosplit for the same reason as exceptionhandler.
 //
 //go:nosplit
-func firstcontinuehandler(info *exceptionrecord, r *context, gp *g) int32 {
+func firstcontinuehandler(info *windows.ExceptionRecord, r *windows.Context, gp *g) int32 {
        if !isgoexception(info, r) {
-               return _EXCEPTION_CONTINUE_SEARCH
+               return windows.EXCEPTION_CONTINUE_SEARCH
        }
-       return _EXCEPTION_CONTINUE_EXECUTION
+       return windows.EXCEPTION_CONTINUE_EXECUTION
 }
 
 // lastcontinuehandler is reached, because runtime cannot handle
@@ -311,12 +304,12 @@ func firstcontinuehandler(info *exceptionrecord, r *context, gp *g) int32 {
 // It is nosplit for the same reason as exceptionhandler.
 //
 //go:nosplit
-func lastcontinuehandler(info *exceptionrecord, r *context, gp *g) int32 {
+func lastcontinuehandler(info *windows.ExceptionRecord, r *windows.Context, gp *g) int32 {
        if islibrary || isarchive {
                // Go DLL/archive has been loaded in a non-go program.
                // If the exception does not originate from go, the go runtime
                // should not take responsibility of crashing the process.
-               return _EXCEPTION_CONTINUE_SEARCH
+               return windows.EXCEPTION_CONTINUE_SEARCH
        }
 
        // VEH is called before SEH, but arm64 MSVC DLLs use SEH to trap
@@ -325,9 +318,9 @@ func lastcontinuehandler(info *exceptionrecord, r *context, gp *g) int32 {
        // arm64 and it's an illegal instruction and this is coming from
        // non-Go code, then assume it's this runtime probing happen, and
        // pass that onward to SEH.
-       if GOARCH == "arm64" && info.exceptioncode == _EXCEPTION_ILLEGAL_INSTRUCTION &&
-               (r.ip() < firstmoduledata.text || firstmoduledata.etext < r.ip()) {
-               return _EXCEPTION_CONTINUE_SEARCH
+       if GOARCH == "arm64" && info.ExceptionCode == windows.EXCEPTION_ILLEGAL_INSTRUCTION &&
+               (r.PC() < firstmoduledata.text || firstmoduledata.etext < r.PC()) {
+               return windows.EXCEPTION_CONTINUE_SEARCH
        }
 
        winthrow(info, r, gp)
@@ -337,7 +330,7 @@ func lastcontinuehandler(info *exceptionrecord, r *context, gp *g) int32 {
 // Always called on g0. gp is the G where the exception occurred.
 //
 //go:nosplit
-func winthrow(info *exceptionrecord, r *context, gp *g) {
+func winthrow(info *windows.ExceptionRecord, r *windows.Context, gp *g) {
        g0 := getg()
 
        if panicking.Load() != 0 { // traceback already printed
@@ -352,9 +345,9 @@ func winthrow(info *exceptionrecord, r *context, gp *g) {
        g0.stackguard0 = g0.stack.lo + stackGuard
        g0.stackguard1 = g0.stackguard0
 
-       print("Exception ", hex(info.exceptioncode), " ", hex(info.exceptioninformation[0]), " ", hex(info.exceptioninformation[1]), " ", hex(r.ip()), "\n")
+       print("Exception ", hex(info.ExceptionCode), " ", hex(info.ExceptionInformation[0]), " ", hex(info.ExceptionInformation[1]), " ", hex(r.PC()), "\n")
 
-       print("PC=", hex(r.ip()), "\n")
+       print("PC=", hex(r.PC()), "\n")
        if g0.m.incgo && gp == g0.m.g0 && g0.m.curg != nil {
                if iscgo {
                        print("signal arrived during external code execution\n")
@@ -368,7 +361,7 @@ func winthrow(info *exceptionrecord, r *context, gp *g) {
 
        level, _, docrash := gotraceback()
        if level > 0 {
-               tracebacktrap(r.ip(), r.sp(), r.lr(), gp)
+               tracebacktrap(r.PC(), r.SP(), r.LR(), gp)
                tracebackothers(gp)
                dumpregs(r)
        }
@@ -387,7 +380,7 @@ func sigpanic() {
        }
 
        switch gp.sig {
-       case _EXCEPTION_ACCESS_VIOLATION, _EXCEPTION_IN_PAGE_ERROR:
+       case windows.EXCEPTION_ACCESS_VIOLATION, windows.EXCEPTION_IN_PAGE_ERROR:
                if gp.sigcode1 < 0x1000 {
                        panicmem()
                }
@@ -403,15 +396,15 @@ func sigpanic() {
                        print("unexpected fault address ", hex(gp.sigcode1), "\n")
                }
                throw("fault")
-       case _EXCEPTION_INT_DIVIDE_BY_ZERO:
+       case windows.EXCEPTION_INT_DIVIDE_BY_ZERO:
                panicdivide()
-       case _EXCEPTION_INT_OVERFLOW:
+       case windows.EXCEPTION_INT_OVERFLOW:
                panicoverflow()
-       case _EXCEPTION_FLT_DENORMAL_OPERAND,
-               _EXCEPTION_FLT_DIVIDE_BY_ZERO,
-               _EXCEPTION_FLT_INEXACT_RESULT,
-               _EXCEPTION_FLT_OVERFLOW,
-               _EXCEPTION_FLT_UNDERFLOW:
+       case windows.EXCEPTION_FLT_DENORMAL_OPERAND,
+               windows.EXCEPTION_FLT_DIVIDE_BY_ZERO,
+               windows.EXCEPTION_FLT_INEXACT_RESULT,
+               windows.EXCEPTION_FLT_OVERFLOW,
+               windows.EXCEPTION_FLT_UNDERFLOW:
                panicfloat()
        }
        throw("fault")
@@ -444,29 +437,28 @@ func crash() {
 // This provides the expected exit status for the shell.
 //
 //go:nosplit
-func dieFromException(info *exceptionrecord, r *context) {
+func dieFromException(info *windows.ExceptionRecord, r *windows.Context) {
        if info == nil {
                gp := getg()
                if gp.sig != 0 {
                        // Try to reconstruct an exception record from
                        // the exception information stored in gp.
-                       info = &exceptionrecord{
-                               exceptionaddress: gp.sigpc,
-                               exceptioncode:    gp.sig,
-                               numberparameters: 2,
+                       info = &windows.ExceptionRecord{
+                               ExceptionAddress: gp.sigpc,
+                               ExceptionCode:    gp.sig,
+                               NumberParameters: 2,
                        }
-                       info.exceptioninformation[0] = gp.sigcode0
-                       info.exceptioninformation[1] = gp.sigcode1
+                       info.ExceptionInformation[0] = gp.sigcode0
+                       info.ExceptionInformation[1] = gp.sigcode1
                } else {
                        // By default, a failing Go application exits with exit code 2.
                        // Use this value when gp does not contain exception info.
-                       info = &exceptionrecord{
-                               exceptioncode: 2,
+                       info = &windows.ExceptionRecord{
+                               ExceptionCode: 2,
                        }
                }
        }
-       const FAIL_FAST_GENERATE_EXCEPTION_ADDRESS = 0x1
-       stdcall(_RaiseFailFastException, uintptr(unsafe.Pointer(info)), uintptr(unsafe.Pointer(r)), FAIL_FAST_GENERATE_EXCEPTION_ADDRESS)
+       stdcall(_RaiseFailFastException, uintptr(unsafe.Pointer(info)), uintptr(unsafe.Pointer(r)), windows.FAIL_FAST_GENERATE_EXCEPTION_ADDRESS)
 }
 
 // gsignalStack is unused on Windows.
diff --git a/src/runtime/signal_windows_386.go b/src/runtime/signal_windows_386.go
new file mode 100644 (file)
index 0000000..1c73129
--- /dev/null
@@ -0,0 +1,28 @@
+// Copyright 2025 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.
+
+package runtime
+
+import "internal/runtime/syscall/windows"
+
+func prepareContextForSigResume(c *windows.Context) {
+       c.Edx = c.Esp
+       c.Ecx = c.Eip
+}
+
+func dumpregs(r *windows.Context) {
+       print("eax     ", hex(r.Eax), "\n")
+       print("ebx     ", hex(r.Ebx), "\n")
+       print("ecx     ", hex(r.Ecx), "\n")
+       print("edx     ", hex(r.Edx), "\n")
+       print("edi     ", hex(r.Edi), "\n")
+       print("esi     ", hex(r.Esi), "\n")
+       print("ebp     ", hex(r.Ebp), "\n")
+       print("esp     ", hex(r.Esp), "\n")
+       print("eip     ", hex(r.Eip), "\n")
+       print("eflags  ", hex(r.EFlags), "\n")
+       print("cs      ", hex(r.SegCs), "\n")
+       print("fs      ", hex(r.SegFs), "\n")
+       print("gs      ", hex(r.SegGs), "\n")
+}
diff --git a/src/runtime/signal_windows_amd64.go b/src/runtime/signal_windows_amd64.go
new file mode 100644 (file)
index 0000000..ecb7024
--- /dev/null
@@ -0,0 +1,36 @@
+// Copyright 2025 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.
+
+package runtime
+
+import "internal/runtime/syscall/windows"
+
+func prepareContextForSigResume(c *windows.Context) {
+       c.R8 = c.Rsp
+       c.R9 = c.Rip
+}
+
+func dumpregs(r *windows.Context) {
+       print("rax     ", hex(r.Rax), "\n")
+       print("rbx     ", hex(r.Rbx), "\n")
+       print("rcx     ", hex(r.Rcx), "\n")
+       print("rdx     ", hex(r.Rdx), "\n")
+       print("rdi     ", hex(r.Rdi), "\n")
+       print("rsi     ", hex(r.Rsi), "\n")
+       print("rbp     ", hex(r.Rbp), "\n")
+       print("rsp     ", hex(r.Rsp), "\n")
+       print("r8      ", hex(r.R8), "\n")
+       print("r9      ", hex(r.R9), "\n")
+       print("r10     ", hex(r.R10), "\n")
+       print("r11     ", hex(r.R11), "\n")
+       print("r12     ", hex(r.R12), "\n")
+       print("r13     ", hex(r.R13), "\n")
+       print("r14     ", hex(r.R14), "\n")
+       print("r15     ", hex(r.R15), "\n")
+       print("rip     ", hex(r.Rip), "\n")
+       print("rflags  ", hex(r.EFlags), "\n")
+       print("cs      ", hex(r.SegCs), "\n")
+       print("fs      ", hex(r.SegFs), "\n")
+       print("gs      ", hex(r.SegGs), "\n")
+}
diff --git a/src/runtime/signal_windows_arm64.go b/src/runtime/signal_windows_arm64.go
new file mode 100644 (file)
index 0000000..78bddb9
--- /dev/null
@@ -0,0 +1,49 @@
+// Copyright 2025 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.
+
+package runtime
+
+import "internal/runtime/syscall/windows"
+
+func prepareContextForSigResume(c *windows.Context) {
+       c.X[0] = c.XSp
+       c.X[1] = c.Pc
+}
+
+func dumpregs(r *windows.Context) {
+       print("r0   ", hex(r.X[0]), "\n")
+       print("r1   ", hex(r.X[1]), "\n")
+       print("r2   ", hex(r.X[2]), "\n")
+       print("r3   ", hex(r.X[3]), "\n")
+       print("r4   ", hex(r.X[4]), "\n")
+       print("r5   ", hex(r.X[5]), "\n")
+       print("r6   ", hex(r.X[6]), "\n")
+       print("r7   ", hex(r.X[7]), "\n")
+       print("r8   ", hex(r.X[8]), "\n")
+       print("r9   ", hex(r.X[9]), "\n")
+       print("r10  ", hex(r.X[10]), "\n")
+       print("r11  ", hex(r.X[11]), "\n")
+       print("r12  ", hex(r.X[12]), "\n")
+       print("r13  ", hex(r.X[13]), "\n")
+       print("r14  ", hex(r.X[14]), "\n")
+       print("r15  ", hex(r.X[15]), "\n")
+       print("r16  ", hex(r.X[16]), "\n")
+       print("r17  ", hex(r.X[17]), "\n")
+       print("r18  ", hex(r.X[18]), "\n")
+       print("r19  ", hex(r.X[19]), "\n")
+       print("r20  ", hex(r.X[20]), "\n")
+       print("r21  ", hex(r.X[21]), "\n")
+       print("r22  ", hex(r.X[22]), "\n")
+       print("r23  ", hex(r.X[23]), "\n")
+       print("r24  ", hex(r.X[24]), "\n")
+       print("r25  ", hex(r.X[25]), "\n")
+       print("r26  ", hex(r.X[26]), "\n")
+       print("r27  ", hex(r.X[27]), "\n")
+       print("r28  ", hex(r.X[28]), "\n")
+       print("r29  ", hex(r.X[29]), "\n")
+       print("lr   ", hex(r.X[30]), "\n")
+       print("sp   ", hex(r.XSp), "\n")
+       print("pc   ", hex(r.Pc), "\n")
+       print("cpsr ", hex(r.Cpsr), "\n")
+}