diff --git a/lib/std/os/linux.zig b/lib/std/os/linux.zig index aeaf6f2a53eb961078106775ecb4aad7b89addef..4f45396e1adac4ed14e752a1359365420e8e8114 100644 --- a/lib/std/os/linux.zig +++ b/lib/std/os/linux.zig @@ -80,6 +80,7 @@ pub const restore_rt = syscall_bits.restore_rt; pub const socketcall = syscall_bits.socketcall; pub const syscall_pipe = syscall_bits.syscall_pipe; pub const syscall_fork = syscall_bits.syscall_fork; +pub const syscall_lseek = syscall_bits.syscall_lseek; pub fn clone( func: *const fn (arg: usize) callconv(.c) u8, @@ -1809,7 +1810,7 @@ pub fn fchmodat2(fd: fd_t, path: [*:0]const u8, mode: mode_t, flags: u32) usize } /// Can only be called on 32 bit systems. For 64 bit see `lseek`. -pub fn llseek(fd: fd_t, offset: off_t, result: ?*off_t, whence: u32) usize { +pub fn llseek(fd: fd_t, offset: off_t, result: ?*off_t, whence: u32) u32 { // NOTE: The offset parameter splitting is independent from the target // endianness. return syscall5( @@ -1823,8 +1824,15 @@ pub fn llseek(fd: fd_t, offset: off_t, result: ?*off_t, whence: u32) usize { } /// Can only be called on 64 bit systems. For 32 bit see `llseek`. -pub fn lseek(fd: fd_t, offset: off_t, whence: u32) usize { - return syscall3(.lseek, @as(u32, @bitCast(fd)), @as(u64, @bitCast(offset)), whence); +pub fn lseek(fd: fd_t, offset: off_t, whence: u32) u64 { + return switch (builtin.abi) { + .gnuabin32, + .muslabin32, + .gnux32, + .muslx32, + => syscall_lseek(fd, offset, whence), + else => syscall3(.lseek, @as(u32, @bitCast(fd)), @as(u64, @bitCast(offset)), whence), + }; } pub fn exit(status: i32) noreturn { diff --git a/lib/std/os/linux/mipsn32.zig b/lib/std/os/linux/mipsn32.zig index 04b240af9fa7631a635024cc7847a62fd691023a..acb3a227d130e372731299e51148c8ff8365fa4d 100644 --- a/lib/std/os/linux/mipsn32.zig +++ b/lib/std/os/linux/mipsn32.zig @@ -163,6 +163,25 @@ pub fn syscall_pipe( : .{ .r1 = true, .r3 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .r13 = true, .r14 = true, .r15 = true, .r24 = true, .r25 = true, .hi = true, .lo = true, .memory = true }); } +pub fn syscall_lseek( + fd: std.os.linux.fd_t, + offset: std.os.linux.off_t, + whence: u32, +) u64 { + return asm volatile ( + \\ syscall + \\ beq $a3, $zero, 1f + \\ blez $v0, 1f + \\ dsubu $v0, $zero, $v0 + \\1: + : [ret] "={$2}" (-> u64), + : [number] "{$2}" (@intFromEnum(SYS.lseek)), + [fd] "{$4}" (@as(u32, @bitCast(fd))), + [offset] "{$5}" (@as(u64, @bitCast(offset))), + [whence] "{$6}" (whence), + : .{ .r1 = true, .r3 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .r13 = true, .r14 = true, .r15 = true, .r24 = true, .r25 = true, .hi = true, .lo = true, .memory = true }); +} + pub fn clone() callconv(.naked) u32 { // __clone(func, stack, flags, arg, ptid, tls, ctid) // a0, a1, a2, a3, a4, a5, a6 diff --git a/lib/std/os/linux/x32.zig b/lib/std/os/linux/x32.zig index d26833d9a17bdf40bd76d6477068152fc676dbb2..9cfe2f7899d9535aed61019997b94d99a5527668 100644 --- a/lib/std/os/linux/x32.zig +++ b/lib/std/os/linux/x32.zig @@ -109,6 +109,20 @@ pub fn syscall6( : .{ .rcx = true, .r11 = true, .memory = true }); } +pub fn syscall_lseek( + fd: std.os.linux.fd_t, + offset: std.os.linux.off_t, + whence: u32, +) u64 { + return asm volatile ("syscall" + : [ret] "={rax}" (-> u64), + : [number] "{rax}" (@intFromEnum(SYS.lseek)), + [fd] "{rdi}" (@as(u32, @bitCast(fd))), + [offset] "{rsi}" (@as(u64, @bitCast(offset))), + [whence] "{rdx}" (whence), + : .{ .rcx = true, .r11 = true, .memory = true }); +} + pub fn clone() callconv(.naked) u32 { asm volatile ( \\ movl $0x40000038,%%eax // SYS_clone