Source file src/pkg/runtime/syscall_windows.go
1
2
3
4
5 package runtime
6
7 import (
8 "unsafe"
9 )
10
11 type callbacks struct {
12 lock mutex
13 ctxt [cb_max]*wincallbackcontext
14 n int
15 }
16
17 func (c *wincallbackcontext) isCleanstack() bool {
18 return c.cleanstack
19 }
20
21 func (c *wincallbackcontext) setCleanstack(cleanstack bool) {
22 c.cleanstack = cleanstack
23 }
24
25 var (
26 cbs callbacks
27 cbctxts **wincallbackcontext = &cbs.ctxt[0]
28 )
29
30 func callbackasm()
31
32
33
34
35
36
37
38
39
40
41 func callbackasmAddr(i int) uintptr {
42 var entrySize int
43 switch GOARCH {
44 default:
45 panic("unsupported architecture")
46 case "386", "amd64":
47 entrySize = 5
48 case "arm":
49
50
51 entrySize = 8
52 }
53 return funcPC(callbackasm) + uintptr(i*entrySize)
54 }
55
56
57 func compileCallback(fn eface, cleanstack bool) (code uintptr) {
58 if fn._type == nil || (fn._type.kind&kindMask) != kindFunc {
59 panic("compileCallback: expected function with one uintptr-sized result")
60 }
61 ft := (*functype)(unsafe.Pointer(fn._type))
62 if len(ft.out()) != 1 {
63 panic("compileCallback: expected function with one uintptr-sized result")
64 }
65 uintptrSize := unsafe.Sizeof(uintptr(0))
66 if ft.out()[0].size != uintptrSize {
67 panic("compileCallback: expected function with one uintptr-sized result")
68 }
69 argsize := uintptr(0)
70 for _, t := range ft.in() {
71 if t.size > uintptrSize {
72 panic("compileCallback: argument size is larger than uintptr")
73 }
74 argsize += uintptrSize
75 }
76
77 lock(&cbs.lock)
78
79 n := cbs.n
80 for i := 0; i < n; i++ {
81 if cbs.ctxt[i].gobody == fn.data && cbs.ctxt[i].isCleanstack() == cleanstack {
82 r := callbackasmAddr(i)
83 unlock(&cbs.lock)
84 return r
85 }
86 }
87 if n >= cb_max {
88 unlock(&cbs.lock)
89 throw("too many callback functions")
90 }
91
92 c := new(wincallbackcontext)
93 c.gobody = fn.data
94 c.argsize = argsize
95 c.setCleanstack(cleanstack)
96 if cleanstack && argsize != 0 {
97 c.restorestack = argsize
98 } else {
99 c.restorestack = 0
100 }
101 cbs.ctxt[n] = c
102 cbs.n++
103
104 r := callbackasmAddr(n)
105 unlock(&cbs.lock)
106 return r
107 }
108
109 const _LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800
110
111
112
113
114
115
116
117 func syscall_loadsystemlibrary(filename *uint16, absoluteFilepath *uint16) (handle, err uintptr) {
118 lockOSThread()
119 c := &getg().m.syscall
120
121 if useLoadLibraryEx {
122 c.fn = getLoadLibraryEx()
123 c.n = 3
124 args := struct {
125 lpFileName *uint16
126 hFile uintptr
127 flags uint32
128 }{filename, 0, _LOAD_LIBRARY_SEARCH_SYSTEM32}
129 c.args = uintptr(noescape(unsafe.Pointer(&args)))
130 } else {
131 c.fn = getLoadLibrary()
132 c.n = 1
133 c.args = uintptr(noescape(unsafe.Pointer(&absoluteFilepath)))
134 }
135
136 cgocall(asmstdcallAddr, unsafe.Pointer(c))
137 handle = c.r1
138 if handle == 0 {
139 err = c.err
140 }
141 unlockOSThread()
142 return
143 }
144
145
146
147 func syscall_loadlibrary(filename *uint16) (handle, err uintptr) {
148 lockOSThread()
149 defer unlockOSThread()
150 c := &getg().m.syscall
151 c.fn = getLoadLibrary()
152 c.n = 1
153 c.args = uintptr(noescape(unsafe.Pointer(&filename)))
154 cgocall(asmstdcallAddr, unsafe.Pointer(c))
155 handle = c.r1
156 if handle == 0 {
157 err = c.err
158 }
159 return
160 }
161
162
163
164 func syscall_getprocaddress(handle uintptr, procname *byte) (outhandle, err uintptr) {
165 lockOSThread()
166 defer unlockOSThread()
167 c := &getg().m.syscall
168 c.fn = getGetProcAddress()
169 c.n = 2
170 c.args = uintptr(noescape(unsafe.Pointer(&handle)))
171 cgocall(asmstdcallAddr, unsafe.Pointer(c))
172 outhandle = c.r1
173 if outhandle == 0 {
174 err = c.err
175 }
176 return
177 }
178
179
180
181 func syscall_Syscall(fn, nargs, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
182 lockOSThread()
183 defer unlockOSThread()
184 c := &getg().m.syscall
185 c.fn = fn
186 c.n = nargs
187 c.args = uintptr(noescape(unsafe.Pointer(&a1)))
188 cgocall(asmstdcallAddr, unsafe.Pointer(c))
189 return c.r1, c.r2, c.err
190 }
191
192
193
194 func syscall_Syscall6(fn, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
195 lockOSThread()
196 defer unlockOSThread()
197 c := &getg().m.syscall
198 c.fn = fn
199 c.n = nargs
200 c.args = uintptr(noescape(unsafe.Pointer(&a1)))
201 cgocall(asmstdcallAddr, unsafe.Pointer(c))
202 return c.r1, c.r2, c.err
203 }
204
205
206
207 func syscall_Syscall9(fn, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2, err uintptr) {
208 lockOSThread()
209 defer unlockOSThread()
210 c := &getg().m.syscall
211 c.fn = fn
212 c.n = nargs
213 c.args = uintptr(noescape(unsafe.Pointer(&a1)))
214 cgocall(asmstdcallAddr, unsafe.Pointer(c))
215 return c.r1, c.r2, c.err
216 }
217
218
219
220 func syscall_Syscall12(fn, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12 uintptr) (r1, r2, err uintptr) {
221 lockOSThread()
222 defer unlockOSThread()
223 c := &getg().m.syscall
224 c.fn = fn
225 c.n = nargs
226 c.args = uintptr(noescape(unsafe.Pointer(&a1)))
227 cgocall(asmstdcallAddr, unsafe.Pointer(c))
228 return c.r1, c.r2, c.err
229 }
230
231
232
233 func syscall_Syscall15(fn, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15 uintptr) (r1, r2, err uintptr) {
234 lockOSThread()
235 defer unlockOSThread()
236 c := &getg().m.syscall
237 c.fn = fn
238 c.n = nargs
239 c.args = uintptr(noescape(unsafe.Pointer(&a1)))
240 cgocall(asmstdcallAddr, unsafe.Pointer(c))
241 return c.r1, c.r2, c.err
242 }
243
244
245
246 func syscall_Syscall18(fn, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18 uintptr) (r1, r2, err uintptr) {
247 lockOSThread()
248 defer unlockOSThread()
249 c := &getg().m.syscall
250 c.fn = fn
251 c.n = nargs
252 c.args = uintptr(noescape(unsafe.Pointer(&a1)))
253 cgocall(asmstdcallAddr, unsafe.Pointer(c))
254 return c.r1, c.r2, c.err
255 }
256
View as plain text