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