aboutsummaryrefslogtreecommitdiff
path: root/core/sys/linux
diff options
context:
space:
mode:
authorflysand7 <yyakut.ac@gmail.com>2023-11-02 08:51:33 +1100
committerflysand7 <yyakut.ac@gmail.com>2023-11-03 00:56:20 +1100
commit7faa1460049a3f9500239a10f8377fc508d6f19e (patch)
tree05a48950f6ff1762e303f9ae0d482b27ada909b6 /core/sys/linux
parent62d0b0ae72bc858ed77876d097663eac4f157ab9 (diff)
WIP
Diffstat (limited to 'core/sys/linux')
-rw-r--r--core/sys/linux/bits.odin170
-rw-r--r--core/sys/linux/constants.odin83
-rw-r--r--core/sys/linux/sys.odin505
-rw-r--r--core/sys/linux/types.odin452
4 files changed, 1149 insertions, 61 deletions
diff --git a/core/sys/linux/bits.odin b/core/sys/linux/bits.odin
index 0cf90ed3b..fd86b798f 100644
--- a/core/sys/linux/bits.odin
+++ b/core/sys/linux/bits.odin
@@ -1398,3 +1398,173 @@ PER_OSF4 :: 0x000f
PER_HPUX :: 0x0010
PER_MASK :: 0x00ff
+/*
+ Bits for access modes for shared memory
+*/
+IPC_Mode_Bits :: enum {
+ WROTH = 1,
+ RDOTH = 2,
+ WRGRP = 4,
+ RDGRP = 5,
+ WRUSR = 7,
+ RDUSR = 8,
+ DEST = 9,
+ LOCKED = 10,
+}
+
+/*
+ Shared memory flags bits
+*/
+IPC_Flags_Bits :: enum {
+ IPC_CREAT = 9,
+ IPC_EXCL = 10,
+ IPC_NOWAIT = 11,
+ // Semaphore
+ SEM_UNDO = 9,
+ // Shared memory
+ SHM_HUGETLB = 11,
+ SHM_NORESERVE = 12,
+ SHM_RDONLY = 12,
+ SHM_RND = 13,
+ SHM_REMAP = 14,
+ SHM_EXEC = 15,
+ // Message queue
+ MSG_NOERROR = 12,
+ MSG_EXCEPT = 13,
+ MSG_COPY = 14,
+}
+
+/*
+ IPC memory commands
+*/
+IPC_Cmd :: enum i16 {
+ // IPC common
+ IPC_RMID = 0,
+ IPC_SET = 1,
+ IPC_STAT = 2,
+ // Shared memory
+ SHM_LOCK = 11,
+ SHM_UNLOCK = 12,
+ SHM_STAT = 13,
+ SHM_INFO = 14,
+ SHM_STAT_ANY = 15,
+ // Semaphore
+ GETPID = 11,
+ GETVAL = 12,
+ GETALL = 13,
+ GETNCNT = 14,
+ GETZCNT = 15,
+ SETVAL = 16,
+ SETALL = 17,
+ SEM_STAT = 18,
+ SEM_INFO = 19,
+ SEM_STAT_ANY = 20,
+ // Message queue
+ MSG_STAT = 11,
+ MSG_INFO = 12,
+ MSG_STAT_ANY = 13,
+}
+
+/*
+ File locking operation bits
+*/
+FLock_Op_Bits :: enum {
+ SH = 1,
+ EX = 2,
+ NB = 4,
+ UN = 8,
+}
+
+/*
+ ptrace requests
+*/
+PTrace_Request :: enum {
+ TRACEME = 0,
+ PEEKTEXT = 1,
+ PEEKDATA = 2,
+ PEEKUSER = 3,
+ POKETEXT = 4,
+ POKEDATA = 5,
+ POKEUSER = 6,
+ CONT = 7,
+ KILL = 8,
+ SINGLESTEP = 9,
+ GETREGS = 12,
+ SETREGS = 13,
+ GETFPREGS = 14,
+ SETFPREGS = 15,
+ ATTACH = 16,
+ DETACH = 17,
+ GETFPXREGS = 18,
+ SETFPXREGS = 19,
+ SYSCALL = 24,
+ GET_THREAD_AREA = 25,
+ SET_THREAD_AREA = 26,
+ ARCH_PRCTL = 30,
+ SYSEMU = 31,
+ SYSEMU_SINGLESTEP = 32,
+ SINGLEBLOCK = 33,
+ SETOPTIONS = 0x4200,
+ GETEVENTMSG = 0x4201,
+ GETSIGINFO = 0x4202,
+ SETSIGINFO = 0x4203,
+ GETREGSET = 0x4204,
+ SETREGSET = 0x4205,
+ SEIZE = 0x4206,
+ INTERRUPT = 0x4207,
+ LISTEN = 0x4208,
+ PEEKSIGINFO = 0x4209,
+ GETSIGMASK = 0x420a,
+ SETSIGMASK = 0x420b,
+ SECCOMP_GET_FILTER = 0x420c,
+ SECCOMP_GET_METADATA = 0x420d,
+ GET_SYSCALL_INFO = 0x420e,
+ GET_RSEQ_CONFIGURATION = 0x420f,
+};
+
+/*
+ ptrace options
+*/
+PTrace_Options_Bits :: enum {
+ TRACESYSGOOD = 0,
+ TRACEFORK = 1,
+ TRACEVFORK = 2,
+ TRACECLONE = 3,
+ TRACEEXEC = 4,
+ TRACEVFORKDONE = 5,
+ TRACEEXIT = 6,
+ TRACESECCOMP = 7,
+ EXITKILL = 20,
+ SUSPEND_SECCOMP = 21,
+}
+
+/*
+ ptrace event codes.
+*/
+PTrace_Event_Code :: enum {
+ EVENT_FORK = 1,
+ EVENT_VFORK = 2,
+ EVENT_CLONE = 3,
+ EVENT_EXEC = 4,
+ EVENT_VFORK_DONE = 5,
+ EVENT_EXIT = 6,
+ EVENT_SECCOMP = 7,
+ EVENT_STOP = 128,
+}
+
+/*
+ ptrace's get syscall info operation.
+*/
+PTrace_Get_Syscall_Info_Op :: enum u8 {
+ NONE = 0,
+ ENTRY = 1,
+ EXIT = 2,
+ SECCOMP = 3,
+};
+
+/*
+ ptrace's PEEKSIGINFO flags bits
+*/
+PTrace_Peek_Sig_Info_Flags_Bits :: enum {
+ SHARED = 0,
+} \ No newline at end of file
diff --git a/core/sys/linux/constants.odin b/core/sys/linux/constants.odin
index e725ed2fd..a1bcd09ab 100644
--- a/core/sys/linux/constants.odin
+++ b/core/sys/linux/constants.odin
@@ -83,6 +83,10 @@ STATX_BASIC_STATS :: Statx_Mask {
.BLOCKS,
}
+/*
+ Tell `shmget` to create a new key
+*/
+IPC_PRIVATE :: Key(0)
FCntl_Command_DUPFD :: distinct FCntl_Command
FCntl_Command_GETFD :: distinct FCntl_Command
@@ -197,3 +201,82 @@ FUTEX_WAIT_REQUEUE_PI :: Futex_Wait_requeue_Pi_Type(.WAIT_REQUEUE_PI)
FUTEX_CMP_REQUEUE_PI :: Futex_Cmp_requeue_Pi_Type(.CMP_REQUEUE_PI)
FUTEX_LOCK_PI2 :: Futex_Lock_Pi2_Type(.LOCK_PI2)
+PTrace_Traceme_Type :: distinct PTrace_Request
+PTrace_Peek_Type :: distinct PTrace_Request
+PTrace_Poke_Type :: distinct PTrace_Request
+PTrace_Cont_Type :: distinct PTrace_Request
+PTrace_Kill_Type :: distinct PTrace_Request
+PTrace_Singlestep_Type :: distinct PTrace_Request
+PTrace_Getregs_Type :: distinct PTrace_Request
+PTrace_Setregs_Type :: distinct PTrace_Request
+PTrace_Getfpregs_Type :: distinct PTrace_Request
+PTrace_Setfpregs_Type :: distinct PTrace_Request
+PTrace_Attach_Type :: distinct PTrace_Request
+PTrace_Detach_Type :: distinct PTrace_Request
+PTrace_Getfpxregs_Type :: distinct PTrace_Request
+PTrace_Setfpxregs_Type :: distinct PTrace_Request
+PTrace_Syscall_Type :: distinct PTrace_Request
+PTrace_Get_Thread_Area_Type :: distinct PTrace_Request
+PTrace_Set_Thread_Area_Type :: distinct PTrace_Request
+PTrace_Arch_Prctl_Type :: distinct PTrace_Request
+PTrace_Sysemu_Type :: distinct PTrace_Request
+PTrace_Sysemu_Singlestep_Type :: distinct PTrace_Request
+PTrace_Singleblock_Type :: distinct PTrace_Request
+PTrace_Setoptions_Type :: distinct PTrace_Request
+PTrace_Geteventmsg_Type :: distinct PTrace_Request
+PTrace_Getsiginfo_Type :: distinct PTrace_Request
+PTrace_Setsiginfo_Type :: distinct PTrace_Request
+PTrace_Getregset_Type :: distinct PTrace_Request
+PTrace_Setregset_Type :: distinct PTrace_Request
+PTrace_Seize_Type :: distinct PTrace_Request
+PTrace_Interrupt_Type :: distinct PTrace_Request
+PTrace_Listen_Type :: distinct PTrace_Request
+PTrace_Peeksiginfo_Type :: distinct PTrace_Request
+PTrace_Getsigmask_Type :: distinct PTrace_Request
+PTrace_Setsigmask_Type :: distinct PTrace_Request
+PTrace_Seccomp_Get_Filter_Type :: distinct PTrace_Request
+PTrace_Seccomp_Get_Metadata_Type :: distinct PTrace_Request
+PTrace_Get_Syscall_Info_Type :: distinct PTrace_Request
+PTrace_Get_RSeq_Configuration_Type :: distinct PTrace_Request
+
+PTRACE_TRACEME :: PTrace_Traceme_Type(.TRACEME)
+PTRACE_PEEKTEXT :: PTrace_Peek_Type(.PEEKTEXT)
+PTRACE_PEEKDATA :: PTrace_Peek_Type(.PEEKDATA)
+PTRACE_PEEKUSER :: PTrace_Peek_Type(.PEEKUSER)
+PTRACE_POKETEXT :: PTrace_Poke_Type(.POKETEXT)
+PTRACE_POKEDATA :: PTrace_Poke_Type(.POKEDATA)
+PTRACE_POKEUSER :: PTrace_Poke_Type(.POKEUSER)
+PTRACE_CONT :: PTrace_Cont_Type(.CONT)
+PTRACE_KILL :: PTrace_Kill_Type(.KILL)
+PTRACE_SINGLESTEP :: PTrace_Singlestep_Type(.SINGLESTEP)
+PTRACE_GETREGS :: PTrace_Getregs_Type(.GETREGS)
+PTRACE_SETREGS :: PTrace_Setregs_Type(.SETREGS)
+PTRACE_GETFPREGS :: PTrace_Getfpregs_Type(.GETFPREGS)
+PTRACE_SETFPREGS :: PTrace_Setfpregs_Type(.SETFPREGS)
+PTRACE_ATTACH :: PTrace_Attach_Type(.ATTACH)
+PTRACE_DETACH :: PTrace_Detach_Type(.DETACH)
+PTRACE_GETFPXREGS :: PTrace_Getfpxregs_Type(.GETFPXREGS)
+PTRACE_SETFPXREGS :: PTrace_Setfpxregs_Type(.SETFPXREGS)
+PTRACE_SYSCALL :: PTrace_Syscall_Type(.SYSCALL)
+PTRACE_GET_THREAD_AREA :: PTrace_Get_Thread_Area_Type(.GET_THREAD_AREA)
+PTRACE_SET_THREAD_AREA :: PTrace_Set_Thread_Area_Type(.SET_THREAD_AREA)
+PTRACE_ARCH_PRCTL :: PTrace_Arch_Prctl_Type(.ARCH_PRCTL)
+PTRACE_SYSEMU :: PTrace_Sysemu_Type(.SYSEMU)
+PTRACE_SYSEMU_SINGLESTEP :: PTrace_Sysemu_Singlestep_Type(.SYSEMU_SINGLESTEP)
+PTRACE_SINGLEBLOCK :: PTrace_Singleblock_Type(.SINGLEBLOCK)
+PTRACE_SETOPTIONS :: PTrace_Setoptions_Type(.SETOPTIONS)
+PTRACE_GETEVENTMSG :: PTrace_Geteventmsg_Type(.GETEVENTMSG)
+PTRACE_GETSIGINFO :: PTrace_Getsiginfo_Type(.GETSIGINFO)
+PTRACE_SETSIGINFO :: PTrace_Setsiginfo_Type(.SETSIGINFO)
+PTRACE_GETREGSET :: PTrace_Getregset_Type(.GETREGSET)
+PTRACE_SETREGSET :: PTrace_Setregset_Type(.SETREGSET)
+PTRACE_SEIZE :: PTrace_Seize_Type(.SEIZE)
+PTRACE_INTERRUPT :: PTrace_Interrupt_Type(.INTERRUPT)
+PTRACE_LISTEN :: PTrace_Listen_Type(.LISTEN)
+PTRACE_PEEKSIGINFO :: PTrace_Peeksiginfo_Type(.PEEKSIGINFO)
+PTRACE_GETSIGMASK :: PTrace_Getsigmask_Type(.GETSIGMASK)
+PTRACE_SETSIGMASK :: PTrace_Setsigmask_Type(.SETSIGMASK)
+PTRACE_SECCOMP_GET_FILTER :: PTrace_Seccomp_Get_Filter_Type(.SECCOMP_GET_FILTER)
+PTRACE_SECCOMP_GET_METADATA :: PTrace_Seccomp_Get_Metadata_Type(.SECCOMP_GET_METADATA)
+PTRACE_GET_SYSCALL_INFO :: PTrace_Get_Syscall_Info_Type(.GET_SYSCALL_INFO)
+PTRACE_GET_RSEQ_CONFIGURATION :: PTrace_Get_RSeq_Configuration_Type(.GET_RSEQ_CONFIGURATION)
diff --git a/core/sys/linux/sys.odin b/core/sys/linux/sys.odin
index dfb25e5dd..d04a6c857 100644
--- a/core/sys/linux/sys.odin
+++ b/core/sys/linux/sys.odin
@@ -165,7 +165,16 @@ munmap :: proc "contextless" (addr: rawptr, size: uint) -> (Errno) {
return Errno(-ret)
}
-// TODO(flysand): brk
+/*
+ Extend the data segment size until the address `addr`. Note: you may be
+ familiar with sbrk(), which is not actually a syscall, so is not
+ implemented here.
+ Available since Linux 1.0.
+*/
+brk :: proc "contextless" (addr: uintptr) -> (Errno) {
+ ret := syscall(SYS_brk, addr)
+ return Errno(-ret)
+}
/// Alter an action taken by a process
rt_sigaction :: proc "contextless" (sig: Signal, sigaction: ^Sig_Action, old_sigaction: ^Sig_Action) -> Errno {
@@ -180,8 +189,6 @@ rt_sigprocmask :: proc "contextless" (mask_kind: Sig_Mask_Kind, new_set: ^Sig_Se
return Errno(-ret)
}
-// TODO(flysand): rt_sigreturn
-
// TODO(flysand): ioctl
/// Read the file at a specified offset
@@ -200,9 +207,23 @@ pwrite :: proc "contextless" (fd: Fd, buf: []$T, offset: i64) -> (int, Errno) {
return errno_unwrap(ret, int)
}
-// TODO(flysand): readv
+/*
+ Read the data from file into multiple buffers.
+ Available since Linux 2.0.
+*/
+readv :: proc "contextless" (fd: Fd, iov: []IO_Vec) -> (int, Errno) {
+ ret := syscall(SYS_readv, fd, raw_data(iov), len(iov))
+ return errno_unwrap(ret, int)
+}
-// TODO(flysand): writev
+/*
+ Write the data from multiple buffers into a file.
+ Available since Linux 2.0.
+*/
+writev :: proc "contextless" (fd: Fd, iov: []IO_Vec) -> (int, Errno) {
+ ret := syscall(SYS_writev, fd, raw_data(iov), len(iov))
+ return errno_unwrap(ret, int)
+}
/// Check user permissions for a file
/// If Mode is F_OK, checks whether the file exists
@@ -226,11 +247,18 @@ pipe2 :: proc "contextless" (pipes: ^[2]Fd, flags: Open_Flags) -> (Errno) {
return Errno(-ret)
}
-// TODO(flysand): select
-
-// TODO(flysand): sched_yield
+/*
+ Yield the processor.
+ Available since Linux 2.0.
+*/
+sched_yield :: proc "contextless" () {
+ syscall(SYS_sched_yield)
+}
-// TODO(flysand): add docs here
+/*
+ Remap a virtual memory address.
+ Available since Linux 2.0.
+*/
mremap :: proc "contextless" (old_addr: rawptr, old_size: uint, new_size: uint, flags: MRemap_Flags, new_addr: uintptr = 0) -> (rawptr, Errno) {
if .FIXED in flags {
ret := syscall(SYS_mremap, old_addr, old_size, new_size, transmute(i32) flags, new_addr)
@@ -248,7 +276,14 @@ msync :: proc "contextless" (addr: rawptr, size: uint, flags: MSync_Flags) -> (E
return Errno(-ret)
}
-// TODO(flysand): mincore
+/*
+ Determine if pages are resident in memory.
+ Available since Linux 2.4.
+*/
+mincore :: proc "contextless" (addr: rawptr, size: uint, vec: []b8) -> (Errno) {
+ ret := syscall(SYS_mincore, addr, size, raw_data(vec))
+ return Errno(-ret)
+}
/// Give advice about use of memory
/// Available since Linux 2.4
@@ -257,11 +292,44 @@ madvise :: proc "contextless" (addr: rawptr, size: uint, advice: MAdvice) -> (Er
return Errno(-ret)
}
-// TODO(flysand): shmget
+/*
+ Allocate a SystemV shared memory segment.
+ Available since Linux 2.0.
+*/
+shmget :: proc "contextless" (key: Key, size: uint, flags: IPC_Flags) -> (Key, Errno) {
+ ret := syscall(SYS_shmget, key, size, transmute(i16) flags)
+ return errno_unwrap(ret, Key)
+}
-// TODO(flysand): shmat
+/*
+ SystemV shared memory segment operations.
+ Available since Linux 2.0.
+*/
+shmat :: proc "contextless" (key: Key, addr: rawptr, flags: IPC_Flags) -> (rawptr, Errno) {
+ ret := syscall(SYS_shmat, key, addr, transmute(i16) flags)
+ return errno_unwrap(ret, Key)
+}
-// TODO(flysand): shmctl
+shmctl_ds :: proc "contextless" (key: Key, cmd: IPC_Cmd, buf: ^Shmid_DS) -> (Errno) {
+ ret := syscall(SYS_shmctl, key, cmd, buf)
+ return Errno(-ret)
+}
+
+shmctl_info :: proc "contextless" (key: Key, cmd: IPC_Cmd, buf: ^Shmid_Info) -> (int, Errno) {
+ ret := syscall(SYS_shmctl, key, cmd, buf)
+ return errno_unwrap(ret, int)
+}
+
+shmctl_stat :: proc "contextless" (index: int, cmd: IPC_Cmd, buf: ^Shmid_DS) -> (Key, Errno) {
+ ret := syscall(SYS_shmctl, key, cmd, buf)
+ return errno_unwrap(ret, Key)
+}
+
+/*
+ SystemV shared memory control.
+ Available since Linux 2.0.
+*/
+shmctl :: proc {shmctl_ds, shmctl_info, shmctl_stat}
/// Allocate a new file descriptor that refers to the same file as the one provided
/// Available since Linux 1.0
@@ -283,15 +351,48 @@ dup2 :: proc "contextless" (old: Fd, new: Fd) -> (Fd, Errno) {
}
}
-// TODO(flysand): pause
+/*
+ Wait until the next signal is delivered.
+ Available since Linux 1.0.
+*/
+pause :: proc "contextless" () {
+ syscall(SYS_pause)
+}
-// TODO(flysand): nanosleep
+/*
+ High-resolution sleep.
+ Available since Linux 2.0.
+*/
+nanosleep :: proc "contextless" (req: ^Time_Spec, rem: ^Time_Spec) -> (Errno) {
+ ret := syscall(SYS_nanosleep, req, rem)
+ return Errno(-ret)
+}
-// TODO(flysand): getitimer
+/*
+ Get the value of an internal timer.
+ Available since Linux 1.0.
+*/
+getitimer :: proc "contextless" (which: ITimer_Which, cur: ^ITimer_Val) -> (Errno) {
+ ret := syscall(SYS_getitimer, cur)
+ return Errno(-ret)
+}
-// TODO(flysand): alarm
+/*
+ Set an alarm clock for delivery of a signal.
+ Available since Linux 1.0.
+*/
+alarm :: proc "contextless" (seconds: u32) -> u32 {
+ return cast(u32) syscall(SYS_alarm, seconds)
+}
-// TODO(flysand): setitimer
+/*
+ Set the value of an internal timer.
+ Available since Linux 1.0.
+*/
+getitimer :: proc "contextless" (which: ITimer_Which, new: ^ITimer_Val, old: ^ITimer_Val) -> (Errno) {
+ ret := syscall(SYS_getitimer, new, old)
+ return Errno(-ret)
+}
/// Returns the thread group ID of the current process
/// Note that it doesn't return the pid, despite it's name.
@@ -300,7 +401,20 @@ getpid :: proc "contextless" () -> Pid {
return cast(Pid) syscall(SYS_getpid)
}
-// TODO(flysand): sendfile
+/*
+ Transfer the data between file descriptors.
+ Available since Linux 2.2.
+ On 32-bit platforms available since Linux 2.6.
+*/
+sendfile :: proc "contextless" (out: Fd, in: Fd, offset: ^i64, count: uint) -> (int, Errno) {
+ when size_of(int) == 8 {
+ ret := syscall(SYS_sendfile, out, in, offset, count)
+ return errno_unwrap(ret, Errno)
+ } else {
+ ret := syscall(SYS_sendfile64, out, in, offset, count)
+ return errno_unwrap(ret, Errno)
+ }
+}
/// Create a socket file descriptor
/// Available since Linux 2.0
@@ -377,10 +491,28 @@ recv :: proc {recvfrom, recv_noaddr}
/// Available since Linux 2.0
send :: proc {sendto, send_noaddr}
-// TODO(flysand): sendmsg
+/*
+ Send a message on a socket.
+ Available since Linux 2.0.
+*/
+sendmsg :: proc "contextless" (sock: Fd, msghdr: ^Msg_Hdr, flags: Socket_Msg) -> (int, Errno) {
+ ret := syscall(SYS_sendmsg, sock, msghdr, transmute(i32) flags)
+ return errno_unwrap(ret, int)
+}
-// TODO(flysand): recvmsg
+/*
+ Receive a message on a socket.
+ Available since Linux 2.0.
+*/
+recvmsg :: proc "contextless" (sock: Fd, msghdr: ^Msg_Hdr, flags: Socket_Msg) -> (int, Errno) {
+ ret := syscall(SYS_recvmsg, sock, msghdr, transmute(i32) flags)
+ return errno_unwrap(ret, int)
+}
+/*
+ Shutdown a socket.
+ Available since Linux 2.0.
+*/
shutdown :: proc "contextless" (sock: Fd, how: Shutdown_How) -> (Errno) {
ret := syscall(SYS_shutdown, sock, how)
return Errno(-ret)
@@ -405,11 +537,34 @@ listen :: proc "contextless" (sock: Fd, queue_len: i32) -> (Errno) {
return Errno(-ret)
}
-// TODO(flysand): getsockname
+/*
+ Get socket name (aka it's bound address).
+ Available since Linux 2.0.
+*/
+getsockname :: proc "contextless" (sock: Fd, addr: ^Sock_Addr_Any) -> (Errno) {
+ addr_len := size_of(Sock_Addr_Any)
+ ret := syscall(SYS_getsockname, sock, addr, &addr_len)
+ return Errno(-ret)
+}
-// TODO(flysand): getpeername
+/*
+ Get the name of the connected peer socket.
+ Available since Linux 2.0.
+*/
+getpeername :: proc "contextless" (sock: Fd, addr: ^Sock_Addr_Any) -> (Errno) {
+ addr_len := size_of(Sock_Addr_Any)
+ ret := syscall(SYS_getpeername, sock, addr, &addr_len)
+ return Errno(-ret)
+}
-// TODO(flysand): socketpair
+/*
+ Create a pair of connected sockets.
+ Available since Linux 2.0.
+*/
+socketpair :: proc "contextless" (domain: Protocol_Family, type: Socket_Type, proto: Protocol, pair: ^[2]Fd) -> (Errno) {
+ ret := syscall(SYS_socketpair, domain, type, proto, pair)
+ return Errno(-ret)
+}
// TODO(flysand): the parameters are the same, maybe there's a way to make it into a single proc, sacrificing type
// safety slightly
@@ -518,9 +673,32 @@ fork :: proc "contextless" () -> (Pid, Errno) {
}
}
-// TODO(flysand): vfork
+/*
+ Create a child process and block parent.
+ Available since Linux 2.2.
+*/
+vfork :: proc "contextless" () -> Pid {
+ when ODIN_ARCH != .arm64 {
+ return Pid(syscall(SYS_vfork))
+ } else {
+ return Pid(syscall(SYS_fork))
+ }
+}
-// TODO(flysand): execve
+/*
+ Replace the current process with another program.
+ Available since Linux 1.0.
+ On ARM64 available since Linux 3.19.
+*/
+execve :: proc "contextless" (name: cstring, argv: [^]cstring, envp: [^]cstring) -> (Errno) {
+ when ODIN_ARCH != .arm64 {
+ ret := syscall(SYS_execve, cast(rawptr) name, cast(rawptr) argv, cast(rawptr) envp)
+ return Errno(-ret)
+ } else {
+ ret := syscall(SYS_execveat, AT_FDCWD, cast(rawptr) name, cast(rawptr) argv, cast(rawptr) envp)
+ return Errno(-ret)
+ }
+}
/// Exit the thread with a given exit code
/// Available since Linux 1.0
@@ -539,7 +717,14 @@ wait4 :: proc "contextless" (pid: Pid, status: ^u32, options: Wait_Options) -> (
/// See wait4
waitpid :: wait4
-// TODO(flysand): kill
+/*
+ Send signal to a process.
+ Available since Linux 1.0.
+*/
+kill :: proc "contextless" (pid: Pid, signal: Signal) -> (Errno) {
+ ret := syscall(SYS_kill, pid, signal)
+ return Errno(-ret)
+}
/// Get system information
/// Available since Linux 1.0
@@ -548,21 +733,84 @@ uname :: proc "contextless" (uts_name: ^UTS_Name) -> (Errno) {
return Errno(-ret)
}
-// TODO(flysand): semget
+/*
+ Get a SystemV semaphore set identifier.
+ Available since Linux 2.0.
+*/
+semget :: proc "contextless" (key: Key, n: i32, flags: IPC_Flags) -> (Key, Errno) {
+ ret := syscall(SYS_semget, key, n, transmute(i16) flags)
+ return errno_unwrap(ret, Key)
+}
-// TODO(flysand): semop
+/*
+ SystemV semaphore operations.
+ Available since Linux 2.0.
+*/
+semop :: proc "contextless" (key: Key, ops: []Sem_Buf) -> (Errno) {
+ ret := syscall(SYS_semop, key, raw_data(ops), len(ops))
+ return Errno(-ret)
+}
-// TODO(flysand): semctl
+semctl3 :: proc "contextless" (key: Key, semnum: i32, cmd: IPC_Cmd) -> (int, Errno) {
+ ret := syscall(SYS_semctl, key, semnum, cmd)
+ return errno_unwrap(ret, int)
+}
-// TODO(flysand): shmdt
+semctl4 :: proc "contextless" (key: Key, semnum: i32, cmd: IPC_Cmd, semun: Sem_Un) -> (int, Errno) {
+ ret := syscall(SYS_semctl, key, semnum, cmd, semun)
+ return errno_unwrap(ret, int)
+}
-// TODO(flysand): msgget
+/*
+ SystemV semaphore control operations.
+ Available since Linux 2.0.
+*/
+semctl :: proc {semctl3, semctl4}
-// TODO(flysand): msgsnd
+/*
+ SystemV shared memory operations.
+ Available since Linux 2.0.
+*/
+shmdt :: proc "contextless" (shmaddr: rawptr) -> (Errno) {
+ ret := syscall(SYS_shmdt, shmaddr)
+ return Errno(-ret)
+}
-// TODO(flysand): msgrcv
+/*
+ Get SystemV message queue identifier.
+ Available since Linux 2.0.
+*/
+msgget :: proc "contextless" (key: Key, flags: IPC_Flags) -> (Key, Errno) {
+ ret := syscall(SYS_msgget, key, transmute(i16) flags)
+ return errno_unwrap(ret, Key)
+}
-// TODO(flysand): msgctl
+/*
+ Send message to a SystemV message queue.
+ Available since Linux 2.0.
+*/
+msgsnd :: proc "contextless" (key: Key, buf: rawptr, size: int, flags: IPC_Flags) -> (Errno) {
+ ret := syscall(SYS_msgsnd, key, buf, size, transmute(i16) flags)
+ return Errno(-ret)
+}
+
+/*
+ Receive a message from a SystemV message queue.
+ Available since Linux 2.0.
+*/
+msgrcv :: proc "contextless" (key: Key, buf: rawptr, size: int, type: uint, flags: IPC_Flags) -> (int, Errno) {
+ ret := syscall(SYS_msgrcv, key, buf, size, type, transmute(i16) flags)
+ return errno_unwrap(ret, int)
+}
+
+/*
+ SystemV message control operations.
+ Available since Linux 2.0.
+*/
+msgctl :: proc "contextless" (key: Key, cmd: IPC_Cmd, buf: ^Msqid_DS) -> (int, Errno) {
+ ret := syscall(SYS_msgctl, key, cmd, buf)
+ return errno_unwrap(ret, int)
+}
fcntl_dupfd :: proc "contextless" (fd: Fd, cmd: FCntl_Command_DUPFD, newfd: Fd) -> (Fd, Errno) {
ret := syscall(SYS_fcntl, fd, cmd, newfd)
@@ -726,7 +974,14 @@ fcntl :: proc {
fcntl_set_file_rw_hint,
}
-// TODO(flysand): flock
+/*
+ Apply or remove advisory lock on an open file.
+ Available since Linux 2.0.
+*/
+flock :: proc "contextless" (fd: Fd, operation: FLock_Op) -> (Errno) {
+ ret := syscall(SYS_flock, fd, transmute(i32) operation)
+ return Errno(-ret)
+}
/// Sync state of the file with the storage device
fsync :: proc "contextless" (fd: Fd) -> (Errno) {
@@ -734,7 +989,15 @@ fsync :: proc "contextless" (fd: Fd) -> (Errno) {
return Errno(-ret)
}
-// TODO(flysand): fdatasync
+/*
+ Synchronize the state of the file with the storage device. Similar to `fsync`,
+ except does not flush the metadata.
+ Available since Linux 2.0.
+*/
+fdatasync :: proc "contextless" (fd: Fd) -> (Errno) {
+ ret := syscall(SYS_fdatasync, fd)
+ return Errno(-ret)
+}
/// Truncate a file to specified length
/// On 32-bit architectures available since Linux 2.4
@@ -828,7 +1091,19 @@ rmdir :: proc "contextless" (name: cstring) -> (Errno) {
}
}
-// TODO(flysand): creat
+/*
+ Create a file.
+ Available since Linux 1.0.
+ On ARM64 available since Linux 2.6.16.
+*/
+creat :: proc "contextless" (name: cstring, mode: Mode) -> (Errno) {
+ when ODIN_ARCH == .arm64 {
+ return openat(AT_FDCWD, name, {.CREAT, .WRONLY,.TRUNC}, mode)
+ } else {
+ ret := syscall(SYS_creat, cast(rawptr) name, transmute(u32) mode)
+ return Errno(-ret)
+ }
+}
/// Create a hard link on a file
/// Available since Linux 1.0
@@ -949,9 +1224,23 @@ lchown :: proc "contextless" (name: cstring, uid: Uid, gid: Gid) -> (Errno) {
}
}
-// TODO(flysand): umask
+/*
+ Set file mode creation mask.
+ Available since Linux 1.0.
+*/
+umask :: proc "contextless" (mask: Mask) -> Mask {
+ ret := syscall(SYS_umask, transmute(u32) mask)
+ return transmute(u32) cast(u32) ret
+}
-// TODO(flysand): gettimeofday
+/*
+ Get current time.
+ Available since Linux 1.0.
+*/
+gettimeofday :: proc "contextless" (tv: ^Time_Val) -> (Errno) {
+ ret := syscall(SYS_gettimeofday, tv)
+ return Errno(-ret)
+}
/// Get limits on resources
/// Available since Linux 1.0
@@ -980,7 +1269,97 @@ times :: proc "contextless" (tms: ^Tms) -> (Errno) {
return Errno(-ret)
}
-// TODO(flysand): ptrace
+ptrace_traceme :: proc "contextless" (rq: PTrace_Traceme_Type) -> (Errno) {
+ ret := syscall(SYS_ptrace, rq)
+ return Errno(-ret)
+}
+
+ptrace_peek :: proc "contextless" (rq: PTrace_Peek_Type, addr: uintptr) -> (uint, Errno) {
+ ret := syscall(SYS_ptrace, rq, addr)
+ return errno_unwrap(rq, uint)
+}
+
+ptrace_poke :: proc "contextless" (rq: PTrace_Poke_Type, addr: uintptr, data: uint) -> (Errno) {
+ ret := syscall(SYS_ptrace, rq, addr, data)
+ return Errno(-ret)
+}
+
+ptrace_getregs :: proc "contextless" (rq: PTrace_Getregs_Type, buf: ^User_Regs) -> (Errno) {
+ ret := syscall(SYS_ptrace, rq, 0, buf)
+ return Errno(-ret)
+}
+
+ptrace_getfpregs :: proc "contextless" (rq: PTrace_Getfpregs_Type, buf: ^User_FP_Regs) -> (Errno) {
+ ret := syscall(SYS_ptrace, rq, 0, buf)
+ return Errno(-ret)
+}
+
+ptrace_getfpxregs :: proc "contextless" (rq: PTrace_Getfpxregs_Type, buf: ^User_FPX_Regs) -> (Errno) {
+ ret := syscall(SYS_ptrace, rq, 0, buf)
+ return Errno(-ret)
+}
+
+ptrace_setregs :: proc "contextless" (rq: PTrace_Setregs_Type, buf: ^User_Regs) -> (Errno) {
+ ret := syscall(SYS_ptrace, rq, 0, buf)
+ return Errno(-ret)
+}
+
+ptrace_setfpregs :: proc "contextless" (rq: PTrace_Setfpregs_Type, buf: ^User_FP_Regs) -> (Errno) {
+ ret := syscall(SYS_ptrace, rq, 0, buf)
+ return Errno(-ret)
+}
+
+ptrace_setfpxregs :: proc "contextless" (rq: PTrace_Setfpxregs_Type, buf: ^User_FPX_Regs) -> (Errno) {
+ ret := syscall(SYS_ptrace, rq, 0, buf)
+ return Errno(-ret)
+}
+
+// TODO(flysand): ptrace_getregset
+// TODO(flysand): ptrace_setregset
+// TODO(flysand): ptrace_setsiginfo
+// TODO(flysand): ptrace_peeksiginfo
+// TODO(flysand): ptrace_getsigmask
+// TODO(flysand): ptrace_setsigmask
+
+ptrace_setoptions :: proc "contextless" (rq: PTrace_Setoptions_Type, options: PTrace_Options) -> (Errno) {
+ ret := syscall(SYS_ptrace, rq, 0, transmute(u32) options)
+ return Errno(-ret)
+}
+
+// TODO(flysand): ptrace_geteventmsg
+// TODO(flysand): ptrace_cont
+// TODO(flysand): ptrace_syscall
+// TODO(flysand): ptrace_singlestep
+// TODO(flysand): ptrace_set_syscall
+// TODO(flysand): ptrace_sysemu
+// TODO(flysand): ptrace_sysemu_singlestep
+// TODO(flysand): ptrace_listen
+// TODO(flysand): ptrace_kill
+// TODO(flysand): ptrace_interrupt
+// TODO(flysand): ptrace_attach
+// TODO(flysand): ptrace_seize
+// TODO(flysand): ptrace_seccomp_get_filter
+// TODO(flysand): ptrace_detach
+// TODO(flysand): ptrace_get_thread_area
+// TODO(flysand): ptrace_set_thread_area
+// TODO(flysand): ptrace_get_syscall_info
+// TODO(flysand): ptrace_setsigmask
+
+/*
+ Trace process
+*/
+ptrace :: proc {
+ ptrace_traceme,
+ peek,
+ ptrace_poke,
+ ptrace_getregs,
+ ptrace_getfpregs,
+ ptrace_getfpxregs,
+ ptrace_setregs,
+ ptrace_setfpregs,
+ ptrace_setfpxregs,
+ ptrace_setoptions,
+}
/// Get real user ID
/// Available since Linux 1.0
@@ -1186,8 +1565,6 @@ getpgid :: proc "contextless" (pid: Pid) -> (Pid, Errno) {
return errno_unwrap(ret, Pid)
}
-// NOTE(flysand): setfsuid and setfsgid are deprecated
-
/// Get session ID of the calling process
/// Available since Linux 2.0
getsid :: proc "contextless" (pid: Pid) -> (Pid, Errno) {
@@ -1234,8 +1611,6 @@ sigaltstack :: proc "contextless" (stack: ^Sig_Stack, old_stack: ^Sig_Stack) ->
return Errno(-ret)
}
-// TODO(flysand): utime
-
/// Create a special or ordinary file
/// `mode` parameter contains both the the file mode and the type of the node to create
/// -> Add one of S_IFSOCK, S_IFBLK, S_IFFIFO, S_IFCHR to mode
@@ -1251,8 +1626,6 @@ mknod :: proc "contextless" (name: cstring, mode: Mode, dev: Dev) -> (Errno) {
}
}
-// TODO(flysand): uselib
-
/// Set the process execution domain
/// Available since Linux 1.2
personality :: proc "contextless" (personality: uint) -> (uint, Errno) {
@@ -1414,16 +1787,10 @@ setdomainname :: proc "contextless" (name: string) -> (Errno) {
// TODO(flysand): ioperm
-// TODO(flysand): create_module
-
// TODO(flysand): init_module
// TODO(flysand): delete_module
-// TODO(flysand): get_kernel_syms
-
-// TODO(flysand): query_module
-
// TODO(flysand): quotactl
// TODO(flysand): nfsservctl
@@ -1474,9 +1841,14 @@ gettid :: proc "contextless" () -> Pid {
// TODO(flysand): fremovexattr
-// TODO(flysand): tkill
-
-// TODO(flysand): time
+/*
+ Get current time in seconds.
+ Available since Linux 1.0.
+*/
+time :: proc "contextless" (tloc: ^uint) -> (Errno) {
+ ret := syscall(SYS_time, tloc)
+ return Errno(-ret)
+}
/// Wait on a futex until it's signaled
futex_wait :: proc "contextless" (futex: ^Futex, op: Futex_Wait_Type, flags: Futex_Flags, val: u32, timeout: ^Time_Spec = nil) -> (Errno) {
@@ -1593,8 +1965,6 @@ set_tid_address :: proc "contextless" (tidptr: ^u32) {
syscall(SYS_set_tid_address, tidptr)
}
-// TODO(flysand): restart_syscall
-
// TODO(flysand): semtimedop
// TODO(flysand): fadvise64
@@ -1847,7 +2217,6 @@ dup3 :: proc "contextless" (old: Fd, new: Fd, flags: Open_Flags) -> (Fd, Errno)
// TODO(flysand): pwritev
-
/// Send signal information to a thread
/// Available since Linux 2.2
rt_tgsigqueueinfo :: proc "contextless" (tgid: Pid, pid: Pid, sig: Signal, si: ^Sig_Info) -> (Errno) {
@@ -1862,7 +2231,14 @@ perf_event_open :: proc "contextless" (attr: ^Perf_Event_Attr, pid: Pid, cpu: in
return errno_unwrap(ret, Fd)
}
-// TODO(flysand): recvmmsg
+/*
+ Receive multiple messages from a socket.
+ Available since Linux 2.6.33.
+*/
+recvmmsg :: proc "contextless" (sock: Fd, msg_vec: []MMsg_Hdr, flags: Socket_Msg) -> (int, Errno) {
+ ret := syscall(SYS_recvmmsg, sock, raw_data(msg_vec), len(msg_vec), transmute(i32) flags)
+ return errno_unwrap(ret, int)
+}
// TODO(flysand): fanotify_init
@@ -1878,7 +2254,14 @@ perf_event_open :: proc "contextless" (attr: ^Perf_Event_Attr, pid: Pid, cpu: in
// TODO(flysand): syncfs
-// TODO(flysand): sendmmsg
+/*
+ Send multiple messages on a socket.
+ Available since Linux 3.0.
+*/
+sendmmsg :: proc "contextless" (sock: Fd, msg_vec: []MMsg_Hdr, flags: Socket_Msg) -> (int, Errno) {
+ ret := syscall(SYS_sendmmsg, sock, raw_data(msg_vec), len(msg_vec), transmute(i32) flags)
+ return errno_unwrap(ret, int)
+}
// TODO(flysand): setns
diff --git a/core/sys/linux/types.odin b/core/sys/linux/types.odin
index 8789ca2d1..cc3c24075 100644
--- a/core/sys/linux/types.odin
+++ b/core/sys/linux/types.odin
@@ -26,6 +26,9 @@ Pid_FD :: distinct i32
/// Used pretty much only in struct Stat64 for 32-bit platforms
Inode :: distinct u64
+/// Shared memory identifiers used by `shm*` calls
+Key :: distinct i32
+
/// Represents time with nanosecond precision
Time_Spec :: struct {
time_sec: uint,
@@ -38,6 +41,15 @@ Time_Val :: struct {
microseconds: int,
}
+/*
+ Access and modification times for files
+*/
+UTim_Buf :: struct {
+ actime: uint,
+ modtime: uint,
+};
+
+
/// open.2 flags
Open_Flags :: bit_set[Open_Flags_Bits; u32]
@@ -235,6 +247,13 @@ FLock :: struct {
pid: Pid,
}
+/*
+ File locking operations.
+ Use one of `EX`, `RW` or `UN` to specify the operation, and add `UN` if
+ you need a non-blocking operation.
+*/
+FLock_Op :: bit_set[FLock_Op_Bits; i32]
+
/// Flags for fcntl_notify
FD_Notifications :: bit_set[FD_Notifications_Bits; i32]
@@ -496,6 +515,25 @@ Sock_Addr_Any :: struct #raw_union {
using ipv6: Sock_Addr_In6,
}
+/*
+ Message header for sendmsg/recvmsg
+*/
+Msg_Hdr :: struct {
+ name: rawptr,
+ namelen: i32,
+ iov: []IO_Vec, // ptr followed by length, abi matches
+ control: []u8,
+ flags: Socket_Msg,
+};
+
+/*
+ Multiple message header for sendmmsg/recvmmsg
+*/
+MMsg_Hdr :: struct {
+ hdr: Msg_Hdr,
+ len: u32,
+}
+
/// Just an alias to make futex-values more visible
Futex :: u32
@@ -564,3 +602,417 @@ RUsage :: struct {
nvcsw_word: int,
nivcsw_word: int,
}
+
+/*
+ Struct used for IO operations
+*/
+IO_Vec :: struct {
+ base: rawptr,
+ len: uint,
+}
+
+/*
+ Access mode for shared memory
+*/
+IPC_Mode :: bit_set[IPC_Mode; u32]
+
+/*
+ Flags used by IPC objects
+*/
+IPC_Flags :: bit_set[IPC_Flags_Bits; i16]
+
+/*
+ Permissions for IPC objects
+*/
+IPC_Perm :: struct {
+ key: Key,
+ uid: u32,
+ gid: u32,
+ cuid: u32,
+ cgid: u32,
+ mode: IPC_Mode,
+ seq: u16,
+ _: [2 + 2*size_of(int)],
+}
+
+when size_of(int) == 8 || ODIN_ARCH == .i386 {
+ // 32-bit and 64-bit x86, 64-bit arm
+ _Arch_Shmid_DS :: struct {
+ perm: IPC_Perm,
+ segsz: uint,
+ atime: int,
+ dtime: int,
+ ctime: int,
+ cpid: Pid,
+ lpid: Pid,
+ nattch: uint,
+ _: [2]uint,
+ }
+} else {
+ // Other 32-bit platforms
+ // NOTE(flysand): I'm not risking assuming it's little endian...
+ _Arch_Shmid_DS :: struct {
+ perm: IPC_Perm,
+ segsz: uint,
+ atime: uint,
+ atime_high: uint,
+ dtime: uint,
+ dtime_high: uint,
+ ctime: uint,
+ ctime_high: uint,
+ cpid: Pid,
+ lpid: Pid,
+ nattach: uint,
+ _: [2]uint,
+ }
+}
+
+/*
+ SystemV shared memory data.
+*/
+Shmid_DS :: _Arch_Shmid_DS
+
+/*
+ SystemV shared memory info.
+*/
+Shm_Info :: struct {
+ used_ids: i32
+ shm_tot: uint,
+ shm_rss: uint,
+ shm_swp: uint,
+ swap_attempts: uint,
+ swap_successes: uint,
+}
+
+/*
+ SystemV semaphore operation.
+*/
+Sem_Buf :: struct {
+ num: u16,
+ op: IPC_Cmd,
+ flg: IPC_Flags,
+}
+
+when ODIN_ARCH == .i386 {
+ _Arch_Semid_DS :: struct {
+ perm: IPC_Perm,
+ otime: uint,
+ otime_high: uint,
+ ctime: uint,
+ ctime_high: uint,
+ nsems: uint,
+ _: [2]uint,
+ }
+else when ODIN_ARCH == .amd64 {
+ _Arch_Semid_DS :: struct {
+ perm: IPC_Perm,
+ otime: int,
+ ctime: int,
+ nsems: uint,
+ _: [2]uint,
+ }
+} else when ODIN_ARCH == .amd32 {
+ _Arch_Semid_DS :: struct {
+ perm: IPC_Perm,
+ otime: uint,
+ otime_high: uint,
+ ctime: uint,
+ ctime_high: uint,
+ nsems: uint,
+ _: [2]uint,
+ }
+} else when ODIN_ARCH == .amd64 {
+ _Arch_Semid_DS :: struct {
+ perm: IPC_Perm,
+ otime: int,
+ ctime: int,
+ sem_nsems: uint,
+ __unused3: uint,
+ __unused4: uint,
+ }
+}
+
+/*
+ Architecture-specific semaphore data.
+*/
+Semid_DS :: _Arch_Semid_DS
+
+/*
+ Argument for semctl functions
+*/
+Sem_Un :: struct #raw_union {
+ val: i32,
+ buf: rawptr,
+ array: u16,
+ __buf: Sem_Info,
+ _: uintptr,
+}
+
+/*
+ SystenV semaphore info.
+*/
+Sem_Info {
+ map: i32,
+ mni: i32,
+ mns: i32,
+ mnu: i32,
+ msl: i32,
+ opm: i32,
+ ume: i32,
+ usz: i32,
+ vmx: i32,
+ aem: i32,
+}
+
+/*
+ Template for the struct used for sending and receiving messages
+*/
+Msg_Buf :: struct {
+ type: int,
+ text: [0]u8,
+}
+
+/*
+ SystemV message queue data.
+*/
+struct Msqid_DS {
+ perm: IPC_Perm,
+ stime: uint,
+ rtime: uint,
+ ctime: uint,
+ cbytes: uint,
+ qnum: uint,
+ qbytes: uint,
+ lspid: Pid,
+ lrpid: Pid,
+ _: [2]uint
+};
+
+/*
+ Interval timer types
+*/
+ITimer_Which :: enum {
+ REAL = 0,
+ VIRTUAL = 1,
+ PROF = 2,
+}
+
+/*
+ Interval timer value
+*/
+ITimer_Val :: struct {
+ interval: Time_Val,
+ value: Time_Val,
+}
+
+when ODIN_ARCH == .arm32 {
+ _Arch_User_Regs :: struct {
+ cpsr: uint,
+ pc: uint,
+ lr: uint,
+ sp: uint,
+ ip: uint,
+ fp: uint,
+ r10: uint,
+ r9: uint,
+ r8: uint,
+ r7: uint,
+ r6: uint,
+ r5: uint,
+ r4: uint,
+ r3: uint,
+ r2: uint,
+ r1: uint,
+ r0: uint,
+ ORIG_r0: uint,
+ }
+ // TODO(flysand): Idk what to do about these, couldn't find their
+ // definitions
+ _Arch_User_FP_Regs :: struct {}
+ _Arch_User_FPX_Regs :: struct {}
+} else when ODIN_ARCH == .arm64 {
+ _Arch_User_Regs :: struct {
+ regs: [31]uint,
+ sp: uint,
+ pc: uint,
+ pstate: uint,
+ }
+ _Arch_User_FP_Regs :: struct {
+ vregs: [32]u128,
+ fpsr: u32,
+ fpcr: u32,
+ _: [2]u32
+ }
+ _Arch_User_FPX_Regs :: struct {}
+} else when ODIN_ARCH == .i386 {
+ _Arch_User_Regs :: struct {
+ ebx: uint,
+ ecx: uint,
+ edx: uint,
+ esi: uint,
+ edi: uint,
+ ebp: uint,
+ eax: uint,
+ xds: uint,
+ xes: uint,
+ xfs: uint,
+ xgs: uint,
+ orig_eax: uint,
+ eip: uint,
+ xcs: uint,
+ eflags: uint,
+ esp: uint,
+ xss: uint,
+ }
+ // x87 FPU state
+ _Arch_User_FP_Regs :: struct {
+ cwd: uint,
+ swd: uint,
+ twd: uint,
+ fip: uint,
+ fcs: uint,
+ foo: uint,
+ fos: uint,
+ st_space: [20]uint,
+ }
+ // FXSR instruction set state
+ _Arch_User_FPX_Regs :: struct {
+ cwd: u16,
+ swd: u16,
+ twd: u16,
+ fop: u16,
+ fip: uint,
+ fcs: uint,
+ foo: uint,
+ fos: uint,
+ mxcsr: uint,
+ _: uint,
+ st_space: [32]uint,
+ xmm_space: [32]uint,
+ padding: [56]uint,
+ }
+} else when ODIN_ARCH == .amd64 {
+ _Arch_User_Regs {
+ // Callee-preserved, may not be correct if the syscall doesn't need
+ // these registers
+ r15: uint,
+ r14: uint,
+ r13: uint,
+ r12: uint,
+ rbp: uint,
+ rbx: uint,
+ // Always saved
+ r11: uint,
+ r10: uint,
+ r9: uint,
+ r8: uint,
+ rax: uint,
+ rcx: uint,
+ rdx: uint,
+ rsi: uint,
+ rdi: uint,
+ // On syscall entry this is the syscall number, on CPU exception this
+ // is the error code, on hardware interrupt this is its IRQ number
+ orig_rax: uint,
+ // Return frame for iretq
+ rip: uint,
+ cs: uint,
+ eflags: uint,
+ rsp: uint,
+ ss: uint,
+ }
+ // All floating point state
+ _Arch_User_FP_Regs :: struct {
+ cwd: u16,
+ swd: u16,
+ twd: u16,
+ fop: u16,
+ rip: uint,
+ rdp: uint,
+ mxcsr: u32,
+ mxcsr_mask: u32,
+ st_space: [32]u32,
+ xmm_space: [64]u32,
+ _: [24]u32;
+ }
+}
+
+/*
+ Architecture-specific registers struct.
+*/
+User_Regs :: _Arch_User_Regs
+
+/*
+ Architecture-specific floating-point registers
+*/
+User_FP_Regs :: _Arch_User_FP_Regs
+
+/*
+ Architecture-specific extended floating-point registers.
+ Currently only used for x86 CPU's.
+*/
+User_FPX_Regs :: _Arch_User_FPX_Regs
+
+/*
+ ptrace options.
+*/
+PTrace_Options :: bit_set[PTrace_Options_Bits; u32]
+
+/*
+ ptrace's PEEKSIGINFO argument.
+*/
+PTrace_Peek_Sig_Info_Args :: struct {
+ off: u64,
+ flags: PTrace_Peek_Sig_Info_Flags,
+ nr: i32,
+}
+
+/*
+ ptrace's PEEKSIGINFO flags.
+*/
+PTrace_Peek_Sig_Info_Flags :: bit_set[PTrace_Peek_Sig_Info_Flags_Bits, u32]
+
+/*
+ ptrace's SECCOMP metadata.
+*/
+PTrace_Seccomp_Metadata
+{
+ filter_off: u64,
+ flags: u64,
+}
+
+/*
+ ptrace's results of GET_SYSCALL_INFO.
+*/
+PTrace_Syscall_Info :: struct {
+ op: PTrace_Get_Syscall_Info_Op,
+ arch: u32, // TODO: AUDIT_ARCH*
+ instruction_pointer: u64,
+ stack_pointer: u64,
+ using _: struct #raw_union {
+ entry: struct {
+ nr: u64,
+ args: [6]u64,
+ },
+ exit: struct {
+ rval: i64,
+ is_error: b8,
+ },
+ seccomp: struct {
+ nr: u64,
+ args: [6]u64,
+ ret_data: u32,
+ },
+ };
+};
+
+/*
+ ptrace's results of GET_RSEQ_CONFIGURATION.
+*/
+PTrace_RSeq_Configuration {
+ rseq_abi_pointer: u64,
+ rseq_abi_size: u32,
+ signature: u32,
+ flags: u32,
+ _: u32,
+}; \ No newline at end of file