shadow_shim_helper_rs/
shadow_syscalls.rs

1/// shadow-specific syscall numbers. When running under shadow, the shim (or
2/// managed code) can make syscalls with these numbers to invoke shadow-specific
3/// syscalls.
4//
5// We comment-out old syscall numbers instead of removing them for a few reasons:
6// - If shadow accidentally tries using an old version of the shim, it could lead to very confusing
7//   behaviour if shadow and the shim were to interpret the syscall numbers differently.
8// - If the plugin tries to interact with shadow by calling one of shadow's custom syscalls (for
9//   example to disable interposition), we wouldn't want the syscall meaning to change, even though
10//   we don't support this feature.
11// - When looking at shadow logs (for example syscall counts) from old simulations using old shadow
12//   versions, it might be less confusing if those old logs used the same syscall numbers.
13#[derive(Debug, Eq, PartialEq, num_enum::TryFromPrimitive, num_enum::IntoPrimitive)]
14#[repr(u32)]
15#[allow(non_camel_case_types)]
16pub enum ShadowSyscallNum {
17    // Deprecated: SYS_shadow_set_ptrace_allow_native_syscalls = 1000,
18    // Deprecated: SYS_shadow_get_ipc_blk = 1001,
19    // Deprecated: SYS_shadow_get_shm_blk = 1002,
20    hostname_to_addr_ipv4 = 1003,
21    init_memory_manager = 1004,
22    // Conceptually similar to SYS_sched_yield, but made by the shim to return
23    // control to Shadow. For now, using a different syscall here is mostly for
24    // debugging purposes, so that it doesn't appear that the managed code
25    // issues a SYS_sched_yield.
26    shadow_yield = 1005,
27}
28
29impl TryFrom<linux_api::syscall::SyscallNum> for ShadowSyscallNum {
30    type Error = <ShadowSyscallNum as TryFrom<u32>>::Error;
31
32    fn try_from(value: linux_api::syscall::SyscallNum) -> Result<Self, Self::Error> {
33        ShadowSyscallNum::try_from(u32::from(value))
34    }
35}
36
37impl From<ShadowSyscallNum> for linux_api::syscall::SyscallNum {
38    fn from(value: ShadowSyscallNum) -> Self {
39        linux_api::syscall::SyscallNum::from(u32::from(value))
40    }
41}
42
43pub mod export {
44    use super::*;
45
46    /// Returns whether the given number is a shadow-specific syscall number.
47    #[unsafe(no_mangle)]
48    pub extern "C-unwind" fn syscall_num_is_shadow(n: core::ffi::c_long) -> bool {
49        let Ok(n) = u32::try_from(n) else {
50            return false;
51        };
52        ShadowSyscallNum::try_from(n).is_ok()
53    }
54}