diff options
Diffstat (limited to 'v_windows/v/vlib/builtin/linux_bare/linux_syscalls.v')
-rw-r--r-- | v_windows/v/vlib/builtin/linux_bare/linux_syscalls.v | 433 |
1 files changed, 433 insertions, 0 deletions
diff --git a/v_windows/v/vlib/builtin/linux_bare/linux_syscalls.v b/v_windows/v/vlib/builtin/linux_bare/linux_syscalls.v new file mode 100644 index 0000000..b0b2c47 --- /dev/null +++ b/v_windows/v/vlib/builtin/linux_bare/linux_syscalls.v @@ -0,0 +1,433 @@ +module builtin + +enum SigIndex { + si_signo = 0x00 + si_code = 0x02 + si_pid = 0x04 + si_uid = 0x05 + si_status = 0x06 + si_size = 0x80 +} + +enum Signo { + sighup = 1 // Hangup. + sigint = 2 // Interactive attention signal. + sigquit = 3 // Quit. + sigill = 4 // Illegal instruction. + sigtrap = 5 // Trace/breakpoint trap. + sigabrt = 6 // Abnormal termination. + sigbus = 7 + sigfpe = 8 // Erroneous arithmetic operation. + sigkill = 9 // Killed. + sigusr1 = 10 + sigsegv = 11 // Invalid access to memory. + sigusr2 = 12 + sigpipe = 13 // Broken pipe. + sigalrm = 14 // Alarm clock. + sigterm = 15 // Termination request. + sigstkflt = 16 + sigchld = 17 + sigcont = 18 + sigstop = 19 + sigtstp = 20 + sigttin = 21 // Background read from control terminal. + sigttou = 22 // Background write to control terminal. + sigurg = 23 + sigxcpu = 24 // CPU time limit exceeded. + sigxfsz = 25 // File size limit exceeded. + sigvtalrm = 26 // Virtual timer expired. + sigprof = 27 // Profiling timer expired. + sigwinch = 28 + sigpoll = 29 + sigsys = 31 +} + +// List of all the errors returned by syscalls +enum Errno { + enoerror = 0x00000000 + eperm = 0x00000001 + enoent = 0x00000002 + esrch = 0x00000003 + eintr = 0x00000004 + eio = 0x00000005 + enxio = 0x00000006 + e2big = 0x00000007 + enoexec = 0x00000008 + ebadf = 0x00000009 + echild = 0x0000000a + eagain = 0x0000000b + enomem = 0x0000000c + eacces = 0x0000000d + efault = 0x0000000e + enotblk = 0x0000000f + ebusy = 0x00000010 + eexist = 0x00000011 + exdev = 0x00000012 + enodev = 0x00000013 + enotdir = 0x00000014 + eisdir = 0x00000015 + einval = 0x00000016 + enfile = 0x00000017 + emfile = 0x00000018 + enotty = 0x00000019 + etxtbsy = 0x0000001a + efbig = 0x0000001b + enospc = 0x0000001c + espipe = 0x0000001d + erofs = 0x0000001e + emlink = 0x0000001f + epipe = 0x00000020 + edom = 0x00000021 + erange = 0x00000022 +} + +enum MemProt { + prot_read = 0x1 + prot_write = 0x2 + prot_exec = 0x4 + prot_none = 0x0 + prot_growsdown = 0x01000000 + prot_growsup = 0x02000000 +} + +enum MapFlags { + map_shared = 0x01 + map_private = 0x02 + map_shared_validate = 0x03 + map_type = 0x0f + map_fixed = 0x10 + map_file = 0x00 + map_anonymous = 0x20 + map_huge_shift = 26 + map_huge_mask = 0x3f +} + +// const ( +// fcntlf_dupfd = 0x00000000 +// fcntlf_exlck = 0x00000004 +// fcntlf_getfd = 0x00000001 +// fcntlf_getfl = 0x00000003 +// fcntlf_getlk = 0x00000005 +// fcntlf_getlk64 = 0x0000000c +// fcntlf_getown = 0x00000009 +// fcntlf_getowner_uids = 0x00000011 +// fcntlf_getown_ex = 0x00000010 +// fcntlf_getsig = 0x0000000b +// fcntlf_ofd_getlk = 0x00000024 +// fcntlf_ofd_setlk = 0x00000025 +// fcntlf_ofd_setlkw = 0x00000026 +// fcntlf_owner_pgrp = 0x00000002 +// fcntlf_owner_pid = 0x00000001 +// fcntlf_owner_tid = 0x00000000 +// fcntlf_rdlck = 0x00000000 +// fcntlf_setfd = 0x00000002 +// fcntlf_setfl = 0x00000004 +// fcntlf_setlk = 0x00000006 +// fcntlf_setlk64 = 0x0000000d +// fcntlf_setlkw = 0x00000007 +// fcntlf_setlkw64 = 0x0000000e +// fcntlf_setown = 0x00000008 +// fcntlf_setown_ex = 0x0000000f +// fcntlf_setsig = 0x0000000a +// fcntlf_shlck = 0x00000008 +// fcntlf_unlck = 0x00000002 +// fcntlf_wrlck = 0x00000001 +// fcntllock_ex = 0x00000002 +// fcntllock_mand = 0x00000020 +// fcntllock_nb = 0x00000004 +// fcntllock_read = 0x00000040 +// fcntllock_rw = 0x000000c0 +// fcntllock_sh = 0x00000001 +// fcntllock_un = 0x00000008 +// fcntllock_write = 0x00000080 +// fcntlo_accmode = 0x00000003 +// fcntlo_append = 0x00000400 +// fcntlo_cloexec = 0x00080000 +// fcntlo_creat = 0x00000040 +// fcntlo_direct = 0x00004000 +// fcntlo_directory = 0x00010000 +// fcntlo_dsync = 0x00001000 +// fcntlo_excl = 0x00000080 +// fcntlo_largefile = 0x00008000 +// fcntlo_ndelay = 0x00000800 +// fcntlo_noatime = 0x00040000 +// fcntlo_noctty = 0x00000100 +// fcntlo_nofollow = 0x00020000 +// fcntlo_nonblock = 0x00000800 +// fcntlo_path = 0x00200000 +// fcntlo_rdonly = 0x00000000 +// fcntlo_rdwr = 0x00000002 +// fcntlo_trunc = 0x00000200 +// fcntlo_wronly = 0x00000001 +// ) + +/* +Paraphrased from "man 2 waitid" on Linux + + Upon successful return, waitid() fills in the + following fields of the siginfo_t structure + pointed to by infop: + + si_pid, offset 0x10, int index 0x04: + The process ID of the child. + + si_uid: offset 0x14, int index 0x05 + The real user ID of the child. + + si_signo: offset 0x00, int index 0x00 + Always set to SIGCHLD. + + si_status: ofset 0x18, int index 0x06 + 1 the exit status of the child, as given to _exit(2) + (or exit(3)) (sc_sys.cld_exited) + 2 the signal that caused the child to terminate, stop, + or continue. + 3 The si_code field can be used to determine how to + interpret this field. + + si_code, set to one of (enum Wi_si_code), offset 0x08, int index 0x02: + CLD_EXITED (child called _exit(2)); + CLD_KILLED (child killed by signal); + CLD_DUMPED (child killed by signal, and dumped core); + CLD_STOPPED (child stopped by signal); + CLD_TRAPPED (traced child has trapped); + CLD_CONTINUED (child continued by SIGCONT). +*/ + +const ( + wp_sys_wnohang = u64(0x00000001) + wp_sys_wuntraced = u64(0x00000002) + wp_sys_wstopped = u64(0x00000002) + wp_sys_wexited = u64(0x00000004) + wp_sys_wcontinued = u64(0x00000008) + wp_sys_wnowait = u64(0x01000000) // don't reap, just poll status. + wp_sys___wnothread = u64(0x20000000) // don't wait on children of other threads in this group + wp_sys___wall = u64(0x40000000) // wait on all children, regardless of type + wp_sys___wclone = u64(0x80000000) // wait only on non-sigchld children +) + +// First argument to waitid: +enum WiWhich { + p_all = 0 + p_pid = 1 + p_pgid = 2 +} + +enum WiSiCode { + cld_exited = 1 // child has exited + cld_killed = 2 // child was killed + cld_dumped = 3 // child terminated abnormally + cld_trapped = 4 // traced child has trapped + cld_stopped = 5 // child has stopped + cld_continued = 6 // stopped child has continued +} + +fn split_int_errno(rc_in u64) (i64, Errno) { + rc := i64(rc_in) + if rc < 0 { + return i64(-1), Errno(-rc) + } + return rc, Errno.enoerror +} + +// 0 sys_read +fn sys_read(fd i64, buf &byte, count u64) (i64, Errno) { + return split_int_errno(sys_call3(0, u64(fd), u64(buf), count)) +} + +// 1 sys_write +pub fn sys_write(fd i64, buf &byte, count u64) (i64, Errno) { + return split_int_errno(sys_call3(1, u64(fd), u64(buf), count)) +} + +// 2 sys_open +fn sys_open(filename &byte, flags i64, mode int) (i64, Errno) { + return split_int_errno(sys_call3(2, u64(filename), u64(flags), u64(mode))) +} + +// 3 sys_close +fn sys_close(fd i64) Errno { + return Errno(-i64(sys_call1(3, u64(fd)))) +} + +// 9 sys_mmap +fn sys_mmap(addr &byte, len u64, prot MemProt, flags MapFlags, fildes u64, off u64) (&byte, Errno) { + rc := sys_call6(9, u64(addr), len, u64(prot), u64(flags), fildes, off) + a, e := split_int_errno(rc) + return &byte(a), e +} + +// 11 sys_munmap +fn sys_munmap(addr voidptr, len u64) Errno { + return Errno(-sys_call2(11, u64(addr), len)) +} + +// 22 sys_pipe +fn sys_pipe(filedes &int) Errno { + return Errno(sys_call1(22, u64(filedes))) +} + +// 24 sys_sched_yield +fn sys_sched_yield() Errno { + return Errno(sys_call0(24)) +} + +// 28 sys_madvise +fn sys_madvise(addr voidptr, len u64, advice int) Errno { + return Errno(sys_call3(28, u64(addr), len, u64(advice))) +} + +// 39 sys_getpid +fn sys_getpid() int { + return int(sys_call0(39)) +} + +// 57 sys_fork +fn sys_fork() int { + return int(sys_call0(57)) +} + +// 58 sys_vfork +fn sys_vfork() int { + return int(sys_call0(58)) +} + +// 33 sys_dup2 +fn sys_dup2(oldfd int, newfd int) (i64, Errno) { + return split_int_errno(sys_call2(33, u64(oldfd), u64(newfd))) +} + +// 59 sys_execve +fn sys_execve(filename &byte, argv []&byte, envp []&byte) int { + return int(sys_call3(59, u64(filename), argv.data, envp.data)) +} + +// 60 sys_exit +[noreturn] +fn sys_exit(ec int) { + sys_call1(60, u64(ec)) + for {} +} + +// 102 sys_getuid +fn sys_getuid() int { + return int(sys_call0(102)) +} + +// 247 sys_waitid +fn sys_waitid(which WiWhich, pid int, infop &int, options int, ru voidptr) Errno { + return Errno(sys_call5(247, u64(which), u64(pid), u64(infop), u64(options), u64(ru))) +} + +fn sys_call0(scn u64) u64 { + mut res := u64(0) + asm amd64 { + syscall + ; =a (res) + ; a (scn) + } + return res +} + +fn sys_call1(scn u64, arg1 u64) u64 { + mut res := u64(0) + asm amd64 { + syscall + ; =a (res) + ; a (scn) + D (arg1) + } + return res +} + +fn sys_call2(scn u64, arg1 u64, arg2 u64) u64 { + mut res := u64(0) + asm amd64 { + syscall + ; =a (res) + ; a (scn) + D (arg1) + S (arg2) + } + return res +} + +fn sys_call3(scn u64, arg1 u64, arg2 u64, arg3 u64) u64 { + mut res := u64(0) + asm amd64 { + syscall + ; =a (res) + ; a (scn) + D (arg1) + S (arg2) + d (arg3) + } + return res +} + +fn sys_call4(scn u64, arg1 u64, arg2 u64, arg3 u64, arg4 u64) u64 { + mut res := u64(0) + asm amd64 { + mov r10, arg4 + syscall + ; =a (res) + ; a (scn) + D (arg1) + S (arg2) + d (arg3) + r (arg4) + ; r10 + } + return res +} + +fn sys_call5(scn u64, arg1 u64, arg2 u64, arg3 u64, arg4 u64, arg5 u64) u64 { + mut res := u64(0) + asm amd64 { + mov r10, arg4 + mov r8, arg5 + syscall + ; =a (res) + ; a (scn) + D (arg1) + S (arg2) + d (arg3) + r (arg4) + r (arg5) + ; r10 + r8 + } + return res +} + +fn sys_call6(scn u64, arg1 u64, arg2 u64, arg3 u64, arg4 u64, arg5 u64, arg6 u64) u64 { + mut res := u64(0) + asm amd64 { + mov r10, arg4 + mov r8, arg5 + mov r9, arg6 + syscall + ; =a (res) + ; a (scn) + D (arg1) + S (arg2) + d (arg3) + r (arg4) + r (arg5) + r (arg6) + ; r10 + r8 + r9 + } + return res +} + +asm amd64 { + .globl _start + _start: + call main + mov rax, 60 + xor rdi, rdi + syscall + ret +} |