summaryrefslogtreecommitdiff
path: root/src/runtime
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2014-11-24 12:07:11 -0500
committerRuss Cox <rsc@golang.org>2014-11-24 12:07:11 -0500
commite5fc9ffb729e31c4eb0a6518e819e9fc70f14818 (patch)
tree5f67f9fb6c209085505b8fa6a01a245942ea45c3 /src/runtime
parentdf7d4576f312e1b646af4f5f1a32412a4221b785 (diff)
parentdb6a11ff558add790779fdef118b5ad899f77137 (diff)
downloadgo-e5fc9ffb729e31c4eb0a6518e819e9fc70f14818.tar.gz
[dev.garbage] all: merge dev.cc (493ad916c3b1) into dev.garbage
TBR=austin CC=golang-codereviews https://codereview.appspot.com/179290043
Diffstat (limited to 'src/runtime')
-rw-r--r--src/runtime/arch1_386.go2
-rw-r--r--src/runtime/arch1_amd64.go2
-rw-r--r--src/runtime/arch1_amd64p32.go15
-rw-r--r--src/runtime/arch1_arm.go2
-rw-r--r--src/runtime/arch1_power64.go15
-rw-r--r--src/runtime/arch1_power64le.go15
-rw-r--r--src/runtime/arch_amd64p32.h17
-rw-r--r--src/runtime/arch_power64le.h14
-rw-r--r--src/runtime/asm_amd64p32.s2
-rw-r--r--src/runtime/asm_power64x.s59
-rw-r--r--src/runtime/atomic_power64x.go69
-rw-r--r--src/runtime/chan.go1
-rw-r--r--src/runtime/defs1_netbsd_386.go22
-rw-r--r--src/runtime/defs1_netbsd_amd64.go20
-rw-r--r--src/runtime/defs_linux_386.go9
-rw-r--r--src/runtime/defs_linux_amd64.go10
-rw-r--r--src/runtime/defs_linux_arm.go9
-rw-r--r--src/runtime/defs_linux_power64.go198
-rw-r--r--src/runtime/defs_linux_power64.h204
-rw-r--r--src/runtime/defs_linux_power64le.go198
-rw-r--r--src/runtime/defs_linux_power64le.h204
-rw-r--r--src/runtime/defs_plan9_386.go2
-rw-r--r--src/runtime/defs_plan9_amd64.go2
-rw-r--r--src/runtime/env_plan9.go3
-rw-r--r--src/runtime/gengoos.go84
-rw-r--r--src/runtime/heapdump.go2
-rw-r--r--src/runtime/lfstack.go4
-rw-r--r--src/runtime/lfstack_32bit.go2
-rw-r--r--src/runtime/lfstack_linux_power64x.go20
-rw-r--r--src/runtime/malloc.go11
-rw-r--r--src/runtime/malloc2.go2
-rw-r--r--src/runtime/mem_bsd.go4
-rw-r--r--src/runtime/mem_nacl.c120
-rw-r--r--src/runtime/mem_plan9.c121
-rw-r--r--src/runtime/mem_plan9.go70
-rw-r--r--src/runtime/mgc0.go16
-rw-r--r--src/runtime/netpoll_stub.go (renamed from src/runtime/netpoll_stub.c)9
-rw-r--r--src/runtime/netpoll_windows.go4
-rw-r--r--src/runtime/os1_nacl.go197
-rw-r--r--src/runtime/os1_netbsd.go265
-rw-r--r--src/runtime/os1_netbsd_386.go16
-rw-r--r--src/runtime/os1_netbsd_amd64.go16
-rw-r--r--src/runtime/os1_plan9.go270
-rw-r--r--src/runtime/os1_windows.go564
-rw-r--r--src/runtime/os1_windows_386.go118
-rw-r--r--src/runtime/os1_windows_amd64.go137
-rw-r--r--src/runtime/os2_nacl.go154
-rw-r--r--src/runtime/os2_netbsd.go18
-rw-r--r--src/runtime/os2_plan9.go72
-rw-r--r--src/runtime/os2_windows.go25
-rw-r--r--src/runtime/os_android.h1
-rw-r--r--src/runtime/os_android_arm.go (renamed from src/runtime/os_android.c)11
-rw-r--r--src/runtime/os_nacl.c315
-rw-r--r--src/runtime/os_nacl.go21
-rw-r--r--src/runtime/os_nacl.h162
-rw-r--r--src/runtime/os_nacl_arm.go (renamed from src/runtime/os_nacl_arm.c)19
-rw-r--r--src/runtime/os_netbsd.c371
-rw-r--r--src/runtime/os_netbsd.go32
-rw-r--r--src/runtime/os_netbsd.h31
-rw-r--r--src/runtime/os_netbsd_386.c17
-rw-r--r--src/runtime/os_netbsd_amd64.c18
-rw-r--r--src/runtime/os_plan9.c368
-rw-r--r--src/runtime/os_plan9.go27
-rw-r--r--src/runtime/os_plan9.h93
-rw-r--r--src/runtime/os_plan9_386.c150
-rw-r--r--src/runtime/os_plan9_386.go131
-rw-r--r--src/runtime/os_plan9_amd64.c158
-rw-r--r--src/runtime/os_plan9_amd64.go139
-rw-r--r--src/runtime/os_windows.c636
-rw-r--r--src/runtime/os_windows.go16
-rw-r--r--src/runtime/os_windows.h42
-rw-r--r--src/runtime/os_windows_386.c128
-rw-r--r--src/runtime/os_windows_amd64.c150
-rw-r--r--src/runtime/panic.go2
-rw-r--r--src/runtime/proc.go22
-rw-r--r--src/runtime/race/race_unix_test.go30
-rw-r--r--src/runtime/race1.go37
-rw-r--r--src/runtime/race_amd64.s43
-rw-r--r--src/runtime/runtime2.go16
-rw-r--r--src/runtime/select.go2
-rw-r--r--src/runtime/sema.go2
-rw-r--r--src/runtime/signal_android_386.h1
-rw-r--r--src/runtime/signal_android_arm.h1
-rw-r--r--src/runtime/signal_linux_386.go2
-rw-r--r--src/runtime/signal_linux_amd64.go2
-rw-r--r--src/runtime/signal_linux_arm.go2
-rw-r--r--src/runtime/signal_linux_power64.h49
-rw-r--r--src/runtime/signal_linux_power64le.h49
-rw-r--r--src/runtime/signal_linux_power64x.go71
-rw-r--r--src/runtime/signal_nacl.go45
-rw-r--r--src/runtime/signal_nacl_386.go34
-rw-r--r--src/runtime/signal_nacl_386.h23
-rw-r--r--src/runtime/signal_nacl_amd64p32.go44
-rw-r--r--src/runtime/signal_nacl_amd64p32.h31
-rw-r--r--src/runtime/signal_nacl_arm.go47
-rw-r--r--src/runtime/signal_nacl_arm.h28
-rw-r--r--src/runtime/signal_netbsd.go46
-rw-r--r--src/runtime/signal_netbsd_386.go38
-rw-r--r--src/runtime/signal_netbsd_386.h23
-rw-r--r--src/runtime/signal_netbsd_amd64.go48
-rw-r--r--src/runtime/signal_netbsd_amd64.h31
-rw-r--r--src/runtime/signal_plan9.go (renamed from src/runtime/signals_plan9.h)57
-rw-r--r--src/runtime/signal_power64x.c137
-rw-r--r--src/runtime/signal_power64x.go144
-rw-r--r--src/runtime/signals_android.h1
-rw-r--r--src/runtime/signals_nacl.h53
-rw-r--r--src/runtime/signals_netbsd.h54
-rw-r--r--src/runtime/stack1.go2
-rw-r--r--src/runtime/stack2.go2
-rw-r--r--src/runtime/stubs.go2
-rw-r--r--src/runtime/stubs2.go3
-rw-r--r--src/runtime/stubs3.go (renamed from src/runtime/arch_power64.h)16
-rw-r--r--src/runtime/sys_linux_power64x.s3
-rw-r--r--src/runtime/sys_power64x.c38
-rw-r--r--src/runtime/sys_power64x.go37
-rw-r--r--src/runtime/sys_windows_386.s16
-rw-r--r--src/runtime/sys_windows_amd64.s14
-rw-r--r--src/runtime/syscall_windows.go18
-rw-r--r--src/runtime/zgoarch_386.go12
-rw-r--r--src/runtime/zgoarch_amd64.go12
-rw-r--r--src/runtime/zgoarch_amd64p32.go12
-rw-r--r--src/runtime/zgoarch_arm.go12
-rw-r--r--src/runtime/zgoarch_power64.go12
-rw-r--r--src/runtime/zgoarch_power64le.go12
-rw-r--r--src/runtime/zgoos_android.go17
-rw-r--r--src/runtime/zgoos_darwin.go17
-rw-r--r--src/runtime/zgoos_dragonfly.go17
-rw-r--r--src/runtime/zgoos_freebsd.go17
-rw-r--r--src/runtime/zgoos_linux.go19
-rw-r--r--src/runtime/zgoos_nacl.go17
-rw-r--r--src/runtime/zgoos_netbsd.go17
-rw-r--r--src/runtime/zgoos_openbsd.go17
-rw-r--r--src/runtime/zgoos_plan9.go17
-rw-r--r--src/runtime/zgoos_solaris.go17
-rw-r--r--src/runtime/zgoos_windows.go17
135 files changed, 4013 insertions, 4065 deletions
diff --git a/src/runtime/arch1_386.go b/src/runtime/arch1_386.go
index 7746dfbf0..a73e207ed 100644
--- a/src/runtime/arch1_386.go
+++ b/src/runtime/arch1_386.go
@@ -9,7 +9,7 @@ const (
_BigEndian = 0
_CacheLineSize = 64
_RuntimeGogoBytes = 64
- _PhysPageSize = _NaCl*65536 + (1-_NaCl)*4096 // 4k normally; 64k on NaCl
+ _PhysPageSize = goos_nacl*65536 + (1-goos_nacl)*4096 // 4k normally; 64k on NaCl
_PCQuantum = 1
_Int64Align = 4
)
diff --git a/src/runtime/arch1_amd64.go b/src/runtime/arch1_amd64.go
index 83c9c2dc9..794b7f65c 100644
--- a/src/runtime/arch1_amd64.go
+++ b/src/runtime/arch1_amd64.go
@@ -8,7 +8,7 @@ const (
thechar = '6'
_BigEndian = 0
_CacheLineSize = 64
- _RuntimeGogoBytes = 64 + (_Plan9|_Solaris|_Windows)*16
+ _RuntimeGogoBytes = 64 + (goos_plan9|goos_solaris|goos_windows)*16
_PhysPageSize = 4096
_PCQuantum = 1
_Int64Align = 8
diff --git a/src/runtime/arch1_amd64p32.go b/src/runtime/arch1_amd64p32.go
new file mode 100644
index 000000000..2cee21f0c
--- /dev/null
+++ b/src/runtime/arch1_amd64p32.go
@@ -0,0 +1,15 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime
+
+const (
+ thechar = '6'
+ _BigEndian = 0
+ _CacheLineSize = 64
+ _RuntimeGogoBytes = 64
+ _PhysPageSize = 65536*goos_nacl + 4096*(1-goos_nacl)
+ _PCQuantum = 1
+ _Int64Align = 8
+)
diff --git a/src/runtime/arch1_arm.go b/src/runtime/arch1_arm.go
index 5cb79fd68..6662eaeac 100644
--- a/src/runtime/arch1_arm.go
+++ b/src/runtime/arch1_arm.go
@@ -9,7 +9,7 @@ const (
_BigEndian = 0
_CacheLineSize = 32
_RuntimeGogoBytes = 60
- _PhysPageSize = 65536*_NaCl + 4096*(1-_NaCl)
+ _PhysPageSize = 65536*goos_nacl + 4096*(1-goos_nacl)
_PCQuantum = 4
_Int64Align = 4
)
diff --git a/src/runtime/arch1_power64.go b/src/runtime/arch1_power64.go
new file mode 100644
index 000000000..01e2b70f9
--- /dev/null
+++ b/src/runtime/arch1_power64.go
@@ -0,0 +1,15 @@
+// Copyright 2014 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
+
+const (
+ thechar = '9'
+ _BigEndian = 1
+ _CacheLineSize = 64
+ _RuntimeGogoBytes = 64
+ _PhysPageSize = 65536
+ _PCQuantum = 4
+ _Int64Align = 8
+)
diff --git a/src/runtime/arch1_power64le.go b/src/runtime/arch1_power64le.go
new file mode 100644
index 000000000..6580732a3
--- /dev/null
+++ b/src/runtime/arch1_power64le.go
@@ -0,0 +1,15 @@
+// Copyright 2014 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
+
+const (
+ thechar = '9'
+ _BigEndian = 0
+ _CacheLineSize = 64
+ _RuntimeGogoBytes = 64
+ _PhysPageSize = 65536
+ _PCQuantum = 4
+ _Int64Align = 8
+)
diff --git a/src/runtime/arch_amd64p32.h b/src/runtime/arch_amd64p32.h
deleted file mode 100644
index d3e864987..000000000
--- a/src/runtime/arch_amd64p32.h
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-enum {
- thechar = '6',
- BigEndian = 0,
- CacheLineSize = 64,
- RuntimeGogoBytes = 64,
-#ifdef GOOS_nacl
- PhysPageSize = 65536,
-#else
- PhysPageSize = 4096,
-#endif
- PCQuantum = 1,
- Int64Align = 8
-};
diff --git a/src/runtime/arch_power64le.h b/src/runtime/arch_power64le.h
deleted file mode 100644
index 684ac9953..000000000
--- a/src/runtime/arch_power64le.h
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2014 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.
-
-enum {
- thechar = '9',
- BigEndian = 0,
- CacheLineSize = 64,
- RuntimeGogoBytes = 64,
- PhysPageSize = 65536,
- PCQuantum = 4,
- Int64Align = 8
-};
-
diff --git a/src/runtime/asm_amd64p32.s b/src/runtime/asm_amd64p32.s
index 60c438c1d..c87d848fe 100644
--- a/src/runtime/asm_amd64p32.s
+++ b/src/runtime/asm_amd64p32.s
@@ -169,7 +169,7 @@ TEXT runtime·mcall(SB), NOSPLIT, $0-4
// of the G stack. We need to distinguish the routine that
// lives at the bottom of the G stack from the one that lives
// at the top of the system stack because the one at the top of
-// the M stack terminates the stack walk (see topofstack()).
+// the system stack terminates the stack walk (see topofstack()).
TEXT runtime·systemstack_switch(SB), NOSPLIT, $0-0
RET
diff --git a/src/runtime/asm_power64x.s b/src/runtime/asm_power64x.s
index 6169202ea..548c88e47 100644
--- a/src/runtime/asm_power64x.s
+++ b/src/runtime/asm_power64x.s
@@ -4,7 +4,8 @@
// +build power64 power64le
-#include "zasm_GOOS_GOARCH.h"
+#include "go_asm.h"
+#include "go_tls.h"
#include "funcdata.h"
#include "textflag.h"
@@ -144,58 +145,44 @@ TEXT runtime·mcall(SB), NOSPLIT, $-8-8
BL (CTR)
BR runtime·badmcall2(SB)
-// switchtoM is a dummy routine that onM leaves at the bottom
+// systemstack_switch is a dummy routine that systemstack leaves at the bottom
// of the G stack. We need to distinguish the routine that
// lives at the bottom of the G stack from the one that lives
-// at the top of the M stack because the one at the top of
-// the M stack terminates the stack walk (see topofstack()).
-TEXT runtime·switchtoM(SB), NOSPLIT, $0-0
+// at the top of the system stack because the one at the top of
+// the system stack terminates the stack walk (see topofstack()).
+TEXT runtime·systemstack_switch(SB), NOSPLIT, $0-0
UNDEF
BL (LR) // make sure this function is not leaf
RETURN
-// func onM_signalok(fn func())
-TEXT runtime·onM_signalok(SB), NOSPLIT, $8-8
- MOVD g, R3 // R3 = g
- MOVD g_m(R3), R4 // R4 = g->m
- MOVD m_gsignal(R4), R4 // R4 = g->m->gsignal
- MOVD fn+0(FP), R11 // context for call below
- CMP R3, R4
- BEQ onsignal
- MOVD R11, 8(R1)
- BL runtime·onM(SB)
- RETURN
-
-onsignal:
- MOVD 0(R11), R3 // code pointer
- MOVD R3, CTR
- BL (CTR)
- RETURN
-
-// void onM(fn func())
-TEXT runtime·onM(SB), NOSPLIT, $0-8
+// func systemstack(fn func())
+TEXT runtime·systemstack(SB), NOSPLIT, $0-8
MOVD fn+0(FP), R3 // R3 = fn
MOVD R3, R11 // context
MOVD g_m(g), R4 // R4 = m
+ MOVD m_gsignal(R4), R5 // R5 = gsignal
+ CMP g, R5
+ BEQ noswitch
+
MOVD m_g0(R4), R5 // R5 = g0
CMP g, R5
- BEQ onm
+ BEQ noswitch
MOVD m_curg(R4), R6
CMP g, R6
- BEQ oncurg
+ BEQ switch
- // Not g0, not curg. Must be gsignal, but that's not allowed.
+ // Bad: g is not gsignal, not g0, not curg. What is it?
// Hide call from linker nosplit analysis.
- MOVD $runtime·badonm(SB), R3
+ MOVD $runtime·badsystemstack(SB), R3
MOVD R3, CTR
BL (CTR)
-oncurg:
+switch:
// save our state in g->sched. Pretend to
- // be switchtoM if the G stack is scanned.
- MOVD $runtime·switchtoM(SB), R6
+ // be systemstack_switch if the G stack is scanned.
+ MOVD $runtime·systemstack_switch(SB), R6
ADD $8, R6 // get past prologue
MOVD R6, (g_sched+gobuf_pc)(g)
MOVD R1, (g_sched+gobuf_sp)(g)
@@ -205,7 +192,7 @@ oncurg:
// switch to g0
MOVD R5, g
MOVD (g_sched+gobuf_sp)(g), R3
- // make it look like mstart called onM on g0, to stop traceback
+ // make it look like mstart called systemstack on g0, to stop traceback
SUB $8, R3
MOVD $runtime·mstart(SB), R4
MOVD R4, 0(R3)
@@ -223,7 +210,7 @@ oncurg:
MOVD R0, (g_sched+gobuf_sp)(g)
RETURN
-onm:
+noswitch:
// already on m stack, just call directly
MOVD 0(R11), R3 // code pointer
MOVD R3, CTR
@@ -987,6 +974,10 @@ TEXT runtime·goexit(SB),NOSPLIT,$-8-0
MOVD R0, R0 // NOP
BL runtime·goexit1(SB) // does not return
+TEXT runtime·getg(SB),NOSPLIT,$-8-8
+ MOVD g, ret+0(FP)
+ RETURN
+
TEXT runtime·prefetcht0(SB),NOSPLIT,$0-8
RETURN
diff --git a/src/runtime/atomic_power64x.go b/src/runtime/atomic_power64x.go
new file mode 100644
index 000000000..a0dcf514b
--- /dev/null
+++ b/src/runtime/atomic_power64x.go
@@ -0,0 +1,69 @@
+// Copyright 2014 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.
+
+// +build power64 power64le
+
+package runtime
+
+import "unsafe"
+
+//go:noescape
+func xadd(ptr *uint32, delta int32) uint32
+
+//go:noescape
+func xadd64(ptr *uint64, delta int64) uint64
+
+//go:noescape
+func xchg(ptr *uint32, new uint32) uint32
+
+//go:noescape
+func xchg64(ptr *uint64, new uint64) uint64
+
+// xchgp cannot have a go:noescape annotation, because
+// while ptr does not escape, new does. If new is marked as
+// not escaping, the compiler will make incorrect escape analysis
+// decisions about the value being xchg'ed.
+// Instead, make xchgp a wrapper around the actual atomic.
+// When calling the wrapper we mark ptr as noescape explicitly.
+
+//go:nosplit
+func xchgp(ptr unsafe.Pointer, new unsafe.Pointer) unsafe.Pointer {
+ return xchgp1(noescape(ptr), new)
+}
+
+func xchgp1(ptr unsafe.Pointer, new unsafe.Pointer) unsafe.Pointer
+
+//go:noescape
+func xchguintptr(ptr *uintptr, new uintptr) uintptr
+
+//go:noescape
+func atomicload(ptr *uint32) uint32
+
+//go:noescape
+func atomicload64(ptr *uint64) uint64
+
+//go:noescape
+func atomicloadp(ptr unsafe.Pointer) unsafe.Pointer
+
+//go:noescape
+func atomicor8(ptr *uint8, val uint8)
+
+//go:noescape
+func cas64(ptr *uint64, old, new uint64) bool
+
+//go:noescape
+func atomicstore(ptr *uint32, val uint32)
+
+//go:noescape
+func atomicstore64(ptr *uint64, val uint64)
+
+// atomicstorep cannot have a go:noescape annotation.
+// See comment above for xchgp.
+
+//go:nosplit
+func atomicstorep(ptr unsafe.Pointer, new unsafe.Pointer) {
+ atomicstorep1(noescape(ptr), new)
+}
+
+func atomicstorep1(ptr unsafe.Pointer, val unsafe.Pointer)
diff --git a/src/runtime/chan.go b/src/runtime/chan.go
index bb0110f94..330422ad0 100644
--- a/src/runtime/chan.go
+++ b/src/runtime/chan.go
@@ -630,6 +630,7 @@ func (q *waitq) dequeue() *sudog {
return nil
}
q.first = sgp.next
+ sgp.next = nil
if q.last == sgp {
q.last = nil
}
diff --git a/src/runtime/defs1_netbsd_386.go b/src/runtime/defs1_netbsd_386.go
index e39fd04c7..f222bed99 100644
--- a/src/runtime/defs1_netbsd_386.go
+++ b/src/runtime/defs1_netbsd_386.go
@@ -84,8 +84,8 @@ const (
)
type sigaltstackt struct {
- ss_sp *byte
- ss_size uint32
+ ss_sp uintptr
+ ss_size uintptr
ss_flags int32
}
@@ -101,8 +101,8 @@ type siginfo struct {
}
type stackt struct {
- ss_sp *byte
- ss_size uint32
+ ss_sp uintptr
+ ss_size uintptr
ss_flags int32
}
@@ -111,18 +111,30 @@ type timespec struct {
tv_nsec int32
}
+func (ts *timespec) set_sec(x int32) {
+ ts.tv_sec = int64(x)
+}
+
+func (ts *timespec) set_nsec(x int32) {
+ ts.tv_nsec = x
+}
+
type timeval struct {
tv_sec int64
tv_usec int32
}
+func (tv *timeval) set_usec(x int32) {
+ tv.tv_usec = x
+}
+
type itimerval struct {
it_interval timeval
it_value timeval
}
type mcontextt struct {
- __gregs [19]int32
+ __gregs [19]uint32
__fpregs [644]byte
_mc_tlsbase int32
}
diff --git a/src/runtime/defs1_netbsd_amd64.go b/src/runtime/defs1_netbsd_amd64.go
index cca701e5b..c2bde4dab 100644
--- a/src/runtime/defs1_netbsd_amd64.go
+++ b/src/runtime/defs1_netbsd_amd64.go
@@ -84,8 +84,8 @@ const (
)
type sigaltstackt struct {
- ss_sp *byte
- ss_size uint64
+ ss_sp uintptr
+ ss_size uintptr
ss_flags int32
pad_cgo_0 [4]byte
}
@@ -103,8 +103,8 @@ type siginfo struct {
}
type stackt struct {
- ss_sp *byte
- ss_size uint64
+ ss_sp uintptr
+ ss_size uintptr
ss_flags int32
pad_cgo_0 [4]byte
}
@@ -114,12 +114,24 @@ type timespec struct {
tv_nsec int64
}
+func (ts *timespec) set_sec(x int32) {
+ ts.tv_sec = int64(x)
+}
+
+func (ts *timespec) set_nsec(x int32) {
+ ts.tv_nsec = int64(x)
+}
+
type timeval struct {
tv_sec int64
tv_usec int32
pad_cgo_0 [4]byte
}
+func (tv *timeval) set_usec(x int32) {
+ tv.tv_usec = x
+}
+
type itimerval struct {
it_interval timeval
it_value timeval
diff --git a/src/runtime/defs_linux_386.go b/src/runtime/defs_linux_386.go
index ddf592c91..f55924b61 100644
--- a/src/runtime/defs_linux_386.go
+++ b/src/runtime/defs_linux_386.go
@@ -155,10 +155,11 @@ type sigactiont struct {
}
type siginfo struct {
- si_signo int32
- si_errno int32
- si_code int32
- _sifields [116]byte
+ si_signo int32
+ si_errno int32
+ si_code int32
+ // below here is a union; si_addr is the only field we use
+ si_addr uint32
}
type sigaltstackt struct {
diff --git a/src/runtime/defs_linux_amd64.go b/src/runtime/defs_linux_amd64.go
index 7f8f5816c..a73f47514 100644
--- a/src/runtime/defs_linux_amd64.go
+++ b/src/runtime/defs_linux_amd64.go
@@ -117,11 +117,11 @@ type sigactiont struct {
}
type siginfo struct {
- si_signo int32
- si_errno int32
- si_code int32
- pad_cgo_0 [4]byte
- _sifields [112]byte
+ si_signo int32
+ si_errno int32
+ si_code int32
+ // below here is a union; si_addr is the only field we use
+ si_addr uint64
}
type itimerval struct {
diff --git a/src/runtime/defs_linux_arm.go b/src/runtime/defs_linux_arm.go
index a874b1594..c3a6e2f01 100644
--- a/src/runtime/defs_linux_arm.go
+++ b/src/runtime/defs_linux_arm.go
@@ -147,10 +147,11 @@ type itimerval struct {
}
type siginfo struct {
- si_signo int32
- si_errno int32
- si_code int32
- _sifields [4]uint8
+ si_signo int32
+ si_errno int32
+ si_code int32
+ // below here is a union; si_addr is the only field we use
+ si_addr uint32
}
type sigactiont struct {
diff --git a/src/runtime/defs_linux_power64.go b/src/runtime/defs_linux_power64.go
new file mode 100644
index 000000000..f90b84874
--- /dev/null
+++ b/src/runtime/defs_linux_power64.go
@@ -0,0 +1,198 @@
+// created by cgo -cdefs and then converted to Go
+// cgo -cdefs defs_linux.go defs3_linux.go
+
+package runtime
+
+const (
+ _EINTR = 0x4
+ _EAGAIN = 0xb
+ _ENOMEM = 0xc
+
+ _PROT_NONE = 0x0
+ _PROT_READ = 0x1
+ _PROT_WRITE = 0x2
+ _PROT_EXEC = 0x4
+
+ _MAP_ANON = 0x20
+ _MAP_PRIVATE = 0x2
+ _MAP_FIXED = 0x10
+
+ _MADV_DONTNEED = 0x4
+
+ _SA_RESTART = 0x10000000
+ _SA_ONSTACK = 0x8000000
+ _SA_SIGINFO = 0x4
+
+ _SIGHUP = 0x1
+ _SIGINT = 0x2
+ _SIGQUIT = 0x3
+ _SIGILL = 0x4
+ _SIGTRAP = 0x5
+ _SIGABRT = 0x6
+ _SIGBUS = 0x7
+ _SIGFPE = 0x8
+ _SIGKILL = 0x9
+ _SIGUSR1 = 0xa
+ _SIGSEGV = 0xb
+ _SIGUSR2 = 0xc
+ _SIGPIPE = 0xd
+ _SIGALRM = 0xe
+ _SIGSTKFLT = 0x10
+ _SIGCHLD = 0x11
+ _SIGCONT = 0x12
+ _SIGSTOP = 0x13
+ _SIGTSTP = 0x14
+ _SIGTTIN = 0x15
+ _SIGTTOU = 0x16
+ _SIGURG = 0x17
+ _SIGXCPU = 0x18
+ _SIGXFSZ = 0x19
+ _SIGVTALRM = 0x1a
+ _SIGPROF = 0x1b
+ _SIGWINCH = 0x1c
+ _SIGIO = 0x1d
+ _SIGPWR = 0x1e
+ _SIGSYS = 0x1f
+
+ _FPE_INTDIV = 0x1
+ _FPE_INTOVF = 0x2
+ _FPE_FLTDIV = 0x3
+ _FPE_FLTOVF = 0x4
+ _FPE_FLTUND = 0x5
+ _FPE_FLTRES = 0x6
+ _FPE_FLTINV = 0x7
+ _FPE_FLTSUB = 0x8
+
+ _BUS_ADRALN = 0x1
+ _BUS_ADRERR = 0x2
+ _BUS_OBJERR = 0x3
+
+ _SEGV_MAPERR = 0x1
+ _SEGV_ACCERR = 0x2
+
+ _ITIMER_REAL = 0x0
+ _ITIMER_VIRTUAL = 0x1
+ _ITIMER_PROF = 0x2
+
+ _EPOLLIN = 0x1
+ _EPOLLOUT = 0x4
+ _EPOLLERR = 0x8
+ _EPOLLHUP = 0x10
+ _EPOLLRDHUP = 0x2000
+ _EPOLLET = 0x80000000
+ _EPOLL_CLOEXEC = 0x80000
+ _EPOLL_CTL_ADD = 0x1
+ _EPOLL_CTL_DEL = 0x2
+ _EPOLL_CTL_MOD = 0x3
+)
+
+//struct Sigset {
+// uint64 sig[1];
+//};
+//typedef uint64 Sigset;
+
+type timespec struct {
+ tv_sec int64
+ tv_nsec int64
+}
+
+func (ts *timespec) set_sec(x int64) {
+ ts.tv_sec = x
+}
+
+func (ts *timespec) set_nsec(x int32) {
+ ts.tv_nsec = int64(x)
+}
+
+type timeval struct {
+ tv_sec int64
+ tv_usec int64
+}
+
+func (tv *timeval) set_usec(x int32) {
+ tv.tv_usec = int64(x)
+}
+
+type sigactiont struct {
+ sa_handler uintptr
+ sa_flags uint64
+ sa_restorer uintptr
+ sa_mask uint64
+}
+
+type siginfo struct {
+ si_signo int32
+ si_errno int32
+ si_code int32
+ // below here is a union; si_addr is the only field we use
+ si_addr uint64
+}
+
+type itimerval struct {
+ it_interval timeval
+ it_value timeval
+}
+
+type epollevent struct {
+ events uint32
+ pad_cgo_0 [4]byte
+ data [8]byte // unaligned uintptr
+}
+
+// created by cgo -cdefs and then converted to Go
+// cgo -cdefs defs_linux.go defs3_linux.go
+
+const (
+ _O_RDONLY = 0x0
+ _O_CLOEXEC = 0x80000
+ _SA_RESTORER = 0
+)
+
+type ptregs struct {
+ gpr [32]uint64
+ nip uint64
+ msr uint64
+ orig_gpr3 uint64
+ ctr uint64
+ link uint64
+ xer uint64
+ ccr uint64
+ softe uint64
+ trap uint64
+ dar uint64
+ dsisr uint64
+ result uint64
+}
+
+type vreg struct {
+ u [4]uint32
+}
+
+type sigaltstackt struct {
+ ss_sp *byte
+ ss_flags int32
+ pad_cgo_0 [4]byte
+ ss_size uintptr
+}
+
+type sigcontext struct {
+ _unused [4]uint64
+ signal int32
+ _pad0 int32
+ handler uint64
+ oldmask uint64
+ regs *ptregs
+ gp_regs [48]uint64
+ fp_regs [33]float64
+ v_regs *vreg
+ vmx_reserve [101]int64
+}
+
+type ucontext struct {
+ uc_flags uint64
+ uc_link *ucontext
+ uc_stack sigaltstackt
+ uc_sigmask uint64
+ __unused [15]uint64
+ uc_mcontext sigcontext
+}
diff --git a/src/runtime/defs_linux_power64.h b/src/runtime/defs_linux_power64.h
deleted file mode 100644
index 93742fa34..000000000
--- a/src/runtime/defs_linux_power64.h
+++ /dev/null
@@ -1,204 +0,0 @@
-// Created by cgo -cdefs - DO NOT EDIT
-// cgo -cdefs defs_linux.go defs3_linux.go
-
-
-enum {
- EINTR = 0x4,
- EAGAIN = 0xb,
- ENOMEM = 0xc,
-
- PROT_NONE = 0x0,
- PROT_READ = 0x1,
- PROT_WRITE = 0x2,
- PROT_EXEC = 0x4,
-
- MAP_ANON = 0x20,
- MAP_PRIVATE = 0x2,
- MAP_FIXED = 0x10,
-
- MADV_DONTNEED = 0x4,
-
- SA_RESTART = 0x10000000,
- SA_ONSTACK = 0x8000000,
- SA_SIGINFO = 0x4,
-
- SIGHUP = 0x1,
- SIGINT = 0x2,
- SIGQUIT = 0x3,
- SIGILL = 0x4,
- SIGTRAP = 0x5,
- SIGABRT = 0x6,
- SIGBUS = 0x7,
- SIGFPE = 0x8,
- SIGKILL = 0x9,
- SIGUSR1 = 0xa,
- SIGSEGV = 0xb,
- SIGUSR2 = 0xc,
- SIGPIPE = 0xd,
- SIGALRM = 0xe,
- SIGSTKFLT = 0x10,
- SIGCHLD = 0x11,
- SIGCONT = 0x12,
- SIGSTOP = 0x13,
- SIGTSTP = 0x14,
- SIGTTIN = 0x15,
- SIGTTOU = 0x16,
- SIGURG = 0x17,
- SIGXCPU = 0x18,
- SIGXFSZ = 0x19,
- SIGVTALRM = 0x1a,
- SIGPROF = 0x1b,
- SIGWINCH = 0x1c,
- SIGIO = 0x1d,
- SIGPWR = 0x1e,
- SIGSYS = 0x1f,
-
- FPE_INTDIV = 0x1,
- FPE_INTOVF = 0x2,
- FPE_FLTDIV = 0x3,
- FPE_FLTOVF = 0x4,
- FPE_FLTUND = 0x5,
- FPE_FLTRES = 0x6,
- FPE_FLTINV = 0x7,
- FPE_FLTSUB = 0x8,
-
- BUS_ADRALN = 0x1,
- BUS_ADRERR = 0x2,
- BUS_OBJERR = 0x3,
-
- SEGV_MAPERR = 0x1,
- SEGV_ACCERR = 0x2,
-
- ITIMER_REAL = 0x0,
- ITIMER_VIRTUAL = 0x1,
- ITIMER_PROF = 0x2,
-
- EPOLLIN = 0x1,
- EPOLLOUT = 0x4,
- EPOLLERR = 0x8,
- EPOLLHUP = 0x10,
- EPOLLRDHUP = 0x2000,
- EPOLLET = -0x80000000,
- EPOLL_CLOEXEC = 0x80000,
- EPOLL_CTL_ADD = 0x1,
- EPOLL_CTL_DEL = 0x2,
- EPOLL_CTL_MOD = 0x3,
-};
-
-typedef struct Sigset Sigset;
-typedef struct Timespec Timespec;
-typedef struct Timeval Timeval;
-typedef struct SigactionT SigactionT;
-typedef struct Siginfo Siginfo;
-typedef struct Itimerval Itimerval;
-typedef struct EpollEvent EpollEvent;
-
-#pragma pack on
-
-//struct Sigset {
-// uint64 sig[1];
-//};
-//typedef uint64 Sigset;
-
-struct Timespec {
- int64 tv_sec;
- int64 tv_nsec;
-};
-struct Timeval {
- int64 tv_sec;
- int64 tv_usec;
-};
-struct SigactionT {
- void *sa_handler;
- uint64 sa_flags;
- void *sa_restorer;
- uint64 sa_mask;
-};
-struct Siginfo {
- int32 si_signo;
- int32 si_errno;
- int32 si_code;
- byte Pad_cgo_0[4];
- byte _sifields[112];
-};
-struct Itimerval {
- Timeval it_interval;
- Timeval it_value;
-};
-struct EpollEvent {
- uint32 events;
- byte Pad_cgo_0[4];
- byte data[8]; // unaligned uintptr
-};
-
-
-#pragma pack off
-// Created by cgo -cdefs - DO NOT EDIT
-// cgo -cdefs defs_linux.go defs3_linux.go
-
-
-enum {
- O_RDONLY = 0x0,
- O_CLOEXEC = 0x80000,
- SA_RESTORER = 0,
-};
-
-typedef struct Ptregs Ptregs;
-typedef struct Vreg Vreg;
-typedef struct SigaltstackT SigaltstackT;
-typedef struct Sigcontext Sigcontext;
-typedef struct Ucontext Ucontext;
-
-#pragma pack on
-
-struct Ptregs {
- uint64 gpr[32];
- uint64 nip;
- uint64 msr;
- uint64 orig_gpr3;
- uint64 ctr;
- uint64 link;
- uint64 xer;
- uint64 ccr;
- uint64 softe;
- uint64 trap;
- uint64 dar;
- uint64 dsisr;
- uint64 result;
-};
-typedef uint64 Gregset[48];
-typedef float64 FPregset[33];
-struct Vreg {
- uint32 u[4];
-};
-
-struct SigaltstackT {
- byte *ss_sp;
- int32 ss_flags;
- byte Pad_cgo_0[4];
- uint64 ss_size;
-};
-
-struct Sigcontext {
- uint64 _unused[4];
- int32 signal;
- int32 _pad0;
- uint64 handler;
- uint64 oldmask;
- Ptregs *regs;
- uint64 gp_regs[48];
- float64 fp_regs[33];
- Vreg *v_regs;
- int64 vmx_reserve[101];
-};
-struct Ucontext {
- uint64 uc_flags;
- Ucontext *uc_link;
- SigaltstackT uc_stack;
- uint64 uc_sigmask;
- uint64 __unused[15];
- Sigcontext uc_mcontext;
-};
-
-
-#pragma pack off
diff --git a/src/runtime/defs_linux_power64le.go b/src/runtime/defs_linux_power64le.go
new file mode 100644
index 000000000..f90b84874
--- /dev/null
+++ b/src/runtime/defs_linux_power64le.go
@@ -0,0 +1,198 @@
+// created by cgo -cdefs and then converted to Go
+// cgo -cdefs defs_linux.go defs3_linux.go
+
+package runtime
+
+const (
+ _EINTR = 0x4
+ _EAGAIN = 0xb
+ _ENOMEM = 0xc
+
+ _PROT_NONE = 0x0
+ _PROT_READ = 0x1
+ _PROT_WRITE = 0x2
+ _PROT_EXEC = 0x4
+
+ _MAP_ANON = 0x20
+ _MAP_PRIVATE = 0x2
+ _MAP_FIXED = 0x10
+
+ _MADV_DONTNEED = 0x4
+
+ _SA_RESTART = 0x10000000
+ _SA_ONSTACK = 0x8000000
+ _SA_SIGINFO = 0x4
+
+ _SIGHUP = 0x1
+ _SIGINT = 0x2
+ _SIGQUIT = 0x3
+ _SIGILL = 0x4
+ _SIGTRAP = 0x5
+ _SIGABRT = 0x6
+ _SIGBUS = 0x7
+ _SIGFPE = 0x8
+ _SIGKILL = 0x9
+ _SIGUSR1 = 0xa
+ _SIGSEGV = 0xb
+ _SIGUSR2 = 0xc
+ _SIGPIPE = 0xd
+ _SIGALRM = 0xe
+ _SIGSTKFLT = 0x10
+ _SIGCHLD = 0x11
+ _SIGCONT = 0x12
+ _SIGSTOP = 0x13
+ _SIGTSTP = 0x14
+ _SIGTTIN = 0x15
+ _SIGTTOU = 0x16
+ _SIGURG = 0x17
+ _SIGXCPU = 0x18
+ _SIGXFSZ = 0x19
+ _SIGVTALRM = 0x1a
+ _SIGPROF = 0x1b
+ _SIGWINCH = 0x1c
+ _SIGIO = 0x1d
+ _SIGPWR = 0x1e
+ _SIGSYS = 0x1f
+
+ _FPE_INTDIV = 0x1
+ _FPE_INTOVF = 0x2
+ _FPE_FLTDIV = 0x3
+ _FPE_FLTOVF = 0x4
+ _FPE_FLTUND = 0x5
+ _FPE_FLTRES = 0x6
+ _FPE_FLTINV = 0x7
+ _FPE_FLTSUB = 0x8
+
+ _BUS_ADRALN = 0x1
+ _BUS_ADRERR = 0x2
+ _BUS_OBJERR = 0x3
+
+ _SEGV_MAPERR = 0x1
+ _SEGV_ACCERR = 0x2
+
+ _ITIMER_REAL = 0x0
+ _ITIMER_VIRTUAL = 0x1
+ _ITIMER_PROF = 0x2
+
+ _EPOLLIN = 0x1
+ _EPOLLOUT = 0x4
+ _EPOLLERR = 0x8
+ _EPOLLHUP = 0x10
+ _EPOLLRDHUP = 0x2000
+ _EPOLLET = 0x80000000
+ _EPOLL_CLOEXEC = 0x80000
+ _EPOLL_CTL_ADD = 0x1
+ _EPOLL_CTL_DEL = 0x2
+ _EPOLL_CTL_MOD = 0x3
+)
+
+//struct Sigset {
+// uint64 sig[1];
+//};
+//typedef uint64 Sigset;
+
+type timespec struct {
+ tv_sec int64
+ tv_nsec int64
+}
+
+func (ts *timespec) set_sec(x int64) {
+ ts.tv_sec = x
+}
+
+func (ts *timespec) set_nsec(x int32) {
+ ts.tv_nsec = int64(x)
+}
+
+type timeval struct {
+ tv_sec int64
+ tv_usec int64
+}
+
+func (tv *timeval) set_usec(x int32) {
+ tv.tv_usec = int64(x)
+}
+
+type sigactiont struct {
+ sa_handler uintptr
+ sa_flags uint64
+ sa_restorer uintptr
+ sa_mask uint64
+}
+
+type siginfo struct {
+ si_signo int32
+ si_errno int32
+ si_code int32
+ // below here is a union; si_addr is the only field we use
+ si_addr uint64
+}
+
+type itimerval struct {
+ it_interval timeval
+ it_value timeval
+}
+
+type epollevent struct {
+ events uint32
+ pad_cgo_0 [4]byte
+ data [8]byte // unaligned uintptr
+}
+
+// created by cgo -cdefs and then converted to Go
+// cgo -cdefs defs_linux.go defs3_linux.go
+
+const (
+ _O_RDONLY = 0x0
+ _O_CLOEXEC = 0x80000
+ _SA_RESTORER = 0
+)
+
+type ptregs struct {
+ gpr [32]uint64
+ nip uint64
+ msr uint64
+ orig_gpr3 uint64
+ ctr uint64
+ link uint64
+ xer uint64
+ ccr uint64
+ softe uint64
+ trap uint64
+ dar uint64
+ dsisr uint64
+ result uint64
+}
+
+type vreg struct {
+ u [4]uint32
+}
+
+type sigaltstackt struct {
+ ss_sp *byte
+ ss_flags int32
+ pad_cgo_0 [4]byte
+ ss_size uintptr
+}
+
+type sigcontext struct {
+ _unused [4]uint64
+ signal int32
+ _pad0 int32
+ handler uint64
+ oldmask uint64
+ regs *ptregs
+ gp_regs [48]uint64
+ fp_regs [33]float64
+ v_regs *vreg
+ vmx_reserve [101]int64
+}
+
+type ucontext struct {
+ uc_flags uint64
+ uc_link *ucontext
+ uc_stack sigaltstackt
+ uc_sigmask uint64
+ __unused [15]uint64
+ uc_mcontext sigcontext
+}
diff --git a/src/runtime/defs_linux_power64le.h b/src/runtime/defs_linux_power64le.h
deleted file mode 100644
index 93742fa34..000000000
--- a/src/runtime/defs_linux_power64le.h
+++ /dev/null
@@ -1,204 +0,0 @@
-// Created by cgo -cdefs - DO NOT EDIT
-// cgo -cdefs defs_linux.go defs3_linux.go
-
-
-enum {
- EINTR = 0x4,
- EAGAIN = 0xb,
- ENOMEM = 0xc,
-
- PROT_NONE = 0x0,
- PROT_READ = 0x1,
- PROT_WRITE = 0x2,
- PROT_EXEC = 0x4,
-
- MAP_ANON = 0x20,
- MAP_PRIVATE = 0x2,
- MAP_FIXED = 0x10,
-
- MADV_DONTNEED = 0x4,
-
- SA_RESTART = 0x10000000,
- SA_ONSTACK = 0x8000000,
- SA_SIGINFO = 0x4,
-
- SIGHUP = 0x1,
- SIGINT = 0x2,
- SIGQUIT = 0x3,
- SIGILL = 0x4,
- SIGTRAP = 0x5,
- SIGABRT = 0x6,
- SIGBUS = 0x7,
- SIGFPE = 0x8,
- SIGKILL = 0x9,
- SIGUSR1 = 0xa,
- SIGSEGV = 0xb,
- SIGUSR2 = 0xc,
- SIGPIPE = 0xd,
- SIGALRM = 0xe,
- SIGSTKFLT = 0x10,
- SIGCHLD = 0x11,
- SIGCONT = 0x12,
- SIGSTOP = 0x13,
- SIGTSTP = 0x14,
- SIGTTIN = 0x15,
- SIGTTOU = 0x16,
- SIGURG = 0x17,
- SIGXCPU = 0x18,
- SIGXFSZ = 0x19,
- SIGVTALRM = 0x1a,
- SIGPROF = 0x1b,
- SIGWINCH = 0x1c,
- SIGIO = 0x1d,
- SIGPWR = 0x1e,
- SIGSYS = 0x1f,
-
- FPE_INTDIV = 0x1,
- FPE_INTOVF = 0x2,
- FPE_FLTDIV = 0x3,
- FPE_FLTOVF = 0x4,
- FPE_FLTUND = 0x5,
- FPE_FLTRES = 0x6,
- FPE_FLTINV = 0x7,
- FPE_FLTSUB = 0x8,
-
- BUS_ADRALN = 0x1,
- BUS_ADRERR = 0x2,
- BUS_OBJERR = 0x3,
-
- SEGV_MAPERR = 0x1,
- SEGV_ACCERR = 0x2,
-
- ITIMER_REAL = 0x0,
- ITIMER_VIRTUAL = 0x1,
- ITIMER_PROF = 0x2,
-
- EPOLLIN = 0x1,
- EPOLLOUT = 0x4,
- EPOLLERR = 0x8,
- EPOLLHUP = 0x10,
- EPOLLRDHUP = 0x2000,
- EPOLLET = -0x80000000,
- EPOLL_CLOEXEC = 0x80000,
- EPOLL_CTL_ADD = 0x1,
- EPOLL_CTL_DEL = 0x2,
- EPOLL_CTL_MOD = 0x3,
-};
-
-typedef struct Sigset Sigset;
-typedef struct Timespec Timespec;
-typedef struct Timeval Timeval;
-typedef struct SigactionT SigactionT;
-typedef struct Siginfo Siginfo;
-typedef struct Itimerval Itimerval;
-typedef struct EpollEvent EpollEvent;
-
-#pragma pack on
-
-//struct Sigset {
-// uint64 sig[1];
-//};
-//typedef uint64 Sigset;
-
-struct Timespec {
- int64 tv_sec;
- int64 tv_nsec;
-};
-struct Timeval {
- int64 tv_sec;
- int64 tv_usec;
-};
-struct SigactionT {
- void *sa_handler;
- uint64 sa_flags;
- void *sa_restorer;
- uint64 sa_mask;
-};
-struct Siginfo {
- int32 si_signo;
- int32 si_errno;
- int32 si_code;
- byte Pad_cgo_0[4];
- byte _sifields[112];
-};
-struct Itimerval {
- Timeval it_interval;
- Timeval it_value;
-};
-struct EpollEvent {
- uint32 events;
- byte Pad_cgo_0[4];
- byte data[8]; // unaligned uintptr
-};
-
-
-#pragma pack off
-// Created by cgo -cdefs - DO NOT EDIT
-// cgo -cdefs defs_linux.go defs3_linux.go
-
-
-enum {
- O_RDONLY = 0x0,
- O_CLOEXEC = 0x80000,
- SA_RESTORER = 0,
-};
-
-typedef struct Ptregs Ptregs;
-typedef struct Vreg Vreg;
-typedef struct SigaltstackT SigaltstackT;
-typedef struct Sigcontext Sigcontext;
-typedef struct Ucontext Ucontext;
-
-#pragma pack on
-
-struct Ptregs {
- uint64 gpr[32];
- uint64 nip;
- uint64 msr;
- uint64 orig_gpr3;
- uint64 ctr;
- uint64 link;
- uint64 xer;
- uint64 ccr;
- uint64 softe;
- uint64 trap;
- uint64 dar;
- uint64 dsisr;
- uint64 result;
-};
-typedef uint64 Gregset[48];
-typedef float64 FPregset[33];
-struct Vreg {
- uint32 u[4];
-};
-
-struct SigaltstackT {
- byte *ss_sp;
- int32 ss_flags;
- byte Pad_cgo_0[4];
- uint64 ss_size;
-};
-
-struct Sigcontext {
- uint64 _unused[4];
- int32 signal;
- int32 _pad0;
- uint64 handler;
- uint64 oldmask;
- Ptregs *regs;
- uint64 gp_regs[48];
- float64 fp_regs[33];
- Vreg *v_regs;
- int64 vmx_reserve[101];
-};
-struct Ucontext {
- uint64 uc_flags;
- Ucontext *uc_link;
- SigaltstackT uc_stack;
- uint64 uc_sigmask;
- uint64 __unused[15];
- Sigcontext uc_mcontext;
-};
-
-
-#pragma pack off
diff --git a/src/runtime/defs_plan9_386.go b/src/runtime/defs_plan9_386.go
index 170506b23..212ecdf14 100644
--- a/src/runtime/defs_plan9_386.go
+++ b/src/runtime/defs_plan9_386.go
@@ -1,5 +1,7 @@
package runtime
+const _PAGESIZE = 0x1000
+
type ureg struct {
di uint32 /* general registers */
si uint32 /* ... */
diff --git a/src/runtime/defs_plan9_amd64.go b/src/runtime/defs_plan9_amd64.go
index 17becfb66..510da0e99 100644
--- a/src/runtime/defs_plan9_amd64.go
+++ b/src/runtime/defs_plan9_amd64.go
@@ -1,5 +1,7 @@
package runtime
+const _PAGESIZE = 0x1000
+
type ureg struct {
ax uint64
bx uint64
diff --git a/src/runtime/env_plan9.go b/src/runtime/env_plan9.go
index e442c3483..ec50cac48 100644
--- a/src/runtime/env_plan9.go
+++ b/src/runtime/env_plan9.go
@@ -54,3 +54,6 @@ func gogetenv(key string) string {
sp.len = int(r)
return s
}
+
+var _cgo_setenv unsafe.Pointer // pointer to C function
+var _cgo_unsetenv unsafe.Pointer // pointer to C function
diff --git a/src/runtime/gengoos.go b/src/runtime/gengoos.go
new file mode 100644
index 000000000..06621c8db
--- /dev/null
+++ b/src/runtime/gengoos.go
@@ -0,0 +1,84 @@
+// Copyright 2014 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.
+
+// +build ignore
+
+package main
+
+import (
+ "bytes"
+ "fmt"
+ "io/ioutil"
+ "log"
+ "strconv"
+ "strings"
+)
+
+var gooses, goarches []string
+
+func main() {
+ data, err := ioutil.ReadFile("../go/build/syslist.go")
+ if err != nil {
+ log.Fatal(err)
+ }
+ const (
+ goosPrefix = `const goosList = `
+ goarchPrefix = `const goarchList = `
+ )
+ for _, line := range strings.Split(string(data), "\n") {
+ if strings.HasPrefix(line, goosPrefix) {
+ text, err := strconv.Unquote(strings.TrimPrefix(line, goosPrefix))
+ if err != nil {
+ log.Fatalf("parsing goosList %#q: %v", strings.TrimPrefix(line, goosPrefix), err)
+ }
+ gooses = strings.Fields(text)
+ }
+ if strings.HasPrefix(line, goarchPrefix) {
+ text, err := strconv.Unquote(strings.TrimPrefix(line, goarchPrefix))
+ if err != nil {
+ log.Fatal("parsing goarchList: %v", err)
+ }
+ goarches = strings.Fields(text)
+ }
+ }
+
+ for _, target := range gooses {
+ var buf bytes.Buffer
+ fmt.Fprintf(&buf, "// generated by gengoos.go using 'go generate'\n\n")
+ if target == "linux" {
+ fmt.Fprintf(&buf, "// +build !android\n\n") // must explicitly exclude android for linux
+ }
+ fmt.Fprintf(&buf, "package runtime\n\n")
+ fmt.Fprintf(&buf, "const theGoos = `%s`\n\n", target)
+ for _, goos := range gooses {
+ value := 0
+ if goos == target {
+ value = 1
+ }
+ fmt.Fprintf(&buf, "const goos_%s = %d\n", goos, value)
+ }
+ err := ioutil.WriteFile("zgoos_"+target+".go", buf.Bytes(), 0666)
+ if err != nil {
+ log.Fatal(err)
+ }
+ }
+
+ for _, target := range goarches {
+ var buf bytes.Buffer
+ fmt.Fprintf(&buf, "// generated by gengoos.go using 'go generate'\n\n")
+ fmt.Fprintf(&buf, "package runtime\n\n")
+ fmt.Fprintf(&buf, "const theGoarch = `%s`\n\n", target)
+ for _, goarch := range goarches {
+ value := 0
+ if goarch == target {
+ value = 1
+ }
+ fmt.Fprintf(&buf, "const goarch_%s = %d\n", goarch, value)
+ }
+ err := ioutil.WriteFile("zgoarch_"+target+".go", buf.Bytes(), 0666)
+ if err != nil {
+ log.Fatal(err)
+ }
+ }
+}
diff --git a/src/runtime/heapdump.go b/src/runtime/heapdump.go
index c6f97025f..e1693d40f 100644
--- a/src/runtime/heapdump.go
+++ b/src/runtime/heapdump.go
@@ -7,7 +7,7 @@
// finalizers, etc.) to a file.
// The format of the dumped file is described at
-// http://code.google.com/p/go-wiki/wiki/heapdump14
+// http://golang.org/s/go14heapdump.
package runtime
diff --git a/src/runtime/lfstack.go b/src/runtime/lfstack.go
index a4ad8a10c..fd3325972 100644
--- a/src/runtime/lfstack.go
+++ b/src/runtime/lfstack.go
@@ -12,6 +12,10 @@ import "unsafe"
func lfstackpush(head *uint64, node *lfnode) {
node.pushcnt++
new := lfstackPack(node, node.pushcnt)
+ if node1, _ := lfstackUnpack(new); node1 != node {
+ println("runtime: lfstackpush invalid packing: node=", node, " cnt=", hex(node.pushcnt), " packed=", hex(new), " -> node=", node1, "\n")
+ gothrow("lfstackpush")
+ }
for {
old := atomicload64(head)
node.next = old
diff --git a/src/runtime/lfstack_32bit.go b/src/runtime/lfstack_32bit.go
index 61d8678d9..4b8bcbac6 100644
--- a/src/runtime/lfstack_32bit.go
+++ b/src/runtime/lfstack_32bit.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build 386 arm
+// +build 386 arm nacl
package runtime
diff --git a/src/runtime/lfstack_linux_power64x.go b/src/runtime/lfstack_linux_power64x.go
index 7a122bf92..89e389fc7 100644
--- a/src/runtime/lfstack_linux_power64x.go
+++ b/src/runtime/lfstack_linux_power64x.go
@@ -9,18 +9,24 @@ package runtime
import "unsafe"
-// On Power64, Linux limits the user address space to 43 bits.
-// (https://www.kernel.org/doc/ols/2001/ppc64.pdf)
-// In addition to the 21 bits taken from the top, we can take 3 from the
-// bottom, because node must be pointer-aligned, giving a total of 24 bits
+// On Power64, Linux limits the user address space to 46 bits (see
+// TASK_SIZE_USER64 in the Linux kernel). This has grown over time,
+// so here we allow 48 bit addresses.
+//
+// In addition to the 16 bits taken from the top, we can take 3 from the
+// bottom, because node must be pointer-aligned, giving a total of 19 bits
// of count.
+const (
+ addrBits = 48
+ cntBits = 64 - addrBits + 3
+)
func lfstackPack(node *lfnode, cnt uintptr) uint64 {
- return uint64(uintptr(unsafe.Pointer(node)))<<21 | uint64(cnt&(1<<24-1))
+ return uint64(uintptr(unsafe.Pointer(node)))<<(64-addrBits) | uint64(cnt&(1<<cntBits-1))
}
func lfstackUnpack(val uint64) (node *lfnode, cnt uintptr) {
- node = (*lfnode)(unsafe.Pointer(uintptr(val >> 24 << 3)))
- cnt = uintptr(val & (1<<24 - 1))
+ node = (*lfnode)(unsafe.Pointer(uintptr(val >> cntBits << 3)))
+ cnt = uintptr(val & (1<<cntBits - 1))
return
}
diff --git a/src/runtime/malloc.go b/src/runtime/malloc.go
index 86e20b249..e9fec7bb1 100644
--- a/src/runtime/malloc.go
+++ b/src/runtime/malloc.go
@@ -546,6 +546,8 @@ func GC() {
// linker-provided
var noptrdata struct{}
+var enoptrdata struct{}
+var noptrbss struct{}
var enoptrbss struct{}
// SetFinalizer sets the finalizer associated with x to f.
@@ -622,8 +624,13 @@ func SetFinalizer(obj interface{}, finalizer interface{}) {
// func main() {
// runtime.SetFinalizer(Foo, nil)
// }
- // The segments are, in order: text, rodata, noptrdata, data, bss, noptrbss.
- if uintptr(unsafe.Pointer(&noptrdata)) <= uintptr(e.data) && uintptr(e.data) < uintptr(unsafe.Pointer(&enoptrbss)) {
+ // The relevant segments are: noptrdata, data, bss, noptrbss.
+ // We cannot assume they are in any order or even contiguous,
+ // due to external linking.
+ if uintptr(unsafe.Pointer(&noptrdata)) <= uintptr(e.data) && uintptr(e.data) < uintptr(unsafe.Pointer(&enoptrdata)) ||
+ uintptr(unsafe.Pointer(&data)) <= uintptr(e.data) && uintptr(e.data) < uintptr(unsafe.Pointer(&edata)) ||
+ uintptr(unsafe.Pointer(&bss)) <= uintptr(e.data) && uintptr(e.data) < uintptr(unsafe.Pointer(&ebss)) ||
+ uintptr(unsafe.Pointer(&noptrbss)) <= uintptr(e.data) && uintptr(e.data) < uintptr(unsafe.Pointer(&enoptrbss)) {
return
}
gothrow("runtime.SetFinalizer: pointer not in allocated block")
diff --git a/src/runtime/malloc2.go b/src/runtime/malloc2.go
index 511638d3d..a9d40de30 100644
--- a/src/runtime/malloc2.go
+++ b/src/runtime/malloc2.go
@@ -126,7 +126,7 @@ const (
// See http://golang.org/issue/5402 and http://golang.org/issue/5236.
// On other 64-bit platforms, we limit the arena to 128GB, or 37 bits.
// On 32-bit, we don't bother limiting anything, so we use the full 32-bit address.
- _MHeapMap_TotalBits = (_64bit*_Windows)*35 + (_64bit*(1-_Windows))*37 + (1-_64bit)*32
+ _MHeapMap_TotalBits = (_64bit*goos_windows)*35 + (_64bit*(1-goos_windows))*37 + (1-_64bit)*32
_MHeapMap_Bits = _MHeapMap_TotalBits - _PageShift
_MaxMem = uintptr(1<<_MHeapMap_TotalBits - 1)
diff --git a/src/runtime/mem_bsd.go b/src/runtime/mem_bsd.go
index 4bd40a39f..e9be5ec8c 100644
--- a/src/runtime/mem_bsd.go
+++ b/src/runtime/mem_bsd.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build dragonfly freebsd netbsd openbsd solaris
+// +build dragonfly freebsd nacl netbsd openbsd solaris
package runtime
@@ -38,7 +38,7 @@ func sysReserve(v unsafe.Pointer, n uintptr, reserved *bool) unsafe.Pointer {
// On 64-bit, people with ulimit -v set complain if we reserve too
// much address space. Instead, assume that the reservation is okay
// and check the assumption in SysMap.
- if ptrSize == 8 && uint64(n) > 1<<32 {
+ if ptrSize == 8 && uint64(n) > 1<<32 || goos_nacl != 0 {
*reserved = false
return v
}
diff --git a/src/runtime/mem_nacl.c b/src/runtime/mem_nacl.c
deleted file mode 100644
index 6c836f18a..000000000
--- a/src/runtime/mem_nacl.c
+++ /dev/null
@@ -1,120 +0,0 @@
-// 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.
-
-#include "runtime.h"
-#include "arch_GOARCH.h"
-#include "defs_GOOS_GOARCH.h"
-#include "os_GOOS.h"
-#include "malloc.h"
-#include "textflag.h"
-
-enum
-{
- Debug = 0,
-};
-
-#pragma textflag NOSPLIT
-void*
-runtime·sysAlloc(uintptr n, uint64 *stat)
-{
- void *v;
-
- v = runtime·mmap(nil, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
- if(v < (void*)4096) {
- if(Debug)
- runtime·printf("sysAlloc(%p): %p\n", n, v);
- return nil;
- }
- runtime·xadd64(stat, n);
- if(Debug)
- runtime·printf("sysAlloc(%p) = %p\n", n, v);
- return v;
-}
-
-void
-runtime·SysUnused(void *v, uintptr n)
-{
- if(Debug)
- runtime·printf("SysUnused(%p, %p)\n", v, n);
-}
-
-void
-runtime·SysUsed(void *v, uintptr n)
-{
- USED(v);
- USED(n);
-}
-
-void
-runtime·SysFree(void *v, uintptr n, uint64 *stat)
-{
- if(Debug)
- runtime·printf("SysFree(%p, %p)\n", v, n);
- runtime·xadd64(stat, -(uint64)n);
- runtime·munmap(v, n);
-}
-
-void
-runtime·SysFault(void *v, uintptr n)
-{
- runtime·mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE|MAP_FIXED, -1, 0);
-}
-
-void*
-runtime·SysReserve(void *v, uintptr n, bool *reserved)
-{
- void *p;
-
- // On 64-bit, people with ulimit -v set complain if we reserve too
- // much address space. Instead, assume that the reservation is okay
- // and check the assumption in SysMap.
- if(NaCl || sizeof(void*) == 8) {
- *reserved = false;
- return v;
- }
-
- p = runtime·mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE, -1, 0);
- if(p < (void*)4096)
- return nil;
- *reserved = true;
- return p;
-}
-
-void
-runtime·SysMap(void *v, uintptr n, bool reserved, uint64 *stat)
-{
- void *p;
-
- runtime·xadd64(stat, n);
-
- // On 64-bit, we don't actually have v reserved, so tread carefully.
- if(!reserved) {
- p = runtime·mmap(v, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
- if(p == (void*)ENOMEM) {
- runtime·printf("SysMap(%p, %p): %p\n", v, n, p);
- runtime·throw("runtime: out of memory");
- }
- if(p != v) {
- runtime·printf("SysMap(%p, %p): %p\n", v, n, p);
- runtime·printf("runtime: address space conflict: map(%p) = %p\n", v, p);
- runtime·throw("runtime: address space conflict");
- }
- if(Debug)
- runtime·printf("SysMap(%p, %p) = %p\n", v, n, p);
- return;
- }
-
- p = runtime·mmap(v, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_FIXED|MAP_PRIVATE, -1, 0);
- if(p == (void*)ENOMEM) {
- runtime·printf("SysMap(%p, %p): %p\n", v, n, p);
- runtime·throw("runtime: out of memory");
- }
- if(p != v) {
- runtime·printf("SysMap(%p, %p): %p\n", v, n, p);
- runtime·printf("mmap MAP_FIXED %p returned %p\n", v, p);
- runtime·throw("runtime: cannot map pages in arena address space");
- }
- if(Debug)
- runtime·printf("SysMap(%p, %p) = %p\n", v, n, p);
-}
diff --git a/src/runtime/mem_plan9.c b/src/runtime/mem_plan9.c
deleted file mode 100644
index d673d6f83..000000000
--- a/src/runtime/mem_plan9.c
+++ /dev/null
@@ -1,121 +0,0 @@
-// 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.
-
-#include "runtime.h"
-#include "defs_GOOS_GOARCH.h"
-#include "arch_GOARCH.h"
-#include "malloc.h"
-#include "os_GOOS.h"
-#include "textflag.h"
-
-extern byte runtime·end[];
-#pragma dataflag NOPTR
-static byte *bloc = { runtime·end };
-static Mutex memlock;
-
-enum
-{
- Round = PAGESIZE-1
-};
-
-static void*
-brk(uintptr nbytes)
-{
- uintptr bl;
-
- runtime·lock(&memlock);
- // Plan 9 sbrk from /sys/src/libc/9sys/sbrk.c
- bl = ((uintptr)bloc + Round) & ~Round;
- if(runtime·brk_((void*)(bl + nbytes)) < 0) {
- runtime·unlock(&memlock);
- return nil;
- }
- bloc = (byte*)bl + nbytes;
- runtime·unlock(&memlock);
- return (void*)bl;
-}
-
-static void
-sysalloc(void)
-{
- uintptr nbytes;
- uint64 *stat;
- void *p;
-
- nbytes = g->m->scalararg[0];
- stat = g->m->ptrarg[0];
- g->m->scalararg[0] = 0;
- g->m->ptrarg[0] = nil;
-
- p = brk(nbytes);
- if(p != nil)
- runtime·xadd64(stat, nbytes);
-
- g->m->ptrarg[0] = p;
-}
-
-#pragma textflag NOSPLIT
-void*
-runtime·sysAlloc(uintptr nbytes, uint64 *stat)
-{
- void (*fn)(void);
- void *p;
-
- g->m->scalararg[0] = nbytes;
- g->m->ptrarg[0] = stat;
- fn = sysalloc;
- runtime·onM(&fn);
- p = g->m->ptrarg[0];
- g->m->ptrarg[0] = nil;
- return p;
-}
-
-void
-runtime·SysFree(void *v, uintptr nbytes, uint64 *stat)
-{
- runtime·xadd64(stat, -(uint64)nbytes);
- runtime·lock(&memlock);
- // from tiny/mem.c
- // Push pointer back if this is a free
- // of the most recent sysAlloc.
- nbytes += (nbytes + Round) & ~Round;
- if(bloc == (byte*)v+nbytes)
- bloc -= nbytes;
- runtime·unlock(&memlock);
-}
-
-void
-runtime·SysUnused(void *v, uintptr nbytes)
-{
- USED(v, nbytes);
-}
-
-void
-runtime·SysUsed(void *v, uintptr nbytes)
-{
- USED(v, nbytes);
-}
-
-void
-runtime·SysMap(void *v, uintptr nbytes, bool reserved, uint64 *stat)
-{
- // SysReserve has already allocated all heap memory,
- // but has not adjusted stats.
- USED(v, reserved);
- runtime·xadd64(stat, nbytes);
-}
-
-void
-runtime·SysFault(void *v, uintptr nbytes)
-{
- USED(v, nbytes);
-}
-
-void*
-runtime·SysReserve(void *v, uintptr nbytes, bool *reserved)
-{
- USED(v);
- *reserved = true;
- return brk(nbytes);
-}
diff --git a/src/runtime/mem_plan9.go b/src/runtime/mem_plan9.go
new file mode 100644
index 000000000..a5d7c1a4c
--- /dev/null
+++ b/src/runtime/mem_plan9.go
@@ -0,0 +1,70 @@
+// 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.
+
+package runtime
+
+import "unsafe"
+
+var bloc uintptr
+var memlock mutex
+
+const memRound = _PAGESIZE - 1
+
+func initBloc() {
+ bloc = uintptr(unsafe.Pointer(&end))
+}
+
+func sbrk(n uintptr) unsafe.Pointer {
+ lock(&memlock)
+ // Plan 9 sbrk from /sys/src/libc/9sys/sbrk.c
+ bl := (bloc + memRound) &^ memRound
+ if brk_(unsafe.Pointer(bl+n)) < 0 {
+ unlock(&memlock)
+ return nil
+ }
+ bloc = bl + n
+ unlock(&memlock)
+ return unsafe.Pointer(bl)
+}
+
+func sysAlloc(n uintptr, stat *uint64) unsafe.Pointer {
+ p := sbrk(n)
+ if p != nil {
+ xadd64(stat, int64(n))
+ }
+ return p
+}
+
+func sysFree(v unsafe.Pointer, n uintptr, stat *uint64) {
+ xadd64(stat, -int64(n))
+ lock(&memlock)
+ // from tiny/mem.c
+ // Push pointer back if this is a free
+ // of the most recent sysAlloc.
+ n += (n + memRound) &^ memRound
+ if bloc == uintptr(v)+n {
+ bloc -= n
+ }
+ unlock(&memlock)
+}
+
+func sysUnused(v unsafe.Pointer, n uintptr) {
+}
+
+func sysUsed(v unsafe.Pointer, n uintptr) {
+}
+
+func sysMap(v unsafe.Pointer, n uintptr, reserved bool, stat *uint64) {
+ // sysReserve has already allocated all heap memory,
+ // but has not adjusted stats.
+ xadd64(stat, int64(n))
+}
+
+func sysFault(v unsafe.Pointer, n uintptr) {
+}
+
+func sysReserve(v unsafe.Pointer, n uintptr, reserved *bool) unsafe.Pointer {
+ *reserved = true
+ return sbrk(n)
+}
diff --git a/src/runtime/mgc0.go b/src/runtime/mgc0.go
index 00e64c0ff..7797894fc 100644
--- a/src/runtime/mgc0.go
+++ b/src/runtime/mgc0.go
@@ -51,10 +51,26 @@ func clearpools() {
if c := p.mcache; c != nil {
c.tiny = nil
c.tinysize = 0
+
+ // disconnect cached list before dropping it on the floor,
+ // so that a dangling ref to one entry does not pin all of them.
+ var sg, sgnext *sudog
+ for sg = c.sudogcache; sg != nil; sg = sgnext {
+ sgnext = sg.next
+ sg.next = nil
+ }
c.sudogcache = nil
}
+
// clear defer pools
for i := range p.deferpool {
+ // disconnect cached list before dropping it on the floor,
+ // so that a dangling ref to one entry does not pin all of them.
+ var d, dlink *_defer
+ for d = p.deferpool[i]; d != nil; d = dlink {
+ dlink = d.link
+ d.link = nil
+ }
p.deferpool[i] = nil
}
}
diff --git a/src/runtime/netpoll_stub.c b/src/runtime/netpoll_stub.go
index b7a8f2944..6c7e79ea3 100644
--- a/src/runtime/netpoll_stub.c
+++ b/src/runtime/netpoll_stub.go
@@ -4,15 +4,12 @@
// +build plan9
-#include "runtime.h"
+package runtime
// Polls for ready network connections.
// Returns list of goroutines that become runnable.
-G*
-runtime·netpoll(bool block)
-{
+func netpoll(block bool) (gp *g) {
// Implementation for platforms that do not support
// integrated network poller.
- USED(block);
- return nil;
+ return
}
diff --git a/src/runtime/netpoll_windows.go b/src/runtime/netpoll_windows.go
index 88e878137..23d5dc00f 100644
--- a/src/runtime/netpoll_windows.go
+++ b/src/runtime/netpoll_windows.go
@@ -108,7 +108,7 @@ retry:
op = entries[i].op
errno = 0
qty = 0
- if stdcall5(_WSAGetOverlappedResult, netpollfd(op.pd), uintptr(unsafe.Pointer(op)), uintptr(unsafe.Pointer(&qty)), 0, uintptr(unsafe.Pointer(&flags))) == 0 {
+ if stdcall5(_WSAGetOverlappedResult, op.pd.fd, uintptr(unsafe.Pointer(op)), uintptr(unsafe.Pointer(&qty)), 0, uintptr(unsafe.Pointer(&flags))) == 0 {
errno = int32(getlasterror())
}
handlecompletion(&gp, op, errno, qty)
@@ -152,5 +152,5 @@ func handlecompletion(gpp **g, op *net_op, errno int32, qty uint32) {
}
op.errno = errno
op.qty = qty
- netpollready(gpp, op.pd, mode)
+ netpollready((**g)(noescape(unsafe.Pointer(gpp))), op.pd, mode)
}
diff --git a/src/runtime/os1_nacl.go b/src/runtime/os1_nacl.go
new file mode 100644
index 000000000..7b4c99a3d
--- /dev/null
+++ b/src/runtime/os1_nacl.go
@@ -0,0 +1,197 @@
+// 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.
+
+package runtime
+
+import "unsafe"
+
+// Called to initialize a new m (including the bootstrap m).
+// Called on the parent thread (main thread in case of bootstrap), can allocate memory.
+func mpreinit(mp *m) {
+ mp.gsignal = malg(32 * 1024)
+ mp.gsignal.m = mp
+}
+
+func sigtramp()
+
+// Called to initialize a new m (including the bootstrap m).
+// Called on the new thread, can not allocate memory.
+func minit() {
+ _g_ := getg()
+
+ // Initialize signal handling
+ ret := nacl_exception_stack(_g_.m.gsignal.stack.lo, 32*1024)
+ if ret < 0 {
+ print("runtime: nacl_exception_stack: error ", -ret, "\n")
+ }
+
+ ret = nacl_exception_handler(funcPC(sigtramp), nil)
+ if ret < 0 {
+ print("runtime: nacl_exception_handler: error ", -ret, "\n")
+ }
+}
+
+// Called from dropm to undo the effect of an minit.
+func unminit() {
+}
+
+func osinit() {
+ ncpu = 1
+ getg().m.procid = 2
+ //nacl_exception_handler(funcPC(sigtramp), nil);
+}
+
+func crash() {
+ *(*int32)(nil) = 0
+}
+
+//go:nosplit
+func get_random_data(rnd *unsafe.Pointer, rnd_len *int32) {
+ *rnd = nil
+ *rnd_len = 0
+}
+
+func goenvs() {
+ goenvs_unix()
+}
+
+func initsig() {
+}
+
+//go:nosplit
+func usleep(us uint32) {
+ var ts timespec
+
+ ts.tv_sec = int64(us / 1e6)
+ ts.tv_nsec = int32(us%1e6) * 1e3
+ nacl_nanosleep(&ts, nil)
+}
+
+func mstart_nacl()
+
+func newosproc(mp *m, stk unsafe.Pointer) {
+ tls := (*[3]unsafe.Pointer)(unsafe.Pointer(&mp.tls))
+ tls[0] = unsafe.Pointer(mp.g0)
+ tls[1] = unsafe.Pointer(mp)
+ ret := nacl_thread_create(funcPC(mstart_nacl), stk, unsafe.Pointer(&tls[2]), nil)
+ if ret < 0 {
+ print("nacl_thread_create: error ", -ret, "\n")
+ gothrow("newosproc")
+ }
+}
+
+//go:nosplit
+func semacreate() uintptr {
+ var cond uintptr
+ systemstack(func() {
+ mu := nacl_mutex_create(0)
+ if mu < 0 {
+ print("nacl_mutex_create: error ", -mu, "\n")
+ gothrow("semacreate")
+ }
+ c := nacl_cond_create(0)
+ if c < 0 {
+ print("nacl_cond_create: error ", -cond, "\n")
+ gothrow("semacreate")
+ }
+ cond = uintptr(c)
+ _g_ := getg()
+ _g_.m.waitsemalock = uint32(mu)
+ })
+ return cond
+}
+
+//go:nosplit
+func semasleep(ns int64) int32 {
+ var ret int32
+
+ systemstack(func() {
+ _g_ := getg()
+ if nacl_mutex_lock(int32(_g_.m.waitsemalock)) < 0 {
+ gothrow("semasleep")
+ }
+
+ for _g_.m.waitsemacount == 0 {
+ if ns < 0 {
+ if nacl_cond_wait(int32(_g_.m.waitsema), int32(_g_.m.waitsemalock)) < 0 {
+ gothrow("semasleep")
+ }
+ } else {
+ var ts timespec
+ end := ns + nanotime()
+ ts.tv_sec = end / 1e9
+ ts.tv_nsec = int32(end % 1e9)
+ r := nacl_cond_timed_wait_abs(int32(_g_.m.waitsema), int32(_g_.m.waitsemalock), &ts)
+ if r == -_ETIMEDOUT {
+ nacl_mutex_unlock(int32(_g_.m.waitsemalock))
+ ret = -1
+ return
+ }
+ if r < 0 {
+ gothrow("semasleep")
+ }
+ }
+ }
+
+ _g_.m.waitsemacount = 0
+ nacl_mutex_unlock(int32(_g_.m.waitsemalock))
+ ret = 0
+ })
+ return ret
+}
+
+//go:nosplit
+func semawakeup(mp *m) {
+ systemstack(func() {
+ if nacl_mutex_lock(int32(mp.waitsemalock)) < 0 {
+ gothrow("semawakeup")
+ }
+ if mp.waitsemacount != 0 {
+ gothrow("semawakeup")
+ }
+ mp.waitsemacount = 1
+ nacl_cond_signal(int32(mp.waitsema))
+ nacl_mutex_unlock(int32(mp.waitsemalock))
+ })
+}
+
+func memlimit() uintptr {
+ return 0
+}
+
+// This runs on a foreign stack, without an m or a g. No stack split.
+//go:nosplit
+func badsignal2() {
+ write(2, unsafe.Pointer(&badsignal1[0]), int32(len(badsignal1)))
+ exit(2)
+}
+
+var badsignal1 = []byte("runtime: signal received on thread not created by Go.\n")
+
+func madvise(addr unsafe.Pointer, n uintptr, flags int32) {}
+func munmap(addr unsafe.Pointer, n uintptr) {}
+func resetcpuprofiler(hz int32) {}
+func sigdisable(uint32) {}
+func sigenable(uint32) {}
+func closeonexec(int32) {}
+
+var writelock uint32 // test-and-set spin lock for write
+
+/*
+An attempt at IRT. Doesn't work. See end of sys_nacl_amd64.s.
+
+void (*nacl_irt_query)(void);
+
+int8 nacl_irt_basic_v0_1_str[] = "nacl-irt-basic-0.1";
+void *nacl_irt_basic_v0_1[6]; // exit, gettod, clock, nanosleep, sched_yield, sysconf
+int32 nacl_irt_basic_v0_1_size = sizeof(nacl_irt_basic_v0_1);
+
+int8 nacl_irt_memory_v0_3_str[] = "nacl-irt-memory-0.3";
+void *nacl_irt_memory_v0_3[3]; // mmap, munmap, mprotect
+int32 nacl_irt_memory_v0_3_size = sizeof(nacl_irt_memory_v0_3);
+
+int8 nacl_irt_thread_v0_1_str[] = "nacl-irt-thread-0.1";
+void *nacl_irt_thread_v0_1[3]; // thread_create, thread_exit, thread_nice
+int32 nacl_irt_thread_v0_1_size = sizeof(nacl_irt_thread_v0_1);
+*/
diff --git a/src/runtime/os1_netbsd.go b/src/runtime/os1_netbsd.go
new file mode 100644
index 000000000..493be30fa
--- /dev/null
+++ b/src/runtime/os1_netbsd.go
@@ -0,0 +1,265 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime
+
+import "unsafe"
+
+const (
+ _ESRCH = 3
+ _ENOTSUP = 91
+
+ // From NetBSD's <sys/time.h>
+ _CLOCK_REALTIME = 0
+ _CLOCK_VIRTUAL = 1
+ _CLOCK_PROF = 2
+ _CLOCK_MONOTONIC = 3
+)
+
+var sigset_none = sigset{}
+var sigset_all = sigset{[4]uint32{^uint32(0), ^uint32(0), ^uint32(0), ^uint32(0)}}
+
+// From NetBSD's <sys/sysctl.h>
+const (
+ _CTL_HW = 6
+ _HW_NCPU = 3
+)
+
+func getncpu() int32 {
+ mib := [2]uint32{_CTL_HW, _HW_NCPU}
+ out := uint32(0)
+ nout := unsafe.Sizeof(out)
+ ret := sysctl(&mib[0], 2, (*byte)(unsafe.Pointer(&out)), &nout, nil, 0)
+ if ret >= 0 {
+ return int32(out)
+ }
+ return 1
+}
+
+//go:nosplit
+func semacreate() uintptr {
+ return 1
+}
+
+//go:nosplit
+func semasleep(ns int64) int32 {
+ _g_ := getg()
+
+ // spin-mutex lock
+ for {
+ if xchg(&_g_.m.waitsemalock, 1) == 0 {
+ break
+ }
+ osyield()
+ }
+
+ for {
+ // lock held
+ if _g_.m.waitsemacount == 0 {
+ // sleep until semaphore != 0 or timeout.
+ // thrsleep unlocks m.waitsemalock.
+ if ns < 0 {
+ // TODO(jsing) - potential deadlock!
+ //
+ // There is a potential deadlock here since we
+ // have to release the waitsemalock mutex
+ // before we call lwp_park() to suspend the
+ // thread. This allows another thread to
+ // release the lock and call lwp_unpark()
+ // before the thread is actually suspended.
+ // If this occurs the current thread will end
+ // up sleeping indefinitely. Unfortunately
+ // the NetBSD kernel does not appear to provide
+ // a mechanism for unlocking the userspace
+ // mutex once the thread is actually parked.
+ atomicstore(&_g_.m.waitsemalock, 0)
+ lwp_park(nil, 0, unsafe.Pointer(&_g_.m.waitsemacount), nil)
+ } else {
+ var ts timespec
+ var nsec int32
+ ns += nanotime()
+ ts.set_sec(timediv(ns, 1000000000, &nsec))
+ ts.set_nsec(nsec)
+ // TODO(jsing) - potential deadlock!
+ // See above for details.
+ atomicstore(&_g_.m.waitsemalock, 0)
+ lwp_park(&ts, 0, unsafe.Pointer(&_g_.m.waitsemacount), nil)
+ }
+ // reacquire lock
+ for {
+ if xchg(&_g_.m.waitsemalock, 1) == 0 {
+ break
+ }
+ osyield()
+ }
+ }
+
+ // lock held (again)
+ if _g_.m.waitsemacount != 0 {
+ // semaphore is available.
+ _g_.m.waitsemacount--
+ // spin-mutex unlock
+ atomicstore(&_g_.m.waitsemalock, 0)
+ return 0
+ }
+
+ // semaphore not available.
+ // if there is a timeout, stop now.
+ // otherwise keep trying.
+ if ns >= 0 {
+ break
+ }
+ }
+
+ // lock held but giving up
+ // spin-mutex unlock
+ atomicstore(&_g_.m.waitsemalock, 0)
+ return -1
+}
+
+//go:nosplit
+func semawakeup(mp *m) {
+ // spin-mutex lock
+ for {
+ if xchg(&mp.waitsemalock, 1) == 0 {
+ break
+ }
+ osyield()
+ }
+
+ mp.waitsemacount++
+ // TODO(jsing) - potential deadlock, see semasleep() for details.
+ // Confirm that LWP is parked before unparking...
+ ret := lwp_unpark(int32(mp.procid), unsafe.Pointer(&mp.waitsemacount))
+ if ret != 0 && ret != _ESRCH {
+ // semawakeup can be called on signal stack.
+ systemstack(func() {
+ print("thrwakeup addr=", &mp.waitsemacount, " sem=", mp.waitsemacount, " ret=", ret, "\n")
+ })
+ }
+
+ // spin-mutex unlock
+ atomicstore(&mp.waitsemalock, 0)
+}
+
+func newosproc(mp *m, stk unsafe.Pointer) {
+ if false {
+ print("newosproc stk=", stk, " m=", mp, " g=", mp.g0, " id=", mp.id, "/", int32(mp.tls[0]), " ostk=", &mp, "\n")
+ }
+
+ mp.tls[0] = uintptr(mp.id) // so 386 asm can find it
+
+ var uc ucontextt
+ getcontext(unsafe.Pointer(&uc))
+
+ uc.uc_flags = _UC_SIGMASK | _UC_CPU
+ uc.uc_link = nil
+ uc.uc_sigmask = sigset_all
+
+ lwp_mcontext_init(&uc.uc_mcontext, stk, mp, mp.g0, funcPC(mstart))
+
+ ret := lwp_create(unsafe.Pointer(&uc), 0, unsafe.Pointer(&mp.procid))
+ if ret < 0 {
+ print("runtime: failed to create new OS thread (have ", mcount()-1, " already; errno=", -ret, ")\n")
+ gothrow("runtime.newosproc")
+ }
+}
+
+func osinit() {
+ ncpu = getncpu()
+}
+
+var urandom_data [_HashRandomBytes]byte
+var urandom_dev = []byte("/dev/urandom\x00")
+
+//go:nosplit
+func get_random_data(rnd *unsafe.Pointer, rnd_len *int32) {
+ fd := open(&urandom_dev[0], 0 /* O_RDONLY */, 0)
+ if read(fd, unsafe.Pointer(&urandom_data), _HashRandomBytes) == _HashRandomBytes {
+ *rnd = unsafe.Pointer(&urandom_data[0])
+ *rnd_len = _HashRandomBytes
+ } else {
+ *rnd = nil
+ *rnd_len = 0
+ }
+ close(fd)
+}
+
+func goenvs() {
+ goenvs_unix()
+}
+
+// Called to initialize a new m (including the bootstrap m).
+// Called on the parent thread (main thread in case of bootstrap), can allocate memory.
+func mpreinit(mp *m) {
+ mp.gsignal = malg(32 * 1024)
+ mp.gsignal.m = mp
+}
+
+// Called to initialize a new m (including the bootstrap m).
+// Called on the new thread, can not allocate memory.
+func minit() {
+ _g_ := getg()
+ _g_.m.procid = uint64(lwp_self())
+
+ // Initialize signal handling
+ signalstack((*byte)(unsafe.Pointer(_g_.m.gsignal.stack.lo)), 32*1024)
+ sigprocmask(_SIG_SETMASK, &sigset_none, nil)
+}
+
+// Called from dropm to undo the effect of an minit.
+func unminit() {
+ signalstack(nil, 0)
+}
+
+func memlimit() uintptr {
+ return 0
+}
+
+func sigtramp()
+
+type sigactiont struct {
+ sa_sigaction uintptr
+ sa_mask sigset
+ sa_flags int32
+}
+
+func setsig(i int32, fn uintptr, restart bool) {
+ var sa sigactiont
+ sa.sa_flags = _SA_SIGINFO | _SA_ONSTACK
+ if restart {
+ sa.sa_flags |= _SA_RESTART
+ }
+ sa.sa_mask = sigset_all
+ if fn == funcPC(sighandler) {
+ fn = funcPC(sigtramp)
+ }
+ sa.sa_sigaction = fn
+ sigaction(i, &sa, nil)
+}
+
+func getsig(i int32) uintptr {
+ var sa sigactiont
+ sigaction(i, nil, &sa)
+ if sa.sa_sigaction == funcPC(sigtramp) {
+ return funcPC(sighandler)
+ }
+ return sa.sa_sigaction
+}
+
+func signalstack(p *byte, n int32) {
+ var st sigaltstackt
+
+ st.ss_sp = uintptr(unsafe.Pointer(p))
+ st.ss_size = uintptr(n)
+ st.ss_flags = 0
+ if p == nil {
+ st.ss_flags = _SS_DISABLE
+ }
+ sigaltstack(&st, nil)
+}
+
+func unblocksignals() {
+ sigprocmask(_SIG_SETMASK, &sigset_none, nil)
+}
diff --git a/src/runtime/os1_netbsd_386.go b/src/runtime/os1_netbsd_386.go
new file mode 100644
index 000000000..037f7e36d
--- /dev/null
+++ b/src/runtime/os1_netbsd_386.go
@@ -0,0 +1,16 @@
+// 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 "unsafe"
+
+func lwp_mcontext_init(mc *mcontextt, stk unsafe.Pointer, mp *m, gp *g, fn uintptr) {
+ // Machine dependent mcontext initialisation for LWP.
+ mc.__gregs[_REG_EIP] = uint32(funcPC(lwp_tramp))
+ mc.__gregs[_REG_UESP] = uint32(uintptr(stk))
+ mc.__gregs[_REG_EBX] = uint32(uintptr(unsafe.Pointer(mp)))
+ mc.__gregs[_REG_EDX] = uint32(uintptr(unsafe.Pointer(gp)))
+ mc.__gregs[_REG_ESI] = uint32(fn)
+}
diff --git a/src/runtime/os1_netbsd_amd64.go b/src/runtime/os1_netbsd_amd64.go
new file mode 100644
index 000000000..5118b0c4f
--- /dev/null
+++ b/src/runtime/os1_netbsd_amd64.go
@@ -0,0 +1,16 @@
+// 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 "unsafe"
+
+func lwp_mcontext_init(mc *mcontextt, stk unsafe.Pointer, mp *m, gp *g, fn uintptr) {
+ // Machine dependent mcontext initialisation for LWP.
+ mc.__gregs[_REG_RIP] = uint64(funcPC(lwp_tramp))
+ mc.__gregs[_REG_RSP] = uint64(uintptr(stk))
+ mc.__gregs[_REG_R8] = uint64(uintptr(unsafe.Pointer(mp)))
+ mc.__gregs[_REG_R9] = uint64(uintptr(unsafe.Pointer(gp)))
+ mc.__gregs[_REG_R12] = uint64(fn)
+}
diff --git a/src/runtime/os1_plan9.go b/src/runtime/os1_plan9.go
new file mode 100644
index 000000000..0f8da03f2
--- /dev/null
+++ b/src/runtime/os1_plan9.go
@@ -0,0 +1,270 @@
+// 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.
+
+package runtime
+
+import "unsafe"
+
+// Called to initialize a new m (including the bootstrap m).
+// Called on the parent thread (main thread in case of bootstrap), can allocate memory.
+func mpreinit(mp *m) {
+ // Initialize stack and goroutine for note handling.
+ mp.gsignal = malg(32 * 1024)
+ mp.gsignal.m = mp
+ mp.notesig = (*int8)(mallocgc(_ERRMAX, nil, _FlagNoScan))
+ // Initialize stack for handling strings from the
+ // errstr system call, as used in package syscall.
+ mp.errstr = (*byte)(mallocgc(_ERRMAX, nil, _FlagNoScan))
+}
+
+// Called to initialize a new m (including the bootstrap m).
+// Called on the new thread, can not allocate memory.
+func minit() {
+ // Mask all SSE floating-point exceptions
+ // when running on the 64-bit kernel.
+ setfpmasks()
+}
+
+// Called from dropm to undo the effect of an minit.
+func unminit() {
+}
+
+var sysstat = []byte("/dev/sysstat\x00")
+
+func getproccount() int32 {
+ var buf [2048]byte
+ fd := open(&sysstat[0], _OREAD, 0)
+ if fd < 0 {
+ return 1
+ }
+ ncpu := int32(0)
+ for {
+ n := read(fd, unsafe.Pointer(&buf), int32(len(buf)))
+ if n <= 0 {
+ break
+ }
+ for i := int32(0); i < n; i++ {
+ if buf[i] == '\n' {
+ ncpu++
+ }
+ }
+ }
+ close(fd)
+ if ncpu == 0 {
+ ncpu = 1
+ }
+ return ncpu
+}
+
+var pid = []byte("#c/pid\x00")
+
+func getpid() uint64 {
+ var b [20]byte
+ fd := open(&pid[0], 0, 0)
+ if fd >= 0 {
+ read(fd, unsafe.Pointer(&b), int32(len(b)))
+ close(fd)
+ }
+ c := b[:]
+ for c[0] == ' ' || c[0] == '\t' {
+ c = c[1:]
+ }
+ return uint64(atoi(c))
+}
+
+func osinit() {
+ initBloc()
+ ncpu = getproccount()
+ getg().m.procid = getpid()
+ notify(unsafe.Pointer(funcPC(sigtramp)))
+}
+
+func crash() {
+ notify(nil)
+ *(*int)(nil) = 0
+}
+
+var random_data [_HashRandomBytes]byte
+var random_dev = []byte("/dev/random\x00")
+
+//go:nosplit
+func get_random_data(rnd *unsafe.Pointer, rnd_len *int32) {
+ fd := open(&random_dev[0], 0 /* O_RDONLY */, 0)
+ if read(fd, unsafe.Pointer(&random_data), _HashRandomBytes) == _HashRandomBytes {
+ *rnd = unsafe.Pointer(&random_data[0])
+ *rnd_len = _HashRandomBytes
+ } else {
+ *rnd = nil
+ *rnd_len = 0
+ }
+ close(fd)
+}
+
+func goenvs() {
+}
+
+func initsig() {
+}
+
+//go:nosplit
+func osyield() {
+ sleep(0)
+}
+
+//go:nosplit
+func usleep(µs uint32) {
+ ms := int32(µs / 1000)
+ if ms == 0 {
+ ms = 1
+ }
+ sleep(ms)
+}
+
+//go:nosplit
+func nanotime() int64 {
+ var scratch int64
+ ns := nsec(&scratch)
+ // TODO(aram): remove hack after I fix _nsec in the pc64 kernel.
+ if ns == 0 {
+ return scratch
+ }
+ return ns
+}
+
+//go:nosplit
+func itoa(buf []byte, val uint64) []byte {
+ i := len(buf) - 1
+ for val >= 10 {
+ buf[i] = byte(val%10 + '0')
+ i--
+ val /= 10
+ }
+ buf[i] = byte(val + '0')
+ return buf[i:]
+}
+
+var goexits = []byte("go: exit ")
+
+func goexitsall(status *byte) {
+ var buf [_ERRMAX]byte
+ n := copy(buf[:], goexits)
+ n = copy(buf[n:], gostringnocopy(status))
+ pid := getpid()
+ for mp := (*m)(atomicloadp(unsafe.Pointer(&allm))); mp != nil; mp = mp.alllink {
+ if mp.procid != pid {
+ postnote(mp.procid, buf[:])
+ }
+ }
+}
+
+var procdir = []byte("/proc/")
+var notefile = []byte("/note\x00")
+
+func postnote(pid uint64, msg []byte) int {
+ var buf [128]byte
+ var tmp [32]byte
+ n := copy(buf[:], procdir)
+ n += copy(buf[n:], itoa(tmp[:], pid))
+ copy(buf[n:], notefile)
+ fd := open(&buf[0], _OWRITE, 0)
+ if fd < 0 {
+ return -1
+ }
+ len := findnull(&msg[0])
+ if write(uintptr(fd), (unsafe.Pointer)(&msg[0]), int32(len)) != int64(len) {
+ close(fd)
+ return -1
+ }
+ close(fd)
+ return 0
+}
+
+//go:nosplit
+func exit(e int) {
+ var status []byte
+ if e == 0 {
+ status = []byte("\x00")
+ } else {
+ // build error string
+ var tmp [32]byte
+ status = []byte(gostringnocopy(&itoa(tmp[:], uint64(e))[0]) + "\x00")
+ }
+ goexitsall(&status[0])
+ exits(&status[0])
+}
+
+func newosproc(mp *m, stk unsafe.Pointer) {
+ if false {
+ print("newosproc mp=", mp, " ostk=", &mp, "\n")
+ }
+ pid := rfork(_RFPROC | _RFMEM | _RFNOWAIT)
+ if pid < 0 {
+ gothrow("newosproc: rfork failed")
+ }
+ if pid == 0 {
+ tstart_plan9(mp)
+ }
+}
+
+//go:nosplit
+func semacreate() uintptr {
+ return 1
+}
+
+//go:nosplit
+func semasleep(ns int64) int {
+ _g_ := getg()
+ if ns >= 0 {
+ ms := timediv(ns, 1000000, nil)
+ if ms == 0 {
+ ms = 1
+ }
+ ret := plan9_tsemacquire(&_g_.m.waitsemacount, ms)
+ if ret == 1 {
+ return 0 // success
+ }
+ return -1 // timeout or interrupted
+ }
+ for plan9_semacquire(&_g_.m.waitsemacount, 1) < 0 {
+ // interrupted; try again (c.f. lock_sema.go)
+ }
+ return 0 // success
+}
+
+//go:nosplit
+func semawakeup(mp *m) {
+ plan9_semrelease(&mp.waitsemacount, 1)
+}
+
+//go:nosplit
+func read(fd int32, buf unsafe.Pointer, n int32) int32 {
+ return pread(fd, buf, n, -1)
+}
+
+//go:nosplit
+func write(fd uintptr, buf unsafe.Pointer, n int32) int64 {
+ return int64(pwrite(int32(fd), buf, n, -1))
+}
+
+func memlimit() uint64 {
+ return 0
+}
+
+var _badsignal = []byte("runtime: signal received on thread not created by Go.\n")
+
+// This runs on a foreign stack, without an m or a g. No stack split.
+//go:nosplit
+func badsignal2() {
+ pwrite(2, unsafe.Pointer(&_badsignal[0]), int32(len(_badsignal)), -1)
+ exits(&_badsignal[0])
+}
+
+func atoi(b []byte) int {
+ n := 0
+ for len(b) > 0 && '0' <= b[0] && b[0] <= '9' {
+ n = n*10 + int(b[0]) - '0'
+ b = b[1:]
+ }
+ return n
+}
diff --git a/src/runtime/os1_windows.go b/src/runtime/os1_windows.go
new file mode 100644
index 000000000..57ea050f2
--- /dev/null
+++ b/src/runtime/os1_windows.go
@@ -0,0 +1,564 @@
+// 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 (
+ "unsafe"
+)
+
+//go:cgo_import_dynamic runtime._AddVectoredExceptionHandler AddVectoredExceptionHandler "kernel32.dll"
+//go:cgo_import_dynamic runtime._CloseHandle CloseHandle "kernel32.dll"
+//go:cgo_import_dynamic runtime._CreateEventA CreateEventA "kernel32.dll"
+//go:cgo_import_dynamic runtime._CreateThread CreateThread "kernel32.dll"
+//go:cgo_import_dynamic runtime._CreateWaitableTimerA CreateWaitableTimerA "kernel32.dll"
+//go:cgo_import_dynamic runtime._CryptAcquireContextW CryptAcquireContextW "advapi32.dll"
+//go:cgo_import_dynamic runtime._CryptGenRandom CryptGenRandom "advapi32.dll"
+//go:cgo_import_dynamic runtime._CryptReleaseContext CryptReleaseContext "advapi32.dll"
+//go:cgo_import_dynamic runtime._DuplicateHandle DuplicateHandle "kernel32.dll"
+//go:cgo_import_dynamic runtime._ExitProcess ExitProcess "kernel32.dll"
+//go:cgo_import_dynamic runtime._FreeEnvironmentStringsW FreeEnvironmentStringsW "kernel32.dll"
+//go:cgo_import_dynamic runtime._GetEnvironmentStringsW GetEnvironmentStringsW "kernel32.dll"
+//go:cgo_import_dynamic runtime._GetProcAddress GetProcAddress "kernel32.dll"
+//go:cgo_import_dynamic runtime._GetStdHandle GetStdHandle "kernel32.dll"
+//go:cgo_import_dynamic runtime._GetSystemInfo GetSystemInfo "kernel32.dll"
+//go:cgo_import_dynamic runtime._GetThreadContext GetThreadContext "kernel32.dll"
+//go:cgo_import_dynamic runtime._LoadLibraryW LoadLibraryW "kernel32.dll"
+//go:cgo_import_dynamic runtime._LoadLibraryA LoadLibraryA "kernel32.dll"
+//go:cgo_import_dynamic runtime._NtWaitForSingleObject NtWaitForSingleObject "ntdll.dll"
+//go:cgo_import_dynamic runtime._ResumeThread ResumeThread "kernel32.dll"
+//go:cgo_import_dynamic runtime._SetConsoleCtrlHandler SetConsoleCtrlHandler "kernel32.dll"
+//go:cgo_import_dynamic runtime._SetEvent SetEvent "kernel32.dll"
+//go:cgo_import_dynamic runtime._SetProcessPriorityBoost SetProcessPriorityBoost "kernel32.dll"
+//go:cgo_import_dynamic runtime._SetThreadPriority SetThreadPriority "kernel32.dll"
+//go:cgo_import_dynamic runtime._SetUnhandledExceptionFilter SetUnhandledExceptionFilter "kernel32.dll"
+//go:cgo_import_dynamic runtime._SetWaitableTimer SetWaitableTimer "kernel32.dll"
+//go:cgo_import_dynamic runtime._Sleep Sleep "kernel32.dll"
+//go:cgo_import_dynamic runtime._SuspendThread SuspendThread "kernel32.dll"
+//go:cgo_import_dynamic runtime._WaitForSingleObject WaitForSingleObject "kernel32.dll"
+//go:cgo_import_dynamic runtime._WriteFile WriteFile "kernel32.dll"
+//go:cgo_import_dynamic runtime._timeBeginPeriod timeBeginPeriod "winmm.dll"
+
+var (
+ _AddVectoredExceptionHandler,
+ _CloseHandle,
+ _CreateEventA,
+ _CreateThread,
+ _CreateWaitableTimerA,
+ _CryptAcquireContextW,
+ _CryptGenRandom,
+ _CryptReleaseContext,
+ _DuplicateHandle,
+ _ExitProcess,
+ _FreeEnvironmentStringsW,
+ _GetEnvironmentStringsW,
+ _GetProcAddress,
+ _GetStdHandle,
+ _GetSystemInfo,
+ _GetThreadContext,
+ _LoadLibraryW,
+ _LoadLibraryA,
+ _NtWaitForSingleObject,
+ _ResumeThread,
+ _SetConsoleCtrlHandler,
+ _SetEvent,
+ _SetProcessPriorityBoost,
+ _SetThreadPriority,
+ _SetUnhandledExceptionFilter,
+ _SetWaitableTimer,
+ _Sleep,
+ _SuspendThread,
+ _WaitForSingleObject,
+ _WriteFile,
+ _timeBeginPeriod stdFunction
+)
+
+var _GetQueuedCompletionStatusEx stdFunction
+
+// in sys_windows_386.s and sys_windows_amd64.s
+func externalthreadhandler()
+func exceptiontramp()
+func firstcontinuetramp()
+func lastcontinuetramp()
+
+//go:nosplit
+func getLoadLibrary() uintptr {
+ return uintptr(unsafe.Pointer(_LoadLibraryW))
+}
+
+//go:nosplit
+func getGetProcAddress() uintptr {
+ return uintptr(unsafe.Pointer(_GetProcAddress))
+}
+
+func getproccount() int32 {
+ var info systeminfo
+ stdcall1(_GetSystemInfo, uintptr(unsafe.Pointer(&info)))
+ return int32(info.dwnumberofprocessors)
+}
+
+const (
+ currentProcess = ^uintptr(0) // -1 = current process
+ currentThread = ^uintptr(1) // -2 = current thread
+)
+
+var (
+ kernel32Name = []byte("kernel32.dll\x00")
+ addVectoredContinueHandlerName = []byte("AddVectoredContinueHandler\x00")
+ getQueuedCompletionStatusExName = []byte("GetQueuedCompletionStatusEx\x00")
+)
+
+func osinit() {
+ setBadSignalMsg()
+
+ kernel32 := stdcall1(_LoadLibraryA, uintptr(unsafe.Pointer(&kernel32Name[0])))
+
+ externalthreadhandlerp = funcPC(externalthreadhandler)
+
+ stdcall2(_AddVectoredExceptionHandler, 1, funcPC(exceptiontramp))
+ addVectoredContinueHandler := uintptr(0)
+ if kernel32 != 0 {
+ addVectoredContinueHandler = stdcall2(_GetProcAddress, kernel32, uintptr(unsafe.Pointer(&addVectoredContinueHandlerName[0])))
+ }
+ if addVectoredContinueHandler == 0 || unsafe.Sizeof(&kernel32) == 4 {
+ // use SetUnhandledExceptionFilter for windows-386 or
+ // if VectoredContinueHandler is unavailable.
+ // note: SetUnhandledExceptionFilter handler won't be called, if debugging.
+ stdcall1(_SetUnhandledExceptionFilter, funcPC(lastcontinuetramp))
+ } else {
+ stdcall2(stdFunction(unsafe.Pointer(addVectoredContinueHandler)), 1, funcPC(firstcontinuetramp))
+ stdcall2(stdFunction(unsafe.Pointer(addVectoredContinueHandler)), 0, funcPC(lastcontinuetramp))
+ }
+
+ stdcall2(_SetConsoleCtrlHandler, funcPC(ctrlhandler), 1)
+
+ stdcall1(_timeBeginPeriod, 1)
+
+ ncpu = getproccount()
+
+ // Windows dynamic priority boosting assumes that a process has different types
+ // 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.
+ stdcall2(_SetProcessPriorityBoost, currentProcess, 1)
+
+ if kernel32 != 0 {
+ _GetQueuedCompletionStatusEx = stdFunction(unsafe.Pointer(stdcall2(_GetProcAddress, kernel32, uintptr(unsafe.Pointer(&getQueuedCompletionStatusExName[0])))))
+ }
+}
+
+var random_data [_HashRandomBytes]byte
+
+//go:nosplit
+func get_random_data(rnd *unsafe.Pointer, rnd_len *int32) {
+ const (
+ prov_rsa_full = 1
+ crypt_verifycontext = 0xF0000000
+ )
+ var handle uintptr
+ *rnd = nil
+ *rnd_len = 0
+ if stdcall5(_CryptAcquireContextW, uintptr(unsafe.Pointer(&handle)), 0, 0, prov_rsa_full, crypt_verifycontext) != 0 {
+ if stdcall3(_CryptGenRandom, handle, _HashRandomBytes, uintptr(unsafe.Pointer(&random_data[0]))) != 0 {
+ *rnd = unsafe.Pointer(&random_data[0])
+ *rnd_len = _HashRandomBytes
+ }
+ stdcall2(_CryptReleaseContext, handle, 0)
+ }
+}
+
+func goenvs() {
+ var p *uint16
+
+ env := (*uint16)(unsafe.Pointer(stdcall0(_GetEnvironmentStringsW)))
+
+ n := 0
+ for p = env; *p != 0; n++ {
+ p = (*uint16)(add(unsafe.Pointer(p), uintptr(findnullw(p)+1)*unsafe.Sizeof(*p)))
+ }
+
+ envs = makeStringSlice(int(n))
+
+ p = env
+ for i := 0; i < n; i++ {
+ envs[i] = gostringw(p)
+ p = (*uint16)(add(unsafe.Pointer(p), uintptr(findnullw(p)+1)*unsafe.Sizeof(*p)))
+ }
+
+ stdcall1(_FreeEnvironmentStringsW, uintptr(unsafe.Pointer(env)))
+}
+
+//go:nosplit
+func exit(code int32) {
+ stdcall1(_ExitProcess, uintptr(code))
+}
+
+//go:nosplit
+func write(fd uintptr, buf unsafe.Pointer, n int32) int32 {
+ const (
+ _STD_OUTPUT_HANDLE = ^uintptr(10) // -11
+ _STD_ERROR_HANDLE = ^uintptr(11) // -12
+ )
+ var handle uintptr
+ switch fd {
+ case 1:
+ handle = stdcall1(_GetStdHandle, _STD_OUTPUT_HANDLE)
+ case 2:
+ handle = stdcall1(_GetStdHandle, _STD_ERROR_HANDLE)
+ default:
+ // assume fd is real windows handle.
+ handle = fd
+ }
+ var written uint32
+ stdcall5(_WriteFile, handle, uintptr(buf), uintptr(n), uintptr(unsafe.Pointer(&written)), 0)
+ return int32(written)
+}
+
+//go:nosplit
+func semasleep(ns int64) int32 {
+ // store ms in ns to save stack space
+ if ns < 0 {
+ ns = _INFINITE
+ } else {
+ ns = int64(timediv(ns, 1000000, nil))
+ if ns == 0 {
+ ns = 1
+ }
+ }
+ if stdcall2(_WaitForSingleObject, getg().m.waitsema, uintptr(ns)) != 0 {
+ return -1 // timeout
+ }
+ return 0
+}
+
+//go:nosplit
+func semawakeup(mp *m) {
+ stdcall1(_SetEvent, mp.waitsema)
+}
+
+//go:nosplit
+func semacreate() uintptr {
+ return stdcall4(_CreateEventA, 0, 0, 0, 0)
+}
+
+func newosproc(mp *m, stk unsafe.Pointer) {
+ const _STACK_SIZE_PARAM_IS_A_RESERVATION = 0x00010000
+ thandle := stdcall6(_CreateThread, 0, 0x20000,
+ funcPC(tstart_stdcall), uintptr(unsafe.Pointer(mp)),
+ _STACK_SIZE_PARAM_IS_A_RESERVATION, 0)
+ if thandle == 0 {
+ println("runtime: failed to create new OS thread (have ", mcount(), " already; errno=", getlasterror(), ")")
+ gothrow("runtime.newosproc")
+ }
+}
+
+// Called to initialize a new m (including the bootstrap m).
+// Called on the parent thread (main thread in case of bootstrap), can allocate memory.
+func mpreinit(mp *m) {
+}
+
+// Called to initialize a new m (including the bootstrap m).
+// Called on the new thread, can not allocate memory.
+func minit() {
+ var thandle uintptr
+ stdcall7(_DuplicateHandle, currentProcess, currentThread, currentProcess, uintptr(unsafe.Pointer(&thandle)), 0, 0, _DUPLICATE_SAME_ACCESS)
+ atomicstoreuintptr(&getg().m.thread, thandle)
+}
+
+// Called from dropm to undo the effect of an minit.
+func unminit() {
+ tp := &getg().m.thread
+ stdcall1(_CloseHandle, *tp)
+ *tp = 0
+}
+
+// Described in http://www.dcl.hpi.uni-potsdam.de/research/WRK/2007/08/getting-os-information-the-kuser_shared_data-structure/
+type _KSYSTEM_TIME struct {
+ LowPart uint32
+ High1Time int32
+ High2Time int32
+}
+
+const (
+ _INTERRUPT_TIME = 0x7ffe0008
+ _SYSTEM_TIME = 0x7ffe0014
+)
+
+//go:nosplit
+func systime(addr uintptr) int64 {
+ timeaddr := (*_KSYSTEM_TIME)(unsafe.Pointer(addr))
+
+ var t _KSYSTEM_TIME
+ for i := 1; i < 10000; i++ {
+ // these fields must be read in that order (see URL above)
+ t.High1Time = timeaddr.High1Time
+ t.LowPart = timeaddr.LowPart
+ t.High2Time = timeaddr.High2Time
+ if t.High1Time == t.High2Time {
+ return int64(t.High1Time)<<32 | int64(t.LowPart)
+ }
+ if (i % 100) == 0 {
+ osyield()
+ }
+ }
+ systemstack(func() {
+ gothrow("interrupt/system time is changing too fast")
+ })
+ return 0
+}
+
+//go:nosplit
+func unixnano() int64 {
+ return (systime(_SYSTEM_TIME) - 116444736000000000) * 100
+}
+
+//go:nosplit
+func nanotime() int64 {
+ return systime(_INTERRUPT_TIME) * 100
+}
+
+// Calling stdcall on os stack.
+//go:nosplit
+func stdcall(fn stdFunction) uintptr {
+ gp := getg()
+ mp := gp.m
+ mp.libcall.fn = uintptr(unsafe.Pointer(fn))
+
+ if mp.profilehz != 0 {
+ // leave pc/sp for cpu profiler
+ mp.libcallg = gp
+ mp.libcallpc = getcallerpc(unsafe.Pointer(&fn))
+ // sp must be the last, because once async cpu profiler finds
+ // all three values to be non-zero, it will use them
+ mp.libcallsp = getcallersp(unsafe.Pointer(&fn))
+ }
+ asmcgocall(unsafe.Pointer(funcPC(asmstdcall)), unsafe.Pointer(&mp.libcall))
+ mp.libcallsp = 0
+ return mp.libcall.r1
+}
+
+//go:nosplit
+func stdcall0(fn stdFunction) uintptr {
+ mp := getg().m
+ mp.libcall.n = 0
+ mp.libcall.args = uintptr(noescape(unsafe.Pointer(&fn))) // it's unused but must be non-nil, otherwise crashes
+ return stdcall(fn)
+}
+
+//go:nosplit
+func stdcall1(fn stdFunction, a0 uintptr) uintptr {
+ mp := getg().m
+ mp.libcall.n = 1
+ mp.libcall.args = uintptr(noescape(unsafe.Pointer(&a0)))
+ return stdcall(fn)
+}
+
+//go:nosplit
+func stdcall2(fn stdFunction, a0, a1 uintptr) uintptr {
+ mp := getg().m
+ mp.libcall.n = 2
+ mp.libcall.args = uintptr(noescape(unsafe.Pointer(&a0)))
+ return stdcall(fn)
+}
+
+//go:nosplit
+func stdcall3(fn stdFunction, a0, a1, a2 uintptr) uintptr {
+ mp := getg().m
+ mp.libcall.n = 3
+ mp.libcall.args = uintptr(noescape(unsafe.Pointer(&a0)))
+ return stdcall(fn)
+}
+
+//go:nosplit
+func stdcall4(fn stdFunction, a0, a1, a2, a3 uintptr) uintptr {
+ mp := getg().m
+ mp.libcall.n = 4
+ mp.libcall.args = uintptr(noescape(unsafe.Pointer(&a0)))
+ return stdcall(fn)
+}
+
+//go:nosplit
+func stdcall5(fn stdFunction, a0, a1, a2, a3, a4 uintptr) uintptr {
+ mp := getg().m
+ mp.libcall.n = 5
+ mp.libcall.args = uintptr(noescape(unsafe.Pointer(&a0)))
+ return stdcall(fn)
+}
+
+//go:nosplit
+func stdcall6(fn stdFunction, a0, a1, a2, a3, a4, a5 uintptr) uintptr {
+ mp := getg().m
+ mp.libcall.n = 6
+ mp.libcall.args = uintptr(noescape(unsafe.Pointer(&a0)))
+ return stdcall(fn)
+}
+
+//go:nosplit
+func stdcall7(fn stdFunction, a0, a1, a2, a3, a4, a5, a6 uintptr) uintptr {
+ mp := getg().m
+ mp.libcall.n = 7
+ mp.libcall.args = uintptr(noescape(unsafe.Pointer(&a0)))
+ return stdcall(fn)
+}
+
+// in sys_windows_386.s and sys_windows_amd64.s
+func usleep1(usec uint32)
+
+//go:nosplit
+func osyield() {
+ usleep1(1)
+}
+
+//go:nosplit
+func usleep(us uint32) {
+ // Have 1us units; want 100ns units.
+ usleep1(10 * us)
+}
+
+func issigpanic(code uint32) uint32 {
+ switch code {
+ default:
+ return 0
+ case _EXCEPTION_ACCESS_VIOLATION:
+ 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:
+ }
+ return 1
+}
+
+func initsig() {
+ /*
+ // TODO(brainman): I don't think we need that bit of code
+ // following line keeps these functions alive at link stage
+ // if there's a better way please write it here
+ void *e = runtime·exceptiontramp;
+ void *f = runtime·firstcontinuetramp;
+ void *l = runtime·lastcontinuetramp;
+ USED(e);
+ USED(f);
+ USED(l);
+ */
+}
+
+func ctrlhandler1(_type uint32) uint32 {
+ var s uint32
+
+ switch _type {
+ case _CTRL_C_EVENT, _CTRL_BREAK_EVENT:
+ s = _SIGINT
+ default:
+ return 0
+ }
+
+ if sigsend(s) {
+ return 1
+ }
+ exit(2) // SIGINT, SIGTERM, etc
+ return 0
+}
+
+// in sys_windows_386.s and sys_windows_amd64.s
+func profileloop()
+
+var profiletimer uintptr
+
+func profilem(mp *m) {
+ var r *context
+ rbuf := make([]byte, unsafe.Sizeof(*r)+15)
+
+ tls := &mp.tls[0]
+ if mp == &m0 {
+ tls = &tls0[0]
+ }
+ gp := *((**g)(unsafe.Pointer(tls)))
+
+ // align Context to 16 bytes
+ r = (*context)(unsafe.Pointer((uintptr(unsafe.Pointer(&rbuf[15]))) &^ 15))
+ r.contextflags = _CONTEXT_CONTROL
+ stdcall2(_GetThreadContext, mp.thread, uintptr(unsafe.Pointer(r)))
+ dosigprof(r, gp, mp)
+}
+
+func profileloop1() {
+ stdcall2(_SetThreadPriority, currentThread, _THREAD_PRIORITY_HIGHEST)
+
+ for {
+ stdcall2(_WaitForSingleObject, profiletimer, _INFINITE)
+ first := (*m)(atomicloadp(unsafe.Pointer(&allm)))
+ for mp := first; mp != nil; mp = mp.alllink {
+ thread := atomicloaduintptr(&mp.thread)
+ // Do not profile threads blocked on Notes,
+ // this includes idle worker threads,
+ // idle timer thread, idle heap scavenger, etc.
+ if thread == 0 || mp.profilehz == 0 || mp.blocked {
+ continue
+ }
+ stdcall1(_SuspendThread, thread)
+ if mp.profilehz != 0 && !mp.blocked {
+ profilem(mp)
+ }
+ stdcall1(_ResumeThread, thread)
+ }
+ }
+}
+
+var cpuprofilerlock mutex
+
+func resetcpuprofiler(hz int32) {
+ lock(&cpuprofilerlock)
+ if profiletimer == 0 {
+ timer := stdcall3(_CreateWaitableTimerA, 0, 0, 0)
+ atomicstoreuintptr(&profiletimer, timer)
+ thread := stdcall6(_CreateThread, 0, 0, funcPC(profileloop), 0, 0, 0)
+ stdcall2(_SetThreadPriority, thread, _THREAD_PRIORITY_HIGHEST)
+ stdcall1(_CloseHandle, thread)
+ }
+ unlock(&cpuprofilerlock)
+
+ ms := int32(0)
+ due := ^int64(^uint64(1 << 63))
+ if hz > 0 {
+ ms = 1000 / hz
+ if ms == 0 {
+ ms = 1
+ }
+ due = int64(ms) * -10000
+ }
+ stdcall6(_SetWaitableTimer, profiletimer, uintptr(unsafe.Pointer(&due)), uintptr(ms), 0, 0, 0)
+ atomicstore((*uint32)(unsafe.Pointer(&getg().m.profilehz)), uint32(hz))
+}
+
+func memlimit() uintptr {
+ return 0
+}
+
+var (
+ badsignalmsg [100]byte
+ badsignallen int32
+)
+
+func setBadSignalMsg() {
+ const msg = "runtime: signal received on thread not created by Go.\n"
+ for i, c := range msg {
+ badsignalmsg[i] = byte(c)
+ badsignallen++
+ }
+}
+
+func crash() {
+ // TODO: This routine should do whatever is needed
+ // to make the Windows program abort/crash as it
+ // would if Go was not intercepting signals.
+ // On Unix the routine would remove the custom signal
+ // handler and then raise a signal (like SIGABRT).
+ // Something like that should happen here.
+ // It's okay to leave this empty for now: if crash returns
+ // the ordinary exit-after-panic happens.
+}
diff --git a/src/runtime/os1_windows_386.go b/src/runtime/os1_windows_386.go
new file mode 100644
index 000000000..0afef9156
--- /dev/null
+++ b/src/runtime/os1_windows_386.go
@@ -0,0 +1,118 @@
+// 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 (
+ "unsafe"
+)
+
+var text struct{}
+
+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")
+}
+
+func isgoexception(info *exceptionrecord, r *context) bool {
+ // Only handle exception if executing instructions in Go binary
+ // (not Windows library code).
+ if r.eip < uint32(uintptr(unsafe.Pointer(&text))) || uint32(uintptr(unsafe.Pointer(&etext))) < r.eip {
+ return false
+ }
+
+ if issigpanic(info.exceptioncode) == 0 {
+ return false
+ }
+
+ return true
+}
+
+// Called by sigtramp from Windows VEH handler.
+// Return value signals whether the exception has been handled (EXCEPTION_CONTINUE_EXECUTION)
+// or should be made available to other handlers in the chain (EXCEPTION_CONTINUE_SEARCH).
+func exceptionhandler(info *exceptionrecord, r *context, gp *g) int32 {
+ if !isgoexception(info, r) {
+ return _EXCEPTION_CONTINUE_SEARCH
+ }
+
+ // 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 = uintptr(info.exceptioninformation[0])
+ gp.sigcode1 = uintptr(info.exceptioninformation[1])
+ gp.sigpc = uintptr(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 := unsafe.Pointer(uintptr(r.esp))
+ sp = add(sp, ^uintptr(unsafe.Sizeof(uintptr(0))-1)) // sp--
+ *((*uintptr)(sp)) = uintptr(r.eip)
+ r.esp = uint32(uintptr(sp))
+ }
+ r.eip = uint32(funcPC(sigpanic))
+ return _EXCEPTION_CONTINUE_EXECUTION
+}
+
+// lastcontinuehandler is reached, because runtime cannot handle
+// current exception. lastcontinuehandler will print crash info and exit.
+func lastcontinuehandler(info *exceptionrecord, r *context, gp *g) uint32 {
+ _g_ := getg()
+
+ if panicking != 0 { // traceback already printed
+ exit(2)
+ }
+ panicking = 1
+
+ print("Exception ", hex(info.exceptioncode), " ", hex(info.exceptioninformation[0]), " ", hex(info.exceptioninformation[1]), " ", hex(r.eip), "\n")
+
+ print("PC=", hex(r.eip), "\n")
+ if _g_.m.lockedg != nil && _g_.m.ncgo > 0 && gp == _g_.m.g0 {
+ print("signal arrived during cgo execution\n")
+ gp = _g_.m.lockedg
+ }
+ print("\n")
+
+ var docrash bool
+ if gotraceback(&docrash) > 0 {
+ tracebacktrap(uintptr(r.eip), uintptr(r.esp), 0, gp)
+ tracebackothers(gp)
+ dumpregs(r)
+ }
+
+ if docrash {
+ crash()
+ }
+
+ exit(2)
+ return 0 // not reached
+}
+
+func sigenable(sig uint32) {
+}
+
+func sigdisable(sig uint32) {
+}
+
+func dosigprof(r *context, gp *g, mp *m) {
+ sigprof((*byte)(unsafe.Pointer(uintptr(r.eip))), (*byte)(unsafe.Pointer(uintptr(r.esp))), nil, gp, mp)
+}
diff --git a/src/runtime/os1_windows_amd64.go b/src/runtime/os1_windows_amd64.go
new file mode 100644
index 000000000..0d21b3881
--- /dev/null
+++ b/src/runtime/os1_windows_amd64.go
@@ -0,0 +1,137 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime
+
+import (
+ "unsafe"
+)
+
+var text struct{}
+
+func dumpregs(r *context) {
+ print("rax ", hex(r.rax), "\n")
+ print("rbx ", hex(r.rbx), "\n")
+ print("rcx ", hex(r.rcx), "\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")
+}
+
+func isgoexception(info *exceptionrecord, r *context) bool {
+ // Only handle exception if executing instructions in Go binary
+ // (not Windows library code).
+ if r.rip < uint64(uintptr(unsafe.Pointer(&text))) || uint64(uintptr(unsafe.Pointer(&etext))) < r.rip {
+ return false
+ }
+
+ if issigpanic(info.exceptioncode) == 0 {
+ return false
+ }
+
+ return true
+}
+
+// Called by sigtramp from Windows VEH handler.
+// Return value signals whether the exception has been handled (EXCEPTION_CONTINUE_EXECUTION)
+// or should be made available to other handlers in the chain (EXCEPTION_CONTINUE_SEARCH).
+
+func exceptionhandler(info *exceptionrecord, r *context, gp *g) int32 {
+ if !isgoexception(info, r) {
+ return _EXCEPTION_CONTINUE_SEARCH
+ }
+
+ // 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 = uintptr(info.exceptioninformation[0])
+ gp.sigcode1 = uintptr(info.exceptioninformation[1])
+ gp.sigpc = uintptr(r.rip)
+
+ // Only push runtime·sigpanic if r->rip != 0.
+ // If r->rip == 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.rip != 0 {
+ sp := unsafe.Pointer(uintptr(r.rsp))
+ sp = add(sp, ^uintptr(unsafe.Sizeof(uintptr(0))-1)) // sp--
+ *((*uintptr)(sp)) = uintptr(r.rip)
+ r.rsp = uint64(uintptr(sp))
+ }
+ r.rip = uint64(funcPC(sigpanic))
+ return _EXCEPTION_CONTINUE_EXECUTION
+}
+
+// It seems Windows searches ContinueHandler's list even
+// if ExceptionHandler returns EXCEPTION_CONTINUE_EXECUTION.
+// firstcontinuehandler will stop that search,
+// if exceptionhandler did the same earlier.
+func firstcontinuehandler(info *exceptionrecord, r *context, gp *g) int32 {
+ if !isgoexception(info, r) {
+ return _EXCEPTION_CONTINUE_SEARCH
+ }
+ return _EXCEPTION_CONTINUE_EXECUTION
+}
+
+// lastcontinuehandler is reached, because runtime cannot handle
+// current exception. lastcontinuehandler will print crash info and exit.
+func lastcontinuehandler(info *exceptionrecord, r *context, gp *g) uint32 {
+ _g_ := getg()
+
+ if panicking != 0 { // traceback already printed
+ exit(2)
+ }
+ panicking = 1
+
+ print("Exception ", hex(info.exceptioncode), " ", hex(info.exceptioninformation[0]), " ", hex(info.exceptioninformation[1]), " ", hex(r.rip), "\n")
+
+ print("PC=", hex(r.rip), "\n")
+ if _g_.m.lockedg != nil && _g_.m.ncgo > 0 && gp == _g_.m.g0 {
+ print("signal arrived during cgo execution\n")
+ gp = _g_.m.lockedg
+ }
+ print("\n")
+
+ var docrash bool
+ if gotraceback(&docrash) > 0 {
+ tracebacktrap(uintptr(r.rip), uintptr(r.rsp), 0, gp)
+ tracebackothers(gp)
+ dumpregs(r)
+ }
+
+ if docrash {
+ crash()
+ }
+
+ exit(2)
+ return 0 // not reached
+}
+
+func sigenable(sig uint32) {
+}
+
+func sigdisable(sig uint32) {
+}
+
+func dosigprof(r *context, gp *g, mp *m) {
+ sigprof((*byte)(unsafe.Pointer(uintptr(r.rip))), (*byte)(unsafe.Pointer(uintptr(r.rsp))), nil, gp, mp)
+}
diff --git a/src/runtime/os2_nacl.go b/src/runtime/os2_nacl.go
new file mode 100644
index 000000000..0c91e0f73
--- /dev/null
+++ b/src/runtime/os2_nacl.go
@@ -0,0 +1,154 @@
+// Copyright 2014 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
+
+const (
+ _NSIG = 32
+ _SI_USER = 1
+
+ // native_client/src/trusted/service_runtime/include/sys/errno.h
+ // The errors are mainly copied from Linux.
+ _EPERM = 1 /* Operation not permitted */
+ _ENOENT = 2 /* No such file or directory */
+ _ESRCH = 3 /* No such process */
+ _EINTR = 4 /* Interrupted system call */
+ _EIO = 5 /* I/O error */
+ _ENXIO = 6 /* No such device or address */
+ _E2BIG = 7 /* Argument list too long */
+ _ENOEXEC = 8 /* Exec format error */
+ _EBADF = 9 /* Bad file number */
+ _ECHILD = 10 /* No child processes */
+ _EAGAIN = 11 /* Try again */
+ _ENOMEM = 12 /* Out of memory */
+ _EACCES = 13 /* Permission denied */
+ _EFAULT = 14 /* Bad address */
+ _EBUSY = 16 /* Device or resource busy */
+ _EEXIST = 17 /* File exists */
+ _EXDEV = 18 /* Cross-device link */
+ _ENODEV = 19 /* No such device */
+ _ENOTDIR = 20 /* Not a directory */
+ _EISDIR = 21 /* Is a directory */
+ _EINVAL = 22 /* Invalid argument */
+ _ENFILE = 23 /* File table overflow */
+ _EMFILE = 24 /* Too many open files */
+ _ENOTTY = 25 /* Not a typewriter */
+ _EFBIG = 27 /* File too large */
+ _ENOSPC = 28 /* No space left on device */
+ _ESPIPE = 29 /* Illegal seek */
+ _EROFS = 30 /* Read-only file system */
+ _EMLINK = 31 /* Too many links */
+ _EPIPE = 32 /* Broken pipe */
+ _ENAMETOOLONG = 36 /* File name too long */
+ _ENOSYS = 38 /* Function not implemented */
+ _EDQUOT = 122 /* Quota exceeded */
+ _EDOM = 33 /* Math arg out of domain of func */
+ _ERANGE = 34 /* Math result not representable */
+ _EDEADLK = 35 /* Deadlock condition */
+ _ENOLCK = 37 /* No record locks available */
+ _ENOTEMPTY = 39 /* Directory not empty */
+ _ELOOP = 40 /* Too many symbolic links */
+ _ENOMSG = 42 /* No message of desired type */
+ _EIDRM = 43 /* Identifier removed */
+ _ECHRNG = 44 /* Channel number out of range */
+ _EL2NSYNC = 45 /* Level 2 not synchronized */
+ _EL3HLT = 46 /* Level 3 halted */
+ _EL3RST = 47 /* Level 3 reset */
+ _ELNRNG = 48 /* Link number out of range */
+ _EUNATCH = 49 /* Protocol driver not attached */
+ _ENOCSI = 50 /* No CSI structure available */
+ _EL2HLT = 51 /* Level 2 halted */
+ _EBADE = 52 /* Invalid exchange */
+ _EBADR = 53 /* Invalid request descriptor */
+ _EXFULL = 54 /* Exchange full */
+ _ENOANO = 55 /* No anode */
+ _EBADRQC = 56 /* Invalid request code */
+ _EBADSLT = 57 /* Invalid slot */
+ _EDEADLOCK = _EDEADLK /* File locking deadlock error */
+ _EBFONT = 59 /* Bad font file fmt */
+ _ENOSTR = 60 /* Device not a stream */
+ _ENODATA = 61 /* No data (for no delay io) */
+ _ETIME = 62 /* Timer expired */
+ _ENOSR = 63 /* Out of streams resources */
+ _ENONET = 64 /* Machine is not on the network */
+ _ENOPKG = 65 /* Package not installed */
+ _EREMOTE = 66 /* The object is remote */
+ _ENOLINK = 67 /* The link has been severed */
+ _EADV = 68 /* Advertise error */
+ _ESRMNT = 69 /* Srmount error */
+ _ECOMM = 70 /* Communication error on send */
+ _EPROTO = 71 /* Protocol error */
+ _EMULTIHOP = 72 /* Multihop attempted */
+ _EDOTDOT = 73 /* Cross mount point (not really error) */
+ _EBADMSG = 74 /* Trying to read unreadable message */
+ _EOVERFLOW = 75 /* Value too large for defined data type */
+ _ENOTUNIQ = 76 /* Given log. name not unique */
+ _EBADFD = 77 /* f.d. invalid for this operation */
+ _EREMCHG = 78 /* Remote address changed */
+ _ELIBACC = 79 /* Can't access a needed shared lib */
+ _ELIBBAD = 80 /* Accessing a corrupted shared lib */
+ _ELIBSCN = 81 /* .lib section in a.out corrupted */
+ _ELIBMAX = 82 /* Attempting to link in too many libs */
+ _ELIBEXEC = 83 /* Attempting to exec a shared library */
+ _EILSEQ = 84
+ _EUSERS = 87
+ _ENOTSOCK = 88 /* Socket operation on non-socket */
+ _EDESTADDRREQ = 89 /* Destination address required */
+ _EMSGSIZE = 90 /* Message too long */
+ _EPROTOTYPE = 91 /* Protocol wrong type for socket */
+ _ENOPROTOOPT = 92 /* Protocol not available */
+ _EPROTONOSUPPORT = 93 /* Unknown protocol */
+ _ESOCKTNOSUPPORT = 94 /* Socket type not supported */
+ _EOPNOTSUPP = 95 /* Operation not supported on transport endpoint */
+ _EPFNOSUPPORT = 96 /* Protocol family not supported */
+ _EAFNOSUPPORT = 97 /* Address family not supported by protocol family */
+ _EADDRINUSE = 98 /* Address already in use */
+ _EADDRNOTAVAIL = 99 /* Address not available */
+ _ENETDOWN = 100 /* Network interface is not configured */
+ _ENETUNREACH = 101 /* Network is unreachable */
+ _ENETRESET = 102
+ _ECONNABORTED = 103 /* Connection aborted */
+ _ECONNRESET = 104 /* Connection reset by peer */
+ _ENOBUFS = 105 /* No buffer space available */
+ _EISCONN = 106 /* Socket is already connected */
+ _ENOTCONN = 107 /* Socket is not connected */
+ _ESHUTDOWN = 108 /* Can't send after socket shutdown */
+ _ETOOMANYREFS = 109
+ _ETIMEDOUT = 110 /* Connection timed out */
+ _ECONNREFUSED = 111 /* Connection refused */
+ _EHOSTDOWN = 112 /* Host is down */
+ _EHOSTUNREACH = 113 /* Host is unreachable */
+ _EALREADY = 114 /* Socket already connected */
+ _EINPROGRESS = 115 /* Connection already in progress */
+ _ESTALE = 116
+ _ENOTSUP = _EOPNOTSUPP /* Not supported */
+ _ENOMEDIUM = 123 /* No medium (in tape drive) */
+ _ECANCELED = 125 /* Operation canceled. */
+ _ELBIN = 2048 /* Inode is remote (not really error) */
+ _EFTYPE = 2049 /* Inappropriate file type or format */
+ _ENMFILE = 2050 /* No more files */
+ _EPROCLIM = 2051
+ _ENOSHARE = 2052 /* No such host or network path */
+ _ECASECLASH = 2053 /* Filename exists with different case */
+ _EWOULDBLOCK = _EAGAIN /* Operation would block */
+
+ // native_client/src/trusted/service_runtime/include/bits/mman.h.
+ // NOTE: DO NOT USE native_client/src/shared/imc/nacl_imc_c.h.
+ // Those MAP_*values are different from these.
+ _PROT_NONE = 0x0
+ _PROT_READ = 0x1
+ _PROT_WRITE = 0x2
+ _PROT_EXEC = 0x4
+
+ _MAP_SHARED = 0x1
+ _MAP_PRIVATE = 0x2
+ _MAP_FIXED = 0x10
+ _MAP_ANON = 0x20
+
+ _MADV_FREE = 0
+ _SIGFPE = 8
+ _FPE_INTDIV = 0
+)
+
+type siginfo struct{}
diff --git a/src/runtime/os2_netbsd.go b/src/runtime/os2_netbsd.go
new file mode 100644
index 000000000..46576b9bc
--- /dev/null
+++ b/src/runtime/os2_netbsd.go
@@ -0,0 +1,18 @@
+// 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.
+
+package runtime
+
+const (
+ _SS_DISABLE = 4
+ _SIG_BLOCK = 1
+ _SIG_UNBLOCK = 2
+ _SIG_SETMASK = 3
+ _NSIG = 33
+ _SI_USER = 0
+
+ // From NetBSD's <sys/ucontext.h>
+ _UC_SIGMASK = 0x01
+ _UC_CPU = 0x04
+)
diff --git a/src/runtime/os2_plan9.go b/src/runtime/os2_plan9.go
new file mode 100644
index 000000000..f64f4c8da
--- /dev/null
+++ b/src/runtime/os2_plan9.go
@@ -0,0 +1,72 @@
+// 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.
+
+// Plan 9-specific system calls
+
+package runtime
+
+// open
+const (
+ _OREAD = 0
+ _OWRITE = 1
+ _ORDWR = 2
+ _OEXEC = 3
+ _OTRUNC = 16
+ _OCEXEC = 32
+ _ORCLOSE = 64
+ _OEXCL = 0x1000
+)
+
+// rfork
+const (
+ _RFNAMEG = 1 << 0
+ _RFENVG = 1 << 1
+ _RFFDG = 1 << 2
+ _RFNOTEG = 1 << 3
+ _RFPROC = 1 << 4
+ _RFMEM = 1 << 5
+ _RFNOWAIT = 1 << 6
+ _RFCNAMEG = 1 << 10
+ _RFCENVG = 1 << 11
+ _RFCFDG = 1 << 12
+ _RFREND = 1 << 13
+ _RFNOMNT = 1 << 14
+)
+
+// notify
+const (
+ _NCONT = 0
+ _NDFLT = 1
+)
+
+type uinptr _Plink
+
+type tos struct {
+ prof struct { // Per process profiling
+ pp *_Plink // known to be 0(ptr)
+ next *_Plink // known to be 4(ptr)
+ last *_Plink
+ first *_Plink
+ pid uint32
+ what uint32
+ }
+ cyclefreq uint64 // cycle clock frequency if there is one, 0 otherwise
+ kcycles int64 // cycles spent in kernel
+ pcycles int64 // cycles spent in process (kernel + user)
+ pid uint32 // might as well put the pid here
+ clock uint32
+ // top of stack is here
+}
+
+const (
+ _NSIG = 14 // number of signals in sigtable array
+ _ERRMAX = 128 // max length of note string
+
+ // Notes in runtime·sigtab that are handled by runtime·sigpanic.
+ _SIGRFAULT = 2
+ _SIGWFAULT = 3
+ _SIGINTDIV = 4
+ _SIGFLOAT = 5
+ _SIGTRAP = 6
+)
diff --git a/src/runtime/os2_windows.go b/src/runtime/os2_windows.go
new file mode 100644
index 000000000..d5b1f471f
--- /dev/null
+++ b/src/runtime/os2_windows.go
@@ -0,0 +1,25 @@
+// 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 "unsafe"
+
+// Call a Windows function with stdcall conventions,
+// and switch to os stack during the call.
+func asmstdcall(fn unsafe.Pointer)
+
+func getlasterror() uint32
+func setlasterror(err uint32)
+
+// Function to be called by windows CreateThread
+// to start new os thread.
+func tstart_stdcall(newm *m) uint32
+
+func ctrlhandler(_type uint32) uint32
+
+// TODO(brainman): should not need those
+const (
+ _NSIG = 65
+)
diff --git a/src/runtime/os_android.h b/src/runtime/os_android.h
deleted file mode 100644
index c7c1098e8..000000000
--- a/src/runtime/os_android.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "os_linux.h"
diff --git a/src/runtime/os_android.c b/src/runtime/os_android_arm.go
index 5805f6871..132832236 100644
--- a/src/runtime/os_android.c
+++ b/src/runtime/os_android_arm.go
@@ -2,15 +2,14 @@
// 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_GOOS_GOARCH.h"
-#include "os_GOOS.h"
+package runtime
+
+import _ "unsafe"
// Export the runtime entry point symbol.
//
// Used by the app package to start the Go runtime after loading
// a shared library via JNI. See golang.org/x/mobile/app.
-void _rt0_arm_linux1();
-#pragma cgo_export_static _rt0_arm_linux1
-#pragma cgo_export_dynamic _rt0_arm_linux1
+//go:cgo_export_static _rt0_arm_linux1
+//go:cgo_export_dynamic _rt0_arm_linux1
diff --git a/src/runtime/os_nacl.c b/src/runtime/os_nacl.c
deleted file mode 100644
index ad72cc7c6..000000000
--- a/src/runtime/os_nacl.c
+++ /dev/null
@@ -1,315 +0,0 @@
-// 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.
-
-#include "runtime.h"
-#include "defs_GOOS_GOARCH.h"
-#include "os_GOOS.h"
-#include "arch_GOARCH.h"
-#include "textflag.h"
-#include "stack.h"
-
-int8 *goos = "nacl";
-extern SigTab runtime·sigtab[];
-
-void runtime·sigtramp(void);
-
-// Called to initialize a new m (including the bootstrap m).
-// Called on the parent thread (main thread in case of bootstrap), can allocate memory.
-void
-runtime·mpreinit(M *mp)
-{
- mp->gsignal = runtime·malg(32*1024); // OS X wants >=8K, Linux >=2K
- runtime·writebarrierptr_nostore(&mp->gsignal, mp->gsignal);
-
- mp->gsignal->m = mp;
- runtime·writebarrierptr_nostore(&mp->gsignal->m, mp->gsignal->m);
-}
-
-// Called to initialize a new m (including the bootstrap m).
-// Called on the new thread, can not allocate memory.
-void
-runtime·minit(void)
-{
- int32 ret;
-
- // Initialize signal handling
- ret = runtime·nacl_exception_stack((byte*)g->m->gsignal->stack.lo, 32*1024);
- if(ret < 0)
- runtime·printf("runtime: nacl_exception_stack: error %d\n", -ret);
-
- ret = runtime·nacl_exception_handler(runtime·sigtramp, nil);
- if(ret < 0)
- runtime·printf("runtime: nacl_exception_handler: error %d\n", -ret);
-}
-
-// Called from dropm to undo the effect of an minit.
-void
-runtime·unminit(void)
-{
-}
-
-int8 runtime·sigtrampf[] = "runtime: signal at PC=%X AX=%X CX=%X DX=%X BX=%X DI=%X R15=%X *SP=%X\n";
-int8 runtime·sigtrampp[] = "runtime: sigtramp";
-
-extern byte runtime·tls0[];
-
-void
-runtime·osinit(void)
-{
- runtime·ncpu = 1;
- g->m->procid = 2;
-//runtime·nacl_exception_handler(runtime·sigtramp, nil);
-}
-
-void
-runtime·crash(void)
-{
- *(int32*)0 = 0;
-}
-
-#pragma textflag NOSPLIT
-void
-runtime·get_random_data(byte **rnd, int32 *rnd_len)
-{
- *rnd = nil;
- *rnd_len = 0;
-}
-
-void
-runtime·goenvs(void)
-{
- runtime·goenvs_unix();
-}
-
-void
-runtime·initsig(void)
-{
-}
-
-#pragma textflag NOSPLIT
-void
-runtime·usleep(uint32 us)
-{
- Timespec ts;
-
- ts.tv_sec = us/1000000;
- ts.tv_nsec = (us%1000000)*1000;
- runtime·nacl_nanosleep(&ts, nil);
-}
-
-void runtime·mstart_nacl(void);
-
-void
-runtime·newosproc(M *mp, void *stk)
-{
- int32 ret;
- void **tls;
-
- tls = (void**)mp->tls;
- tls[0] = mp->g0;
- tls[1] = mp;
- ret = runtime·nacl_thread_create(runtime·mstart_nacl, stk, tls+2, 0);
- if(ret < 0) {
- runtime·printf("nacl_thread_create: error %d\n", -ret);
- runtime·throw("newosproc");
- }
-}
-
-static void
-semacreate(void)
-{
- int32 mu, cond;
-
- mu = runtime·nacl_mutex_create(0);
- if(mu < 0) {
- runtime·printf("nacl_mutex_create: error %d\n", -mu);
- runtime·throw("semacreate");
- }
- cond = runtime·nacl_cond_create(0);
- if(cond < 0) {
- runtime·printf("nacl_cond_create: error %d\n", -cond);
- runtime·throw("semacreate");
- }
- g->m->waitsemalock = mu;
- g->m->scalararg[0] = cond; // assigned to m->waitsema
-}
-
-#pragma textflag NOSPLIT
-uint32
-runtime·semacreate(void)
-{
- void (*fn)(void);
- uint32 x;
-
- fn = semacreate;
- runtime·onM(&fn);
- x = g->m->scalararg[0];
- g->m->scalararg[0] = 0;
- return x;
-}
-
-static void
-semasleep(void)
-{
- int32 ret;
- int64 ns;
-
- ns = (int64)(uint32)g->m->scalararg[0] | (int64)(uint32)g->m->scalararg[1]<<32;
- g->m->scalararg[0] = 0;
- g->m->scalararg[1] = 0;
-
- ret = runtime·nacl_mutex_lock(g->m->waitsemalock);
- if(ret < 0) {
- //runtime·printf("nacl_mutex_lock: error %d\n", -ret);
- runtime·throw("semasleep");
- }
- if(g->m->waitsemacount > 0) {
- g->m->waitsemacount = 0;
- runtime·nacl_mutex_unlock(g->m->waitsemalock);
- g->m->scalararg[0] = 0;
- return;
- }
-
- while(g->m->waitsemacount == 0) {
- if(ns < 0) {
- ret = runtime·nacl_cond_wait(g->m->waitsema, g->m->waitsemalock);
- if(ret < 0) {
- //runtime·printf("nacl_cond_wait: error %d\n", -ret);
- runtime·throw("semasleep");
- }
- } else {
- Timespec ts;
-
- ns += runtime·nanotime();
- ts.tv_sec = runtime·timediv(ns, 1000000000, (int32*)&ts.tv_nsec);
- ret = runtime·nacl_cond_timed_wait_abs(g->m->waitsema, g->m->waitsemalock, &ts);
- if(ret == -ETIMEDOUT) {
- runtime·nacl_mutex_unlock(g->m->waitsemalock);
- g->m->scalararg[0] = -1;
- return;
- }
- if(ret < 0) {
- //runtime·printf("nacl_cond_timed_wait_abs: error %d\n", -ret);
- runtime·throw("semasleep");
- }
- }
- }
-
- g->m->waitsemacount = 0;
- runtime·nacl_mutex_unlock(g->m->waitsemalock);
- g->m->scalararg[0] = 0;
-}
-
-#pragma textflag NOSPLIT
-int32
-runtime·semasleep(int64 ns)
-{
- int32 r;
- void (*fn)(void);
-
- g->m->scalararg[0] = (uint32)ns;
- g->m->scalararg[1] = (uint32)(ns>>32);
- fn = semasleep;
- runtime·onM(&fn);
- r = g->m->scalararg[0];
- g->m->scalararg[0] = 0;
- return r;
-}
-
-static void
-semawakeup(void)
-{
- int32 ret;
- M *mp;
-
- mp = g->m->ptrarg[0];
- g->m->ptrarg[0] = nil;
-
- ret = runtime·nacl_mutex_lock(mp->waitsemalock);
- if(ret < 0) {
- //runtime·printf("nacl_mutex_lock: error %d\n", -ret);
- runtime·throw("semawakeup");
- }
- if(mp->waitsemacount != 0) {
- //runtime·printf("semawakeup: double wakeup\n");
- runtime·throw("semawakeup");
- }
- mp->waitsemacount = 1;
- runtime·nacl_cond_signal(mp->waitsema);
- runtime·nacl_mutex_unlock(mp->waitsemalock);
-}
-
-#pragma textflag NOSPLIT
-void
-runtime·semawakeup(M *mp)
-{
- void (*fn)(void);
-
- g->m->ptrarg[0] = mp;
- fn = semawakeup;
- runtime·onM(&fn);
-}
-
-uintptr
-runtime·memlimit(void)
-{
- runtime·printf("memlimit\n");
- return 0;
-}
-
-#pragma dataflag NOPTR
-static int8 badsignal[] = "runtime: signal received on thread not created by Go.\n";
-
-// This runs on a foreign stack, without an m or a g. No stack split.
-#pragma textflag NOSPLIT
-void
-runtime·badsignal2(void)
-{
- runtime·write(2, badsignal, sizeof badsignal - 1);
- runtime·exit(2);
-}
-
-void runtime·madvise(byte*, uintptr, int32) { }
-void runtime·munmap(byte*, uintptr) {}
-
-void
-runtime·resetcpuprofiler(int32 hz)
-{
- USED(hz);
-}
-
-void
-runtime·sigdisable(uint32)
-{
-}
-
-void
-runtime·sigenable(uint32)
-{
-}
-
-void
-runtime·closeonexec(int32)
-{
-}
-
-uint32 runtime·writelock; // test-and-set spin lock for runtime.write
-
-/*
-An attempt at IRT. Doesn't work. See end of sys_nacl_amd64.s.
-
-void (*runtime·nacl_irt_query)(void);
-
-int8 runtime·nacl_irt_basic_v0_1_str[] = "nacl-irt-basic-0.1";
-void *runtime·nacl_irt_basic_v0_1[6]; // exit, gettod, clock, nanosleep, sched_yield, sysconf
-int32 runtime·nacl_irt_basic_v0_1_size = sizeof(runtime·nacl_irt_basic_v0_1);
-
-int8 runtime·nacl_irt_memory_v0_3_str[] = "nacl-irt-memory-0.3";
-void *runtime·nacl_irt_memory_v0_3[3]; // mmap, munmap, mprotect
-int32 runtime·nacl_irt_memory_v0_3_size = sizeof(runtime·nacl_irt_memory_v0_3);
-
-int8 runtime·nacl_irt_thread_v0_1_str[] = "nacl-irt-thread-0.1";
-void *runtime·nacl_irt_thread_v0_1[3]; // thread_create, thread_exit, thread_nice
-int32 runtime·nacl_irt_thread_v0_1_size = sizeof(runtime·nacl_irt_thread_v0_1);
-*/
diff --git a/src/runtime/os_nacl.go b/src/runtime/os_nacl.go
index 8dd43ff06..eff9ec30e 100644
--- a/src/runtime/os_nacl.go
+++ b/src/runtime/os_nacl.go
@@ -6,8 +6,8 @@ package runtime
import "unsafe"
-func nacl_exception_stack(p unsafe.Pointer, size int32) int32
-func nacl_exception_handler(fn, arg unsafe.Pointer) int32
+func nacl_exception_stack(p uintptr, size int32) int32
+func nacl_exception_handler(fn uintptr, arg unsafe.Pointer) int32
func nacl_sem_create(flag int32) int32
func nacl_sem_wait(sem int32) int32
func nacl_sem_post(sem int32) int32
@@ -19,9 +19,20 @@ func nacl_cond_create(flag int32) int32
func nacl_cond_wait(cond, n int32) int32
func nacl_cond_signal(cond int32) int32
func nacl_cond_broadcast(cond int32) int32
-func nacl_cond_timed_wait_abs(cond, lock int32, ts unsafe.Pointer) int32
-func nacl_thread_create(fn, stk, tls, xx unsafe.Pointer) int32
-func nacl_nanosleep(ts, extra unsafe.Pointer) int32
+
+//go:noescape
+func nacl_cond_timed_wait_abs(cond, lock int32, ts *timespec) int32
+func nacl_thread_create(fn uintptr, stk, tls, xx unsafe.Pointer) int32
+
+//go:noescape
+func nacl_nanosleep(ts, extra *timespec) int32
+func nanotime() int64
+func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) unsafe.Pointer
+func exit(code int32)
+func osyield()
+
+//go:noescape
+func write(fd uintptr, p unsafe.Pointer, n int32) int32
func os_sigpipe() {
gothrow("too many writes on closed pipe")
diff --git a/src/runtime/os_nacl.h b/src/runtime/os_nacl.h
deleted file mode 100644
index 7c9d9c242..000000000
--- a/src/runtime/os_nacl.h
+++ /dev/null
@@ -1,162 +0,0 @@
-enum {
- NSIG = 32,
- SI_USER = 1,
-
- // native_client/src/trusted/service_runtime/include/sys/errno.h
- // The errors are mainly copied from Linux.
- EPERM = 1, /* Operation not permitted */
- ENOENT = 2, /* No such file or directory */
- ESRCH = 3, /* No such process */
- EINTR = 4, /* Interrupted system call */
- EIO = 5, /* I/O error */
- ENXIO = 6, /* No such device or address */
- E2BIG = 7, /* Argument list too long */
- ENOEXEC = 8, /* Exec format error */
- EBADF = 9, /* Bad file number */
- ECHILD = 10, /* No child processes */
- EAGAIN = 11, /* Try again */
- ENOMEM = 12, /* Out of memory */
- EACCES = 13, /* Permission denied */
- EFAULT = 14, /* Bad address */
- EBUSY = 16, /* Device or resource busy */
- EEXIST = 17, /* File exists */
- EXDEV = 18, /* Cross-device link */
- ENODEV = 19, /* No such device */
- ENOTDIR = 20, /* Not a directory */
- EISDIR = 21, /* Is a directory */
- EINVAL = 22, /* Invalid argument */
- ENFILE = 23, /* File table overflow */
- EMFILE = 24, /* Too many open files */
- ENOTTY = 25, /* Not a typewriter */
- EFBIG = 27, /* File too large */
- ENOSPC = 28, /* No space left on device */
- ESPIPE = 29, /* Illegal seek */
- EROFS = 30, /* Read-only file system */
- EMLINK = 31, /* Too many links */
- EPIPE = 32, /* Broken pipe */
- ENAMETOOLONG = 36, /* File name too long */
- ENOSYS = 38, /* Function not implemented */
- EDQUOT = 122, /* Quota exceeded */
- EDOM = 33, /* Math arg out of domain of func */
- ERANGE = 34, /* Math result not representable */
- EDEADLK = 35, /* Deadlock condition */
- ENOLCK = 37, /* No record locks available */
- ENOTEMPTY = 39, /* Directory not empty */
- ELOOP = 40, /* Too many symbolic links */
- ENOMSG = 42, /* No message of desired type */
- EIDRM = 43, /* Identifier removed */
- ECHRNG = 44, /* Channel number out of range */
- EL2NSYNC = 45, /* Level 2 not synchronized */
- EL3HLT = 46, /* Level 3 halted */
- EL3RST = 47, /* Level 3 reset */
- ELNRNG = 48, /* Link number out of range */
- EUNATCH = 49, /* Protocol driver not attached */
- ENOCSI = 50, /* No CSI structure available */
- EL2HLT = 51, /* Level 2 halted */
- EBADE = 52, /* Invalid exchange */
- EBADR = 53, /* Invalid request descriptor */
- EXFULL = 54, /* Exchange full */
- ENOANO = 55, /* No anode */
- EBADRQC = 56, /* Invalid request code */
- EBADSLT = 57, /* Invalid slot */
- EDEADLOCK = EDEADLK, /* File locking deadlock error */
- EBFONT = 59, /* Bad font file fmt */
- ENOSTR = 60, /* Device not a stream */
- ENODATA = 61, /* No data (for no delay io) */
- ETIME = 62, /* Timer expired */
- ENOSR = 63, /* Out of streams resources */
- ENONET = 64, /* Machine is not on the network */
- ENOPKG = 65, /* Package not installed */
- EREMOTE = 66, /* The object is remote */
- ENOLINK = 67, /* The link has been severed */
- EADV = 68, /* Advertise error */
- ESRMNT = 69, /* Srmount error */
- ECOMM = 70, /* Communication error on send */
- EPROTO = 71, /* Protocol error */
- EMULTIHOP = 72, /* Multihop attempted */
- EDOTDOT = 73, /* Cross mount point (not really error) */
- EBADMSG = 74, /* Trying to read unreadable message */
- EOVERFLOW = 75, /* Value too large for defined data type */
- ENOTUNIQ = 76, /* Given log. name not unique */
- EBADFD = 77, /* f.d. invalid for this operation */
- EREMCHG = 78, /* Remote address changed */
- ELIBACC = 79, /* Can't access a needed shared lib */
- ELIBBAD = 80, /* Accessing a corrupted shared lib */
- ELIBSCN = 81, /* .lib section in a.out corrupted */
- ELIBMAX = 82, /* Attempting to link in too many libs */
- ELIBEXEC = 83, /* Attempting to exec a shared library */
- EILSEQ = 84,
- EUSERS = 87,
- ENOTSOCK = 88, /* Socket operation on non-socket */
- EDESTADDRREQ = 89, /* Destination address required */
- EMSGSIZE = 90, /* Message too long */
- EPROTOTYPE = 91, /* Protocol wrong type for socket */
- ENOPROTOOPT = 92, /* Protocol not available */
- EPROTONOSUPPORT = 93, /* Unknown protocol */
- ESOCKTNOSUPPORT = 94, /* Socket type not supported */
- EOPNOTSUPP = 95, /* Operation not supported on transport endpoint */
- EPFNOSUPPORT = 96, /* Protocol family not supported */
- EAFNOSUPPORT = 97, /* Address family not supported by protocol family */
- EADDRINUSE = 98, /* Address already in use */
- EADDRNOTAVAIL = 99, /* Address not available */
- ENETDOWN = 100, /* Network interface is not configured */
- ENETUNREACH = 101, /* Network is unreachable */
- ENETRESET = 102,
- ECONNABORTED = 103, /* Connection aborted */
- ECONNRESET = 104, /* Connection reset by peer */
- ENOBUFS = 105, /* No buffer space available */
- EISCONN = 106, /* Socket is already connected */
- ENOTCONN = 107, /* Socket is not connected */
- ESHUTDOWN = 108, /* Can't send after socket shutdown */
- ETOOMANYREFS = 109,
- ETIMEDOUT = 110, /* Connection timed out */
- ECONNREFUSED = 111, /* Connection refused */
- EHOSTDOWN = 112, /* Host is down */
- EHOSTUNREACH = 113, /* Host is unreachable */
- EALREADY = 114, /* Socket already connected */
- EINPROGRESS = 115, /* Connection already in progress */
- ESTALE = 116,
- ENOTSUP = EOPNOTSUPP, /* Not supported */
- ENOMEDIUM = 123, /* No medium (in tape drive) */
- ECANCELED = 125, /* Operation canceled. */
- ELBIN = 2048, /* Inode is remote (not really error) */
- EFTYPE = 2049, /* Inappropriate file type or format */
- ENMFILE = 2050, /* No more files */
- EPROCLIM = 2051,
- ENOSHARE = 2052, /* No such host or network path */
- ECASECLASH = 2053, /* Filename exists with different case */
- EWOULDBLOCK = EAGAIN, /* Operation would block */
-
- // native_client/src/trusted/service_runtime/include/bits/mman.h.
- // NOTE: DO NOT USE native_client/src/shared/imc/nacl_imc_c.h.
- // Those MAP_*values are different from these.
- PROT_NONE = 0x0,
- PROT_READ = 0x1,
- PROT_WRITE = 0x2,
- PROT_EXEC = 0x4,
-
- MAP_SHARED = 0x1,
- MAP_PRIVATE = 0x2,
- MAP_FIXED = 0x10,
- MAP_ANON = 0x20,
-};
-typedef byte* kevent_udata;
-
-int32 runtime·nacl_exception_stack(byte*, int32);
-int32 runtime·nacl_exception_handler(void*, void*);
-int32 runtime·nacl_sem_create(int32);
-int32 runtime·nacl_sem_wait(int32);
-int32 runtime·nacl_sem_post(int32);
-int32 runtime·nacl_mutex_create(int32);
-int32 runtime·nacl_mutex_lock(int32);
-int32 runtime·nacl_mutex_trylock(int32);
-int32 runtime·nacl_mutex_unlock(int32);
-int32 runtime·nacl_cond_create(int32);
-int32 runtime·nacl_cond_wait(int32, int32);
-int32 runtime·nacl_cond_signal(int32);
-int32 runtime·nacl_cond_broadcast(int32);
-int32 runtime·nacl_cond_timed_wait_abs(int32, int32, Timespec*);
-int32 runtime·nacl_thread_create(void*, void*, void*, void*);
-int32 runtime·nacl_nanosleep(Timespec*, Timespec*);
-
-void runtime·sigpanic(void);
diff --git a/src/runtime/os_nacl_arm.c b/src/runtime/os_nacl_arm.go
index 1248ea644..a43e7c47b 100644
--- a/src/runtime/os_nacl_arm.c
+++ b/src/runtime/os_nacl_arm.go
@@ -2,23 +2,16 @@
// 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_GOOS_GOARCH.h"
-#include "os_GOOS.h"
-#include "textflag.h"
+package runtime
-void
-runtime·checkgoarm(void)
-{
- return; // NaCl/ARM only supports ARMv7
+func checkgoarm() {
+ return // NaCl/ARM only supports ARMv7
}
-#pragma textflag NOSPLIT
-int64
-runtime·cputicks(void)
-{
+//go:nosplit
+func cputicks() int64 {
// Currently cputicks() is used in blocking profiler and to seed runtime·fastrand1().
// runtime·nanotime() is a poor approximation of CPU ticks that is enough for the profiler.
// TODO: need more entropy to better seed fastrand1.
- return runtime·nanotime();
+ return nanotime()
}
diff --git a/src/runtime/os_netbsd.c b/src/runtime/os_netbsd.c
deleted file mode 100644
index 28929ea57..000000000
--- a/src/runtime/os_netbsd.c
+++ /dev/null
@@ -1,371 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "runtime.h"
-#include "defs_GOOS_GOARCH.h"
-#include "os_GOOS.h"
-#include "signal_unix.h"
-#include "stack.h"
-#include "textflag.h"
-
-enum
-{
- ESRCH = 3,
- ENOTSUP = 91,
-
- // From NetBSD's <sys/time.h>
- CLOCK_REALTIME = 0,
- CLOCK_VIRTUAL = 1,
- CLOCK_PROF = 2,
- CLOCK_MONOTONIC = 3
-};
-
-extern SigTab runtime·sigtab[];
-
-static Sigset sigset_none;
-static Sigset sigset_all = { ~(uint32)0, ~(uint32)0, ~(uint32)0, ~(uint32)0, };
-
-extern void runtime·getcontext(UcontextT *context);
-extern int32 runtime·lwp_create(UcontextT *context, uintptr flags, void *lwpid);
-extern void runtime·lwp_mcontext_init(void *mc, void *stack, M *mp, G *gp, void (*fn)(void));
-extern int32 runtime·lwp_park(Timespec *abstime, int32 unpark, void *hint, void *unparkhint);
-extern int32 runtime·lwp_unpark(int32 lwp, void *hint);
-extern int32 runtime·lwp_self(void);
-
-// From NetBSD's <sys/sysctl.h>
-#define CTL_HW 6
-#define HW_NCPU 3
-
-static int32
-getncpu(void)
-{
- uint32 mib[2];
- uint32 out;
- int32 ret;
- uintptr nout;
-
- // Fetch hw.ncpu via sysctl.
- mib[0] = CTL_HW;
- mib[1] = HW_NCPU;
- nout = sizeof out;
- out = 0;
- ret = runtime·sysctl(mib, 2, (byte*)&out, &nout, nil, 0);
- if(ret >= 0)
- return out;
- else
- return 1;
-}
-
-#pragma textflag NOSPLIT
-uintptr
-runtime·semacreate(void)
-{
- return 1;
-}
-
-static void
-semasleep(void)
-{
- int64 ns;
- Timespec ts;
-
- ns = (int64)(uint32)g->m->scalararg[0] | (int64)(uint32)g->m->scalararg[1]<<32;
- g->m->scalararg[0] = 0;
- g->m->scalararg[1] = 0;
-
- // spin-mutex lock
- while(runtime·xchg(&g->m->waitsemalock, 1))
- runtime·osyield();
-
- for(;;) {
- // lock held
- if(g->m->waitsemacount == 0) {
- // sleep until semaphore != 0 or timeout.
- // thrsleep unlocks m->waitsemalock.
- if(ns < 0) {
- // TODO(jsing) - potential deadlock!
- //
- // There is a potential deadlock here since we
- // have to release the waitsemalock mutex
- // before we call lwp_park() to suspend the
- // thread. This allows another thread to
- // release the lock and call lwp_unpark()
- // before the thread is actually suspended.
- // If this occurs the current thread will end
- // up sleeping indefinitely. Unfortunately
- // the NetBSD kernel does not appear to provide
- // a mechanism for unlocking the userspace
- // mutex once the thread is actually parked.
- runtime·atomicstore(&g->m->waitsemalock, 0);
- runtime·lwp_park(nil, 0, &g->m->waitsemacount, nil);
- } else {
- ns = ns + runtime·nanotime();
- // NOTE: tv_nsec is int64 on amd64, so this assumes a little-endian system.
- ts.tv_nsec = 0;
- ts.tv_sec = runtime·timediv(ns, 1000000000, (int32*)&ts.tv_nsec);
- // TODO(jsing) - potential deadlock!
- // See above for details.
- runtime·atomicstore(&g->m->waitsemalock, 0);
- runtime·lwp_park(&ts, 0, &g->m->waitsemacount, nil);
- }
- // reacquire lock
- while(runtime·xchg(&g->m->waitsemalock, 1))
- runtime·osyield();
- }
-
- // lock held (again)
- if(g->m->waitsemacount != 0) {
- // semaphore is available.
- g->m->waitsemacount--;
- // spin-mutex unlock
- runtime·atomicstore(&g->m->waitsemalock, 0);
- g->m->scalararg[0] = 0; // semaphore acquired
- return;
- }
-
- // semaphore not available.
- // if there is a timeout, stop now.
- // otherwise keep trying.
- if(ns >= 0)
- break;
- }
-
- // lock held but giving up
- // spin-mutex unlock
- runtime·atomicstore(&g->m->waitsemalock, 0);
- g->m->scalararg[0] = -1;
- return;
-}
-
-#pragma textflag NOSPLIT
-int32
-runtime·semasleep(int64 ns)
-{
- int32 r;
- void (*fn)(void);
-
- g->m->scalararg[0] = (uint32)ns;
- g->m->scalararg[1] = (uint32)(ns>>32);
- fn = semasleep;
- runtime·onM(&fn);
- r = g->m->scalararg[0];
- g->m->scalararg[0] = 0;
- return r;
-}
-
-static void badsemawakeup(void);
-
-#pragma textflag NOSPLIT
-void
-runtime·semawakeup(M *mp)
-{
- uint32 ret;
- void (*fn)(void);
- void *oldptr;
- uintptr oldscalar;
-
- // spin-mutex lock
- while(runtime·xchg(&mp->waitsemalock, 1))
- runtime·osyield();
- mp->waitsemacount++;
- // TODO(jsing) - potential deadlock, see semasleep() for details.
- // Confirm that LWP is parked before unparking...
- ret = runtime·lwp_unpark(mp->procid, &mp->waitsemacount);
- if(ret != 0 && ret != ESRCH) {
- // semawakeup can be called on signal stack.
- // Save old ptrarg/scalararg so we can restore them.
- oldptr = g->m->ptrarg[0];
- oldscalar = g->m->scalararg[0];
- g->m->ptrarg[0] = mp;
- g->m->scalararg[0] = ret;
- fn = badsemawakeup;
- if(g == g->m->gsignal)
- fn();
- else
- runtime·onM(&fn);
- g->m->ptrarg[0] = oldptr;
- g->m->scalararg[0] = oldscalar;
- }
- // spin-mutex unlock
- runtime·atomicstore(&mp->waitsemalock, 0);
-}
-
-static void
-badsemawakeup(void)
-{
- M *mp;
- int32 ret;
-
- mp = g->m->ptrarg[0];
- g->m->ptrarg[0] = nil;
- ret = g->m->scalararg[0];
- g->m->scalararg[0] = 0;
-
- runtime·printf("thrwakeup addr=%p sem=%d ret=%d\n", &mp->waitsemacount, mp->waitsemacount, ret);
-}
-
-void
-runtime·newosproc(M *mp, void *stk)
-{
- UcontextT uc;
- int32 ret;
-
- if(0) {
- runtime·printf(
- "newosproc stk=%p m=%p g=%p id=%d/%d ostk=%p\n",
- stk, mp, mp->g0, mp->id, (int32)mp->tls[0], &mp);
- }
-
- mp->tls[0] = mp->id; // so 386 asm can find it
-
- runtime·getcontext(&uc);
-
- uc.uc_flags = _UC_SIGMASK | _UC_CPU;
- uc.uc_link = nil;
- uc.uc_sigmask = sigset_all;
-
- runtime·lwp_mcontext_init(&uc.uc_mcontext, stk, mp, mp->g0, runtime·mstart);
-
- ret = runtime·lwp_create(&uc, 0, &mp->procid);
-
- if(ret < 0) {
- runtime·printf("runtime: failed to create new OS thread (have %d already; errno=%d)\n", runtime·mcount() - 1, -ret);
- runtime·throw("runtime.newosproc");
- }
-}
-
-void
-runtime·osinit(void)
-{
- runtime·ncpu = getncpu();
-}
-
-#pragma textflag NOSPLIT
-void
-runtime·get_random_data(byte **rnd, int32 *rnd_len)
-{
- #pragma dataflag NOPTR
- static byte urandom_data[HashRandomBytes];
- int32 fd;
- fd = runtime·open("/dev/urandom", 0 /* O_RDONLY */, 0);
- if(runtime·read(fd, urandom_data, HashRandomBytes) == HashRandomBytes) {
- *rnd = urandom_data;
- *rnd_len = HashRandomBytes;
- } else {
- *rnd = nil;
- *rnd_len = 0;
- }
- runtime·close(fd);
-}
-
-void
-runtime·goenvs(void)
-{
- runtime·goenvs_unix();
-}
-
-// Called to initialize a new m (including the bootstrap m).
-// Called on the parent thread (main thread in case of bootstrap), can allocate memory.
-void
-runtime·mpreinit(M *mp)
-{
- mp->gsignal = runtime·malg(32*1024);
- runtime·writebarrierptr_nostore(&mp->gsignal, mp->gsignal);
-
- mp->gsignal->m = mp;
- runtime·writebarrierptr_nostore(&mp->gsignal->m, mp->gsignal->m);
-}
-
-// Called to initialize a new m (including the bootstrap m).
-// Called on the new thread, can not allocate memory.
-void
-runtime·minit(void)
-{
- g->m->procid = runtime·lwp_self();
-
- // Initialize signal handling
- runtime·signalstack((byte*)g->m->gsignal->stack.lo, 32*1024);
- runtime·sigprocmask(SIG_SETMASK, &sigset_none, nil);
-}
-
-// Called from dropm to undo the effect of an minit.
-void
-runtime·unminit(void)
-{
- runtime·signalstack(nil, 0);
-}
-
-uintptr
-runtime·memlimit(void)
-{
- return 0;
-}
-
-extern void runtime·sigtramp(void);
-
-typedef struct sigaction {
- union {
- void (*_sa_handler)(int32);
- void (*_sa_sigaction)(int32, Siginfo*, void *);
- } _sa_u; /* signal handler */
- uint32 sa_mask[4]; /* signal mask to apply */
- int32 sa_flags; /* see signal options below */
-} SigactionT;
-
-void
-runtime·setsig(int32 i, GoSighandler *fn, bool restart)
-{
- SigactionT sa;
-
- runtime·memclr((byte*)&sa, sizeof sa);
- sa.sa_flags = SA_SIGINFO|SA_ONSTACK;
- if(restart)
- sa.sa_flags |= SA_RESTART;
- sa.sa_mask[0] = ~0U;
- sa.sa_mask[1] = ~0U;
- sa.sa_mask[2] = ~0U;
- sa.sa_mask[3] = ~0U;
- if (fn == runtime·sighandler)
- fn = (void*)runtime·sigtramp;
- sa._sa_u._sa_sigaction = (void*)fn;
- runtime·sigaction(i, &sa, nil);
-}
-
-GoSighandler*
-runtime·getsig(int32 i)
-{
- SigactionT sa;
-
- runtime·memclr((byte*)&sa, sizeof sa);
- runtime·sigaction(i, nil, &sa);
- if((void*)sa._sa_u._sa_sigaction == runtime·sigtramp)
- return runtime·sighandler;
- return (void*)sa._sa_u._sa_sigaction;
-}
-
-void
-runtime·signalstack(byte *p, int32 n)
-{
- StackT st;
-
- st.ss_sp = (void*)p;
- st.ss_size = n;
- st.ss_flags = 0;
- if(p == nil)
- st.ss_flags = SS_DISABLE;
- runtime·sigaltstack(&st, nil);
-}
-
-void
-runtime·unblocksignals(void)
-{
- runtime·sigprocmask(SIG_SETMASK, &sigset_none, nil);
-}
-
-#pragma textflag NOSPLIT
-int8*
-runtime·signame(int32 sig)
-{
- return runtime·sigtab[sig].name;
-}
diff --git a/src/runtime/os_netbsd.go b/src/runtime/os_netbsd.go
index f000c5e9f..a153bf2eb 100644
--- a/src/runtime/os_netbsd.go
+++ b/src/runtime/os_netbsd.go
@@ -6,15 +6,37 @@ package runtime
import "unsafe"
-func setitimer(mode int32, new, old unsafe.Pointer)
-func sigaction(sig int32, new, old unsafe.Pointer)
-func sigaltstack(new, old unsafe.Pointer)
-func sigprocmask(mode int32, new, old unsafe.Pointer)
+//go:noescape
+func setitimer(mode int32, new, old *itimerval)
+
+//go:noescape
+func sigaction(sig int32, new, old *sigactiont)
+
+//go:noescape
+func sigaltstack(new, old *sigaltstackt)
+
+//go:noescape
+func sigprocmask(mode int32, new, old *sigset)
+
+//go:noescape
func sysctl(mib *uint32, miblen uint32, out *byte, size *uintptr, dst *byte, ndst uintptr) int32
+
func lwp_tramp()
+
func raise(sig int32)
+
+//go:noescape
func getcontext(ctxt unsafe.Pointer)
+
+//go:noescape
func lwp_create(ctxt unsafe.Pointer, flags uintptr, lwpid unsafe.Pointer) int32
-func lwp_park(abstime unsafe.Pointer, unpark int32, hint, unparkhint unsafe.Pointer) int32
+
+//go:noescape
+func lwp_park(abstime *timespec, unpark int32, hint, unparkhint unsafe.Pointer) int32
+
+//go:noescape
func lwp_unpark(lwp int32, hint unsafe.Pointer) int32
+
func lwp_self() int32
+
+func osyield()
diff --git a/src/runtime/os_netbsd.h b/src/runtime/os_netbsd.h
deleted file mode 100644
index f95db325f..000000000
--- a/src/runtime/os_netbsd.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// 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.
-
-
-typedef uintptr kevent_udata;
-
-struct sigaction;
-
-void runtime·sigpanic(void);
-
-void runtime·setitimer(int32, Itimerval*, Itimerval*);
-void runtime·sigaction(int32, struct sigaction*, struct sigaction*);
-void runtime·sigaltstack(SigaltstackT*, SigaltstackT*);
-void runtime·sigprocmask(int32, Sigset*, Sigset*);
-void runtime·unblocksignals(void);
-int32 runtime·sysctl(uint32*, uint32, byte*, uintptr*, byte*, uintptr);
-extern void runtime·lwp_tramp(void);
-
-enum {
- SS_DISABLE = 4,
- SIG_BLOCK = 1,
- SIG_UNBLOCK = 2,
- SIG_SETMASK = 3,
- NSIG = 33,
- SI_USER = 0,
-
- // From NetBSD's <sys/ucontext.h>
- _UC_SIGMASK = 0x01,
- _UC_CPU = 0x04,
-};
diff --git a/src/runtime/os_netbsd_386.c b/src/runtime/os_netbsd_386.c
deleted file mode 100644
index 23e9db3c1..000000000
--- a/src/runtime/os_netbsd_386.c
+++ /dev/null
@@ -1,17 +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.
-
-#include "runtime.h"
-#include "defs_GOOS_GOARCH.h"
-#include "os_GOOS.h"
-
-void
-runtime·lwp_mcontext_init(McontextT *mc, void *stack, M *mp, G *gp, void (*fn)(void))
-{
- mc->__gregs[REG_EIP] = (uint32)runtime·lwp_tramp;
- mc->__gregs[REG_UESP] = (uint32)stack;
- mc->__gregs[REG_EBX] = (uint32)mp;
- mc->__gregs[REG_EDX] = (uint32)gp;
- mc->__gregs[REG_ESI] = (uint32)fn;
-}
diff --git a/src/runtime/os_netbsd_amd64.c b/src/runtime/os_netbsd_amd64.c
deleted file mode 100644
index 226846cbb..000000000
--- a/src/runtime/os_netbsd_amd64.c
+++ /dev/null
@@ -1,18 +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.
-
-#include "runtime.h"
-#include "defs_GOOS_GOARCH.h"
-#include "os_GOOS.h"
-
-void
-runtime·lwp_mcontext_init(McontextT *mc, void *stack, M *mp, G *gp, void (*fn)(void))
-{
- // Machine dependent mcontext initialisation for LWP.
- mc->__gregs[REG_RIP] = (uint64)runtime·lwp_tramp;
- mc->__gregs[REG_RSP] = (uint64)stack;
- mc->__gregs[REG_R8] = (uint64)mp;
- mc->__gregs[REG_R9] = (uint64)gp;
- mc->__gregs[REG_R12] = (uint64)fn;
-}
diff --git a/src/runtime/os_plan9.c b/src/runtime/os_plan9.c
deleted file mode 100644
index 18460fc12..000000000
--- a/src/runtime/os_plan9.c
+++ /dev/null
@@ -1,368 +0,0 @@
-// 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.
-
-#include "runtime.h"
-#include "os_GOOS.h"
-#include "arch_GOARCH.h"
-#include "textflag.h"
-#include "malloc.h"
-
-int8 *goos = "plan9";
-extern SigTab runtime·sigtab[];
-
-int32 runtime·postnote(int32, int8*);
-
-// Called to initialize a new m (including the bootstrap m).
-// Called on the parent thread (main thread in case of bootstrap), can allocate memory.
-void
-runtime·mpreinit(M *mp)
-{
- // Initialize stack and goroutine for note handling.
- mp->gsignal = runtime·malg(32*1024);
- runtime·writebarrierptr_nostore(&mp->gsignal, mp->gsignal);
-
- mp->gsignal->m = mp;
- runtime·writebarrierptr_nostore(&mp->gsignal->m, mp->gsignal->m);
-
- mp->notesig = (int8*)runtime·mallocgc(ERRMAX*sizeof(int8), nil, FlagNoScan);
- runtime·writebarrierptr_nostore(&mp->notesig, mp->notesig);
-
- // Initialize stack for handling strings from the
- // errstr system call, as used in package syscall.
- mp->errstr = (byte*)runtime·mallocgc(ERRMAX*sizeof(byte), nil, FlagNoScan);
- runtime·writebarrierptr_nostore(&mp->errstr, mp->errstr);
-}
-
-// Called to initialize a new m (including the bootstrap m).
-// Called on the new thread, can not allocate memory.
-void
-runtime·minit(void)
-{
- // Mask all SSE floating-point exceptions
- // when running on the 64-bit kernel.
- runtime·setfpmasks();
-}
-
-// Called from dropm to undo the effect of an minit.
-void
-runtime·unminit(void)
-{
-}
-
-
-static int32
-getproccount(void)
-{
- int32 fd, i, n, ncpu;
- byte buf[2048];
-
- fd = runtime·open("/dev/sysstat", OREAD, 0);
- if(fd < 0)
- return 1;
- ncpu = 0;
- for(;;) {
- n = runtime·read(fd, buf, sizeof buf);
- if(n <= 0)
- break;
- for(i = 0; i < n; i++) {
- if(buf[i] == '\n')
- ncpu++;
- }
- }
- runtime·close(fd);
- return ncpu > 0 ? ncpu : 1;
-}
-
-static int32
-getpid(void)
-{
- byte b[20], *c;
- int32 fd;
-
- runtime·memclr(b, sizeof(b));
- fd = runtime·open("#c/pid", 0, 0);
- if(fd >= 0) {
- runtime·read(fd, b, sizeof(b));
- runtime·close(fd);
- }
- c = b;
- while(*c == ' ' || *c == '\t')
- c++;
- return runtime·atoi(c);
-}
-
-void
-runtime·osinit(void)
-{
- runtime·ncpu = getproccount();
- g->m->procid = getpid();
- runtime·notify(runtime·sigtramp);
-}
-
-void
-runtime·crash(void)
-{
- runtime·notify(nil);
- *(int32*)0 = 0;
-}
-
-#pragma textflag NOSPLIT
-void
-runtime·get_random_data(byte **rnd, int32 *rnd_len)
-{
- static byte random_data[HashRandomBytes];
- int32 fd;
-
- fd = runtime·open("/dev/random", 0 /* O_RDONLY */, 0);
- if(runtime·read(fd, random_data, HashRandomBytes) == HashRandomBytes) {
- *rnd = random_data;
- *rnd_len = HashRandomBytes;
- } else {
- *rnd = nil;
- *rnd_len = 0;
- }
- runtime·close(fd);
-}
-
-void
-runtime·goenvs(void)
-{
-}
-
-void
-runtime·initsig(void)
-{
-}
-
-#pragma textflag NOSPLIT
-void
-runtime·osyield(void)
-{
- runtime·sleep(0);
-}
-
-#pragma textflag NOSPLIT
-void
-runtime·usleep(uint32 µs)
-{
- uint32 ms;
-
- ms = µs/1000;
- if(ms == 0)
- ms = 1;
- runtime·sleep(ms);
-}
-
-#pragma textflag NOSPLIT
-int64
-runtime·nanotime(void)
-{
- int64 ns, scratch;
-
- ns = runtime·nsec(&scratch);
- // TODO(aram): remove hack after I fix _nsec in the pc64 kernel.
- if(ns == 0)
- return scratch;
- return ns;
-}
-
-#pragma textflag NOSPLIT
-void
-runtime·itoa(int32 n, byte *p, uint32 len)
-{
- byte *q, c;
- uint32 i;
-
- if(len <= 1)
- return;
-
- runtime·memclr(p, len);
- q = p;
-
- if(n==0) {
- *q++ = '0';
- USED(q);
- return;
- }
- if(n < 0) {
- *q++ = '-';
- p++;
- n = -n;
- }
- for(i=0; n > 0 && i < len; i++) {
- *q++ = '0' + (n%10);
- n = n/10;
- }
- for(q--; q >= p; ) {
- c = *p;
- *p++ = *q;
- *q-- = c;
- }
-}
-
-void
-runtime·goexitsall(int8 *status)
-{
- int8 buf[ERRMAX];
- M *mp;
- int32 pid;
-
- runtime·snprintf((byte*)buf, sizeof buf, "go: exit %s", status);
- pid = getpid();
- for(mp=runtime·atomicloadp(&runtime·allm); mp; mp=mp->alllink)
- if(mp->procid != pid)
- runtime·postnote(mp->procid, buf);
-}
-
-int32
-runtime·postnote(int32 pid, int8* msg)
-{
- int32 fd;
- intgo len;
- uint8 buf[128];
- uint8 tmp[16];
- uint8 *p, *q;
-
- runtime·memclr(buf, sizeof buf);
-
- /* build path string /proc/pid/note */
- q = tmp;
- p = buf;
- runtime·itoa(pid, tmp, sizeof tmp);
- runtime·memmove((void*)p, (void*)"/proc/", 6);
- for(p += 6; *p++ = *q++; );
- p--;
- runtime·memmove((void*)p, (void*)"/note", 5);
-
- fd = runtime·open((int8*)buf, OWRITE, 0);
- if(fd < 0)
- return -1;
-
- len = runtime·findnull((byte*)msg);
- if(runtime·write(fd, msg, len) != len) {
- runtime·close(fd);
- return -1;
- }
- runtime·close(fd);
- return 0;
-}
-
-static void exit(void);
-
-#pragma textflag NOSPLIT
-void
-runtime·exit(int32 e)
-{
- void (*fn)(void);
-
- g->m->scalararg[0] = e;
- fn = exit;
- runtime·onM(&fn);
-}
-
-static void
-exit(void)
-{
- int32 e;
- byte tmp[16];
- int8 *status;
-
- e = g->m->scalararg[0];
- g->m->scalararg[0] = 0;
-
- if(e == 0)
- status = "";
- else {
- /* build error string */
- runtime·itoa(e, tmp, sizeof tmp);
- status = (int8*)tmp;
- }
-
- runtime·goexitsall(status);
- runtime·exits(status);
-}
-
-void
-runtime·newosproc(M *mp, void *stk)
-{
- int32 pid;
-
- if(0)
- runtime·printf("newosproc mp=%p ostk=%p\n", mp, &mp);
-
- USED(stk);
- if((pid = runtime·rfork(RFPROC|RFMEM|RFNOWAIT)) < 0)
- runtime·throw("newosproc: rfork failed\n");
- if(pid == 0)
- runtime·tstart_plan9(mp);
-}
-
-#pragma textflag NOSPLIT
-uintptr
-runtime·semacreate(void)
-{
- return 1;
-}
-
-#pragma textflag NOSPLIT
-int32
-runtime·semasleep(int64 ns)
-{
- int32 ret;
- int32 ms;
-
- if(ns >= 0) {
- ms = runtime·timediv(ns, 1000000, nil);
- if(ms == 0)
- ms = 1;
- ret = runtime·plan9_tsemacquire(&g->m->waitsemacount, ms);
- if(ret == 1)
- return 0; // success
- return -1; // timeout or interrupted
- }
-
- while(runtime·plan9_semacquire(&g->m->waitsemacount, 1) < 0) {
- /* interrupted; try again (c.f. lock_sema.c) */
- }
- return 0; // success
-}
-
-#pragma textflag NOSPLIT
-void
-runtime·semawakeup(M *mp)
-{
- runtime·plan9_semrelease(&mp->waitsemacount, 1);
-}
-
-#pragma textflag NOSPLIT
-int32
-runtime·read(int32 fd, void *buf, int32 nbytes)
-{
- return runtime·pread(fd, buf, nbytes, -1LL);
-}
-
-#pragma textflag NOSPLIT
-int32
-runtime·write(uintptr fd, void *buf, int32 nbytes)
-{
- return runtime·pwrite((int32)fd, buf, nbytes, -1LL);
-}
-
-uintptr
-runtime·memlimit(void)
-{
- return 0;
-}
-
-#pragma dataflag NOPTR
-static int8 badsignal[] = "runtime: signal received on thread not created by Go.\n";
-
-// This runs on a foreign stack, without an m or a g. No stack split.
-#pragma textflag NOSPLIT
-void
-runtime·badsignal2(void)
-{
- runtime·pwrite(2, badsignal, sizeof badsignal - 1, -1LL);
- runtime·exits(badsignal);
-}
diff --git a/src/runtime/os_plan9.go b/src/runtime/os_plan9.go
index 20e47bf42..2dcdfc009 100644
--- a/src/runtime/os_plan9.go
+++ b/src/runtime/os_plan9.go
@@ -6,22 +6,49 @@ package runtime
import "unsafe"
+//go:noescape
func pread(fd int32, buf unsafe.Pointer, nbytes int32, offset int64) int32
+
+//go:noescape
func pwrite(fd int32, buf unsafe.Pointer, nbytes int32, offset int64) int32
+
func seek(fd int32, offset int64, whence int32) int64
+
+//go:noescape
func exits(msg *byte)
+
+//go:noescape
func brk_(addr unsafe.Pointer) uintptr
+
func sleep(ms int32) int32
+
func rfork(flags int32) int32
+
+//go:noescape
func plan9_semacquire(addr *uint32, block int32) int32
+
+//go:noescape
func plan9_tsemacquire(addr *uint32, ms int32) int32
+
+//go:noescape
func plan9_semrelease(addr *uint32, count int32) int32
+
+//go:noescape
func notify(fn unsafe.Pointer) int32
+
func noted(mode int32) int32
+
+//go:noescape
func nsec(*int64) int64
+
+//go:noescape
func sigtramp(ureg, msg unsafe.Pointer)
+
func setfpmasks()
+
+//go:noescape
func tstart_plan9(newm *m)
+
func errstr() string
type _Plink uintptr
diff --git a/src/runtime/os_plan9.h b/src/runtime/os_plan9.h
deleted file mode 100644
index 6d1802483..000000000
--- a/src/runtime/os_plan9.h
+++ /dev/null
@@ -1,93 +0,0 @@
-// 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.
-
-// Plan 9-specific system calls
-int32 runtime·pread(int32 fd, void *buf, int32 nbytes, int64 offset);
-int32 runtime·pwrite(int32 fd, void *buf, int32 nbytes, int64 offset);
-int64 runtime·seek(int32 fd, int64 offset, int32 whence);
-void runtime·exits(int8* msg);
-intptr runtime·brk_(void*);
-int32 runtime·sleep(int32 ms);
-int32 runtime·rfork(int32 flags);
-int32 runtime·plan9_semacquire(uint32 *addr, int32 block);
-int32 runtime·plan9_tsemacquire(uint32 *addr, int32 ms);
-int32 runtime·plan9_semrelease(uint32 *addr, int32 count);
-int32 runtime·notify(void (*fn)(void*, int8*));
-int32 runtime·noted(int32);
-int64 runtime·nsec(int64*);
-void runtime·sigtramp(void*, int8*);
-void runtime·sigpanic(void);
-void runtime·goexitsall(int8*);
-void runtime·setfpmasks(void);
-void runtime·tstart_plan9(M *newm);
-
-/* open */
-enum
-{
- OREAD = 0,
- OWRITE = 1,
- ORDWR = 2,
- OEXEC = 3,
- OTRUNC = 16,
- OCEXEC = 32,
- ORCLOSE = 64,
- OEXCL = 0x1000
-};
-
-/* rfork */
-enum
-{
- RFNAMEG = (1<<0),
- RFENVG = (1<<1),
- RFFDG = (1<<2),
- RFNOTEG = (1<<3),
- RFPROC = (1<<4),
- RFMEM = (1<<5),
- RFNOWAIT = (1<<6),
- RFCNAMEG = (1<<10),
- RFCENVG = (1<<11),
- RFCFDG = (1<<12),
- RFREND = (1<<13),
- RFNOMNT = (1<<14)
-};
-
-/* notify */
-enum
-{
- NCONT = 0,
- NDFLT = 1
-};
-
-typedef struct Tos Tos;
-typedef intptr _Plink;
-
-struct Tos {
- struct TosProf /* Per process profiling */
- {
- _Plink *pp; /* known to be 0(ptr) */
- _Plink *next; /* known to be 4(ptr) */
- _Plink *last;
- _Plink *first;
- uint32 pid;
- uint32 what;
- } prof;
- uint64 cyclefreq; /* cycle clock frequency if there is one, 0 otherwise */
- int64 kcycles; /* cycles spent in kernel */
- int64 pcycles; /* cycles spent in process (kernel + user) */
- uint32 pid; /* might as well put the pid here */
- uint32 clock;
- /* top of stack is here */
-};
-
-enum {
- NSIG = 14, /* number of signals in runtime·SigTab array */
- ERRMAX = 128, /* max length of note string */
-
- /* Notes in runtime·sigtab that are handled by runtime·sigpanic. */
- SIGRFAULT = 2,
- SIGWFAULT = 3,
- SIGINTDIV = 4,
- SIGFLOAT = 5,
- SIGTRAP = 6,
-};
diff --git a/src/runtime/os_plan9_386.c b/src/runtime/os_plan9_386.c
deleted file mode 100644
index 42c6d161c..000000000
--- a/src/runtime/os_plan9_386.c
+++ /dev/null
@@ -1,150 +0,0 @@
-// 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.
-
-#include "runtime.h"
-#include "defs_GOOS_GOARCH.h"
-#include "os_GOOS.h"
-#include "signals_GOOS.h"
-
-void
-runtime·dumpregs(Ureg *u)
-{
- runtime·printf("ax %x\n", u->ax);
- runtime·printf("bx %x\n", u->bx);
- runtime·printf("cx %x\n", u->cx);
- runtime·printf("dx %x\n", u->dx);
- runtime·printf("di %x\n", u->di);
- runtime·printf("si %x\n", u->si);
- runtime·printf("bp %x\n", u->bp);
- runtime·printf("sp %x\n", u->sp);
- runtime·printf("pc %x\n", u->pc);
- runtime·printf("flags %x\n", u->flags);
- runtime·printf("cs %x\n", u->cs);
- runtime·printf("fs %x\n", u->fs);
- runtime·printf("gs %x\n", u->gs);
-}
-
-int32
-runtime·sighandler(void *v, int8 *note, G *gp)
-{
- uintptr *sp;
- SigTab *t;
- bool crash;
- Ureg *ureg;
- intgo len, n;
- int32 sig, flags;
-
- ureg = (Ureg*)v;
-
- // The kernel will never pass us a nil note or ureg so we probably
- // made a mistake somewhere in runtime·sigtramp.
- if(ureg == nil || note == nil) {
- runtime·printf("sighandler: ureg %p note %p\n", ureg, note);
- goto Throw;
- }
-
- // Check that the note is no more than ERRMAX bytes (including
- // the trailing NUL). We should never receive a longer note.
- len = runtime·findnull((byte*)note);
- if(len > ERRMAX-1) {
- runtime·printf("sighandler: note is longer than ERRMAX\n");
- goto Throw;
- }
-
- // See if the note matches one of the patterns in runtime·sigtab.
- // Notes that do not match any pattern can be handled at a higher
- // level by the program but will otherwise be ignored.
- flags = SigNotify;
- for(sig = 0; sig < nelem(runtime·sigtab); sig++) {
- t = &runtime·sigtab[sig];
- n = runtime·findnull((byte*)t->name);
- if(len < n)
- continue;
- if(runtime·strncmp((byte*)note, (byte*)t->name, n) == 0) {
- flags = t->flags;
- break;
- }
- }
-
- if(flags & SigGoExit)
- runtime·exits(note+9); // Strip "go: exit " prefix.
-
- if(flags & SigPanic) {
- // Copy the error string from sigtramp's stack into m->notesig so
- // we can reliably access it from the panic routines.
- runtime·memmove(g->m->notesig, note, len+1);
-
- gp->sig = sig;
- gp->sigpc = ureg->pc;
-
- // Only push runtime·sigpanic if PC != 0.
- //
- // If PC == 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(ureg->pc != 0) {
- sp = (uintptr*)ureg->sp;
- *--sp = ureg->pc;
- ureg->sp = (uint32)sp;
- }
- ureg->pc = (uintptr)runtime·sigpanic;
- return NCONT;
- }
-
- if(flags & SigNotify) {
- // TODO(ality): See if os/signal wants it.
- //if(runtime·sigsend(...))
- // return NCONT;
- }
- if(flags & SigKill)
- goto Exit;
- if(!(flags & SigThrow))
- return NCONT;
-
-Throw:
- g->m->throwing = 1;
- g->m->caughtsig = gp;
- runtime·startpanic();
-
- runtime·printf("%s\n", note);
- runtime·printf("PC=%x\n", ureg->pc);
- runtime·printf("\n");
-
- if(runtime·gotraceback(&crash)) {
- runtime·goroutineheader(gp);
- runtime·tracebacktrap(ureg->pc, ureg->sp, 0, gp);
- runtime·tracebackothers(gp);
- runtime·printf("\n");
- runtime·dumpregs(ureg);
- }
-
- if(crash)
- runtime·crash();
-
-Exit:
- runtime·goexitsall(note);
- runtime·exits(note);
- return NDFLT; // not reached
-}
-
-void
-runtime·sigenable(uint32 sig)
-{
- USED(sig);
-}
-
-void
-runtime·sigdisable(uint32 sig)
-{
- USED(sig);
-}
-
-void
-runtime·resetcpuprofiler(int32 hz)
-{
- // TODO: Enable profiling interrupts.
-
- g->m->profilehz = hz;
-}
diff --git a/src/runtime/os_plan9_386.go b/src/runtime/os_plan9_386.go
new file mode 100644
index 000000000..7dda13931
--- /dev/null
+++ b/src/runtime/os_plan9_386.go
@@ -0,0 +1,131 @@
+// 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.
+
+package runtime
+
+import "unsafe"
+
+func dumpregs(u *ureg) {
+ print("ax ", hex(u.ax), "\n")
+ print("bx ", hex(u.bx), "\n")
+ print("cx ", hex(u.cx), "\n")
+ print("dx ", hex(u.dx), "\n")
+ print("di ", hex(u.di), "\n")
+ print("si ", hex(u.si), "\n")
+ print("bp ", hex(u.bp), "\n")
+ print("sp ", hex(u.sp), "\n")
+ print("pc ", hex(u.pc), "\n")
+ print("flags ", hex(u.flags), "\n")
+ print("cs ", hex(u.cs), "\n")
+ print("fs ", hex(u.fs), "\n")
+ print("gs ", hex(u.gs), "\n")
+}
+
+func sighandler(_ureg *ureg, note *byte, gp *g) int {
+ _g_ := getg()
+ var t sigTabT
+ var docrash bool
+ var length int
+ var sig int
+ var flags int
+
+ // The kernel will never pass us a nil note or ureg so we probably
+ // made a mistake somewhere in sigtramp.
+ if _ureg == nil || note == nil {
+ print("sighandler: ureg ", _ureg, " note ", note, "\n")
+ goto Throw
+ }
+ // Check that the note is no more than ERRMAX bytes (including
+ // the trailing NUL). We should never receive a longer note.
+ length = findnull(note)
+ if length > _ERRMAX-1 {
+ print("sighandler: note is longer than ERRMAX\n")
+ goto Throw
+ }
+ // See if the note matches one of the patterns in sigtab.
+ // Notes that do not match any pattern can be handled at a higher
+ // level by the program but will otherwise be ignored.
+ flags = _SigNotify
+ for sig, t = range sigtable {
+ n := len(t.name)
+ if length < n {
+ continue
+ }
+ if strncmp(note, &t.name[0], uintptr(n)) == 0 {
+ flags = t.flags
+ break
+ }
+ }
+ if flags&_SigGoExit != 0 {
+ exits((*byte)(add(unsafe.Pointer(note), 9))) // Strip "go: exit " prefix.
+ }
+ if flags&_SigPanic != 0 {
+ // Copy the error string from sigtramp's stack into m->notesig so
+ // we can reliably access it from the panic routines.
+ memmove(unsafe.Pointer(_g_.m.notesig), unsafe.Pointer(note), uintptr(length+1))
+ gp.sig = uint32(sig)
+ gp.sigpc = uintptr(_ureg.pc)
+ // Only push sigpanic if PC != 0.
+ //
+ // If PC == 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 sigpanic instead. (Otherwise the trace will end at
+ // sigpanic and we won't get to see who faulted).
+ if _ureg.pc != 0 {
+ sp := _ureg.sp
+ if regSize > ptrSize {
+ sp -= ptrSize
+ *(*uintptr)(unsafe.Pointer(uintptr(sp))) = 0
+ }
+ sp -= ptrSize
+ *(*uintptr)(unsafe.Pointer(uintptr(sp))) = uintptr(_ureg.pc)
+ _ureg.sp = sp
+ }
+ _ureg.pc = uint32(funcPC(sigpanic))
+ return _NCONT
+ }
+ if flags&_SigNotify != 0 {
+ // TODO(ality): See if os/signal wants it.
+ //if(sigsend(...))
+ // return _NCONT;
+ }
+ if flags&_SigKill != 0 {
+ goto Exit
+ }
+ if flags&_SigThrow == 0 {
+ return _NCONT
+ }
+Throw:
+ _g_.m.throwing = 1
+ _g_.m.caughtsig = gp
+ startpanic()
+ print(gostringnocopy(note), "\n")
+ print("PC=", hex(_ureg.pc), "\n")
+ print("\n")
+ if gotraceback(&docrash) > 0 {
+ goroutineheader(gp)
+ tracebacktrap(uintptr(_ureg.pc), uintptr(_ureg.sp), 0, gp)
+ tracebackothers(gp)
+ print("\n")
+ dumpregs(_ureg)
+ }
+ if docrash {
+ crash()
+ }
+Exit:
+ goexitsall(note)
+ exits(note)
+ return _NDFLT // not reached
+}
+
+func sigenable(sig uint32) {
+}
+
+func sigdisable(sig uint32) {
+}
+
+func resetcpuprofiler(hz int32) {
+ // TODO: Enable profiling interrupts.
+ getg().m.profilehz = hz
+}
diff --git a/src/runtime/os_plan9_amd64.c b/src/runtime/os_plan9_amd64.c
deleted file mode 100644
index a9dc0eb96..000000000
--- a/src/runtime/os_plan9_amd64.c
+++ /dev/null
@@ -1,158 +0,0 @@
-// 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.
-
-#include "runtime.h"
-#include "defs_GOOS_GOARCH.h"
-#include "os_GOOS.h"
-#include "signals_GOOS.h"
-
-void
-runtime·dumpregs(Ureg *u)
-{
- runtime·printf("ax %X\n", u->ax);
- runtime·printf("bx %X\n", u->bx);
- runtime·printf("cx %X\n", u->cx);
- runtime·printf("dx %X\n", u->dx);
- runtime·printf("di %X\n", u->di);
- runtime·printf("si %X\n", u->si);
- runtime·printf("bp %X\n", u->bp);
- runtime·printf("sp %X\n", u->sp);
- runtime·printf("r8 %X\n", u->r8);
- runtime·printf("r9 %X\n", u->r9);
- runtime·printf("r10 %X\n", u->r10);
- runtime·printf("r11 %X\n", u->r11);
- runtime·printf("r12 %X\n", u->r12);
- runtime·printf("r13 %X\n", u->r13);
- runtime·printf("r14 %X\n", u->r14);
- runtime·printf("r15 %X\n", u->r15);
- runtime·printf("ip %X\n", u->ip);
- runtime·printf("flags %X\n", u->flags);
- runtime·printf("cs %X\n", (uint64)u->cs);
- runtime·printf("fs %X\n", (uint64)u->fs);
- runtime·printf("gs %X\n", (uint64)u->gs);
-}
-
-int32
-runtime·sighandler(void *v, int8 *note, G *gp)
-{
- uintptr *sp;
- SigTab *t;
- bool crash;
- Ureg *ureg;
- intgo len, n;
- int32 sig, flags;
-
- ureg = (Ureg*)v;
-
- // The kernel will never pass us a nil note or ureg so we probably
- // made a mistake somewhere in runtime·sigtramp.
- if(ureg == nil || note == nil) {
- runtime·printf("sighandler: ureg %p note %p\n", ureg, note);
- goto Throw;
- }
-
- // Check that the note is no more than ERRMAX bytes (including
- // the trailing NUL). We should never receive a longer note.
- len = runtime·findnull((byte*)note);
- if(len > ERRMAX-1) {
- runtime·printf("sighandler: note is longer than ERRMAX\n");
- goto Throw;
- }
-
- // See if the note matches one of the patterns in runtime·sigtab.
- // Notes that do not match any pattern can be handled at a higher
- // level by the program but will otherwise be ignored.
- flags = SigNotify;
- for(sig = 0; sig < nelem(runtime·sigtab); sig++) {
- t = &runtime·sigtab[sig];
- n = runtime·findnull((byte*)t->name);
- if(len < n)
- continue;
- if(runtime·strncmp((byte*)note, (byte*)t->name, n) == 0) {
- flags = t->flags;
- break;
- }
- }
-
- if(flags & SigGoExit)
- runtime·exits(note+9); // Strip "go: exit " prefix.
-
- if(flags & SigPanic) {
- // Copy the error string from sigtramp's stack into m->notesig so
- // we can reliably access it from the panic routines.
- runtime·memmove(g->m->notesig, note, len+1);
-
- gp->sig = sig;
- gp->sigpc = ureg->ip;
-
- // Only push runtime·sigpanic if PC != 0.
- //
- // If PC == 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(ureg->ip != 0) {
- sp = (uintptr*)ureg->sp;
- *--sp = ureg->ip;
- ureg->sp = (uint64)sp;
- }
- ureg->ip = (uintptr)runtime·sigpanic;
- return NCONT;
- }
-
- if(flags & SigNotify) {
- // TODO(ality): See if os/signal wants it.
- //if(runtime·sigsend(...))
- // return NCONT;
- }
- if(flags & SigKill)
- goto Exit;
- if(!(flags & SigThrow))
- return NCONT;
-
-Throw:
- g->m->throwing = 1;
- g->m->caughtsig = gp;
- runtime·startpanic();
-
- runtime·printf("%s\n", note);
- runtime·printf("PC=%X\n", ureg->ip);
- runtime·printf("\n");
-
- if(runtime·gotraceback(&crash)) {
- runtime·goroutineheader(gp);
- runtime·tracebacktrap(ureg->ip, ureg->sp, 0, gp);
- runtime·tracebackothers(gp);
- runtime·printf("\n");
- runtime·dumpregs(ureg);
- }
-
- if(crash)
- runtime·crash();
-
-Exit:
- runtime·goexitsall(note);
- runtime·exits(note);
- return NDFLT; // not reached
-}
-
-void
-runtime·sigenable(uint32 sig)
-{
- USED(sig);
-}
-
-void
-runtime·sigdisable(uint32 sig)
-{
- USED(sig);
-}
-
-void
-runtime·resetcpuprofiler(int32 hz)
-{
- // TODO: Enable profiling interrupts.
-
- g->m->profilehz = hz;
-}
diff --git a/src/runtime/os_plan9_amd64.go b/src/runtime/os_plan9_amd64.go
new file mode 100644
index 000000000..8727dcc20
--- /dev/null
+++ b/src/runtime/os_plan9_amd64.go
@@ -0,0 +1,139 @@
+// 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.
+
+package runtime
+
+import "unsafe"
+
+func dumpregs(u *ureg) {
+ print("ax ", hex(u.ax), "\n")
+ print("bx ", hex(u.bx), "\n")
+ print("cx ", hex(u.cx), "\n")
+ print("dx ", hex(u.dx), "\n")
+ print("di ", hex(u.di), "\n")
+ print("si ", hex(u.si), "\n")
+ print("bp ", hex(u.bp), "\n")
+ print("sp ", hex(u.sp), "\n")
+ print("r8 ", hex(u.r8), "\n")
+ print("r9 ", hex(u.r9), "\n")
+ print("r10 ", hex(u.r10), "\n")
+ print("r11 ", hex(u.r11), "\n")
+ print("r12 ", hex(u.r12), "\n")
+ print("r13 ", hex(u.r13), "\n")
+ print("r14 ", hex(u.r14), "\n")
+ print("r15 ", hex(u.r15), "\n")
+ print("ip ", hex(u.ip), "\n")
+ print("flags ", hex(u.flags), "\n")
+ print("cs ", hex(uint64(u.cs)), "\n")
+ print("fs ", hex(uint64(u.fs)), "\n")
+ print("gs ", hex(uint64(u.gs)), "\n")
+}
+
+func sighandler(_ureg *ureg, note *byte, gp *g) int {
+ _g_ := getg()
+ var t sigTabT
+ var docrash bool
+ var length int
+ var sig int
+ var flags int
+
+ // The kernel will never pass us a nil note or ureg so we probably
+ // made a mistake somewhere in sigtramp.
+ if _ureg == nil || note == nil {
+ print("sighandler: ureg ", _ureg, " note ", note, "\n")
+ goto Throw
+ }
+ // Check that the note is no more than ERRMAX bytes (including
+ // the trailing NUL). We should never receive a longer note.
+ length = findnull(note)
+ if length > _ERRMAX-1 {
+ print("sighandler: note is longer than ERRMAX\n")
+ goto Throw
+ }
+ // See if the note matches one of the patterns in sigtab.
+ // Notes that do not match any pattern can be handled at a higher
+ // level by the program but will otherwise be ignored.
+ flags = _SigNotify
+ for sig, t = range sigtable {
+ n := len(t.name)
+ if length < n {
+ continue
+ }
+ if strncmp(note, &t.name[0], uintptr(n)) == 0 {
+ flags = t.flags
+ break
+ }
+ }
+ if flags&_SigGoExit != 0 {
+ exits((*byte)(add(unsafe.Pointer(note), 9))) // Strip "go: exit " prefix.
+ }
+ if flags&_SigPanic != 0 {
+ // Copy the error string from sigtramp's stack into m->notesig so
+ // we can reliably access it from the panic routines.
+ memmove(unsafe.Pointer(_g_.m.notesig), unsafe.Pointer(note), uintptr(length+1))
+ gp.sig = uint32(sig)
+ gp.sigpc = uintptr(_ureg.ip)
+ // Only push sigpanic if PC != 0.
+ //
+ // If PC == 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 sigpanic instead. (Otherwise the trace will end at
+ // sigpanic and we won't get to see who faulted).
+ if _ureg.ip != 0 {
+ sp := _ureg.sp
+ if regSize > ptrSize {
+ sp -= ptrSize
+ *(*uintptr)(unsafe.Pointer(uintptr(sp))) = 0
+ }
+ sp -= ptrSize
+ *(*uintptr)(unsafe.Pointer(uintptr(sp))) = uintptr(_ureg.ip)
+ _ureg.sp = sp
+ }
+ _ureg.ip = uint64(funcPC(sigpanic))
+ return _NCONT
+ }
+ if flags&_SigNotify != 0 {
+ // TODO(ality): See if os/signal wants it.
+ //if(sigsend(...))
+ // return _NCONT;
+ }
+ if flags&_SigKill != 0 {
+ goto Exit
+ }
+ if flags&_SigThrow == 0 {
+ return _NCONT
+ }
+Throw:
+ _g_.m.throwing = 1
+ _g_.m.caughtsig = gp
+ startpanic()
+ print(gostringnocopy(note), "\n")
+ print("PC=", hex(_ureg.ip), "\n")
+ print("\n")
+ if gotraceback(&docrash) > 0 {
+ goroutineheader(gp)
+ tracebacktrap(uintptr(_ureg.ip), uintptr(_ureg.sp), 0, gp)
+ tracebackothers(gp)
+ print("\n")
+ dumpregs(_ureg)
+ }
+ if docrash {
+ crash()
+ }
+Exit:
+ goexitsall(note)
+ exits(note)
+ return _NDFLT // not reached
+}
+
+func sigenable(sig uint32) {
+}
+
+func sigdisable(sig uint32) {
+}
+
+func resetcpuprofiler(hz int32) {
+ // TODO: Enable profiling interrupts.
+ getg().m.profilehz = hz
+}
diff --git a/src/runtime/os_windows.c b/src/runtime/os_windows.c
deleted file mode 100644
index b8b8eda5f..000000000
--- a/src/runtime/os_windows.c
+++ /dev/null
@@ -1,636 +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.
-
-#include "runtime.h"
-#include "type.h"
-#include "defs_GOOS_GOARCH.h"
-#include "os_GOOS.h"
-#include "textflag.h"
-#include "arch_GOARCH.h"
-#include "malloc.h"
-
-#pragma dynimport runtime·AddVectoredExceptionHandler AddVectoredExceptionHandler "kernel32.dll"
-#pragma dynimport runtime·CloseHandle CloseHandle "kernel32.dll"
-#pragma dynimport runtime·CreateEvent CreateEventA "kernel32.dll"
-#pragma dynimport runtime·CreateThread CreateThread "kernel32.dll"
-#pragma dynimport runtime·CreateWaitableTimer CreateWaitableTimerA "kernel32.dll"
-#pragma dynimport runtime·CryptAcquireContextW CryptAcquireContextW "advapi32.dll"
-#pragma dynimport runtime·CryptGenRandom CryptGenRandom "advapi32.dll"
-#pragma dynimport runtime·CryptReleaseContext CryptReleaseContext "advapi32.dll"
-#pragma dynimport runtime·DuplicateHandle DuplicateHandle "kernel32.dll"
-#pragma dynimport runtime·ExitProcess ExitProcess "kernel32.dll"
-#pragma dynimport runtime·FreeEnvironmentStringsW FreeEnvironmentStringsW "kernel32.dll"
-#pragma dynimport runtime·GetEnvironmentStringsW GetEnvironmentStringsW "kernel32.dll"
-#pragma dynimport runtime·GetProcAddress GetProcAddress "kernel32.dll"
-#pragma dynimport runtime·GetStdHandle GetStdHandle "kernel32.dll"
-#pragma dynimport runtime·GetSystemInfo GetSystemInfo "kernel32.dll"
-#pragma dynimport runtime·GetThreadContext GetThreadContext "kernel32.dll"
-#pragma dynimport runtime·LoadLibrary LoadLibraryW "kernel32.dll"
-#pragma dynimport runtime·LoadLibraryA LoadLibraryA "kernel32.dll"
-#pragma dynimport runtime·NtWaitForSingleObject NtWaitForSingleObject "ntdll.dll"
-#pragma dynimport runtime·ResumeThread ResumeThread "kernel32.dll"
-#pragma dynimport runtime·SetConsoleCtrlHandler SetConsoleCtrlHandler "kernel32.dll"
-#pragma dynimport runtime·SetEvent SetEvent "kernel32.dll"
-#pragma dynimport runtime·SetProcessPriorityBoost SetProcessPriorityBoost "kernel32.dll"
-#pragma dynimport runtime·SetThreadPriority SetThreadPriority "kernel32.dll"
-#pragma dynimport runtime·SetUnhandledExceptionFilter SetUnhandledExceptionFilter "kernel32.dll"
-#pragma dynimport runtime·SetWaitableTimer SetWaitableTimer "kernel32.dll"
-#pragma dynimport runtime·Sleep Sleep "kernel32.dll"
-#pragma dynimport runtime·SuspendThread SuspendThread "kernel32.dll"
-#pragma dynimport runtime·WaitForSingleObject WaitForSingleObject "kernel32.dll"
-#pragma dynimport runtime·WriteFile WriteFile "kernel32.dll"
-#pragma dynimport runtime·timeBeginPeriod timeBeginPeriod "winmm.dll"
-
-extern void *runtime·AddVectoredExceptionHandler;
-extern void *runtime·CloseHandle;
-extern void *runtime·CreateEvent;
-extern void *runtime·CreateThread;
-extern void *runtime·CreateWaitableTimer;
-extern void *runtime·CryptAcquireContextW;
-extern void *runtime·CryptGenRandom;
-extern void *runtime·CryptReleaseContext;
-extern void *runtime·DuplicateHandle;
-extern void *runtime·ExitProcess;
-extern void *runtime·FreeEnvironmentStringsW;
-extern void *runtime·GetEnvironmentStringsW;
-extern void *runtime·GetProcAddress;
-extern void *runtime·GetStdHandle;
-extern void *runtime·GetSystemInfo;
-extern void *runtime·GetThreadContext;
-extern void *runtime·LoadLibrary;
-extern void *runtime·LoadLibraryA;
-extern void *runtime·NtWaitForSingleObject;
-extern void *runtime·ResumeThread;
-extern void *runtime·SetConsoleCtrlHandler;
-extern void *runtime·SetEvent;
-extern void *runtime·SetProcessPriorityBoost;
-extern void *runtime·SetThreadPriority;
-extern void *runtime·SetUnhandledExceptionFilter;
-extern void *runtime·SetWaitableTimer;
-extern void *runtime·Sleep;
-extern void *runtime·SuspendThread;
-extern void *runtime·WaitForSingleObject;
-extern void *runtime·WriteFile;
-extern void *runtime·timeBeginPeriod;
-
-#pragma dataflag NOPTR
-void *runtime·GetQueuedCompletionStatusEx;
-
-extern uintptr runtime·externalthreadhandlerp;
-void runtime·externalthreadhandler(void);
-void runtime·exceptiontramp(void);
-void runtime·firstcontinuetramp(void);
-void runtime·lastcontinuetramp(void);
-
-#pragma textflag NOSPLIT
-uintptr
-runtime·getLoadLibrary(void)
-{
- return (uintptr)runtime·LoadLibrary;
-}
-
-#pragma textflag NOSPLIT
-uintptr
-runtime·getGetProcAddress(void)
-{
- return (uintptr)runtime·GetProcAddress;
-}
-
-static int32
-getproccount(void)
-{
- SystemInfo info;
-
- runtime·stdcall1(runtime·GetSystemInfo, (uintptr)&info);
- return info.dwNumberOfProcessors;
-}
-
-void
-runtime·osinit(void)
-{
- void *kernel32;
- void *addVectoredContinueHandler;
-
- kernel32 = runtime·stdcall1(runtime·LoadLibraryA, (uintptr)"kernel32.dll");
-
- runtime·externalthreadhandlerp = (uintptr)runtime·externalthreadhandler;
-
- runtime·stdcall2(runtime·AddVectoredExceptionHandler, 1, (uintptr)runtime·exceptiontramp);
- addVectoredContinueHandler = nil;
- if(kernel32 != nil)
- addVectoredContinueHandler = runtime·stdcall2(runtime·GetProcAddress, (uintptr)kernel32, (uintptr)"AddVectoredContinueHandler");
- if(addVectoredContinueHandler == nil || sizeof(void*) == 4) {
- // use SetUnhandledExceptionFilter for windows-386 or
- // if VectoredContinueHandler is unavailable.
- // note: SetUnhandledExceptionFilter handler won't be called, if debugging.
- runtime·stdcall1(runtime·SetUnhandledExceptionFilter, (uintptr)runtime·lastcontinuetramp);
- } else {
- runtime·stdcall2(addVectoredContinueHandler, 1, (uintptr)runtime·firstcontinuetramp);
- runtime·stdcall2(addVectoredContinueHandler, 0, (uintptr)runtime·lastcontinuetramp);
- }
-
- runtime·stdcall2(runtime·SetConsoleCtrlHandler, (uintptr)runtime·ctrlhandler, 1);
-
- runtime·stdcall1(runtime·timeBeginPeriod, 1);
-
- runtime·ncpu = getproccount();
-
- // Windows dynamic priority boosting assumes that a process has different types
- // 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.
- runtime·stdcall2(runtime·SetProcessPriorityBoost, -1, 1);
-
- if(kernel32 != nil) {
- runtime·GetQueuedCompletionStatusEx = runtime·stdcall2(runtime·GetProcAddress, (uintptr)kernel32, (uintptr)"GetQueuedCompletionStatusEx");
- }
-}
-
-#pragma textflag NOSPLIT
-void
-runtime·get_random_data(byte **rnd, int32 *rnd_len)
-{
- uintptr handle;
- *rnd = nil;
- *rnd_len = 0;
- if(runtime·stdcall5(runtime·CryptAcquireContextW, (uintptr)&handle, (uintptr)nil, (uintptr)nil,
- 1 /* PROV_RSA_FULL */,
- 0xf0000000U /* CRYPT_VERIFYCONTEXT */) != 0) {
- static byte random_data[HashRandomBytes];
- if(runtime·stdcall3(runtime·CryptGenRandom, handle, HashRandomBytes, (uintptr)&random_data[0])) {
- *rnd = random_data;
- *rnd_len = HashRandomBytes;
- }
- runtime·stdcall2(runtime·CryptReleaseContext, handle, 0);
- }
-}
-
-void
-runtime·goenvs(void)
-{
- extern Slice runtime·envs;
-
- uint16 *env;
- String *s;
- int32 i, n;
- uint16 *p;
-
- env = runtime·stdcall0(runtime·GetEnvironmentStringsW);
-
- n = 0;
- for(p=env; *p; n++)
- p += runtime·findnullw(p)+1;
-
- runtime·envs = runtime·makeStringSlice(n);
- s = (String*)runtime·envs.array;
-
- p = env;
- for(i=0; i<n; i++) {
- s[i] = runtime·gostringw(p);
- p += runtime·findnullw(p)+1;
- }
-
- runtime·stdcall1(runtime·FreeEnvironmentStringsW, (uintptr)env);
-}
-
-#pragma textflag NOSPLIT
-void
-runtime·exit(int32 code)
-{
- runtime·stdcall1(runtime·ExitProcess, code);
-}
-
-#pragma textflag NOSPLIT
-int32
-runtime·write(uintptr fd, void *buf, int32 n)
-{
- void *handle;
- uint32 written;
-
- written = 0;
- switch(fd) {
- case 1:
- handle = runtime·stdcall1(runtime·GetStdHandle, -11);
- break;
- case 2:
- handle = runtime·stdcall1(runtime·GetStdHandle, -12);
- break;
- default:
- // assume fd is real windows handle.
- handle = (void*)fd;
- break;
- }
- runtime·stdcall5(runtime·WriteFile, (uintptr)handle, (uintptr)buf, n, (uintptr)&written, 0);
- return written;
-}
-
-#define INFINITE ((uintptr)0xFFFFFFFF)
-
-#pragma textflag NOSPLIT
-int32
-runtime·semasleep(int64 ns)
-{
- // store ms in ns to save stack space
- if(ns < 0)
- ns = INFINITE;
- else {
- ns = runtime·timediv(ns, 1000000, nil);
- if(ns == 0)
- ns = 1;
- }
- if(runtime·stdcall2(runtime·WaitForSingleObject, (uintptr)g->m->waitsema, ns) != 0)
- return -1; // timeout
- return 0;
-}
-
-#pragma textflag NOSPLIT
-void
-runtime·semawakeup(M *mp)
-{
- runtime·stdcall1(runtime·SetEvent, mp->waitsema);
-}
-
-#pragma textflag NOSPLIT
-uintptr
-runtime·semacreate(void)
-{
- return (uintptr)runtime·stdcall4(runtime·CreateEvent, 0, 0, 0, 0);
-}
-
-#define STACK_SIZE_PARAM_IS_A_RESERVATION ((uintptr)0x00010000)
-
-void
-runtime·newosproc(M *mp, void *stk)
-{
- void *thandle;
-
- USED(stk);
-
- thandle = runtime·stdcall6(runtime·CreateThread,
- (uintptr)nil, 0x20000, (uintptr)runtime·tstart_stdcall, (uintptr)mp,
- STACK_SIZE_PARAM_IS_A_RESERVATION, (uintptr)nil);
- if(thandle == nil) {
- runtime·printf("runtime: failed to create new OS thread (have %d already; errno=%d)\n", runtime·mcount(), runtime·getlasterror());
- runtime·throw("runtime.newosproc");
- }
-}
-
-// Called to initialize a new m (including the bootstrap m).
-// Called on the parent thread (main thread in case of bootstrap), can allocate memory.
-void
-runtime·mpreinit(M *mp)
-{
- USED(mp);
-}
-
-// Called to initialize a new m (including the bootstrap m).
-// Called on the new thread, can not allocate memory.
-void
-runtime·minit(void)
-{
- uintptr thandle;
-
- // -1 = current process, -2 = current thread
- runtime·stdcall7(runtime·DuplicateHandle, -1, -2, -1, (uintptr)&thandle, 0, 0, DUPLICATE_SAME_ACCESS);
- runtime·atomicstoreuintptr(&g->m->thread, thandle);
-}
-
-// Called from dropm to undo the effect of an minit.
-void
-runtime·unminit(void)
-{
- runtime·stdcall1(runtime·CloseHandle, g->m->thread);
- g->m->thread = 0;
-}
-
-// Described in http://www.dcl.hpi.uni-potsdam.de/research/WRK/2007/08/getting-os-information-the-kuser_shared_data-structure/
-typedef struct KSYSTEM_TIME {
- uint32 LowPart;
- int32 High1Time;
- int32 High2Time;
-} KSYSTEM_TIME;
-
-#pragma dataflag NOPTR
-const KSYSTEM_TIME* INTERRUPT_TIME = (KSYSTEM_TIME*)0x7ffe0008;
-#pragma dataflag NOPTR
-const KSYSTEM_TIME* SYSTEM_TIME = (KSYSTEM_TIME*)0x7ffe0014;
-
-static void badsystime(void);
-
-#pragma textflag NOSPLIT
-int64
-runtime·systime(KSYSTEM_TIME *timeaddr)
-{
- KSYSTEM_TIME t;
- int32 i;
- void (*fn)(void);
-
- for(i = 1; i < 10000; i++) {
- // these fields must be read in that order (see URL above)
- t.High1Time = timeaddr->High1Time;
- t.LowPart = timeaddr->LowPart;
- t.High2Time = timeaddr->High2Time;
- if(t.High1Time == t.High2Time)
- return (int64)t.High1Time<<32 | t.LowPart;
- if((i%100) == 0)
- runtime·osyield();
- }
- fn = badsystime;
- runtime·onM(&fn);
- return 0;
-}
-
-#pragma textflag NOSPLIT
-int64
-runtime·unixnano(void)
-{
- return (runtime·systime(SYSTEM_TIME) - 116444736000000000LL) * 100LL;
-}
-
-static void
-badsystime(void)
-{
- runtime·throw("interrupt/system time is changing too fast");
-}
-
-#pragma textflag NOSPLIT
-int64
-runtime·nanotime(void)
-{
- return runtime·systime(INTERRUPT_TIME) * 100LL;
-}
-
-// Calling stdcall on os stack.
-#pragma textflag NOSPLIT
-static void*
-stdcall(void *fn)
-{
- g->m->libcall.fn = (uintptr)fn;
- if(g->m->profilehz != 0) {
- // leave pc/sp for cpu profiler
- g->m->libcallg = g;
- g->m->libcallpc = (uintptr)runtime·getcallerpc(&fn);
- // sp must be the last, because once async cpu profiler finds
- // all three values to be non-zero, it will use them
- g->m->libcallsp = (uintptr)runtime·getcallersp(&fn);
- }
- runtime·asmcgocall(runtime·asmstdcall, &g->m->libcall);
- g->m->libcallsp = 0;
- return (void*)g->m->libcall.r1;
-}
-
-#pragma textflag NOSPLIT
-void*
-runtime·stdcall0(void *fn)
-{
- g->m->libcall.n = 0;
- g->m->libcall.args = (uintptr)&fn; // it's unused but must be non-nil, otherwise crashes
- return stdcall(fn);
-}
-
-#pragma textflag NOSPLIT
-void*
-runtime·stdcall1(void *fn, uintptr a0)
-{
- USED(a0);
- g->m->libcall.n = 1;
- g->m->libcall.args = (uintptr)&a0;
- return stdcall(fn);
-}
-
-#pragma textflag NOSPLIT
-void*
-runtime·stdcall2(void *fn, uintptr a0, uintptr a1)
-{
- USED(a0, a1);
- g->m->libcall.n = 2;
- g->m->libcall.args = (uintptr)&a0;
- return stdcall(fn);
-}
-
-#pragma textflag NOSPLIT
-void*
-runtime·stdcall3(void *fn, uintptr a0, uintptr a1, uintptr a2)
-{
- USED(a0, a1, a2);
- g->m->libcall.n = 3;
- g->m->libcall.args = (uintptr)&a0;
- return stdcall(fn);
-}
-
-#pragma textflag NOSPLIT
-void*
-runtime·stdcall4(void *fn, uintptr a0, uintptr a1, uintptr a2, uintptr a3)
-{
- USED(a0, a1, a2, a3);
- g->m->libcall.n = 4;
- g->m->libcall.args = (uintptr)&a0;
- return stdcall(fn);
-}
-
-#pragma textflag NOSPLIT
-void*
-runtime·stdcall5(void *fn, uintptr a0, uintptr a1, uintptr a2, uintptr a3, uintptr a4)
-{
- USED(a0, a1, a2, a3, a4);
- g->m->libcall.n = 5;
- g->m->libcall.args = (uintptr)&a0;
- return stdcall(fn);
-}
-
-#pragma textflag NOSPLIT
-void*
-runtime·stdcall6(void *fn, uintptr a0, uintptr a1, uintptr a2, uintptr a3, uintptr a4, uintptr a5)
-{
- USED(a0, a1, a2, a3, a4, a5);
- g->m->libcall.n = 6;
- g->m->libcall.args = (uintptr)&a0;
- return stdcall(fn);
-}
-
-#pragma textflag NOSPLIT
-void*
-runtime·stdcall7(void *fn, uintptr a0, uintptr a1, uintptr a2, uintptr a3, uintptr a4, uintptr a5, uintptr a6)
-{
- USED(a0, a1, a2, a3, a4, a5, a6);
- g->m->libcall.n = 7;
- g->m->libcall.args = (uintptr)&a0;
- return stdcall(fn);
-}
-
-extern void runtime·usleep1(uint32);
-
-#pragma textflag NOSPLIT
-void
-runtime·osyield(void)
-{
- runtime·usleep1(1);
-}
-
-#pragma textflag NOSPLIT
-void
-runtime·usleep(uint32 us)
-{
- // Have 1us units; want 100ns units.
- runtime·usleep1(10*us);
-}
-
-uint32
-runtime·issigpanic(uint32 code)
-{
- switch(code) {
- case EXCEPTION_ACCESS_VIOLATION:
- 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:
- return 1;
- }
- return 0;
-}
-
-void
-runtime·initsig(void)
-{
- // following line keeps these functions alive at link stage
- // if there's a better way please write it here
- void *e = runtime·exceptiontramp;
- void *f = runtime·firstcontinuetramp;
- void *l = runtime·lastcontinuetramp;
- USED(e);
- USED(f);
- USED(l);
-}
-
-uint32
-runtime·ctrlhandler1(uint32 type)
-{
- int32 s;
-
- switch(type) {
- case CTRL_C_EVENT:
- case CTRL_BREAK_EVENT:
- s = SIGINT;
- break;
- default:
- return 0;
- }
-
- if(runtime·sigsend(s))
- return 1;
- runtime·exit(2); // SIGINT, SIGTERM, etc
- return 0;
-}
-
-extern void runtime·dosigprof(Context *r, G *gp, M *mp);
-extern void runtime·profileloop(void);
-#pragma dataflag NOPTR
-static void *profiletimer;
-
-static void
-profilem(M *mp)
-{
- extern M runtime·m0;
- extern uint32 runtime·tls0[];
- byte rbuf[sizeof(Context)+15];
- Context *r;
- void *tls;
- G *gp;
-
- tls = mp->tls;
- if(mp == &runtime·m0)
- tls = runtime·tls0;
- gp = *(G**)tls;
-
- // align Context to 16 bytes
- r = (Context*)((uintptr)(&rbuf[15]) & ~15);
- r->ContextFlags = CONTEXT_CONTROL;
- runtime·stdcall2(runtime·GetThreadContext, (uintptr)mp->thread, (uintptr)r);
- runtime·dosigprof(r, gp, mp);
-}
-
-void
-runtime·profileloop1(void)
-{
- M *mp, *allm;
- uintptr thread;
-
- runtime·stdcall2(runtime·SetThreadPriority, -2, THREAD_PRIORITY_HIGHEST);
-
- for(;;) {
- runtime·stdcall2(runtime·WaitForSingleObject, (uintptr)profiletimer, -1);
- allm = runtime·atomicloadp(&runtime·allm);
- for(mp = allm; mp != nil; mp = mp->alllink) {
- thread = runtime·atomicloaduintptr(&mp->thread);
- // Do not profile threads blocked on Notes,
- // this includes idle worker threads,
- // idle timer thread, idle heap scavenger, etc.
- if(thread == 0 || mp->profilehz == 0 || mp->blocked)
- continue;
- runtime·stdcall1(runtime·SuspendThread, (uintptr)thread);
- if(mp->profilehz != 0 && !mp->blocked)
- profilem(mp);
- runtime·stdcall1(runtime·ResumeThread, (uintptr)thread);
- }
- }
-}
-
-void
-runtime·resetcpuprofiler(int32 hz)
-{
- static Mutex lock;
- void *timer, *thread;
- int32 ms;
- int64 due;
-
- runtime·lock(&lock);
- if(profiletimer == nil) {
- timer = runtime·stdcall3(runtime·CreateWaitableTimer, (uintptr)nil, (uintptr)nil, (uintptr)nil);
- runtime·atomicstorep(&profiletimer, timer);
- thread = runtime·stdcall6(runtime·CreateThread,
- (uintptr)nil, (uintptr)nil, (uintptr)runtime·profileloop, (uintptr)nil, (uintptr)nil, (uintptr)nil);
- runtime·stdcall2(runtime·SetThreadPriority, (uintptr)thread, THREAD_PRIORITY_HIGHEST);
- runtime·stdcall1(runtime·CloseHandle, (uintptr)thread);
- }
- runtime·unlock(&lock);
-
- ms = 0;
- due = 1LL<<63;
- if(hz > 0) {
- ms = 1000 / hz;
- if(ms == 0)
- ms = 1;
- due = ms * -10000;
- }
- runtime·stdcall6(runtime·SetWaitableTimer,
- (uintptr)profiletimer, (uintptr)&due, ms, (uintptr)nil, (uintptr)nil, (uintptr)nil);
- runtime·atomicstore((uint32*)&g->m->profilehz, hz);
-}
-
-uintptr
-runtime·memlimit(void)
-{
- return 0;
-}
-
-#pragma dataflag NOPTR
-int8 runtime·badsignalmsg[] = "runtime: signal received on thread not created by Go.\n";
-int32 runtime·badsignallen = sizeof runtime·badsignalmsg - 1;
-
-void
-runtime·crash(void)
-{
- // TODO: This routine should do whatever is needed
- // to make the Windows program abort/crash as it
- // would if Go was not intercepting signals.
- // On Unix the routine would remove the custom signal
- // handler and then raise a signal (like SIGABRT).
- // Something like that should happen here.
- // It's okay to leave this empty for now: if crash returns
- // the ordinary exit-after-panic happens.
-}
diff --git a/src/runtime/os_windows.go b/src/runtime/os_windows.go
index fcd8f44cc..097b5d629 100644
--- a/src/runtime/os_windows.go
+++ b/src/runtime/os_windows.go
@@ -4,24 +4,8 @@
package runtime
-import "unsafe"
-
type stdFunction *byte
-func stdcall0(fn stdFunction) uintptr
-func stdcall1(fn stdFunction, a0 uintptr) uintptr
-func stdcall2(fn stdFunction, a0, a1 uintptr) uintptr
-func stdcall3(fn stdFunction, a0, a1, a2 uintptr) uintptr
-func stdcall4(fn stdFunction, a0, a1, a2, a3 uintptr) uintptr
-func stdcall5(fn stdFunction, a0, a1, a2, a3, a4 uintptr) uintptr
-func stdcall6(fn stdFunction, a0, a1, a2, a3, a4, a5 uintptr) uintptr
-func stdcall7(fn stdFunction, a0, a1, a2, a3, a4, a5, a6 uintptr) uintptr
-
-func asmstdcall(fn unsafe.Pointer)
-func getlasterror() uint32
-func setlasterror(err uint32)
-func usleep1(usec uint32)
-
func os_sigpipe() {
gothrow("too many writes on closed pipe")
}
diff --git a/src/runtime/os_windows.h b/src/runtime/os_windows.h
deleted file mode 100644
index d5d168d77..000000000
--- a/src/runtime/os_windows.h
+++ /dev/null
@@ -1,42 +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.
-
-extern void *runtime·LoadLibrary;
-extern void *runtime·GetProcAddress;
-extern void *runtime·GetQueuedCompletionStatusEx;
-
-// Call a Windows function with stdcall conventions,
-// and switch to os stack during the call.
-void runtime·asmstdcall(void *c);
-void *runtime·stdcall0(void *fn);
-void *runtime·stdcall1(void *fn, uintptr a0);
-void *runtime·stdcall2(void *fn, uintptr a0, uintptr a1);
-void *runtime·stdcall3(void *fn, uintptr a0, uintptr a1, uintptr a2);
-void *runtime·stdcall4(void *fn, uintptr a0, uintptr a1, uintptr a2, uintptr a3);
-void *runtime·stdcall5(void *fn, uintptr a0, uintptr a1, uintptr a2, uintptr a3, uintptr a4);
-void *runtime·stdcall6(void *fn, uintptr a0, uintptr a1, uintptr a2, uintptr a3, uintptr a4, uintptr a5);
-void *runtime·stdcall7(void *fn, uintptr a0, uintptr a1, uintptr a2, uintptr a3, uintptr a4, uintptr a5, uintptr a6);
-
-uint32 runtime·getlasterror(void);
-void runtime·setlasterror(uint32 err);
-
-// Function to be called by windows CreateThread
-// to start new os thread.
-uint32 runtime·tstart_stdcall(M *newm);
-
-uint32 runtime·issigpanic(uint32);
-void runtime·sigpanic(void);
-uint32 runtime·ctrlhandler(uint32 type);
-
-// Windows dll function to go callback entry.
-byte *runtime·compilecallback(Eface fn, bool cleanstack);
-void *runtime·callbackasm(void);
-
-void runtime·install_exception_handler(void);
-void runtime·remove_exception_handler(void);
-
-// TODO(brainman): should not need those
-enum {
- NSIG = 65,
-};
diff --git a/src/runtime/os_windows_386.c b/src/runtime/os_windows_386.c
deleted file mode 100644
index 9962f0dc2..000000000
--- a/src/runtime/os_windows_386.c
+++ /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.
-
-#include "runtime.h"
-#include "defs_GOOS_GOARCH.h"
-#include "os_GOOS.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);
-}
-
-bool
-runtime·isgoexception(ExceptionRecord *info, Context *r)
-{
- extern byte runtime·text[], runtime·etext[];
-
- // Only handle exception if executing instructions in Go binary
- // (not Windows library code).
- if(r->Eip < (uint32)runtime·text || (uint32)runtime·etext < r->Eip)
- return false;
-
- if(!runtime·issigpanic(info->ExceptionCode))
- return false;
-
- return true;
-}
-
-// Called by sigtramp from Windows VEH handler.
-// Return value signals whether the exception has been handled (EXCEPTION_CONTINUE_EXECUTION)
-// or should be made available to other handlers in the chain (EXCEPTION_CONTINUE_SEARCH).
-uint32
-runtime·exceptionhandler(ExceptionRecord *info, Context *r, G *gp)
-{
- uintptr *sp;
-
- if(!runtime·isgoexception(info, r))
- return EXCEPTION_CONTINUE_SEARCH;
-
- // 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 EXCEPTION_CONTINUE_EXECUTION;
-}
-
-// lastcontinuehandler is reached, because runtime cannot handle
-// current exception. lastcontinuehandler will print crash info and exit.
-uint32
-runtime·lastcontinuehandler(ExceptionRecord *info, Context *r, G *gp)
-{
- bool crash;
-
- if(runtime·panicking) // traceback already printed
- runtime·exit(2);
- runtime·panicking = 1;
-
- runtime·printf("Exception %x %p %p %p\n", info->ExceptionCode,
- (uintptr)info->ExceptionInformation[0], (uintptr)info->ExceptionInformation[1], (uintptr)r->Eip);
-
- runtime·printf("PC=%x\n", r->Eip);
- if(g->m->lockedg != nil && g->m->ncgo > 0 && gp == g->m->g0) {
- runtime·printf("signal arrived during cgo execution\n");
- gp = g->m->lockedg;
- }
- runtime·printf("\n");
-
- if(runtime·gotraceback(&crash)){
- runtime·tracebacktrap(r->Eip, r->Esp, 0, gp);
- runtime·tracebackothers(gp);
- runtime·dumpregs(r);
- }
-
- if(crash)
- runtime·crash();
-
- runtime·exit(2);
- return 0; // not reached
-}
-
-void
-runtime·sigenable(uint32 sig)
-{
- USED(sig);
-}
-
-void
-runtime·sigdisable(uint32 sig)
-{
- USED(sig);
-}
-
-void
-runtime·dosigprof(Context *r, G *gp, M *mp)
-{
- runtime·sigprof((uint8*)r->Eip, (uint8*)r->Esp, nil, gp, mp);
-}
diff --git a/src/runtime/os_windows_amd64.c b/src/runtime/os_windows_amd64.c
deleted file mode 100644
index e4617e4ce..000000000
--- a/src/runtime/os_windows_amd64.c
+++ /dev/null
@@ -1,150 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "runtime.h"
-#include "defs_GOOS_GOARCH.h"
-#include "os_GOOS.h"
-
-void
-runtime·dumpregs(Context *r)
-{
- runtime·printf("rax %X\n", r->Rax);
- runtime·printf("rbx %X\n", r->Rbx);
- runtime·printf("rcx %X\n", r->Rcx);
- runtime·printf("rdx %X\n", r->Rdx);
- runtime·printf("rdi %X\n", r->Rdi);
- runtime·printf("rsi %X\n", r->Rsi);
- runtime·printf("rbp %X\n", r->Rbp);
- runtime·printf("rsp %X\n", r->Rsp);
- runtime·printf("r8 %X\n", r->R8 );
- runtime·printf("r9 %X\n", r->R9 );
- runtime·printf("r10 %X\n", r->R10);
- runtime·printf("r11 %X\n", r->R11);
- runtime·printf("r12 %X\n", r->R12);
- runtime·printf("r13 %X\n", r->R13);
- runtime·printf("r14 %X\n", r->R14);
- runtime·printf("r15 %X\n", r->R15);
- runtime·printf("rip %X\n", r->Rip);
- runtime·printf("rflags %X\n", r->EFlags);
- runtime·printf("cs %X\n", (uint64)r->SegCs);
- runtime·printf("fs %X\n", (uint64)r->SegFs);
- runtime·printf("gs %X\n", (uint64)r->SegGs);
-}
-
-bool
-runtime·isgoexception(ExceptionRecord *info, Context *r)
-{
- extern byte runtime·text[], runtime·etext[];
-
- // Only handle exception if executing instructions in Go binary
- // (not Windows library code).
- if(r->Rip < (uint64)runtime·text || (uint64)runtime·etext < r->Rip)
- return false;
-
- if(!runtime·issigpanic(info->ExceptionCode))
- return false;
-
- return true;
-}
-
-// Called by sigtramp from Windows VEH handler.
-// Return value signals whether the exception has been handled (EXCEPTION_CONTINUE_EXECUTION)
-// or should be made available to other handlers in the chain (EXCEPTION_CONTINUE_SEARCH).
-uint32
-runtime·exceptionhandler(ExceptionRecord *info, Context *r, G *gp)
-{
- uintptr *sp;
-
- if(!runtime·isgoexception(info, r))
- return EXCEPTION_CONTINUE_SEARCH;
-
- // 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->Rip;
-
- // Only push runtime·sigpanic if r->rip != 0.
- // If r->rip == 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->Rip != 0) {
- sp = (uintptr*)r->Rsp;
- *--sp = r->Rip;
- r->Rsp = (uintptr)sp;
- }
- r->Rip = (uintptr)runtime·sigpanic;
- return EXCEPTION_CONTINUE_EXECUTION;
-}
-
-// It seems Windows searches ContinueHandler's list even
-// if ExceptionHandler returns EXCEPTION_CONTINUE_EXECUTION.
-// firstcontinuehandler will stop that search,
-// if exceptionhandler did the same earlier.
-uint32
-runtime·firstcontinuehandler(ExceptionRecord *info, Context *r, G *gp)
-{
- USED(gp);
- if(!runtime·isgoexception(info, r))
- return EXCEPTION_CONTINUE_SEARCH;
- return EXCEPTION_CONTINUE_EXECUTION;
-}
-
-// lastcontinuehandler is reached, because runtime cannot handle
-// current exception. lastcontinuehandler will print crash info and exit.
-uint32
-runtime·lastcontinuehandler(ExceptionRecord *info, Context *r, G *gp)
-{
- bool crash;
-
- if(runtime·panicking) // traceback already printed
- runtime·exit(2);
- runtime·panicking = 1;
-
- runtime·printf("Exception %x %p %p %p\n", info->ExceptionCode,
- info->ExceptionInformation[0], info->ExceptionInformation[1], r->Rip);
-
-
- runtime·printf("PC=%X\n", r->Rip);
- if(g->m->lockedg != nil && g->m->ncgo > 0 && gp == g->m->g0) {
- runtime·printf("signal arrived during cgo execution\n");
- gp = g->m->lockedg;
- }
- runtime·printf("\n");
-
- if(runtime·gotraceback(&crash)){
- runtime·tracebacktrap(r->Rip, r->Rsp, 0, gp);
- runtime·tracebackothers(gp);
- runtime·dumpregs(r);
- }
-
- if(crash)
- runtime·crash();
-
- runtime·exit(2);
- return 0; // not reached
-}
-
-void
-runtime·sigenable(uint32 sig)
-{
- USED(sig);
-}
-
-void
-runtime·sigdisable(uint32 sig)
-{
- USED(sig);
-}
-
-void
-runtime·dosigprof(Context *r, G *gp, M *mp)
-{
- runtime·sigprof((uint8*)r->Rip, (uint8*)r->Rsp, nil, gp, mp);
-}
diff --git a/src/runtime/panic.go b/src/runtime/panic.go
index 892946702..95e780b1d 100644
--- a/src/runtime/panic.go
+++ b/src/runtime/panic.go
@@ -162,7 +162,7 @@ func init() {
// Allocate a Defer, usually using per-P pool.
// Each defer must be released with freedefer.
-// Note: runs on M stack
+// Note: runs on g0 stack
func newdefer(siz int32) *_defer {
var d *_defer
sc := deferclass(uintptr(siz))
diff --git a/src/runtime/proc.go b/src/runtime/proc.go
index 12e2e71e9..64f6a3520 100644
--- a/src/runtime/proc.go
+++ b/src/runtime/proc.go
@@ -63,11 +63,13 @@ func main() {
if _cgo_free == nil {
gothrow("_cgo_free missing")
}
- if _cgo_setenv == nil {
- gothrow("_cgo_setenv missing")
- }
- if _cgo_unsetenv == nil {
- gothrow("_cgo_unsetenv missing")
+ if GOOS != "windows" {
+ if _cgo_setenv == nil {
+ gothrow("_cgo_setenv missing")
+ }
+ if _cgo_unsetenv == nil {
+ gothrow("_cgo_unsetenv missing")
+ }
}
}
@@ -165,6 +167,7 @@ func acquireSudog() *sudog {
gothrow("acquireSudog: found s.elem != nil in cache")
}
c.sudogcache = s.next
+ s.next = nil
return s
}
@@ -193,6 +196,15 @@ func releaseSudog(s *sudog) {
if s.selectdone != nil {
gothrow("runtime: sudog with non-nil selectdone")
}
+ if s.next != nil {
+ gothrow("runtime: sudog with non-nil next")
+ }
+ if s.prev != nil {
+ gothrow("runtime: sudog with non-nil prev")
+ }
+ if s.waitlink != nil {
+ gothrow("runtime: sudog with non-nil waitlink")
+ }
gp := getg()
if gp.param != nil {
gothrow("runtime: releaseSudog with non-nil gp.param")
diff --git a/src/runtime/race/race_unix_test.go b/src/runtime/race/race_unix_test.go
new file mode 100644
index 000000000..84f0acece
--- /dev/null
+++ b/src/runtime/race/race_unix_test.go
@@ -0,0 +1,30 @@
+// Copyright 2014 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.
+
+// +build race
+// +build darwin freebsd linux
+
+package race_test
+
+import (
+ "sync/atomic"
+ "syscall"
+ "testing"
+ "unsafe"
+)
+
+// Test that race detector does not crash when accessing non-Go allocated memory (issue 9136).
+func TestNonGoMemory(t *testing.T) {
+ data, err := syscall.Mmap(-1, 0, 4096, syscall.PROT_READ|syscall.PROT_WRITE, syscall.MAP_ANON|syscall.MAP_PRIVATE)
+ if err != nil {
+ t.Fatalf("failed to mmap memory: %v", err)
+ }
+ p := (*uint32)(unsafe.Pointer(&data[0]))
+ atomic.AddUint32(p, 1)
+ (*p)++
+ if *p != 2 {
+ t.Fatalf("data[0] = %v, expect 2", *p)
+ }
+ syscall.Munmap(data)
+}
diff --git a/src/runtime/race1.go b/src/runtime/race1.go
index 4c580429c..2ec2bee65 100644
--- a/src/runtime/race1.go
+++ b/src/runtime/race1.go
@@ -81,6 +81,10 @@ var __tsan_go_ignore_sync_end byte
//go:cgo_import_static __tsan_go_atomic32_compare_exchange
//go:cgo_import_static __tsan_go_atomic64_compare_exchange
+// start/end of global data (data+bss).
+var racedatastart uintptr
+var racedataend uintptr
+
// start/end of heap for race_amd64.s
var racearenastart uintptr
var racearenaend uintptr
@@ -99,7 +103,7 @@ func racecall(*byte, uintptr, uintptr, uintptr, uintptr)
//go:nosplit
func isvalidaddr(addr unsafe.Pointer) bool {
return racearenastart <= uintptr(addr) && uintptr(addr) < racearenaend ||
- uintptr(unsafe.Pointer(&noptrdata)) <= uintptr(addr) && uintptr(addr) < uintptr(unsafe.Pointer(&enoptrbss))
+ racedatastart <= uintptr(addr) && uintptr(addr) < racedataend
}
//go:nosplit
@@ -113,9 +117,36 @@ func raceinit() uintptr {
racecall(&__tsan_init, uintptr(unsafe.Pointer(&racectx)), funcPC(racesymbolizethunk), 0, 0)
// Round data segment to page boundaries, because it's used in mmap().
- start := uintptr(unsafe.Pointer(&noptrdata)) &^ (_PageSize - 1)
- size := round(uintptr(unsafe.Pointer(&enoptrbss))-start, _PageSize)
+ start := ^uintptr(0)
+ end := uintptr(0)
+ if start > uintptr(unsafe.Pointer(&noptrdata)) {
+ start = uintptr(unsafe.Pointer(&noptrdata))
+ }
+ if start > uintptr(unsafe.Pointer(&data)) {
+ start = uintptr(unsafe.Pointer(&data))
+ }
+ if start > uintptr(unsafe.Pointer(&noptrbss)) {
+ start = uintptr(unsafe.Pointer(&noptrbss))
+ }
+ if start > uintptr(unsafe.Pointer(&bss)) {
+ start = uintptr(unsafe.Pointer(&bss))
+ }
+ if end < uintptr(unsafe.Pointer(&enoptrdata)) {
+ end = uintptr(unsafe.Pointer(&enoptrdata))
+ }
+ if end < uintptr(unsafe.Pointer(&edata)) {
+ end = uintptr(unsafe.Pointer(&edata))
+ }
+ if end < uintptr(unsafe.Pointer(&enoptrbss)) {
+ end = uintptr(unsafe.Pointer(&enoptrbss))
+ }
+ if end < uintptr(unsafe.Pointer(&ebss)) {
+ end = uintptr(unsafe.Pointer(&ebss))
+ }
+ size := round(end-start, _PageSize)
racecall(&__tsan_map_shadow, start, size, 0, 0)
+ racedatastart = start
+ racedataend = start + size
return racectx
}
diff --git a/src/runtime/race_amd64.s b/src/runtime/race_amd64.s
index a7f44870a..d54d9798f 100644
--- a/src/runtime/race_amd64.s
+++ b/src/runtime/race_amd64.s
@@ -139,17 +139,15 @@ TEXT racecalladdr<>(SB), NOSPLIT, $0-0
get_tls(R12)
MOVQ g(R12), R14
MOVQ g_racectx(R14), RARG0 // goroutine context
- // Check that addr is within [arenastart, arenaend) or within [noptrdata, enoptrbss).
+ // Check that addr is within [arenastart, arenaend) or within [racedatastart, racedataend).
CMPQ RARG1, runtime·racearenastart(SB)
JB data
CMPQ RARG1, runtime·racearenaend(SB)
JB call
data:
- MOVQ $runtime·noptrdata(SB), R13
- CMPQ RARG1, R13
+ CMPQ RARG1, runtime·racedatastart(SB)
JB ret
- MOVQ $runtime·enoptrbss(SB), R13
- CMPQ RARG1, R13
+ CMPQ RARG1, runtime·racedataend(SB)
JAE ret
call:
MOVQ AX, AX // w/o this 6a miscompiles this function
@@ -167,6 +165,7 @@ TEXT runtime·racefuncenter(SB), NOSPLIT, $0-8
MOVQ callpc+0(FP), RARG1
// void __tsan_func_enter(ThreadState *thr, void *pc);
MOVQ $__tsan_func_enter(SB), AX
+ // racecall<> preserves R15
CALL racecall<>(SB)
MOVQ R15, DX // restore function entry context
RET
@@ -307,13 +306,45 @@ TEXT sync∕atomic·CompareAndSwapPointer(SB), NOSPLIT, $0-0
TEXT racecallatomic<>(SB), NOSPLIT, $0-0
// Trigger SIGSEGV early.
MOVQ 16(SP), R12
- MOVL (R12), R12
+ MOVL (R12), R13
+ // Check that addr is within [arenastart, arenaend) or within [racedatastart, racedataend).
+ CMPQ R12, runtime·racearenastart(SB)
+ JB racecallatomic_data
+ CMPQ R12, runtime·racearenaend(SB)
+ JB racecallatomic_ok
+racecallatomic_data:
+ CMPQ R12, runtime·racedatastart(SB)
+ JB racecallatomic_ignore
+ CMPQ R12, runtime·racedataend(SB)
+ JAE racecallatomic_ignore
+racecallatomic_ok:
+ // Addr is within the good range, call the atomic function.
get_tls(R12)
MOVQ g(R12), R14
MOVQ g_racectx(R14), RARG0 // goroutine context
MOVQ 8(SP), RARG1 // caller pc
MOVQ (SP), RARG2 // pc
LEAQ 16(SP), RARG3 // arguments
+ JMP racecall<>(SB) // does not return
+racecallatomic_ignore:
+ // Addr is outside the good range.
+ // Call __tsan_go_ignore_sync_begin to ignore synchronization during the atomic op.
+ // An attempt to synchronize on the address would cause crash.
+ MOVQ AX, R15 // remember the original function
+ MOVQ $__tsan_go_ignore_sync_begin(SB), AX
+ MOVQ g(R12), R14
+ MOVQ g_racectx(R14), RARG0 // goroutine context
+ CALL racecall<>(SB)
+ MOVQ R15, AX // restore the original function
+ // Call the atomic function.
+ MOVQ g_racectx(R14), RARG0 // goroutine context
+ MOVQ 8(SP), RARG1 // caller pc
+ MOVQ (SP), RARG2 // pc
+ LEAQ 16(SP), RARG3 // arguments
+ CALL racecall<>(SB)
+ // Call __tsan_go_ignore_sync_end.
+ MOVQ $__tsan_go_ignore_sync_end(SB), AX
+ MOVQ g_racectx(R14), RARG0 // goroutine context
JMP racecall<>(SB)
// void runtime·racecall(void(*f)(...), ...)
diff --git a/src/runtime/runtime2.go b/src/runtime/runtime2.go
index 7625a2dd8..d18178d09 100644
--- a/src/runtime/runtime2.go
+++ b/src/runtime/runtime2.go
@@ -45,7 +45,13 @@ const (
_Pdead
)
-// XXX inserting below here
+// The next line makes 'go generate' write the zgen_*.go files with
+// per-OS and per-arch information, including constants
+// named goos_$GOOS and goarch_$GOARCH for every
+// known GOOS and GOARCH. The constant is 1 on the
+// current system, 0 otherwise; multiplying by them is
+// useful for defining GOOS- or GOARCH-specific constants.
+//go:generate go run gengoos.go
type mutex struct {
// Futex-based impl treats it as uint32 key,
@@ -397,14 +403,6 @@ type itab struct {
fun [0]uintptr
}
-const (
- // TODO: Generate in cmd/dist.
- _NaCl = 0
- _Windows = 0
- _Solaris = 0
- _Plan9 = 0
-)
-
// Lock-free stack node.
// // Also known to export_test.go.
type lfnode struct {
diff --git a/src/runtime/select.go b/src/runtime/select.go
index e918b734a..5e5047bc1 100644
--- a/src/runtime/select.go
+++ b/src/runtime/select.go
@@ -399,6 +399,7 @@ loop:
}
}
sgnext = sglist.waitlink
+ sglist.waitlink = nil
releaseSudog(sglist)
sglist = sgnext
}
@@ -636,6 +637,7 @@ func (q *waitq) dequeueSudoG(s *sudog) {
if q.last == sgp {
q.last = prevsgp
}
+ s.next = nil
return
}
l = &sgp.next
diff --git a/src/runtime/sema.go b/src/runtime/sema.go
index d2a028c01..26dbd30ea 100644
--- a/src/runtime/sema.go
+++ b/src/runtime/sema.go
@@ -201,6 +201,7 @@ func syncsemacquire(s *syncSema) {
}
unlock(&s.lock)
if wake != nil {
+ wake.next = nil
goready(wake.g)
}
} else {
@@ -242,6 +243,7 @@ func syncsemrelease(s *syncSema, n uint32) {
if wake.releasetime != 0 {
wake.releasetime = cputicks()
}
+ wake.next = nil
goready(wake.g)
n--
}
diff --git a/src/runtime/signal_android_386.h b/src/runtime/signal_android_386.h
deleted file mode 100644
index 2a1bb4b3e..000000000
--- a/src/runtime/signal_android_386.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "signal_linux_386.h"
diff --git a/src/runtime/signal_android_arm.h b/src/runtime/signal_android_arm.h
deleted file mode 100644
index 8a05e21e5..000000000
--- a/src/runtime/signal_android_arm.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "signal_linux_arm.h"
diff --git a/src/runtime/signal_linux_386.go b/src/runtime/signal_linux_386.go
index 41eae80ea..085f66e89 100644
--- a/src/runtime/signal_linux_386.go
+++ b/src/runtime/signal_linux_386.go
@@ -26,7 +26,7 @@ func (c *sigctxt) cs() uint32 { return uint32(c.regs().cs) }
func (c *sigctxt) fs() uint32 { return uint32(c.regs().fs) }
func (c *sigctxt) gs() uint32 { return uint32(c.regs().gs) }
func (c *sigctxt) sigcode() uint32 { return uint32(c.info.si_code) }
-func (c *sigctxt) sigaddr() uint32 { return uint32(*(*uintptr)(add(unsafe.Pointer(c.info), 2*ptrSize))) }
+func (c *sigctxt) sigaddr() uint32 { return c.info.si_addr }
func (c *sigctxt) set_eip(x uint32) { c.regs().eip = x }
func (c *sigctxt) set_esp(x uint32) { c.regs().esp = x }
diff --git a/src/runtime/signal_linux_amd64.go b/src/runtime/signal_linux_amd64.go
index d94b19102..5e339b8a4 100644
--- a/src/runtime/signal_linux_amd64.go
+++ b/src/runtime/signal_linux_amd64.go
@@ -36,7 +36,7 @@ func (c *sigctxt) cs() uint64 { return uint64(c.regs().cs) }
func (c *sigctxt) fs() uint64 { return uint64(c.regs().fs) }
func (c *sigctxt) gs() uint64 { return uint64(c.regs().gs) }
func (c *sigctxt) sigcode() uint64 { return uint64(c.info.si_code) }
-func (c *sigctxt) sigaddr() uint64 { return uint64(*(*uintptr)(add(unsafe.Pointer(c.info), 2*ptrSize))) }
+func (c *sigctxt) sigaddr() uint64 { return c.info.si_addr }
func (c *sigctxt) set_rip(x uint64) { c.regs().rip = x }
func (c *sigctxt) set_rsp(x uint64) { c.regs().rsp = x }
diff --git a/src/runtime/signal_linux_arm.go b/src/runtime/signal_linux_arm.go
index 4a5670e74..bdb4314fa 100644
--- a/src/runtime/signal_linux_arm.go
+++ b/src/runtime/signal_linux_arm.go
@@ -35,7 +35,7 @@ func (c *sigctxt) error() uint32 { return c.regs().error_code }
func (c *sigctxt) oldmask() uint32 { return c.regs().oldmask }
func (c *sigctxt) sigcode() uint32 { return uint32(c.info.si_code) }
-func (c *sigctxt) sigaddr() uint32 { return uint32(*(*uintptr)(add(unsafe.Pointer(c.info), 2*ptrSize))) }
+func (c *sigctxt) sigaddr() uint32 { return c.info.si_addr }
func (c *sigctxt) set_pc(x uint32) { c.regs().pc = x }
func (c *sigctxt) set_sp(x uint32) { c.regs().sp = x }
diff --git a/src/runtime/signal_linux_power64.h b/src/runtime/signal_linux_power64.h
deleted file mode 100644
index 840648920..000000000
--- a/src/runtime/signal_linux_power64.h
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2014 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.
-
-#define SIG_REGS(ctxt) (*((Sigcontext*)&((Ucontext*)(ctxt))->uc_mcontext)->regs)
-
-#define SIG_R0(info, ctxt) (SIG_REGS(ctxt).gpr[0])
-#define SIG_R1(info, ctxt) (SIG_REGS(ctxt).gpr[1])
-#define SIG_R2(info, ctxt) (SIG_REGS(ctxt).gpr[2])
-#define SIG_R3(info, ctxt) (SIG_REGS(ctxt).gpr[3])
-#define SIG_R4(info, ctxt) (SIG_REGS(ctxt).gpr[4])
-#define SIG_R5(info, ctxt) (SIG_REGS(ctxt).gpr[5])
-#define SIG_R6(info, ctxt) (SIG_REGS(ctxt).gpr[6])
-#define SIG_R7(info, ctxt) (SIG_REGS(ctxt).gpr[7])
-#define SIG_R8(info, ctxt) (SIG_REGS(ctxt).gpr[8])
-#define SIG_R9(info, ctxt) (SIG_REGS(ctxt).gpr[9])
-#define SIG_R10(info, ctxt) (SIG_REGS(ctxt).gpr[10])
-#define SIG_R11(info, ctxt) (SIG_REGS(ctxt).gpr[11])
-#define SIG_R12(info, ctxt) (SIG_REGS(ctxt).gpr[12])
-#define SIG_R13(info, ctxt) (SIG_REGS(ctxt).gpr[13])
-#define SIG_R14(info, ctxt) (SIG_REGS(ctxt).gpr[14])
-#define SIG_R15(info, ctxt) (SIG_REGS(ctxt).gpr[15])
-#define SIG_R16(info, ctxt) (SIG_REGS(ctxt).gpr[16])
-#define SIG_R17(info, ctxt) (SIG_REGS(ctxt).gpr[17])
-#define SIG_R18(info, ctxt) (SIG_REGS(ctxt).gpr[18])
-#define SIG_R19(info, ctxt) (SIG_REGS(ctxt).gpr[19])
-#define SIG_R20(info, ctxt) (SIG_REGS(ctxt).gpr[20])
-#define SIG_R21(info, ctxt) (SIG_REGS(ctxt).gpr[21])
-#define SIG_R22(info, ctxt) (SIG_REGS(ctxt).gpr[22])
-#define SIG_R23(info, ctxt) (SIG_REGS(ctxt).gpr[23])
-#define SIG_R24(info, ctxt) (SIG_REGS(ctxt).gpr[24])
-#define SIG_R25(info, ctxt) (SIG_REGS(ctxt).gpr[25])
-#define SIG_R26(info, ctxt) (SIG_REGS(ctxt).gpr[26])
-#define SIG_R27(info, ctxt) (SIG_REGS(ctxt).gpr[27])
-#define SIG_R28(info, ctxt) (SIG_REGS(ctxt).gpr[28])
-#define SIG_R29(info, ctxt) (SIG_REGS(ctxt).gpr[29])
-#define SIG_R30(info, ctxt) (SIG_REGS(ctxt).gpr[30])
-#define SIG_R31(info, ctxt) (SIG_REGS(ctxt).gpr[31])
-
-#define SIG_SP(info, ctxt) (SIG_REGS(ctxt).gpr[1])
-#define SIG_PC(info, ctxt) (SIG_REGS(ctxt).nip)
-#define SIG_TRAP(info, ctxt) (SIG_REGS(ctxt).trap)
-#define SIG_CTR(info, ctxt) (SIG_REGS(ctxt).ctr)
-#define SIG_LINK(info, ctxt) (SIG_REGS(ctxt).link)
-#define SIG_XER(info, ctxt) (SIG_REGS(ctxt).xer)
-#define SIG_CCR(info, ctxt) (SIG_REGS(ctxt).ccr)
-
-#define SIG_CODE0(info, ctxt) ((uintptr)(info)->si_code)
-#define SIG_FAULT(info, ctxt) (SIG_REGS(ctxt).dar)
diff --git a/src/runtime/signal_linux_power64le.h b/src/runtime/signal_linux_power64le.h
deleted file mode 100644
index 840648920..000000000
--- a/src/runtime/signal_linux_power64le.h
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2014 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.
-
-#define SIG_REGS(ctxt) (*((Sigcontext*)&((Ucontext*)(ctxt))->uc_mcontext)->regs)
-
-#define SIG_R0(info, ctxt) (SIG_REGS(ctxt).gpr[0])
-#define SIG_R1(info, ctxt) (SIG_REGS(ctxt).gpr[1])
-#define SIG_R2(info, ctxt) (SIG_REGS(ctxt).gpr[2])
-#define SIG_R3(info, ctxt) (SIG_REGS(ctxt).gpr[3])
-#define SIG_R4(info, ctxt) (SIG_REGS(ctxt).gpr[4])
-#define SIG_R5(info, ctxt) (SIG_REGS(ctxt).gpr[5])
-#define SIG_R6(info, ctxt) (SIG_REGS(ctxt).gpr[6])
-#define SIG_R7(info, ctxt) (SIG_REGS(ctxt).gpr[7])
-#define SIG_R8(info, ctxt) (SIG_REGS(ctxt).gpr[8])
-#define SIG_R9(info, ctxt) (SIG_REGS(ctxt).gpr[9])
-#define SIG_R10(info, ctxt) (SIG_REGS(ctxt).gpr[10])
-#define SIG_R11(info, ctxt) (SIG_REGS(ctxt).gpr[11])
-#define SIG_R12(info, ctxt) (SIG_REGS(ctxt).gpr[12])
-#define SIG_R13(info, ctxt) (SIG_REGS(ctxt).gpr[13])
-#define SIG_R14(info, ctxt) (SIG_REGS(ctxt).gpr[14])
-#define SIG_R15(info, ctxt) (SIG_REGS(ctxt).gpr[15])
-#define SIG_R16(info, ctxt) (SIG_REGS(ctxt).gpr[16])
-#define SIG_R17(info, ctxt) (SIG_REGS(ctxt).gpr[17])
-#define SIG_R18(info, ctxt) (SIG_REGS(ctxt).gpr[18])
-#define SIG_R19(info, ctxt) (SIG_REGS(ctxt).gpr[19])
-#define SIG_R20(info, ctxt) (SIG_REGS(ctxt).gpr[20])
-#define SIG_R21(info, ctxt) (SIG_REGS(ctxt).gpr[21])
-#define SIG_R22(info, ctxt) (SIG_REGS(ctxt).gpr[22])
-#define SIG_R23(info, ctxt) (SIG_REGS(ctxt).gpr[23])
-#define SIG_R24(info, ctxt) (SIG_REGS(ctxt).gpr[24])
-#define SIG_R25(info, ctxt) (SIG_REGS(ctxt).gpr[25])
-#define SIG_R26(info, ctxt) (SIG_REGS(ctxt).gpr[26])
-#define SIG_R27(info, ctxt) (SIG_REGS(ctxt).gpr[27])
-#define SIG_R28(info, ctxt) (SIG_REGS(ctxt).gpr[28])
-#define SIG_R29(info, ctxt) (SIG_REGS(ctxt).gpr[29])
-#define SIG_R30(info, ctxt) (SIG_REGS(ctxt).gpr[30])
-#define SIG_R31(info, ctxt) (SIG_REGS(ctxt).gpr[31])
-
-#define SIG_SP(info, ctxt) (SIG_REGS(ctxt).gpr[1])
-#define SIG_PC(info, ctxt) (SIG_REGS(ctxt).nip)
-#define SIG_TRAP(info, ctxt) (SIG_REGS(ctxt).trap)
-#define SIG_CTR(info, ctxt) (SIG_REGS(ctxt).ctr)
-#define SIG_LINK(info, ctxt) (SIG_REGS(ctxt).link)
-#define SIG_XER(info, ctxt) (SIG_REGS(ctxt).xer)
-#define SIG_CCR(info, ctxt) (SIG_REGS(ctxt).ccr)
-
-#define SIG_CODE0(info, ctxt) ((uintptr)(info)->si_code)
-#define SIG_FAULT(info, ctxt) (SIG_REGS(ctxt).dar)
diff --git a/src/runtime/signal_linux_power64x.go b/src/runtime/signal_linux_power64x.go
new file mode 100644
index 000000000..0a406b31f
--- /dev/null
+++ b/src/runtime/signal_linux_power64x.go
@@ -0,0 +1,71 @@
+// Copyright 2014 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.
+
+// +build linux
+// +build power64 power64le
+
+package runtime
+
+import "unsafe"
+
+type sigctxt struct {
+ info *siginfo
+ ctxt unsafe.Pointer
+}
+
+func (c *sigctxt) regs() *ptregs { return (*ucontext)(c.ctxt).uc_mcontext.regs }
+func (c *sigctxt) r0() uint64 { return c.regs().gpr[0] }
+func (c *sigctxt) r1() uint64 { return c.regs().gpr[1] }
+func (c *sigctxt) r2() uint64 { return c.regs().gpr[2] }
+func (c *sigctxt) r3() uint64 { return c.regs().gpr[3] }
+func (c *sigctxt) r4() uint64 { return c.regs().gpr[4] }
+func (c *sigctxt) r5() uint64 { return c.regs().gpr[5] }
+func (c *sigctxt) r6() uint64 { return c.regs().gpr[6] }
+func (c *sigctxt) r7() uint64 { return c.regs().gpr[7] }
+func (c *sigctxt) r8() uint64 { return c.regs().gpr[8] }
+func (c *sigctxt) r9() uint64 { return c.regs().gpr[9] }
+func (c *sigctxt) r10() uint64 { return c.regs().gpr[10] }
+func (c *sigctxt) r11() uint64 { return c.regs().gpr[11] }
+func (c *sigctxt) r12() uint64 { return c.regs().gpr[12] }
+func (c *sigctxt) r13() uint64 { return c.regs().gpr[13] }
+func (c *sigctxt) r14() uint64 { return c.regs().gpr[14] }
+func (c *sigctxt) r15() uint64 { return c.regs().gpr[15] }
+func (c *sigctxt) r16() uint64 { return c.regs().gpr[16] }
+func (c *sigctxt) r17() uint64 { return c.regs().gpr[17] }
+func (c *sigctxt) r18() uint64 { return c.regs().gpr[18] }
+func (c *sigctxt) r19() uint64 { return c.regs().gpr[19] }
+func (c *sigctxt) r20() uint64 { return c.regs().gpr[20] }
+func (c *sigctxt) r21() uint64 { return c.regs().gpr[21] }
+func (c *sigctxt) r22() uint64 { return c.regs().gpr[22] }
+func (c *sigctxt) r23() uint64 { return c.regs().gpr[23] }
+func (c *sigctxt) r24() uint64 { return c.regs().gpr[24] }
+func (c *sigctxt) r25() uint64 { return c.regs().gpr[25] }
+func (c *sigctxt) r26() uint64 { return c.regs().gpr[26] }
+func (c *sigctxt) r27() uint64 { return c.regs().gpr[27] }
+func (c *sigctxt) r28() uint64 { return c.regs().gpr[28] }
+func (c *sigctxt) r29() uint64 { return c.regs().gpr[29] }
+func (c *sigctxt) r30() uint64 { return c.regs().gpr[30] }
+func (c *sigctxt) r31() uint64 { return c.regs().gpr[31] }
+func (c *sigctxt) sp() uint64 { return c.regs().gpr[1] }
+func (c *sigctxt) pc() uint64 { return c.regs().nip }
+func (c *sigctxt) trap() uint64 { return c.regs().trap }
+func (c *sigctxt) ctr() uint64 { return c.regs().ctr }
+func (c *sigctxt) link() uint64 { return c.regs().link }
+func (c *sigctxt) xer() uint64 { return c.regs().xer }
+func (c *sigctxt) ccr() uint64 { return c.regs().ccr }
+
+func (c *sigctxt) sigcode() uint32 { return uint32(c.info.si_code) }
+func (c *sigctxt) sigaddr() uint64 { return c.info.si_addr }
+func (c *sigctxt) fault() uint64 { return c.regs().dar }
+
+func (c *sigctxt) set_r0(x uint64) { c.regs().gpr[0] = x }
+func (c *sigctxt) set_r30(x uint64) { c.regs().gpr[30] = x }
+func (c *sigctxt) set_pc(x uint64) { c.regs().nip = x }
+func (c *sigctxt) set_sp(x uint64) { c.regs().gpr[1] = x }
+func (c *sigctxt) set_link(x uint64) { c.regs().link = x }
+
+func (c *sigctxt) set_sigcode(x uint32) { c.info.si_code = int32(x) }
+func (c *sigctxt) set_sigaddr(x uint64) {
+ *(*uintptr)(add(unsafe.Pointer(c.info), 2*ptrSize)) = uintptr(x)
+}
diff --git a/src/runtime/signal_nacl.go b/src/runtime/signal_nacl.go
new file mode 100644
index 000000000..122648bc3
--- /dev/null
+++ b/src/runtime/signal_nacl.go
@@ -0,0 +1,45 @@
+// 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
+
+type sigTabT struct {
+ flags int32
+ name string
+}
+
+var sigtable = [...]sigTabT{
+ /* 0 */ {0, "SIGNONE: no trap"},
+ /* 1 */ {_SigNotify + _SigKill, "SIGHUP: terminal line hangup"},
+ /* 2 */ {_SigNotify + _SigKill, "SIGINT: interrupt"},
+ /* 3 */ {_SigNotify + _SigThrow, "SIGQUIT: quit"},
+ /* 4 */ {_SigThrow, "SIGILL: illegal instruction"},
+ /* 5 */ {_SigThrow, "SIGTRAP: trace trap"},
+ /* 6 */ {_SigNotify + _SigThrow, "SIGABRT: abort"},
+ /* 7 */ {_SigThrow, "SIGEMT: emulate instruction executed"},
+ /* 8 */ {_SigPanic, "SIGFPE: floating-point exception"},
+ /* 9 */ {0, "SIGKILL: kill"},
+ /* 10 */ {_SigPanic, "SIGBUS: bus error"},
+ /* 11 */ {_SigPanic, "SIGSEGV: segmentation violation"},
+ /* 12 */ {_SigThrow, "SIGSYS: bad system call"},
+ /* 13 */ {_SigNotify, "SIGPIPE: write to broken pipe"},
+ /* 14 */ {_SigNotify, "SIGALRM: alarm clock"},
+ /* 15 */ {_SigNotify + _SigKill, "SIGTERM: termination"},
+ /* 16 */ {_SigNotify, "SIGURG: urgent condition on socket"},
+ /* 17 */ {0, "SIGSTOP: stop"},
+ /* 18 */ {_SigNotify + _SigDefault, "SIGTSTP: keyboard stop"},
+ /* 19 */ {0, "SIGCONT: continue after stop"},
+ /* 20 */ {_SigNotify, "SIGCHLD: child status has changed"},
+ /* 21 */ {_SigNotify + _SigDefault, "SIGTTIN: background read from tty"},
+ /* 22 */ {_SigNotify + _SigDefault, "SIGTTOU: background write to tty"},
+ /* 23 */ {_SigNotify, "SIGIO: i/o now possible"},
+ /* 24 */ {_SigNotify, "SIGXCPU: cpu limit exceeded"},
+ /* 25 */ {_SigNotify, "SIGXFSZ: file size limit exceeded"},
+ /* 26 */ {_SigNotify, "SIGVTALRM: virtual alarm clock"},
+ /* 27 */ {_SigNotify, "SIGPROF: profiling alarm clock"},
+ /* 28 */ {_SigNotify, "SIGWINCH: window size change"},
+ /* 29 */ {_SigNotify, "SIGINFO: status request from keyboard"},
+ /* 30 */ {_SigNotify, "SIGUSR1: user-defined signal 1"},
+ /* 31 */ {_SigNotify, "SIGUSR2: user-defined signal 2"},
+}
diff --git a/src/runtime/signal_nacl_386.go b/src/runtime/signal_nacl_386.go
new file mode 100644
index 000000000..0a1e7c6ea
--- /dev/null
+++ b/src/runtime/signal_nacl_386.go
@@ -0,0 +1,34 @@
+// Copyright 2013 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 "unsafe"
+
+type sigctxt struct {
+ info *siginfo
+ ctxt unsafe.Pointer
+}
+
+func (c *sigctxt) regs() *excregs386 { return &(*exccontext)(c.ctxt).regs }
+func (c *sigctxt) eax() uint32 { return c.regs().eax }
+func (c *sigctxt) ebx() uint32 { return c.regs().ebx }
+func (c *sigctxt) ecx() uint32 { return c.regs().ecx }
+func (c *sigctxt) edx() uint32 { return c.regs().edx }
+func (c *sigctxt) edi() uint32 { return c.regs().edi }
+func (c *sigctxt) esi() uint32 { return c.regs().esi }
+func (c *sigctxt) ebp() uint32 { return c.regs().ebp }
+func (c *sigctxt) esp() uint32 { return c.regs().esp }
+func (c *sigctxt) eip() uint32 { return c.regs().eip }
+func (c *sigctxt) eflags() uint32 { return c.regs().eflags }
+func (c *sigctxt) cs() uint32 { return ^uint32(0) }
+func (c *sigctxt) fs() uint32 { return ^uint32(0) }
+func (c *sigctxt) gs() uint32 { return ^uint32(0) }
+func (c *sigctxt) sigcode() uint32 { return ^uint32(0) }
+func (c *sigctxt) sigaddr() uint32 { return 0 }
+
+func (c *sigctxt) set_eip(x uint32) { c.regs().eip = x }
+func (c *sigctxt) set_esp(x uint32) { c.regs().esp = x }
+func (c *sigctxt) set_sigcode(x uint32) {}
+func (c *sigctxt) set_sigaddr(x uint32) {}
diff --git a/src/runtime/signal_nacl_386.h b/src/runtime/signal_nacl_386.h
deleted file mode 100644
index c9481b5f4..000000000
--- a/src/runtime/signal_nacl_386.h
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2013 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.
-
-#define SIG_REGS(ctxt) (((ExcContext*)(ctxt))->regs)
-
-#define SIG_EAX(info, ctxt) (SIG_REGS(ctxt).eax)
-#define SIG_EBX(info, ctxt) (SIG_REGS(ctxt).ebx)
-#define SIG_ECX(info, ctxt) (SIG_REGS(ctxt).ecx)
-#define SIG_EDX(info, ctxt) (SIG_REGS(ctxt).edx)
-#define SIG_EDI(info, ctxt) (SIG_REGS(ctxt).edi)
-#define SIG_ESI(info, ctxt) (SIG_REGS(ctxt).esi)
-#define SIG_EBP(info, ctxt) (SIG_REGS(ctxt).ebp)
-#define SIG_ESP(info, ctxt) (SIG_REGS(ctxt).esp)
-#define SIG_EIP(info, ctxt) (SIG_REGS(ctxt).eip)
-#define SIG_EFLAGS(info, ctxt) (SIG_REGS(ctxt).eflags)
-
-#define SIG_CS(info, ctxt) (~0)
-#define SIG_FS(info, ctxt) (~0)
-#define SIG_GS(info, ctxt) (~0)
-
-#define SIG_CODE0(info, ctxt) (~0)
-#define SIG_CODE1(info, ctxt) (0)
diff --git a/src/runtime/signal_nacl_amd64p32.go b/src/runtime/signal_nacl_amd64p32.go
new file mode 100644
index 000000000..024cebadd
--- /dev/null
+++ b/src/runtime/signal_nacl_amd64p32.go
@@ -0,0 +1,44 @@
+// Copyright 2014 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 "unsafe"
+
+type sigctxt struct {
+ info *siginfo
+ ctxt unsafe.Pointer
+}
+
+func (c *sigctxt) regs() *excregsamd64 {
+ return &(*exccontext)(c.ctxt).regs
+}
+func (c *sigctxt) rax() uint64 { return c.regs().rax }
+func (c *sigctxt) rbx() uint64 { return c.regs().rbx }
+func (c *sigctxt) rcx() uint64 { return c.regs().rcx }
+func (c *sigctxt) rdx() uint64 { return c.regs().rdx }
+func (c *sigctxt) rdi() uint64 { return c.regs().rdi }
+func (c *sigctxt) rsi() uint64 { return c.regs().rsi }
+func (c *sigctxt) rbp() uint64 { return c.regs().rbp }
+func (c *sigctxt) rsp() uint64 { return c.regs().rsp }
+func (c *sigctxt) r8() uint64 { return c.regs().r8 }
+func (c *sigctxt) r9() uint64 { return c.regs().r9 }
+func (c *sigctxt) r10() uint64 { return c.regs().r10 }
+func (c *sigctxt) r11() uint64 { return c.regs().r11 }
+func (c *sigctxt) r12() uint64 { return c.regs().r12 }
+func (c *sigctxt) r13() uint64 { return c.regs().r13 }
+func (c *sigctxt) r14() uint64 { return c.regs().r14 }
+func (c *sigctxt) r15() uint64 { return c.regs().r15 }
+func (c *sigctxt) rip() uint64 { return c.regs().rip }
+func (c *sigctxt) rflags() uint64 { return uint64(c.regs().rflags) }
+func (c *sigctxt) cs() uint64 { return ^uint64(0) }
+func (c *sigctxt) fs() uint64 { return ^uint64(0) }
+func (c *sigctxt) gs() uint64 { return ^uint64(0) }
+func (c *sigctxt) sigcode() uint64 { return ^uint64(0) }
+func (c *sigctxt) sigaddr() uint64 { return 0 }
+
+func (c *sigctxt) set_rip(x uint64) { c.regs().rip = x }
+func (c *sigctxt) set_rsp(x uint64) { c.regs().rsp = x }
+func (c *sigctxt) set_sigcode(x uint64) {}
+func (c *sigctxt) set_sigaddr(x uint64) {}
diff --git a/src/runtime/signal_nacl_amd64p32.h b/src/runtime/signal_nacl_amd64p32.h
deleted file mode 100644
index f62305cb5..000000000
--- a/src/runtime/signal_nacl_amd64p32.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2013 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.
-
-#define SIG_REGS(ctxt) (((ExcContext*)(ctxt))->regs.regs64)
-
-#define SIG_RAX(info, ctxt) (SIG_REGS(ctxt).rax)
-#define SIG_RBX(info, ctxt) (SIG_REGS(ctxt).rbx)
-#define SIG_RCX(info, ctxt) (SIG_REGS(ctxt).rcx)
-#define SIG_RDX(info, ctxt) (SIG_REGS(ctxt).rdx)
-#define SIG_RDI(info, ctxt) (SIG_REGS(ctxt).rdi)
-#define SIG_RSI(info, ctxt) (SIG_REGS(ctxt).rsi)
-#define SIG_RBP(info, ctxt) (SIG_REGS(ctxt).rbp)
-#define SIG_RSP(info, ctxt) (SIG_REGS(ctxt).rsp)
-#define SIG_R8(info, ctxt) (SIG_REGS(ctxt).r8)
-#define SIG_R9(info, ctxt) (SIG_REGS(ctxt).r9)
-#define SIG_R10(info, ctxt) (SIG_REGS(ctxt).r10)
-#define SIG_R11(info, ctxt) (SIG_REGS(ctxt).r11)
-#define SIG_R12(info, ctxt) (SIG_REGS(ctxt).r12)
-#define SIG_R13(info, ctxt) (SIG_REGS(ctxt).r13)
-#define SIG_R14(info, ctxt) (SIG_REGS(ctxt).r14)
-#define SIG_R15(info, ctxt) (SIG_REGS(ctxt).r15)
-#define SIG_RIP(info, ctxt) (SIG_REGS(ctxt).rip)
-#define SIG_RFLAGS(info, ctxt) (SIG_REGS(ctxt).rflags)
-
-#define SIG_CS(info, ctxt) (~0)
-#define SIG_FS(info, ctxt) (~0)
-#define SIG_GS(info, ctxt) (~0)
-
-#define SIG_CODE0(info, ctxt) (~0)
-#define SIG_CODE1(info, ctxt) (0)
diff --git a/src/runtime/signal_nacl_arm.go b/src/runtime/signal_nacl_arm.go
new file mode 100644
index 000000000..1aeaa4e42
--- /dev/null
+++ b/src/runtime/signal_nacl_arm.go
@@ -0,0 +1,47 @@
+// Copyright 2014 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 "unsafe"
+
+type sigctxt struct {
+ info *siginfo
+ ctxt unsafe.Pointer
+}
+
+func (c *sigctxt) regs() *excregsarm { return &(*exccontext)(c.ctxt).regs }
+
+func (c *sigctxt) r0() uint32 { return c.regs().r0 }
+func (c *sigctxt) r1() uint32 { return c.regs().r1 }
+func (c *sigctxt) r2() uint32 { return c.regs().r2 }
+func (c *sigctxt) r3() uint32 { return c.regs().r3 }
+func (c *sigctxt) r4() uint32 { return c.regs().r4 }
+func (c *sigctxt) r5() uint32 { return c.regs().r5 }
+func (c *sigctxt) r6() uint32 { return c.regs().r6 }
+func (c *sigctxt) r7() uint32 { return c.regs().r7 }
+func (c *sigctxt) r8() uint32 { return c.regs().r8 }
+func (c *sigctxt) r9() uint32 { return c.regs().r9 }
+func (c *sigctxt) r10() uint32 { return c.regs().r10 }
+func (c *sigctxt) fp() uint32 { return c.regs().r11 }
+func (c *sigctxt) ip() uint32 { return c.regs().r12 }
+func (c *sigctxt) sp() uint32 { return c.regs().sp }
+func (c *sigctxt) lr() uint32 { return c.regs().lr }
+func (c *sigctxt) pc() uint32 { return c.regs().pc }
+func (c *sigctxt) cpsr() uint32 { return c.regs().cpsr }
+func (c *sigctxt) fault() uint32 { return ^uint32(0) }
+func (c *sigctxt) trap() uint32 { return ^uint32(0) }
+func (c *sigctxt) error() uint32 { return ^uint32(0) }
+func (c *sigctxt) oldmask() uint32 { return ^uint32(0) }
+
+func (c *sigctxt) sigcode() uint32 { return 0 }
+func (c *sigctxt) sigaddr() uint32 { return 0 }
+
+func (c *sigctxt) set_pc(x uint32) { c.regs().pc = x }
+func (c *sigctxt) set_sp(x uint32) { c.regs().sp = x }
+func (c *sigctxt) set_lr(x uint32) { c.regs().lr = x }
+func (c *sigctxt) set_r10(x uint32) { c.regs().r10 = x }
+
+func (c *sigctxt) set_sigcode(x uint32) {}
+func (c *sigctxt) set_sigaddr(x uint32) {}
diff --git a/src/runtime/signal_nacl_arm.h b/src/runtime/signal_nacl_arm.h
deleted file mode 100644
index e5bbb211d..000000000
--- a/src/runtime/signal_nacl_arm.h
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2014 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.
-
-#define SIG_REGS(ctxt) (((ExcContext*)(ctxt))->regs)
-
-#define SIG_R0(info, ctxt) (SIG_REGS(ctxt).r0)
-#define SIG_R1(info, ctxt) (SIG_REGS(ctxt).r1)
-#define SIG_R2(info, ctxt) (SIG_REGS(ctxt).r2)
-#define SIG_R3(info, ctxt) (SIG_REGS(ctxt).r3)
-#define SIG_R4(info, ctxt) (SIG_REGS(ctxt).r4)
-#define SIG_R5(info, ctxt) (SIG_REGS(ctxt).r5)
-#define SIG_R6(info, ctxt) (SIG_REGS(ctxt).r6)
-#define SIG_R7(info, ctxt) (SIG_REGS(ctxt).r7)
-#define SIG_R8(info, ctxt) (SIG_REGS(ctxt).r8)
-#define SIG_R9(info, ctxt) (SIG_REGS(ctxt).r9)
-#define SIG_R10(info, ctxt) (SIG_REGS(ctxt).r10)
-#define SIG_FP(info, ctxt) (SIG_REGS(ctxt).r11)
-#define SIG_IP(info, ctxt) (SIG_REGS(ctxt).r12)
-#define SIG_SP(info, ctxt) (SIG_REGS(ctxt).sp)
-#define SIG_LR(info, ctxt) (SIG_REGS(ctxt).lr)
-#define SIG_PC(info, ctxt) (SIG_REGS(ctxt).pc)
-#define SIG_CPSR(info, ctxt) (SIG_REGS(ctxt).cpsr)
-#define SIG_FAULT(info, ctxt) (~0)
-#define SIG_TRAP(info, ctxt) (~0)
-#define SIG_ERROR(info, ctxt) (~0)
-#define SIG_OLDMASK(info, ctxt) (~0)
-#define SIG_CODE0(info, ctxt) (~0)
diff --git a/src/runtime/signal_netbsd.go b/src/runtime/signal_netbsd.go
new file mode 100644
index 000000000..78afc59ef
--- /dev/null
+++ b/src/runtime/signal_netbsd.go
@@ -0,0 +1,46 @@
+// 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
+
+type sigTabT struct {
+ flags int32
+ name string
+}
+
+var sigtable = [...]sigTabT{
+ /* 0 */ {0, "SIGNONE: no trap"},
+ /* 1 */ {_SigNotify + _SigKill, "SIGHUP: terminal line hangup"},
+ /* 2 */ {_SigNotify + _SigKill, "SIGINT: interrupt"},
+ /* 3 */ {_SigNotify + _SigThrow, "SIGQUIT: quit"},
+ /* 4 */ {_SigThrow, "SIGILL: illegal instruction"},
+ /* 5 */ {_SigThrow, "SIGTRAP: trace trap"},
+ /* 6 */ {_SigNotify + _SigThrow, "SIGABRT: abort"},
+ /* 7 */ {_SigThrow, "SIGEMT: emulate instruction executed"},
+ /* 8 */ {_SigPanic, "SIGFPE: floating-point exception"},
+ /* 9 */ {0, "SIGKILL: kill"},
+ /* 10 */ {_SigPanic, "SIGBUS: bus error"},
+ /* 11 */ {_SigPanic, "SIGSEGV: segmentation violation"},
+ /* 12 */ {_SigThrow, "SIGSYS: bad system call"},
+ /* 13 */ {_SigNotify, "SIGPIPE: write to broken pipe"},
+ /* 14 */ {_SigNotify, "SIGALRM: alarm clock"},
+ /* 15 */ {_SigNotify + _SigKill, "SIGTERM: termination"},
+ /* 16 */ {_SigNotify, "SIGURG: urgent condition on socket"},
+ /* 17 */ {0, "SIGSTOP: stop"},
+ /* 18 */ {_SigNotify + _SigDefault, "SIGTSTP: keyboard stop"},
+ /* 19 */ {0, "SIGCONT: continue after stop"},
+ /* 20 */ {_SigNotify, "SIGCHLD: child status has changed"},
+ /* 21 */ {_SigNotify + _SigDefault, "SIGTTIN: background read from tty"},
+ /* 22 */ {_SigNotify + _SigDefault, "SIGTTOU: background write to tty"},
+ /* 23 */ {_SigNotify, "SIGIO: i/o now possible"},
+ /* 24 */ {_SigNotify, "SIGXCPU: cpu limit exceeded"},
+ /* 25 */ {_SigNotify, "SIGXFSZ: file size limit exceeded"},
+ /* 26 */ {_SigNotify, "SIGVTALRM: virtual alarm clock"},
+ /* 27 */ {_SigNotify, "SIGPROF: profiling alarm clock"},
+ /* 28 */ {_SigNotify, "SIGWINCH: window size change"},
+ /* 29 */ {_SigNotify, "SIGINFO: status request from keyboard"},
+ /* 30 */ {_SigNotify, "SIGUSR1: user-defined signal 1"},
+ /* 31 */ {_SigNotify, "SIGUSR2: user-defined signal 2"},
+ /* 32 */ {_SigNotify, "SIGTHR: reserved"},
+}
diff --git a/src/runtime/signal_netbsd_386.go b/src/runtime/signal_netbsd_386.go
new file mode 100644
index 000000000..6702336ab
--- /dev/null
+++ b/src/runtime/signal_netbsd_386.go
@@ -0,0 +1,38 @@
+// Copyright 2013 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 "unsafe"
+
+type sigctxt struct {
+ info *siginfo
+ ctxt unsafe.Pointer
+}
+
+func (c *sigctxt) regs() *mcontextt { return &(*ucontextt)(c.ctxt).uc_mcontext }
+func (c *sigctxt) eax() uint32 { return c.regs().__gregs[_REG_EAX] }
+func (c *sigctxt) ebx() uint32 { return c.regs().__gregs[_REG_EBX] }
+func (c *sigctxt) ecx() uint32 { return c.regs().__gregs[_REG_ECX] }
+func (c *sigctxt) edx() uint32 { return c.regs().__gregs[_REG_EDX] }
+func (c *sigctxt) edi() uint32 { return c.regs().__gregs[_REG_EDI] }
+func (c *sigctxt) esi() uint32 { return c.regs().__gregs[_REG_ESI] }
+func (c *sigctxt) ebp() uint32 { return c.regs().__gregs[_REG_EBP] }
+func (c *sigctxt) esp() uint32 { return c.regs().__gregs[_REG_UESP] }
+func (c *sigctxt) eip() uint32 { return c.regs().__gregs[_REG_EIP] }
+func (c *sigctxt) eflags() uint32 { return c.regs().__gregs[_REG_EFL] }
+func (c *sigctxt) cs() uint32 { return uint32(c.regs().__gregs[_REG_CS]) }
+func (c *sigctxt) fs() uint32 { return uint32(c.regs().__gregs[_REG_FS]) }
+func (c *sigctxt) gs() uint32 { return uint32(c.regs().__gregs[_REG_GS]) }
+func (c *sigctxt) sigcode() uint32 { return uint32(c.info._code) }
+func (c *sigctxt) sigaddr() uint32 {
+ return uint32(*(*uint32)(unsafe.Pointer(&c.info._reason[0])))
+}
+
+func (c *sigctxt) set_eip(x uint32) { c.regs().__gregs[_REG_EIP] = x }
+func (c *sigctxt) set_esp(x uint32) { c.regs().__gregs[_REG_UESP] = x }
+func (c *sigctxt) set_sigcode(x uint32) { c.info._code = int32(x) }
+func (c *sigctxt) set_sigaddr(x uint32) {
+ *(*uint32)(unsafe.Pointer(&c.info._reason[0])) = x
+}
diff --git a/src/runtime/signal_netbsd_386.h b/src/runtime/signal_netbsd_386.h
deleted file mode 100644
index d5a8a0c4b..000000000
--- a/src/runtime/signal_netbsd_386.h
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2013 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.
-
-#define SIG_REGS(ctxt) (((UcontextT*)(ctxt))->uc_mcontext)
-
-#define SIG_EAX(info, ctxt) (SIG_REGS(ctxt).__gregs[REG_EAX])
-#define SIG_EBX(info, ctxt) (SIG_REGS(ctxt).__gregs[REG_EBX])
-#define SIG_ECX(info, ctxt) (SIG_REGS(ctxt).__gregs[REG_ECX])
-#define SIG_EDX(info, ctxt) (SIG_REGS(ctxt).__gregs[REG_EDX])
-#define SIG_EDI(info, ctxt) (SIG_REGS(ctxt).__gregs[REG_EDI])
-#define SIG_ESI(info, ctxt) (SIG_REGS(ctxt).__gregs[REG_ESI])
-#define SIG_EBP(info, ctxt) (SIG_REGS(ctxt).__gregs[REG_EBP])
-#define SIG_ESP(info, ctxt) (SIG_REGS(ctxt).__gregs[REG_UESP])
-#define SIG_EIP(info, ctxt) (SIG_REGS(ctxt).__gregs[REG_EIP])
-#define SIG_EFLAGS(info, ctxt) (SIG_REGS(ctxt).__gregs[REG_EFL])
-
-#define SIG_CS(info, ctxt) (SIG_REGS(ctxt).__gregs[REG_CS])
-#define SIG_FS(info, ctxt) (SIG_REGS(ctxt).__gregs[REG_FS])
-#define SIG_GS(info, ctxt) (SIG_REGS(ctxt).__gregs[REG_GS])
-
-#define SIG_CODE0(info, ctxt) ((info)->_code)
-#define SIG_CODE1(info, ctxt) (*(uintptr*)&(info)->_reason[0])
diff --git a/src/runtime/signal_netbsd_amd64.go b/src/runtime/signal_netbsd_amd64.go
new file mode 100644
index 000000000..e22f4a724
--- /dev/null
+++ b/src/runtime/signal_netbsd_amd64.go
@@ -0,0 +1,48 @@
+// Copyright 2013 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 "unsafe"
+
+type sigctxt struct {
+ info *siginfo
+ ctxt unsafe.Pointer
+}
+
+func (c *sigctxt) regs() *mcontextt {
+ return (*mcontextt)(unsafe.Pointer(&(*ucontextt)(c.ctxt).uc_mcontext))
+}
+func (c *sigctxt) rax() uint64 { return c.regs().__gregs[_REG_RAX] }
+func (c *sigctxt) rbx() uint64 { return c.regs().__gregs[_REG_RBX] }
+func (c *sigctxt) rcx() uint64 { return c.regs().__gregs[_REG_RCX] }
+func (c *sigctxt) rdx() uint64 { return c.regs().__gregs[_REG_RDX] }
+func (c *sigctxt) rdi() uint64 { return c.regs().__gregs[_REG_RDI] }
+func (c *sigctxt) rsi() uint64 { return c.regs().__gregs[_REG_RSI] }
+func (c *sigctxt) rbp() uint64 { return c.regs().__gregs[_REG_RBP] }
+func (c *sigctxt) rsp() uint64 { return c.regs().__gregs[_REG_RSP] }
+func (c *sigctxt) r8() uint64 { return c.regs().__gregs[_REG_R8] }
+func (c *sigctxt) r9() uint64 { return c.regs().__gregs[_REG_R8] }
+func (c *sigctxt) r10() uint64 { return c.regs().__gregs[_REG_R10] }
+func (c *sigctxt) r11() uint64 { return c.regs().__gregs[_REG_R11] }
+func (c *sigctxt) r12() uint64 { return c.regs().__gregs[_REG_R12] }
+func (c *sigctxt) r13() uint64 { return c.regs().__gregs[_REG_R13] }
+func (c *sigctxt) r14() uint64 { return c.regs().__gregs[_REG_R14] }
+func (c *sigctxt) r15() uint64 { return c.regs().__gregs[_REG_R15] }
+func (c *sigctxt) rip() uint64 { return c.regs().__gregs[_REG_RIP] }
+func (c *sigctxt) rflags() uint64 { return c.regs().__gregs[_REG_RFLAGS] }
+func (c *sigctxt) cs() uint64 { return c.regs().__gregs[_REG_CS] }
+func (c *sigctxt) fs() uint64 { return c.regs().__gregs[_REG_FS] }
+func (c *sigctxt) gs() uint64 { return c.regs().__gregs[_REG_GS] }
+func (c *sigctxt) sigcode() uint64 { return uint64(c.info._code) }
+func (c *sigctxt) sigaddr() uint64 {
+ return uint64(*(*uint64)(unsafe.Pointer(&c.info._reason[0])))
+}
+
+func (c *sigctxt) set_rip(x uint64) { c.regs().__gregs[_REG_RIP] = x }
+func (c *sigctxt) set_rsp(x uint64) { c.regs().__gregs[_REG_RSP] = x }
+func (c *sigctxt) set_sigcode(x uint64) { c.info._code = int32(x) }
+func (c *sigctxt) set_sigaddr(x uint64) {
+ *(*uint64)(unsafe.Pointer(&c.info._reason[0])) = x
+}
diff --git a/src/runtime/signal_netbsd_amd64.h b/src/runtime/signal_netbsd_amd64.h
deleted file mode 100644
index 7ec4cd98c..000000000
--- a/src/runtime/signal_netbsd_amd64.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2013 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.
-
-#define SIG_REGS(ctxt) (((UcontextT*)(ctxt))->uc_mcontext)
-
-#define SIG_RAX(info, ctxt) (SIG_REGS(ctxt).__gregs[REG_RAX])
-#define SIG_RBX(info, ctxt) (SIG_REGS(ctxt).__gregs[REG_RBX])
-#define SIG_RCX(info, ctxt) (SIG_REGS(ctxt).__gregs[REG_RCX])
-#define SIG_RDX(info, ctxt) (SIG_REGS(ctxt).__gregs[REG_RDX])
-#define SIG_RDI(info, ctxt) (SIG_REGS(ctxt).__gregs[REG_RDI])
-#define SIG_RSI(info, ctxt) (SIG_REGS(ctxt).__gregs[REG_RSI])
-#define SIG_RBP(info, ctxt) (SIG_REGS(ctxt).__gregs[REG_RBP])
-#define SIG_RSP(info, ctxt) (SIG_REGS(ctxt).__gregs[REG_RSP])
-#define SIG_R8(info, ctxt) (SIG_REGS(ctxt).__gregs[REG_R8])
-#define SIG_R9(info, ctxt) (SIG_REGS(ctxt).__gregs[REG_R9])
-#define SIG_R10(info, ctxt) (SIG_REGS(ctxt).__gregs[REG_R10])
-#define SIG_R11(info, ctxt) (SIG_REGS(ctxt).__gregs[REG_R11])
-#define SIG_R12(info, ctxt) (SIG_REGS(ctxt).__gregs[REG_R12])
-#define SIG_R13(info, ctxt) (SIG_REGS(ctxt).__gregs[REG_R13])
-#define SIG_R14(info, ctxt) (SIG_REGS(ctxt).__gregs[REG_R14])
-#define SIG_R15(info, ctxt) (SIG_REGS(ctxt).__gregs[REG_R15])
-#define SIG_RIP(info, ctxt) (SIG_REGS(ctxt).__gregs[REG_RIP])
-#define SIG_RFLAGS(info, ctxt) (SIG_REGS(ctxt).__gregs[REG_RFLAGS])
-
-#define SIG_CS(info, ctxt) (SIG_REGS(ctxt).__gregs[REG_CS])
-#define SIG_FS(info, ctxt) (SIG_REGS(ctxt).__gregs[REG_FS])
-#define SIG_GS(info, ctxt) (SIG_REGS(ctxt).__gregs[REG_GS])
-
-#define SIG_CODE0(info, ctxt) ((info)->_code)
-#define SIG_CODE1(info, ctxt) (*(uintptr*)&(info)->_reason[0])
diff --git a/src/runtime/signals_plan9.h b/src/runtime/signal_plan9.go
index 4ee8e542c..37d24359b 100644
--- a/src/runtime/signals_plan9.h
+++ b/src/runtime/signal_plan9.go
@@ -2,62 +2,53 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-#include "textflag.h"
+package runtime
-#define N SigNotify
-#define K SigKill
-#define T SigThrow
-#define P SigPanic
-#define E SigGoExit
+type sigTabT struct {
+ flags int
+ name []byte
+}
// Incoming notes are compared against this table using strncmp, so the
// order matters: longer patterns must appear before their prefixes.
-// There are #defined SIG constants in os_plan9.h for the table index of
-// some of these.
+// There are _SIG constants in os2_plan9.go for the table index of some
+// of these.
//
// If you add entries to this table, you must respect the prefix ordering
-// and also update the constant values is os_plan9.h.
-
-#pragma dataflag NOPTR
-SigTab runtime·sigtab[] = {
+// and also update the constant values is os2_plan9.go.
+var sigtable = [...]sigTabT{
// Traps that we cannot be recovered.
- T, "sys: trap: debug exception",
- T, "sys: trap: invalid opcode",
+ {_SigThrow, []byte("sys: trap: debug exception")},
+ {_SigThrow, []byte("sys: trap: invalid opcode")},
// We can recover from some memory errors in runtime·sigpanic.
- P, "sys: trap: fault read addr", // SIGRFAULT
- P, "sys: trap: fault write addr", // SIGWFAULT
+ {_SigPanic, []byte("sys: trap: fault read addr")}, // SIGRFAULT
+ {_SigPanic, []byte("sys: trap: fault write addr")}, // SIGWFAULT
// We can also recover from math errors.
- P, "sys: trap: divide error", // SIGINTDIV
- P, "sys: fp:", // SIGFLOAT
+ {_SigPanic, []byte("sys: trap: divide error")}, // SIGINTDIV
+ {_SigPanic, []byte("sys: fp:")}, // SIGFLOAT
// All other traps are normally handled as if they were marked SigThrow.
// We mark them SigPanic here so that debug.SetPanicOnFault will work.
- P, "sys: trap:", // SIGTRAP
+ {_SigPanic, []byte("sys: trap:")}, // SIGTRAP
// Writes to a closed pipe can be handled if desired, otherwise they're ignored.
- N, "sys: write on closed pipe",
+ {_SigNotify, []byte("sys: write on closed pipe")},
// Other system notes are more serious and cannot be recovered.
- T, "sys:",
+ {_SigThrow, []byte("sys:")},
// Issued to all other procs when calling runtime·exit.
- E, "go: exit ",
+ {_SigGoExit, []byte("go: exit ")},
// Kill is sent by external programs to cause an exit.
- K, "kill",
+ {_SigKill, []byte("kill")},
// Interrupts can be handled if desired, otherwise they cause an exit.
- N+K, "interrupt",
- N+K, "hangup",
+ {_SigNotify + _SigKill, []byte("interrupt")},
+ {_SigNotify + _SigKill, []byte("hangup")},
// Alarms can be handled if desired, otherwise they're ignored.
- N, "alarm",
-};
-
-#undef N
-#undef K
-#undef T
-#undef P
-#undef E
+ {_SigNotify, []byte("alarm")},
+}
diff --git a/src/runtime/signal_power64x.c b/src/runtime/signal_power64x.c
deleted file mode 100644
index c0bf1c4a5..000000000
--- a/src/runtime/signal_power64x.c
+++ /dev/null
@@ -1,137 +0,0 @@
-// Copyright 2014 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.
-
-// +build linux
-// +build power64 power64le
-
-#include "runtime.h"
-#include "defs_GOOS_GOARCH.h"
-#include "os_GOOS.h"
-#include "signal_GOOS_GOARCH.h"
-#include "signals_GOOS.h"
-
-void
-runtime·dumpregs(Siginfo *info, void *ctxt)
-{
- USED(info); USED(ctxt);
- runtime·printf("r0 %X\t", SIG_R0(info, ctxt));
- runtime·printf("r1 %X\n", SIG_R1(info, ctxt));
- runtime·printf("r2 %X\t", SIG_R2(info, ctxt));
- runtime·printf("r3 %X\n", SIG_R3(info, ctxt));
- runtime·printf("r4 %X\t", SIG_R4(info, ctxt));
- runtime·printf("r5 %X\n", SIG_R5(info, ctxt));
- runtime·printf("r6 %X\t", SIG_R6(info, ctxt));
- runtime·printf("r7 %X\n", SIG_R7(info, ctxt));
- runtime·printf("r8 %X\t", SIG_R8(info, ctxt));
- runtime·printf("r9 %X\n", SIG_R9(info, ctxt));
- runtime·printf("r10 %X\t", SIG_R10(info, ctxt));
- runtime·printf("r11 %X\n", SIG_R11(info, ctxt));
- runtime·printf("r12 %X\t", SIG_R12(info, ctxt));
- runtime·printf("r13 %X\n", SIG_R13(info, ctxt));
- runtime·printf("r14 %X\t", SIG_R14(info, ctxt));
- runtime·printf("r15 %X\n", SIG_R15(info, ctxt));
- runtime·printf("r16 %X\t", SIG_R16(info, ctxt));
- runtime·printf("r17 %X\n", SIG_R17(info, ctxt));
- runtime·printf("r18 %X\t", SIG_R18(info, ctxt));
- runtime·printf("r19 %X\n", SIG_R19(info, ctxt));
- runtime·printf("r20 %X\t", SIG_R20(info, ctxt));
- runtime·printf("r21 %X\n", SIG_R21(info, ctxt));
- runtime·printf("r22 %X\t", SIG_R22(info, ctxt));
- runtime·printf("r23 %X\n", SIG_R23(info, ctxt));
- runtime·printf("r24 %X\t", SIG_R24(info, ctxt));
- runtime·printf("r25 %X\n", SIG_R25(info, ctxt));
- runtime·printf("r26 %X\t", SIG_R26(info, ctxt));
- runtime·printf("r27 %X\n", SIG_R27(info, ctxt));
- runtime·printf("r28 %X\t", SIG_R28(info, ctxt));
- runtime·printf("r29 %X\n", SIG_R29(info, ctxt));
- runtime·printf("r30 %X\t", SIG_R30(info, ctxt));
- runtime·printf("r31 %X\n", SIG_R31(info, ctxt));
- runtime·printf("pc %X\t", SIG_PC(info, ctxt));
- runtime·printf("ctr %X\n", SIG_CTR(info, ctxt));
- runtime·printf("link %X\t", SIG_LINK(info, ctxt));
- runtime·printf("xer %X\n", SIG_XER(info, ctxt));
- runtime·printf("ccr %X\t", SIG_CCR(info, ctxt));
- runtime·printf("trap %X\n", SIG_TRAP(info, ctxt));
-}
-
-void
-runtime·sighandler(int32 sig, Siginfo *info, void *ctxt, G *gp)
-{
- SigTab *t;
- bool crash;
-
- if(sig == SIGPROF) {
- runtime·sigprof((uint8*)SIG_PC(info, ctxt), (uint8*)SIG_SP(info, ctxt), (uint8*)SIG_LINK(info, ctxt), gp, g->m);
- return;
- }
- t = &runtime·sigtab[sig];
- if(SIG_CODE0(info, ctxt) != SI_USER && (t->flags & SigPanic)) {
- // 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 = sig;
- gp->sigcode0 = SIG_CODE0(info, ctxt);
- gp->sigcode1 = SIG_FAULT(info, ctxt);
- gp->sigpc = SIG_PC(info, ctxt);
-
- // We arrange link, and pc to pretend the panicking
- // function calls sigpanic directly.
- // Always save LINK to stack so that panics in leaf
- // functions are correctly handled. This smashes
- // the stack frame but we're not going back there
- // anyway.
- SIG_SP(info, ctxt) -= sizeof(uintptr);
- *(uintptr*)SIG_SP(info, ctxt) = SIG_LINK(info, ctxt);
- // Don't bother saving PC if it's zero, which is
- // probably a call to a nil func: the old link register
- // is more useful in the stack trace.
- if(gp->sigpc != 0)
- SIG_LINK(info, ctxt) = gp->sigpc;
- // In case we are panicking from external C code
- SIG_R0(info, ctxt) = 0;
- SIG_R30(info, ctxt) = (uintptr)gp;
- SIG_PC(info, ctxt) = (uintptr)runtime·sigpanic;
- return;
- }
-
- if(SIG_CODE0(info, ctxt) == SI_USER || (t->flags & SigNotify))
- if(runtime·sigsend(sig))
- return;
- if(t->flags & SigKill)
- runtime·exit(2);
- if(!(t->flags & SigThrow))
- return;
-
- g->m->throwing = 1;
- g->m->caughtsig = gp;
- if(runtime·panicking) // traceback already printed
- runtime·exit(2);
- runtime·panicking = 1;
-
- if(sig < 0 || sig >= NSIG)
- runtime·printf("Signal %d\n", sig);
- else
- runtime·printf("%s\n", runtime·sigtab[sig].name);
-
- runtime·printf("PC=%x\n", SIG_PC(info, ctxt));
- if(g->m->lockedg != nil && g->m->ncgo > 0 && gp == g->m->g0) {
- runtime·printf("signal arrived during cgo execution\n");
- gp = g->m->lockedg;
- }
- runtime·printf("\n");
-
- if(runtime·gotraceback(&crash)){
- runtime·goroutineheader(gp);
- runtime·tracebacktrap(SIG_PC(info, ctxt), SIG_SP(info, ctxt), SIG_LINK(info, ctxt), gp);
- runtime·tracebackothers(gp);
- runtime·printf("\n");
- runtime·dumpregs(info, ctxt);
- }
-
- if(crash)
- runtime·crash();
-
- runtime·exit(2);
-}
diff --git a/src/runtime/signal_power64x.go b/src/runtime/signal_power64x.go
new file mode 100644
index 000000000..fc83beb1b
--- /dev/null
+++ b/src/runtime/signal_power64x.go
@@ -0,0 +1,144 @@
+// Copyright 2014 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.
+
+// +build linux
+// +build power64 power64le
+
+package runtime
+
+import "unsafe"
+
+func dumpregs(c *sigctxt) {
+ print("r0 ", hex(c.r0()), "\t")
+ print("r1 ", hex(c.r1()), "\n")
+ print("r2 ", hex(c.r2()), "\t")
+ print("r3 ", hex(c.r3()), "\n")
+ print("r4 ", hex(c.r4()), "\t")
+ print("r5 ", hex(c.r5()), "\n")
+ print("r6 ", hex(c.r6()), "\t")
+ print("r7 ", hex(c.r7()), "\n")
+ print("r8 ", hex(c.r8()), "\t")
+ print("r9 ", hex(c.r9()), "\n")
+ print("r10 ", hex(c.r10()), "\t")
+ print("r11 ", hex(c.r11()), "\n")
+ print("r12 ", hex(c.r12()), "\t")
+ print("r13 ", hex(c.r13()), "\n")
+ print("r14 ", hex(c.r14()), "\t")
+ print("r15 ", hex(c.r15()), "\n")
+ print("r16 ", hex(c.r16()), "\t")
+ print("r17 ", hex(c.r17()), "\n")
+ print("r18 ", hex(c.r18()), "\t")
+ print("r19 ", hex(c.r19()), "\n")
+ print("r20 ", hex(c.r20()), "\t")
+ print("r21 ", hex(c.r21()), "\n")
+ print("r22 ", hex(c.r22()), "\t")
+ print("r23 ", hex(c.r23()), "\n")
+ print("r24 ", hex(c.r24()), "\t")
+ print("r25 ", hex(c.r25()), "\n")
+ print("r26 ", hex(c.r26()), "\t")
+ print("r27 ", hex(c.r27()), "\n")
+ print("r28 ", hex(c.r28()), "\t")
+ print("r29 ", hex(c.r29()), "\n")
+ print("r30 ", hex(c.r30()), "\t")
+ print("r31 ", hex(c.r31()), "\n")
+ print("pc ", hex(c.pc()), "\t")
+ print("ctr ", hex(c.ctr()), "\n")
+ print("link ", hex(c.link()), "\t")
+ print("xer ", hex(c.xer()), "\n")
+ print("ccr ", hex(c.ccr()), "\t")
+ print("trap ", hex(c.trap()), "\n")
+}
+
+func sighandler(sig uint32, info *siginfo, ctxt unsafe.Pointer, gp *g) {
+ _g_ := getg()
+ c := &sigctxt{info, ctxt}
+
+ if sig == _SIGPROF {
+ sigprof((*byte)(unsafe.Pointer(uintptr(c.pc()))), (*byte)(unsafe.Pointer(uintptr(c.sp()))), (*byte)(unsafe.Pointer(uintptr(c.link()))), gp, _g_.m)
+ return
+ }
+ flags := int32(_SigThrow)
+ if sig < uint32(len(sigtable)) {
+ flags = sigtable[sig].flags
+ }
+ if c.sigcode() != _SI_USER && flags&_SigPanic != 0 {
+ // 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 = sig
+ gp.sigcode0 = uintptr(c.sigcode())
+ gp.sigcode1 = uintptr(c.fault())
+ gp.sigpc = uintptr(c.pc())
+
+ // We arrange link, and pc to pretend the panicking
+ // function calls sigpanic directly.
+ // Always save LINK to stack so that panics in leaf
+ // functions are correctly handled. This smashes
+ // the stack frame but we're not going back there
+ // anyway.
+ sp := c.sp() - ptrSize
+ c.set_sp(sp)
+ *(*uint64)(unsafe.Pointer(uintptr(sp))) = c.link()
+
+ // Don't bother saving PC if it's zero, which is
+ // probably a call to a nil func: the old link register
+ // is more useful in the stack trace.
+ if gp.sigpc != 0 {
+ c.set_link(uint64(gp.sigpc))
+ }
+
+ // In case we are panicking from external C code
+ c.set_r0(0)
+ c.set_r30(uint64(uintptr(unsafe.Pointer(gp))))
+ c.set_pc(uint64(funcPC(sigpanic)))
+ return
+ }
+
+ if c.sigcode() == _SI_USER || flags&_SigNotify != 0 {
+ if sigsend(sig) {
+ return
+ }
+ }
+
+ if flags&_SigKill != 0 {
+ exit(2)
+ }
+
+ if flags&_SigThrow == 0 {
+ return
+ }
+
+ _g_.m.throwing = 1
+ _g_.m.caughtsig = gp
+ startpanic()
+
+ if sig < uint32(len(sigtable)) {
+ print(sigtable[sig].name, "\n")
+ } else {
+ print("Signal ", sig, "\n")
+ }
+
+ print("PC=", hex(c.pc()), "\n")
+ if _g_.m.lockedg != nil && _g_.m.ncgo > 0 && gp == _g_.m.g0 {
+ print("signal arrived during cgo execution\n")
+ gp = _g_.m.lockedg
+ }
+ print("\n")
+
+ var docrash bool
+ if gotraceback(&docrash) > 0 {
+ goroutineheader(gp)
+ tracebacktrap(uintptr(c.pc()), uintptr(c.sp()), uintptr(c.link()), gp)
+ tracebackothers(gp)
+ print("\n")
+ dumpregs(c)
+ }
+
+ if docrash {
+ crash()
+ }
+
+ exit(2)
+}
diff --git a/src/runtime/signals_android.h b/src/runtime/signals_android.h
deleted file mode 100644
index 5140d8a18..000000000
--- a/src/runtime/signals_android.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "signals_linux.h"
diff --git a/src/runtime/signals_nacl.h b/src/runtime/signals_nacl.h
deleted file mode 100644
index 8761e1bd9..000000000
--- a/src/runtime/signals_nacl.h
+++ /dev/null
@@ -1,53 +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.
-
-#include "textflag.h"
-
-#define N SigNotify
-#define K SigKill
-#define T SigThrow
-#define P SigPanic
-#define D SigDefault
-
-#pragma dataflag NOPTR
-SigTab runtime·sigtab[] = {
- /* 0 */ 0, "SIGNONE: no trap",
- /* 1 */ N+K, "SIGHUP: terminal line hangup",
- /* 2 */ N+K, "SIGINT: interrupt",
- /* 3 */ N+T, "SIGQUIT: quit",
- /* 4 */ T, "SIGILL: illegal instruction",
- /* 5 */ T, "SIGTRAP: trace trap",
- /* 6 */ N+T, "SIGABRT: abort",
- /* 7 */ T, "SIGEMT: emulate instruction executed",
- /* 8 */ P, "SIGFPE: floating-point exception",
- /* 9 */ 0, "SIGKILL: kill",
- /* 10 */ P, "SIGBUS: bus error",
- /* 11 */ P, "SIGSEGV: segmentation violation",
- /* 12 */ T, "SIGSYS: bad system call",
- /* 13 */ N, "SIGPIPE: write to broken pipe",
- /* 14 */ N, "SIGALRM: alarm clock",
- /* 15 */ N+K, "SIGTERM: termination",
- /* 16 */ N, "SIGURG: urgent condition on socket",
- /* 17 */ 0, "SIGSTOP: stop",
- /* 18 */ N+D, "SIGTSTP: keyboard stop",
- /* 19 */ 0, "SIGCONT: continue after stop",
- /* 20 */ N, "SIGCHLD: child status has changed",
- /* 21 */ N+D, "SIGTTIN: background read from tty",
- /* 22 */ N+D, "SIGTTOU: background write to tty",
- /* 23 */ N, "SIGIO: i/o now possible",
- /* 24 */ N, "SIGXCPU: cpu limit exceeded",
- /* 25 */ N, "SIGXFSZ: file size limit exceeded",
- /* 26 */ N, "SIGVTALRM: virtual alarm clock",
- /* 27 */ N, "SIGPROF: profiling alarm clock",
- /* 28 */ N, "SIGWINCH: window size change",
- /* 29 */ N, "SIGINFO: status request from keyboard",
- /* 30 */ N, "SIGUSR1: user-defined signal 1",
- /* 31 */ N, "SIGUSR2: user-defined signal 2",
-};
-
-#undef N
-#undef K
-#undef T
-#undef P
-#undef D
diff --git a/src/runtime/signals_netbsd.h b/src/runtime/signals_netbsd.h
deleted file mode 100644
index 950a2fe62..000000000
--- a/src/runtime/signals_netbsd.h
+++ /dev/null
@@ -1,54 +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.
-
-#include "textflag.h"
-
-#define N SigNotify
-#define K SigKill
-#define T SigThrow
-#define P SigPanic
-#define D SigDefault
-
-#pragma dataflag NOPTR
-SigTab runtime·sigtab[] = {
- /* 0 */ 0, "SIGNONE: no trap",
- /* 1 */ N+K, "SIGHUP: terminal line hangup",
- /* 2 */ N+K, "SIGINT: interrupt",
- /* 3 */ N+T, "SIGQUIT: quit",
- /* 4 */ T, "SIGILL: illegal instruction",
- /* 5 */ T, "SIGTRAP: trace trap",
- /* 6 */ N+T, "SIGABRT: abort",
- /* 7 */ T, "SIGEMT: emulate instruction executed",
- /* 8 */ P, "SIGFPE: floating-point exception",
- /* 9 */ 0, "SIGKILL: kill",
- /* 10 */ P, "SIGBUS: bus error",
- /* 11 */ P, "SIGSEGV: segmentation violation",
- /* 12 */ T, "SIGSYS: bad system call",
- /* 13 */ N, "SIGPIPE: write to broken pipe",
- /* 14 */ N, "SIGALRM: alarm clock",
- /* 15 */ N+K, "SIGTERM: termination",
- /* 16 */ N, "SIGURG: urgent condition on socket",
- /* 17 */ 0, "SIGSTOP: stop",
- /* 18 */ N+D, "SIGTSTP: keyboard stop",
- /* 19 */ 0, "SIGCONT: continue after stop",
- /* 20 */ N, "SIGCHLD: child status has changed",
- /* 21 */ N+D, "SIGTTIN: background read from tty",
- /* 22 */ N+D, "SIGTTOU: background write to tty",
- /* 23 */ N, "SIGIO: i/o now possible",
- /* 24 */ N, "SIGXCPU: cpu limit exceeded",
- /* 25 */ N, "SIGXFSZ: file size limit exceeded",
- /* 26 */ N, "SIGVTALRM: virtual alarm clock",
- /* 27 */ N, "SIGPROF: profiling alarm clock",
- /* 28 */ N, "SIGWINCH: window size change",
- /* 29 */ N, "SIGINFO: status request from keyboard",
- /* 30 */ N, "SIGUSR1: user-defined signal 1",
- /* 31 */ N, "SIGUSR2: user-defined signal 2",
- /* 32 */ N, "SIGTHR: reserved",
-};
-
-#undef N
-#undef K
-#undef T
-#undef P
-#undef D
diff --git a/src/runtime/stack1.go b/src/runtime/stack1.go
index 57d0f8c65..c14347dbd 100644
--- a/src/runtime/stack1.go
+++ b/src/runtime/stack1.go
@@ -781,7 +781,7 @@ func shrinkstack(gp *g) {
if gp.syscallsp != 0 {
return
}
- if _Windows != 0 && gp.m != nil && gp.m.libcallsp != 0 {
+ if goos_windows != 0 && gp.m != nil && gp.m.libcallsp != 0 {
return
}
diff --git a/src/runtime/stack2.go b/src/runtime/stack2.go
index c3718c205..e50b32c78 100644
--- a/src/runtime/stack2.go
+++ b/src/runtime/stack2.go
@@ -59,7 +59,7 @@ const (
// to each stack below the usual guard area for OS-specific
// purposes like signal handling. Used on Windows and on
// Plan 9 because they do not use a separate stack.
- _StackSystem = _Windows*512*ptrSize + _Plan9*512
+ _StackSystem = goos_windows*512*ptrSize + goos_plan9*512
// The minimum size of stack used by Go code
_StackMin = 2048
diff --git a/src/runtime/stubs.go b/src/runtime/stubs.go
index 4063e5434..4408e22bf 100644
--- a/src/runtime/stubs.go
+++ b/src/runtime/stubs.go
@@ -154,7 +154,7 @@ func setcallerpc(argp unsafe.Pointer, pc uintptr)
//
// func f(arg1, arg2, arg3 int) {
// pc := getcallerpc(unsafe.Pointer(&arg1))
-// sp := getcallerpc(unsafe.Pointer(&arg2))
+// sp := getcallersp(unsafe.Pointer(&arg1))
// }
//
// These two lines find the PC and SP immediately following
diff --git a/src/runtime/stubs2.go b/src/runtime/stubs2.go
index 526b3c569..60751dd34 100644
--- a/src/runtime/stubs2.go
+++ b/src/runtime/stubs2.go
@@ -2,7 +2,10 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+// +build !plan9
// +build !solaris
+// +build !windows
+// +build !nacl
package runtime
diff --git a/src/runtime/arch_power64.h b/src/runtime/stubs3.go
index 7cfb9da2f..ffaa28775 100644
--- a/src/runtime/arch_power64.h
+++ b/src/runtime/stubs3.go
@@ -2,13 +2,11 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-enum {
- thechar = '9',
- BigEndian = 1,
- CacheLineSize = 64,
- RuntimeGogoBytes = 64,
- PhysPageSize = 65536,
- PCQuantum = 4,
- Int64Align = 8
-};
+// +build plan9
+package runtime
+
+func close(fd int32) int32
+
+//go:noescape
+func open(name *byte, mode, perm int32) int32
diff --git a/src/runtime/sys_linux_power64x.s b/src/runtime/sys_linux_power64x.s
index fb24d3e79..395f657bf 100644
--- a/src/runtime/sys_linux_power64x.s
+++ b/src/runtime/sys_linux_power64x.s
@@ -9,7 +9,8 @@
// System calls and other sys.stuff for Power64, Linux
//
-#include "zasm_GOOS_GOARCH.h"
+#include "go_asm.h"
+#include "go_tls.h"
#include "textflag.h"
#define SYS_exit 1
diff --git a/src/runtime/sys_power64x.c b/src/runtime/sys_power64x.c
deleted file mode 100644
index 79d976255..000000000
--- a/src/runtime/sys_power64x.c
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2014 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.
-
-// +build power64 power64le
-
-#include "runtime.h"
-
-// adjust Gobuf as if it executed a call to fn with context ctxt
-// and then did an immediate Gosave.
-void
-runtime·gostartcall(Gobuf *gobuf, void (*fn)(void), void *ctxt)
-{
- if(gobuf->lr != 0)
- runtime·throw("invalid use of gostartcall");
- gobuf->lr = gobuf->pc;
- gobuf->pc = (uintptr)fn;
- gobuf->ctxt = ctxt;
-}
-
-// Called to rewind context saved during morestack back to beginning of function.
-// To help us, the linker emits a jmp back to the beginning right after the
-// call to morestack. We just have to decode and apply that jump.
-void
-runtime·rewindmorestack(Gobuf *gobuf)
-{
- uint32 inst;
-
- inst = *(uint32*)gobuf->pc;
- if((gobuf->pc&3) == 0 && (inst>>24) == 0x4b && (inst&3) == 0) {
- //runtime·printf("runtime: rewind pc=%p to pc=%p\n", gobuf->pc, gobuf->pc + ((int32)(inst<<8)>>8));
- gobuf->pc += (int32)(inst<<8)>>8;
- return;
- }
- runtime·printf("runtime: pc=%p %x\n", gobuf->pc, inst);
- runtime·throw("runtime: misuse of rewindmorestack");
-}
-
diff --git a/src/runtime/sys_power64x.go b/src/runtime/sys_power64x.go
new file mode 100644
index 000000000..90ebde7b4
--- /dev/null
+++ b/src/runtime/sys_power64x.go
@@ -0,0 +1,37 @@
+// Copyright 2014 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.
+
+// +build power64 power64le
+
+package runtime
+
+import "unsafe"
+
+// adjust Gobuf as if it executed a call to fn with context ctxt
+// and then did an immediate Gosave.
+func gostartcall(buf *gobuf, fn, ctxt unsafe.Pointer) {
+ if buf.lr != 0 {
+ gothrow("invalid use of gostartcall")
+ }
+ buf.lr = buf.pc
+ buf.pc = uintptr(fn)
+ buf.ctxt = ctxt
+}
+
+// Called to rewind context saved during morestack back to beginning of function.
+// To help us, the linker emits a jmp back to the beginning right after the
+// call to morestack. We just have to decode and apply that jump.
+func rewindmorestack(buf *gobuf) {
+ var inst uint32
+ if buf.pc&3 == 0 && buf.pc != 0 {
+ inst = *(*uint32)(unsafe.Pointer(buf.pc))
+ if inst>>26 == 18 && inst&3 == 0 {
+ //print("runtime: rewind pc=", hex(buf.pc), " to pc=", hex(uintptr(buf.pc + int32(inst<<6)>>6)), "\n");
+ buf.pc += uintptr(int32(inst<<6) >> 6)
+ return
+ }
+ }
+ print("runtime: pc=", hex(buf.pc), " ", hex(inst), "\n")
+ gothrow("runtime: misuse of rewindmorestack")
+}
diff --git a/src/runtime/sys_windows_386.s b/src/runtime/sys_windows_386.s
index 2793e5221..c8a830cdf 100644
--- a/src/runtime/sys_windows_386.s
+++ b/src/runtime/sys_windows_386.s
@@ -44,7 +44,7 @@ TEXT runtime·badsignal2(SB),NOSPLIT,$24
// stderr
MOVL $-12, 0(SP)
MOVL SP, BP
- CALL *runtime·GetStdHandle(SB)
+ CALL *runtime·_GetStdHandle(SB)
MOVL BP, SP
MOVL AX, 0(SP) // handle
@@ -56,7 +56,7 @@ TEXT runtime·badsignal2(SB),NOSPLIT,$24
MOVL $0, 0(DX)
MOVL DX, 12(SP)
MOVL $0, 16(SP) // overlapped
- CALL *runtime·WriteFile(SB)
+ CALL *runtime·_WriteFile(SB)
MOVL BP, SI
RET
@@ -208,7 +208,7 @@ TEXT runtime·externalthreadhandler(SB),NOSPLIT,$0
MOVL BX, g_m(SP)
LEAL -8192(SP), CX
MOVL CX, (g_stack+stack_lo)(SP)
- ADDL $const_StackGuard, CX
+ ADDL $const__StackGuard, CX
MOVL CX, g_stackguard0(SP)
MOVL CX, g_stackguard1(SP)
MOVL DX, (g_stack+stack_hi)(SP)
@@ -255,8 +255,8 @@ TEXT runtime·callbackasm1+0(SB),NOSPLIT,$0
MOVL -4(BX)(AX*4), BX
// extract callback context
- MOVL cbctxt_gobody(BX), AX
- MOVL cbctxt_argsize(BX), DX
+ MOVL wincallbackcontext_gobody(BX), AX
+ MOVL wincallbackcontext_argsize(BX), DX
// preserve whatever's at the memory location that
// the callback will use to store the return value
@@ -266,7 +266,7 @@ TEXT runtime·callbackasm1+0(SB),NOSPLIT,$0
ADDL $4, DX
// remember how to restore stack on return
- MOVL cbctxt_restorestack(BX), BX
+ MOVL wincallbackcontext_restorestack(BX), BX
PUSHL BX
// call target Go function
@@ -314,7 +314,7 @@ TEXT runtime·tstart(SB),NOSPLIT,$0
MOVL AX, (g_stack+stack_hi)(DX)
SUBL $(64*1024), AX // stack size
MOVL AX, (g_stack+stack_lo)(DX)
- ADDL $const_StackGuard, AX
+ ADDL $const__StackGuard, AX
MOVL AX, g_stackguard0(DX)
MOVL AX, g_stackguard1(DX)
@@ -415,7 +415,7 @@ TEXT runtime·usleep2(SB),NOSPLIT,$20
MOVL $0, alertable-16(SP)
MOVL $-1, handle-20(SP)
MOVL SP, BP
- MOVL runtime·NtWaitForSingleObject(SB), AX
+ MOVL runtime·_NtWaitForSingleObject(SB), AX
CALL AX
MOVL BP, SP
RET
diff --git a/src/runtime/sys_windows_amd64.s b/src/runtime/sys_windows_amd64.s
index 5e5c2e7f5..68f7cd392 100644
--- a/src/runtime/sys_windows_amd64.s
+++ b/src/runtime/sys_windows_amd64.s
@@ -66,7 +66,7 @@ TEXT runtime·badsignal2(SB),NOSPLIT,$48
// stderr
MOVQ $-12, CX // stderr
MOVQ CX, 0(SP)
- MOVQ runtime·GetStdHandle(SB), AX
+ MOVQ runtime·_GetStdHandle(SB), AX
CALL AX
MOVQ AX, CX // handle
@@ -79,7 +79,7 @@ TEXT runtime·badsignal2(SB),NOSPLIT,$48
MOVQ $0, 0(R9)
MOVQ R9, 24(SP)
MOVQ $0, 32(SP) // overlapped
- MOVQ runtime·WriteFile(SB), AX
+ MOVQ runtime·_WriteFile(SB), AX
CALL AX
RET
@@ -245,7 +245,7 @@ TEXT runtime·externalthreadhandler(SB),NOSPLIT,$0
LEAQ -8192(SP), CX
MOVQ CX, (g_stack+stack_lo)(SP)
- ADDQ $const_StackGuard, CX
+ ADDQ $const__StackGuard, CX
MOVQ CX, g_stackguard0(SP)
MOVQ CX, g_stackguard1(SP)
MOVQ DX, (g_stack+stack_hi)(SP)
@@ -294,8 +294,8 @@ TEXT runtime·callbackasm1(SB),NOSPLIT,$0
MOVQ -8(CX)(AX*8), AX
// extract callback context
- MOVQ cbctxt_argsize(AX), DX
- MOVQ cbctxt_gobody(AX), AX
+ MOVQ wincallbackcontext_argsize(AX), DX
+ MOVQ wincallbackcontext_gobody(AX), AX
// preserve whatever's at the memory location that
// the callback will use to store the return value
@@ -355,7 +355,7 @@ TEXT runtime·tstart_stdcall(SB),NOSPLIT,$0
MOVQ AX, (g_stack+stack_hi)(DX)
SUBQ $(64*1024), AX // stack size
MOVQ AX, (g_stack+stack_lo)(DX)
- ADDQ $const_StackGuard, AX
+ ADDQ $const__StackGuard, AX
MOVQ AX, g_stackguard0(DX)
MOVQ AX, g_stackguard1(DX)
@@ -436,7 +436,7 @@ TEXT runtime·usleep2(SB),NOSPLIT,$16
MOVQ BX, (R8)
MOVQ $-1, CX // handle
MOVQ $0, DX // alertable
- MOVQ runtime·NtWaitForSingleObject(SB), AX
+ MOVQ runtime·_NtWaitForSingleObject(SB), AX
CALL AX
MOVQ 8(SP), SP
RET
diff --git a/src/runtime/syscall_windows.go b/src/runtime/syscall_windows.go
index efbcab510..661ee59d7 100644
--- a/src/runtime/syscall_windows.go
+++ b/src/runtime/syscall_windows.go
@@ -41,20 +41,20 @@ func callbackasmAddr(i int) uintptr {
func compileCallback(fn eface, cleanstack bool) (code uintptr) {
if fn._type == nil || (fn._type.kind&kindMask) != kindFunc {
- panic("compilecallback: not a function")
+ panic("compileCallback: not a function")
}
ft := (*functype)(unsafe.Pointer(fn._type))
- if len(ft.out) != 1 {
- panic("compilecallback: function must have one output parameter")
+ if ft.out.len != 1 {
+ panic("compileCallback: function must have one output parameter")
}
uintptrSize := unsafe.Sizeof(uintptr(0))
- if t := (**_type)(unsafe.Pointer(&ft.out[0])); (*t).size != uintptrSize {
- panic("compilecallback: output parameter size is wrong")
+ if t := (**_type)(unsafe.Pointer(ft.out.array)); (*t).size != uintptrSize {
+ panic("compileCallback: output parameter size is wrong")
}
argsize := uintptr(0)
- for _, t := range (*[1024](*_type))(unsafe.Pointer(&ft.in[0]))[:len(ft.in)] {
+ for _, t := range (*[1024](*_type))(unsafe.Pointer(ft.in.array))[:ft.in.len] {
if (*t).size > uintptrSize {
- panic("compilecallback: input parameter size is wrong")
+ panic("compileCallback: input parameter size is wrong")
}
argsize += uintptrSize
}
@@ -87,8 +87,6 @@ func compileCallback(fn eface, cleanstack bool) (code uintptr) {
return callbackasmAddr(n)
}
-func getLoadLibrary() uintptr
-
//go:nosplit
func syscall_loadlibrary(filename *uint16) (handle, err uintptr) {
var c libcall
@@ -103,8 +101,6 @@ func syscall_loadlibrary(filename *uint16) (handle, err uintptr) {
return
}
-func getGetProcAddress() uintptr
-
//go:nosplit
func syscall_getprocaddress(handle uintptr, procname *byte) (outhandle, err uintptr) {
var c libcall
diff --git a/src/runtime/zgoarch_386.go b/src/runtime/zgoarch_386.go
new file mode 100644
index 000000000..057a746bb
--- /dev/null
+++ b/src/runtime/zgoarch_386.go
@@ -0,0 +1,12 @@
+// generated by gengoos.go using 'go generate'
+
+package runtime
+
+const theGoarch = `386`
+
+const goarch_386 = 1
+const goarch_amd64 = 0
+const goarch_amd64p32 = 0
+const goarch_arm = 0
+const goarch_power64 = 0
+const goarch_power64le = 0
diff --git a/src/runtime/zgoarch_amd64.go b/src/runtime/zgoarch_amd64.go
new file mode 100644
index 000000000..a71240726
--- /dev/null
+++ b/src/runtime/zgoarch_amd64.go
@@ -0,0 +1,12 @@
+// generated by gengoos.go using 'go generate'
+
+package runtime
+
+const theGoarch = `amd64`
+
+const goarch_386 = 0
+const goarch_amd64 = 1
+const goarch_amd64p32 = 0
+const goarch_arm = 0
+const goarch_power64 = 0
+const goarch_power64le = 0
diff --git a/src/runtime/zgoarch_amd64p32.go b/src/runtime/zgoarch_amd64p32.go
new file mode 100644
index 000000000..2b6a142bb
--- /dev/null
+++ b/src/runtime/zgoarch_amd64p32.go
@@ -0,0 +1,12 @@
+// generated by gengoos.go using 'go generate'
+
+package runtime
+
+const theGoarch = `amd64p32`
+
+const goarch_386 = 0
+const goarch_amd64 = 0
+const goarch_amd64p32 = 1
+const goarch_arm = 0
+const goarch_power64 = 0
+const goarch_power64le = 0
diff --git a/src/runtime/zgoarch_arm.go b/src/runtime/zgoarch_arm.go
new file mode 100644
index 000000000..403021005
--- /dev/null
+++ b/src/runtime/zgoarch_arm.go
@@ -0,0 +1,12 @@
+// generated by gengoos.go using 'go generate'
+
+package runtime
+
+const theGoarch = `arm`
+
+const goarch_386 = 0
+const goarch_amd64 = 0
+const goarch_amd64p32 = 0
+const goarch_arm = 1
+const goarch_power64 = 0
+const goarch_power64le = 0
diff --git a/src/runtime/zgoarch_power64.go b/src/runtime/zgoarch_power64.go
new file mode 100644
index 000000000..cc361f050
--- /dev/null
+++ b/src/runtime/zgoarch_power64.go
@@ -0,0 +1,12 @@
+// generated by gengoos.go using 'go generate'
+
+package runtime
+
+const theGoarch = `power64`
+
+const goarch_386 = 0
+const goarch_amd64 = 0
+const goarch_amd64p32 = 0
+const goarch_arm = 0
+const goarch_power64 = 1
+const goarch_power64le = 0
diff --git a/src/runtime/zgoarch_power64le.go b/src/runtime/zgoarch_power64le.go
new file mode 100644
index 000000000..41294e61b
--- /dev/null
+++ b/src/runtime/zgoarch_power64le.go
@@ -0,0 +1,12 @@
+// generated by gengoos.go using 'go generate'
+
+package runtime
+
+const theGoarch = `power64le`
+
+const goarch_386 = 0
+const goarch_amd64 = 0
+const goarch_amd64p32 = 0
+const goarch_arm = 0
+const goarch_power64 = 0
+const goarch_power64le = 1
diff --git a/src/runtime/zgoos_android.go b/src/runtime/zgoos_android.go
new file mode 100644
index 000000000..0590bd9ab
--- /dev/null
+++ b/src/runtime/zgoos_android.go
@@ -0,0 +1,17 @@
+// generated by gengoos.go using 'go generate'
+
+package runtime
+
+const theGoos = `android`
+
+const goos_android = 1
+const goos_darwin = 0
+const goos_dragonfly = 0
+const goos_freebsd = 0
+const goos_linux = 0
+const goos_nacl = 0
+const goos_netbsd = 0
+const goos_openbsd = 0
+const goos_plan9 = 0
+const goos_solaris = 0
+const goos_windows = 0
diff --git a/src/runtime/zgoos_darwin.go b/src/runtime/zgoos_darwin.go
new file mode 100644
index 000000000..c0a7cd6e7
--- /dev/null
+++ b/src/runtime/zgoos_darwin.go
@@ -0,0 +1,17 @@
+// generated by gengoos.go using 'go generate'
+
+package runtime
+
+const theGoos = `darwin`
+
+const goos_android = 0
+const goos_darwin = 1
+const goos_dragonfly = 0
+const goos_freebsd = 0
+const goos_linux = 0
+const goos_nacl = 0
+const goos_netbsd = 0
+const goos_openbsd = 0
+const goos_plan9 = 0
+const goos_solaris = 0
+const goos_windows = 0
diff --git a/src/runtime/zgoos_dragonfly.go b/src/runtime/zgoos_dragonfly.go
new file mode 100644
index 000000000..008d6de81
--- /dev/null
+++ b/src/runtime/zgoos_dragonfly.go
@@ -0,0 +1,17 @@
+// generated by gengoos.go using 'go generate'
+
+package runtime
+
+const theGoos = `dragonfly`
+
+const goos_android = 0
+const goos_darwin = 0
+const goos_dragonfly = 1
+const goos_freebsd = 0
+const goos_linux = 0
+const goos_nacl = 0
+const goos_netbsd = 0
+const goos_openbsd = 0
+const goos_plan9 = 0
+const goos_solaris = 0
+const goos_windows = 0
diff --git a/src/runtime/zgoos_freebsd.go b/src/runtime/zgoos_freebsd.go
new file mode 100644
index 000000000..247894035
--- /dev/null
+++ b/src/runtime/zgoos_freebsd.go
@@ -0,0 +1,17 @@
+// generated by gengoos.go using 'go generate'
+
+package runtime
+
+const theGoos = `freebsd`
+
+const goos_android = 0
+const goos_darwin = 0
+const goos_dragonfly = 0
+const goos_freebsd = 1
+const goos_linux = 0
+const goos_nacl = 0
+const goos_netbsd = 0
+const goos_openbsd = 0
+const goos_plan9 = 0
+const goos_solaris = 0
+const goos_windows = 0
diff --git a/src/runtime/zgoos_linux.go b/src/runtime/zgoos_linux.go
new file mode 100644
index 000000000..c775ab538
--- /dev/null
+++ b/src/runtime/zgoos_linux.go
@@ -0,0 +1,19 @@
+// generated by gengoos.go using 'go generate'
+
+// +build !android
+
+package runtime
+
+const theGoos = `linux`
+
+const goos_android = 0
+const goos_darwin = 0
+const goos_dragonfly = 0
+const goos_freebsd = 0
+const goos_linux = 1
+const goos_nacl = 0
+const goos_netbsd = 0
+const goos_openbsd = 0
+const goos_plan9 = 0
+const goos_solaris = 0
+const goos_windows = 0
diff --git a/src/runtime/zgoos_nacl.go b/src/runtime/zgoos_nacl.go
new file mode 100644
index 000000000..d9d88f450
--- /dev/null
+++ b/src/runtime/zgoos_nacl.go
@@ -0,0 +1,17 @@
+// generated by gengoos.go using 'go generate'
+
+package runtime
+
+const theGoos = `nacl`
+
+const goos_android = 0
+const goos_darwin = 0
+const goos_dragonfly = 0
+const goos_freebsd = 0
+const goos_linux = 0
+const goos_nacl = 1
+const goos_netbsd = 0
+const goos_openbsd = 0
+const goos_plan9 = 0
+const goos_solaris = 0
+const goos_windows = 0
diff --git a/src/runtime/zgoos_netbsd.go b/src/runtime/zgoos_netbsd.go
new file mode 100644
index 000000000..ff2c5cb8f
--- /dev/null
+++ b/src/runtime/zgoos_netbsd.go
@@ -0,0 +1,17 @@
+// generated by gengoos.go using 'go generate'
+
+package runtime
+
+const theGoos = `netbsd`
+
+const goos_android = 0
+const goos_darwin = 0
+const goos_dragonfly = 0
+const goos_freebsd = 0
+const goos_linux = 0
+const goos_nacl = 0
+const goos_netbsd = 1
+const goos_openbsd = 0
+const goos_plan9 = 0
+const goos_solaris = 0
+const goos_windows = 0
diff --git a/src/runtime/zgoos_openbsd.go b/src/runtime/zgoos_openbsd.go
new file mode 100644
index 000000000..b071dc63a
--- /dev/null
+++ b/src/runtime/zgoos_openbsd.go
@@ -0,0 +1,17 @@
+// generated by gengoos.go using 'go generate'
+
+package runtime
+
+const theGoos = `openbsd`
+
+const goos_android = 0
+const goos_darwin = 0
+const goos_dragonfly = 0
+const goos_freebsd = 0
+const goos_linux = 0
+const goos_nacl = 0
+const goos_netbsd = 0
+const goos_openbsd = 1
+const goos_plan9 = 0
+const goos_solaris = 0
+const goos_windows = 0
diff --git a/src/runtime/zgoos_plan9.go b/src/runtime/zgoos_plan9.go
new file mode 100644
index 000000000..4306b0f1e
--- /dev/null
+++ b/src/runtime/zgoos_plan9.go
@@ -0,0 +1,17 @@
+// generated by gengoos.go using 'go generate'
+
+package runtime
+
+const theGoos = `plan9`
+
+const goos_android = 0
+const goos_darwin = 0
+const goos_dragonfly = 0
+const goos_freebsd = 0
+const goos_linux = 0
+const goos_nacl = 0
+const goos_netbsd = 0
+const goos_openbsd = 0
+const goos_plan9 = 1
+const goos_solaris = 0
+const goos_windows = 0
diff --git a/src/runtime/zgoos_solaris.go b/src/runtime/zgoos_solaris.go
new file mode 100644
index 000000000..10f9537d0
--- /dev/null
+++ b/src/runtime/zgoos_solaris.go
@@ -0,0 +1,17 @@
+// generated by gengoos.go using 'go generate'
+
+package runtime
+
+const theGoos = `solaris`
+
+const goos_android = 0
+const goos_darwin = 0
+const goos_dragonfly = 0
+const goos_freebsd = 0
+const goos_linux = 0
+const goos_nacl = 0
+const goos_netbsd = 0
+const goos_openbsd = 0
+const goos_plan9 = 0
+const goos_solaris = 1
+const goos_windows = 0
diff --git a/src/runtime/zgoos_windows.go b/src/runtime/zgoos_windows.go
new file mode 100644
index 000000000..56f5c58ce
--- /dev/null
+++ b/src/runtime/zgoos_windows.go
@@ -0,0 +1,17 @@
+// generated by gengoos.go using 'go generate'
+
+package runtime
+
+const theGoos = `windows`
+
+const goos_android = 0
+const goos_darwin = 0
+const goos_dragonfly = 0
+const goos_freebsd = 0
+const goos_linux = 0
+const goos_nacl = 0
+const goos_netbsd = 0
+const goos_openbsd = 0
+const goos_plan9 = 0
+const goos_solaris = 0
+const goos_windows = 1