1const std = @import("../../std.zig");
2const maxInt = std.math.maxInt;
3const linux = std.os.linux;
4const iovec = std.os.iovec;
5const iovec_const = std.os.iovec_const;
6const socklen_t = linux.socklen_t;
7const stack_t = linux.stack_t;
8const sigset_t = linux.sigset_t;
9const uid_t = linux.uid_t;
10const gid_t = linux.gid_t;
11const pid_t = linux.pid_t;
12const sockaddr = linux.sockaddr;
13const timespec = linux.timespec;
14
15pub fn syscall0(number: SYS) usize {
16    return asm volatile ("svc #0"
17        : [ret] "={r0}" (-> usize),
18        : [number] "{r7}" (@enumToInt(number)),
19        : "memory"
20    );
21}
22
23pub fn syscall1(number: SYS, arg1: usize) usize {
24    return asm volatile ("svc #0"
25        : [ret] "={r0}" (-> usize),
26        : [number] "{r7}" (@enumToInt(number)),
27          [arg1] "{r0}" (arg1),
28        : "memory"
29    );
30}
31
32pub fn syscall2(number: SYS, arg1: usize, arg2: usize) usize {
33    return asm volatile ("svc #0"
34        : [ret] "={r0}" (-> usize),
35        : [number] "{r7}" (@enumToInt(number)),
36          [arg1] "{r0}" (arg1),
37          [arg2] "{r1}" (arg2),
38        : "memory"
39    );
40}
41
42pub fn syscall3(number: SYS, arg1: usize, arg2: usize, arg3: usize) usize {
43    return asm volatile ("svc #0"
44        : [ret] "={r0}" (-> usize),
45        : [number] "{r7}" (@enumToInt(number)),
46          [arg1] "{r0}" (arg1),
47          [arg2] "{r1}" (arg2),
48          [arg3] "{r2}" (arg3),
49        : "memory"
50    );
51}
52
53pub fn syscall4(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize {
54    return asm volatile ("svc #0"
55        : [ret] "={r0}" (-> usize),
56        : [number] "{r7}" (@enumToInt(number)),
57          [arg1] "{r0}" (arg1),
58          [arg2] "{r1}" (arg2),
59          [arg3] "{r2}" (arg3),
60          [arg4] "{r3}" (arg4),
61        : "memory"
62    );
63}
64
65pub fn syscall5(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize, arg5: usize) usize {
66    return asm volatile ("svc #0"
67        : [ret] "={r0}" (-> usize),
68        : [number] "{r7}" (@enumToInt(number)),
69          [arg1] "{r0}" (arg1),
70          [arg2] "{r1}" (arg2),
71          [arg3] "{r2}" (arg3),
72          [arg4] "{r3}" (arg4),
73          [arg5] "{r4}" (arg5),
74        : "memory"
75    );
76}
77
78pub fn syscall6(
79    number: SYS,
80    arg1: usize,
81    arg2: usize,
82    arg3: usize,
83    arg4: usize,
84    arg5: usize,
85    arg6: usize,
86) usize {
87    return asm volatile ("svc #0"
88        : [ret] "={r0}" (-> usize),
89        : [number] "{r7}" (@enumToInt(number)),
90          [arg1] "{r0}" (arg1),
91          [arg2] "{r1}" (arg2),
92          [arg3] "{r2}" (arg3),
93          [arg4] "{r3}" (arg4),
94          [arg5] "{r4}" (arg5),
95          [arg6] "{r5}" (arg6),
96        : "memory"
97    );
98}
99
100/// This matches the libc clone function.
101pub extern fn clone(
102    func: fn (arg: usize) callconv(.C) u8,
103    stack: usize,
104    flags: u32,
105    arg: usize,
106    ptid: *i32,
107    tls: usize,
108    ctid: *i32,
109) usize;
110
111pub fn restore() callconv(.Naked) void {
112    return asm volatile ("svc #0"
113        :
114        : [number] "{r7}" (@enumToInt(SYS.sigreturn)),
115        : "memory"
116    );
117}
118
119pub fn restore_rt() callconv(.Naked) void {
120    return asm volatile ("svc #0"
121        :
122        : [number] "{r7}" (@enumToInt(SYS.rt_sigreturn)),
123        : "memory"
124    );
125}
126
127pub const SYS = enum(usize) {
128    restart_syscall = 0,
129    exit = 1,
130    fork = 2,
131    read = 3,
132    write = 4,
133    open = 5,
134    close = 6,
135    creat = 8,
136    link = 9,
137    unlink = 10,
138    execve = 11,
139    chdir = 12,
140    mknod = 14,
141    chmod = 15,
142    lchown = 16,
143    lseek = 19,
144    getpid = 20,
145    mount = 21,
146    setuid = 23,
147    getuid = 24,
148    ptrace = 26,
149    pause = 29,
150    access = 33,
151    nice = 34,
152    sync = 36,
153    kill = 37,
154    rename = 38,
155    mkdir = 39,
156    rmdir = 40,
157    dup = 41,
158    pipe = 42,
159    times = 43,
160    brk = 45,
161    setgid = 46,
162    getgid = 47,
163    geteuid = 49,
164    getegid = 50,
165    acct = 51,
166    umount2 = 52,
167    ioctl = 54,
168    fcntl = 55,
169    setpgid = 57,
170    umask = 60,
171    chroot = 61,
172    ustat = 62,
173    dup2 = 63,
174    getppid = 64,
175    getpgrp = 65,
176    setsid = 66,
177    sigaction = 67,
178    setreuid = 70,
179    setregid = 71,
180    sigsuspend = 72,
181    sigpending = 73,
182    sethostname = 74,
183    setrlimit = 75,
184    getrusage = 77,
185    gettimeofday = 78,
186    settimeofday = 79,
187    getgroups = 80,
188    setgroups = 81,
189    symlink = 83,
190    readlink = 85,
191    uselib = 86,
192    swapon = 87,
193    reboot = 88,
194    munmap = 91,
195    truncate = 92,
196    ftruncate = 93,
197    fchmod = 94,
198    fchown = 95,
199    getpriority = 96,
200    setpriority = 97,
201    statfs = 99,
202    fstatfs = 100,
203    syslog = 103,
204    setitimer = 104,
205    getitimer = 105,
206    stat = 106,
207    lstat = 107,
208    fstat = 108,
209    vhangup = 111,
210    wait4 = 114,
211    swapoff = 115,
212    sysinfo = 116,
213    fsync = 118,
214    sigreturn = 119,
215    clone = 120,
216    setdomainname = 121,
217    uname = 122,
218    adjtimex = 124,
219    mprotect = 125,
220    sigprocmask = 126,
221    init_module = 128,
222    delete_module = 129,
223    quotactl = 131,
224    getpgid = 132,
225    fchdir = 133,
226    bdflush = 134,
227    sysfs = 135,
228    personality = 136,
229    setfsuid = 138,
230    setfsgid = 139,
231    _llseek = 140,
232    getdents = 141,
233    _newselect = 142,
234    flock = 143,
235    msync = 144,
236    readv = 145,
237    writev = 146,
238    getsid = 147,
239    fdatasync = 148,
240    _sysctl = 149,
241    mlock = 150,
242    munlock = 151,
243    mlockall = 152,
244    munlockall = 153,
245    sched_setparam = 154,
246    sched_getparam = 155,
247    sched_setscheduler = 156,
248    sched_getscheduler = 157,
249    sched_yield = 158,
250    sched_get_priority_max = 159,
251    sched_get_priority_min = 160,
252    sched_rr_get_interval = 161,
253    nanosleep = 162,
254    mremap = 163,
255    setresuid = 164,
256    getresuid = 165,
257    poll = 168,
258    nfsservctl = 169,
259    setresgid = 170,
260    getresgid = 171,
261    prctl = 172,
262    rt_sigreturn = 173,
263    rt_sigaction = 174,
264    rt_sigprocmask = 175,
265    rt_sigpending = 176,
266    rt_sigtimedwait = 177,
267    rt_sigqueueinfo = 178,
268    rt_sigsuspend = 179,
269    pread64 = 180,
270    pwrite64 = 181,
271    chown = 182,
272    getcwd = 183,
273    capget = 184,
274    capset = 185,
275    sigaltstack = 186,
276    sendfile = 187,
277    vfork = 190,
278    ugetrlimit = 191,
279    mmap2 = 192,
280    truncate64 = 193,
281    ftruncate64 = 194,
282    stat64 = 195,
283    lstat64 = 196,
284    fstat64 = 197,
285    lchown32 = 198,
286    getuid32 = 199,
287    getgid32 = 200,
288    geteuid32 = 201,
289    getegid32 = 202,
290    setreuid32 = 203,
291    setregid32 = 204,
292    getgroups32 = 205,
293    setgroups32 = 206,
294    fchown32 = 207,
295    setresuid32 = 208,
296    getresuid32 = 209,
297    setresgid32 = 210,
298    getresgid32 = 211,
299    chown32 = 212,
300    setuid32 = 213,
301    setgid32 = 214,
302    setfsuid32 = 215,
303    setfsgid32 = 216,
304    getdents64 = 217,
305    pivot_root = 218,
306    mincore = 219,
307    madvise = 220,
308    fcntl64 = 221,
309    gettid = 224,
310    readahead = 225,
311    setxattr = 226,
312    lsetxattr = 227,
313    fsetxattr = 228,
314    getxattr = 229,
315    lgetxattr = 230,
316    fgetxattr = 231,
317    listxattr = 232,
318    llistxattr = 233,
319    flistxattr = 234,
320    removexattr = 235,
321    lremovexattr = 236,
322    fremovexattr = 237,
323    tkill = 238,
324    sendfile64 = 239,
325    futex = 240,
326    sched_setaffinity = 241,
327    sched_getaffinity = 242,
328    io_setup = 243,
329    io_destroy = 244,
330    io_getevents = 245,
331    io_submit = 246,
332    io_cancel = 247,
333    exit_group = 248,
334    lookup_dcookie = 249,
335    epoll_create = 250,
336    epoll_ctl = 251,
337    epoll_wait = 252,
338    remap_file_pages = 253,
339    set_tid_address = 256,
340    timer_create = 257,
341    timer_settime = 258,
342    timer_gettime = 259,
343    timer_getoverrun = 260,
344    timer_delete = 261,
345    clock_settime = 262,
346    clock_gettime = 263,
347    clock_getres = 264,
348    clock_nanosleep = 265,
349    statfs64 = 266,
350    fstatfs64 = 267,
351    tgkill = 268,
352    utimes = 269,
353    fadvise64_64 = 270,
354    pciconfig_iobase = 271,
355    pciconfig_read = 272,
356    pciconfig_write = 273,
357    mq_open = 274,
358    mq_unlink = 275,
359    mq_timedsend = 276,
360    mq_timedreceive = 277,
361    mq_notify = 278,
362    mq_getsetattr = 279,
363    waitid = 280,
364    socket = 281,
365    bind = 282,
366    connect = 283,
367    listen = 284,
368    accept = 285,
369    getsockname = 286,
370    getpeername = 287,
371    socketpair = 288,
372    send = 289,
373    sendto = 290,
374    recv = 291,
375    recvfrom = 292,
376    shutdown = 293,
377    setsockopt = 294,
378    getsockopt = 295,
379    sendmsg = 296,
380    recvmsg = 297,
381    semop = 298,
382    semget = 299,
383    semctl = 300,
384    msgsnd = 301,
385    msgrcv = 302,
386    msgget = 303,
387    msgctl = 304,
388    shmat = 305,
389    shmdt = 306,
390    shmget = 307,
391    shmctl = 308,
392    add_key = 309,
393    request_key = 310,
394    keyctl = 311,
395    semtimedop = 312,
396    vserver = 313,
397    ioprio_set = 314,
398    ioprio_get = 315,
399    inotify_init = 316,
400    inotify_add_watch = 317,
401    inotify_rm_watch = 318,
402    mbind = 319,
403    get_mempolicy = 320,
404    set_mempolicy = 321,
405    openat = 322,
406    mkdirat = 323,
407    mknodat = 324,
408    fchownat = 325,
409    futimesat = 326,
410    fstatat64 = 327,
411    unlinkat = 328,
412    renameat = 329,
413    linkat = 330,
414    symlinkat = 331,
415    readlinkat = 332,
416    fchmodat = 333,
417    faccessat = 334,
418    pselect6 = 335,
419    ppoll = 336,
420    unshare = 337,
421    set_robust_list = 338,
422    get_robust_list = 339,
423    splice = 340,
424    sync_file_range = 341,
425    tee = 342,
426    vmsplice = 343,
427    move_pages = 344,
428    getcpu = 345,
429    epoll_pwait = 346,
430    kexec_load = 347,
431    utimensat = 348,
432    signalfd = 349,
433    timerfd_create = 350,
434    eventfd = 351,
435    fallocate = 352,
436    timerfd_settime = 353,
437    timerfd_gettime = 354,
438    signalfd4 = 355,
439    eventfd2 = 356,
440    epoll_create1 = 357,
441    dup3 = 358,
442    pipe2 = 359,
443    inotify_init1 = 360,
444    preadv = 361,
445    pwritev = 362,
446    rt_tgsigqueueinfo = 363,
447    perf_event_open = 364,
448    recvmmsg = 365,
449    accept4 = 366,
450    fanotify_init = 367,
451    fanotify_mark = 368,
452    prlimit64 = 369,
453    name_to_handle_at = 370,
454    open_by_handle_at = 371,
455    clock_adjtime = 372,
456    syncfs = 373,
457    sendmmsg = 374,
458    setns = 375,
459    process_vm_readv = 376,
460    process_vm_writev = 377,
461    kcmp = 378,
462    finit_module = 379,
463    sched_setattr = 380,
464    sched_getattr = 381,
465    renameat2 = 382,
466    seccomp = 383,
467    getrandom = 384,
468    memfd_create = 385,
469    bpf = 386,
470    execveat = 387,
471    userfaultfd = 388,
472    membarrier = 389,
473    mlock2 = 390,
474    copy_file_range = 391,
475    preadv2 = 392,
476    pwritev2 = 393,
477    pkey_mprotect = 394,
478    pkey_alloc = 395,
479    pkey_free = 396,
480    statx = 397,
481    rseq = 398,
482    io_pgetevents = 399,
483    migrate_pages = 400,
484    kexec_file_load = 401,
485    clock_gettime64 = 403,
486    clock_settime64 = 404,
487    clock_adjtime64 = 405,
488    clock_getres_time64 = 406,
489    clock_nanosleep_time64 = 407,
490    timer_gettime64 = 408,
491    timer_settime64 = 409,
492    timerfd_gettime64 = 410,
493    timerfd_settime64 = 411,
494    utimensat_time64 = 412,
495    pselect6_time64 = 413,
496    ppoll_time64 = 414,
497    io_pgetevents_time64 = 416,
498    recvmmsg_time64 = 417,
499    mq_timedsend_time64 = 418,
500    mq_timedreceive_time64 = 419,
501    semtimedop_time64 = 420,
502    rt_sigtimedwait_time64 = 421,
503    futex_time64 = 422,
504    sched_rr_get_interval_time64 = 423,
505    pidfd_send_signal = 424,
506    io_uring_setup = 425,
507    io_uring_enter = 426,
508    io_uring_register = 427,
509    open_tree = 428,
510    move_mount = 429,
511    fsopen = 430,
512    fsconfig = 431,
513    fsmount = 432,
514    fspick = 433,
515    pidfd_open = 434,
516    clone3 = 435,
517    close_range = 436,
518    openat2 = 437,
519    pidfd_getfd = 438,
520    faccessat2 = 439,
521    process_madvise = 440,
522    epoll_pwait2 = 441,
523    mount_setattr = 442,
524    landlock_create_ruleset = 444,
525    landlock_add_rule = 445,
526    landlock_restrict_self = 446,
527
528    breakpoint = 0x0f0001,
529    cacheflush = 0x0f0002,
530    usr26 = 0x0f0003,
531    usr32 = 0x0f0004,
532    set_tls = 0x0f0005,
533    get_tls = 0x0f0006,
534
535    _,
536};
537
538pub const MMAP2_UNIT = 4096;
539
540pub const O = struct {
541    pub const CREAT = 0o100;
542    pub const EXCL = 0o200;
543    pub const NOCTTY = 0o400;
544    pub const TRUNC = 0o1000;
545    pub const APPEND = 0o2000;
546    pub const NONBLOCK = 0o4000;
547    pub const DSYNC = 0o10000;
548    pub const SYNC = 0o4010000;
549    pub const RSYNC = 0o4010000;
550    pub const DIRECTORY = 0o40000;
551    pub const NOFOLLOW = 0o100000;
552    pub const CLOEXEC = 0o2000000;
553
554    pub const ASYNC = 0o20000;
555    pub const DIRECT = 0o200000;
556    pub const LARGEFILE = 0o400000;
557    pub const NOATIME = 0o1000000;
558    pub const PATH = 0o10000000;
559    pub const TMPFILE = 0o20040000;
560    pub const NDELAY = NONBLOCK;
561};
562
563pub const F = struct {
564    pub const DUPFD = 0;
565    pub const GETFD = 1;
566    pub const SETFD = 2;
567    pub const GETFL = 3;
568    pub const SETFL = 4;
569
570    pub const SETOWN = 8;
571    pub const GETOWN = 9;
572    pub const SETSIG = 10;
573    pub const GETSIG = 11;
574
575    pub const GETLK = 12;
576    pub const SETLK = 13;
577    pub const SETLKW = 14;
578
579    pub const RDLCK = 0;
580    pub const WRLCK = 1;
581    pub const UNLCK = 2;
582
583    pub const SETOWN_EX = 15;
584    pub const GETOWN_EX = 16;
585
586    pub const GETOWNER_UIDS = 17;
587};
588
589pub const LOCK = struct {
590    pub const SH = 1;
591    pub const EX = 2;
592    pub const UN = 8;
593    pub const NB = 4;
594};
595
596pub const MAP = struct {
597    /// stack-like segment
598    pub const GROWSDOWN = 0x0100;
599    /// ETXTBSY
600    pub const DENYWRITE = 0x0800;
601    /// mark it as an executable
602    pub const EXECUTABLE = 0x1000;
603    /// pages are locked
604    pub const LOCKED = 0x2000;
605    /// don't check for reservations
606    pub const NORESERVE = 0x4000;
607};
608
609pub const VDSO = struct {
610    pub const CGT_SYM = "__vdso_clock_gettime";
611    pub const CGT_VER = "LINUX_2.6";
612};
613
614pub const HWCAP = struct {
615    pub const SWP = 1 << 0;
616    pub const HALF = 1 << 1;
617    pub const THUMB = 1 << 2;
618    pub const @"26BIT" = 1 << 3;
619    pub const FAST_MULT = 1 << 4;
620    pub const FPA = 1 << 5;
621    pub const VFP = 1 << 6;
622    pub const EDSP = 1 << 7;
623    pub const JAVA = 1 << 8;
624    pub const IWMMXT = 1 << 9;
625    pub const CRUNCH = 1 << 10;
626    pub const THUMBEE = 1 << 11;
627    pub const NEON = 1 << 12;
628    pub const VFPv3 = 1 << 13;
629    pub const VFPv3D16 = 1 << 14;
630    pub const TLS = 1 << 15;
631    pub const VFPv4 = 1 << 16;
632    pub const IDIVA = 1 << 17;
633    pub const IDIVT = 1 << 18;
634    pub const VFPD32 = 1 << 19;
635    pub const IDIV = IDIVA | IDIVT;
636    pub const LPAE = 1 << 20;
637    pub const EVTSTRM = 1 << 21;
638};
639
640pub const Flock = extern struct {
641    l_type: i16,
642    l_whence: i16,
643    __pad0: [4]u8,
644    l_start: off_t,
645    l_len: off_t,
646    l_pid: pid_t,
647    __unused: [4]u8,
648};
649
650pub const msghdr = extern struct {
651    msg_name: ?*sockaddr,
652    msg_namelen: socklen_t,
653    msg_iov: [*]iovec,
654    msg_iovlen: i32,
655    msg_control: ?*anyopaque,
656    msg_controllen: socklen_t,
657    msg_flags: i32,
658};
659
660pub const msghdr_const = extern struct {
661    msg_name: ?*const sockaddr,
662    msg_namelen: socklen_t,
663    msg_iov: [*]iovec_const,
664    msg_iovlen: i32,
665    msg_control: ?*anyopaque,
666    msg_controllen: socklen_t,
667    msg_flags: i32,
668};
669
670pub const blksize_t = i32;
671pub const nlink_t = u32;
672pub const time_t = isize;
673pub const mode_t = u32;
674pub const off_t = i64;
675pub const ino_t = u64;
676pub const dev_t = u64;
677pub const blkcnt_t = i64;
678
679// The `stat` definition used by the Linux kernel.
680pub const Stat = extern struct {
681    dev: dev_t,
682    __dev_padding: u32,
683    __ino_truncated: u32,
684    mode: mode_t,
685    nlink: nlink_t,
686    uid: uid_t,
687    gid: gid_t,
688    rdev: dev_t,
689    __rdev_padding: u32,
690    size: off_t,
691    blksize: blksize_t,
692    blocks: blkcnt_t,
693    atim: timespec,
694    mtim: timespec,
695    ctim: timespec,
696    ino: ino_t,
697
698    pub fn atime(self: @This()) timespec {
699        return self.atim;
700    }
701
702    pub fn mtime(self: @This()) timespec {
703        return self.mtim;
704    }
705
706    pub fn ctime(self: @This()) timespec {
707        return self.ctim;
708    }
709};
710
711pub const timeval = extern struct {
712    tv_sec: i32,
713    tv_usec: i32,
714};
715
716pub const timezone = extern struct {
717    tz_minuteswest: i32,
718    tz_dsttime: i32,
719};
720
721pub const mcontext_t = extern struct {
722    trap_no: usize,
723    error_code: usize,
724    oldmask: usize,
725    arm_r0: usize,
726    arm_r1: usize,
727    arm_r2: usize,
728    arm_r3: usize,
729    arm_r4: usize,
730    arm_r5: usize,
731    arm_r6: usize,
732    arm_r7: usize,
733    arm_r8: usize,
734    arm_r9: usize,
735    arm_r10: usize,
736    arm_fp: usize,
737    arm_ip: usize,
738    arm_sp: usize,
739    arm_lr: usize,
740    arm_pc: usize,
741    arm_cpsr: usize,
742    fault_address: usize,
743};
744
745pub const ucontext_t = extern struct {
746    flags: usize,
747    link: *ucontext_t,
748    stack: stack_t,
749    mcontext: mcontext_t,
750    sigmask: sigset_t,
751    regspace: [64]u64,
752};
753
754pub const Elf_Symndx = u32;
755