繁体   English   中英

在 Golang 的 syscall 包中,syscall.Syscall() 是如何以及在何处为特定于 Windows 的系统调用定义的?

[英]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.Syscallsyscall.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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM