linux: Correct pread64 syscall for ARM/MIPS

Closes #4615
This commit is contained in:
LemonBoy 2020-03-03 17:19:40 +01:00 committed by Andrew Kelley
parent 226b801830
commit a6fb6dcfc9
2 changed files with 28 additions and 13 deletions

View File

@ -39,6 +39,13 @@ pub fn getauxval(index: usize) usize {
return 0; 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. /// Get the errno from a syscall return value, or 0 for no error.
pub fn getErrno(r: usize) u12 { pub fn getErrno(r: usize) u12 {
const signed_r = @bitCast(isize, r); 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 { pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: u64) usize {
if (@hasDecl(@This(), "SYS_pread64")) { if (@hasDecl(@This(), "SYS_pread64")) {
return syscall5( if (require_aligned_register_pair) {
SYS_pread64, return syscall6(
@bitCast(usize, @as(isize, fd)), SYS_pread64,
@ptrToInt(buf), @bitCast(usize, @as(isize, fd)),
count, @ptrToInt(buf),
@truncate(usize, offset), count,
@truncate(usize, offset >> 32), 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 { } else {
return syscall4(SYS_pread, @bitCast(usize, @as(isize, fd)), @ptrToInt(buf), count, offset); 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 { pub fn pipe(fd: *[2]i32) usize {
if (builtin.arch == .mipsel) { if (comptime builtin.arch.isMIPS()) {
return syscall_pipe(fd); return syscall_pipe(fd);
} else if (@hasDecl(@This(), "SYS_pipe")) { } else if (@hasDecl(@This(), "SYS_pipe")) {
return syscall1(SYS_pipe, @ptrToInt(fd)); return syscall1(SYS_pipe, @ptrToInt(fd));

View File

@ -45,10 +45,6 @@ fn testThreadIdFn(thread_id: *Thread.Id) void {
} }
test "sendfile" { test "sendfile" {
if (std.Target.current.cpu.arch == .mipsel) {
// https://github.com/ziglang/zig/issues/4615
return error.SkipZigTest;
}
try fs.makePath(a, "os_test_tmp"); try fs.makePath(a, "os_test_tmp");
defer fs.deleteTree("os_test_tmp") catch {}; defer fs.deleteTree("os_test_tmp") catch {};