this.write_null(dest)?;
}
- // macOS API stubs.
- | "pthread_attr_get_np"
- | "pthread_getattr_np"
- => {
- this.write_null(dest)?;
- }
- "pthread_get_stackaddr_np" => {
- let stack_addr = Scalar::from_uint(STACK_ADDR, dest.layout.size);
- this.write_scalar(stack_addr, dest)?;
- }
- "pthread_get_stacksize_np" => {
- let stack_size = Scalar::from_uint(STACK_SIZE, dest.layout.size);
- this.write_scalar(stack_size, dest)?;
- }
- "_tlv_atexit" => {
- // FIXME: register the destructor.
- }
- "_NSGetArgc" => {
- this.write_scalar(this.machine.argc.expect("machine must be initialized"), dest)?;
- }
- "_NSGetArgv" => {
- this.write_scalar(this.machine.argv.expect("machine must be initialized"), dest)?;
- }
- "SecRandomCopyBytes" => {
- let len = this.read_scalar(args[1])?.to_machine_usize(this)?;
- let ptr = this.read_scalar(args[2])?.not_undef()?;
- this.gen_random(ptr, len as usize)?;
- this.write_null(dest)?;
- }
-
- // Windows API stubs.
- // HANDLE = isize
- // DWORD = ULONG = u32
- // BOOL = i32
- "GetProcessHeap" => {
- // Just fake a HANDLE
- this.write_scalar(Scalar::from_int(1, this.pointer_size()), dest)?;
- }
- "HeapAlloc" => {
- let _handle = this.read_scalar(args[0])?.to_machine_isize(this)?;
- let flags = this.read_scalar(args[1])?.to_u32()?;
- let size = this.read_scalar(args[2])?.to_machine_usize(this)?;
- let zero_init = (flags & 0x00000008) != 0; // HEAP_ZERO_MEMORY
- let res = this.malloc(size, zero_init, MiriMemoryKind::WinHeap);
- this.write_scalar(res, dest)?;
- }
- "HeapFree" => {
- let _handle = this.read_scalar(args[0])?.to_machine_isize(this)?;
- let _flags = this.read_scalar(args[1])?.to_u32()?;
- let ptr = this.read_scalar(args[2])?.not_undef()?;
- this.free(ptr, MiriMemoryKind::WinHeap)?;
- this.write_scalar(Scalar::from_int(1, Size::from_bytes(4)), dest)?;
- }
- "HeapReAlloc" => {
- let _handle = this.read_scalar(args[0])?.to_machine_isize(this)?;
- let _flags = this.read_scalar(args[1])?.to_u32()?;
- let ptr = this.read_scalar(args[2])?.not_undef()?;
- let size = this.read_scalar(args[3])?.to_machine_usize(this)?;
- let res = this.realloc(ptr, size, MiriMemoryKind::WinHeap)?;
- this.write_scalar(res, dest)?;
- }
-
- "SetLastError" => {
- this.set_last_error(this.read_scalar(args[0])?.not_undef()?)?;
- }
- "GetLastError" => {
- let last_error = this.get_last_error()?;
- this.write_scalar(last_error, dest)?;
- }
-
- "AddVectoredExceptionHandler" => {
- // Any non zero value works for the stdlib. This is just used for stack overflows anyway.
- this.write_scalar(Scalar::from_int(1, dest.layout.size), dest)?;
- }
-
- | "InitializeCriticalSection"
- | "EnterCriticalSection"
- | "LeaveCriticalSection"
- | "DeleteCriticalSection"
- => {
- // Nothing to do, not even a return value.
- }
-
- | "GetModuleHandleW"
- | "GetProcAddress"
- | "TryEnterCriticalSection"
- | "GetConsoleScreenBufferInfo"
- | "SetConsoleTextAttribute"
- => {
- // Pretend these do not exist / nothing happened, by returning zero.
- this.write_null(dest)?;
- }
-
- "GetSystemInfo" => {
- let system_info = this.deref_operand(args[0])?;
- // Initialize with `0`.
- this.memory.write_bytes(
- system_info.ptr,
- iter::repeat(0u8).take(system_info.layout.size.bytes() as usize),
- )?;
- // Set number of processors.
- let dword_size = Size::from_bytes(4);
- let num_cpus = this.mplace_field(system_info, 6)?;
- this.write_scalar(Scalar::from_int(NUM_CPUS, dword_size), num_cpus.into())?;
- }
-
- "TlsAlloc" => {
- // This just creates a key; Windows does not natively support TLS destructors.
-
- // Create key and return it.
- let key = this.machine.tls.create_tls_key(None) as u128;
-
- // Figure out how large a TLS key actually is. This is `c::DWORD`.
- if dest.layout.size.bits() < 128
- && key >= (1u128 << dest.layout.size.bits() as u128)
- {
- throw_unsup!(OutOfTls);
- }
- this.write_scalar(Scalar::from_uint(key, dest.layout.size), dest)?;
- }
- "TlsGetValue" => {
- let key = this.read_scalar(args[0])?.to_u32()? as u128;
- let ptr = this.machine.tls.load_tls(key, tcx)?;
- this.write_scalar(ptr, dest)?;
- }
- "TlsSetValue" => {
- let key = this.read_scalar(args[0])?.to_u32()? as u128;
- let new_ptr = this.read_scalar(args[1])?.not_undef()?;
- this.machine.tls.store_tls(key, this.test_null(new_ptr)?)?;
-
- // Return success (`1`).
- this.write_scalar(Scalar::from_int(1, dest.layout.size), dest)?;
- }
- "GetStdHandle" => {
- let which = this.read_scalar(args[0])?.to_i32()?;
- // We just make this the identity function, so we know later in `WriteFile`
- // which one it is.
- this.write_scalar(Scalar::from_int(which, this.pointer_size()), dest)?;
- }
- "GetConsoleMode" => {
- // Everything is a pipe.
- this.write_null(dest)?;
- }
- "GetCommandLineW" => {
- this.write_scalar(
- this.machine.cmd_line.expect("machine must be initialized"),
- dest,
- )?;
- }
- // The actual name of 'RtlGenRandom'
- "SystemFunction036" => {
- let ptr = this.read_scalar(args[0])?.not_undef()?;
- let len = this.read_scalar(args[1])?.to_u32()?;
- this.gen_random(ptr, len as usize)?;
- this.write_scalar(Scalar::from_bool(true), dest)?;
- }
-
_ => match this.tcx.sess.target.target.target_os.to_lowercase().as_str() {
"linux" | "macos" => posix::EvalContextExt::emulate_foreign_item_by_name(this, link_name, args, dest)?,
"windows" => windows::EvalContextExt::emulate_foreign_item_by_name(this, link_name, args, dest)?,
this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;
}
+ "pthread_getattr_np" => {
+ this.write_null(dest)?;
+ }
_ => throw_unsup_format!("can't call foreign function: {}", link_name),
};
this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;
}
+ // macOS API stubs.
+ "pthread_attr_get_np" => {
+ this.write_null(dest)?;
+ }
+ "pthread_get_stackaddr_np" => {
+ let stack_addr = Scalar::from_uint(STACK_ADDR, dest.layout.size);
+ this.write_scalar(stack_addr, dest)?;
+ }
+ "pthread_get_stacksize_np" => {
+ let stack_size = Scalar::from_uint(STACK_SIZE, dest.layout.size);
+ this.write_scalar(stack_size, dest)?;
+ }
+ "_tlv_atexit" => {
+ // FIXME: register the destructor.
+ }
+ "_NSGetArgc" => {
+ this.write_scalar(this.machine.argc.expect("machine must be initialized"), dest)?;
+ }
+ "_NSGetArgv" => {
+ this.write_scalar(this.machine.argv.expect("machine must be initialized"), dest)?;
+ }
+ "SecRandomCopyBytes" => {
+ let len = this.read_scalar(args[1])?.to_machine_usize(this)?;
+ let ptr = this.read_scalar(args[2])?.not_undef()?;
+ this.gen_random(ptr, len as usize)?;
+ this.write_null(dest)?;
+ }
+
+
_ => throw_unsup_format!("can't call foreign function: {}", link_name),
};
use crate::*;
use rustc::ty::layout::Size;
+use std::iter;
impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
dest: PlaceTy<'tcx, Tag>,
) -> InterpResult<'tcx> {
let this = self.eval_context_mut();
+ let tcx = &{ this.tcx.tcx };
match link_name {
// Environment related shims
dest,
)?;
}
+ // Windows API stubs.
+ // HANDLE = isize
+ // DWORD = ULONG = u32
+ // BOOL = i32
+ "GetProcessHeap" => {
+ // Just fake a HANDLE
+ this.write_scalar(Scalar::from_int(1, this.pointer_size()), dest)?;
+ }
+ "HeapAlloc" => {
+ let _handle = this.read_scalar(args[0])?.to_machine_isize(this)?;
+ let flags = this.read_scalar(args[1])?.to_u32()?;
+ let size = this.read_scalar(args[2])?.to_machine_usize(this)?;
+ let zero_init = (flags & 0x00000008) != 0; // HEAP_ZERO_MEMORY
+ let res = this.malloc(size, zero_init, MiriMemoryKind::WinHeap);
+ this.write_scalar(res, dest)?;
+ }
+ "HeapFree" => {
+ let _handle = this.read_scalar(args[0])?.to_machine_isize(this)?;
+ let _flags = this.read_scalar(args[1])?.to_u32()?;
+ let ptr = this.read_scalar(args[2])?.not_undef()?;
+ this.free(ptr, MiriMemoryKind::WinHeap)?;
+ this.write_scalar(Scalar::from_int(1, Size::from_bytes(4)), dest)?;
+ }
+ "HeapReAlloc" => {
+ let _handle = this.read_scalar(args[0])?.to_machine_isize(this)?;
+ let _flags = this.read_scalar(args[1])?.to_u32()?;
+ let ptr = this.read_scalar(args[2])?.not_undef()?;
+ let size = this.read_scalar(args[3])?.to_machine_usize(this)?;
+ let res = this.realloc(ptr, size, MiriMemoryKind::WinHeap)?;
+ this.write_scalar(res, dest)?;
+ }
+
+ "SetLastError" => {
+ this.set_last_error(this.read_scalar(args[0])?.not_undef()?)?;
+ }
+ "GetLastError" => {
+ let last_error = this.get_last_error()?;
+ this.write_scalar(last_error, dest)?;
+ }
+
+ "AddVectoredExceptionHandler" => {
+ // Any non zero value works for the stdlib. This is just used for stack overflows anyway.
+ this.write_scalar(Scalar::from_int(1, dest.layout.size), dest)?;
+ }
+
+ | "InitializeCriticalSection"
+ | "EnterCriticalSection"
+ | "LeaveCriticalSection"
+ | "DeleteCriticalSection"
+ => {
+ // Nothing to do, not even a return value.
+ }
+
+ | "GetModuleHandleW"
+ | "GetProcAddress"
+ | "TryEnterCriticalSection"
+ | "GetConsoleScreenBufferInfo"
+ | "SetConsoleTextAttribute"
+ => {
+ // Pretend these do not exist / nothing happened, by returning zero.
+ this.write_null(dest)?;
+ }
+
+ "GetSystemInfo" => {
+ let system_info = this.deref_operand(args[0])?;
+ // Initialize with `0`.
+ this.memory.write_bytes(
+ system_info.ptr,
+ iter::repeat(0u8).take(system_info.layout.size.bytes() as usize),
+ )?;
+ // Set number of processors.
+ let dword_size = Size::from_bytes(4);
+ let num_cpus = this.mplace_field(system_info, 6)?;
+ this.write_scalar(Scalar::from_int(NUM_CPUS, dword_size), num_cpus.into())?;
+ }
+
+ "TlsAlloc" => {
+ // This just creates a key; Windows does not natively support TLS destructors.
+
+ // Create key and return it.
+ let key = this.machine.tls.create_tls_key(None) as u128;
+
+ // Figure out how large a TLS key actually is. This is `c::DWORD`.
+ if dest.layout.size.bits() < 128
+ && key >= (1u128 << dest.layout.size.bits() as u128)
+ {
+ throw_unsup!(OutOfTls);
+ }
+ this.write_scalar(Scalar::from_uint(key, dest.layout.size), dest)?;
+ }
+ "TlsGetValue" => {
+ let key = this.read_scalar(args[0])?.to_u32()? as u128;
+ let ptr = this.machine.tls.load_tls(key, tcx)?;
+ this.write_scalar(ptr, dest)?;
+ }
+ "TlsSetValue" => {
+ let key = this.read_scalar(args[0])?.to_u32()? as u128;
+ let new_ptr = this.read_scalar(args[1])?.not_undef()?;
+ this.machine.tls.store_tls(key, this.test_null(new_ptr)?)?;
+
+ // Return success (`1`).
+ this.write_scalar(Scalar::from_int(1, dest.layout.size), dest)?;
+ }
+ "GetStdHandle" => {
+ let which = this.read_scalar(args[0])?.to_i32()?;
+ // We just make this the identity function, so we know later in `WriteFile`
+ // which one it is.
+ this.write_scalar(Scalar::from_int(which, this.pointer_size()), dest)?;
+ }
+ "GetConsoleMode" => {
+ // Everything is a pipe.
+ this.write_null(dest)?;
+ }
+ "GetCommandLineW" => {
+ this.write_scalar(
+ this.machine.cmd_line.expect("machine must be initialized"),
+ dest,
+ )?;
+ }
+ // The actual name of 'RtlGenRandom'
+ "SystemFunction036" => {
+ let ptr = this.read_scalar(args[0])?.not_undef()?;
+ let len = this.read_scalar(args[1])?.to_u32()?;
+ this.gen_random(ptr, len as usize)?;
+ this.write_scalar(Scalar::from_bool(true), dest)?;
+ }
_ => throw_unsup_format!("can't call foreign function: {}", link_name),
}