| author | |
| committer | |
| log | 3f956f98903214a6a79a123d62c4084ea3ba49f9 |
| tree | 84639c6497a69dd67debd86e4f63e60e4b02b7a1 |
| parent | e74fd3ce555c675235fa65fa3647caeb4757b4cd |
| signature |
This is the one syscall that returns a u64 despite usize == u32 in these ABIs.
Rather than huge API churn for all return types in std.os.linux just to benefit
these incredibly niche ABIs, just special-case this particular syscall, as we do
with a few others depending on arch.3 files changed, 44 insertions(+), 3 deletions(-)
lib/std/os/linux.zig+11-3| ... | @@ -80,6 +80,7 @@ pub const restore_rt = syscall_bits.restore_rt; | ... | @@ -80,6 +80,7 @@ pub const restore_rt = syscall_bits.restore_rt; |
| 80 | pub const socketcall = syscall_bits.socketcall; | 80 | pub const socketcall = syscall_bits.socketcall; |
| 81 | pub const syscall_pipe = syscall_bits.syscall_pipe; | 81 | pub const syscall_pipe = syscall_bits.syscall_pipe; |
| 82 | pub const syscall_fork = syscall_bits.syscall_fork; | 82 | pub const syscall_fork = syscall_bits.syscall_fork; |
| 83 | pub const syscall_lseek = syscall_bits.syscall_lseek; | ||
| 83 | 84 | ||
| 84 | pub fn clone( | 85 | pub fn clone( |
| 85 | func: *const fn (arg: usize) callconv(.c) u8, | 86 | 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 | ... | @@ -1809,7 +1810,7 @@ pub fn fchmodat2(fd: fd_t, path: [*:0]const u8, mode: mode_t, flags: u32) usize |
| 1809 | } | 1810 | } |
| 1810 | 1811 | ||
| 1811 | /// Can only be called on 32 bit systems. For 64 bit see `lseek`. | 1812 | /// Can only be called on 32 bit systems. For 64 bit see `lseek`. |
| 1812 | pub fn llseek(fd: fd_t, offset: off_t, result: ?*off_t, whence: u32) usize { | 1813 | pub fn llseek(fd: fd_t, offset: off_t, result: ?*off_t, whence: u32) u32 { |
| 1813 | // NOTE: The offset parameter splitting is independent from the target | 1814 | // NOTE: The offset parameter splitting is independent from the target |
| 1814 | // endianness. | 1815 | // endianness. |
| 1815 | return syscall5( | 1816 | return syscall5( |
| ... | @@ -1823,8 +1824,15 @@ pub fn llseek(fd: fd_t, offset: off_t, result: ?*off_t, whence: u32) usize { | ... | @@ -1823,8 +1824,15 @@ pub fn llseek(fd: fd_t, offset: off_t, result: ?*off_t, whence: u32) usize { |
| 1823 | } | 1824 | } |
| 1824 | 1825 | ||
| 1825 | /// Can only be called on 64 bit systems. For 32 bit see `llseek`. | 1826 | /// Can only be called on 64 bit systems. For 32 bit see `llseek`. |
| 1826 | pub fn lseek(fd: fd_t, offset: off_t, whence: u32) usize { | 1827 | pub fn lseek(fd: fd_t, offset: off_t, whence: u32) u64 { |
| 1827 | return syscall3(.lseek, @as(u32, @bitCast(fd)), @as(u64, @bitCast(offset)), whence); | 1828 | return switch (builtin.abi) { |
| 1829 | .gnuabin32, | ||
| 1830 | .muslabin32, | ||
| 1831 | .gnux32, | ||
| 1832 | .muslx32, | ||
| 1833 | => syscall_lseek(fd, offset, whence), | ||
| 1834 | else => syscall3(.lseek, @as(u32, @bitCast(fd)), @as(u64, @bitCast(offset)), whence), | ||
| 1835 | }; | ||
| 1828 | } | 1836 | } |
| 1829 | 1837 | ||
| 1830 | pub fn exit(status: i32) noreturn { | 1838 | pub fn exit(status: i32) noreturn { |
lib/std/os/linux/mipsn32.zig+19| ... | @@ -163,6 +163,25 @@ pub fn syscall_pipe( | ... | @@ -163,6 +163,25 @@ pub fn syscall_pipe( |
| 163 | : .{ .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 }); | 163 | : .{ .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 }); |
| 164 | } | 164 | } |
| 165 | 165 | ||
| 166 | pub fn syscall_lseek( | ||
| 167 | fd: std.os.linux.fd_t, | ||
| 168 | offset: std.os.linux.off_t, | ||
| 169 | whence: u32, | ||
| 170 | ) u64 { | ||
| 171 | return asm volatile ( | ||
| 172 | \\ syscall | ||
| 173 | \\ beq $a3, $zero, 1f | ||
| 174 | \\ blez $v0, 1f | ||
| 175 | \\ dsubu $v0, $zero, $v0 | ||
| 176 | \\1: | ||
| 177 | : [ret] "={$2}" (-> u64), | ||
| 178 | : [number] "{$2}" (@intFromEnum(SYS.lseek)), | ||
| 179 | [fd] "{$4}" (@as(u32, @bitCast(fd))), | ||
| 180 | [offset] "{$5}" (@as(u64, @bitCast(offset))), | ||
| 181 | [whence] "{$6}" (whence), | ||
| 182 | : .{ .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 }); | ||
| 183 | } | ||
| 184 | |||
| 166 | pub fn clone() callconv(.naked) u32 { | 185 | pub fn clone() callconv(.naked) u32 { |
| 167 | // __clone(func, stack, flags, arg, ptid, tls, ctid) | 186 | // __clone(func, stack, flags, arg, ptid, tls, ctid) |
| 168 | // a0, a1, a2, a3, a4, a5, a6 | 187 | // a0, a1, a2, a3, a4, a5, a6 |
lib/std/os/linux/x32.zig+14| ... | @@ -109,6 +109,20 @@ pub fn syscall6( | ... | @@ -109,6 +109,20 @@ pub fn syscall6( |
| 109 | : .{ .rcx = true, .r11 = true, .memory = true }); | 109 | : .{ .rcx = true, .r11 = true, .memory = true }); |
| 110 | } | 110 | } |
| 111 | 111 | ||
| 112 | pub fn syscall_lseek( | ||
| 113 | fd: std.os.linux.fd_t, | ||
| 114 | offset: std.os.linux.off_t, | ||
| 115 | whence: u32, | ||
| 116 | ) u64 { | ||
| 117 | return asm volatile ("syscall" | ||
| 118 | : [ret] "={rax}" (-> u64), | ||
| 119 | : [number] "{rax}" (@intFromEnum(SYS.lseek)), | ||
| 120 | [fd] "{rdi}" (@as(u32, @bitCast(fd))), | ||
| 121 | [offset] "{rsi}" (@as(u64, @bitCast(offset))), | ||
| 122 | [whence] "{rdx}" (whence), | ||
| 123 | : .{ .rcx = true, .r11 = true, .memory = true }); | ||
| 124 | } | ||
| 125 | |||
| 112 | pub fn clone() callconv(.naked) u32 { | 126 | pub fn clone() callconv(.naked) u32 { |
| 113 | asm volatile ( | 127 | asm volatile ( |
| 114 | \\ movl $0x40000038,%%eax // SYS_clone | 128 | \\ movl $0x40000038,%%eax // SYS_clone |