Trait miri::helpers::EvalContextExt
source · pub trait EvalContextExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> {
Show 46 methods
fn have_module(&self, path: &[&str]) -> bool { ... }
fn try_resolve_path(
&self,
path: &[&str],
namespace: Namespace
) -> Option<Instance<'tcx>> { ... }
fn resolve_path(&self, path: &[&str], namespace: Namespace) -> Instance<'tcx> { ... }
fn eval_path_scalar(
&self,
path: &[&str]
) -> InterpResult<'tcx, Scalar<Provenance>> { ... }
fn eval_libc(&self, name: &str) -> InterpResult<'tcx, Scalar<Provenance>> { ... }
fn eval_libc_i32(&self, name: &str) -> InterpResult<'tcx, i32> { ... }
fn eval_windows(
&self,
module: &str,
name: &str
) -> InterpResult<'tcx, Scalar<Provenance>> { ... }
fn eval_windows_u64(
&self,
module: &str,
name: &str
) -> InterpResult<'tcx, u64> { ... }
fn libc_ty_layout(&self, name: &str) -> InterpResult<'tcx, TyAndLayout<'tcx>> { ... }
fn windows_ty_layout(
&self,
name: &str
) -> InterpResult<'tcx, TyAndLayout<'tcx>> { ... }
fn mplace_field_named(
&self,
mplace: &MPlaceTy<'tcx, Provenance>,
name: &str
) -> InterpResult<'tcx, MPlaceTy<'tcx, Provenance>> { ... }
fn write_int(
&mut self,
i: impl Into<i128>,
dest: &PlaceTy<'tcx, Provenance>
) -> InterpResult<'tcx> { ... }
fn write_int_fields(
&mut self,
values: &[i128],
dest: &MPlaceTy<'tcx, Provenance>
) -> InterpResult<'tcx> { ... }
fn write_int_fields_named(
&mut self,
values: &[(&str, i128)],
dest: &MPlaceTy<'tcx, Provenance>
) -> InterpResult<'tcx> { ... }
fn write_null(
&mut self,
dest: &PlaceTy<'tcx, Provenance>
) -> InterpResult<'tcx> { ... }
fn ptr_is_null(
&self,
ptr: Pointer<Option<Provenance>>
) -> InterpResult<'tcx, bool> { ... }
fn local_place(
&mut self,
local: Local
) -> InterpResult<'tcx, PlaceTy<'tcx, Provenance>> { ... }
fn gen_random(
&mut self,
ptr: Pointer<Option<Provenance>>,
len: u64
) -> InterpResult<'tcx> { ... }
fn call_function(
&mut self,
f: Instance<'tcx>,
caller_abi: Abi,
args: &[Immediate<Provenance>],
dest: Option<&PlaceTy<'tcx, Provenance>>,
stack_pop: StackPopCleanup
) -> InterpResult<'tcx> { ... }
fn visit_freeze_sensitive(
&self,
place: &MPlaceTy<'tcx, Provenance>,
size: Size,
action: impl FnMut(AllocRange, bool) -> InterpResult<'tcx>
) -> InterpResult<'tcx> { ... }
fn check_no_isolation(&self, name: &str) -> InterpResult<'tcx> { ... }
fn reject_in_isolation(
&self,
op_name: &str,
reject_with: RejectOpWith
) -> InterpResult<'tcx> { ... }
fn assert_target_os(&self, target_os: &str, name: &str) { ... }
fn assert_target_os_is_unix(&self, name: &str) { ... }
fn last_error_place(
&mut self
) -> InterpResult<'tcx, MPlaceTy<'tcx, Provenance>> { ... }
fn set_last_error(
&mut self,
scalar: Scalar<Provenance>
) -> InterpResult<'tcx> { ... }
fn get_last_error(&mut self) -> InterpResult<'tcx, Scalar<Provenance>> { ... }
fn io_error_to_errnum(
&self,
err_kind: ErrorKind
) -> InterpResult<'tcx, Scalar<Provenance>> { ... }
fn try_errnum_to_io_error(
&self,
errnum: Scalar<Provenance>
) -> InterpResult<'tcx, Option<ErrorKind>> { ... }
fn set_last_error_from_io_error(
&mut self,
err_kind: ErrorKind
) -> InterpResult<'tcx> { ... }
fn try_unwrap_io_result<T: From<i32>>(
&mut self,
result: Result<T>
) -> InterpResult<'tcx, T> { ... }
fn deref_operand_and_offset(
&self,
op: &OpTy<'tcx, Provenance>,
offset: u64,
layout: TyAndLayout<'tcx>
) -> InterpResult<'tcx, MPlaceTy<'tcx, Provenance>> { ... }
fn read_scalar_at_offset(
&self,
op: &OpTy<'tcx, Provenance>,
offset: u64,
layout: TyAndLayout<'tcx>
) -> InterpResult<'tcx, Scalar<Provenance>> { ... }
fn write_scalar_at_offset(
&mut self,
op: &OpTy<'tcx, Provenance>,
offset: u64,
value: impl Into<Scalar<Provenance>>,
layout: TyAndLayout<'tcx>
) -> InterpResult<'tcx, ()> { ... }
fn read_timespec(
&mut self,
tp: &MPlaceTy<'tcx, Provenance>
) -> InterpResult<'tcx, Option<Duration>> { ... }
fn read_c_str<'a>(
&'a self,
ptr: Pointer<Option<Provenance>>
) -> InterpResult<'tcx, &'a [u8]>
where
'tcx: 'a,
'mir: 'a,
{ ... }
fn write_c_str(
&mut self,
c_str: &[u8],
ptr: Pointer<Option<Provenance>>,
size: u64
) -> InterpResult<'tcx, (bool, u64)> { ... }
fn read_wide_str(
&self,
ptr: Pointer<Option<Provenance>>
) -> InterpResult<'tcx, Vec<u16>> { ... }
fn write_wide_str(
&mut self,
wide_str: &[u16],
ptr: Pointer<Option<Provenance>>,
size: u64
) -> InterpResult<'tcx, (bool, u64)> { ... }
fn check_abi<'a>(&self, abi: Abi, exp_abi: Abi) -> InterpResult<'a, ()> { ... }
fn frame_in_std(&self) -> bool { ... }
fn handle_unsupported<S: AsRef<str>>(
&mut self,
error_msg: S
) -> InterpResult<'tcx, ()> { ... }
fn check_abi_and_shim_symbol_clash(
&mut self,
abi: Abi,
exp_abi: Abi,
link_name: Symbol
) -> InterpResult<'tcx, ()> { ... }
fn check_shim<'a, const N: usize>(
&mut self,
abi: Abi,
exp_abi: Abi,
link_name: Symbol,
args: &'a [OpTy<'tcx, Provenance>]
) -> InterpResult<'tcx, &'a [OpTy<'tcx, Provenance>; N]>
where
&'a [OpTy<'tcx, Provenance>; N]: TryFrom<&'a [OpTy<'tcx, Provenance>]>,
{ ... }
fn mark_immutable(&mut self, mplace: &MemPlace<Provenance>) { ... }
fn item_link_name(&self, def_id: DefId) -> Symbol { ... }
}
Provided Methods§
sourcefn have_module(&self, path: &[&str]) -> bool
fn have_module(&self, path: &[&str]) -> bool
Checks if the given crate/module exists.
sourcefn try_resolve_path(
&self,
path: &[&str],
namespace: Namespace
) -> Option<Instance<'tcx>>
fn try_resolve_path(
&self,
path: &[&str],
namespace: Namespace
) -> Option<Instance<'tcx>>
Gets an instance for a path; fails gracefully if the path does not exist.
sourcefn resolve_path(&self, path: &[&str], namespace: Namespace) -> Instance<'tcx>
fn resolve_path(&self, path: &[&str], namespace: Namespace) -> Instance<'tcx>
Gets an instance for a path.
sourcefn eval_path_scalar(
&self,
path: &[&str]
) -> InterpResult<'tcx, Scalar<Provenance>>
fn eval_path_scalar(
&self,
path: &[&str]
) -> InterpResult<'tcx, Scalar<Provenance>>
Evaluates the scalar at the specified path. Returns Some(val) if the path could be resolved, and None otherwise
sourcefn eval_libc(&self, name: &str) -> InterpResult<'tcx, Scalar<Provenance>>
fn eval_libc(&self, name: &str) -> InterpResult<'tcx, Scalar<Provenance>>
Helper function to get a libc
constant as a Scalar
.
sourcefn eval_libc_i32(&self, name: &str) -> InterpResult<'tcx, i32>
fn eval_libc_i32(&self, name: &str) -> InterpResult<'tcx, i32>
Helper function to get a libc
constant as an i32
.
sourcefn eval_windows(
&self,
module: &str,
name: &str
) -> InterpResult<'tcx, Scalar<Provenance>>
fn eval_windows(
&self,
module: &str,
name: &str
) -> InterpResult<'tcx, Scalar<Provenance>>
Helper function to get a windows
constant as a Scalar
.
sourcefn eval_windows_u64(&self, module: &str, name: &str) -> InterpResult<'tcx, u64>
fn eval_windows_u64(&self, module: &str, name: &str) -> InterpResult<'tcx, u64>
Helper function to get a windows
constant as a u64
.
sourcefn libc_ty_layout(&self, name: &str) -> InterpResult<'tcx, TyAndLayout<'tcx>>
fn libc_ty_layout(&self, name: &str) -> InterpResult<'tcx, TyAndLayout<'tcx>>
Helper function to get the TyAndLayout
of a libc
type
sourcefn windows_ty_layout(&self, name: &str) -> InterpResult<'tcx, TyAndLayout<'tcx>>
fn windows_ty_layout(&self, name: &str) -> InterpResult<'tcx, TyAndLayout<'tcx>>
Helper function to get the TyAndLayout
of a windows
type
sourcefn mplace_field_named(
&self,
mplace: &MPlaceTy<'tcx, Provenance>,
name: &str
) -> InterpResult<'tcx, MPlaceTy<'tcx, Provenance>>
fn mplace_field_named(
&self,
mplace: &MPlaceTy<'tcx, Provenance>,
name: &str
) -> InterpResult<'tcx, MPlaceTy<'tcx, Provenance>>
Project to the given named field of the mplace (which must be a struct or union type).
sourcefn write_int(
&mut self,
i: impl Into<i128>,
dest: &PlaceTy<'tcx, Provenance>
) -> InterpResult<'tcx>
fn write_int(
&mut self,
i: impl Into<i128>,
dest: &PlaceTy<'tcx, Provenance>
) -> InterpResult<'tcx>
Write an int of the appropriate size to dest
. The target type may be signed or unsigned,
we try to do the right thing anyway. i128
can fit all integer types except for u128
so
this method is fine for almost all integer types.
sourcefn write_int_fields(
&mut self,
values: &[i128],
dest: &MPlaceTy<'tcx, Provenance>
) -> InterpResult<'tcx>
fn write_int_fields(
&mut self,
values: &[i128],
dest: &MPlaceTy<'tcx, Provenance>
) -> InterpResult<'tcx>
Write the first N fields of the given place.
sourcefn write_int_fields_named(
&mut self,
values: &[(&str, i128)],
dest: &MPlaceTy<'tcx, Provenance>
) -> InterpResult<'tcx>
fn write_int_fields_named(
&mut self,
values: &[(&str, i128)],
dest: &MPlaceTy<'tcx, Provenance>
) -> InterpResult<'tcx>
Write the given fields of the given place.
sourcefn write_null(&mut self, dest: &PlaceTy<'tcx, Provenance>) -> InterpResult<'tcx>
fn write_null(&mut self, dest: &PlaceTy<'tcx, Provenance>) -> InterpResult<'tcx>
Write a 0 of the appropriate size to dest
.
sourcefn ptr_is_null(
&self,
ptr: Pointer<Option<Provenance>>
) -> InterpResult<'tcx, bool>
fn ptr_is_null(
&self,
ptr: Pointer<Option<Provenance>>
) -> InterpResult<'tcx, bool>
Test if this pointer equals 0.
sourcefn local_place(
&mut self,
local: Local
) -> InterpResult<'tcx, PlaceTy<'tcx, Provenance>>
fn local_place(
&mut self,
local: Local
) -> InterpResult<'tcx, PlaceTy<'tcx, Provenance>>
Get the Place
for a local
sourcefn gen_random(
&mut self,
ptr: Pointer<Option<Provenance>>,
len: u64
) -> InterpResult<'tcx>
fn gen_random(
&mut self,
ptr: Pointer<Option<Provenance>>,
len: u64
) -> InterpResult<'tcx>
Generate some random bytes, and write them to dest
.
sourcefn call_function(
&mut self,
f: Instance<'tcx>,
caller_abi: Abi,
args: &[Immediate<Provenance>],
dest: Option<&PlaceTy<'tcx, Provenance>>,
stack_pop: StackPopCleanup
) -> InterpResult<'tcx>
fn call_function(
&mut self,
f: Instance<'tcx>,
caller_abi: Abi,
args: &[Immediate<Provenance>],
dest: Option<&PlaceTy<'tcx, Provenance>>,
stack_pop: StackPopCleanup
) -> InterpResult<'tcx>
Call a function: Push the stack frame and pass the arguments. For now, arguments must be scalars (so that the caller does not have to know the layout).
If you do not provie a return place, a dangling zero-sized place will be created for your convenience.
sourcefn visit_freeze_sensitive(
&self,
place: &MPlaceTy<'tcx, Provenance>,
size: Size,
action: impl FnMut(AllocRange, bool) -> InterpResult<'tcx>
) -> InterpResult<'tcx>
fn visit_freeze_sensitive(
&self,
place: &MPlaceTy<'tcx, Provenance>,
size: Size,
action: impl FnMut(AllocRange, bool) -> InterpResult<'tcx>
) -> InterpResult<'tcx>
Visits the memory covered by place
, sensitive to freezing: the 2nd parameter
of action
will be true if this is frozen, false if this is in an UnsafeCell
.
The range is relative to place
.
sourcefn check_no_isolation(&self, name: &str) -> InterpResult<'tcx>
fn check_no_isolation(&self, name: &str) -> InterpResult<'tcx>
Helper function used inside the shims of foreign functions to check that isolation is
disabled. It returns an error using the name
of the foreign function if this is not the
case.
sourcefn reject_in_isolation(
&self,
op_name: &str,
reject_with: RejectOpWith
) -> InterpResult<'tcx>
fn reject_in_isolation(
&self,
op_name: &str,
reject_with: RejectOpWith
) -> InterpResult<'tcx>
Helper function used inside the shims of foreign functions which reject the op when isolation is enabled. It is used to print a warning/backtrace about the rejection.
sourcefn assert_target_os(&self, target_os: &str, name: &str)
fn assert_target_os(&self, target_os: &str, name: &str)
Helper function used inside the shims of foreign functions to assert that the target OS
is target_os
. It panics showing a message with the name
of the foreign function
if this is not the case.
sourcefn assert_target_os_is_unix(&self, name: &str)
fn assert_target_os_is_unix(&self, name: &str)
Helper function used inside the shims of foreign functions to assert that the target OS
is part of the UNIX family. It panics showing a message with the name
of the foreign function
if this is not the case.
sourcefn last_error_place(&mut self) -> InterpResult<'tcx, MPlaceTy<'tcx, Provenance>>
fn last_error_place(&mut self) -> InterpResult<'tcx, MPlaceTy<'tcx, Provenance>>
Get last error variable as a place, lazily allocating thread-local storage for it if necessary.
sourcefn set_last_error(&mut self, scalar: Scalar<Provenance>) -> InterpResult<'tcx>
fn set_last_error(&mut self, scalar: Scalar<Provenance>) -> InterpResult<'tcx>
Sets the last error variable.
sourcefn get_last_error(&mut self) -> InterpResult<'tcx, Scalar<Provenance>>
fn get_last_error(&mut self) -> InterpResult<'tcx, Scalar<Provenance>>
Gets the last error variable.
sourcefn io_error_to_errnum(
&self,
err_kind: ErrorKind
) -> InterpResult<'tcx, Scalar<Provenance>>
fn io_error_to_errnum(
&self,
err_kind: ErrorKind
) -> InterpResult<'tcx, Scalar<Provenance>>
This function tries to produce the most similar OS error from the std::io::ErrorKind
as a platform-specific errnum.
sourcefn try_errnum_to_io_error(
&self,
errnum: Scalar<Provenance>
) -> InterpResult<'tcx, Option<ErrorKind>>
fn try_errnum_to_io_error(
&self,
errnum: Scalar<Provenance>
) -> InterpResult<'tcx, Option<ErrorKind>>
The inverse of io_error_to_errnum
.
sourcefn set_last_error_from_io_error(
&mut self,
err_kind: ErrorKind
) -> InterpResult<'tcx>
fn set_last_error_from_io_error(
&mut self,
err_kind: ErrorKind
) -> InterpResult<'tcx>
Sets the last OS error using a std::io::ErrorKind
.
sourcefn try_unwrap_io_result<T: From<i32>>(
&mut self,
result: Result<T>
) -> InterpResult<'tcx, T>
fn try_unwrap_io_result<T: From<i32>>(
&mut self,
result: Result<T>
) -> InterpResult<'tcx, T>
Helper function that consumes an std::io::Result<T>
and returns an
InterpResult<'tcx,T>::Ok
instead. In case the result is an error, this function returns
Ok(-1)
and sets the last OS error accordingly.
This function uses T: From<i32>
instead of i32
directly because some IO related
functions return different integer types (like read
, that returns an i64
).
sourcefn deref_operand_and_offset(
&self,
op: &OpTy<'tcx, Provenance>,
offset: u64,
layout: TyAndLayout<'tcx>
) -> InterpResult<'tcx, MPlaceTy<'tcx, Provenance>>
fn deref_operand_and_offset(
&self,
op: &OpTy<'tcx, Provenance>,
offset: u64,
layout: TyAndLayout<'tcx>
) -> InterpResult<'tcx, MPlaceTy<'tcx, Provenance>>
Calculates the MPlaceTy given the offset and layout of an access on an operand
fn read_scalar_at_offset(
&self,
op: &OpTy<'tcx, Provenance>,
offset: u64,
layout: TyAndLayout<'tcx>
) -> InterpResult<'tcx, Scalar<Provenance>>
fn write_scalar_at_offset(
&mut self,
op: &OpTy<'tcx, Provenance>,
offset: u64,
value: impl Into<Scalar<Provenance>>,
layout: TyAndLayout<'tcx>
) -> InterpResult<'tcx, ()>
sourcefn read_timespec(
&mut self,
tp: &MPlaceTy<'tcx, Provenance>
) -> InterpResult<'tcx, Option<Duration>>
fn read_timespec(
&mut self,
tp: &MPlaceTy<'tcx, Provenance>
) -> InterpResult<'tcx, Option<Duration>>
Parse a timespec
struct and return it as a std::time::Duration
. It returns None
if the value in the timespec
struct is invalid. Some libc functions will return
EINVAL
in this case.
sourcefn read_c_str<'a>(
&'a self,
ptr: Pointer<Option<Provenance>>
) -> InterpResult<'tcx, &'a [u8]>where
'tcx: 'a,
'mir: 'a,
fn read_c_str<'a>(
&'a self,
ptr: Pointer<Option<Provenance>>
) -> InterpResult<'tcx, &'a [u8]>where
'tcx: 'a,
'mir: 'a,
Read a sequence of bytes until the first null terminator.
sourcefn write_c_str(
&mut self,
c_str: &[u8],
ptr: Pointer<Option<Provenance>>,
size: u64
) -> InterpResult<'tcx, (bool, u64)>
fn write_c_str(
&mut self,
c_str: &[u8],
ptr: Pointer<Option<Provenance>>,
size: u64
) -> InterpResult<'tcx, (bool, u64)>
Helper function to write a sequence of bytes with an added null-terminator, which is what
the Unix APIs usually handle. This function returns Ok((false, length))
without trying
to write if size
is not large enough to fit the contents of c_str
plus a null
terminator. It returns Ok((true, length))
if the writing process was successful. The
string length returned does include the null terminator.
sourcefn read_wide_str(
&self,
ptr: Pointer<Option<Provenance>>
) -> InterpResult<'tcx, Vec<u16>>
fn read_wide_str(
&self,
ptr: Pointer<Option<Provenance>>
) -> InterpResult<'tcx, Vec<u16>>
Read a sequence of u16 until the first null terminator.
sourcefn write_wide_str(
&mut self,
wide_str: &[u16],
ptr: Pointer<Option<Provenance>>,
size: u64
) -> InterpResult<'tcx, (bool, u64)>
fn write_wide_str(
&mut self,
wide_str: &[u16],
ptr: Pointer<Option<Provenance>>,
size: u64
) -> InterpResult<'tcx, (bool, u64)>
Helper function to write a sequence of u16 with an added 0x0000-terminator, which is what
the Windows APIs usually handle. This function returns Ok((false, length))
without trying
to write if size
is not large enough to fit the contents of os_string
plus a null
terminator. It returns Ok((true, length))
if the writing process was successful. The
string length returned does include the null terminator. Length is measured in units of
u16.
sourcefn check_abi<'a>(&self, abi: Abi, exp_abi: Abi) -> InterpResult<'a, ()>
fn check_abi<'a>(&self, abi: Abi, exp_abi: Abi) -> InterpResult<'a, ()>
Check that the ABI is what we expect.
fn frame_in_std(&self) -> bool
sourcefn handle_unsupported<S: AsRef<str>>(
&mut self,
error_msg: S
) -> InterpResult<'tcx, ()>
fn handle_unsupported<S: AsRef<str>>(
&mut self,
error_msg: S
) -> InterpResult<'tcx, ()>
Handler that should be called when unsupported functionality is encountered. This function will either panic within the context of the emulated application or return an error in the Miri process context
Return value of Ok(bool)
indicates whether execution should continue.
fn check_abi_and_shim_symbol_clash(
&mut self,
abi: Abi,
exp_abi: Abi,
link_name: Symbol
) -> InterpResult<'tcx, ()>
fn check_shim<'a, const N: usize>(
&mut self,
abi: Abi,
exp_abi: Abi,
link_name: Symbol,
args: &'a [OpTy<'tcx, Provenance>]
) -> InterpResult<'tcx, &'a [OpTy<'tcx, Provenance>; N]>where
&'a [OpTy<'tcx, Provenance>; N]: TryFrom<&'a [OpTy<'tcx, Provenance>]>,
sourcefn mark_immutable(&mut self, mplace: &MemPlace<Provenance>)
fn mark_immutable(&mut self, mplace: &MemPlace<Provenance>)
Mark a machine allocation that was just created as immutable.