Skip to content

Commit d24ec86

Browse files
jordanrh1ianlancetaylor
authored andcommitted
runtime: support windows/arm
Updates #26148 Change-Id: I8f68b2c926c7b11dc86c9664ed7ff2d2f78b64b4 Reviewed-on: https://go-review.googlesource.com/128715 Run-TryBot: Ian Lance Taylor <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]>
1 parent 37db664 commit d24ec86

17 files changed

+4942
-21
lines changed

src/cmd/vet/all/whitelist/windows_386.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
runtime/sys_windows_386.s: [386] profileloop: use of 4(SP) points beyond argument frame
44
runtime/sys_windows_386.s: [386] ctrlhandler: 4(SP) should be _type+0(FP)
55
runtime/sys_windows_386.s: [386] setldt: function setldt missing Go declaration
6-
runtime/zcallback_windows.s: [386] callbackasm: function callbackasm missing Go declaration
76
runtime/sys_windows_386.s: [386] callbackasm1+0: function callbackasm1+0 missing Go declaration
87
runtime/sys_windows_386.s: [386] tstart: function tstart missing Go declaration
98
runtime/sys_windows_386.s: [386] tstart_stdcall: RET without writing to 4-byte ret+4(FP)

src/cmd/vet/all/whitelist/windows_amd64.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,3 @@ runtime/sys_windows_amd64.s: [amd64] callbackasm1: function callbackasm1 missing
66
runtime/sys_windows_amd64.s: [amd64] tstart_stdcall: RET without writing to 4-byte ret+8(FP)
77
runtime/sys_windows_amd64.s: [amd64] settls: function settls missing Go declaration
88
runtime/sys_windows_amd64.s: [amd64] cannot check cross-package assembly function: now is in package time
9-
runtime/zcallback_windows.s: [amd64] callbackasm: function callbackasm missing Go declaration

src/runtime/asm_arm.s

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -784,13 +784,17 @@ TEXT setg<>(SB),NOSPLIT|NOFRAME,$0-0
784784
MOVW R0, g
785785

786786
// Save g to thread-local storage.
787+
#ifdef GOOS_windows
788+
B runtime·save_g(SB)
789+
#else
787790
MOVB runtime·iscgo(SB), R0
788791
CMP $0, R0
789792
B.EQ 2(PC)
790793
B runtime·save_g(SB)
791794

792795
MOVW g, R0
793796
RET
797+
#endif
794798

795799
TEXT runtime·emptyfunc(SB),0,$0-0
796800
RET

