diff options
| author | flysand7 <yyakut.ac@gmail.com> | 2023-11-04 12:46:45 +1100 |
|---|---|---|
| committer | flysand7 <yyakut.ac@gmail.com> | 2023-11-04 12:46:45 +1100 |
| commit | 1e622979f80b633e791e04a910c5d27e557cde80 (patch) | |
| tree | 232c509ae9ba76bd2388b80ba3d53243b4d4d29a /core/sys/linux | |
| parent | 7faa1460049a3f9500239a10f8377fc508d6f19e (diff) | |
[sys/linux]: Add more syscalls
Diffstat (limited to 'core/sys/linux')
| -rw-r--r-- | core/sys/linux/bits.odin | 52 | ||||
| -rw-r--r-- | core/sys/linux/sys.odin | 285 | ||||
| -rw-r--r-- | core/sys/linux/types.odin | 75 |
3 files changed, 356 insertions, 56 deletions
diff --git a/core/sys/linux/bits.odin b/core/sys/linux/bits.odin index fd86b798f..c7c0e5ae6 100644 --- a/core/sys/linux/bits.odin +++ b/core/sys/linux/bits.odin @@ -1567,4 +1567,54 @@ PTrace_Get_Syscall_Info_Op :: enum u8 { */ PTrace_Peek_Sig_Info_Flags_Bits :: enum { SHARED = 0, -}
\ No newline at end of file +} + +/* + Syslog actions. +*/ +Syslog_Action :: enum i32 { + CLOSE = 0, + OPEN = 1, + READ = 2, + READ_ALL = 3, + READ_CLEAR = 4, + CLEAR = 5, + CONSOLE_OFF = 6, + CONSOLE_ON = 7, + CONSOLE_LEVEL = 8, + SIZE_UNREAD = 9, + SIZE_BUFFER = 10, +} + +/* + Bits for splice flags. +*/ +Splice_Flags_Bits :: enum { + MOVE = 0x01, + NONBLOCK = 0x02, + MORE = 0x04, + GIFT = 0x08, +} + +/* + Clock IDs for various system clocks. +*/ +Clock_ID :: enum { + REALTIME = 0, + MONOTONIC = 1, + PROCESS_CPUTIME_ID = 2, + THREAD_CPUTIME_ID = 3, + MONOTONIC_RAW = 4, + REALTIME_COARSE = 5, + MONOTONIC_COARSE = 6, + BOOTTIME = 7, + REALTIME_ALARM = 8, + BOOTTIME_ALARM = 9, +} + +/* + Bits for POSIX interval timer flags. +*/ +ITimer_Flags_Bits :: enum { + ABSTIME = 1, +} diff --git a/core/sys/linux/sys.odin b/core/sys/linux/sys.odin index d04a6c857..13226939e 100644 --- a/core/sys/linux/sys.odin +++ b/core/sys/linux/sys.odin @@ -1274,83 +1274,148 @@ ptrace_traceme :: proc "contextless" (rq: PTrace_Traceme_Type) -> (Errno) { return Errno(-ret) } -ptrace_peek :: proc "contextless" (rq: PTrace_Peek_Type, addr: uintptr) -> (uint, Errno) { - ret := syscall(SYS_ptrace, rq, addr) +ptrace_peek :: proc "contextless" (rq: PTrace_Peek_Type, pid: Pid, addr: uintptr) -> (uint, Errno) { + ret := syscall(SYS_ptrace, rq, pid: Pid, addr, pid) 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) +ptrace_poke :: proc "contextless" (rq: PTrace_Poke_Type, pid: Pid, addr: uintptr, data: uint) -> (Errno) { + ret := syscall(SYS_ptrace, rq, pid: Pid, addr, data) return Errno(-ret) } -ptrace_getregs :: proc "contextless" (rq: PTrace_Getregs_Type, buf: ^User_Regs) -> (Errno) { - ret := syscall(SYS_ptrace, rq, 0, buf) +ptrace_getregs :: proc "contextless" (rq: PTrace_Getregs_Type, pid: Pid, buf: ^User_Regs) -> (Errno) { + ret := syscall(SYS_ptrace, rq, pid, 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) +ptrace_getfpregs :: proc "contextless" (rq: PTrace_Getfpregs_Type, pid: Pid, buf: ^User_FP_Regs) -> (Errno) { + ret := syscall(SYS_ptrace, rq, pid, 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) +ptrace_getfpxregs :: proc "contextless" (rq: PTrace_Getfpxregs_Type, pid: Pid, buf: ^User_FPX_Regs) -> (Errno) { + ret := syscall(SYS_ptrace, rq, pid, 0, buf) return Errno(-ret) } -ptrace_setregs :: proc "contextless" (rq: PTrace_Setregs_Type, buf: ^User_Regs) -> (Errno) { - ret := syscall(SYS_ptrace, rq, 0, buf) +ptrace_setregs :: proc "contextless" (rq: PTrace_Setregs_Type, pid: Pid, buf: ^User_Regs) -> (Errno) { + ret := syscall(SYS_ptrace, rq, pid, 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) +ptrace_setfpregs :: proc "contextless" (rq: PTrace_Setfpregs_Type, pid: Pid, buf: ^User_FP_Regs) -> (Errno) { + ret := syscall(SYS_ptrace, rq, pid, 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) +ptrace_setfpxregs :: proc "contextless" (rq: PTrace_Setfpxregs_Type, pid: Pid, buf: ^User_FPX_Regs) -> (Errno) { + ret := syscall(SYS_ptrace, rq, pid, 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_getregset :: proc "contextless" (rq: PTrace_Getgetset_Type, pid: Pid, note: PTrace_Note_Type, buf: ^IO_Vec) -> (Errno) { + ret := syscall(SYS_ptrace, rq, pid, note, buf) + return Errno(-ret) +} + +ptrace_setregset :: proc "contextless" (rq: PTrace_Setgetset_Type, pid: Pid, note: PTrace_Note_Type, buf: ^IO_Vec) -> (Errno) { + ret := syscall(SYS_ptrace, rq, pid, note, buf) + return Errno(-ret) +} + +ptrace_getsiginfo :: proc "contextless" (rq: PTrace_Getsiginfo_Type, pid: Pid, si: ^Sig_Info) -> (Errno) { + ret := syscall(SYS_ptrace, rq, pid, si) + return Errno(-ret) +} + +ptrace_peeksiginfo :: proc "contextless" (rq: PTrace_Peeksiginfo_Type, pid: Pid, si: ^Sig_Info) -> (Errno) { + ret := syscall(SYS_ptrace, rq, pid, si) + return Errno(-ret) +} + +ptrace_getsigmask :: proc "contextless" (rq: PTrace_Getsigmask, pid: Pid, sigmask: ^Sig_Mask) -> (Errno) { + ret := syscall(SYS_ptrace, rq, pid, size_of(Sig_Mask), sigmask) + return Errno(-ret) +} + +ptrace_setsigmask :: proc "contextless" (rq: PTrace_Setsigmask, pid: Pid, sigmask: ^Sig_Mask) -> (Errno) { + ret := syscall(SYS_ptrace, rq, pid, size_of(Sig_Mask), sigmask) + return Errno(-ret) +} + +ptrace_setoptions :: proc "contextless" (rq: PTrace_Setoptions_Type, pid: Pid, options: PTrace_Options) -> (Errno) { + ret := syscall(SYS_ptrace, rq, pid, 0, transmute(u32) options) + return Errno(-ret) +} + +ptrace_geteventmsg :: proc "contextless" (rq: PTrace_Geteventmsg_Type, pid: Pid, msg: ^uint) -> (Errno) { + ret := syscall(SYS_ptrace, rq, pid, msg) + return Errno(-ret) +} + +ptrace_cont :: proc "contextless" (rq: PTrace_Cont_Type, pid: Pid, sig: Signal) -> (Errno) { + ret := syscall(SYS_ptrace, rq, pid, sig) + return Errno(-ret) +} + +ptrace_singlestep :: proc "contextless" (rq: PTrace_Singlestep_Type, pid: Pid, sig: Signal) -> (Errno) { + ret := syscall(SYS_ptrace, rq, pid, sig) + return Errno(-ret) +} -ptrace_setoptions :: proc "contextless" (rq: PTrace_Setoptions_Type, options: PTrace_Options) -> (Errno) { - ret := syscall(SYS_ptrace, rq, 0, transmute(u32) options) +ptrace_syscall :: proc "contextless" (rq: PTrace_Syscall_Type, pid: Pid, sig: Signal) -> (Errno) { + ret := syscall(SYS_ptrace, rq, pid, sig) + return Errno(-ret) +} + +ptrace_sysemu :: proc "contextless" (rq: PTrace_Sysemu_Type, pid: Pid, sig: Signal) -> (Errno) { + ret := syscall(SYS_ptrace, rq, pid, sig) + return Errno(-ret) +} + +ptrace_sysemu_singlestep :: proc "contextless" (rq: PTrace_Sysemu_Singlestep_Type, pid: Pid, sig: Signal) -> (Errno) { + ret := syscall(SYS_ptrace, rq, pid, sig) + return Errno(-ret) +} + +ptrace_listen :: proc "contextless" (rq: PTrace_Listen_Type, pid: Pid) -> (Errno) { + ret := syscall(SYS_ptrace, rq, pid) + return Errno(-ret) +} + +ptrace_interrupt :: proc "contextless" (rq: PTrace_Interrupt_Type, pid: Pid) -> (Errno) { + ret := syscall(SYS_ptrace, rq, pid) + return Errno(-ret) +} + +ptrace_attach :: proc "contextless" (rq: PTrace_Attach_Type, pid: Pid) -> (Errno) { + ret := syscall(SYS_ptrace, rq, pid) + return Errno(-ret) +} + +ptrace_seize :: proc "contextless" (rq: PTrace_Seize_Type, pid: Pid, opt: PTrace_Options) -> (Errno) { + ret := syscall(SYS_ptrace, rq, pid, 0, transmute(u32) opt) 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 + +ptrace_detach :: proc "contextless" (rq: PTrace_Detach_Type, pid: Pid, sig: Signal) -> (Errno) { + ret := syscall(SYS_ptrace, rq, pid, 0, sig) + return Errno(-ret) +} + // TODO(flysand): ptrace_get_thread_area // TODO(flysand): ptrace_set_thread_area // TODO(flysand): ptrace_get_syscall_info -// TODO(flysand): ptrace_setsigmask /* - Trace process + Trace process. */ ptrace :: proc { ptrace_traceme, - peek, + ptrace_peek, ptrace_poke, ptrace_getregs, ptrace_getfpregs, @@ -1358,7 +1423,24 @@ ptrace :: proc { ptrace_setregs, ptrace_setfpregs, ptrace_setfpxregs, + ptrace_getregset, + ptrace_setregset, + ptrace_getsiginfo, + ptrace_peeksiginfo, + ptrace_getsigmask, + ptrace_setsigmask, ptrace_setoptions, + ptrace_geteventmsg, + ptrace_cont, + ptrace_singlestep, + ptrace_syscall, + ptrace_sysemu, + ptrace_sysemu_singlestep, + ptrace_listen, + ptrace_interrupt, + ptrace_attach, + ptrace_seize, + ptrace_detach, } /// Get real user ID @@ -1372,7 +1454,15 @@ getuid :: proc "contextless" () -> Uid { } } -// TODO(flysand): syslog +/* + Read or clear kernel message ring buffer. + Available since Linux 1.0. +*/ +syslog :: proc "contextless" (act: Syslog_Action, buf: []u8) -> (int, Errno) { + ret := syscall(SYS_syslog, act, raw_data(buf), len(buf)) + return errno_unwrap(ret, int) +} + /// Get real group ID /// Available since Linux 1.0 @@ -1498,9 +1588,35 @@ setregid :: proc "contextless" (real: Gid, effective: Gid) -> (Errno) { } } -// TODO(flysand): getgroups +/* + Get supplementary group IDs. + Available since Linux 1.0. + On 32-bit platforms available since Linux 2.4. +*/ +getgroups :: proc "contextless" (gids: []Gid) -> (int, Errno) { + when size_of(int) == 8 { + ret := syscall(SYS_getgroups, len(gids), rawptr(gids)) + return errno_unwrap(ret, int) + } else { + ret := syscall(SYS_getgroups32, len(gids), rawptr(gids)) + return errno_unwrap(ret, int) + } +} -// TODO(flysand): setgroups +/* + Set supplementary group IDs. + Available since Linux 1.0. + On 32-bit platforms available since Linux 2.4. +*/ +setgroups :: proc "contextless" (gids: []Gid) -> (Errno) { + when size_of(int) == 8 { + ret := syscall(SYS_setgroup, len(gids), rawptr(gids)) + return Errno(-ret) + } else { + ret := syscall(SYS_setgroup32, len(gids), rawptr(gids)) + return Errno(-ret) + } +} /// Set real, effective and/or saved user id /// If any of the arguments is -1, the corresponding id is not changed @@ -1969,15 +2085,50 @@ set_tid_address :: proc "contextless" (tidptr: ^u32) { // TODO(flysand): fadvise64 -// TODO(flysand): timer_create +/* + Create POSIX per-process timer. + Available since Linux 2.6. +*/ +timer_create :: proc "contextless" (clock_id: Clock_Id, sigevent: ^Sig_Event, timer: ^Timer) -> (Errno) { + ret := syscall(SYS_timer_create, clock_id, sigevent, timer) + return Errno(-ret) +} -// TODO(flysand): timer_settime +/* + Get the state of the POSIX per-process timer. + Available since Linux 2.6. +*/ +timer_gettime :: proc "contextless" (timer: Timer, curr_value: ^ITimer_Spec) -> (Errno) { + ret := syscall(SYS_timer_gettime, timer, curr_value) + return Errno(-ret) +} -// TODO(flysand): timer_gettime +/* + Arm/disarm the state of the POSIX per-process timer. + Available since Linux 2.6. +*/ +timer_settime :: proc "contextless" (timer: Timer, flags: ITimer_Flags, #no_alias new_value, old_value: ^ITimer_Spec) -> (Errno) { + ret := syscall(SYS_timer_settime, timer, transmute(u32) flags, new_value, old_value) + return Errno(-ret) +} -// TODO(flysand): timer_getoverrun +/* + Get overrun count of the POSIX per-process timer. + Available since Linux 2.6. +*/ +timer_getoverrun :: proc "contextless" (timer: Timer) -> (int, Errno) { + ret := syscall(SYS_timer_getoverrun, timer) + return errno_unwrap(ret, int) +} -// TODO(flysand): timer_delete +/* + Delete a POSIX per-process timer. + Available since Linux 2.6. +*/ +timer_delete :: proc "contextless" (timer: Timer) -> (Errno) { + ret := syscall(SYS_timer_delete, timer) + return Errno(-ret) +} // TODO(flysand): clock_settime @@ -1998,7 +2149,14 @@ exit_group :: proc "contextless" (code: i32) -> ! { // TODO(flysand): epoll_ctl -// TODO(flysand): tgkill +/* + Send a signal to a specific thread in a thread group. + Available since Linux 2.6. +*/ +tgkill :: proc "contextless" (tgid, tid: Pid, sig: Signal) -> (Errno) { + ret := syscall(SYS_tgkill, tgid, tid, sig) + return Errno(-ret) +} // TODO(flysand): utimes @@ -2078,8 +2236,6 @@ fchownat :: proc "contextless" (dirfd: Fd, name: cstring, uid: Uid, gid: Gid) -> return Errno(-ret) } -// TODO(flysand): futimesat - /// Get information about a file at a specific directory /// Available since Linux 2.6.16 fstatat :: proc "contextless" (dirfd: Fd, name: cstring, stat: ^Stat, flags: FD_Flags) -> (Errno) { @@ -2164,9 +2320,23 @@ ppoll :: proc "contextless" (fds: []Poll_Fd, timeout: ^Time_Spec, sigmask: ^Sig_ // TODO(flysand): get_robust_list -// TODO(flysand): splice +/* + Transfer the data between file descriptors. + Available since Linux 2.6.17. +*/ +splice :: proc "contextless" (fd_in: Fd, off_in: ^i64, fd_out: Fd, off_out: ^i64, len: uint, flags: Splice_Flags) -> (int, Errno) { + ret := syscall(SYS_splice, fd_in, off_in, fd_out, off_out, len, transmute(u32) flags) + return errno_unwrap(ret, int) +} -// TODO(flysand): tee +/* + Transfer the data between file descriptors. + Available since Linux 2.6.16. +*/ +tee :: proc "contextless" (fd_in: Fd, fd_out: Fd, len: uint, flags: Splice_Flags) -> (int, Errno) { + ret := syscall(SYS_tee, fd_in, fd_out, len, transmute(u32) flags) + return errno_unwrap(ret, int) +} // TODO(flysand): sync_file_range @@ -2299,7 +2469,14 @@ getrandom :: proc "contextless" (buf: []u8, flags: Get_Random_Flags) -> (int, Er // TODO(flysand): bpf -// TODO(flysand): execveat +/* + Execute program relative to a directory file descriptor. + Available since Linux 3.19. +*/ +execveat :: proc "contextless" (dirfd: Fd, name: cstring, argv: [^]cstring, envp: [^]cstring) -> (Errno) { + ret := syscall(SYS_execveat, dirfd, cast(rawptr) name, cast(rawptr) argv, cast(rawptr) envp) + return Errno(-ret) +} // TODO(flysand): userfaultfd diff --git a/core/sys/linux/types.odin b/core/sys/linux/types.odin index cc3c24075..f763cf15f 100644 --- a/core/sys/linux/types.odin +++ b/core/sys/linux/types.odin @@ -29,6 +29,11 @@ Inode :: distinct u64 /// Shared memory identifiers used by `shm*` calls Key :: distinct i32 +/* + Represents timer IDs +*/ +Timer :: distinct i32 + /// Represents time with nanosecond precision Time_Spec :: struct { time_sec: uint, @@ -458,6 +463,28 @@ Sig_Info :: struct #packed { }, } +SIGEV_MAX_SIZE :: 64 +SIGEV_PAD_SIZE :: ((SIGEV_MAX_SIZE-size_of(i32)*2+size_of(Sig_Val))/size_of(i32)) + +Sig_Val :: struct #raw_union { + sival_int: i32, + sival_ptr: rawptr, +} + +Sig_Event :: struct { + value: Sig_Val, + signo: i32, + notify: i32, + using: struct #raw_union { + _: [SIGEV_PAD_SIZE]u32, + thread_id: Pid, + using _: struct { + notify_function: #type proc "c" (val: Sig_Val), + notify_attribute: rawptr, + }, + }, +} + Sig_Stack_Flags :: bit_set[Sig_Stack_Flag; i32] Sig_Stack :: struct { @@ -805,6 +832,16 @@ ITimer_Val :: struct { value: Time_Val, } +ITimer_Spec { + interval: Time_Spec, + value: Time_Spec, +} + +/* + Flags for POSIX interval timers. +*/ +ITimer_Flags :: bit_set[ITimer_Flags_Bits, u32] + when ODIN_ARCH == .arm32 { _Arch_User_Regs :: struct { cpsr: uint, @@ -1015,4 +1052,40 @@ PTrace_RSeq_Configuration { signature: u32, flags: u32, _: u32, -};
\ No newline at end of file +}; + +/* + Note types for PTRACE_GETREGSET. Mirrors constants in `elf` definition, + files though this enum only contains the constants defined for architectures + Odin can compile to. +*/ +PTrace_Note_Type :: enum { + NT_PRSTATUS = 1, + NT_PRFPREG = 2, + NT_PRPSINFO = 3, + NT_TASKSTRUCT = 4, + NT_AUXV = 6, + NT_SIGINFO = 0x53494749, + NT_FILE = 0x46494c45, + NT_PRXFPREG = 0x46e62b7f, + NT_386_TLS = 0x200, + NT_386_IOPERM = 0x201, + NT_X86_XSTATE = 0x202, + NT_X86_SHSTK = 0x204, + NT_ARM_VFP = 0x400, + NT_ARM_TLS = 0x401, + NT_ARM_HW_BREAK = 0x402, + NT_ARM_HW_WATCH = 0x403, + NT_ARM_SYSTEM_CALL = 0x404, + NT_ARM_SVE = 0x405, + NT_ARM_PAC_MASK = 0x406, + NT_ARM_PACA_KEYS = 0x407, + NT_ARM_PACG_KEYS = 0x408, + NT_ARM_TAGGED_ADDR_CTRL = 0x409, + NT_ARM_PAC_ENABLED_KEYS = 0x40a, + NT_ARM_SSVE = 0x40b, + NT_ARM_ZA = 0x40c, + NT_ARM_ZT = 0x40d, +} + +Splice_Flags :: bit_set[Splice_Flags_Bits; u32] |