make some things on foreign_items private

This commit is contained in:
Ralf Jung 2023-10-06 09:20:51 +02:00
parent bc8d4dfa95
commit 099311ba5a
12 changed files with 258 additions and 258 deletions

View file

@ -37,119 +37,129 @@ impl DynSym {
}
/// Returned by `emulate_foreign_item_inner`.
pub enum EmulateByNameResult<'mir, 'tcx> {
pub enum EmulateForeignItemResult {
/// The caller is expected to jump to the return block.
NeedsJumping,
/// Jumping has already been taken care of.
AlreadyJumped,
/// A MIR body has been found for the function.
MirBody(&'mir mir::Body<'tcx>, ty::Instance<'tcx>),
/// The item is not supported.
NotSupported,
}
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
/// Returns the minimum alignment for the target architecture for allocations of the given size.
fn min_align(&self, size: u64, kind: MiriMemoryKind) -> Align {
let this = self.eval_context_ref();
// List taken from `library/std/src/sys/common/alloc.rs`.
// This list should be kept in sync with the one from libstd.
let min_align = match this.tcx.sess.target.arch.as_ref() {
"x86" | "arm" | "mips" | "mips32r6" | "powerpc" | "powerpc64" | "asmjs" | "wasm32" => 8,
"x86_64" | "aarch64" | "mips64" | "mips64r6" | "s390x" | "sparc64" | "loongarch64" =>
16,
arch => bug!("unsupported target architecture for malloc: `{}`", arch),
/// Emulates calling a foreign item, failing if the item is not supported.
/// This function will handle `goto_block` if needed.
/// Returns Ok(None) if the foreign item was completely handled
/// by this function.
/// Returns Ok(Some(body)) if processing the foreign item
/// is delegated to another function.
fn emulate_foreign_item(
&mut self,
link_name: Symbol,
abi: Abi,
args: &[OpTy<'tcx, Provenance>],
dest: &PlaceTy<'tcx, Provenance>,
ret: Option<mir::BasicBlock>,
unwind: mir::UnwindAction,
) -> InterpResult<'tcx, Option<(&'mir mir::Body<'tcx>, ty::Instance<'tcx>)>> {
let this = self.eval_context_mut();
let tcx = this.tcx.tcx;
// First: functions that diverge.
let ret = match ret {
None =>
match link_name.as_str() {
"miri_start_panic" => {
// `check_shim` happens inside `handle_miri_start_panic`.
this.handle_miri_start_panic(abi, link_name, args, unwind)?;
return Ok(None);
}
// This matches calls to the foreign item `panic_impl`.
// The implementation is provided by the function with the `#[panic_handler]` attribute.
"panic_impl" => {
// We don't use `check_shim` here because we are just forwarding to the lang
// item. Argument count checking will be performed when the returned `Body` is
// called.
this.check_abi_and_shim_symbol_clash(abi, Abi::Rust, link_name)?;
let panic_impl_id = tcx.lang_items().panic_impl().unwrap();
let panic_impl_instance = ty::Instance::mono(tcx, panic_impl_id);
return Ok(Some((
this.load_mir(panic_impl_instance.def, None)?,
panic_impl_instance,
)));
}
#[rustfmt::skip]
| "exit"
| "ExitProcess"
=> {
let exp_abi = if link_name.as_str() == "exit" {
Abi::C { unwind: false }
} else {
Abi::System { unwind: false }
};
let [code] = this.check_shim(abi, exp_abi, link_name, args)?;
// it's really u32 for ExitProcess, but we have to put it into the `Exit` variant anyway
let code = this.read_scalar(code)?.to_i32()?;
throw_machine_stop!(TerminationInfo::Exit { code: code.into(), leak_check: false });
}
"abort" => {
let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
throw_machine_stop!(TerminationInfo::Abort(
"the program aborted execution".to_owned()
))
}
_ => {
if let Some(body) = this.lookup_exported_symbol(link_name)? {
return Ok(Some(body));
}
this.handle_unsupported(format!(
"can't call (diverging) foreign function: {link_name}"
))?;
return Ok(None);
}
},
Some(p) => p,
};
// Windows always aligns, even small allocations.
// Source: <https://support.microsoft.com/en-us/help/286470/how-to-use-pageheap-exe-in-windows-xp-windows-2000-and-windows-server>
// But jemalloc does not, so for the C heap we only align if the allocation is sufficiently big.
if kind == MiriMemoryKind::WinHeap || size >= min_align {
return Align::from_bytes(min_align).unwrap();
}
// We have `size < min_align`. Round `size` *down* to the next power of two and use that.
fn prev_power_of_two(x: u64) -> u64 {
let next_pow2 = x.next_power_of_two();
if next_pow2 == x {
// x *is* a power of two, just use that.
x
} else {
// x is between two powers, so next = 2*prev.
next_pow2 / 2
// Second: functions that return immediately.
match this.emulate_foreign_item_inner(link_name, abi, args, dest)? {
EmulateForeignItemResult::NeedsJumping => {
trace!("{:?}", this.dump_place(dest));
this.go_to_block(ret);
}
EmulateForeignItemResult::AlreadyJumped => (),
EmulateForeignItemResult::NotSupported => {
if let Some(body) = this.lookup_exported_symbol(link_name)? {
return Ok(Some(body));
}
this.handle_unsupported(format!(
"can't call foreign function `{link_name}` on OS `{os}`",
os = this.tcx.sess.target.os,
))?;
return Ok(None);
}
}
Align::from_bytes(prev_power_of_two(size)).unwrap()
Ok(None)
}
fn malloc(
/// Emulates a call to a `DynSym`.
fn emulate_dyn_sym(
&mut self,
size: u64,
zero_init: bool,
kind: MiriMemoryKind,
) -> InterpResult<'tcx, Pointer<Option<Provenance>>> {
let this = self.eval_context_mut();
if size == 0 {
Ok(Pointer::null())
} else {
let align = this.min_align(size, kind);
let ptr = this.allocate_ptr(Size::from_bytes(size), align, kind.into())?;
if zero_init {
// We just allocated this, the access is definitely in-bounds and fits into our address space.
this.write_bytes_ptr(
ptr.into(),
iter::repeat(0u8).take(usize::try_from(size).unwrap()),
)
.unwrap();
}
Ok(ptr.into())
}
}
fn free(
&mut self,
ptr: Pointer<Option<Provenance>>,
kind: MiriMemoryKind,
sym: DynSym,
abi: Abi,
args: &[OpTy<'tcx, Provenance>],
dest: &PlaceTy<'tcx, Provenance>,
ret: Option<mir::BasicBlock>,
unwind: mir::UnwindAction,
) -> InterpResult<'tcx> {
let this = self.eval_context_mut();
if !this.ptr_is_null(ptr)? {
this.deallocate_ptr(ptr, None, kind.into())?;
}
let res = self.emulate_foreign_item(sym.0, abi, args, dest, ret, unwind)?;
assert!(res.is_none(), "DynSyms that delegate are not supported");
Ok(())
}
fn realloc(
&mut self,
old_ptr: Pointer<Option<Provenance>>,
new_size: u64,
kind: MiriMemoryKind,
) -> InterpResult<'tcx, Pointer<Option<Provenance>>> {
let this = self.eval_context_mut();
let new_align = this.min_align(new_size, kind);
if this.ptr_is_null(old_ptr)? {
if new_size == 0 {
Ok(Pointer::null())
} else {
let new_ptr =
this.allocate_ptr(Size::from_bytes(new_size), new_align, kind.into())?;
Ok(new_ptr.into())
}
} else {
if new_size == 0 {
this.deallocate_ptr(old_ptr, None, kind.into())?;
Ok(Pointer::null())
} else {
let new_ptr = this.reallocate_ptr(
old_ptr,
None,
Size::from_bytes(new_size),
new_align,
kind.into(),
)?;
Ok(new_ptr.into())
}
}
}
/// Lookup the body of a function that has `link_name` as the symbol name.
fn lookup_exported_symbol(
&mut self,
@ -244,6 +254,78 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
}
}
fn malloc(
&mut self,
size: u64,
zero_init: bool,
kind: MiriMemoryKind,
) -> InterpResult<'tcx, Pointer<Option<Provenance>>> {
let this = self.eval_context_mut();
if size == 0 {
Ok(Pointer::null())
} else {
let align = this.min_align(size, kind);
let ptr = this.allocate_ptr(Size::from_bytes(size), align, kind.into())?;
if zero_init {
// We just allocated this, the access is definitely in-bounds and fits into our address space.
this.write_bytes_ptr(
ptr.into(),
iter::repeat(0u8).take(usize::try_from(size).unwrap()),
)
.unwrap();
}
Ok(ptr.into())
}
}
fn free(
&mut self,
ptr: Pointer<Option<Provenance>>,
kind: MiriMemoryKind,
) -> InterpResult<'tcx> {
let this = self.eval_context_mut();
if !this.ptr_is_null(ptr)? {
this.deallocate_ptr(ptr, None, kind.into())?;
}
Ok(())
}
fn realloc(
&mut self,
old_ptr: Pointer<Option<Provenance>>,
new_size: u64,
kind: MiriMemoryKind,
) -> InterpResult<'tcx, Pointer<Option<Provenance>>> {
let this = self.eval_context_mut();
let new_align = this.min_align(new_size, kind);
if this.ptr_is_null(old_ptr)? {
if new_size == 0 {
Ok(Pointer::null())
} else {
let new_ptr =
this.allocate_ptr(Size::from_bytes(new_size), new_align, kind.into())?;
Ok(new_ptr.into())
}
} else {
if new_size == 0 {
this.deallocate_ptr(old_ptr, None, kind.into())?;
Ok(Pointer::null())
} else {
let new_ptr = this.reallocate_ptr(
old_ptr,
None,
Size::from_bytes(new_size),
new_align,
kind.into(),
)?;
Ok(new_ptr.into())
}
}
}
}
impl<'mir, 'tcx: 'mir> EvalContextExtPriv<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
/// Read bytes from a `(ptr, len)` argument
fn read_byte_slice<'i>(&'i self, bytes: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx, &'i [u8]>
where
@ -257,129 +339,47 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
Ok(bytes)
}
/// Emulates calling a foreign item, failing if the item is not supported.
/// This function will handle `goto_block` if needed.
/// Returns Ok(None) if the foreign item was completely handled
/// by this function.
/// Returns Ok(Some(body)) if processing the foreign item
/// is delegated to another function.
fn emulate_foreign_item(
&mut self,
link_name: Symbol,
abi: Abi,
args: &[OpTy<'tcx, Provenance>],
dest: &PlaceTy<'tcx, Provenance>,
ret: Option<mir::BasicBlock>,
unwind: mir::UnwindAction,
) -> InterpResult<'tcx, Option<(&'mir mir::Body<'tcx>, ty::Instance<'tcx>)>> {
let this = self.eval_context_mut();
let tcx = this.tcx.tcx;
// First: functions that diverge.
let ret = match ret {
None =>
match link_name.as_str() {
"miri_start_panic" => {
// `check_shim` happens inside `handle_miri_start_panic`.
this.handle_miri_start_panic(abi, link_name, args, unwind)?;
return Ok(None);
}
// This matches calls to the foreign item `panic_impl`.
// The implementation is provided by the function with the `#[panic_handler]` attribute.
"panic_impl" => {
// We don't use `check_shim` here because we are just forwarding to the lang
// item. Argument count checking will be performed when the returned `Body` is
// called.
this.check_abi_and_shim_symbol_clash(abi, Abi::Rust, link_name)?;
let panic_impl_id = tcx.lang_items().panic_impl().unwrap();
let panic_impl_instance = ty::Instance::mono(tcx, panic_impl_id);
return Ok(Some((
this.load_mir(panic_impl_instance.def, None)?,
panic_impl_instance,
)));
}
#[rustfmt::skip]
| "exit"
| "ExitProcess"
=> {
let exp_abi = if link_name.as_str() == "exit" {
Abi::C { unwind: false }
} else {
Abi::System { unwind: false }
};
let [code] = this.check_shim(abi, exp_abi, link_name, args)?;
// it's really u32 for ExitProcess, but we have to put it into the `Exit` variant anyway
let code = this.read_scalar(code)?.to_i32()?;
throw_machine_stop!(TerminationInfo::Exit { code: code.into(), leak_check: false });
}
"abort" => {
let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
throw_machine_stop!(TerminationInfo::Abort(
"the program aborted execution".to_owned()
))
}
_ => {
if let Some(body) = this.lookup_exported_symbol(link_name)? {
return Ok(Some(body));
}
this.handle_unsupported(format!(
"can't call (diverging) foreign function: {link_name}"
))?;
return Ok(None);
}
},
Some(p) => p,
/// Returns the minimum alignment for the target architecture for allocations of the given size.
fn min_align(&self, size: u64, kind: MiriMemoryKind) -> Align {
let this = self.eval_context_ref();
// List taken from `library/std/src/sys/common/alloc.rs`.
// This list should be kept in sync with the one from libstd.
let min_align = match this.tcx.sess.target.arch.as_ref() {
"x86" | "arm" | "mips" | "mips32r6" | "powerpc" | "powerpc64" | "asmjs" | "wasm32" => 8,
"x86_64" | "aarch64" | "mips64" | "mips64r6" | "s390x" | "sparc64" | "loongarch64" =>
16,
arch => bug!("unsupported target architecture for malloc: `{}`", arch),
};
// Second: functions that return immediately.
match this.emulate_foreign_item_inner(link_name, abi, args, dest)? {
EmulateByNameResult::NeedsJumping => {
trace!("{:?}", this.dump_place(dest));
this.go_to_block(ret);
}
EmulateByNameResult::AlreadyJumped => (),
EmulateByNameResult::MirBody(mir, instance) => return Ok(Some((mir, instance))),
EmulateByNameResult::NotSupported => {
if let Some(body) = this.lookup_exported_symbol(link_name)? {
return Ok(Some(body));
}
this.handle_unsupported(format!(
"can't call foreign function `{link_name}` on OS `{os}`",
os = this.tcx.sess.target.os,
))?;
return Ok(None);
// Windows always aligns, even small allocations.
// Source: <https://support.microsoft.com/en-us/help/286470/how-to-use-pageheap-exe-in-windows-xp-windows-2000-and-windows-server>
// But jemalloc does not, so for the C heap we only align if the allocation is sufficiently big.
if kind == MiriMemoryKind::WinHeap || size >= min_align {
return Align::from_bytes(min_align).unwrap();
}
// We have `size < min_align`. Round `size` *down* to the next power of two and use that.
fn prev_power_of_two(x: u64) -> u64 {
let next_pow2 = x.next_power_of_two();
if next_pow2 == x {
// x *is* a power of two, just use that.
x
} else {
// x is between two powers, so next = 2*prev.
next_pow2 / 2
}
}
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(())
Align::from_bytes(prev_power_of_two(size)).unwrap()
}
/// Emulates calling the internal __rust_* allocator functions
fn emulate_allocator(
&mut self,
default: impl FnOnce(&mut MiriInterpCx<'mir, 'tcx>) -> InterpResult<'tcx>,
) -> InterpResult<'tcx, EmulateByNameResult<'mir, 'tcx>> {
) -> InterpResult<'tcx, EmulateForeignItemResult> {
let this = self.eval_context_mut();
let Some(allocator_kind) = this.tcx.allocator_kind(()) else {
// in real code, this symbol does not exist without an allocator
return Ok(EmulateByNameResult::NotSupported);
return Ok(EmulateForeignItemResult::NotSupported);
};
match allocator_kind {
@ -389,11 +389,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
// and not execute any Miri shim. Somewhat unintuitively doing so is done
// by returning `NotSupported`, which triggers the `lookup_exported_symbol`
// fallback case in `emulate_foreign_item`.
return Ok(EmulateByNameResult::NotSupported);
return Ok(EmulateForeignItemResult::NotSupported);
}
AllocatorKind::Default => {
default(this)?;
Ok(EmulateByNameResult::NeedsJumping)
Ok(EmulateForeignItemResult::NeedsJumping)
}
}
}
@ -404,7 +404,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
abi: Abi,
args: &[OpTy<'tcx, Provenance>],
dest: &PlaceTy<'tcx, Provenance>,
) -> InterpResult<'tcx, EmulateByNameResult<'mir, 'tcx>> {
) -> InterpResult<'tcx, EmulateForeignItemResult> {
let this = self.eval_context_mut();
// First deal with any external C functions in linked .so file.
@ -415,7 +415,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
// by the specified `.so` file; we should continue and check if it corresponds to
// a provided shim.
if this.call_external_c_fct(link_name, dest, args)? {
return Ok(EmulateByNameResult::NeedsJumping);
return Ok(EmulateForeignItemResult::NeedsJumping);
}
}
@ -615,7 +615,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
"__rust_alloc" => return this.emulate_allocator(default),
"miri_alloc" => {
default(this)?;
return Ok(EmulateByNameResult::NeedsJumping);
return Ok(EmulateForeignItemResult::NeedsJumping);
}
_ => unreachable!(),
}
@ -675,7 +675,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
}
"miri_dealloc" => {
default(this)?;
return Ok(EmulateByNameResult::NeedsJumping);
return Ok(EmulateForeignItemResult::NeedsJumping);
}
_ => unreachable!(),
}
@ -1076,12 +1076,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
shims::windows::foreign_items::EvalContextExt::emulate_foreign_item_inner(
this, link_name, abi, args, dest,
),
_ => Ok(EmulateByNameResult::NotSupported),
_ => Ok(EmulateForeignItemResult::NotSupported),
},
};
// We only fall through to here if we did *not* hit the `_` arm above,
// i.e., if we actually emulated the function with one of the shims.
Ok(EmulateByNameResult::NeedsJumping)
Ok(EmulateForeignItemResult::NeedsJumping)
}
/// Check some basic requirements for this allocation request:

