Skip to main content

thruput_xdr/
syscalls.rs

1//! # Syscalls Module
2//!
3//! This contains the generated system call bindings for all syscalls in Thruput.
4//! In most cases, you should not need to call these functions directly.  Instead,
5//! the SDK provides a higher-level interface for using these functions.
6//!
7//! Internal notes, for those who are curious:
8//!
9//! There are three variants generated for each syscall:
10//!
11//! 1. **{syscall_name}**: Convenience wrapper that returns `SyscallResult<T>`.
12//!    Takes only input parameters and returns outputs in the Result. Calls `uninit_{syscall_name}`
13//!    internally with MaybeUninit outputs. For syscalls that don't return (like Exit, Return),
14//!    this variant returns `!` and calls the uninit variant directly.
15//!    We do not generate this method if it returns a span argument,
16//!    as in that case the caller is responsible for providing a buffer into which the
17//!    syscall can write the output.
18//!
19//! 2. **raw_{syscall_name}**: Takes input arguments as immutable references (&) or,
20//!    for non-optional arguments marked `primitive_type` in syscalls.yaml, as the
21//!    value itself; such a type must fit in one `SyscallWord` (32 bits on riscv32).
22//!    Outputs are taken as mutable references (&mut). Returns a `SysErr` error code.
23//!
24//! 3. **uninit_{syscall_name}**: Low-level variant that takes outputs as
25//!    `&mut MaybeUninit<T>` arguments (instead of `&mut T`), and inputs the same way
26//!    as the raw variant. Fixed-size outputs are initialized only if the error is
27//!    `kSyscallErrorCodeNone` (0); span outputs only in their first `min(len, written_len)` bytes.
28//!
29//! The raw_{syscall_name} variant is a thin wrapper around the uninit_{syscall_name} variant,
30//! with appropriate transmute calls to convert from `&mut T` to `&mut MaybeUninit<T>`.
31//! The {syscall_name} variant also wraps uninit_{syscall_name}, handling MaybeUninit initialization
32//! and returning results in a more idiomatic Rust style.
33//!
34//! These bindings are a thin wrapper around the dispatch chokepoint
35//! `thruput_syscall::syscall_wrapper`, which leaves the guest and executes a
36//! system call. See the `thruput-syscall` crate for the per-target dispatch
37//! paths (riscv32 `ecall`, native mock).
38
39use crate::*;
40
41// The `syscalls` feature pulls in `thruput-syscall`, which only provides a
42// dispatch path on riscv32 or under its `syscalls_mock` feature. On any other
43// target it is empty, so guard with a clear message rather than letting the
44// `SyscallWord` / `syscall_wrapper` imports below fail as unresolved.
45#[cfg(not(any(target_arch = "riscv32", feature = "syscalls_mock")))]
46compile_error!(
47    "the `syscalls` feature has no dispatch path on this target; build for riscv32 or enable `syscalls_mock`"
48);
49
50pub use thruput_syscall::SyscallWord;
51use thruput_syscall::syscall_wrapper;
52
53pub type SyscallResult<T> = core::result::Result<T, SysErr>;
54
55thruput_xdr_macros::generate_syscall_decls!("src/syscalls.yaml");