From ef4054978692bd934eb575d0027c1c5476af9931 Mon Sep 17 00:00:00 2001 From: qmuntal Date: Fri, 25 Jul 2025 16:35:07 +0200 Subject: [PATCH] runtime,syscall: move loadlibrary and getprocaddress to syscall There is no need for loadlibrary, loadsystemlibrary and getprocaddress to be implemented in the runtime and linknamed from syscall. Change-Id: Icefd53a8e8f7012ed0c94c356be4179d5e45a01b Reviewed-on: https://go-review.googlesource.com/c/go/+/690516 Reviewed-by: Mark Freeman Reviewed-by: Michael Pratt LUCI-TryBot-Result: Go LUCI --- src/runtime/os_windows.go | 3 +-- src/runtime/syscall_windows.go | 41 +------------------------------ src/syscall/dll_windows.go | 45 +++++++++++++++++++++++++++++++--- 3 files changed, 44 insertions(+), 45 deletions(-) diff --git a/src/runtime/os_windows.go b/src/runtime/os_windows.go index 88d730aa02..7821c71ff3 100644 --- a/src/runtime/os_windows.go +++ b/src/runtime/os_windows.go @@ -41,7 +41,6 @@ const ( //go:cgo_import_dynamic runtime._GetThreadContext GetThreadContext%2 "kernel32.dll" //go:cgo_import_dynamic runtime._SetThreadContext SetThreadContext%2 "kernel32.dll" //go:cgo_import_dynamic runtime._LoadLibraryExW LoadLibraryExW%3 "kernel32.dll" -//go:cgo_import_dynamic runtime._LoadLibraryW LoadLibraryW%1 "kernel32.dll" //go:cgo_import_dynamic runtime._PostQueuedCompletionStatus PostQueuedCompletionStatus%4 "kernel32.dll" //go:cgo_import_dynamic runtime._QueryPerformanceCounter QueryPerformanceCounter%1 "kernel32.dll" //go:cgo_import_dynamic runtime._QueryPerformanceFrequency QueryPerformanceFrequency%1 "kernel32.dll" @@ -99,7 +98,6 @@ var ( _GetThreadContext, _SetThreadContext, _LoadLibraryExW, - _LoadLibraryW, _PostQueuedCompletionStatus, _QueryPerformanceCounter, _QueryPerformanceFrequency, @@ -245,6 +243,7 @@ func windows_GetSystemDirectory() string { } func windowsLoadSystemLib(name []uint16) uintptr { + const _LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800 return stdcall3(_LoadLibraryExW, uintptr(unsafe.Pointer(&name[0])), 0, _LOAD_LIBRARY_SEARCH_SYSTEM32) } diff --git a/src/runtime/syscall_windows.go b/src/runtime/syscall_windows.go index 0f74ebbe24..5619afd6ce 100644 --- a/src/runtime/syscall_windows.go +++ b/src/runtime/syscall_windows.go @@ -412,48 +412,9 @@ func callbackWrap(a *callbackArgs) { } } -const _LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800 - -//go:linkname syscall_loadsystemlibrary syscall.loadsystemlibrary -func syscall_loadsystemlibrary(filename *uint16) (handle, err uintptr) { - handle, _, err = syscall_syscalln(uintptr(unsafe.Pointer(_LoadLibraryExW)), 3, uintptr(unsafe.Pointer(filename)), 0, _LOAD_LIBRARY_SEARCH_SYSTEM32) - KeepAlive(filename) - if handle != 0 { - err = 0 - } - return -} - -// golang.org/x/sys linknames syscall.loadlibrary -// (in addition to standard package syscall). -// Do not remove or change the type signature. -// -//go:linkname syscall_loadlibrary syscall.loadlibrary -func syscall_loadlibrary(filename *uint16) (handle, err uintptr) { - handle, _, err = syscall_syscalln(uintptr(unsafe.Pointer(_LoadLibraryW)), 1, uintptr(unsafe.Pointer(filename))) - KeepAlive(filename) - if handle != 0 { - err = 0 - } - return -} - -// golang.org/x/sys linknames syscall.getprocaddress -// (in addition to standard package syscall). -// Do not remove or change the type signature. -// -//go:linkname syscall_getprocaddress syscall.getprocaddress -func syscall_getprocaddress(handle uintptr, procname *byte) (outhandle, err uintptr) { - outhandle, _, err = syscall_syscalln(uintptr(unsafe.Pointer(_GetProcAddress)), 2, handle, uintptr(unsafe.Pointer(procname))) - KeepAlive(procname) - if outhandle != 0 { - err = 0 - } - return -} - //go:linkname syscall_syscalln syscall.syscalln //go:nosplit +//go:uintptrkeepalive func syscall_syscalln(fn, n uintptr, args ...uintptr) (r1, r2, err uintptr) { if n > uintptr(len(args)) { panic("syscall: n > len(args)") // should not be reachable from user code diff --git a/src/syscall/dll_windows.go b/src/syscall/dll_windows.go index 21b99d6e64..9d77986953 100644 --- a/src/syscall/dll_windows.go +++ b/src/syscall/dll_windows.go @@ -11,6 +11,15 @@ import ( "unsafe" ) +// Use double underscore to avoid name collision autogenerated functions. +//go:cgo_import_dynamic syscall.__LoadLibraryExW LoadLibraryExW%3 "kernel32.dll" +//go:cgo_import_dynamic syscall.__GetProcAddress GetProcAddress%2 "kernel32.dll" + +var ( + __LoadLibraryExW unsafe.Pointer + __GetProcAddress unsafe.Pointer +) + // DLLError describes reasons for DLL load failures. type DLLError struct { Err error @@ -94,9 +103,39 @@ func SyscallN(p uintptr, args ...uintptr) (r1, r2 uintptr, err Errno) { // //go:noescape func syscalln(fn, n uintptr, args ...uintptr) (r1, r2 uintptr, err Errno) -func loadlibrary(filename *uint16) (handle uintptr, err Errno) -func loadsystemlibrary(filename *uint16) (handle uintptr, err Errno) -func getprocaddress(handle uintptr, procname *uint8) (proc uintptr, err Errno) + +// N.B. For the loadlibrary, loadlibrary, and getprocaddress functions below: +// +// //go:linkname to act as an allowlist for linker's -checklinkname, as +// golang.org/x/sys/windows linknames these functions. + +//go:linkname loadlibrary +func loadlibrary(filename *uint16) (uintptr, Errno) { + handle, _, err := SyscallN(uintptr(__LoadLibraryExW), uintptr(unsafe.Pointer(filename)), 0, 0) + if handle != 0 { + err = 0 + } + return handle, err +} + +//go:linkname loadsystemlibrary +func loadsystemlibrary(filename *uint16) (uintptr, Errno) { + const _LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800 + handle, _, err := SyscallN(uintptr(__LoadLibraryExW), uintptr(unsafe.Pointer(filename)), 0, _LOAD_LIBRARY_SEARCH_SYSTEM32) + if handle != 0 { + err = 0 + } + return handle, err +} + +//go:linkname getprocaddress +func getprocaddress(handle uintptr, procname *uint8) (uintptr, Errno) { + proc, _, err := SyscallN(uintptr(__GetProcAddress), handle, uintptr(unsafe.Pointer(procname))) + if proc != 0 { + err = 0 + } + return proc, err +} // A DLL implements access to a single DLL. type DLL struct { -- 2.51.0