View file

@ -2,7 +2,7 @@ use rustc_span::Symbol;
use rustc_target::spec::abi::Abi;
use crate::*;
use shims::foreign_items::EmulateByNameResult;
use shims::foreign_items::EmulateForeignItemResult;
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
@ -17,7 +17,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
abi: Abi,
args: &[OpTy<'tcx, Provenance>],
dest: &PlaceTy<'tcx, Provenance>,
) -> InterpResult<'tcx, EmulateByNameResult<'mir, 'tcx>> {
) -> InterpResult<'tcx, EmulateForeignItemResult> {
let this = self.eval_context_mut();
match link_name.as_str() {
@ -26,10 +26,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
this.write_null(dest)?;
}
_ => return Ok(EmulateByNameResult::NotSupported),
_ => return Ok(EmulateForeignItemResult::NotSupported),
}
#[allow(unreachable_code)]
Ok(EmulateByNameResult::NeedsJumping)
Ok(EmulateForeignItemResult::NeedsJumping)
}
}

View file

@ -9,7 +9,7 @@ use rustc_target::abi::{Align, Size};
use rustc_target::spec::abi::Abi;
use crate::*;
use shims::foreign_items::EmulateByNameResult;
use shims::foreign_items::EmulateForeignItemResult;
use shims::unix::fs::EvalContextExt as _;
use shims::unix::mem::EvalContextExt as _;
use shims::unix::sync::EvalContextExt as _;
@ -28,7 +28,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
abi: Abi,
args: &[OpTy<'tcx, Provenance>],
dest: &PlaceTy<'tcx, Provenance>,
) -> InterpResult<'tcx, EmulateByNameResult<'mir, 'tcx>> {
) -> InterpResult<'tcx, EmulateForeignItemResult> {
let this = self.eval_context_mut();
// See `fn emulate_foreign_item_inner` in `shims/foreign_items.rs` for the general pattern.
@ -626,11 +626,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
"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),
_ => Ok(EmulateForeignItemResult::NotSupported),
};
}
};
Ok(EmulateByNameResult::NeedsJumping)
Ok(EmulateForeignItemResult::NeedsJumping)
}
}

