Appendix F: Linux System Call Tables

This appendix provides system call numbers and argument conventions for the three architectures covered in this book. All values are for the Linux kernel.

Argument conventions: - x86-64: syscall instruction; number in RAX; args in RDI, RSI, RDX, R10, R8, R9; return in RAX - ARM64: svc #0 instruction; number in X8; args in X0, X1, X2, X3, X4, X5; return in X0 - RISC-V: ecall instruction; number in a7; args in a0, a1, a2, a3, a4, a5; return in a0

Note: ARM64 and RISC-V Linux use the same syscall numbers (from the generic syscall table in include/uapi/asm-generic/unistd.h). x86-64 uses a separate historical table.


File I/O

Name x86-64 ARM64 RISC-V Key Arguments
read 0 63 63 fd, buf, count → bytes read
write 1 64 64 fd, buf, count → bytes written
open 2 56 56 pathname, flags, mode → fd
close 3 57 57 fd → 0
stat 4 80 80 pathname, struct stat * → 0
fstat 5 80 80 fd, struct stat * → 0
lstat 6 1039 1039 pathname, struct stat * (no follow symlink) → 0
poll 7 73 73 fds, nfds, timeout → ready count
lseek 8 62 62 fd, offset, whence → new offset
openat 257 56 56 dirfd, pathname, flags, mode → fd
readv 19 65 65 fd, iov, iovcnt → bytes read
writev 20 66 66 fd, iov, iovcnt → bytes written
pread64 17 67 67 fd, buf, count, offset → bytes read
pwrite64 18 68 68 fd, buf, count, offset → bytes written
readlink 89 78 78 pathname, buf, bufsiz → len
truncate 76 45 45 pathname, length → 0
ftruncate 77 46 46 fd, length → 0
getcwd 79 17 17 buf, size → buf
chdir 80 49 49 pathname → 0
rename 82 38 38 oldpath, newpath → 0
mkdir 83 34 34 pathname, mode → 0
rmdir 84 35 35 pathname → 0
unlink 87 35 35 pathname → 0
symlink 88 36 36 target, linkpath → 0
chmod 90 52 52 pathname, mode → 0
fchmod 91 52 52 fd, mode → 0
getdents64 217 61 61 fd, dirp, count → bytes read
ioctl 16 29 29 fd, request, arg → result
fcntl 72 25 25 fd, cmd, arg → result
dup 32 23 23 oldfd → newfd
dup2 33 1041 1041 oldfd, newfd → newfd
dup3 292 24 24 oldfd, newfd, flags → newfd
pipe 22 59 59 pipefd[2] → 0
pipe2 293 59 59 pipefd[2], flags → 0

Memory Management

Name x86-64 ARM64 RISC-V Key Arguments
mmap 9 222 222 addr, length, prot, flags, fd, offset → addr
mprotect 10 226 226 addr, length, prot → 0
munmap 11 215 215 addr, length → 0
brk 12 214 214 addr → new brk
mremap 25 216 216 addr, old_len, new_len, flags, new_addr → addr
msync 26 227 227 addr, length, flags → 0
madvise 28 233 233 addr, length, advice → 0
mincore 27 232 232 addr, length, vec → 0
mlock 149 228 228 addr, length → 0
munlock 150 229 229 addr, length → 0

mmap Protection Flags (prot argument)

Flag Value Meaning
PROT_NONE 0 No access
PROT_READ 1 Read permission
PROT_WRITE 2 Write permission
PROT_EXEC 4 Execute permission

mmap Map Flags (flags argument)

Flag Value Meaning
MAP_SHARED 1 Shared mapping
MAP_PRIVATE 2 Private copy-on-write mapping
MAP_ANONYMOUS 32 Not backed by a file
MAP_FIXED 16 Map at exactly addr
MAP_POPULATE 32768 Pre-fault pages

Process and Thread Management

Name x86-64 ARM64 RISC-V Key Arguments
fork 57 1079 1079 → pid (0 in child, child pid in parent)
vfork 58 1071 1071 → pid
clone 56 220 220 flags, child_stack, ptid, ctid, regs → tid
execve 59 221 221 filename, argv, envp → 0 (or error)
execveat 322 281 281 dirfd, filename, argv, envp, flags
exit 60 93 93 status code (no return)
exit_group 231 94 94 status code (exits all threads)
wait4 61 1062 1062 pid, wstatus, options, rusage → pid
waitid 247 95 95 idtype, id, infop, options, rusage → 0
kill 62 129 129 pid, sig → 0
tkill 200 130 130 tid, sig → 0
getpid 39 172 172 → pid
gettid 186 178 178 → tid
getppid 110 173 173 → ppid
getuid 102 174 174 → uid
getgid 104 176 176 → gid
geteuid 107 175 175 → euid
getegid 108 177 177 → egid
setuid 105 146 146 uid → 0
setgid 106 144 144 gid → 0
sched_yield 24 124 124 → 0
nanosleep 35 101 101 req, rem → 0
getrusage 98 165 165 who, usage → 0
times 100 153 153 buf → clock ticks
prctl 157 167 167 option, arg2, arg3, arg4, arg5 → result
arch_prctl 158 code, addr → 0 (x86-64: sets FS/GS base)

Signals

