From ce1f3b34c077f22fd7b929b55d09479002a5ce65 Mon Sep 17 00:00:00 2001 From: jason Date: Thu, 2 Jan 2025 11:03:24 -0500 Subject: [PATCH 1/3] Minor fixes + cleanup in os2 and sys/linux Add NOFOLLOW to os2.remove Change Dev from int to u64 and make relavant casts Fix compat64_arg_pair --- core/os/os2/file_linux.odin | 2 +- core/os/os2/path_linux.odin | 2 -- core/sys/linux/helpers.odin | 2 +- core/sys/linux/sys.odin | 6 +++--- core/sys/linux/types.odin | 3 ++- 5 files changed, 7 insertions(+), 8 deletions(-) diff --git a/core/os/os2/file_linux.odin b/core/os/os2/file_linux.odin index 20f179f77..a1e3c4afd 100644 --- a/core/os/os2/file_linux.odin +++ b/core/os/os2/file_linux.odin @@ -275,7 +275,7 @@ _remove :: proc(name: string) -> Error { TEMP_ALLOCATOR_GUARD() name_cstr := temp_cstring(name) or_return - if fd, errno := linux.open(name_cstr, _OPENDIR_FLAGS); errno == .NONE { + if fd, errno := linux.open(name_cstr, _OPENDIR_FLAGS + {.NOFOLLOW}); errno == .NONE { linux.close(fd) return _get_platform_error(linux.rmdir(name_cstr)) } diff --git a/core/os/os2/path_linux.odin b/core/os/os2/path_linux.odin index 7be4121ae..bfdb645ef 100644 --- a/core/os/os2/path_linux.odin +++ b/core/os/os2/path_linux.odin @@ -77,8 +77,6 @@ _mkdir_all :: proc(path: string, perm: int) -> Error { } _remove_all :: proc(path: string) -> Error { - DT_DIR :: 4 - remove_all_dir :: proc(dfd: linux.Fd) -> Error { n := 64 buf := make([]u8, n) diff --git a/core/sys/linux/helpers.odin b/core/sys/linux/helpers.odin index aefc1179e..5273426d8 100644 --- a/core/sys/linux/helpers.odin +++ b/core/sys/linux/helpers.odin @@ -139,7 +139,7 @@ when size_of(int) == 4 { // xxx64 system calls take some parameters as pairs of ulongs rather than a single pointer @(private) compat64_arg_pair :: #force_inline proc "contextless" (a: i64) -> (hi: uint, lo: uint) { - no_sign := uint(a) + no_sign := u64(a) hi = uint(no_sign >> 32) lo = uint(no_sign & 0xffff_ffff) return diff --git a/core/sys/linux/sys.odin b/core/sys/linux/sys.odin index 690902f07..88753a788 100644 --- a/core/sys/linux/sys.odin +++ b/core/sys/linux/sys.odin @@ -1952,10 +1952,10 @@ sigaltstack :: proc "contextless" (stack: ^Sig_Stack, old_stack: ^Sig_Stack) -> */ mknod :: proc "contextless" (name: cstring, mode: Mode, dev: Dev) -> (Errno) { when ODIN_ARCH == .arm64 || ODIN_ARCH == .riscv64 { - ret := syscall(SYS_mknodat, AT_FDCWD, cast(rawptr) name, transmute(u32) mode, dev) + ret := syscall(SYS_mknodat, AT_FDCWD, cast(rawptr) name, transmute(u32) mode, cast(uint) dev) return Errno(-ret) } else { - ret := syscall(SYS_mknod, cast(rawptr) name, transmute(u32) mode, dev) + ret := syscall(SYS_mknod, cast(rawptr) name, transmute(u32) mode, cast(uint) dev) return Errno(-ret) } } @@ -2586,7 +2586,7 @@ mkdirat :: proc "contextless" (dirfd: Fd, name: cstring, mode: Mode) -> (Errno) Available since Linux 2.6.16. */ mknodat :: proc "contextless" (dirfd: Fd, name: cstring, mode: Mode, dev: Dev) -> (Errno) { - ret := syscall(SYS_mknodat, dirfd, cast(rawptr) name, transmute(u32) mode, dev) + ret := syscall(SYS_mknodat, dirfd, cast(rawptr) name, transmute(u32) mode, cast(uint) dev) return Errno(-ret) } diff --git a/core/sys/linux/types.odin b/core/sys/linux/types.odin index 08a443bcc..2c01d072d 100644 --- a/core/sys/linux/types.odin +++ b/core/sys/linux/types.odin @@ -3,7 +3,7 @@ package linux /* Type for storage device handle. */ -Dev :: distinct int +Dev :: distinct u64 /* Type for 32-bit User IDs. @@ -153,6 +153,7 @@ when ODIN_ARCH == .amd64 { uid: Uid, gid: Gid, rdev: Dev, + _: [4]u8, size: i64, blksize: uint, blocks: u64, From 074bef7bafbf4b111ca1bc245dda21ac86810b13 Mon Sep 17 00:00:00 2001 From: jason Date: Thu, 2 Jan 2025 14:50:45 -0500 Subject: [PATCH 2/3] Fix sys/linux 64 bit arguments on 32 bit systems Reverese return values of compat64_arg_pair Add register alignment to specific arm32 system calls --- core/os/os2/file_linux.odin | 3 +++ core/sys/linux/helpers.odin | 2 +- core/sys/linux/sys.odin | 25 ++++++++++++++++++++----- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/core/os/os2/file_linux.odin b/core/os/os2/file_linux.odin index a1e3c4afd..ad2892f40 100644 --- a/core/os/os2/file_linux.odin +++ b/core/os/os2/file_linux.odin @@ -80,6 +80,9 @@ _open :: proc(name: string, flags: File_Flags, perm: int) -> (f: ^File, err: Err // terminal would be incredibly rare. This has no effect on files while // allowing us to open serial devices. sys_flags: linux.Open_Flags = {.NOCTTY, .CLOEXEC} + when size_of(rawptr) == 4 { + sys_flags += {.LARGEFILE} + } switch flags & (O_RDONLY|O_WRONLY|O_RDWR) { case O_RDONLY: case O_WRONLY: sys_flags += {.WRONLY} diff --git a/core/sys/linux/helpers.odin b/core/sys/linux/helpers.odin index 5273426d8..9a7550d57 100644 --- a/core/sys/linux/helpers.odin +++ b/core/sys/linux/helpers.odin @@ -138,7 +138,7 @@ errno_unwrap :: proc {errno_unwrap2, errno_unwrap3} when size_of(int) == 4 { // xxx64 system calls take some parameters as pairs of ulongs rather than a single pointer @(private) - compat64_arg_pair :: #force_inline proc "contextless" (a: i64) -> (hi: uint, lo: uint) { + compat64_arg_pair :: #force_inline proc "contextless" (a: i64) -> (lo: uint, hi: uint) { no_sign := u64(a) hi = uint(no_sign >> 32) lo = uint(no_sign & 0xffff_ffff) diff --git a/core/sys/linux/sys.odin b/core/sys/linux/sys.odin index 88753a788..2117d7d43 100644 --- a/core/sys/linux/sys.odin +++ b/core/sys/linux/sys.odin @@ -151,7 +151,8 @@ lseek :: proc "contextless" (fd: Fd, off: i64, whence: Seek_Whence) -> (i64, Err return errno_unwrap(ret, i64) } else { result: i64 = --- - ret := syscall(SYS__llseek, fd, compat64_arg_pair(off), &result, whence) + lo, hi := compat64_arg_pair(off) + ret := syscall(SYS__llseek, fd, hi, lo, &result, whence) return result, Errno(-ret) } } @@ -251,7 +252,11 @@ ioctl :: proc "contextless" (fd: Fd, request: u32, arg: uintptr) -> (uintptr) { Available since Linux 2.2. */ pread :: proc "contextless" (fd: Fd, buf: []u8, offset: i64) -> (int, Errno) { - ret := syscall(SYS_pread64, fd, raw_data(buf), len(buf), compat64_arg_pair(offset)) + when ODIN_ARCH == .arm32 { + ret := syscall(SYS_pread64, fd, raw_data(buf), len(buf), 0, compat64_arg_pair(offset)) + } else { + ret := syscall(SYS_pread64, fd, raw_data(buf), len(buf), compat64_arg_pair(offset)) + } return errno_unwrap(ret, int) } @@ -261,7 +266,11 @@ pread :: proc "contextless" (fd: Fd, buf: []u8, offset: i64) -> (int, Errno) { Available since Linux 2.2. */ pwrite :: proc "contextless" (fd: Fd, buf: []u8, offset: i64) -> (int, Errno) { - ret := syscall(SYS_pwrite64, fd, raw_data(buf), len(buf), compat64_arg_pair(offset)) + when ODIN_ARCH == .arm32 { + ret := syscall(SYS_pwrite64, fd, raw_data(buf), len(buf), 0, compat64_arg_pair(offset)) + } else { + ret := syscall(SYS_pwrite64, fd, raw_data(buf), len(buf), compat64_arg_pair(offset)) + } return errno_unwrap(ret, int) } @@ -1127,7 +1136,10 @@ fdatasync :: proc "contextless" (fd: Fd) -> (Errno) { On 32-bit architectures available since Linux 2.4. */ truncate :: proc "contextless" (name: cstring, length: i64) -> (Errno) { - when size_of(int) == 4 { + when ODIN_ARCH == .arm32 { + ret := syscall(SYS_truncate64, cast(rawptr) name, 0, compat64_arg_pair(length)) + return Errno(-ret) + } else when size_of(int) == 4 { ret := syscall(SYS_truncate64, cast(rawptr) name, compat64_arg_pair(length)) return Errno(-ret) } else { @@ -1141,7 +1153,10 @@ truncate :: proc "contextless" (name: cstring, length: i64) -> (Errno) { On 32-bit architectures available since 2.4. */ ftruncate :: proc "contextless" (fd: Fd, length: i64) -> (Errno) { - when size_of(int) == 4 { + when ODIN_ARCH == .arm32 { + ret := syscall(SYS_ftruncate64, fd, 0, compat64_arg_pair(length)) + return Errno(-ret) + } else when size_of(int) == 4 { ret := syscall(SYS_ftruncate64, fd, compat64_arg_pair(length)) return Errno(-ret) } else { From 1221e393f7e1ab5efaafdc4c168f2b3467efd2d2 Mon Sep 17 00:00:00 2001 From: jason Date: Fri, 3 Jan 2025 09:29:39 -0500 Subject: [PATCH 3/3] add 32 bit Sig_Info and remove ppoll_time64 call --- core/sys/linux/sys.odin | 9 +- core/sys/linux/types.odin | 219 +++++++++++++++++++++++++++----------- 2 files changed, 156 insertions(+), 72 deletions(-) diff --git a/core/sys/linux/sys.odin b/core/sys/linux/sys.odin index 2117d7d43..fee385fe8 100644 --- a/core/sys/linux/sys.odin +++ b/core/sys/linux/sys.odin @@ -2699,13 +2699,8 @@ faccessat :: proc "contextless" (dirfd: Fd, name: cstring, mode: Mode = F_OK) -> Available since Linux 2.6.16. */ ppoll :: proc "contextless" (fds: []Poll_Fd, timeout: ^Time_Spec, sigmask: ^Sig_Set) -> (i32, Errno) { - when size_of(int) == 8 { - ret := syscall(SYS_ppoll, raw_data(fds), len(fds), timeout, sigmask, size_of(Sig_Set)) - return errno_unwrap(ret, i32) - } else { - ret := syscall(SYS_ppoll_time64, raw_data(fds), len(fds), timeout, sigmask, size_of(Sig_Set)) - return errno_unwrap(ret, i32) - } + ret := syscall(SYS_ppoll, raw_data(fds), len(fds), timeout, sigmask, size_of(Sig_Set)) + return errno_unwrap(ret, i32) } // TODO(flysand): unshare diff --git a/core/sys/linux/types.odin b/core/sys/linux/types.odin index 2c01d072d..dcc72f72b 100644 --- a/core/sys/linux/types.odin +++ b/core/sys/linux/types.odin @@ -517,79 +517,79 @@ Pid_FD_Flags :: bit_set[Pid_FD_Flags_Bits; i32] Sig_Set :: [_SIGSET_NWORDS]uint @private SI_MAX_SIZE :: 128 -@private SI_ARCH_PREAMBLE :: 4 * size_of(i32) +@private SI_ARCH_PREAMBLE :: 4 * size_of(i32) when size_of(rawptr) == 8 else 3 * size_of(i32) @private SI_PAD_SIZE :: SI_MAX_SIZE - SI_ARCH_PREAMBLE Sig_Handler_Fn :: #type proc "c" (sig: Signal) Sig_Restore_Fn :: #type proc "c" () -> ! -Sig_Info :: struct #packed { - signo: Signal, - errno: Errno, - code: i32, - _pad0: i32, - using _union: struct #raw_union { - _pad1: [SI_PAD_SIZE]u8, - using _kill: struct { - pid: Pid, /* sender's pid */ - uid: Uid, /* sender's uid */ - }, - using _timer: struct { - timerid: i32, /* timer id */ - overrun: i32, /* overrun count */ - value: Sig_Val, /* timer value */ - }, - /* POSIX.1b signals */ - using _rt: struct { - _pid0: Pid, /* sender's pid */ - _uid0: Uid, /* sender's uid */ - }, - /* SIGCHLD */ - using _sigchld: struct { - _pid1: Pid, /* which child */ - _uid1: Uid, /* sender's uid */ - status: i32, /* exit code */ - utime: uint, - stime: uint, //clock_t - }, - /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ - using _sigfault: struct { - addr: rawptr, /* faulting insn/memory ref. */ - using _: struct #raw_union { - trapno: i32, /* Trap number that caused signal */ - addr_lsb: i16, /* LSB of the reported address */ - using _addr_bnd: struct { - _pad2: u64, - lower: rawptr, /* lower bound during fault */ - upper: rawptr, /* upper bound during fault */ - }, - using _addr_pkey: struct { - _pad3: u64, - pkey: u32, /* protection key on PTE that faulted */ - }, - using _perf: struct { - perf_data: u64, - perf_type: u32, - perf_flags: u32, +when size_of(rawptr) == 8 { + Sig_Info :: struct #packed { + signo: Signal, + errno: Errno, + code: i32, + _pad0: i32, + using _union: struct #raw_union { + _pad1: [SI_PAD_SIZE]u8, + using _kill: struct { + pid: Pid, /* sender's pid */ + uid: Uid, /* sender's uid */ + }, + using _timer: struct { + timerid: i32, /* timer id */ + overrun: i32, /* overrun count */ + value: Sig_Val, /* timer value */ + }, + /* POSIX.1b signals */ + using _rt: struct { + _pid0: Pid, /* sender's pid */ + _uid0: Uid, /* sender's uid */ + }, + /* SIGCHLD */ + using _sigchld: struct { + _pid1: Pid, /* which child */ + _uid1: Uid, /* sender's uid */ + status: i32, /* exit code */ + utime: uint, + stime: uint, //clock_t + }, + /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ + using _sigfault: struct { + addr: rawptr, /* faulting insn/memory ref. */ + using _: struct #raw_union { + trapno: i32, /* Trap number that caused signal */ + addr_lsb: i16, /* LSB of the reported address */ + using _addr_bnd: struct { + _pad2: u64, + lower: rawptr, /* lower bound during fault */ + upper: rawptr, /* upper bound during fault */ + }, + using _addr_pkey: struct { + _pad3: u64, + pkey: u32, /* protection key on PTE that faulted */ + }, + using _perf: struct { + perf_data: u64, + perf_type: u32, + perf_flags: u32, + }, }, }, + /* SIGPOLL */ + using _sigpoll: struct { + band: int, /* POLL_IN, POLL_OUT, POLL_MSG */ + fd: Fd, + }, + /* SIGSYS */ + using _sigsys: struct { + call_addr: rawptr, /* calling user insn */ + syscall: i32, /* triggering system call number */ + arch: u32, /* AUDIT_ARCH_* of syscall */ + }, }, - /* SIGPOLL */ - using _sigpoll: struct { - band: int, /* POLL_IN, POLL_OUT, POLL_MSG */ - fd: Fd, - }, - /* SIGSYS */ - using _sigsys: struct { - call_addr: rawptr, /* calling user insn */ - syscall: i32, /* triggering system call number */ - arch: u32, /* AUDIT_ARCH_* of syscall */ - }, - }, -} + } -#assert(size_of(Sig_Info) == 128) -when ODIN_ARCH == .amd64 || ODIN_ARCH == .arm64 { + #assert(size_of(Sig_Info) == 128) #assert(offset_of(Sig_Info, signo) == 0x00) #assert(offset_of(Sig_Info, errno) == 0x04) #assert(offset_of(Sig_Info, code) == 0x08) @@ -616,7 +616,96 @@ when ODIN_ARCH == .amd64 || ODIN_ARCH == .arm64 { #assert(offset_of(Sig_Info, syscall) == 0x18) #assert(offset_of(Sig_Info, arch) == 0x1C) } else { - // TODO + Sig_Info :: struct { + signo: Signal, + errno: Errno, + code: i32, + using _union: struct #raw_union { + _pad1: [SI_PAD_SIZE]u8, + using _kill: struct { + pid: Pid, /* sender's pid */ + uid: Uid, /* sender's uid */ + }, + using _timer: struct { + timerid: i32, /* timer id */ + overrun: i32, /* overrun count */ + value: Sig_Val, /* timer value */ + }, + /* POSIX.1b signals */ + using _rt: struct { + _pid0: Pid, /* sender's pid */ + _uid0: Uid, /* sender's uid */ + }, + /* SIGCHLD */ + using _sigchld: struct { + _pid1: Pid, /* which child */ + _uid1: Uid, /* sender's uid */ + status: i32, /* exit code */ + utime: uint, + stime: uint, //clock_t + }, + /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ + using _sigfault: struct { + addr: rawptr, /* faulting insn/memory ref. */ + using _: struct #raw_union { + trapno: i32, /* Trap number that caused signal */ + addr_lsb: i16, /* LSB of the reported address */ + using _addr_bnd: struct { + _pad2: u32, + lower: rawptr, /* lower bound during fault */ + upper: rawptr, /* upper bound during fault */ + }, + using _addr_pkey: struct { + _pad3: u32, + pkey: u32, /* protection key on PTE that faulted */ + }, + using _perf: struct { + perf_data: u32, + perf_type: u32, + perf_flags: u32, + }, + }, + }, + /* SIGPOLL */ + using _sigpoll: struct { + band: int, /* POLL_IN, POLL_OUT, POLL_MSG */ + fd: Fd, + }, + /* SIGSYS */ + using _sigsys: struct { + call_addr: rawptr, /* calling user insn */ + syscall: i32, /* triggering system call number */ + arch: u32, /* AUDIT_ARCH_* of syscall */ + }, + }, + } + + #assert(size_of(Sig_Info) == 128) + #assert(offset_of(Sig_Info, signo) == 0x00) + #assert(offset_of(Sig_Info, errno) == 0x04) + #assert(offset_of(Sig_Info, code) == 0x08) + #assert(offset_of(Sig_Info, pid) == 0x0c) + #assert(offset_of(Sig_Info, uid) == 0x10) + #assert(offset_of(Sig_Info, timerid) == 0x0c) + #assert(offset_of(Sig_Info, overrun) == 0x10) + #assert(offset_of(Sig_Info, value) == 0x14) + #assert(offset_of(Sig_Info, status) == 0x14) + #assert(offset_of(Sig_Info, utime) == 0x18) + #assert(offset_of(Sig_Info, stime) == 0x1c) + #assert(offset_of(Sig_Info, addr) == 0x0c) + #assert(offset_of(Sig_Info, addr_lsb) == 0x10) + #assert(offset_of(Sig_Info, trapno) == 0x10) + #assert(offset_of(Sig_Info, lower) == 0x14) + #assert(offset_of(Sig_Info, upper) == 0x18) + #assert(offset_of(Sig_Info, pkey) == 0x14) + #assert(offset_of(Sig_Info, perf_data) == 0x10) + #assert(offset_of(Sig_Info, perf_type) == 0x14) + #assert(offset_of(Sig_Info, perf_flags) == 0x18) + #assert(offset_of(Sig_Info, band) == 0x0c) + #assert(offset_of(Sig_Info, fd) == 0x10) + #assert(offset_of(Sig_Info, call_addr) == 0x0c) + #assert(offset_of(Sig_Info, syscall) == 0x10) + #assert(offset_of(Sig_Info, arch) == 0x14) } SIGEV_MAX_SIZE :: 64