[英]How and where is syscall.Syscall() defined for Windows-specific system calls in Golang's syscall package?
我试图了解 Golangs 系统调用包的一些低级细节。 特别是,我对特定于 Windows 的系统调用感兴趣(请参见下面的示例)。
我可以找到基于 UNIX 的系统的syscall.Syscall()
的定义:
但是,我找不到基于 Windows 的系统的任何此类定义,例如asm_windows_amd64.s
。
特别是, asm_unix_amd64.s
有以下构建指令,所以它的·Syscall(SB),NOSPLIT,$0-56
定义不能是 Windows 系统调用也调用的:
1// +build netbsd freebsd openbsd dragonfly
syscall.Syscall()
在哪里为基于 Windows 的系统定义?
示例: https : //godoc.org/golang.org/x/sys/windows#example-LoadLibrary
h, err := windows.LoadLibrary("kernel32.dll")
if err != nil {
abort("LoadLibrary", err)
}
defer windows.FreeLibrary(h)
proc, err := windows.GetProcAddress(h, "GetVersion")
if err != nil {
abort("GetProcAddress", err)
}
r, _, _ := syscall.Syscall(uintptr(proc), 0, 0, 0, 0)
major := byte(r)
minor := uint8(r >> 8)
build := uint16(r >> 16)
print("windows version ", major, ".", minor, " (Build ", build, ")\n")
我没有或使用 Windows,但一些 grep 与源的工作发现这一点:
syscall.Syscall
、 syscall.Syscall6
等在runtime/syscall_windows.go
中定义。 例如,从第 179 行(当前)开始:
//go:linkname syscall_Syscall syscall.Syscall //go:nosplit func syscall_Syscall(fn, nargs, a1, a2, a3 uintptr) (r1, r2, err uintptr) { lockOSThread() defer unlockOSThread() c := &getg().m.syscall c.fn = fn cn = nargs c.args = uintptr(noescape(unsafe.Pointer(&a1))) cgocall(asmstdcallAddr, unsafe.Pointer(c)) return c.r1, c.r2, c.err
}
go:linkname
是使这个函数被命名为syscall.Syscall
的魔法,即使它在这里被命名为runtime.syscall_Syscall
。
这些使用之前加载的 DLL 来确定如何真正进行系统调用。 (这就是c.fn
作用。)为了调用 DLL,Go 运行时必须锁定线程(参见前两个调用)并使用cgocall
来调用 DLL。 此外,使用getc().m.syscall
获得的结构传递参数需要特殊的getc().m.syscall
。
启动加载似乎是通过runtime/os_windows.go
发生的。 请注意, _GetProcAddress
(和其他函数)由 Windows 加载程序填充,它允许引导。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.