diff options
author | Ori Bernstein <ori@eigenstate.org> | 2019-07-13 22:46:57 -0700 |
---|---|---|
committer | Ori Bernstein <ori@eigenstate.org> | 2019-07-13 22:46:57 -0700 |
commit | 820585fb7338092fa5b5001b81ad45b06376939d (patch) | |
tree | 47214d3efdf0459fdcd73994d83d2d54ed00b686 | |
parent | 77246bfe1b9f147b1b255e811fb8b2032c49dc9e (diff) | |
download | mc-820585fb7338092fa5b5001b81ad45b06376939d.tar.gz |
Oops, mangled something with git9.
-rw-r--r-- | lib/json/test/inputs/n_structure_no_data.json | 0 | ||||
-rw-r--r-- | lib/json/test/inputs/n_structure_whitespace_U+2060_word_joiner.json | 1 | ||||
-rw-r--r-- | lib/json/test/inputs/y_number_negative_zero.json | 1 | ||||
-rw-r--r-- | lib/std/dir+openbsd.myr | 65 | ||||
-rw-r--r-- | lib/std/syswrap-ss+openbsd.myr | 31 | ||||
-rw-r--r-- | lib/std/test/bigint.myr | 8 | ||||
-rw-r--r-- | lib/sys/ifreq+netbsd.myr | 2 | ||||
-rw-r--r-- | lib/sys/ifreq+openbsd.myr | 2 | ||||
-rw-r--r-- | lib/sys/ifreq+plan9.myr | 2 | ||||
-rw-r--r-- | lib/sys/syserrno+openbsd.myr | 123 | ||||
-rw-r--r-- | lib/thread/ncpu+openbsd.myr | 23 | ||||
-rw-r--r-- | rt/abort-netbsd.s | 42 | ||||
-rw-r--r-- | support/syscall-gen/specials+openbsd:6.2-x64.frag | 286 | ||||
-rw-r--r-- | support/syscall-gen/specials+openbsd:6.3-x64.frag | 286 | ||||
-rw-r--r-- | test/data/catfile-in | 1 |
15 files changed, 865 insertions, 8 deletions
diff --git a/lib/json/test/inputs/n_structure_no_data.json b/lib/json/test/inputs/n_structure_no_data.json new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/lib/json/test/inputs/n_structure_no_data.json diff --git a/lib/json/test/inputs/n_structure_whitespace_U+2060_word_joiner.json b/lib/json/test/inputs/n_structure_whitespace_U+2060_word_joiner.json new file mode 100644 index 0000000..81156a6 --- /dev/null +++ b/lib/json/test/inputs/n_structure_whitespace_U+2060_word_joiner.json @@ -0,0 +1 @@ +[]
\ No newline at end of file diff --git a/lib/json/test/inputs/y_number_negative_zero.json b/lib/json/test/inputs/y_number_negative_zero.json new file mode 100644 index 0000000..37af131 --- /dev/null +++ b/lib/json/test/inputs/y_number_negative_zero.json @@ -0,0 +1 @@ +[-0]
\ No newline at end of file diff --git a/lib/std/dir+openbsd.myr b/lib/std/dir+openbsd.myr new file mode 100644 index 0000000..274175d --- /dev/null +++ b/lib/std/dir+openbsd.myr @@ -0,0 +1,65 @@ +use sys + +use "alloc" +use "die" +use "memops" +use "option" +use "result" +use "slcp" +use "sldup" +use "types" + +pkg std = + type dir = struct + fd : sys.fd + buf : byte[16384] + len : int64 + off : int64 + ;; + + const diropen : (p : byte[:] -> std.result(dir#, byte[:])) + const dirread : (d : dir# -> std.option(byte[:])) + const dirclose : (d : dir# -> void) +;; + +const diropen = {p + var fd + var dir + + fd = sys.open(p, sys.Ordonly | sys.Odir) + if fd < 0 + -> `Err "couldn't open directory" + ;; + dir = zalloc() + dir.fd = fd + -> `Ok dir +} + +const dirread = {d + var len + var dent + var namelen + + if d.off >= d.len + len = sys.getdents(d.fd, d.buf[:]) + if len <= 0 + -> `None + ;; + d.len = len + d.off = 0 + ;; + + dent = (&d.buf[d.off] : sys.dirent#) + namelen = 0 + d.off += (dent.reclen : int64) + while dent.name[namelen] != 0 + namelen++ + ;; + -> `Some sldup(dent.name[:namelen]) +} + +const dirclose = {d + sys.close(d.fd) + free(d) +} + diff --git a/lib/std/syswrap-ss+openbsd.myr b/lib/std/syswrap-ss+openbsd.myr new file mode 100644 index 0000000..0f4ed65 --- /dev/null +++ b/lib/std/syswrap-ss+openbsd.myr @@ -0,0 +1,31 @@ +use sys +use "types" +use "errno" +use "cstrconv" +use "slcp" +use "die" + +pkg std = + const nanosleep : (nsecs : uint64 -> errno) + $noret const exit : (status:int -> void) + + pkglocal const bgetcwd : (buf : byte[:] -> errno) +;; + +const exit = {status; sys.exit(status)} + +const bgetcwd = {buf + -> (sys.__getcwd(buf) - 1 : errno) +} + +const nanosleep = {nsecs + var req, rem + var s, ns + + s = (nsecs / 1_000_000_000 : int64) + ns = (nsecs % 1_000_000_000 : int64) + req = [.sec = s, .nsec = ns] + + -> (sys.nanosleep(&req, &rem) : errno) +} + diff --git a/lib/std/test/bigint.myr b/lib/std/test/bigint.myr index 77b822f..c87f1f3 100644 --- a/lib/std/test/bigint.myr +++ b/lib/std/test/bigint.myr @@ -21,7 +21,6 @@ const main = { [.name = "format-zero", .fn = fmtzero], [.name = "division", .fn = smokediv], [.name = "modulo", .fn = smokemod], - [.name = "shift", .fn = shiftoff], [.name = "add-negatives", .fn = addneg], [.name = "sub-negatives", .fn = subneg], ][:]) @@ -265,13 +264,6 @@ const subneg = {c "0") } -const shiftoff = {c - run(c, std.mk(`Shr ( \ - std.mk(`Val "1"), \ - std.mk(`Val "65"))), \ - "0") -} - const run = {c : testr.ctx#, e : cmd#, res : byte[:] var buf : byte[4096] var v, n diff --git a/lib/sys/ifreq+netbsd.myr b/lib/sys/ifreq+netbsd.myr new file mode 100644 index 0000000..e7d6400 --- /dev/null +++ b/lib/sys/ifreq+netbsd.myr @@ -0,0 +1,2 @@ +pkg sys = +;; diff --git a/lib/sys/ifreq+openbsd.myr b/lib/sys/ifreq+openbsd.myr new file mode 100644 index 0000000..e7d6400 --- /dev/null +++ b/lib/sys/ifreq+openbsd.myr @@ -0,0 +1,2 @@ +pkg sys = +;; diff --git a/lib/sys/ifreq+plan9.myr b/lib/sys/ifreq+plan9.myr new file mode 100644 index 0000000..e7d6400 --- /dev/null +++ b/lib/sys/ifreq+plan9.myr @@ -0,0 +1,2 @@ +pkg sys = +;; diff --git a/lib/sys/syserrno+openbsd.myr b/lib/sys/syserrno+openbsd.myr new file mode 100644 index 0000000..e48f893 --- /dev/null +++ b/lib/sys/syserrno+openbsd.myr @@ -0,0 +1,123 @@ +pkg sys = + type errno = int + + const Eperm : errno = -1 /* Operation not permitted */ + const Enoent : errno = -2 /* No such file or directory */ + const Esrch : errno = -3 /* No such process */ + const Eintr : errno = -4 /* Interrupted system call */ + const Eio : errno = -5 /* Input/output error */ + const Enxio : errno = -6 /* Device not configured */ + const E2big : errno = -7 /* Argument list too long */ + const Enoexec : errno = -8 /* Exec format error */ + const Ebadf : errno = -9 /* Bad file descriptor */ + const Echild : errno = -10 /* No child processes */ + const Edeadlk : errno = -11 /* Resource deadlock avoided */ + /* 11 was EAGAIN */ + const Enomem : errno = -12 /* Cannot allocate memory */ + const Eacces : errno = -13 /* Permission denied */ + const Efault : errno = -14 /* Bad address */ + const Enotblk : errno = -15 /* Block device required */ + const Ebusy : errno = -16 /* Device busy */ + const Eexist : errno = -17 /* File exists */ + const Exdev : errno = -18 /* Cross-device link */ + const Enodev : errno = -19 /* Operation not supported by device */ + const Enotdir : errno = -20 /* Not a directory */ + const Eisdir : errno = -21 /* Is a directory */ + const Einval : errno = -22 /* Invalid argument */ + const Enfile : errno = -23 /* Too many open files in system */ + const Emfile : errno = -24 /* Too many open files */ + const Enotty : errno = -25 /* Inappropriate ioctl for device */ + const Etxtbsy : errno = -26 /* Text file busy */ + const Efbig : errno = -27 /* File too large */ + const Enospc : errno = -28 /* No space left on device */ + const Espipe : errno = -29 /* Illegal seek */ + const Erofs : errno = -30 /* Read-only filesystem */ + const Emlink : errno = -31 /* Too many links */ + const Epipe : errno = -32 /* Broken pipe */ + + /* math software */ + const Edom : errno = -33 /* Numerical argument out of domain */ + const Erange : errno = -34 /* Result too large */ + + /* non-blocking and interrupt i/o */ + const Eagain : errno = -35 /* Resource temporarily unavailable */ + const Einprogress : errno = -36 /* Operation now in progress */ + const Ealready : errno = -37 /* Operation already in progress */ + + /* ipc/network software -- argument errors */ + const Enotsock : errno = -38 /* Socket operation on non-socket */ + const Edestaddrreq : errno = -39 /* Destination address required */ + const Emsgsize : errno = -40 /* Message too long */ + const Eprototype : errno = -41 /* Protocol wrong type for socket */ + const Enoprotoopt : errno = -42 /* Protocol not available */ + const Eprotonosupport : errno = -43 /* Protocol not supported */ + const Esocktnosupport : errno = -44 /* Socket type not supported */ + const Eopnotsupp : errno = -45 /* Operation not supported */ + const Epfnosupport : errno = -46 /* Protocol family not supported */ + const Eafnosupport : errno = -47 /* Address family not supported by protocol family */ + const Eaddrinuse : errno = -48 /* Address already in use */ + const Eaddrnotavail : errno = -49 /* Can't assign requested address */ + + /* ipc/network software -- operational errors */ + const Enetdown : errno = -50 /* Network is down */ + const Enetunreach : errno = -51 /* Network is unreachable */ + const Enetreset : errno = -52 /* Network dropped connection on reset */ + const Econnaborted : errno = -53 /* Software caused connection abort */ + const Econnreset : errno = -54 /* Connection reset by peer */ + const Enobufs : errno = -55 /* No buffer space available */ + const Eisconn : errno = -56 /* Socket is already connected */ + const Enotconn : errno = -57 /* Socket is not connected */ + const Eshutdown : errno = -58 /* Can't send after socket shutdown */ + const Etoomanyrefs : errno = -59 /* Too many references: can't splice */ + const Etimedout : errno = -60 /* Operation timed out */ + const Econnrefused : errno = -61 /* Connection refused */ + + const Eloop : errno = -62 /* Too many levels of symbolic links */ + const Enametoolong : errno = -63 /* File name too long */ + + /* should be rearranged */ + const Ehostdown : errno = -64 /* Host is down */ + const Ehostunreach : errno = -65 /* No route to host */ + const Enotempty : errno = -66 /* Directory not empty */ + + /* quotas & mush */ + const Eproclim : errno = -67 /* Too many processes */ + const Eusers : errno = -68 /* Too many users */ + const Edquot : errno = -69 /* Disc quota exceeded */ + + /* Network File System */ + const Estale : errno = -70 /* Stale NFS file handle */ + const Eremote : errno = -71 /* Too many levels of remote in path */ + const Ebadrpc : errno = -72 /* RPC struct is bad */ + const Erpcmismatch : errno = -73 /* RPC version wrong */ + const Eprogunavail : errno = -74 /* RPC prog. not avail */ + const Eprogmismatch : errno = -75 /* Program version wrong */ + const Eprocunavail : errno = -76 /* Bad procedure for program */ + + const Enolck : errno = -77 /* No locks available */ + const Enosys : errno = -78 /* Function not implemented */ + + const Eftype : errno = -79 /* Inappropriate file type or format */ + const Eauth : errno = -80 /* Authentication error */ + const Eneedauth : errno = -81 /* Need authenticator */ + const Eidrm : errno = -82 /* Identifier removed */ + const Enomsg : errno = -83 /* No message of desired type */ + const Eoverflow : errno = -84 /* Value too large to be stored in data type */ + const Ecanceled : errno = -85 /* Operation canceled */ + const Eilseq : errno = -86 /* Illegal byte sequence */ + const Enoattr : errno = -87 /* Attribute not found */ + + const Edoofus : errno = -88 /* Programming error */ + + const Ebadmsg : errno = -89 /* Bad message */ + const Emultihop : errno = -90 /* Multihop attempted */ + const Enolink : errno = -91 /* Link has been severed */ + const Eproto : errno = -92 /* Protocol error */ + + const Enotcapable : errno = -93 /* Capabilities insufficient */ + const Ecapmode : errno = -94 /* Not permitted in capability mode */ + const Enotrecoverable : errno = -95 /* State not recoverable */ + const Eownerdead : errno = -96 /* Previous owner died */ + + const Elast : errno = -96 /* Must be equal largest errno */ +;; diff --git a/lib/thread/ncpu+openbsd.myr b/lib/thread/ncpu+openbsd.myr new file mode 100644 index 0000000..1aa3dc1 --- /dev/null +++ b/lib/thread/ncpu+openbsd.myr @@ -0,0 +1,23 @@ +use std +use sys + +pkg thread = + const ncpu : (-> int) +;; + +const ncpu = { + var mib : int[2] + var ncpu : int + var ncpusz + var res + + mib[0] = 6 /* CTL_HW */ + mib[1] = 3 /* HW_NCPU */ + ncpusz = sizeof(int) + + res = sys.sysctl(mib[:], (&ncpu : void#), &ncpusz, (0 : void#), (0 : sys.size#)) + if res < 0 || ncpu <= 0 + -> 1 + ;; + -> ncpu +} diff --git a/rt/abort-netbsd.s b/rt/abort-netbsd.s new file mode 100644 index 0000000..a4b12bb --- /dev/null +++ b/rt/abort-netbsd.s @@ -0,0 +1,42 @@ +.text + +.globl _rt$abort_oob +.globl __rt$abort_oob +_rt$abort_oob: +__rt$abort_oob: + /* format pc */ + movq (%rsp),%rax + movq $15,%rdx + leaq .digitchars(%rip),%r8 + leaq .pcstr(%rip),%r9 +.loop: + movq %rax, %rcx + andq $0xf, %rcx + movb (%r8,%rcx),%r10b + movb %r10b,(%r9,%rdx) + subq $1, %rdx + shrq $4, %rax + jnz .loop + /* write abort message */ + movq $4, %rax /* write(fd=%rdi, msg=%rsi, len=%rdx) */ + movq $2, %rdi /* fd */ + leaq .msg(%rip), %rsi /* msg */ + movq $(.msgend-.msg), %rdx /* length */ + syscall + /* kill self */ + movq $20,%rax /* getpid */ + syscall + movq %rax, %rdi /* save pid */ + movq $37, %rax /* kill(pid=%rdi, sig=%rsi) */ + movq $6, %rsi + syscall +.data +.msg: /* pc name: */ + .ascii "0x" +.pcstr: + .ascii "0000000000000000" + .ascii ": out of bounds access\n" +.msgend: + +.digitchars: + .ascii "0123456789abcdef" diff --git a/support/syscall-gen/specials+openbsd:6.2-x64.frag b/support/syscall-gen/specials+openbsd:6.2-x64.frag new file mode 100644 index 0000000..b326ec1 --- /dev/null +++ b/support/syscall-gen/specials+openbsd:6.2-x64.frag @@ -0,0 +1,286 @@ +/* process control */ +const exit : (status:int -> void) +const getpid : ( -> pid) +const kill : (pid:pid, sig:int64 -> int64) +const fork : (-> pid) +const wait4 : (pid:pid, loc:int32#, opt : int64, usage:rusage# -> int64) +const waitpid : (pid:pid, loc:int32#, opt : int64 -> int64) +const execv : (cmd : byte[:], args : byte[:][:] -> int64) +const execve : (cmd : byte[:], args : byte[:][:], env : byte[:][:] -> int64) +/* wrappers to extract wait status */ +const waitstatus : (st : int32 -> waitstatus) +extern const __tfork_thread : (tfp : tforkparams#, sz : size, fn : void#, arg : void# -> pid) + +/* fd manipulation */ +const open : (path:byte[:], opts:fdopt -> fd) +const openmode : (path:byte[:], opts:fdopt, mode:int64 -> fd) +const close : (fd:fd -> int64) +const creat : (path:byte[:], mode:int64 -> fd) +const unlink : (path:byte[:] -> int) +const read : (fd:fd, buf:byte[:] -> size) +const pread : (fd:fd, buf:byte[:], off : off -> size) +const readv : (fd:fd, iov:iovec[:] -> size) +const write : (fd:fd, buf:byte[:] -> size) +const pwrite : (fd:fd, buf:byte[:], off : off -> size) +const writev : (fd:fd, iov:iovec[:] -> size) +const lseek : (fd:fd, off : off, whence : whence -> int64) +const stat : (path:byte[:], sb:statbuf# -> int64) +const lstat : (path:byte[:], sb:statbuf# -> int64) +const fstat : (fd:fd, sb:statbuf# -> int64) +const mkdir : (path : byte[:], mode : int64 -> int64) +generic ioctl : (fd:fd, req : int64, arg:@a# -> int64) +const getdents : (fd : fd, buf : byte[:] -> int64) +const chdir : (p : byte[:] -> int64) +const __getcwd : (buf : byte[:] -> int64) +const poll : (pfd : pollfd[:], tm : int -> int) + +/* signals */ +const sigaction : (sig : signo, act : sigaction#, oact : sigaction# -> int) +const sigprocmask : (how : int32, set : sigset#, oset : sigset# -> int) + +/* fd stuff */ +const pipe : (fds : fd[2]# -> int64) +const dup : (fd : fd -> fd) +const dup2 : (src : fd, dst : fd -> fd) +/* NB: the C ABI uses '...' for the args. */ +const fcntl : (fd : fd, cmd : fcntlcmd, args : byte# -> int64) + +/* networking */ +const socket : (dom : sockfam, stype : socktype, proto : sockproto -> fd) +const connect : (sock : fd, addr : sockaddr#, len : size -> int) +const accept : (sock : fd, addr : sockaddr#, len : size# -> fd) +const listen : (sock : fd, backlog : int -> int) +const bind : (sock : fd, addr : sockaddr#, len : size -> int) +const setsockopt : (sock : fd, lev : sockproto, opt : sockopt, val : void#, len : size -> int) +const getsockopt : (sock : fd, lev : sockproto, opt : sockopt, val : void#, len : size# -> int) + +/* memory mapping */ +const munmap : (addr:byte#, len:size -> int64) +const mmap : (addr:byte#, len:size, prot:mprot, flags:mopt, fd:fd, off:off -> byte#) + +/* time - doublecheck if this is right */ +const clock_getres : (clk : clock, ts : timespec# -> int32) +const clock_gettime : (clk : clock, ts : timespec# -> int32) +const clock_settime : (clk : clock, ts : timespec# -> int32) +const sleep : (time : uint64 -> int32) +const nanosleep : (req : timespec#, rem : timespec# -> int32) + +/* system information */ +const uname : (buf : utsname# -> int) +const sysctl : (mib : int[:], \ + old : void#, oldsz : size#, \ + new : void#, newsz : size# \ + -> int) + +/* +wraps a syscall argument, converting it to 64 bits for the syscall function. This is +the same as casting, but more concise than writing a cast to uint64 +*/ +generic a = {x : @t; -> (x : uint64)} + +extern const cstring : (str : byte[:] -> byte#) +extern const alloca : (sz : size -> byte#) + +extern const __freebsd_pipe : (fds : fd[2]# -> int64) + +/* process management */ +const exit = {status; syscall(Sysexit, a(status))} +const getpid = {; -> (syscall(Sysgetpid, 1) : pid)} +const kill = {pid, sig; -> syscall(Syskill, pid, sig)} +const fork = {; -> (syscall(Sysfork) : pid)} +const wait4 = {pid, loc, opt, usage; -> syscall(Syswait4, pid, loc, opt, usage)} +const waitpid = {pid, loc, opt; + -> wait4(pid, loc, opt, (0 : rusage#)) +} + +const execv = {cmd, args + var p, cargs, i + + /* of course we fucking have to duplicate this code everywhere, + * since we want to stack allocate... */ + p = alloca((args.len + 1)*sizeof(byte#)) + cargs = (p : byte##)[:args.len + 1] + for i = 0; i < args.len; i++ + cargs[i] = cstring(args[i]) + ;; + cargs[args.len] = (0 : byte#) + -> syscall(Sysexecve, cstring(cmd), a(p), a(__cenvp)) +} + +const execve = {cmd, args, env + var cargs, cenv, i + var p + + /* copy the args */ + p = alloca((args.len + 1)*sizeof(byte#)) + cargs = (p : byte##)[:args.len] + for i = 0; i < args.len; i++ + cargs[i] = cstring(args[i]) + ;; + cargs[args.len] = (0 : byte#) + + /* + copy the env. + of course we fucking have to duplicate this code everywhere, + since we want to stack allocate... + */ + p = alloca((env.len + 1)*sizeof(byte#)) + cenv = (p : byte##)[:env.len] + for i = 0; i < env.len; i++ + cenv[i] = cstring(env[i]) + ;; + cenv[env.len] = (0 : byte#) + + -> syscall(Sysexecve, cstring(cmd), a(p), a(cenv)) +} + +/* fd manipulation */ +const open = {path, opts; -> (syscall(Sysopen, cstring(path), a(opts), a(0o777)) : fd)} +const openmode = {path, opts, mode; -> (syscall(Sysopen, cstring(path), a(opts), a(mode)) : fd)} +const close = {fd; -> syscall(Sysclose, a(fd))} +const creat = {path, mode; -> (openmode(path, Ocreat | Otrunc | Owronly, mode) : fd)} +const unlink = {path; -> (syscall(Sysunlink, cstring(path)) : int)} +const read = {fd, buf; -> (syscall(Sysread, a(fd), (buf : byte#), a(buf.len)) : size)} +const pread = {fd, buf, off; -> (syscall(Syspread, a(fd), (buf : byte#), a(buf.len), a(off)) : size)} +const readv = {fd, vec; -> (syscall(Sysreadv, a(fd), (vec : iovec#), a(vec.len)) : size)} +const write = {fd, buf; -> (syscall(Syswrite, a(fd), (buf : byte#), a(buf.len)) : size)} +const pwrite = {fd, buf, off; -> (syscall(Syspwrite, a(fd), (buf : byte#), a(buf.len), a(off)) : size)} +const writev = {fd, vec; -> (syscall(Syswritev, a(fd), (vec : iovec#), a(vec.len)) : size)} +const lseek = {fd, off, whence; -> syscall(Syslseek, a(fd), a(off), a(whence))} +const stat = {path, sb; -> syscall(Sysstat, cstring(path), a(sb))} +const lstat = {path, sb; -> syscall(Syslstat, cstring(path), a(sb))} +const fstat = {fd, sb; -> syscall(Sysfstat, a(fd), a(sb))} +const mkdir = {path, mode; -> (syscall(Sysmkdir, cstring(path), a(mode)) : int64)} +generic ioctl = {fd, req, arg; -> (syscall(Sysioctl, a(fd), a(req), a(arg)) : int64)} +const chdir = {dir; -> syscall(Syschdir, cstring(dir))} +const __getcwd = {buf; -> syscall(Sys__getcwd, a(buf), a(buf.len))} +const getdents = {fd, buf; -> (syscall(Sysgetdents, a(fd), a(buf), a(buf.len)) : int64)} + +/* signals */ +const sigaction = {sig, act, oact; -> (syscall(Syssigaction, a(sig), a(act), a(oact)) : int)} +const sigprocmask = {sig, act, oact; -> (syscall(Syssigprocmask, a(sig), a(act), a(oact)) : int)} + +/* file stuff */ +const pipe = {fds; -> syscall(Syspipe, fds)} +const dup = {fd; -> (syscall(Sysdup, a(fd)) : fd)} +const dup2 = {src, dst; -> (syscall(Sysdup2, a(src), a(dst)) : fd)} +const fcntl = {fd, cmd, args; -> syscall(Sysfcntl, a(fd), a(cmd), a(args))} +const poll = {pfd, tm; -> (syscall(Syspoll, (pfd : byte#), a(pfd.len), a(tm)) : int)} + +/* networking */ +const socket = {dom, stype, proto; -> (syscall(Syssocket, a(dom), a(stype), a(proto)) : fd)} +const connect = {sock, addr, len; -> (syscall(Sysconnect, a(sock), a(addr), a(len)) : int)} +const accept = {sock, addr, len; -> (syscall(Sysaccept, a(sock), a(addr), a(len)) : fd)} +const listen = {sock, backlog; -> (syscall(Syslisten, a(sock), a(backlog)) : int)} +const bind = {sock, addr, len; -> (syscall(Sysbind, a(sock), a(addr), a(len)) : int)} +const setsockopt = {sock, lev, opt, val, len; -> (syscall(Syssetsockopt, a(sock), a(lev), a(opt), a(val), a(len)) : int)} +const getsockopt = {sock, lev, opt, val, len; -> (syscall(Syssetsockopt, a(sock), a(lev), a(opt), a(val), a(len)) : int)} + +/* memory management */ +const munmap = {addr, len; -> syscall(Sysmunmap, a(addr), a(len))} +const mmap = {addr, len, prot, flags, fd, off; + /* the actual syscall has padding on the offset arg */ + -> (syscall(Sysmmap, a(addr), a(len), a(prot), a(flags), a(fd), a(0), a(off)) : byte#) +} + +/* time */ +const clock_getres = {clk, ts; -> (syscall(Sysclock_getres, clockid(clk), a(ts)) : int32)} +const clock_gettime = {clk, ts; -> (syscall(Sysclock_gettime, clockid(clk), a(ts)) : int32)} +const clock_settime = {clk, ts; -> (syscall(Sysclock_settime, clockid(clk), a(ts)) : int32)} + +const sleep = {time + var req, rem + req = [.sec = (time : int64), .nsec = 0] + -> nanosleep(&req, &rem) +} + +const nanosleep = {req, rem; -> (syscall(Sysnanosleep, a(req), a(rem)) : int32)} + + +/* system information */ +const uname = {buf + var mib : int[2] + var ret + var sys, syssz + var nod, nodsz + var rel, relsz + var ver, versz + var mach, machsz + + ret = 0 + mib[0] = 1 /* CTL_KERN */ + mib[1] = 1 /* KERN_OSTYPE */ + sys = (buf.system[:] : void#) + syssz = buf.system.len + ret = sysctl(mib[:], sys, &syssz, (0 : void#), (0 : size#)) + if ret < 0 + -> ret + ;; + + mib[0] = 1 /* CTL_KERN */ + mib[1] = 10 /* KERN_HOSTNAME */ + nod = (buf.node[:] : void#) + nodsz = buf.node.len + ret = sysctl(mib[:], nod, &nodsz, (0 : void#), (0 : size#)) + if ret < 0 + -> ret + ;; + + mib[0] = 1 /* CTL_KERN */ + mib[1] = 2 /* KERN_OSRELEASE */ + rel = (buf.release[:] : void#) + relsz = buf.release.len + ret = sysctl(mib[:], rel, &relsz, (0 : void#), (0 : size#)) + if ret < 0 + -> ret + ;; + + mib[0] = 1 /* CTL_KERN */ + mib[1] = 27 /* KERN_OSVERSION */ + ver = (buf.version[:] : void#) + versz = buf.version.len + ret = sysctl(mib[:], ver, &versz, (0 : void#), (0 : size#)) + if ret < 0 + -> ret + ;; + + mib[0] = 6 /* CTL_HW */ + mib[1] = 1 /* HW_MACHINE */ + mach = (buf.machine[:] : void#) + machsz = buf.machine.len + ret = sysctl(mib[:], mach, &machsz, (0 : void#), (0 : size#)) + if ret < 0 + -> ret + ;; + + -> 0 +} + +const sysctl = {mib, old, oldsz, new, newsz + /* all args already passed through a() or ar ptrs */ + -> (syscall(Syssysctl, \ + (mib : int#), a(mib.len), old, oldsz, new, newsz) : int) +} + +const clockid = {clk + match clk + | `Clockrealtime: -> 0 + | `Clockproccputime: -> 2 + | `Clockmonotonic: -> 3 + | `Clockthreadcputime: -> 4 + | `Clockuptime: -> 5 + ;; + -> -1 +} + +const waitstatus = {st + if st < 0 + -> `Waitfail st + ;; + match st & 0o177 + | 0: -> `Waitexit (st >> 8) + | 0x7f:-> `Waitstop (st >> 8) + | sig: -> `Waitsig sig + ;; +} + diff --git a/support/syscall-gen/specials+openbsd:6.3-x64.frag b/support/syscall-gen/specials+openbsd:6.3-x64.frag new file mode 100644 index 0000000..b326ec1 --- /dev/null +++ b/support/syscall-gen/specials+openbsd:6.3-x64.frag @@ -0,0 +1,286 @@ +/* process control */ +const exit : (status:int -> void) +const getpid : ( -> pid) +const kill : (pid:pid, sig:int64 -> int64) +const fork : (-> pid) +const wait4 : (pid:pid, loc:int32#, opt : int64, usage:rusage# -> int64) +const waitpid : (pid:pid, loc:int32#, opt : int64 -> int64) +const execv : (cmd : byte[:], args : byte[:][:] -> int64) +const execve : (cmd : byte[:], args : byte[:][:], env : byte[:][:] -> int64) +/* wrappers to extract wait status */ +const waitstatus : (st : int32 -> waitstatus) +extern const __tfork_thread : (tfp : tforkparams#, sz : size, fn : void#, arg : void# -> pid) + +/* fd manipulation */ +const open : (path:byte[:], opts:fdopt -> fd) +const openmode : (path:byte[:], opts:fdopt, mode:int64 -> fd) +const close : (fd:fd -> int64) +const creat : (path:byte[:], mode:int64 -> fd) +const unlink : (path:byte[:] -> int) +const read : (fd:fd, buf:byte[:] -> size) +const pread : (fd:fd, buf:byte[:], off : off -> size) +const readv : (fd:fd, iov:iovec[:] -> size) +const write : (fd:fd, buf:byte[:] -> size) +const pwrite : (fd:fd, buf:byte[:], off : off -> size) +const writev : (fd:fd, iov:iovec[:] -> size) +const lseek : (fd:fd, off : off, whence : whence -> int64) +const stat : (path:byte[:], sb:statbuf# -> int64) +const lstat : (path:byte[:], sb:statbuf# -> int64) +const fstat : (fd:fd, sb:statbuf# -> int64) +const mkdir : (path : byte[:], mode : int64 -> int64) +generic ioctl : (fd:fd, req : int64, arg:@a# -> int64) +const getdents : (fd : fd, buf : byte[:] -> int64) +const chdir : (p : byte[:] -> int64) +const __getcwd : (buf : byte[:] -> int64) +const poll : (pfd : pollfd[:], tm : int -> int) + +/* signals */ +const sigaction : (sig : signo, act : sigaction#, oact : sigaction# -> int) +const sigprocmask : (how : int32, set : sigset#, oset : sigset# -> int) + +/* fd stuff */ +const pipe : (fds : fd[2]# -> int64) +const dup : (fd : fd -> fd) +const dup2 : (src : fd, dst : fd -> fd) +/* NB: the C ABI uses '...' for the args. */ +const fcntl : (fd : fd, cmd : fcntlcmd, args : byte# -> int64) + +/* networking */ +const socket : (dom : sockfam, stype : socktype, proto : sockproto -> fd) +const connect : (sock : fd, addr : sockaddr#, len : size -> int) +const accept : (sock : fd, addr : sockaddr#, len : size# -> fd) +const listen : (sock : fd, backlog : int -> int) +const bind : (sock : fd, addr : sockaddr#, len : size -> int) +const setsockopt : (sock : fd, lev : sockproto, opt : sockopt, val : void#, len : size -> int) +const getsockopt : (sock : fd, lev : sockproto, opt : sockopt, val : void#, len : size# -> int) + +/* memory mapping */ +const munmap : (addr:byte#, len:size -> int64) +const mmap : (addr:byte#, len:size, prot:mprot, flags:mopt, fd:fd, off:off -> byte#) + +/* time - doublecheck if this is right */ +const clock_getres : (clk : clock, ts : timespec# -> int32) +const clock_gettime : (clk : clock, ts : timespec# -> int32) +const clock_settime : (clk : clock, ts : timespec# -> int32) +const sleep : (time : uint64 -> int32) +const nanosleep : (req : timespec#, rem : timespec# -> int32) + +/* system information */ +const uname : (buf : utsname# -> int) +const sysctl : (mib : int[:], \ + old : void#, oldsz : size#, \ + new : void#, newsz : size# \ + -> int) + +/* +wraps a syscall argument, converting it to 64 bits for the syscall function. This is +the same as casting, but more concise than writing a cast to uint64 +*/ +generic a = {x : @t; -> (x : uint64)} + +extern const cstring : (str : byte[:] -> byte#) +extern const alloca : (sz : size -> byte#) + +extern const __freebsd_pipe : (fds : fd[2]# -> int64) + +/* process management */ +const exit = {status; syscall(Sysexit, a(status))} +const getpid = {; -> (syscall(Sysgetpid, 1) : pid)} +const kill = {pid, sig; -> syscall(Syskill, pid, sig)} +const fork = {; -> (syscall(Sysfork) : pid)} +const wait4 = {pid, loc, opt, usage; -> syscall(Syswait4, pid, loc, opt, usage)} +const waitpid = {pid, loc, opt; + -> wait4(pid, loc, opt, (0 : rusage#)) +} + +const execv = {cmd, args + var p, cargs, i + + /* of course we fucking have to duplicate this code everywhere, + * since we want to stack allocate... */ + p = alloca((args.len + 1)*sizeof(byte#)) + cargs = (p : byte##)[:args.len + 1] + for i = 0; i < args.len; i++ + cargs[i] = cstring(args[i]) + ;; + cargs[args.len] = (0 : byte#) + -> syscall(Sysexecve, cstring(cmd), a(p), a(__cenvp)) +} + +const execve = {cmd, args, env + var cargs, cenv, i + var p + + /* copy the args */ + p = alloca((args.len + 1)*sizeof(byte#)) + cargs = (p : byte##)[:args.len] + for i = 0; i < args.len; i++ + cargs[i] = cstring(args[i]) + ;; + cargs[args.len] = (0 : byte#) + + /* + copy the env. + of course we fucking have to duplicate this code everywhere, + since we want to stack allocate... + */ + p = alloca((env.len + 1)*sizeof(byte#)) + cenv = (p : byte##)[:env.len] + for i = 0; i < env.len; i++ + cenv[i] = cstring(env[i]) + ;; + cenv[env.len] = (0 : byte#) + + -> syscall(Sysexecve, cstring(cmd), a(p), a(cenv)) +} + +/* fd manipulation */ +const open = {path, opts; -> (syscall(Sysopen, cstring(path), a(opts), a(0o777)) : fd)} +const openmode = {path, opts, mode; -> (syscall(Sysopen, cstring(path), a(opts), a(mode)) : fd)} +const close = {fd; -> syscall(Sysclose, a(fd))} +const creat = {path, mode; -> (openmode(path, Ocreat | Otrunc | Owronly, mode) : fd)} +const unlink = {path; -> (syscall(Sysunlink, cstring(path)) : int)} +const read = {fd, buf; -> (syscall(Sysread, a(fd), (buf : byte#), a(buf.len)) : size)} +const pread = {fd, buf, off; -> (syscall(Syspread, a(fd), (buf : byte#), a(buf.len), a(off)) : size)} +const readv = {fd, vec; -> (syscall(Sysreadv, a(fd), (vec : iovec#), a(vec.len)) : size)} +const write = {fd, buf; -> (syscall(Syswrite, a(fd), (buf : byte#), a(buf.len)) : size)} +const pwrite = {fd, buf, off; -> (syscall(Syspwrite, a(fd), (buf : byte#), a(buf.len), a(off)) : size)} +const writev = {fd, vec; -> (syscall(Syswritev, a(fd), (vec : iovec#), a(vec.len)) : size)} +const lseek = {fd, off, whence; -> syscall(Syslseek, a(fd), a(off), a(whence))} +const stat = {path, sb; -> syscall(Sysstat, cstring(path), a(sb))} +const lstat = {path, sb; -> syscall(Syslstat, cstring(path), a(sb))} +const fstat = {fd, sb; -> syscall(Sysfstat, a(fd), a(sb))} +const mkdir = {path, mode; -> (syscall(Sysmkdir, cstring(path), a(mode)) : int64)} +generic ioctl = {fd, req, arg; -> (syscall(Sysioctl, a(fd), a(req), a(arg)) : int64)} +const chdir = {dir; -> syscall(Syschdir, cstring(dir))} +const __getcwd = {buf; -> syscall(Sys__getcwd, a(buf), a(buf.len))} +const getdents = {fd, buf; -> (syscall(Sysgetdents, a(fd), a(buf), a(buf.len)) : int64)} + +/* signals */ +const sigaction = {sig, act, oact; -> (syscall(Syssigaction, a(sig), a(act), a(oact)) : int)} +const sigprocmask = {sig, act, oact; -> (syscall(Syssigprocmask, a(sig), a(act), a(oact)) : int)} + +/* file stuff */ +const pipe = {fds; -> syscall(Syspipe, fds)} +const dup = {fd; -> (syscall(Sysdup, a(fd)) : fd)} +const dup2 = {src, dst; -> (syscall(Sysdup2, a(src), a(dst)) : fd)} +const fcntl = {fd, cmd, args; -> syscall(Sysfcntl, a(fd), a(cmd), a(args))} +const poll = {pfd, tm; -> (syscall(Syspoll, (pfd : byte#), a(pfd.len), a(tm)) : int)} + +/* networking */ +const socket = {dom, stype, proto; -> (syscall(Syssocket, a(dom), a(stype), a(proto)) : fd)} +const connect = {sock, addr, len; -> (syscall(Sysconnect, a(sock), a(addr), a(len)) : int)} +const accept = {sock, addr, len; -> (syscall(Sysaccept, a(sock), a(addr), a(len)) : fd)} +const listen = {sock, backlog; -> (syscall(Syslisten, a(sock), a(backlog)) : int)} +const bind = {sock, addr, len; -> (syscall(Sysbind, a(sock), a(addr), a(len)) : int)} +const setsockopt = {sock, lev, opt, val, len; -> (syscall(Syssetsockopt, a(sock), a(lev), a(opt), a(val), a(len)) : int)} +const getsockopt = {sock, lev, opt, val, len; -> (syscall(Syssetsockopt, a(sock), a(lev), a(opt), a(val), a(len)) : int)} + +/* memory management */ +const munmap = {addr, len; -> syscall(Sysmunmap, a(addr), a(len))} +const mmap = {addr, len, prot, flags, fd, off; + /* the actual syscall has padding on the offset arg */ + -> (syscall(Sysmmap, a(addr), a(len), a(prot), a(flags), a(fd), a(0), a(off)) : byte#) +} + +/* time */ +const clock_getres = {clk, ts; -> (syscall(Sysclock_getres, clockid(clk), a(ts)) : int32)} +const clock_gettime = {clk, ts; -> (syscall(Sysclock_gettime, clockid(clk), a(ts)) : int32)} +const clock_settime = {clk, ts; -> (syscall(Sysclock_settime, clockid(clk), a(ts)) : int32)} + +const sleep = {time + var req, rem + req = [.sec = (time : int64), .nsec = 0] + -> nanosleep(&req, &rem) +} + +const nanosleep = {req, rem; -> (syscall(Sysnanosleep, a(req), a(rem)) : int32)} + + +/* system information */ +const uname = {buf + var mib : int[2] + var ret + var sys, syssz + var nod, nodsz + var rel, relsz + var ver, versz + var mach, machsz + + ret = 0 + mib[0] = 1 /* CTL_KERN */ + mib[1] = 1 /* KERN_OSTYPE */ + sys = (buf.system[:] : void#) + syssz = buf.system.len + ret = sysctl(mib[:], sys, &syssz, (0 : void#), (0 : size#)) + if ret < 0 + -> ret + ;; + + mib[0] = 1 /* CTL_KERN */ + mib[1] = 10 /* KERN_HOSTNAME */ + nod = (buf.node[:] : void#) + nodsz = buf.node.len + ret = sysctl(mib[:], nod, &nodsz, (0 : void#), (0 : size#)) + if ret < 0 + -> ret + ;; + + mib[0] = 1 /* CTL_KERN */ + mib[1] = 2 /* KERN_OSRELEASE */ + rel = (buf.release[:] : void#) + relsz = buf.release.len + ret = sysctl(mib[:], rel, &relsz, (0 : void#), (0 : size#)) + if ret < 0 + -> ret + ;; + + mib[0] = 1 /* CTL_KERN */ + mib[1] = 27 /* KERN_OSVERSION */ + ver = (buf.version[:] : void#) + versz = buf.version.len + ret = sysctl(mib[:], ver, &versz, (0 : void#), (0 : size#)) + if ret < 0 + -> ret + ;; + + mib[0] = 6 /* CTL_HW */ + mib[1] = 1 /* HW_MACHINE */ + mach = (buf.machine[:] : void#) + machsz = buf.machine.len + ret = sysctl(mib[:], mach, &machsz, (0 : void#), (0 : size#)) + if ret < 0 + -> ret + ;; + + -> 0 +} + +const sysctl = {mib, old, oldsz, new, newsz + /* all args already passed through a() or ar ptrs */ + -> (syscall(Syssysctl, \ + (mib : int#), a(mib.len), old, oldsz, new, newsz) : int) +} + +const clockid = {clk + match clk + | `Clockrealtime: -> 0 + | `Clockproccputime: -> 2 + | `Clockmonotonic: -> 3 + | `Clockthreadcputime: -> 4 + | `Clockuptime: -> 5 + ;; + -> -1 +} + +const waitstatus = {st + if st < 0 + -> `Waitfail st + ;; + match st & 0o177 + | 0: -> `Waitexit (st >> 8) + | 0x7f:-> `Waitstop (st >> 8) + | sig: -> `Waitsig sig + ;; +} + diff --git a/test/data/catfile-in b/test/data/catfile-in new file mode 100644 index 0000000..86dd91c --- /dev/null +++ b/test/data/catfile-in @@ -0,0 +1 @@ +Hello-世界 |