From 05b6a2f59c8efa0605db3f5d8f5ef554cb35ff74 Mon Sep 17 00:00:00 2001 From: klutzy Date: Mon, 12 Aug 2013 15:27:46 +0900 Subject: [PATCH] std: Add Win64 support Some extern blobs are duplicated without "stdcall" abi, since Win64 does not use any calling convention. (Giving any abi to them causes llvm producing wrong bytecode.) --- src/libstd/libc.rs | 106 ++++++++++++++++++++++++++ src/libstd/os.rs | 38 ++++++++- src/libstd/rt/thread_local_storage.rs | 9 ++- src/libstd/unstable/dynamic_lib.rs | 12 +++ 4 files changed, 162 insertions(+), 3 deletions(-) diff --git a/src/libstd/libc.rs b/src/libstd/libc.rs index d9bb66a62e9..790dc886c04 100644 --- a/src/libstd/libc.rs +++ b/src/libstd/libc.rs @@ -3259,6 +3259,7 @@ pub mod kernel32 { LPSYSTEM_INFO}; use libc::types::os::arch::extra::{HANDLE, LPHANDLE}; + #[cfg(target_arch = "x86")] #[abi = "stdcall"] extern "stdcall" { pub fn GetEnvironmentVariableW(n: LPCWSTR, @@ -3363,6 +3364,111 @@ pub fn MapViewOfFile(hFileMappingObject: HANDLE, -> LPVOID; pub fn UnmapViewOfFile(lpBaseAddress: LPCVOID) -> BOOL; } + + #[cfg(target_arch = "x86_64")] + extern { + pub fn GetEnvironmentVariableW(n: LPCWSTR, + v: LPWSTR, + nsize: DWORD) + -> DWORD; + pub fn SetEnvironmentVariableW(n: LPCWSTR, v: LPCWSTR) + -> BOOL; + pub fn GetEnvironmentStringsA() -> LPTCH; + pub fn FreeEnvironmentStringsA(env_ptr: LPTCH) -> BOOL; + pub fn GetModuleFileNameW(hModule: HMODULE, + lpFilename: LPWSTR, + nSize: DWORD) + -> DWORD; + pub fn CreateDirectoryW(lpPathName: LPCWSTR, + lpSecurityAttributes: + LPSECURITY_ATTRIBUTES) + -> BOOL; + pub fn CopyFileW(lpExistingFileName: LPCWSTR, + lpNewFileName: LPCWSTR, + bFailIfExists: BOOL) + -> BOOL; + pub fn DeleteFileW(lpPathName: LPCWSTR) -> BOOL; + pub fn RemoveDirectoryW(lpPathName: LPCWSTR) -> BOOL; + pub fn SetCurrentDirectoryW(lpPathName: LPCWSTR) -> BOOL; + pub fn GetLastError() -> DWORD; + pub fn FindFirstFileW(fileName: *u16, findFileData: HANDLE) + -> HANDLE; + pub fn FindNextFileW(findFile: HANDLE, findFileData: HANDLE) + -> BOOL; + pub fn FindClose(findFile: HANDLE) -> BOOL; + pub fn DuplicateHandle(hSourceProcessHandle: HANDLE, + hSourceHandle: HANDLE, + hTargetProcessHandle: HANDLE, + lpTargetHandle: LPHANDLE, + dwDesiredAccess: DWORD, + bInheritHandle: BOOL, + dwOptions: DWORD) + -> BOOL; + pub fn CloseHandle(hObject: HANDLE) -> BOOL; + pub fn OpenProcess(dwDesiredAccess: DWORD, + bInheritHandle: BOOL, + dwProcessId: DWORD) + -> HANDLE; + pub fn GetCurrentProcess() -> HANDLE; + pub fn CreateProcessA(lpApplicationName: LPCTSTR, + lpCommandLine: LPTSTR, + lpProcessAttributes: + LPSECURITY_ATTRIBUTES, + lpThreadAttributes: + LPSECURITY_ATTRIBUTES, + bInheritHandles: BOOL, + dwCreationFlags: DWORD, + lpEnvironment: LPVOID, + lpCurrentDirectory: LPCTSTR, + lpStartupInfo: LPSTARTUPINFO, + lpProcessInformation: + LPPROCESS_INFORMATION) + -> BOOL; + pub fn WaitForSingleObject(hHandle: HANDLE, + dwMilliseconds: DWORD) + -> DWORD; + pub fn TerminateProcess(hProcess: HANDLE, uExitCode: c_uint) + -> BOOL; + pub fn GetExitCodeProcess(hProcess: HANDLE, + lpExitCode: LPDWORD) + -> BOOL; + pub fn GetSystemInfo(lpSystemInfo: LPSYSTEM_INFO); + pub fn VirtualAlloc(lpAddress: LPVOID, + dwSize: SIZE_T, + flAllocationType: DWORD, + flProtect: DWORD) + -> LPVOID; + pub fn VirtualFree(lpAddress: LPVOID, + dwSize: SIZE_T, + dwFreeType: DWORD) + -> BOOL; + pub fn VirtualLock(lpAddress: LPVOID, dwSize: SIZE_T) -> BOOL; + pub fn VirtualUnlock(lpAddress: LPVOID, dwSize: SIZE_T) + -> BOOL; + pub fn VirtualProtect(lpAddress: LPVOID, + dwSize: SIZE_T, + flNewProtect: DWORD, + lpflOldProtect: LPDWORD) + -> BOOL; + pub fn VirtualQuery(lpAddress: LPCVOID, + lpBuffer: LPMEMORY_BASIC_INFORMATION, + dwLength: SIZE_T) + -> SIZE_T; + pub fn CreateFileMappingW(hFile: HANDLE, + lpAttributes: LPSECURITY_ATTRIBUTES, + flProtect: DWORD, + dwMaximumSizeHigh: DWORD, + dwMaximumSizeLow: DWORD, + lpName: LPCTSTR) + -> HANDLE; + pub fn MapViewOfFile(hFileMappingObject: HANDLE, + dwDesiredAccess: DWORD, + dwFileOffsetHigh: DWORD, + dwFileOffsetLow: DWORD, + dwNumberOfBytesToMap: SIZE_T) + -> LPVOID; + pub fn UnmapViewOfFile(lpBaseAddress: LPCVOID) -> BOOL; + } } pub mod msvcrt { diff --git a/src/libstd/os.rs b/src/libstd/os.rs index 0b5f53dbf19..e7caf3f23ab 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -1042,12 +1042,19 @@ pub fn errno() -> uint { #[fixed_stack_segment]; #[inline(never)]; use libc::types::os::arch::extra::DWORD; + #[cfg(target_arch = "x86")] #[link_name = "kernel32"] #[abi = "stdcall"] extern "stdcall" { fn GetLastError() -> DWORD; } + #[cfg(target_arch = "x86_64")] + #[link_name = "kernel32"] + extern { + fn GetLastError() -> DWORD; + } + unsafe { GetLastError() as uint } @@ -1113,6 +1120,7 @@ fn strerror() -> ~str { use libc::types::os::arch::extra::LPSTR; use libc::types::os::arch::extra::LPVOID; + #[cfg(target_arch = "x86")] #[link_name = "kernel32"] #[abi = "stdcall"] extern "stdcall" { @@ -1126,6 +1134,19 @@ fn FormatMessageA(flags: DWORD, -> DWORD; } + #[cfg(target_arch = "x86_64")] + #[link_name = "kernel32"] + extern { + fn FormatMessageA(flags: DWORD, + lpSrc: LPVOID, + msgId: DWORD, + langId: DWORD, + buf: LPSTR, + nsize: DWORD, + args: *c_void) + -> DWORD; + } + static FORMAT_MESSAGE_FROM_SYSTEM: DWORD = 0x00001000; static FORMAT_MESSAGE_IGNORE_INSERTS: DWORD = 0x00000200; @@ -1241,7 +1262,7 @@ fn real_args() -> ~[~str] { type LPCWSTR = *u16; -#[cfg(windows)] +#[cfg(windows, target_arch = "x86")] #[link_name="kernel32"] #[abi="stdcall"] extern "stdcall" { @@ -1249,13 +1270,26 @@ fn real_args() -> ~[~str] { fn LocalFree(ptr: *c_void); } -#[cfg(windows)] +#[cfg(windows, target_arch = "x86_64")] +#[link_name="kernel32"] +extern { + fn GetCommandLineW() -> LPCWSTR; + fn LocalFree(ptr: *c_void); +} + +#[cfg(windows, target_arch = "x86")] #[link_name="shell32"] #[abi="stdcall"] extern "stdcall" { fn CommandLineToArgvW(lpCmdLine: LPCWSTR, pNumArgs: *mut c_int) -> **u16; } +#[cfg(windows, target_arch = "x86_64")] +#[link_name="shell32"] +extern { + fn CommandLineToArgvW(lpCmdLine: LPCWSTR, pNumArgs: *mut c_int) -> **u16; +} + struct OverriddenArgs { val: ~[~str] } diff --git a/src/libstd/rt/thread_local_storage.rs b/src/libstd/rt/thread_local_storage.rs index a9cd29c18c9..b2c2c670b55 100644 --- a/src/libstd/rt/thread_local_storage.rs +++ b/src/libstd/rt/thread_local_storage.rs @@ -86,7 +86,7 @@ pub unsafe fn get(key: Key) -> *mut c_void { TlsGetValue(key) } -#[cfg(windows)] +#[cfg(windows, target_arch = "x86")] #[abi = "stdcall"] extern "stdcall" { fn TlsAlloc() -> DWORD; @@ -94,6 +94,13 @@ pub unsafe fn get(key: Key) -> *mut c_void { fn TlsGetValue(dwTlsIndex: DWORD) -> LPVOID; } +#[cfg(windows, target_arch = "x86_64")] +extern { + fn TlsAlloc() -> DWORD; + fn TlsSetValue(dwTlsIndex: DWORD, lpTlsvalue: LPVOID) -> BOOL; + fn TlsGetValue(dwTlsIndex: DWORD) -> LPVOID; +} + #[test] fn tls_smoke_test() { use cast::transmute; diff --git a/src/libstd/unstable/dynamic_lib.rs b/src/libstd/unstable/dynamic_lib.rs index 6dbe68200b3..90cf49cad1c 100644 --- a/src/libstd/unstable/dynamic_lib.rs +++ b/src/libstd/unstable/dynamic_lib.rs @@ -252,6 +252,7 @@ pub unsafe fn close(handle: *libc::c_void) { FreeLibrary(handle); () } + #[cfg(target_arch = "x86")] #[link_name = "kernel32"] extern "stdcall" { fn SetLastError(error: u32); @@ -261,4 +262,15 @@ fn GetModuleHandleExW(dwFlags: libc::DWORD, name: *u16, fn GetProcAddress(handle: *libc::c_void, name: *libc::c_char) -> *libc::c_void; fn FreeLibrary(handle: *libc::c_void); } + + #[cfg(target_arch = "x86_64")] + #[link_name = "kernel32"] + extern { + fn SetLastError(error: u32); + fn LoadLibraryW(name: *u16) -> *libc::c_void; + fn GetModuleHandleExW(dwFlags: libc::DWORD, name: *u16, + handle: **libc::c_void) -> *libc::c_void; + fn GetProcAddress(handle: *libc::c_void, name: *libc::c_char) -> *libc::c_void; + fn FreeLibrary(handle: *libc::c_void); + } } -- 2.44.0