diff --git a/src/shims/foreign_items.rs b/src/shims/foreign_items.rs index e7cfd43f1b..f9e9f7f02c 100644 --- a/src/shims/foreign_items.rs +++ b/src/shims/foreign_items.rs @@ -366,6 +366,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> { + // 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() { diff --git a/src/shims/unix/foreign_items.rs b/src/shims/unix/foreign_items.rs index 58b0997c6c..49bff7c17e 100644 --- a/src/shims/unix/foreign_items.rs +++ b/src/shims/unix/foreign_items.rs @@ -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 diff --git a/src/shims/unix/linux/foreign_items.rs b/src/shims/unix/linux/foreign_items.rs index 6881d829c1..1e007db1e9 100644 --- a/src/shims/unix/linux/foreign_items.rs +++ b/src/shims/unix/linux/foreign_items.rs @@ -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" => { diff --git a/src/shims/unix/macos/foreign_items.rs b/src/shims/unix/macos/foreign_items.rs index fd7d5fb763..be789648e7 100644 --- a/src/shims/unix/macos/foreign_items.rs +++ b/src/shims/unix/macos/foreign_items.rs @@ -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" => { diff --git a/src/shims/windows/foreign_items.rs b/src/shims/windows/foreign_items.rs index d853f3084d..c6536d1d09 100644 --- a/src/shims/windows/foreign_items.rs +++ b/src/shims/windows/foreign_items.rs @@ -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