]> git.lizzy.rs Git - rust.git/commitdiff
auto merge of #8488 : klutzy/rust/mingw-w64, r=brson
authorbors <bors@rust-lang.org>
Mon, 26 Aug 2013 18:46:13 +0000 (11:46 -0700)
committerbors <bors@rust-lang.org>
Mon, 26 Aug 2013 18:46:13 +0000 (11:46 -0700)
This patchset enables rustc to cross-build mingw-w64 outputs.
Tested on mingw + mingw-w64 (mingw-builds, win64/seh/win32-threads/gcc-4.8.1).

I also patched llvm to support Win64 stack unwinding.
https://github.com/klutzy/llvm/commit/ebe22bdbcebc4f8342c4c7c50e3b61fa6c68c1ad

I cross-built test/run-pass/smallest-hello-world.rs and confirmed it works.
However, I also found something went wrong if I don't have custom `#[start]` routine.

14 files changed:
src/librustc/middle/trans/base.rs
src/libstd/io.rs
src/libstd/libc.rs
src/libstd/os.rs
src/libstd/rt/context.rs
src/libstd/rt/thread_local_storage.rs
src/libstd/unstable/dynamic_lib.rs
src/rt/arch/x86_64/_context.S
src/rt/arch/x86_64/ccall.S
src/rt/arch/x86_64/morestack.S
src/rt/arch/x86_64/regs.h
src/rt/arch/x86_64/sp.h
src/rt/rust_upcall.cpp
src/rt/vg/valgrind.h

