refactor dlsym: dispatch symbols via the normal shim mechanism
This commit is contained in:
parent
f9003c08ab
commit
bc8d4dfa95
24 changed files with 168 additions and 461 deletions
|
|
@ -960,7 +960,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
self.check_abi(abi, exp_abi)?;
|
||||
if let Some((body, instance)) = self.eval_context_mut().lookup_exported_symbol(link_name)? {
|
||||
// If compiler-builtins is providing the symbol, then don't treat it as a clash.
|
||||
// We'll use our built-in implementation in `emulate_foreign_item_by_name` for increased
|
||||
// We'll use our built-in implementation in `emulate_foreign_item_inner` for increased
|
||||
// performance. Note that this means we won't catch any undefined behavior in
|
||||
// compiler-builtins when running other crates, but Miri can still be run on
|
||||
// compiler-builtins itself (or any crate that uses it as a normal dependency)
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#![feature(yeet_expr)]
|
||||
#![feature(nonzero_ops)]
|
||||
#![feature(round_ties_even)]
|
||||
#![feature(let_chains)]
|
||||
#![feature(lint_reasons)]
|
||||
#![feature(trait_upcasting)]
|
||||
// Configure clippy and other lints
|
||||
|
|
@ -86,9 +87,8 @@ pub use rustc_const_eval::interpret::*;
|
|||
// Resolve ambiguity.
|
||||
pub use rustc_const_eval::interpret::{self, AllocMap, PlaceTy, Provenance as _};
|
||||
|
||||
pub use crate::shims::dlsym::{Dlsym, EvalContextExt as _};
|
||||
pub use crate::shims::env::{EnvVars, EvalContextExt as _};
|
||||
pub use crate::shims::foreign_items::EvalContextExt as _;
|
||||
pub use crate::shims::foreign_items::{DynSym, EvalContextExt as _};
|
||||
pub use crate::shims::intrinsics::EvalContextExt as _;
|
||||
pub use crate::shims::os_str::EvalContextExt as _;
|
||||
pub use crate::shims::panic::{CatchUnwindData, EvalContextExt as _};
|
||||
|
|
|
|||
|
|
@ -709,9 +709,7 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
|
|||
"android" => {
|
||||
// "signal"
|
||||
let layout = this.machine.layouts.const_raw_ptr;
|
||||
let dlsym = Dlsym::from_str("signal".as_bytes(), &this.tcx.sess.target.os)?
|
||||
.expect("`signal` must be an actual dlsym on android");
|
||||
let ptr = this.fn_ptr(FnVal::Other(dlsym));
|
||||
let ptr = this.fn_ptr(FnVal::Other(DynSym::from_str("signal")));
|
||||
let val = ImmTy::from_scalar(Scalar::from_pointer(ptr, this), layout);
|
||||
Self::alloc_extern_static(this, "signal", val)?;
|
||||
// A couple zero-initialized pointer-sized extern statics.
|
||||
|
|
@ -867,7 +865,7 @@ impl<'mir, 'tcx> MiriInterpCxExt<'mir, 'tcx> for MiriInterpCx<'mir, 'tcx> {
|
|||
/// Machine hook implementations.
|
||||
impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
|
||||
type MemoryKind = MiriMemoryKind;
|
||||
type ExtraFnVal = Dlsym;
|
||||
type ExtraFnVal = DynSym;
|
||||
|
||||
type FrameExtra = FrameExtra<'tcx>;
|
||||
type AllocExtra = AllocExtra<'tcx>;
|
||||
|
|
@ -939,15 +937,15 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
|
|||
#[inline(always)]
|
||||
fn call_extra_fn(
|
||||
ecx: &mut MiriInterpCx<'mir, 'tcx>,
|
||||
fn_val: Dlsym,
|
||||
fn_val: DynSym,
|
||||
abi: Abi,
|
||||
args: &[FnArg<'tcx, Provenance>],
|
||||
dest: &PlaceTy<'tcx, Provenance>,
|
||||
ret: Option<mir::BasicBlock>,
|
||||
_unwind: mir::UnwindAction,
|
||||
unwind: mir::UnwindAction,
|
||||
) -> InterpResult<'tcx> {
|
||||
let args = ecx.copy_fn_args(args)?; // FIXME: Should `InPlace` arguments be reset to uninit?
|
||||
ecx.call_dlsym(fn_val, abi, &args, dest, ret)
|
||||
ecx.emulate_dyn_sym(fn_val, abi, &args, dest, ret, unwind)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
|
|
|
|||
|
|
@ -1,48 +0,0 @@
|
|||
use rustc_middle::mir;
|
||||
use rustc_target::spec::abi::Abi;
|
||||
|
||||
use crate::helpers::target_os_is_unix;
|
||||
use crate::*;
|
||||
use shims::unix::dlsym as unix;
|
||||
use shims::windows::dlsym as windows;
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
#[allow(non_camel_case_types)]
|
||||
pub enum Dlsym {
|
||||
Posix(unix::Dlsym),
|
||||
Windows(windows::Dlsym),
|
||||
}
|
||||
|
||||
impl Dlsym {
|
||||
// Returns an error for unsupported symbols, and None if this symbol
|
||||
// should become a NULL pointer (pretend it does not exist).
|
||||
pub fn from_str<'tcx>(name: &[u8], target_os: &str) -> InterpResult<'tcx, Option<Dlsym>> {
|
||||
let name = &*String::from_utf8_lossy(name);
|
||||
Ok(match target_os {
|
||||
target if target_os_is_unix(target) =>
|
||||
unix::Dlsym::from_str(name, target)?.map(Dlsym::Posix),
|
||||
"windows" => windows::Dlsym::from_str(name)?.map(Dlsym::Windows),
|
||||
os => bug!("dlsym not implemented for target_os {}", os),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
|
||||
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
fn call_dlsym(
|
||||
&mut self,
|
||||
dlsym: Dlsym,
|
||||
abi: Abi,
|
||||
args: &[OpTy<'tcx, Provenance>],
|
||||
dest: &PlaceTy<'tcx, Provenance>,
|
||||
ret: Option<mir::BasicBlock>,
|
||||
) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_mut();
|
||||
match dlsym {
|
||||
Dlsym::Posix(dlsym) =>
|
||||
unix::EvalContextExt::call_dlsym(this, dlsym, abi, args, dest, ret),
|
||||
Dlsym::Windows(dlsym) =>
|
||||
windows::EvalContextExt::call_dlsym(this, dlsym, abi, args, dest, ret),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,7 +6,7 @@ use rustc_apfloat::Float;
|
|||
use rustc_ast::expand::allocator::AllocatorKind;
|
||||
use rustc_hir::{
|
||||
def::DefKind,
|
||||
def_id::{CrateNum, DefId, LOCAL_CRATE},
|
||||
def_id::{CrateNum, LOCAL_CRATE},
|
||||
};
|
||||
use rustc_middle::middle::{
|
||||
codegen_fn_attrs::CodegenFnAttrFlags, dependency_format::Linkage,
|
||||
|
|
@ -25,7 +25,18 @@ use super::backtrace::EvalContextExt as _;
|
|||
use crate::helpers::target_os_is_unix;
|
||||
use crate::*;
|
||||
|
||||
/// Returned by `emulate_foreign_item_by_name`.
|
||||
/// Type of dynamic symbols (for `dlsym` et al)
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct DynSym(Symbol);
|
||||
|
||||
#[allow(clippy::should_implement_trait)]
|
||||
impl DynSym {
|
||||
pub fn from_str(name: &str) -> Self {
|
||||
DynSym(Symbol::intern(name))
|
||||
}
|
||||
}
|
||||
|
||||
/// Returned by `emulate_foreign_item_inner`.
|
||||
pub enum EmulateByNameResult<'mir, 'tcx> {
|
||||
/// The caller is expected to jump to the return block.
|
||||
NeedsJumping,
|
||||
|
|
@ -254,7 +265,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
/// is delegated to another function.
|
||||
fn emulate_foreign_item(
|
||||
&mut self,
|
||||
def_id: DefId,
|
||||
link_name: Symbol,
|
||||
abi: Abi,
|
||||
args: &[OpTy<'tcx, Provenance>],
|
||||
dest: &PlaceTy<'tcx, Provenance>,
|
||||
|
|
@ -262,7 +273,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
unwind: mir::UnwindAction,
|
||||
) -> InterpResult<'tcx, Option<(&'mir mir::Body<'tcx>, ty::Instance<'tcx>)>> {
|
||||
let this = self.eval_context_mut();
|
||||
let link_name = this.item_link_name(def_id);
|
||||
let tcx = this.tcx.tcx;
|
||||
|
||||
// First: functions that diverge.
|
||||
|
|
@ -322,7 +332,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
};
|
||||
|
||||
// Second: functions that return immediately.
|
||||
match this.emulate_foreign_item_by_name(link_name, abi, args, dest)? {
|
||||
match this.emulate_foreign_item_inner(link_name, abi, args, dest)? {
|
||||
EmulateByNameResult::NeedsJumping => {
|
||||
trace!("{:?}", this.dump_place(dest));
|
||||
this.go_to_block(ret);
|
||||
|
|
@ -345,6 +355,21 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
Ok(None)
|
||||
}
|
||||
|
||||
/// Emulates a call to a `DynSym`.
|
||||
fn emulate_dyn_sym(
|
||||
&mut self,
|
||||
sym: DynSym,
|
||||
abi: Abi,
|
||||
args: &[OpTy<'tcx, Provenance>],
|
||||
dest: &PlaceTy<'tcx, Provenance>,
|
||||
ret: Option<mir::BasicBlock>,
|
||||
unwind: mir::UnwindAction,
|
||||
) -> InterpResult<'tcx> {
|
||||
let res = self.emulate_foreign_item(sym.0, abi, args, dest, ret, unwind)?;
|
||||
assert!(res.is_none(), "DynSyms that delegate are not supported");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Emulates calling the internal __rust_* allocator functions
|
||||
fn emulate_allocator(
|
||||
&mut self,
|
||||
|
|
@ -373,8 +398,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Emulates calling a foreign item using its name.
|
||||
fn emulate_foreign_item_by_name(
|
||||
fn emulate_foreign_item_inner(
|
||||
&mut self,
|
||||
link_name: Symbol,
|
||||
abi: Abi,
|
||||
|
|
@ -1045,11 +1069,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
_ =>
|
||||
return match this.tcx.sess.target.os.as_ref() {
|
||||
target_os if target_os_is_unix(target_os) =>
|
||||
shims::unix::foreign_items::EvalContextExt::emulate_foreign_item_by_name(
|
||||
shims::unix::foreign_items::EvalContextExt::emulate_foreign_item_inner(
|
||||
this, link_name, abi, args, dest,
|
||||
),
|
||||
"windows" =>
|
||||
shims::windows::foreign_items::EvalContextExt::emulate_foreign_item_by_name(
|
||||
shims::windows::foreign_items::EvalContextExt::emulate_foreign_item_inner(
|
||||
this, link_name, abi, args, dest,
|
||||
),
|
||||
_ => Ok(EmulateByNameResult::NotSupported),
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ pub mod unix;
|
|||
pub mod windows;
|
||||
mod x86;
|
||||
|
||||
pub mod dlsym;
|
||||
pub mod env;
|
||||
pub mod os_str;
|
||||
pub mod panic;
|
||||
|
|
@ -58,7 +57,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
// foreign function
|
||||
// Any needed call to `goto_block` will be performed by `emulate_foreign_item`.
|
||||
let args = this.copy_fn_args(args)?; // FIXME: Should `InPlace` arguments be reset to uninit?
|
||||
return this.emulate_foreign_item(instance.def_id(), abi, &args, dest, ret, unwind);
|
||||
let link_name = this.item_link_name(instance.def_id());
|
||||
return this.emulate_foreign_item(link_name, abi, &args, dest, ret, unwind);
|
||||
}
|
||||
|
||||
// Otherwise, load the MIR.
|
||||
|
|
|
|||
|
|
@ -1,54 +0,0 @@
|
|||
use rustc_middle::mir;
|
||||
|
||||
use crate::helpers::check_arg_count;
|
||||
use crate::*;
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
#[allow(non_camel_case_types)]
|
||||
pub enum Dlsym {
|
||||
signal,
|
||||
}
|
||||
|
||||
impl Dlsym {
|
||||
// Returns an error for unsupported symbols, and None if this symbol
|
||||
// should become a NULL pointer (pretend it does not exist).
|
||||
pub fn from_str<'tcx>(name: &str) -> InterpResult<'tcx, Option<Dlsym>> {
|
||||
Ok(match name {
|
||||
"signal" => Some(Dlsym::signal),
|
||||
"android_set_abort_message" => None,
|
||||
_ => throw_unsup_format!("unsupported Android dlsym: {}", name),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
|
||||
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
fn call_dlsym(
|
||||
&mut self,
|
||||
dlsym: Dlsym,
|
||||
args: &[OpTy<'tcx, Provenance>],
|
||||
dest: &PlaceTy<'tcx, Provenance>,
|
||||
ret: Option<mir::BasicBlock>,
|
||||
) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_mut();
|
||||
let ret = ret.expect("we don't support any diverging dlsym");
|
||||
assert!(this.tcx.sess.target.os == "android");
|
||||
|
||||
match dlsym {
|
||||
Dlsym::signal => {
|
||||
if !this.frame_in_std() {
|
||||
throw_unsup_format!(
|
||||
"`signal` support is crude and just enough for libstd to work"
|
||||
);
|
||||
}
|
||||
|
||||
let [_sig, _func] = check_arg_count(args)?;
|
||||
this.write_null(dest)?;
|
||||
}
|
||||
}
|
||||
|
||||
log::trace!("{:?}", this.dump_place(dest));
|
||||
this.go_to_block(ret);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
@ -6,17 +6,26 @@ use shims::foreign_items::EmulateByNameResult;
|
|||
|
||||
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
|
||||
|
||||
pub fn is_dyn_sym(name: &str) -> bool {
|
||||
matches!(name, "signal")
|
||||
}
|
||||
|
||||
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
fn emulate_foreign_item_by_name(
|
||||
fn emulate_foreign_item_inner(
|
||||
&mut self,
|
||||
link_name: Symbol,
|
||||
_abi: Abi,
|
||||
_args: &[OpTy<'tcx, Provenance>],
|
||||
_dest: &PlaceTy<'tcx, Provenance>,
|
||||
abi: Abi,
|
||||
args: &[OpTy<'tcx, Provenance>],
|
||||
dest: &PlaceTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, EmulateByNameResult<'mir, 'tcx>> {
|
||||
let _this = self.eval_context_mut();
|
||||
#[allow(clippy::match_single_binding)]
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
match link_name.as_str() {
|
||||
"signal" if this.frame_in_std() => {
|
||||
let [_sig, _func] =
|
||||
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||
this.write_null(dest)?;
|
||||
}
|
||||
_ => return Ok(EmulateByNameResult::NotSupported),
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,2 +1 @@
|
|||
pub mod dlsym;
|
||||
pub mod foreign_items;
|
||||
|
|
|
|||
|
|
@ -1,55 +0,0 @@
|
|||
use rustc_middle::mir;
|
||||
use rustc_target::spec::abi::Abi;
|
||||
|
||||
use crate::*;
|
||||
use shims::unix::android::dlsym as android;
|
||||
use shims::unix::freebsd::dlsym as freebsd;
|
||||
use shims::unix::linux::dlsym as linux;
|
||||
use shims::unix::macos::dlsym as macos;
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum Dlsym {
|
||||
Android(android::Dlsym),
|
||||
FreeBsd(freebsd::Dlsym),
|
||||
Linux(linux::Dlsym),
|
||||
MacOs(macos::Dlsym),
|
||||
}
|
||||
|
||||
impl Dlsym {
|
||||
// Returns an error for unsupported symbols, and None if this symbol
|
||||
// should become a NULL pointer (pretend it does not exist).
|
||||
pub fn from_str<'tcx>(name: &str, target_os: &str) -> InterpResult<'tcx, Option<Dlsym>> {
|
||||
Ok(match target_os {
|
||||
"android" => android::Dlsym::from_str(name)?.map(Dlsym::Android),
|
||||
"freebsd" => freebsd::Dlsym::from_str(name)?.map(Dlsym::FreeBsd),
|
||||
"linux" => linux::Dlsym::from_str(name)?.map(Dlsym::Linux),
|
||||
"macos" => macos::Dlsym::from_str(name)?.map(Dlsym::MacOs),
|
||||
_ => panic!("unsupported Unix OS {target_os}"),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
|
||||
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
fn call_dlsym(
|
||||
&mut self,
|
||||
dlsym: Dlsym,
|
||||
abi: Abi,
|
||||
args: &[OpTy<'tcx, Provenance>],
|
||||
dest: &PlaceTy<'tcx, Provenance>,
|
||||
ret: Option<mir::BasicBlock>,
|
||||
) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
this.check_abi(abi, Abi::C { unwind: false })?;
|
||||
|
||||
match dlsym {
|
||||
Dlsym::Android(dlsym) =>
|
||||
android::EvalContextExt::call_dlsym(this, dlsym, args, dest, ret),
|
||||
Dlsym::FreeBsd(dlsym) =>
|
||||
freebsd::EvalContextExt::call_dlsym(this, dlsym, args, dest, ret),
|
||||
Dlsym::Linux(dlsym) => linux::EvalContextExt::call_dlsym(this, dlsym, args, dest, ret),
|
||||
Dlsym::MacOs(dlsym) => macos::EvalContextExt::call_dlsym(this, dlsym, args, dest, ret),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
use std::ffi::OsStr;
|
||||
use std::str;
|
||||
|
||||
use log::trace;
|
||||
|
||||
|
|
@ -14,9 +15,14 @@ use shims::unix::mem::EvalContextExt as _;
|
|||
use shims::unix::sync::EvalContextExt as _;
|
||||
use shims::unix::thread::EvalContextExt as _;
|
||||
|
||||
use shims::unix::android::foreign_items as android;
|
||||
use shims::unix::freebsd::foreign_items as freebsd;
|
||||
use shims::unix::linux::foreign_items as linux;
|
||||
use shims::unix::macos::foreign_items as macos;
|
||||
|
||||
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
|
||||
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
fn emulate_foreign_item_by_name(
|
||||
fn emulate_foreign_item_inner(
|
||||
&mut self,
|
||||
link_name: Symbol,
|
||||
abi: Abi,
|
||||
|
|
@ -25,7 +31,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
) -> InterpResult<'tcx, EmulateByNameResult<'mir, 'tcx>> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
// See `fn emulate_foreign_item_by_name` in `shims/foreign_items.rs` for the general pattern.
|
||||
// See `fn emulate_foreign_item_inner` in `shims/foreign_items.rs` for the general pattern.
|
||||
#[rustfmt::skip]
|
||||
match link_name.as_str() {
|
||||
// Environment related shims
|
||||
|
|
@ -230,9 +236,16 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
let [handle, symbol] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||
this.read_target_usize(handle)?;
|
||||
let symbol = this.read_pointer(symbol)?;
|
||||
let symbol_name = this.read_c_str(symbol)?;
|
||||
if let Some(dlsym) = Dlsym::from_str(symbol_name, &this.tcx.sess.target.os)? {
|
||||
let ptr = this.fn_ptr(FnVal::Other(dlsym));
|
||||
let name = this.read_c_str(symbol)?;
|
||||
let is_dyn_sym = |name| match &*this.tcx.sess.target.os {
|
||||
"android" => android::is_dyn_sym(name),
|
||||
"freebsd" => freebsd::is_dyn_sym(name),
|
||||
"linux" => linux::is_dyn_sym(name),
|
||||
"macos" => macos::is_dyn_sym(name),
|
||||
target_os => panic!("unsupported Unix OS {target_os}"),
|
||||
};
|
||||
if let Ok(name) = str::from_utf8(name) && is_dyn_sym(name) {
|
||||
let ptr = this.fn_ptr(FnVal::Other(DynSym::from_str(name)));
|
||||
this.write_pointer(ptr, dest)?;
|
||||
} else {
|
||||
this.write_null(dest)?;
|
||||
|
|
@ -609,10 +622,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
_ => {
|
||||
let target_os = &*this.tcx.sess.target.os;
|
||||
return match target_os {
|
||||
"android" => shims::unix::android::foreign_items::EvalContextExt::emulate_foreign_item_by_name(this, link_name, abi, args, dest),
|
||||
"freebsd" => shims::unix::freebsd::foreign_items::EvalContextExt::emulate_foreign_item_by_name(this, link_name, abi, args, dest),
|
||||
"linux" => shims::unix::linux::foreign_items::EvalContextExt::emulate_foreign_item_by_name(this, link_name, abi, args, dest),
|
||||
"macos" => shims::unix::macos::foreign_items::EvalContextExt::emulate_foreign_item_by_name(this, link_name, abi, args, dest),
|
||||
"android" => android::EvalContextExt::emulate_foreign_item_inner(this, link_name, abi, args, dest),
|
||||
"freebsd" => freebsd::EvalContextExt::emulate_foreign_item_inner(this, link_name, abi, args, dest),
|
||||
"linux" => linux::EvalContextExt::emulate_foreign_item_inner(this, link_name, abi, args, dest),
|
||||
"macos" => macos::EvalContextExt::emulate_foreign_item_inner(this, link_name, abi, args, dest),
|
||||
_ => Ok(EmulateByNameResult::NotSupported),
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,36 +0,0 @@
|
|||
use rustc_middle::mir;
|
||||
|
||||
use crate::*;
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
#[allow(non_camel_case_types)]
|
||||
pub enum Dlsym {}
|
||||
|
||||
impl Dlsym {
|
||||
// Returns an error for unsupported symbols, and None if this symbol
|
||||
// should become a NULL pointer (pretend it does not exist).
|
||||
pub fn from_str<'tcx>(name: &str) -> InterpResult<'tcx, Option<Dlsym>> {
|
||||
throw_unsup_format!("unsupported FreeBSD dlsym: {}", name)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
|
||||
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
fn call_dlsym(
|
||||
&mut self,
|
||||
dlsym: Dlsym,
|
||||
_args: &[OpTy<'tcx, Provenance>],
|
||||
_dest: &PlaceTy<'tcx, Provenance>,
|
||||
ret: Option<mir::BasicBlock>,
|
||||
) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_mut();
|
||||
let _ret = ret.expect("we don't support any diverging dlsym");
|
||||
assert!(this.tcx.sess.target.os == "freebsd");
|
||||
|
||||
match dlsym {}
|
||||
|
||||
//trace!("{:?}", this.dump_place(**dest));
|
||||
//this.go_to_block(ret);
|
||||
//Ok(())
|
||||
}
|
||||
}
|
||||
|
|
@ -5,10 +5,13 @@ use crate::*;
|
|||
use shims::foreign_items::EmulateByNameResult;
|
||||
use shims::unix::thread::EvalContextExt as _;
|
||||
|
||||
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
|
||||
pub fn is_dyn_sym(_name: &str) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
|
||||
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
fn emulate_foreign_item_by_name(
|
||||
fn emulate_foreign_item_inner(
|
||||
&mut self,
|
||||
link_name: Symbol,
|
||||
abi: Abi,
|
||||
|
|
|
|||
|
|
@ -1,2 +1 @@
|
|||
pub mod dlsym;
|
||||
pub mod foreign_items;
|
||||
|
|
|
|||
|
|
@ -1,40 +0,0 @@
|
|||
use rustc_middle::mir;
|
||||
|
||||
use crate::*;
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum Dlsym {}
|
||||
|
||||
impl Dlsym {
|
||||
// Returns an error for unsupported symbols, and None if this symbol
|
||||
// should become a NULL pointer (pretend it does not exist).
|
||||
pub fn from_str<'tcx>(name: &str) -> InterpResult<'tcx, Option<Dlsym>> {
|
||||
Ok(match name {
|
||||
"__pthread_get_minstack" => None,
|
||||
"getrandom" => None, // std falls back to syscall(SYS_getrandom, ...) when this is NULL.
|
||||
"statx" => None, // std falls back to syscall(SYS_statx, ...) when this is NULL.
|
||||
_ => throw_unsup_format!("unsupported Linux dlsym: {}", name),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
|
||||
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
fn call_dlsym(
|
||||
&mut self,
|
||||
dlsym: Dlsym,
|
||||
_args: &[OpTy<'tcx, Provenance>],
|
||||
_dest: &PlaceTy<'tcx, Provenance>,
|
||||
ret: Option<mir::BasicBlock>,
|
||||
) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_mut();
|
||||
let _ret = ret.expect("we don't support any diverging dlsym");
|
||||
assert!(this.tcx.sess.target.os == "linux");
|
||||
|
||||
match dlsym {}
|
||||
|
||||
//trace!("{:?}", this.dump_place(**dest));
|
||||
//this.go_to_block(ret);
|
||||
//Ok(())
|
||||
}
|
||||
}
|
||||
|
|
@ -12,9 +12,13 @@ use shims::unix::linux::sync::futex;
|
|||
use shims::unix::sync::EvalContextExt as _;
|
||||
use shims::unix::thread::EvalContextExt as _;
|
||||
|
||||
pub fn is_dyn_sym(_name: &str) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
|
||||
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
fn emulate_foreign_item_by_name(
|
||||
fn emulate_foreign_item_inner(
|
||||
&mut self,
|
||||
link_name: Symbol,
|
||||
abi: Abi,
|
||||
|
|
@ -23,7 +27,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
) -> InterpResult<'tcx, EmulateByNameResult<'mir, 'tcx>> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
// See `fn emulate_foreign_item_by_name` in `shims/foreign_items.rs` for the general pattern.
|
||||
// See `fn emulate_foreign_item_inner` in `shims/foreign_items.rs` for the general pattern.
|
||||
|
||||
match link_name.as_str() {
|
||||
// errno
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
pub mod dlsym;
|
||||
pub mod fd;
|
||||
pub mod foreign_items;
|
||||
pub mod mem;
|
||||
|
|
|
|||
|
|
@ -1,51 +0,0 @@
|
|||
use rustc_middle::mir;
|
||||
|
||||
use log::trace;
|
||||
|
||||
use super::foreign_items::EvalContextExt as _;
|
||||
use crate::*;
|
||||
use helpers::check_arg_count;
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
#[allow(non_camel_case_types)]
|
||||
pub enum Dlsym {
|
||||
getentropy,
|
||||
}
|
||||
|
||||
impl Dlsym {
|
||||
// Returns an error for unsupported symbols, and None if this symbol
|
||||
// should become a NULL pointer (pretend it does not exist).
|
||||
pub fn from_str<'tcx>(name: &str) -> InterpResult<'tcx, Option<Dlsym>> {
|
||||
Ok(match name {
|
||||
"getentropy" => Some(Dlsym::getentropy),
|
||||
_ => throw_unsup_format!("unsupported macOS dlsym: {}", name),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
|
||||
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
fn call_dlsym(
|
||||
&mut self,
|
||||
dlsym: Dlsym,
|
||||
args: &[OpTy<'tcx, Provenance>],
|
||||
dest: &PlaceTy<'tcx, Provenance>,
|
||||
ret: Option<mir::BasicBlock>,
|
||||
) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_mut();
|
||||
let ret = ret.expect("we don't support any diverging dlsym");
|
||||
assert!(this.tcx.sess.target.os == "macos");
|
||||
|
||||
match dlsym {
|
||||
Dlsym::getentropy => {
|
||||
let [ptr, len] = check_arg_count(args)?;
|
||||
let result = this.getentropy(ptr, len)?;
|
||||
this.write_scalar(result, dest)?;
|
||||
}
|
||||
}
|
||||
|
||||
trace!("{:?}", this.dump_place(dest));
|
||||
this.go_to_block(ret);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
@ -6,9 +6,13 @@ use shims::foreign_items::EmulateByNameResult;
|
|||
use shims::unix::fs::EvalContextExt as _;
|
||||
use shims::unix::thread::EvalContextExt as _;
|
||||
|
||||
pub fn is_dyn_sym(name: &str) -> bool {
|
||||
matches!(name, "getentropy")
|
||||
}
|
||||
|
||||
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
|
||||
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
fn emulate_foreign_item_by_name(
|
||||
fn emulate_foreign_item_inner(
|
||||
&mut self,
|
||||
link_name: Symbol,
|
||||
abi: Abi,
|
||||
|
|
@ -17,7 +21,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
) -> InterpResult<'tcx, EmulateByNameResult<'mir, 'tcx>> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
// See `fn emulate_foreign_item_by_name` in `shims/foreign_items.rs` for the general pattern.
|
||||
// See `fn emulate_foreign_item_inner` in `shims/foreign_items.rs` for the general pattern.
|
||||
|
||||
match link_name.as_str() {
|
||||
// errno
|
||||
|
|
@ -113,8 +117,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
"getentropy" => {
|
||||
let [buf, bufsize] =
|
||||
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||
let result = this.getentropy(buf, bufsize)?;
|
||||
this.write_scalar(result, dest)?;
|
||||
let buf = this.read_pointer(buf)?;
|
||||
let bufsize = this.read_target_usize(bufsize)?;
|
||||
|
||||
this.gen_random(buf, bufsize)?;
|
||||
|
||||
this.write_scalar(Scalar::from_i32(0), dest)?; // KERN_SUCCESS
|
||||
}
|
||||
|
||||
// Access to command-line arguments
|
||||
|
|
@ -206,19 +214,4 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
|
||||
Ok(EmulateByNameResult::NeedsJumping)
|
||||
}
|
||||
|
||||
fn getentropy(
|
||||
&mut self,
|
||||
buffer_op: &OpTy<'tcx, Provenance>,
|
||||
length_op: &OpTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, Scalar<Provenance>> {
|
||||
let this = self.eval_context_mut();
|
||||
this.assert_target_os("macos", "getentropy");
|
||||
|
||||
let ptr = this.read_pointer(buffer_op)?;
|
||||
let len = this.read_target_usize(length_op)?;
|
||||
this.gen_random(ptr, len)?;
|
||||
|
||||
Ok(Scalar::from_i32(0)) // KERN_SUCCESS
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,2 +1 @@
|
|||
pub mod dlsym;
|
||||
pub mod foreign_items;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
pub mod dlsym;
|
||||
pub mod foreign_items;
|
||||
|
||||
mod fs;
|
||||
|
|
|
|||
|
|
@ -1,82 +0,0 @@
|
|||
use rustc_middle::mir;
|
||||
use rustc_target::spec::abi::Abi;
|
||||
|
||||
use log::trace;
|
||||
|
||||
use crate::helpers::check_arg_count;
|
||||
use crate::shims::windows::handle::{EvalContextExt as _, Handle, PseudoHandle};
|
||||
use crate::shims::windows::sync::EvalContextExt as _;
|
||||
use crate::*;
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum Dlsym {
|
||||
SetThreadDescription,
|
||||
WaitOnAddress,
|
||||
WakeByAddressSingle,
|
||||
}
|
||||
|
||||
impl Dlsym {
|
||||
// Returns an error for unsupported symbols, and None if this symbol
|
||||
// should become a NULL pointer (pretend it does not exist).
|
||||
pub fn from_str<'tcx>(name: &str) -> InterpResult<'tcx, Option<Dlsym>> {
|
||||
Ok(match name {
|
||||
"GetSystemTimePreciseAsFileTime" => None,
|
||||
"SetThreadDescription" => Some(Dlsym::SetThreadDescription),
|
||||
"WaitOnAddress" => Some(Dlsym::WaitOnAddress),
|
||||
"WakeByAddressSingle" => Some(Dlsym::WakeByAddressSingle),
|
||||
_ => throw_unsup_format!("unsupported Windows dlsym: {}", name),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
|
||||
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
fn call_dlsym(
|
||||
&mut self,
|
||||
dlsym: Dlsym,
|
||||
abi: Abi,
|
||||
args: &[OpTy<'tcx, Provenance>],
|
||||
dest: &PlaceTy<'tcx, Provenance>,
|
||||
ret: Option<mir::BasicBlock>,
|
||||
) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_mut();
|
||||
let ret = ret.expect("we don't support any diverging dlsym");
|
||||
assert!(this.tcx.sess.target.os == "windows");
|
||||
|
||||
this.check_abi(abi, Abi::System { unwind: false })?;
|
||||
|
||||
match dlsym {
|
||||
Dlsym::SetThreadDescription => {
|
||||
let [handle, name] = check_arg_count(args)?;
|
||||
|
||||
let handle = this.read_scalar(handle)?;
|
||||
|
||||
let name = this.read_wide_str(this.read_pointer(name)?)?;
|
||||
|
||||
let thread = match Handle::from_scalar(handle, this)? {
|
||||
Some(Handle::Thread(thread)) => thread,
|
||||
Some(Handle::Pseudo(PseudoHandle::CurrentThread)) => this.get_active_thread(),
|
||||
_ => this.invalid_handle("SetThreadDescription")?,
|
||||
};
|
||||
|
||||
this.set_thread_name_wide(thread, &name);
|
||||
|
||||
this.write_null(dest)?;
|
||||
}
|
||||
Dlsym::WaitOnAddress => {
|
||||
let [ptr_op, compare_op, size_op, timeout_op] = check_arg_count(args)?;
|
||||
|
||||
this.WaitOnAddress(ptr_op, compare_op, size_op, timeout_op, dest)?;
|
||||
}
|
||||
Dlsym::WakeByAddressSingle => {
|
||||
let [ptr_op] = check_arg_count(args)?;
|
||||
|
||||
this.WakeByAddressSingle(ptr_op)?;
|
||||
}
|
||||
}
|
||||
|
||||
trace!("{:?}", this.dump_place(dest));
|
||||
this.go_to_block(ret);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
use std::iter;
|
||||
use std::str;
|
||||
|
||||
use rustc_span::Symbol;
|
||||
use rustc_target::abi::Size;
|
||||
|
|
@ -10,9 +11,13 @@ use shims::windows::handle::{EvalContextExt as _, Handle, PseudoHandle};
|
|||
use shims::windows::sync::EvalContextExt as _;
|
||||
use shims::windows::thread::EvalContextExt as _;
|
||||
|
||||
fn is_dyn_sym(name: &str) -> bool {
|
||||
matches!(name, "SetThreadDescription" | "WaitOnAddress" | "WakeByAddressSingle")
|
||||
}
|
||||
|
||||
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
|
||||
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
fn emulate_foreign_item_by_name(
|
||||
fn emulate_foreign_item_inner(
|
||||
&mut self,
|
||||
link_name: Symbol,
|
||||
abi: Abi,
|
||||
|
|
@ -21,7 +26,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
) -> InterpResult<'tcx, EmulateByNameResult<'mir, 'tcx>> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
// See `fn emulate_foreign_item_by_name` in `shims/foreign_items.rs` for the general pattern.
|
||||
// See `fn emulate_foreign_item_inner` in `shims/foreign_items.rs` for the general pattern.
|
||||
|
||||
// Windows API stubs.
|
||||
// HANDLE = isize
|
||||
|
|
@ -326,6 +331,18 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
|
||||
this.WakeAllConditionVariable(condvar)?;
|
||||
}
|
||||
"WaitOnAddress" => {
|
||||
let [ptr_op, compare_op, size_op, timeout_op] =
|
||||
this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
|
||||
|
||||
this.WaitOnAddress(ptr_op, compare_op, size_op, timeout_op, dest)?;
|
||||
}
|
||||
"WakeByAddressSingle" => {
|
||||
let [ptr_op] =
|
||||
this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
|
||||
|
||||
this.WakeByAddressSingle(ptr_op)?;
|
||||
}
|
||||
|
||||
// Dynamic symbol loading
|
||||
"GetProcAddress" => {
|
||||
|
|
@ -334,14 +351,58 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
|
||||
this.read_target_isize(hModule)?;
|
||||
let name = this.read_c_str(this.read_pointer(lpProcName)?)?;
|
||||
if let Some(dlsym) = Dlsym::from_str(name, &this.tcx.sess.target.os)? {
|
||||
let ptr = this.fn_ptr(FnVal::Other(dlsym));
|
||||
if let Ok(name) = str::from_utf8(name) && is_dyn_sym(name) {
|
||||
let ptr = this.fn_ptr(FnVal::Other(DynSym::from_str(name)));
|
||||
this.write_pointer(ptr, dest)?;
|
||||
} else {
|
||||
this.write_null(dest)?;
|
||||
}
|
||||
}
|
||||
|
||||
// Threading
|
||||
"CreateThread" => {
|
||||
let [security, stacksize, start, arg, flags, thread] =
|
||||
this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
|
||||
|
||||
let thread_id =
|
||||
this.CreateThread(security, stacksize, start, arg, flags, thread)?;
|
||||
|
||||
this.write_scalar(Handle::Thread(thread_id).to_scalar(this), dest)?;
|
||||
}
|
||||
"WaitForSingleObject" => {
|
||||
let [handle, timeout] =
|
||||
this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
|
||||
|
||||
let ret = this.WaitForSingleObject(handle, timeout)?;
|
||||
this.write_scalar(Scalar::from_u32(ret), dest)?;
|
||||
}
|
||||
"GetCurrentThread" => {
|
||||
let [] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
|
||||
|
||||
this.write_scalar(
|
||||
Handle::Pseudo(PseudoHandle::CurrentThread).to_scalar(this),
|
||||
dest,
|
||||
)?;
|
||||
}
|
||||
"SetThreadDescription" => {
|
||||
let [handle, name] =
|
||||
this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
|
||||
|
||||
let handle = this.read_scalar(handle)?;
|
||||
|
||||
let name = this.read_wide_str(this.read_pointer(name)?)?;
|
||||
|
||||
let thread = match Handle::from_scalar(handle, this)? {
|
||||
Some(Handle::Thread(thread)) => thread,
|
||||
Some(Handle::Pseudo(PseudoHandle::CurrentThread)) => this.get_active_thread(),
|
||||
_ => this.invalid_handle("SetThreadDescription")?,
|
||||
};
|
||||
|
||||
this.set_thread_name_wide(thread, &name);
|
||||
|
||||
this.write_null(dest)?;
|
||||
}
|
||||
|
||||
// Miscellaneous
|
||||
"SystemFunction036" => {
|
||||
// This is really 'RtlGenRandom'.
|
||||
|
|
@ -456,32 +517,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
// Threading
|
||||
"CreateThread" => {
|
||||
let [security, stacksize, start, arg, flags, thread] =
|
||||
this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
|
||||
|
||||
let thread_id =
|
||||
this.CreateThread(security, stacksize, start, arg, flags, thread)?;
|
||||
|
||||
this.write_scalar(Handle::Thread(thread_id).to_scalar(this), dest)?;
|
||||
}
|
||||
"WaitForSingleObject" => {
|
||||
let [handle, timeout] =
|
||||
this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
|
||||
|
||||
let ret = this.WaitForSingleObject(handle, timeout)?;
|
||||
this.write_scalar(Scalar::from_u32(ret), dest)?;
|
||||
}
|
||||
"GetCurrentThread" => {
|
||||
let [] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
|
||||
|
||||
this.write_scalar(
|
||||
Handle::Pseudo(PseudoHandle::CurrentThread).to_scalar(this),
|
||||
dest,
|
||||
)?;
|
||||
}
|
||||
|
||||
// Incomplete shims that we "stub out" just to get pre-main initialization code to work.
|
||||
// These shims are enabled only when the caller is in the standard library.
|
||||
"GetProcessHeap" if this.frame_in_std() => {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
pub mod dlsym;
|
||||
pub mod foreign_items;
|
||||
|
||||
mod handle;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue