master
  1const builtin = @import("builtin");
  2const std = @import("../../std.zig");
  3const SYS = std.os.linux.SYS;
  4
  5pub fn syscall0(number: SYS) u64 {
  6    return asm volatile (
  7        \\ syscall 0
  8        : [ret] "={$r4}" (-> u64),
  9        : [number] "{$r11}" (@intFromEnum(number)),
 10        : .{ .r12 = true, .r13 = true, .r14 = true, .r15 = true, .r16 = true, .r17 = true, .r18 = true, .r19 = true, .r20 = true, .memory = true });
 11}
 12
 13pub fn syscall1(number: SYS, arg1: u64) u64 {
 14    return asm volatile (
 15        \\ syscall 0
 16        : [ret] "={$r4}" (-> u64),
 17        : [number] "{$r11}" (@intFromEnum(number)),
 18          [arg1] "{$r4}" (arg1),
 19        : .{ .r12 = true, .r13 = true, .r14 = true, .r15 = true, .r16 = true, .r17 = true, .r18 = true, .r19 = true, .r20 = true, .memory = true });
 20}
 21
 22pub fn syscall2(number: SYS, arg1: u64, arg2: u64) u64 {
 23    return asm volatile (
 24        \\ syscall 0
 25        : [ret] "={$r4}" (-> u64),
 26        : [number] "{$r11}" (@intFromEnum(number)),
 27          [arg1] "{$r4}" (arg1),
 28          [arg2] "{$r5}" (arg2),
 29        : .{ .r12 = true, .r13 = true, .r14 = true, .r15 = true, .r16 = true, .r17 = true, .r18 = true, .r19 = true, .r20 = true, .memory = true });
 30}
 31
 32pub fn syscall3(number: SYS, arg1: u64, arg2: u64, arg3: u64) u64 {
 33    return asm volatile (
 34        \\ syscall 0
 35        : [ret] "={$r4}" (-> u64),
 36        : [number] "{$r11}" (@intFromEnum(number)),
 37          [arg1] "{$r4}" (arg1),
 38          [arg2] "{$r5}" (arg2),
 39          [arg3] "{$r6}" (arg3),
 40        : .{ .r12 = true, .r13 = true, .r14 = true, .r15 = true, .r16 = true, .r17 = true, .r18 = true, .r19 = true, .r20 = true, .memory = true });
 41}
 42
 43pub fn syscall4(number: SYS, arg1: u64, arg2: u64, arg3: u64, arg4: u64) u64 {
 44    return asm volatile (
 45        \\ syscall 0
 46        : [ret] "={$r4}" (-> u64),
 47        : [number] "{$r11}" (@intFromEnum(number)),
 48          [arg1] "{$r4}" (arg1),
 49          [arg2] "{$r5}" (arg2),
 50          [arg3] "{$r6}" (arg3),
 51          [arg4] "{$r7}" (arg4),
 52        : .{ .r12 = true, .r13 = true, .r14 = true, .r15 = true, .r16 = true, .r17 = true, .r18 = true, .r19 = true, .r20 = true, .memory = true });
 53}
 54
 55pub fn syscall5(number: SYS, arg1: u64, arg2: u64, arg3: u64, arg4: u64, arg5: u64) u64 {
 56    return asm volatile (
 57        \\ syscall 0
 58        : [ret] "={$r4}" (-> u64),
 59        : [number] "{$r11}" (@intFromEnum(number)),
 60          [arg1] "{$r4}" (arg1),
 61          [arg2] "{$r5}" (arg2),
 62          [arg3] "{$r6}" (arg3),
 63          [arg4] "{$r7}" (arg4),
 64          [arg5] "{$r8}" (arg5),
 65        : .{ .r12 = true, .r13 = true, .r14 = true, .r15 = true, .r16 = true, .r17 = true, .r18 = true, .r19 = true, .r20 = true, .memory = true });
 66}
 67
 68pub fn syscall6(
 69    number: SYS,
 70    arg1: u64,
 71    arg2: u64,
 72    arg3: u64,
 73    arg4: u64,
 74    arg5: u64,
 75    arg6: u64,
 76) u64 {
 77    return asm volatile (
 78        \\ syscall 0
 79        : [ret] "={$r4}" (-> u64),
 80        : [number] "{$r11}" (@intFromEnum(number)),
 81          [arg1] "{$r4}" (arg1),
 82          [arg2] "{$r5}" (arg2),
 83          [arg3] "{$r6}" (arg3),
 84          [arg4] "{$r7}" (arg4),
 85          [arg5] "{$r8}" (arg5),
 86          [arg6] "{$r9}" (arg6),
 87        : .{ .r12 = true, .r13 = true, .r14 = true, .r15 = true, .r16 = true, .r17 = true, .r18 = true, .r19 = true, .r20 = true, .memory = true });
 88}
 89
 90pub fn clone() callconv(.naked) u64 {
 91    // __clone(func, stack, flags, arg, ptid, tls, ctid)
 92    //           a0,    a1,    a2,  a3,   a4,  a5,   a6
 93    // sys_clone(flags, stack, ptid, ctid, tls)
 94    //              a0,    a1,   a2,   a3,  a4
 95    asm volatile (
 96        \\ bstrins.d $a1, $zero, 3, 0   # stack to 16 align
 97        \\
 98        \\ # Save function pointer and argument pointer on new thread stack
 99        \\ addi.d  $a1, $a1, -16
100        \\ st.d    $a0, $a1, 0     # save function pointer
101        \\ st.d    $a3, $a1, 8     # save argument pointer
102        \\ or      $a0, $a2, $zero
103        \\ or      $a2, $a4, $zero
104        \\ or      $a3, $a6, $zero
105        \\ or      $a4, $a5, $zero
106        \\ ori     $a7, $zero, 220 # SYS_clone
107        \\ syscall 0               # call clone
108        \\
109        \\ beqz    $a0, 1f         # whether child process
110        \\ jirl    $zero, $ra, 0   # parent process return
111        \\1:
112    );
113    if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (
114        \\ .cfi_undefined 1
115    );
116    asm volatile (
117        \\ move    $fp, $zero
118        \\ move    $ra, $zero
119        \\
120        \\ ld.d    $t8, $sp, 0     # function pointer
121        \\ ld.d    $a0, $sp, 8     # argument pointer
122        \\ jirl    $ra, $t8, 0     # call the user's function
123        \\ ori     $a7, $zero, 93  # SYS_exit
124        \\ syscall 0               # child process exit
125    );
126}
127
128pub const blksize_t = i32;
129pub const nlink_t = u32;
130pub const time_t = i64;
131pub const mode_t = u32;
132pub const off_t = i64;
133pub const ino_t = u64;
134pub const dev_t = u32;
135pub const blkcnt_t = i64;
136
137// The `stat` definition used by the Linux kernel.
138pub const Stat = extern struct {
139    dev: dev_t,
140    ino: ino_t,
141    mode: mode_t,
142    nlink: nlink_t,
143    uid: std.os.linux.uid_t,
144    gid: std.os.linux.gid_t,
145    rdev: dev_t,
146    _pad1: u64,
147    size: off_t,
148    blksize: blksize_t,
149    _pad2: i32,
150    blocks: blkcnt_t,
151    atim: std.os.linux.timespec,
152    mtim: std.os.linux.timespec,
153    ctim: std.os.linux.timespec,
154    _pad3: [2]u32,
155
156    pub fn atime(self: @This()) std.os.linux.timespec {
157        return self.atim;
158    }
159
160    pub fn mtime(self: @This()) std.os.linux.timespec {
161        return self.mtim;
162    }
163
164    pub fn ctime(self: @This()) std.os.linux.timespec {
165        return self.ctim;
166    }
167};
168
169pub const VDSO = struct {
170    pub const CGT_SYM = "__vdso_clock_gettime";
171    pub const CGT_VER = "LINUX_5.10";
172};