View file

@ -2,7 +2,7 @@ use rustc_span::Symbol;
use rustc_target::spec::abi::Abi;
use crate::*;
use shims::foreign_items::EmulateByNameResult;
use shims::foreign_items::EmulateForeignItemResult;
use shims::unix::thread::EvalContextExt as _;
pub fn is_dyn_sym(_name: &str) -> bool {
@ -17,7 +17,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
abi: Abi,
args: &[OpTy<'tcx, Provenance>],
dest: &PlaceTy<'tcx, Provenance>,
) -> InterpResult<'tcx, EmulateByNameResult<'mir, 'tcx>> {
) -> InterpResult<'tcx, EmulateForeignItemResult> {
let this = self.eval_context_mut();
match link_name.as_str() {
// Threading
@ -45,8 +45,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
this.write_scalar(errno_place.to_ref(this).to_scalar(), dest)?;
}
_ => return Ok(EmulateByNameResult::NotSupported),
_ => return Ok(EmulateForeignItemResult::NotSupported),
}
Ok(EmulateByNameResult::NeedsJumping)
Ok(EmulateForeignItemResult::NeedsJumping)
}
}

View file

@ -4,7 +4,7 @@ use rustc_target::spec::abi::Abi;
use crate::machine::SIGRTMAX;
use crate::machine::SIGRTMIN;
use crate::*;
use shims::foreign_items::EmulateByNameResult;
use shims::foreign_items::EmulateForeignItemResult;
use shims::unix::fs::EvalContextExt as _;
use shims::unix::linux::fd::EvalContextExt as _;
use shims::unix::linux::mem::EvalContextExt as _;
@ -24,7 +24,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
abi: Abi,
args: &[OpTy<'tcx, Provenance>],
dest: &PlaceTy<'tcx, Provenance>,
) -> InterpResult<'tcx, EmulateByNameResult<'mir, 'tcx>> {
) -> InterpResult<'tcx, EmulateForeignItemResult> {
let this = self.eval_context_mut();
// See `fn emulate_foreign_item_inner` in `shims/foreign_items.rs` for the general pattern.
@ -186,7 +186,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
}
id => {
this.handle_unsupported(format!("can't execute syscall with ID {id}"))?;
return Ok(EmulateByNameResult::AlreadyJumped);
return Ok(EmulateForeignItemResult::AlreadyJumped);
}
}
}
@ -217,10 +217,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
this.write_null(dest)?;
}
_ => return Ok(EmulateByNameResult::NotSupported),
_ => return Ok(EmulateForeignItemResult::NotSupported),
};
Ok(EmulateByNameResult::NeedsJumping)
Ok(EmulateForeignItemResult::NeedsJumping)
}
}