src/runtime/defs_windows_386.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,9 @@ type context struct {
104104
func (c *context) ip() uintptr { return uintptr(c.eip) }
105105
func (c *context) sp() uintptr { return uintptr(c.esp) }
106106

107+
// 386 does not have link register, so this returns 0.
108+
func (c *context) lr() uintptr { return 0 }
109+
107110
func (c *context) setip(x uintptr) { c.eip = uint32(x) }
108111
func (c *context) setsp(x uintptr) { c.esp = uint32(x) }
109112

src/runtime/defs_windows_amd64.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,9 @@ type context struct {
119119
func (c *context) ip() uintptr { return uintptr(c.rip) }
120120
func (c *context) sp() uintptr { return uintptr(c.rsp) }
121121

122+
// Amd64 does not have link register, so this returns 0.
123+
func (c *context) lr() uintptr { return 0 }
124+
122125
func (c *context) setip(x uintptr) { c.rip = uint64(x) }
123126
func (c *context) setsp(x uintptr) { c.rsp = uint64(x) }
124127

src/runtime/defs_windows_arm.go

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
// Copyright 2018 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package runtime
6+
7+
const (
8+
_PROT_NONE = 0
9+
_PROT_READ = 1
10+
_PROT_WRITE = 2
11+
_PROT_EXEC = 4
12+
13+
_MAP_ANON = 1
14+
_MAP_PRIVATE = 2
15+
16+
_DUPLICATE_SAME_ACCESS = 0x2
17+
_THREAD_PRIORITY_HIGHEST = 0x2
18+
19+
_SIGINT = 0x2
20+
_CTRL_C_EVENT = 0x0
21+
_CTRL_BREAK_EVENT = 0x1
22+
23+
_CONTEXT_CONTROL = 0x10001
24+
_CONTEXT_FULL = 0x10007
25+
26+
_EXCEPTION_ACCESS_VIOLATION = 0xc0000005
27+
_EXCEPTION_BREAKPOINT = 0x80000003
28+
_EXCEPTION_FLT_DENORMAL_OPERAND = 0xc000008d
29+
_EXCEPTION_FLT_DIVIDE_BY_ZERO = 0xc000008e
30+
_EXCEPTION_FLT_INEXACT_RESULT = 0xc000008f
31+
_EXCEPTION_FLT_OVERFLOW = 0xc0000091
32+
_EXCEPTION_FLT_UNDERFLOW = 0xc0000093
33+
_EXCEPTION_INT_DIVIDE_BY_ZERO = 0xc0000094
34+
_EXCEPTION_INT_OVERFLOW = 0xc0000095
35+
36+
_INFINITE = 0xffffffff
37+
_WAIT_TIMEOUT = 0x102
38+
39+
_EXCEPTION_CONTINUE_EXECUTION = -0x1
40+
_EXCEPTION_CONTINUE_SEARCH = 0x0
41+
)
42+
43+
type systeminfo struct {
44+
anon0 [4]byte
45+
dwpagesize uint32
46+
lpminimumapplicationaddress *byte
47+
lpmaximumapplicationaddress *byte
48+
dwactiveprocessormask uint32
49+
dwnumberofprocessors uint32
50+
dwprocessortype uint32
51+
dwallocationgranularity uint32
52+
wprocessorlevel uint16
53+
wprocessorrevision uint16
54+
}
55+
56+
type exceptionrecord struct {
57+
exceptioncode uint32
58+
exceptionflags uint32
59+
exceptionrecord *exceptionrecord
60+
exceptionaddress *byte
61+
numberparameters uint32
62+
exceptioninformation [15]uint32
63+
}
64+
65+
type neon128 struct {
66+
low uint64
67+
high int64
68+
}
69+
70+
type context struct {
71+
contextflags uint32
72+
r0 uint32
73+
r1 uint32
74+
r2 uint32
75+
r3 uint32
76+
r4 uint32
77+
r5 uint32
78+
r6 uint32
79+
r7 uint32
80+
r8 uint32
81+
r9 uint32
82+
r10 uint32
83+
r11 uint32
84+
r12 uint32
85+
86+
spr uint32
87+
lrr uint32
88+
pc uint32
89+
cpsr uint32
90+
91+
fpscr uint32
92+
padding uint32
93+
94+
floatNeon [16]neon128
95+
96+
bvr [8]uint32
97+
bcr [8]uint32
98+
wvr [1]uint32
99+
wcr [1]uint32
100+
padding2 [2]uint32
101+
}
102+
103+
func (c *context) ip() uintptr { return uintptr(c.pc) }
104+
func (c *context) sp() uintptr { return uintptr(c.spr) }
105+
func (c *context) lr() uintptr { return uintptr(c.lrr) }
106+
107+
func (c *context) setip(x uintptr) { c.pc = uint32(x) }
108+
func (c *context) setsp(x uintptr) { c.spr = uint32(x) }
109+
110+
func dumpregs(r *context) {
111+
print("r0 ", hex(r.r0), "\n")
112+
print("r1 ", hex(r.r1), "\n")
113+
print("r2 ", hex(r.r2), "\n")
114+
print("r3 ", hex(r.r3), "\n")
115+
print("r4 ", hex(r.r4), "\n")
116+
print("r5 ", hex(r.r5), "\n")
117+
print("r6 ", hex(r.r6), "\n")
118+
print("r7 ", hex(r.r7), "\n")
119+
print("r8 ", hex(r.r8), "\n")
120+
print("r9 ", hex(r.r9), "\n")
121+
print("r10 ", hex(r.r10), "\n")
122+
print("r11 ", hex(r.r11), "\n")
123+
print("r12 ", hex(r.r12), "\n")
124+
print("sp ", hex(r.spr), "\n")
125+
print("lr ", hex(r.lrr), "\n")
126+
print("pc ", hex(r.pc), "\n")
127+
print("cpsr ", hex(r.cpsr), "\n")
128+
}
129+
130+
type overlapped struct {
131+
internal uint32
132+
internalhigh uint32
133+
anon0 [8]byte
134+
hevent *byte
135+
}
136+
137+
type memoryBasicInformation struct {
138+
baseAddress uintptr
139+
allocationBase uintptr
140+
allocationProtect uint32
141+
regionSize uintptr
142+
state uint32
143+
protect uint32
144+
type_ uint32
145+
}
146+
147+
func stackcheck() {
148+
// TODO: not implemented on ARM
149+
}

src/runtime/os_windows.go

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ const (
4343
//go:cgo_import_dynamic runtime._SetWaitableTimer SetWaitableTimer%6 "kernel32.dll"
4444
//go:cgo_import_dynamic runtime._SuspendThread SuspendThread%1 "kernel32.dll"
4545
//go:cgo_import_dynamic runtime._SwitchToThread SwitchToThread%0 "kernel32.dll"
46+
//go:cgo_import_dynamic runtime._TlsAlloc TlsAlloc%0 "kernel32.dll"
4647
//go:cgo_import_dynamic runtime._VirtualAlloc VirtualAlloc%4 "kernel32.dll"
4748
//go:cgo_import_dynamic runtime._VirtualFree VirtualFree%3 "kernel32.dll"
4849
//go:cgo_import_dynamic runtime._VirtualQuery VirtualQuery%3 "kernel32.dll"
@@ -91,6 +92,7 @@ var (
9192
_SetWaitableTimer,
9293
_SuspendThread,
9394
_SwitchToThread,
95+
_TlsAlloc,
9496
_VirtualAlloc,
9597
_VirtualFree,
9698
_VirtualQuery,
@@ -860,14 +862,34 @@ func profilem(mp *m) {
860862
var r *context
861863
rbuf := make([]byte, unsafe.Sizeof(*r)+15)
862864

863-
tls := &mp.tls[0]
864-
gp := *((**g)(unsafe.Pointer(tls)))
865-
866865
// align Context to 16 bytes
867866
r = (*context)(unsafe.Pointer((uintptr(unsafe.Pointer(&rbuf[15]))) &^ 15))
868867
r.contextflags = _CONTEXT_CONTROL
869868
stdcall2(_GetThreadContext, mp.thread, uintptr(unsafe.Pointer(r)))
870-
sigprof(r.ip(), r.sp(), 0, gp, mp)
869+
870+
var gp *g
871+
switch GOARCH {
872+
default:
873+
panic("unsupported architecture")
874+
case "arm":
875+
// TODO(jordanrh1): this is incorrect when Go is executing
876+
// on the system or signal stacks because curg returns
877+
// the current user g. The true g is stored in thread
878+
// local storage, which we cannot access from another CPU.
879+
// We cannot pull R10 from the thread context because
880+
// it might be executing C code, in which case R10
881+
// would not be g.
882+
gp = mp.curg
883+
case "386", "amd64":
884+
tls := &mp.tls[0]
885+
gp = *((**g)(unsafe.Pointer(tls)))
886+
}
887+
888+
if gp == nil {
889+
sigprofNonGoPC(r.ip())
890+
} else {
891+
sigprof(r.ip(), r.sp(), 0, gp, mp)
892+
}
871893
}
872894

873895
func profileloop1(param uintptr) uint32 {

src/runtime/os_windows_arm.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright 2018 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package runtime
6+
7+
//go:nosplit
8+
func cputicks() int64 {
9+
return nanotime()
10+
}
11+
12+
func checkgoarm() {
13+
if goarm < 7 {
14+
print("Need atomic synchronization instructions, coprocessor ",
15+
"access instructions. Recompile using GOARM=7.\n")
16+
exit(1)
17+
}
18+
}

src/runtime/rt0_windows_arm.s

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Copyright 2018 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
#include "go_asm.h"
6+
#include "go_tls.h"
7+
#include "textflag.h"
8+
9+
// This is the entry point for the program from the
10+
// kernel for an ordinary -buildmode=exe program.
11+
TEXT _rt0_arm_windows(SB),NOSPLIT|NOFRAME,$0
12+
B ·rt0_go(SB)

src/runtime/signal_windows.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ func lastcontinuetramp()
2727

2828
func initExceptionHandler() {
2929
stdcall2(_AddVectoredExceptionHandler, 1, funcPC(exceptiontramp))
30-
if _AddVectoredContinueHandler == nil || unsafe.Sizeof(&_AddVectoredContinueHandler) == 4 {
30+
if _AddVectoredContinueHandler == nil || GOARCH == "386" {
3131
// use SetUnhandledExceptionFilter for windows-386 or
3232
// if VectoredContinueHandler is unavailable.
3333
// note: SetUnhandledExceptionFilter handler won't be called, if debugging.
@@ -177,9 +177,15 @@ func lastcontinuehandler(info *exceptionrecord, r *context, gp *g) int32 {
177177
}
178178
print("\n")
179179

180+
// TODO(jordanrh1): This may be needed for 386/AMD64 as well.
181+
if GOARCH == "arm" {
182+
_g_.m.throwing = 1
183+
_g_.m.caughtsig.set(gp)
184+
}
185+
180186
level, _, docrash := gotraceback()
181187
if level > 0 {
182-
tracebacktrap(r.ip(), r.sp(), 0, gp)
188+
tracebacktrap(r.ip(), r.sp(), r.lr(), gp)
183189
tracebackothers(gp)
184190
dumpregs(r)
185191
}

0 commit comments

Comments
 (0)