2015-09-24 Vladimir Makarov <vmakarov@redhat.com>
[official-gcc.git] / libgo / go / runtime / syscall_windows.go
blob51004b78a0271a5ce535568c26f5a11756a2f9ee
1 // Copyright 2014 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.
5 package runtime
7 import (
8 "unsafe"
11 const _SIGPROF = 0 // dummy value for badsignal
13 type callbacks struct {
14 lock mutex
15 ctxt [cb_max]*wincallbackcontext
16 n int
19 func (c *wincallbackcontext) isCleanstack() bool {
20 return c.cleanstack
23 func (c *wincallbackcontext) setCleanstack(cleanstack bool) {
24 c.cleanstack = cleanstack
27 var (
28 cbs callbacks
29 cbctxts **wincallbackcontext = &cbs.ctxt[0] // to simplify access to cbs.ctxt in sys_windows_*.s
31 callbackasm byte // type isn't really byte, it's code in runtime
34 // callbackasmAddr returns address of runtime.callbackasm
35 // function adjusted by i.
36 // runtime.callbackasm is just a series of CALL instructions
37 // (each is 5 bytes long), and we want callback to arrive at
38 // correspondent call instruction instead of start of
39 // runtime.callbackasm.
40 func callbackasmAddr(i int) uintptr {
41 return uintptr(add(unsafe.Pointer(&callbackasm), uintptr(i*5)))
44 func compileCallback(fn eface, cleanstack bool) (code uintptr) {
45 if fn._type == nil || (fn._type.kind&kindMask) != kindFunc {
46 panic("compilecallback: not a function")
48 ft := (*functype)(unsafe.Pointer(fn._type))
49 if len(ft.out) != 1 {
50 panic("compilecallback: function must have one output parameter")
52 uintptrSize := unsafe.Sizeof(uintptr(0))
53 if t := (**_type)(unsafe.Pointer(&ft.out[0])); (*t).size != uintptrSize {
54 panic("compilecallback: output parameter size is wrong")
56 argsize := uintptr(0)
57 if len(ft.in) > 0 {
58 for _, t := range (*[1024](*_type))(unsafe.Pointer(&ft.in[0]))[:len(ft.in)] {
59 if (*t).size > uintptrSize {
60 panic("compilecallback: input parameter size is wrong")
62 argsize += uintptrSize
66 lock(&cbs.lock)
67 defer unlock(&cbs.lock)
69 n := cbs.n
70 for i := 0; i < n; i++ {
71 if cbs.ctxt[i].gobody == fn.data && cbs.ctxt[i].isCleanstack() == cleanstack {
72 return callbackasmAddr(i)
75 if n >= cb_max {
76 gothrow("too many callback functions")
79 c := new(wincallbackcontext)
80 c.gobody = fn.data
81 c.argsize = argsize
82 c.setCleanstack(cleanstack)
83 if cleanstack && argsize != 0 {
84 c.restorestack = argsize
85 } else {
86 c.restorestack = 0
88 cbs.ctxt[n] = c
89 cbs.n++
91 return callbackasmAddr(n)
94 func getLoadLibrary() uintptr
96 //go:nosplit
97 func syscall_loadlibrary(filename *uint16) (handle, err uintptr) {
98 var c libcall
99 c.fn = getLoadLibrary()
100 c.n = 1
101 c.args = uintptr(unsafe.Pointer(&filename))
102 cgocall_errno(unsafe.Pointer(funcPC(asmstdcall)), unsafe.Pointer(&c))
103 handle = c.r1
104 if handle == 0 {
105 err = c.err
107 return
110 func getGetProcAddress() uintptr
112 //go:nosplit
113 func syscall_getprocaddress(handle uintptr, procname *byte) (outhandle, err uintptr) {
114 var c libcall
115 c.fn = getGetProcAddress()
116 c.n = 2
117 c.args = uintptr(unsafe.Pointer(&handle))
118 cgocall_errno(unsafe.Pointer(funcPC(asmstdcall)), unsafe.Pointer(&c))
119 outhandle = c.r1
120 if outhandle == 0 {
121 err = c.err
123 return
126 //go:nosplit
127 func syscall_Syscall(fn, nargs, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
128 var c libcall
129 c.fn = fn
130 c.n = nargs
131 c.args = uintptr(unsafe.Pointer(&a1))
132 cgocall_errno(unsafe.Pointer(funcPC(asmstdcall)), unsafe.Pointer(&c))
133 return c.r1, c.r2, c.err
136 //go:nosplit
137 func syscall_Syscall6(fn, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
138 var c libcall
139 c.fn = fn
140 c.n = nargs
141 c.args = uintptr(unsafe.Pointer(&a1))
142 cgocall_errno(unsafe.Pointer(funcPC(asmstdcall)), unsafe.Pointer(&c))
143 return c.r1, c.r2, c.err
146 //go:nosplit
147 func syscall_Syscall9(fn, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2, err uintptr) {
148 var c libcall
149 c.fn = fn
150 c.n = nargs
151 c.args = uintptr(unsafe.Pointer(&a1))
152 cgocall_errno(unsafe.Pointer(funcPC(asmstdcall)), unsafe.Pointer(&c))
153 return c.r1, c.r2, c.err
156 //go:nosplit
157 func syscall_Syscall12(fn, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12 uintptr) (r1, r2, err uintptr) {
158 var c libcall
159 c.fn = fn
160 c.n = nargs
161 c.args = uintptr(unsafe.Pointer(&a1))
162 cgocall_errno(unsafe.Pointer(funcPC(asmstdcall)), unsafe.Pointer(&c))
163 return c.r1, c.r2, c.err
166 //go:nosplit
167 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) {
168 var c libcall
169 c.fn = fn
170 c.n = nargs
171 c.args = uintptr(unsafe.Pointer(&a1))
172 cgocall_errno(unsafe.Pointer(funcPC(asmstdcall)), unsafe.Pointer(&c))
173 return c.r1, c.r2, c.err