View file

@ -2,7 +2,7 @@ use rustc_span::Symbol;
use rustc_target::spec::abi::Abi;
use crate::*;
use shims::foreign_items::EmulateByNameResult;
use shims::foreign_items::EmulateForeignItemResult;
use shims::unix::fs::EvalContextExt as _;
use shims::unix::thread::EvalContextExt as _;
@ -18,7 +18,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
abi: Abi,
args: &[OpTy<'tcx, Provenance>],
dest: &PlaceTy<'tcx, Provenance>,
) -> InterpResult<'tcx, EmulateByNameResult<'mir, 'tcx>> {
) -> InterpResult<'tcx, EmulateForeignItemResult> {
let this = self.eval_context_mut();
// See `fn emulate_foreign_item_inner` in `shims/foreign_items.rs` for the general pattern.
@ -209,9 +209,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
this.write_scalar(res, dest)?;
}
_ => return Ok(EmulateByNameResult::NotSupported),
_ => return Ok(EmulateForeignItemResult::NotSupported),
};
Ok(EmulateByNameResult::NeedsJumping)
Ok(EmulateForeignItemResult::NeedsJumping)
}
}

View file

@ -6,7 +6,7 @@ use rustc_target::abi::Size;
use rustc_target::spec::abi::Abi;
use crate::*;
use shims::foreign_items::EmulateByNameResult;
use shims::foreign_items::EmulateForeignItemResult;
use shims::windows::handle::{EvalContextExt as _, Handle, PseudoHandle};
use shims::windows::sync::EvalContextExt as _;
use shims::windows::thread::EvalContextExt as _;
@ -23,7 +23,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
abi: Abi,
args: &[OpTy<'tcx, Provenance>],
dest: &PlaceTy<'tcx, Provenance>,
) -> InterpResult<'tcx, EmulateByNameResult<'mir, 'tcx>> {
) -> InterpResult<'tcx, EmulateForeignItemResult> {
let this = self.eval_context_mut();
// See `fn emulate_foreign_item_inner` in `shims/foreign_items.rs` for the general pattern.
@ -583,9 +583,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
this.write_null(dest)?;
}
_ => return Ok(EmulateByNameResult::NotSupported),
_ => return Ok(EmulateForeignItemResult::NotSupported),
}
Ok(EmulateByNameResult::NeedsJumping)
Ok(EmulateForeignItemResult::NeedsJumping)
}
}

