Skip to content

Commit daaa81f

Browse files
committed
document general shim pattern
1 parent ab88e64 commit daaa81f

File tree

5 files changed

+39
-0
lines changed

5 files changed

+39
-0
lines changed

src/shims/foreign_items.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,38 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
366366
) -> InterpResult<'tcx, EmulateByNameResult<'mir, 'tcx>> {
367367
let this = self.eval_context_mut();
368368

369+
// When adding a new shim, you should follow the following pattern:
370+
// ```
371+
// "shim_name" => {
372+
// let [arg1, arg2, arg3] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
373+
// let result = this.shim_name(arg1, arg2, arg3)?;
374+
// this.write_scalar(result, dest)?;
375+
// }
376+
// ```
377+
// and then define `shim_name` as a helper function in an extension trait in a suitable file
378+
// (see e.g. `unix/fs.rs`):
379+
// ```
380+
// fn shim_name(
381+
// &mut self,
382+
// arg1: &OpTy<'tcx, Provenance>,
383+
// arg2: &OpTy<'tcx, Provenance>,
384+
// arg3: &OpTy<'tcx, Provenance>)
385+
// -> InterpResult<'tcx, Scalar<Provenance>> {
386+
// let this = self.eval_context_mut();
387+
//
388+
// // First thing: load all the arguments. Details depend on the shim.
389+
// let arg1 = this.read_scalar(arg1)?.to_u32()?;
390+
// let arg2 = this.read_pointer(arg2)?; // when you need to work with the pointer directly
391+
// let arg3 = this.deref_operand(arg3)?; // when you want to load/store through the pointer at its declared type
392+
//
393+
// // ...
394+
//
395+
// Ok(Scalar::from_u32(42))
396+
// }
397+
// ```
398+
// You might find existing shims not following this pattern, most
399+
// likely because they predate it or because for some reason they cannot be made to fit.
400+
369401
// Here we dispatch all the shims for foreign functions. If you have a platform specific
370402
// shim, add it to the corresponding submodule.
371403
match link_name.as_str() {

src/shims/unix/foreign_items.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
2424
) -> InterpResult<'tcx, EmulateByNameResult<'mir, 'tcx>> {
2525
let this = self.eval_context_mut();
2626

27+
// See `fn emulate_foreign_item_by_name` in `shims/foreign_items.rs` for the general pattern.
2728
#[rustfmt::skip]
2829
match link_name.as_str() {
2930
// Environment related shims

src/shims/unix/linux/foreign_items.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1919
) -> InterpResult<'tcx, EmulateByNameResult<'mir, 'tcx>> {
2020
let this = self.eval_context_mut();
2121

22+
// See `fn emulate_foreign_item_by_name` in `shims/foreign_items.rs` for the general pattern.
23+
2224
match link_name.as_str() {
2325
// errno
2426
"__errno_location" => {

src/shims/unix/macos/foreign_items.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1717
) -> InterpResult<'tcx, EmulateByNameResult<'mir, 'tcx>> {
1818
let this = self.eval_context_mut();
1919

20+
// See `fn emulate_foreign_item_by_name` in `shims/foreign_items.rs` for the general pattern.
21+
2022
match link_name.as_str() {
2123
// errno
2224
"__error" => {

src/shims/windows/foreign_items.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
2323
) -> InterpResult<'tcx, EmulateByNameResult<'mir, 'tcx>> {
2424
let this = self.eval_context_mut();
2525

26+
// See `fn emulate_foreign_item_by_name` in `shims/foreign_items.rs` for the general pattern.
27+
2628
// Windows API stubs.
2729
// HANDLE = isize
2830
// NTSTATUS = LONH = i32

0 commit comments

Comments
 (0)