aboutsummaryrefslogtreecommitdiff
path: root/core/sys/linux
diff options
context:
space:
mode:
authorjason <jkercher43@gmail.com>2025-01-02 14:50:45 -0500
committerjason <jkercher43@gmail.com>2025-01-02 14:50:45 -0500
commit074bef7bafbf4b111ca1bc245dda21ac86810b13 (patch)
tree39724a5400aa7d87f648799f4ce37361c9375128 /core/sys/linux
parentce1f3b34c077f22fd7b929b55d09479002a5ce65 (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.odin2
-rw-r--r--core/sys/linux/sys.odin25
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 {