migrate more functions
This commit is contained in:
parent
e7d6e718b9
commit
f2f8fb2c20
@ -702,163 +702,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
||||
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)?,
|
||||
|
@ -38,6 +38,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
||||
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),
|
||||
};
|
||||
|
||||
|
@ -53,6 +53,35 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
||||
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),
|
||||
};
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
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> {
|
||||
@ -10,6 +11,7 @@ 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
|
||||
@ -66,6 +68,132 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
||||
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),
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user