View file

@ -5,7 +5,7 @@ use rustc_target::spec::abi::Abi;
use crate::*;
use helpers::bool_to_simd_element;
use shims::foreign_items::EmulateByNameResult;
use shims::foreign_items::EmulateForeignItemResult;
mod sse;
mod sse2;
@ -22,7 +22,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
abi: Abi,
args: &[OpTy<'tcx, Provenance>],
dest: &PlaceTy<'tcx, Provenance>,
) -> InterpResult<'tcx, EmulateByNameResult<'mir, 'tcx>> {
) -> InterpResult<'tcx, EmulateForeignItemResult> {
let this = self.eval_context_mut();
// Prefix should have already been checked.
let unprefixed_name = link_name.as_str().strip_prefix("llvm.x86.").unwrap();
@ -34,7 +34,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
// https://www.intel.com/content/www/us/en/docs/cpp-compiler/developer-guide-reference/2021-8/addcarry-u32-addcarry-u64.html
"addcarry.32" | "addcarry.64" => {
if unprefixed_name == "addcarry.64" && this.tcx.sess.target.arch != "x86_64" {
return Ok(EmulateByNameResult::NotSupported);
return Ok(EmulateForeignItemResult::NotSupported);
}
let [c_in, a, b] = this.check_shim(abi, Abi::Unadjusted, link_name, args)?;
@ -60,7 +60,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
// https://www.intel.com/content/www/us/en/docs/cpp-compiler/developer-guide-reference/2021-8/subborrow-u32-subborrow-u64.html
"subborrow.32" | "subborrow.64" => {
if unprefixed_name == "subborrow.64" && this.tcx.sess.target.arch != "x86_64" {
return Ok(EmulateByNameResult::NotSupported);
return Ok(EmulateForeignItemResult::NotSupported);
}
let [b_in, a, b] = this.check_shim(abi, Abi::Unadjusted, link_name, args)?;
@ -100,9 +100,9 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
this, link_name, abi, args, dest,
);
}
_ => return Ok(EmulateByNameResult::NotSupported),
_ => return Ok(EmulateForeignItemResult::NotSupported),
}
Ok(EmulateByNameResult::NeedsJumping)
Ok(EmulateForeignItemResult::NeedsJumping)
}
}

