Auto merge of #2481 - RalfJung:shim-pattern, r=oli-obk

document general shim pattern

r? `@oli-obk`
This commit is contained in:
bors 2022-08-22 14:44:53 +00:00
commit a109994f22
5 changed files with 39 additions and 0 deletions

View File

@ -369,6 +369,38 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
) -> InterpResult<'tcx, EmulateByNameResult<'mir, 'tcx>> {
let this = self.eval_context_mut();
// When adding a new shim, you should follow the following pattern:
// ```
// "shim_name" => {
// let [arg1, arg2, arg3] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
// let result = this.shim_name(arg1, arg2, arg3)?;
// this.write_scalar(result, dest)?;
// }
// ```
// and then define `shim_name` as a helper function in an extension trait in a suitable file
// (see e.g. `unix/fs.rs`):
// ```
// fn shim_name(
// &mut self,
// arg1: &OpTy<'tcx, Provenance>,
// arg2: &OpTy<'tcx, Provenance>,
// arg3: &OpTy<'tcx, Provenance>)
// -> InterpResult<'tcx, Scalar<Provenance>> {
// let this = self.eval_context_mut();
//
// // First thing: load all the arguments. Details depend on the shim.
// let arg1 = this.read_scalar(arg1)?.to_u32()?;
// let arg2 = this.read_pointer(arg2)?; // when you need to work with the pointer directly
// let arg3 = this.deref_operand(arg3)?; // when you want to load/store through the pointer at its declared type
//
// // ...
//
// Ok(Scalar::from_u32(42))
// }
// ```
// You might find existing shims not following this pattern, most
// likely because they predate it or because for some reason they cannot be made to fit.
// Here we dispatch all the shims for foreign functions. If you have a platform specific
// shim, add it to the corresponding submodule.
match link_name.as_str() {

View File

@ -24,6 +24,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'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.
#[rustfmt::skip]
match link_name.as_str() {
// Environment related shims

View File

@ -19,6 +19,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'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.
match link_name.as_str() {
// errno
"__errno_location" => {

View File

@ -17,6 +17,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'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.
match link_name.as_str() {
// errno
"__error" => {

View File

@ -23,6 +23,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'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.
// Windows API stubs.
// HANDLE = isize
// NTSTATUS = LONH = i32