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)
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;
unsafe {
assert!(libc::fseek(*self,
- offset as c_long,
+ offset as libc::c_long,
convert_whence(whence)) == 0 as c_int);
}
}
unsafe {
assert!(libc::fseek(*self,
- offset as c_long,
+ offset as libc::c_long,
convert_whence(whence)) == 0 as c_int);
}
}
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!();
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")]
LPSYSTEM_INFO};
use libc::types::os::arch::extra::{HANDLE, LPHANDLE};
+ #[cfg(target_arch = "x86")]
#[abi = "stdcall"]
extern "stdcall" {
pub fn GetEnvironmentVariableW(n: LPCWSTR,
-> 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 {
#[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
}
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" {
-> 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;
type LPCWSTR = *u16;
-#[cfg(windows)]
+#[cfg(windows, target_arch = "x86")]
#[link_name="kernel32"]
#[abi="stdcall"]
extern "stdcall" {
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]
}
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,
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),
}
#[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);
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;
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);
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);
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);
TlsGetValue(key)
}
-#[cfg(windows)]
+#[cfg(windows, target_arch = "x86")]
#[abi = "stdcall"]
extern "stdcall" {
fn TlsAlloc() -> DWORD;
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;
FreeLibrary(handle); ()
}
+ #[cfg(target_arch = "x86")]
#[link_name = "kernel32"]
extern "stdcall" {
fn SetLastError(error: u32);
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);
+ }
}
anyhow.
*/
-#if defined(__APPLE__) || defined(_WIN32)
+#if defined(__APPLE__)
#define SWAP_REGISTERS _swap_registers
#else
#define SWAP_REGISTERS 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)
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:
.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
.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
#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.
asm volatile (
"movq %%fs:24, %0"
: "=r"(limit));
+#elif defined(_WIN64)
+ asm volatile (
+ "movq %%gs:0x28, %0"
+ : "=r"(limit));
#endif
return limit;
asm volatile (
"movq %0, %%fs:24"
:: "r"(limit));
+#elif defined(_WIN64)
+ asm volatile (
+ "movq %0, %%gs:0x28"
+ :: "r"(limit));
#endif
}
/**********************************************************************/
+#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,
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);
}
/**
#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__)
/* ------------------------ 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 {
#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,
#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,