index 634e339e03de068bf7ac9220f1ac2e2e944bbf70..1fc682912b35f38af8c22ec3bf9d056d6f6e9168 100644 (file)
@@ -2370,7 +2370,12 @@ fn create_entry_fn(ccx: @mut CrateContext,
             decl_cdecl_fn(ccx.llmod, "amain", llfty)
         } else {
             let main_name = match ccx.sess.targ_cfg.os {
-                session::os_win32 => ~"WinMain@16",
+                session::os_win32 => {
+                    match ccx.sess.targ_cfg.arch {
+                        X86 => ~"WinMain@16",
+                        _ => ~"WinMain",
+                    }
+                },
                 _ => ~"main",
             };
             decl_cdecl_fn(ccx.llmod, main_name, llfty)
index 2412ce9daf3c1a569ff929b1ee109249d46d6224..e3f88033bd06bc74296c46e91e9d7b9d97a571ee 100644 (file)
@@ -53,7 +53,7 @@
 use int;
 use iterator::Iterator;
 use libc::consts::os::posix88::*;
-use libc::{c_int, c_long, c_void, size_t, ssize_t};
+use libc::{c_int, c_void, size_t};
 use libc;
 use num;
 use ops::Drop;
@@ -970,7 +970,7 @@ fn seek(&self, offset: int, whence: SeekStyle) {
 
         unsafe {
             assert!(libc::fseek(*self,
-                                     offset as c_long,
+                                     offset as libc::c_long,
                                      convert_whence(whence)) == 0 as c_int);
         }
     }
@@ -1199,7 +1199,7 @@ fn seek(&self, offset: int, whence: SeekStyle) {
 
         unsafe {
             assert!(libc::fseek(*self,
-                                     offset as c_long,
+                                     offset as libc::c_long,
                                      convert_whence(whence)) == 0 as c_int);
         }
     }
@@ -1240,13 +1240,23 @@ impl Writer for fd_t {
     fn write(&self, v: &[u8]) {
         #[fixed_stack_segment]; #[inline(never)];
 
+        #[cfg(windows)]
+        type IoSize = libc::c_uint;
+        #[cfg(windows)]
+        type IoRet = c_int;
+
+        #[cfg(unix)]
+        type IoSize = size_t;
+        #[cfg(unix)]
+        type IoRet = libc::ssize_t;
+
         unsafe {
             let mut count = 0u;
             do v.as_imm_buf |vbuf, len| {
                 while count < len {
                     let vb = ptr::offset(vbuf, count as int) as *c_void;
-                    let nout = libc::write(*self, vb, len as size_t);
-                    if nout < 0 as ssize_t {
+                    let nout = libc::write(*self, vb, len as IoSize);
+                    if nout < 0 as IoRet {
                         error!("error writing buffer");
                         error!("%s", os::last_os_error());
                         fail!();
index 26b4f15f3e99f4d7fc31b9747d0c3ec800acfad4..790dc886c0497d94f010622fa53d78213ee8cf1e 100644 (file)
@@ -764,6 +764,172 @@ pub struct MEMORY_BASIC_INFORMATION {
                 pub type LPMEMORY_BASIC_INFORMATION = *mut MEMORY_BASIC_INFORMATION;
             }
         }
+
+        #[cfg(target_arch = "x86_64")]
+        pub mod arch {
+            pub mod c95 {
+                pub type c_char = i8;
+                pub type c_schar = i8;
+                pub type c_uchar = u8;
+                pub type c_short = i16;
+                pub type c_ushort = u16;
+                pub type c_int = i32;
+                pub type c_uint = u32;
+                pub type c_long = i32;
+                pub type c_ulong = u32;
+                pub type c_float = f32;
+                pub type c_double = f64;
+                pub type size_t = u64;
+                pub type ptrdiff_t = i64;
+                pub type clock_t = i32;
+                pub type time_t = i64;
+                pub type wchar_t = u16;
+            }
+            pub mod c99 {
+                pub type c_longlong = i64;
+                pub type c_ulonglong = u64;
+                pub type intptr_t = int;
+                pub type uintptr_t = uint;
+            }
+            pub mod posix88 {
+                pub type off_t = i32; // XXX unless _FILE_OFFSET_BITS == 64
+                pub type dev_t = u32;
+                pub type ino_t = i16;
+                pub type pid_t = i64;
+                pub type useconds_t = u32;
+                pub type mode_t = u16;
+                pub type ssize_t = i64;
+            }
+            pub mod posix01 {
+            }
+            pub mod posix08 {
+            }
+            pub mod bsd44 {
+            }
+            pub mod extra {
+                use ptr;
+                use libc::types::common::c95::c_void;
+                use libc::types::os::arch::c95::{c_char, c_int, c_uint, size_t};
+                use libc::types::os::arch::c95::{c_ulong};
+                use libc::types::os::arch::c95::{wchar_t};
+                use libc::types::os::arch::c99::{c_ulonglong};
+
+                pub type BOOL = c_int;
+                pub type BYTE = u8;
+                pub type CCHAR = c_char;
+                pub type CHAR = c_char;
+
+                pub type DWORD = c_ulong;
+                pub type DWORDLONG = c_ulonglong;
+
+                pub type HANDLE = LPVOID;
+                pub type HMODULE = c_uint;
+
+                pub type LONG_PTR = i64; // changed
+
+                pub type LPCWSTR = *WCHAR;
+                pub type LPCSTR = *CHAR;
+                pub type LPCTSTR = *CHAR;
+                pub type LPTCH = *CHAR;
+
+                pub type LPWSTR = *mut WCHAR;
+                pub type LPSTR = *mut CHAR;
+                pub type LPTSTR = *mut CHAR;
+
+                // Not really, but opaque to us.
+                pub type LPSECURITY_ATTRIBUTES = LPVOID;
+
+                pub type LPVOID = *mut c_void;
+                pub type LPCVOID = *c_void;
+                pub type LPBYTE = *mut BYTE;
+                pub type LPWORD = *mut WORD;
+                pub type LPDWORD = *mut DWORD;
+                pub type LPHANDLE = *mut HANDLE;
+
+                pub type LRESULT = LONG_PTR;
+                pub type PBOOL = *mut BOOL;
+                pub type WCHAR = wchar_t;
+                pub type WORD = u16;
+                pub type SIZE_T = size_t;
+
+                pub type time64_t = i64;
+                pub type int64 = i64;
+
+                pub struct STARTUPINFO {
+                    cb: DWORD,
+                    lpReserved: LPTSTR,
+                    lpDesktop: LPTSTR,
+                    lpTitle: LPTSTR,
+                    dwX: DWORD,
+                    dwY: DWORD,
+                    dwXSize: DWORD,
+                    dwYSize: DWORD,
+                    dwXCountChars: DWORD,
+                    dwYCountCharts: DWORD,
+                    dwFillAttribute: DWORD,
+                    dwFlags: DWORD,
+                    wShowWindow: WORD,
+                    cbReserved2: WORD,
+                    lpReserved2: LPBYTE,
+                    hStdInput: HANDLE,
+                    hStdOutput: HANDLE,
+                    hStdError: HANDLE
+                }
+                pub type LPSTARTUPINFO = *mut STARTUPINFO;
+
+                pub struct PROCESS_INFORMATION {
+                    hProcess: HANDLE,
+                    hThread: HANDLE,
+                    dwProcessId: DWORD,
+                    dwThreadId: DWORD
+                }
+                pub type LPPROCESS_INFORMATION = *mut PROCESS_INFORMATION;
+
+                pub struct SYSTEM_INFO {
+                    wProcessorArchitecture: WORD,
+                    wReserved: WORD,
+                    dwPageSize: DWORD,
+                    lpMinimumApplicationAddress: LPVOID,
+                    lpMaximumApplicationAddress: LPVOID,
+                    dwActiveProcessorMask: DWORD,
+                    dwNumberOfProcessors: DWORD,
+                    dwProcessorType: DWORD,
+                    dwAllocationGranularity: DWORD,
+                    wProcessorLevel: WORD,
+                    wProcessorRevision: WORD
+                }
+                pub type LPSYSTEM_INFO = *mut SYSTEM_INFO;
+
+                impl SYSTEM_INFO {
+                    pub fn new() -> SYSTEM_INFO {
+                        SYSTEM_INFO {
+                            wProcessorArchitecture: 0,
+                            wReserved: 0,
+                            dwPageSize: 0,
+                            lpMinimumApplicationAddress: ptr::mut_null(),
+                            lpMaximumApplicationAddress: ptr::mut_null(),
+                            dwActiveProcessorMask: 0,
+                            dwNumberOfProcessors: 0,
+                            dwProcessorType: 0,
+                            dwAllocationGranularity: 0,
+                            wProcessorLevel: 0,
+                            wProcessorRevision: 0
+                        }
+                    }
+                }
+
+                pub struct MEMORY_BASIC_INFORMATION {
+                    BaseAddress: LPVOID,
+                    AllocationBase: LPVOID,
+                    AllocationProtect: DWORD,
+                    RegionSize: SIZE_T,
+                    State: DWORD,
+                    Protect: DWORD,
+                    Type: DWORD
+                }
+                pub type LPMEMORY_BASIC_INFORMATION = *mut MEMORY_BASIC_INFORMATION;
+            }
+        }
     }
 
     #[cfg(target_os = "macos")]
@@ -3093,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,
@@ -3197,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 {
index 0b5f53dbf19e407b2fcdb6ccbeba28005ed285ab..e7caf3f23abae8697754909d85ea9a49cb5f23cf 100644 (file)
@@ -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]
 }
index 5aaddc68383f1e34171aff4f29347f6970e275e0..476554bf7f7bec7801bf58332bc5ede4e700cbf2 100644 (file)
@@ -47,6 +47,7 @@ pub fn new(start: ~fn(), stack: &mut StackSegment) -> Context {
 
         let fp: *c_void = task_start_wrapper as *c_void;
         let argp: *c_void = unsafe { transmute::<&~fn(), *c_void>(&*start) };
+        let stack_base: *uint = stack.start();
         let sp: *uint = stack.end();
         let sp: *mut uint = unsafe { transmute_mut_unsafe(sp) };
         // Save and then immediately load the current context,
@@ -56,7 +57,7 @@ pub fn new(start: ~fn(), stack: &mut StackSegment) -> Context {
             swap_registers(transmute_mut_region(&mut *regs), transmute_region(&*regs));
         };
 
-        initialize_call_frame(&mut *regs, fp, argp, sp);
+        initialize_call_frame(&mut *regs, fp, argp, sp, stack_base);
 
         return Context {
             start: Some(start),
@@ -107,7 +108,8 @@ fn new_regs() -> ~Registers {
 }
 
 #[cfg(target_arch = "x86")]
-fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void, sp: *mut uint) {
+fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void,
+                         sp: *mut uint, _stack_base: *uint) {
 
     let sp = align_down(sp);
     let sp = mut_offset(sp, -4);
@@ -123,14 +125,19 @@ fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void, sp:
     regs.ebp = 0;
 }
 
-#[cfg(target_arch = "x86_64")]
+#[cfg(windows, target_arch = "x86_64")]
+type Registers = [uint, ..34];
+#[cfg(not(windows), target_arch = "x86_64")]
 type Registers = [uint, ..22];
 
-#[cfg(target_arch = "x86_64")]
+#[cfg(windows, target_arch = "x86_64")]
+fn new_regs() -> ~Registers { ~([0, .. 34]) }
+#[cfg(not(windows), target_arch = "x86_64")]
 fn new_regs() -> ~Registers { ~([0, .. 22]) }
 
 #[cfg(target_arch = "x86_64")]
-fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void, sp: *mut uint) {
+fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void,
+                         sp: *mut uint, stack_base: *uint) {
 
     // Redefinitions from regs.h
     static RUSTRT_ARG0: uint = 3;
@@ -138,6 +145,21 @@ fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void, sp:
     static RUSTRT_IP: uint = 8;
     static RUSTRT_RBP: uint = 2;
 
+    #[cfg(windows)]
+    fn initialize_tib(regs: &mut Registers, sp: *mut uint, stack_base: *uint) {
+        // Redefinitions from regs.h
+        static RUSTRT_ST1: uint = 11; // stack bottom
+        static RUSTRT_ST2: uint = 12; // stack top
+        regs[RUSTRT_ST1] = sp as uint;
+        regs[RUSTRT_ST2] = stack_base as uint;
+    }
+    #[cfg(not(windows))]
+    fn initialize_tib(_: &mut Registers, _: *mut uint, _: *uint) {
+    }
+
+    // Win64 manages stack range at TIB: %gs:0x08 (top) and %gs:0x10 (bottom)
+    initialize_tib(regs, sp, stack_base);
+
     let sp = align_down(sp);
     let sp = mut_offset(sp, -1);
 
@@ -164,7 +186,8 @@ fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void, sp:
 fn new_regs() -> ~Registers { ~([0, .. 32]) }
 
 #[cfg(target_arch = "arm")]
-fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void, sp: *mut uint) {
+fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void,
+                         sp: *mut uint, _stack_base: *uint) {
     let sp = align_down(sp);
     // sp of arm eabi is 8-byte aligned
     let sp = mut_offset(sp, -2);
@@ -184,7 +207,8 @@ fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void, sp:
 fn new_regs() -> ~Registers { ~([0, .. 32]) }
 
 #[cfg(target_arch = "mips")]
-fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void, sp: *mut uint) {
+fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void,
+                         sp: *mut uint, _stack_base: *uint) {
     let sp = align_down(sp);
     // sp of mips o32 is 8-byte aligned
     let sp = mut_offset(sp, -2);
index a9cd29c18c9652d58a2fbe10704d236bf6650ccb..b2c2c670b5558eec4482738cb44789622a9967b0 100644 (file)
@@ -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;
index 6dbe68200b3b7fe23d28c62b72dc39083e7ec993..90cf49cad1ccf2a9553507091bfa31c925ee146b 100644 (file)
@@ -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);
+    }
 }
index f718cac963470402a7844e36dfa34f1ff188fc36..857fe91c9141b85c1603cedf69433ffa78317eba 100644 (file)
@@ -54,7 +54,7 @@ First four arguments:
         anyhow.
 */
 
-#if defined(__APPLE__) || defined(_WIN32)
+#if defined(__APPLE__)
 #define SWAP_REGISTERS _swap_registers
 #else
 #define SWAP_REGISTERS swap_registers
@@ -86,16 +86,40 @@ SWAP_REGISTERS:
         mov %r14, (RUSTRT_R14*8)(ARG0)
         mov %r15, (RUSTRT_R15*8)(ARG0)
 
+#if defined(__MINGW32__) || defined(_WINDOWS)
+        mov %rdi, (RUSTRT_RDI*8)(ARG0)
+        mov %rsi, (RUSTRT_RSI*8)(ARG0)
+
+        // Save stack range
+        mov %gs:0x08, %r8
+        mov %r8, (RUSTRT_ST1*8)(ARG0)
+        mov %gs:0x10, %r9
+        mov %r9, (RUSTRT_ST2*8)(ARG0)
+#endif
+
         // Save 0th argument register:
         mov ARG0, (RUSTRT_ARG0*8)(ARG0)
 
         // Save non-volatile XMM registers:
+#if defined(__MINGW32__) || defined(_WINDOWS)
+        movapd %xmm6, (RUSTRT_XMM6*8)(ARG0)
+        movapd %xmm7, (RUSTRT_XMM7*8)(ARG0)
+        movapd %xmm8, (RUSTRT_XMM8*8)(ARG0)
+        movapd %xmm9, (RUSTRT_XMM9*8)(ARG0)
+        movapd %xmm10, (RUSTRT_XMM10*8)(ARG0)
+        movapd %xmm11, (RUSTRT_XMM11*8)(ARG0)
+        movapd %xmm12, (RUSTRT_XMM12*8)(ARG0)
+        movapd %xmm13, (RUSTRT_XMM13*8)(ARG0)
+        movapd %xmm14, (RUSTRT_XMM14*8)(ARG0)
+        movapd %xmm15, (RUSTRT_XMM15*8)(ARG0)
+#else
         movapd %xmm0, (RUSTRT_XMM0*8)(ARG0)
         movapd %xmm1, (RUSTRT_XMM1*8)(ARG0)
         movapd %xmm2, (RUSTRT_XMM2*8)(ARG0)
         movapd %xmm3, (RUSTRT_XMM3*8)(ARG0)
         movapd %xmm4, (RUSTRT_XMM4*8)(ARG0)
         movapd %xmm5, (RUSTRT_XMM5*8)(ARG0)
+#endif
 
         // Restore non-volatile integer registers:
         //   (including RSP)
@@ -107,16 +131,40 @@ SWAP_REGISTERS:
         mov (RUSTRT_R14*8)(ARG1), %r14
         mov (RUSTRT_R15*8)(ARG1), %r15
 
+#if defined(__MINGW32__) || defined(_WINDOWS)
+        mov (RUSTRT_RDI*8)(ARG1), %rdi
+        mov (RUSTRT_RSI*8)(ARG1), %rsi
+
+        // Restore stack range
+        mov (RUSTRT_ST1*8)(ARG1), %r8
+        mov %r8, %gs:0x08
+        mov (RUSTRT_ST2*8)(ARG1), %r9
+        mov %r9, %gs:0x10
+#endif
+
         // Restore 0th argument register:
         mov (RUSTRT_ARG0*8)(ARG1), ARG0
 
         // Restore non-volatile XMM registers:
+#if defined(__MINGW32__) || defined(_WINDOWS)
+        movapd (RUSTRT_XMM6*8)(ARG1), %xmm6
+        movapd (RUSTRT_XMM7*8)(ARG1), %xmm7
+        movapd (RUSTRT_XMM8*8)(ARG1), %xmm8
+        movapd (RUSTRT_XMM9*8)(ARG1), %xmm9
+        movapd (RUSTRT_XMM10*8)(ARG1), %xmm10
+        movapd (RUSTRT_XMM11*8)(ARG1), %xmm11
+        movapd (RUSTRT_XMM12*8)(ARG1), %xmm12
+        movapd (RUSTRT_XMM13*8)(ARG1), %xmm13
+        movapd (RUSTRT_XMM14*8)(ARG1), %xmm14
+        movapd (RUSTRT_XMM15*8)(ARG1), %xmm15
+#else
         movapd (RUSTRT_XMM0*8)(ARG1), %xmm0
         movapd (RUSTRT_XMM1*8)(ARG1), %xmm1
         movapd (RUSTRT_XMM2*8)(ARG1), %xmm2
         movapd (RUSTRT_XMM3*8)(ARG1), %xmm3
         movapd (RUSTRT_XMM4*8)(ARG1), %xmm4
         movapd (RUSTRT_XMM5*8)(ARG1), %xmm5
+#endif
 
         // Jump to the instruction pointer
         // found in regs:
index d4bc37fee957d3f6ac62b43e4c6b7369693a3d5f..dbee5bcdc90a3222e518d9d6fee72391c3a4de82 100644 (file)
 
         .text
 
-#if defined(__APPLE__) || defined(_WIN32)
+#if defined(__APPLE__)
 .globl ___morestack
 .private_extern MORESTACK
 ___morestack:
+#elif defined(_WIN32)
+.globl __morestack
+__morestack:
 #else
 .globl __morestack
 .hidden __morestack
index 9d16afc0a1b3546cca2664f4b1d9acd0e6dc568a..b718c9121c57b8a3d30143c3f0c16508a49ce384 100644 (file)
@@ -11,7 +11,7 @@
 
 .text
 
-#if defined(__APPLE__) || defined(_WIN32)
+#if defined(__APPLE__)
 #define UPCALL_NEW_STACK        _upcall_new_stack
 #define UPCALL_DEL_STACK        _upcall_del_stack
 #define MORESTACK               ___morestack
index 1aca452df108b84e7fb0ccb77c54127e5d7c537c..cff47ac378af0e192a739b9382206865263ed52c 100644 (file)
 #define RUSTRT_R14   6
 #define RUSTRT_R15   7
 #define RUSTRT_IP    8
-// Not used, just padding
-#define RUSTRT_XXX   9
-#define RUSTRT_XMM0 10
-#define RUSTRT_XMM1 12
-#define RUSTRT_XMM2 14
-#define RUSTRT_XMM3 16
-#define RUSTRT_XMM4 18
-#define RUSTRT_XMM5 20
-#define RUSTRT_MAX  22
+#if defined(__MINGW32__) || defined(_WINDOWS)
+    #define RUSTRT_RDI   9
+    #define RUSTRT_RSI   10
+    #define RUSTRT_ST1   11
+    #define RUSTRT_ST2   12
+    #define RUSTRT_XMM6  14
+    #define RUSTRT_XMM7  16
+    #define RUSTRT_XMM8  18
+    #define RUSTRT_XMM9  20
+    #define RUSTRT_XMM10 22
+    #define RUSTRT_XMM11 24
+    #define RUSTRT_XMM12 26
+    #define RUSTRT_XMM13 28
+    #define RUSTRT_XMM14 30
+    #define RUSTRT_XMM15 32
+    #define RUSTRT_MAX   34
+#else
+    // Not used, just padding
+    #define RUSTRT_XXX   9
+    #define RUSTRT_XMM0 10
+    #define RUSTRT_XMM1 12
+    #define RUSTRT_XMM2 14
+    #define RUSTRT_XMM3 16
+    #define RUSTRT_XMM4 18
+    #define RUSTRT_XMM5 20
+    #define RUSTRT_MAX  22
+#endif
 
 // ARG0 is the register in which the first argument goes.
 // Naturally this depends on your operating system.
index bf011f4d01976aee960105858f1805aafa28e29b..764927759fe684bf17ca0996160340d21b5d5401 100644 (file)
@@ -43,6 +43,10 @@ extern "C" CDECL ALWAYS_INLINE uintptr_t get_sp_limit() {
     asm volatile (
         "movq %%fs:24, %0"
         : "=r"(limit));
+#elif defined(_WIN64)
+    asm volatile (
+        "movq %%gs:0x28, %0"
+        : "=r"(limit));
 #endif
 
     return limit;
@@ -65,6 +69,10 @@ extern "C" CDECL ALWAYS_INLINE void record_sp_limit(void *limit) {
     asm volatile (
         "movq %0, %%fs:24"
         :: "r"(limit));
+#elif defined(_WIN64)
+    asm volatile (
+        "movq %0, %%gs:0x28"
+        :: "r"(limit));
 #endif
 }
 
index 21c0d219242613d91a75518af7b2ae391404115c..7ccb06a3296f4ced2905c390e120e949e6b8f317 100644 (file)
@@ -54,8 +54,18 @@ upcall_call_shim_on_rust_stack(void *args, void *fn_ptr) {
 
 /**********************************************************************/
 
+#ifdef __SEH__
+#  define PERSONALITY_FUNC __gxx_personality_seh0
+#else
+#  ifdef __USING_SJLJ_EXCEPTIONS__
+#    define PERSONALITY_FUNC __gxx_personality_sjlj
+#  else
+#    define PERSONALITY_FUNC __gxx_personality_v0
+#  endif
+#endif
+
 extern "C" _Unwind_Reason_Code
-__gxx_personality_v0(int version,
+PERSONALITY_FUNC(int version,
                      _Unwind_Action actions,
                      uint64_t exception_class,
                      _Unwind_Exception *ue_header,
@@ -72,11 +82,11 @@ struct s_rust_personality_args {
 
 extern "C" void
 upcall_s_rust_personality(s_rust_personality_args *args) {
-    args->retval = __gxx_personality_v0(args->version,
-                                        args->actions,
-                                        args->exception_class,
-                                        args->ue_header,
-                                        args->context);
+    args->retval = PERSONALITY_FUNC(args->version,
+                                    args->actions,
+                                    args->exception_class,
+                                    args->ue_header,
+                                    args->context);
 }
 
 /**
index 222a58e156323c6c183db5856690d6fea8d55a09..c9aa0fd0328356b0d3b376fc575b2ad6420074d4 100644 (file)
 #undef PLAT_x86_darwin
 #undef PLAT_amd64_darwin
 #undef PLAT_x86_win32
+#undef PLAT_amd64_win64
 #undef PLAT_x86_linux
 #undef PLAT_amd64_linux
 #undef PLAT_ppc32_linux
 #  define PLAT_amd64_darwin 1
 #elif defined(__MINGW32__) || defined(__CYGWIN32__) \
       || (defined(_WIN32) && defined(_M_IX86))
-#  define PLAT_x86_win32 1
+#  if defined(__x86_64__)
+#    define PLAT_amd64_win64 1
+#  elif defined(__i386__)
+#    define PLAT_x86_win32 1
+#  endif
 #elif defined(__linux__) && defined(__i386__)
 #  define PLAT_x86_linux 1
 #elif defined(__linux__) && defined(__x86_64__)
@@ -349,7 +354,8 @@ valgrind_do_client_request_expr(uintptr_t _zzq_default, uintptr_t _zzq_request,
 
 /* ------------------------ amd64-{linux,darwin} --------------- */
 
-#if defined(PLAT_amd64_linux)  ||  defined(PLAT_amd64_darwin)
+#if defined(PLAT_amd64_linux)  ||  defined(PLAT_amd64_darwin) \
+    || defined(PLAT_amd64_win64)
 
 typedef
    struct { 
@@ -3716,14 +3722,14 @@ VALGRIND_PRINTF(const char *format, ...)
 #if defined(NVALGRIND)
    return 0;
 #else /* NVALGRIND */
-#if defined(_MSC_VER)
+#if defined(_MSC_VER) || defined(PLAT_amd64_win64)
    uintptr_t _qzz_res;
 #else
    unsigned long _qzz_res;
 #endif
    va_list vargs;
    va_start(vargs, format);
-#if defined(_MSC_VER)
+#if defined(_MSC_VER) || defined(PLAT_amd64_win64)
    _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0,
                               VG_USERREQ__PRINTF_VALIST_BY_REF,
                               (uintptr_t)format,
@@ -3754,14 +3760,14 @@ VALGRIND_PRINTF_BACKTRACE(const char *format, ...)
 #if defined(NVALGRIND)
    return 0;
 #else /* NVALGRIND */
-#if defined(_MSC_VER)
+#if defined(_MSC_VER) || defined(PLAT_amd64_win64)
    uintptr_t _qzz_res;
 #else
    unsigned long _qzz_res;
 #endif
    va_list vargs;
    va_start(vargs, format);
-#if defined(_MSC_VER)
+#if defined(_MSC_VER) || defined(PLAT_amd64_win64)
    _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0,
                               VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF,
                               (uintptr_t)format,