View file

@ -7,7 +7,7 @@ use rand::Rng as _;
use super::{bin_op_simd_float_all, bin_op_simd_float_first, FloatBinOp, FloatCmpOp};
use crate::*;
use shims::foreign_items::EmulateByNameResult;
use shims::foreign_items::EmulateForeignItemResult;
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
@ -19,7 +19,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
abi: Abi,
args: &[OpTy<'tcx, Provenance>],
dest: &PlaceTy<'tcx, Provenance>,
) -> InterpResult<'tcx, EmulateByNameResult<'mir, 'tcx>> {
) -> InterpResult<'tcx, EmulateForeignItemResult> {
let this = self.eval_context_mut();
// Prefix should have already been checked.
let unprefixed_name = link_name.as_str().strip_prefix("llvm.x86.sse.").unwrap();
@ -228,9 +228,9 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
this.write_scalar(Scalar::from_u32(res), dest)?;
}
_ => return Ok(EmulateByNameResult::NotSupported),
_ => return Ok(EmulateForeignItemResult::NotSupported),
}
Ok(EmulateByNameResult::NeedsJumping)
Ok(EmulateForeignItemResult::NeedsJumping)
}
}

View file

@ -10,7 +10,7 @@ use rustc_target::spec::abi::Abi;
use super::{bin_op_simd_float_all, bin_op_simd_float_first, FloatBinOp, FloatCmpOp};
use crate::*;
use shims::foreign_items::EmulateByNameResult;
use shims::foreign_items::EmulateForeignItemResult;
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
@ -22,7 +22,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
abi: Abi,
args: &[OpTy<'tcx, Provenance>],
dest: &PlaceTy<'tcx, Provenance>,
) -> InterpResult<'tcx, EmulateByNameResult<'mir, 'tcx>> {
) -> InterpResult<'tcx, EmulateForeignItemResult> {
let this = self.eval_context_mut();
// Prefix should have already been checked.
let unprefixed_name = link_name.as_str().strip_prefix("llvm.x86.sse2.").unwrap();
@ -797,9 +797,9 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
this.yield_active_thread();
}
_ => return Ok(EmulateByNameResult::NotSupported),
_ => return Ok(EmulateForeignItemResult::NotSupported),
}
Ok(EmulateByNameResult::NeedsJumping)
Ok(EmulateForeignItemResult::NeedsJumping)
}
}

