diff options
| author | LemonBoy <thatlemon@gmail.com> | 2020-03-03 17:19:40 +0100 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2020-03-03 11:59:16 -0500 |
| commit | a6fb6dcfc96ad63f9a21110165728da0b8311660 (patch) | |
| tree | e45d24811bdcb06dfb258c1f59f074b2a8bf21d5 /lib/std/os/linux.zig | |
| parent | 226b801830857a9075fdd8180739105bb73eed0e (diff) | |
| download | zig-a6fb6dcfc96ad63f9a21110165728da0b8311660.tar.gz zig-a6fb6dcfc96ad63f9a21110165728da0b8311660.zip | |
linux: Correct pread64 syscall for ARM/MIPS
Closes #4615
Diffstat (limited to 'lib/std/os/linux.zig')
| -rw-r--r-- | lib/std/os/linux.zig | 37 |
1 files changed, 28 insertions, 9 deletions
diff --git a/lib/std/os/linux.zig b/lib/std/os/linux.zig index c2fc06bc9b..238d605360 100644 --- a/lib/std/os/linux.zig +++ b/lib/std/os/linux.zig @@ -39,6 +39,13 @@ pub fn getauxval(index: usize) usize { return 0; } +// Some architectures require 64bit parameters for some syscalls to be passed in +// even-aligned register pair +const require_aligned_register_pair = // + comptime builtin.arch.isMIPS() or + comptime builtin.arch.isARM() or + comptime builtin.arch.isThumb(); + /// Get the errno from a syscall return value, or 0 for no error. pub fn getErrno(r: usize) u12 { const signed_r = @bitCast(isize, r); @@ -318,14 +325,26 @@ pub fn symlinkat(existing: [*:0]const u8, newfd: i32, newpath: [*:0]const u8) us pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: u64) usize { if (@hasDecl(@This(), "SYS_pread64")) { - return syscall5( - SYS_pread64, - @bitCast(usize, @as(isize, fd)), - @ptrToInt(buf), - count, - @truncate(usize, offset), - @truncate(usize, offset >> 32), - ); + if (require_aligned_register_pair) { + return syscall6( + SYS_pread64, + @bitCast(usize, @as(isize, fd)), + @ptrToInt(buf), + count, + 0, + @truncate(usize, offset), + @truncate(usize, offset >> 32), + ); + } else { + return syscall5( + SYS_pread64, + @bitCast(usize, @as(isize, fd)), + @ptrToInt(buf), + count, + @truncate(usize, offset), + @truncate(usize, offset >> 32), + ); + } } else { return syscall4(SYS_pread, @bitCast(usize, @as(isize, fd)), @ptrToInt(buf), count, offset); } @@ -344,7 +363,7 @@ pub fn faccessat(dirfd: i32, path: [*:0]const u8, mode: u32, flags: u32) usize { } pub fn pipe(fd: *[2]i32) usize { - if (builtin.arch == .mipsel) { + if (comptime builtin.arch.isMIPS()) { return syscall_pipe(fd); } else if (@hasDecl(@This(), "SYS_pipe")) { return syscall1(SYS_pipe, @ptrToInt(fd)); |
