migrate more functions

This commit is contained in:
Christian Poveda 2020-02-05 19:46:50 -05:00
parent e7d6e718b9
commit f2f8fb2c20
No known key found for this signature in database
GPG Key ID: 27525EF5E7420A50
4 changed files with 160 additions and 157 deletions

View File

@ -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)?,

View File

@ -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),
};

View File

@ -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),
};

View File

@ -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),
}