View file

@ -5,7 +5,7 @@ use rustc_target::spec::abi::Abi;
use super::horizontal_bin_op;
use crate::*;
use shims::foreign_items::EmulateByNameResult;
use shims::foreign_items::EmulateForeignItemResult;
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
@ -17,7 +17,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
abi: Abi,
args: &[OpTy<'tcx, Provenance>],
dest: &PlaceTy<'tcx, Provenance>,
) -> InterpResult<'tcx, EmulateByNameResult<'mir, 'tcx>> {
) -> InterpResult<'tcx, EmulateForeignItemResult> {
let this = self.eval_context_mut();
// Prefix should have already been checked.
let unprefixed_name = link_name.as_str().strip_prefix("llvm.x86.sse3.").unwrap();
@ -83,8 +83,8 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
/*nonoverlapping*/ true,
)?;
}
_ => return Ok(EmulateByNameResult::NotSupported),
_ => return Ok(EmulateForeignItemResult::NotSupported),
}
Ok(EmulateByNameResult::NeedsJumping)
Ok(EmulateForeignItemResult::NeedsJumping)
}
}

View file

@ -4,7 +4,7 @@ use rustc_target::spec::abi::Abi;
use super::horizontal_bin_op;
use crate::*;
use shims::foreign_items::EmulateByNameResult;
use shims::foreign_items::EmulateForeignItemResult;
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
@ -16,7 +16,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
abi: Abi,
args: &[OpTy<'tcx, Provenance>],
dest: &PlaceTy<'tcx, Provenance>,
) -> InterpResult<'tcx, EmulateByNameResult<'mir, 'tcx>> {
) -> InterpResult<'tcx, EmulateForeignItemResult> {
let this = self.eval_context_mut();
// Prefix should have already been checked.
let unprefixed_name = link_name.as_str().strip_prefix("llvm.x86.ssse3.").unwrap();
@ -192,8 +192,8 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
this.write_immediate(*res, &dest)?;
}
}
_ => return Ok(EmulateByNameResult::NotSupported),
_ => return Ok(EmulateForeignItemResult::NotSupported),
}
Ok(EmulateByNameResult::NeedsJumping)
Ok(EmulateForeignItemResult::NeedsJumping)
}
}