diff options
| author | jason <jkercher43@gmail.com> | 2025-01-02 14:50:45 -0500 |
|---|---|---|
| committer | jason <jkercher43@gmail.com> | 2025-01-02 14:50:45 -0500 |
| commit | 074bef7bafbf4b111ca1bc245dda21ac86810b13 (patch) | |
| tree | 39724a5400aa7d87f648799f4ce37361c9375128 /core/sys/linux | |
| parent | ce1f3b34c077f22fd7b929b55d09479002a5ce65 (diff) | |
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
Diffstat (limited to 'core/sys/linux')
| -rw-r--r-- | core/sys/linux/helpers.odin | 2 | ||||
| -rw-r--r-- | core/sys/linux/sys.odin | 25 |
2 files changed, 21 insertions, 6 deletions
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 { |