Reference

System call ABI

How SlopOS numbers its system calls, which registers they use, and what they return.

This page lists the rules of the SlopOS system call interface: numbering, registers, return values and the families of calls. The authoritative table of numbers is abi/src/syscall/numbers.rs (crate slopos_abi); errno values are in abi/src/errno.rs. System calls explains how the kernel handles a call.

Numbering

RangeContentsRule
0 to 472 (SYSCALL_LINUX_MAX)Linux-numbered callsNumber, name, arguments and behaviour are those of the Linux x86-64 call
1024 (SYSCALL_PRIVATE_BASE) upwardsSlopOS-only callsNumbered 1024 + k, contiguous from k = 0; the private table holds 48 slots (SYSCALL_PRIVATE_TABLE_SIZE)
  • A number below 1024 always means the Linux call with that number. If SlopOS does not implement it, the number returns -ENOSYS; it is never reused for something else.
  • 1024 is above every number Linux has assigned and below the x32 marker bit (bit 30), so a private number cannot be mistaken for either. ARM uses the same scheme with __ARM_NR_BASE.
  • SlopRing uses private numbers, not io_uring's (425 to 427), because it does not implement io_uring's interface.
  • scripts/check_syscall_abi.sh enforces these rules. It compares every number below 1024 with a vendored copy of Linux's syscall_64.tbl and fails if a name sits on a number Linux gave to another call, if the private range has a gap, if a number or name is used twice, or if a private name matches a Linux call without an allowlist entry explaining why.
  • Numbers changed in September 2026 (a breaking change). Programs built against older numbers do not run on current kernels.

Registers

The calling convention is the Linux x86-64 one.

RegisterUse
raxSystem call number on entry, return value on exit
rdi, rsi, rdx, r10, r8, r9Arguments 1 to 6
rcx, r11Overwritten by the syscall instruction

The fourth argument is in r10, not rcx, because the syscall instruction stores the return address in rcx.

Return values and errors

  • Success returns a value of zero or more.
  • Failure returns a negated errno, so any value from -4095 to -1 is an error.
  • Errno values use Linux's numbers (EPERM is 1, ENOSYS is 38).
  • A number with no handler, in either range or outside both, returns -ENOSYS.
  • ERESTARTSYS (512) and ERESTARTNOHAND (514) are kernel-internal and never reach a program. When a signal interrupts a call that returned one of them, the kernel either restarts the call after the signal handler runs or returns -EINTR, following Linux's SA_RESTART rules.

Families

Linux-numbered calls:

FamilyCalls
File I/Oread, write, open, openat, close, pread64, pwrite64, readv, writev, lseek, fcntl, ioctl, flock, fsync, fdatasync, truncate, ftruncate
Paths and metadatastat, fstat, lstat, newfstatat, access, faccessat, faccessat2, getdents64, getcwd, chdir, fchdir, mkdir, mkdirat, rmdir, rename, renameat, link, linkat, unlink, unlinkat, symlink, symlinkat, readlink, readlinkat, chmod, fchmod, fchmodat, fchmodat2, mknod, mknodat, umask, utimensat, statfs, fstatfs
Descriptors and pollingdup, dup2, dup3, pipe, pipe2, poll, ppoll, select, pselect6, memfd_create, pidfd_open, signalfd4
Memorymmap, munmap, mprotect, msync, brk
Processes and threadsfork, clone, execve, wait4, exit, exit_group, getpid, getppid, gettid, getpgid, setpgid, getsid, setsid, getuid, getgid, geteuid, getegid, arch_prctl, futex, prlimit64, vhangup
Signalsrt_sigaction, rt_sigprocmask, rt_sigreturn, rt_sigsuspend, rt_sigtimedwait, rt_sigpending, rt_sigqueueinfo, rt_tgsigqueueinfo, kill, tgkill, sigaltstack
Scheduling and timesched_yield, sched_setaffinity, sched_getaffinity, getcpu, getpriority, setpriority, nanosleep, clock_gettime, clock_settime
Networkingsocket, bind, listen, accept, accept4, connect, sendto, recvfrom, sendmsg, recvmsg, getsockname, getpeername, setsockopt, getsockopt, shutdown
Systemuname, sysinfo, getrandom, mount, umount2, sync, reboot

SlopOS-only calls:

FamilyCalls
Introspection and loggingklog_write, sys_info, process_list, cpu_info, percpu_stats
Terminalctty_read
Process launchspawn_path, sigdefault
Network controlresolve, net_query, net_iface_ctl, net_addr_ctl, net_route_ctl, net_resolver_set, net_monitor
Display and inputfb_info, fb_flip, cursor_set_image, cursor_move, set_display_mode, screen_acquire, input_sink_acquire, input_poll_batch, clipboard_copy, clipboard_paste, font_set, keymap_load, keymap_get_name
SlopRingring_setup, ring_enter, ring_register (see SlopRing)
Wheel of Fateroulette, roulette_result, roulette_draw
Testingtest_report, run_userland_tests, test_panic
Firmware variablesefivar_get, efivar_set

Each call also has a capability class fixed at compile time, which decides who may make it. Permissions lists the classes.

Rules for changing the ABI

  • abi/src/syscall/numbers.rs is the only place a number is written down. Userland imports the constant; documentation does not repeat numbers.
  • A Linux-numbered slot holds only the Linux call of that number, with Linux's arguments.
  • A new SlopOS-only call takes the next free 1024 + k. When the private table is full, SYSCALL_PRIVATE_TABLE_SIZE grows.
  • Every struct passed between a program and the kernel is #[repr(C)] and has compile-time checks on its size and field offsets.

Add a syscall walks through adding one. The Linux syscall(2) and errno(3) man pages document the conventions SlopOS follows, and Linux's syscall_64.tbl is the numbering it follows.

On this page