Name x86-64 ARM64 RISC-V Key Arguments
rt_sigaction 13 134 134 sig, act, oact, sigsetsize → 0
rt_sigprocmask 14 135 135 how, set, oldset, sigsetsize → 0
rt_sigreturn 15 139 139 (no args; restores state from sigframe on stack)
rt_sigsuspend 130 133 133 mask, sigsetsize → -EINTR
rt_sigpending 127 136 136 set, sigsetsize → 0
alarm 37 seconds → remaining alarm
pause 34 (wait for signal)
signalfd4 289 74 74 fd, mask, sizemask, flags → fd

Common Signal Numbers

Signal Number Default Action Description
SIGHUP 1 Terminate Hangup
SIGINT 2 Terminate Interrupt (Ctrl+C)
SIGQUIT 3 Core dump Quit
SIGILL 4 Core dump Illegal instruction
SIGTRAP 5 Core dump Trace/breakpoint trap
SIGABRT 6 Core dump Abort signal
SIGBUS 7 Core dump Bus error (bad memory access)
SIGFPE 8 Core dump Floating-point exception
SIGKILL 9 Terminate Kill (cannot be caught)
SIGSEGV 11 Core dump Segmentation fault
SIGPIPE 13 Terminate Broken pipe
SIGALRM 14 Terminate Timer signal
SIGTERM 15 Terminate Termination signal
SIGCHLD 17 Ignore Child stopped or terminated
SIGCONT 18 Continue Continue if stopped
SIGSTOP 19 Stop Stop (cannot be caught)
SIGTSTP 20 Stop Stop typed at terminal
SIGWINCH 28 Ignore Window size changed

Networking

Name x86-64 ARM64 RISC-V Key Arguments
socket 41 198 198 domain, type, protocol → fd
bind 49 200 200 sockfd, addr, addrlen → 0
listen 50 201 201 sockfd, backlog → 0
accept 43 202 202 sockfd, addr, addrlen → fd
accept4 288 242 242 sockfd, addr, addrlen, flags → fd
connect 42 203 203 sockfd, addr, addrlen → 0
recv (use recvfrom with NULL addr)
recvfrom 45 207 207 sockfd, buf, len, flags, src_addr, addrlen
send (use sendto with NULL addr)
sendto 44 206 206 sockfd, buf, len, flags, dest_addr, addrlen
setsockopt 54 208 208 sockfd, level, optname, optval, optlen
getsockopt 55 209 209 sockfd, level, optname, optval, optlen
shutdown 48 210 210 sockfd, how → 0
getpeername 52 205 205 sockfd, addr, addrlen → 0
getsockname 51 204 204 sockfd, addr, addrlen → 0

Time

Name x86-64 ARM64 RISC-V Key Arguments
time 201 1063 1063 tloc → seconds since epoch
gettimeofday 96 169 169 tv, tz → 0
clock_gettime 228 113 113 clkid, tp → 0
clock_settime 227 112 112 clkid, tp → 0
clock_getres 229 114 114 clkid, res → 0
clock_nanosleep 230 115 115 clkid, flags, req, rem → 0
timer_create 222 107 107 clkid, evp, timerid → 0
timer_settime 223 110 110 timerid, flags, new_value, old_value → 0

Clock IDs

ID Value Description
CLOCK_REALTIME 0 Wall-clock time
CLOCK_MONOTONIC 1 Monotonic time since unspecified point
CLOCK_PROCESS_CPUTIME_ID 2 CPU time of calling process
CLOCK_THREAD_CPUTIME_ID 3 CPU time of calling thread
CLOCK_MONOTONIC_RAW 4 Hardware-based monotonic clock
CLOCK_BOOTTIME 7 Monotonic + suspend time

Error Return Conventions

On success, most syscalls return 0 (or a positive value such as a file descriptor or byte count).

On error, syscalls return a negative value equal to the negated errno constant. For example: - -2 = ENOENT (No such file or directory) - -12 = ENOMEM (Out of memory) - -22 = EINVAL (Invalid argument) - -9 = EBADF (Bad file descriptor) - -11 = EAGAIN / EWOULDBLOCK (Resource temporarily unavailable)

The C library wrapper functions (read(), write(), etc.) detect negative return values, negate them, store the result in errno, and return -1 to the calling C code.

In assembly, after syscall, check if rax is in the range -4095 to -1 to detect an error. The kernel guarantees that successful return values are not in this range (with the exception of mmap, which can return addresses near 0xFFFFFFFFFFFFF000).


Quick Assembly Templates

Hello World (x86-64)

section .data
    msg db "Hello, World!", 10
    msglen equ $ - msg

section .text
    global _start
_start:
    mov rax, 1          ; write
    mov rdi, 1          ; stdout
    lea rsi, [rel msg]  ; buffer
    mov rdx, msglen     ; length
    syscall

    mov rax, 60         ; exit
    xor rdi, rdi        ; status 0
    syscall

Hello World (ARM64)

.data
msg: .ascii "Hello, World!\n"
msglen = . - msg

.text
.global _start
_start:
    mov x8, #64         // write
    mov x0, #1          // stdout
    adr x1, msg         // buffer
    mov x2, #msglen     // length
    svc #0

    mov x8, #93         // exit
    mov x0, #0          // status 0
    svc #0

Hello World (RISC-V)

.data
msg: .ascii "Hello, World!\n"
msglen = . - msg

.text
.global _start
_start:
    li a7, 64           # write
    li a0, 1            # stdout
    la a1, msg          # buffer
    li a2, msglen       # length
    ecall

    li a7, 93           # exit
    li a0, 0            # status 0
    ecall