From 6112e6e404755028b2995bde31ca6e4a6bfe14a8 Mon Sep 17 00:00:00 2001 From: Shenghou Ma Date: Sun, 8 Mar 2015 23:04:48 -0400 Subject: [PATCH] cmd/internal/ld, runtime: record argument size for cgo_dynimport stdcall syscalls When external linking, we must link to implib provided by mingw, so we must use properly decorated names for stdcalls. Because the feature is only used in the runtime, I've designed a new decoration scheme so that we can use the same decorated name for both 386 and amd64. A stdcall function named FooEx from bar16.dll which takes 3 parameters will be imported like this: //go:cgo_import_dynamic runtime._FooEx FooEx%3 "bar16.dll" Depending on the size of uintptr, the linker will later transform it to _FooEx@12 or _FooEx@24. This is in prepration for the next CL that adds external linking support for windows/386. Change-Id: I2d2ea233f976aab3f356f9b508cdd246d5013e2c Signed-off-by: Shenghou Ma Reviewed-on: https://go-review.googlesource.com/7163 Reviewed-by: Alex Brainman Reviewed-by: Ian Lance Taylor --- src/cmd/internal/ld/pe.go | 24 ++++++++++-- src/runtime/os1_windows.go | 76 ++++++++++++++++++-------------------- 2 files changed, 57 insertions(+), 43 deletions(-) diff --git a/src/cmd/internal/ld/pe.go b/src/cmd/internal/ld/pe.go index 40bfc23776c..05882867156 100644 --- a/src/cmd/internal/ld/pe.go +++ b/src/cmd/internal/ld/pe.go @@ -8,6 +8,8 @@ import ( "encoding/binary" "fmt" "sort" + "strconv" + "strings" ) type IMAGE_FILE_HEADER struct { @@ -347,9 +349,10 @@ var sh [16]IMAGE_SECTION_HEADER var dd []IMAGE_DATA_DIRECTORY type Imp struct { - s *LSym - off uint64 - next *Imp + s *LSym + off uint64 + next *Imp + argsize int } type Dll struct { @@ -494,6 +497,21 @@ func initdynimport() *Dll { m = new(Imp) } + // Because external link requires properly stdcall decorated name, + // all external symbols in runtime use %n to denote that the number + // of uinptrs this function consumes. Store the argsize and discard + // the %n suffix if any. + m.argsize = -1 + if i := strings.IndexByte(s.Extname, '%'); i >= 0 { + var err error + m.argsize, err = strconv.Atoi(s.Extname[i+1:]) + if err != nil { + Diag("failed to parse stdcall decoration: %v", err) + } + m.argsize *= Thearch.Ptrsize + s.Extname = s.Extname[:i] + } + m.s = s m.next = d.ms d.ms = m diff --git a/src/runtime/os1_windows.go b/src/runtime/os1_windows.go index f91e9d596d3..561d3ce4575 100644 --- a/src/runtime/os1_windows.go +++ b/src/runtime/os1_windows.go @@ -8,44 +8,42 @@ import ( "unsafe" ) -//go:cgo_import_dynamic runtime._AddVectoredExceptionHandler AddVectoredExceptionHandler "kernel32.dll" -//go:cgo_import_dynamic runtime._CloseHandle CloseHandle "kernel32.dll" -//go:cgo_import_dynamic runtime._CreateEventA CreateEventA "kernel32.dll" -//go:cgo_import_dynamic runtime._CreateIoCompletionPort CreateIoCompletionPort "kernel32.dll" -//go:cgo_import_dynamic runtime._CreateThread CreateThread "kernel32.dll" -//go:cgo_import_dynamic runtime._CreateWaitableTimerA CreateWaitableTimerA "kernel32.dll" -//go:cgo_import_dynamic runtime._CryptAcquireContextW CryptAcquireContextW "advapi32.dll" -//go:cgo_import_dynamic runtime._CryptGenRandom CryptGenRandom "advapi32.dll" -//go:cgo_import_dynamic runtime._CryptReleaseContext CryptReleaseContext "advapi32.dll" -//go:cgo_import_dynamic runtime._DuplicateHandle DuplicateHandle "kernel32.dll" -//go:cgo_import_dynamic runtime._ExitProcess ExitProcess "kernel32.dll" -//go:cgo_import_dynamic runtime._FreeEnvironmentStringsW FreeEnvironmentStringsW "kernel32.dll" -//go:cgo_import_dynamic runtime._GetEnvironmentStringsW GetEnvironmentStringsW "kernel32.dll" -//go:cgo_import_dynamic runtime._GetProcAddress GetProcAddress "kernel32.dll" -//go:cgo_import_dynamic runtime._GetQueuedCompletionStatus GetQueuedCompletionStatus "kernel32.dll" -//go:cgo_import_dynamic runtime._GetStdHandle GetStdHandle "kernel32.dll" -//go:cgo_import_dynamic runtime._GetSystemInfo GetSystemInfo "kernel32.dll" -//go:cgo_import_dynamic runtime._GetThreadContext GetThreadContext "kernel32.dll" -//go:cgo_import_dynamic runtime._LoadLibraryW LoadLibraryW "kernel32.dll" -//go:cgo_import_dynamic runtime._LoadLibraryA LoadLibraryA "kernel32.dll" -//go:cgo_import_dynamic runtime._NtWaitForSingleObject NtWaitForSingleObject "ntdll.dll" -//go:cgo_import_dynamic runtime._ResumeThread ResumeThread "kernel32.dll" -//go:cgo_import_dynamic runtime._SetConsoleCtrlHandler SetConsoleCtrlHandler "kernel32.dll" -//go:cgo_import_dynamic runtime._SetErrorMode SetErrorMode "kernel32.dll" -//go:cgo_import_dynamic runtime._SetEvent SetEvent "kernel32.dll" -//go:cgo_import_dynamic runtime._SetProcessPriorityBoost SetProcessPriorityBoost "kernel32.dll" -//go:cgo_import_dynamic runtime._SetThreadPriority SetThreadPriority "kernel32.dll" -//go:cgo_import_dynamic runtime._SetUnhandledExceptionFilter SetUnhandledExceptionFilter "kernel32.dll" -//go:cgo_import_dynamic runtime._SetWaitableTimer SetWaitableTimer "kernel32.dll" -//go:cgo_import_dynamic runtime._Sleep Sleep "kernel32.dll" -//go:cgo_import_dynamic runtime._SuspendThread SuspendThread "kernel32.dll" -//go:cgo_import_dynamic runtime._VirtualAlloc VirtualAlloc "kernel32.dll" -//go:cgo_import_dynamic runtime._VirtualFree VirtualFree "kernel32.dll" -//go:cgo_import_dynamic runtime._VirtualProtect VirtualProtect "kernel32.dll" -//go:cgo_import_dynamic runtime._WSAGetOverlappedResult WSAGetOverlappedResult "ws2_32.dll" -//go:cgo_import_dynamic runtime._WaitForSingleObject WaitForSingleObject "kernel32.dll" -//go:cgo_import_dynamic runtime._WriteFile WriteFile "kernel32.dll" -//go:cgo_import_dynamic runtime._timeBeginPeriod timeBeginPeriod "winmm.dll" +//go:cgo_import_dynamic runtime._AddVectoredExceptionHandler AddVectoredExceptionHandler%2 "kernel32.dll" +//go:cgo_import_dynamic runtime._CloseHandle CloseHandle%1 "kernel32.dll" +//go:cgo_import_dynamic runtime._CreateEventA CreateEventA%4 "kernel32.dll" +//go:cgo_import_dynamic runtime._CreateIoCompletionPort CreateIoCompletionPort%4 "kernel32.dll" +//go:cgo_import_dynamic runtime._CreateThread CreateThread%6 "kernel32.dll" +//go:cgo_import_dynamic runtime._CreateWaitableTimerA CreateWaitableTimerA%3 "kernel32.dll" +//go:cgo_import_dynamic runtime._CryptAcquireContextW CryptAcquireContextW%5 "advapi32.dll" +//go:cgo_import_dynamic runtime._CryptGenRandom CryptGenRandom%3 "advapi32.dll" +//go:cgo_import_dynamic runtime._CryptReleaseContext CryptReleaseContext%2 "advapi32.dll" +//go:cgo_import_dynamic runtime._DuplicateHandle DuplicateHandle%7 "kernel32.dll" +//go:cgo_import_dynamic runtime._ExitProcess ExitProcess%1 "kernel32.dll" +//go:cgo_import_dynamic runtime._FreeEnvironmentStringsW FreeEnvironmentStringsW%1 "kernel32.dll" +//go:cgo_import_dynamic runtime._GetEnvironmentStringsW GetEnvironmentStringsW%0 "kernel32.dll" +//go:cgo_import_dynamic runtime._GetProcAddress GetProcAddress%2 "kernel32.dll" +//go:cgo_import_dynamic runtime._GetQueuedCompletionStatus GetQueuedCompletionStatus%5 "kernel32.dll" +//go:cgo_import_dynamic runtime._GetStdHandle GetStdHandle%1 "kernel32.dll" +//go:cgo_import_dynamic runtime._GetSystemInfo GetSystemInfo%1 "kernel32.dll" +//go:cgo_import_dynamic runtime._GetThreadContext GetThreadContext%2 "kernel32.dll" +//go:cgo_import_dynamic runtime._LoadLibraryW LoadLibraryW%1 "kernel32.dll" +//go:cgo_import_dynamic runtime._LoadLibraryA LoadLibraryA%1 "kernel32.dll" +//go:cgo_import_dynamic runtime._NtWaitForSingleObject NtWaitForSingleObject%3 "ntdll.dll" +//go:cgo_import_dynamic runtime._ResumeThread ResumeThread%1 "kernel32.dll" +//go:cgo_import_dynamic runtime._SetConsoleCtrlHandler SetConsoleCtrlHandler%2 "kernel32.dll" +//go:cgo_import_dynamic runtime._SetErrorMode SetErrorMode%1 "kernel32.dll" +//go:cgo_import_dynamic runtime._SetEvent SetEvent%1 "kernel32.dll" +//go:cgo_import_dynamic runtime._SetProcessPriorityBoost SetProcessPriorityBoost%2 "kernel32.dll" +//go:cgo_import_dynamic runtime._SetThreadPriority SetThreadPriority%2 "kernel32.dll" +//go:cgo_import_dynamic runtime._SetUnhandledExceptionFilter SetUnhandledExceptionFilter%1 "kernel32.dll" +//go:cgo_import_dynamic runtime._SetWaitableTimer SetWaitableTimer%6 "kernel32.dll" +//go:cgo_import_dynamic runtime._SuspendThread SuspendThread%1 "kernel32.dll" +//go:cgo_import_dynamic runtime._VirtualAlloc VirtualAlloc%4 "kernel32.dll" +//go:cgo_import_dynamic runtime._VirtualFree VirtualFree%3 "kernel32.dll" +//go:cgo_import_dynamic runtime._WSAGetOverlappedResult WSAGetOverlappedResult%5 "ws2_32.dll" +//go:cgo_import_dynamic runtime._WaitForSingleObject WaitForSingleObject%2 "kernel32.dll" +//go:cgo_import_dynamic runtime._WriteFile WriteFile%5 "kernel32.dll" +//go:cgo_import_dynamic runtime._timeBeginPeriod timeBeginPeriod%1 "winmm.dll" var ( // Following syscalls are available on every Windows PC. @@ -80,11 +78,9 @@ var ( _SetThreadPriority, _SetUnhandledExceptionFilter, _SetWaitableTimer, - _Sleep, _SuspendThread, _VirtualAlloc, _VirtualFree, - _VirtualProtect, _WSAGetOverlappedResult, _WaitForSingleObject, _WriteFile,