diff options
44 files changed, 3724 insertions, 222 deletions
@@ -41,6 +41,7 @@ usage(char *prog) printf("\t-o\tOutput to outfile\n"); printf("\t-O dir\tOutput to dir\n"); printf("\t-S\tGenerate assembly source alongside object code\n"); + printf("\t-T\tCompile in test mode\n"); printf("\t-c\tEnable additional (possibly flaky) checking\n"); printf("\t-I path\tAdd 'path' to use search path\n"); printf("\t-d\tPrint debug dumps. Recognized options: f r p i\n"); @@ -200,7 +201,7 @@ main(int argc, char **argv) outfile = NULL; - optinit(&ctx, "cd:?hSo:I:9G:O:", argv, argc); + optinit(&ctx, "cd:?hSo:I:9G:O:T", argv, argc); asmsyntax = Defaultasm; sizefn = size; while (!optdone(&ctx)) { @@ -240,6 +241,9 @@ main(int argc, char **argv) case 'I': lappend(&incpaths, &nincpaths, ctx.optarg); break; + case 'T': + allowhidden++; + break; default: usage(argv[0]); exit(0); @@ -1006,6 +1006,15 @@ capture(Simp *s, Node *n, Node *dst) envsz->expr.type = tyintptr; assignat(s, e, 0, envsz); assignat(s, fp, 0, e); + } else { + /* + * We need to zero out the environment, so that + * duplicating the function doesn't think we have + * a bogus environment. + */ + e = mkintlit(n->loc, 0); + e->expr.type = tyintptr; + assignat(s, fp, 0, e); } assignat(s, fp, Ptrsz, f); return dst; @@ -41,4 +41,4 @@ uninstallmyr: ./mbldwrap.sh uninstall release: - ./support/release.sh 0.2.0 + ./support/release.sh $(VERSION) @@ -65,6 +65,15 @@ Generate assembly code along with the object file. Generate assembly in the Gnu As syntax. .TP +.B -O out +Output code to output path 'out' + +.TP +.B -T +Compile in test mode. This implies that pkglocal functions are +available. + +.TP .B -9 Generate assembly in the Plan 9 syntax. diff --git a/lib/crypto/bld.sub b/lib/crypto/bld.sub index 1c58997..f6954fd 100644 --- a/lib/crypto/bld.sub +++ b/lib/crypto/bld.sub @@ -12,21 +12,26 @@ lib crypto = # hmac hmac.myr - # ciphers + # symmetric ciphers chacha20.myr aes.myr + # public key ciphers + rsa.myr + # randomness entropy.myr # currently assumes a /dev/random rand.myr # utilities for subtle bits ct.myr + ctbig.myr clear.myr lib ../std:std lib ../sys:sys lib ../thread:thread + lib ../iter:iter ;; diff --git a/lib/crypto/ct.myr b/lib/crypto/ct.myr index 28be694..d6fe34d 100644 --- a/lib/crypto/ct.myr +++ b/lib/crypto/ct.myr @@ -53,7 +53,7 @@ generic le = {a, b generic ne = {a, b const nshift = 8*sizeof(@t) - 1 var q = a ^ b - -> ((q | -q) >> nshift)^1 + -> (q | -q) >> nshift } generic mux = {c, a, b diff --git a/lib/crypto/ctbig.myr b/lib/crypto/ctbig.myr index 59ff5f7..89d0caa 100644 --- a/lib/crypto/ctbig.myr +++ b/lib/crypto/ctbig.myr @@ -1,4 +1,5 @@ use std +use iter use "ct" @@ -9,32 +10,64 @@ pkg crypto = ;; generic mkctbign : (v : @a, nbit : std.size -> ctbig#) :: numeric,integral @a + const ctzero : (nbit : std.size -> ctbig#) + const ctbytesle : (v : ctbig# -> byte[:]) + const ctbytesbe : (v : ctbig# -> byte[:]) const mkctbigle : (v : byte[:], nbit : std.size -> ctbig#) - //const mkctbigbe : (v : byte[:], nbit : std.size -> ctbig#) + const mkctbigbe : (v : byte[:], nbit : std.size -> ctbig#) const ctfree : (v : ctbig# -> void) const ctbigdup : (v : ctbig# -> ctbig#) - const ctlike : (v : ctbig# -> ctbig#) - const ct2big : (v : ctbig# -> std.bigint#) - const big2ct : (v : std.bigint#, ndig : std.size -> ctbig#) - - const ctadd : (r : ctbig#, a : ctbig#, b : ctbig# -> void) - const ctsub : (r : ctbig#, a : ctbig#, b : ctbig# -> void) - const ctmul : (r : ctbig#, a : ctbig#, b : ctbig# -> void) - //const ctdivmod : (r : ctbig#, m : ctbig#, a : ctbig#, b : ctbig# -> void) - //const ctmodpow : (r : ctbig#, a : ctbig#, b : ctbig# -> void) - - const ctiszero : (v : ctbig# -> bool) - const cteq : (a : ctbig#, b : ctbig# -> bool) - const ctne : (a : ctbig#, b : ctbig# -> bool) - const ctgt : (a : ctbig#, b : ctbig# -> bool) - const ctge : (a : ctbig#, b : ctbig# -> bool) - const ctlt : (a : ctbig#, b : ctbig# -> bool) - const ctle : (a : ctbig#, b : ctbig# -> bool) + pkglocal const ct2big : (v : ctbig# -> std.bigint#) + pkglocal const big2ct : (v : std.bigint#, nbit : std.size -> ctbig#) + + /* arithmetic */ + pkglocal const ctadd : (r : ctbig#, a : ctbig#, b : ctbig# -> void) + pkglocal const ctsub : (r : ctbig#, a : ctbig#, b : ctbig# -> void) + pkglocal const ctmul : (r : ctbig#, a : ctbig#, b : ctbig# -> void) + pkglocal const ctmodpow : (r : ctbig#, a : ctbig#, b : ctbig#, m : ctbig# -> void) + + pkglocal const ctiszero : (v : ctbig# -> bool) + pkglocal const cteq : (a : ctbig#, b : ctbig# -> bool) + pkglocal const ctne : (a : ctbig#, b : ctbig# -> bool) + pkglocal const ctgt : (a : ctbig#, b : ctbig# -> bool) + pkglocal const ctge : (a : ctbig#, b : ctbig# -> bool) + pkglocal const ctlt : (a : ctbig#, b : ctbig# -> bool) + pkglocal const ctle : (a : ctbig#, b : ctbig# -> bool) + + /* for testing */ + pkglocal const growmod : (r : ctbig#, a : ctbig#, k : uint32, m : ctbig# -> void) + pkglocal const clip : (v : ctbig# -> ctbig#) + + impl std.equatable ctbig# ;; +const Bits = 32 const Base = 0x100000000ul +impl std.equatable ctbig# = + eq = {a, b + -> cteq(a, b) + } +;; + +const __init__ = { + var ct : ctbig# + + ct = ctzero(0) + std.fmtinstall(std.typeof(ct), ctfmt) + ctfree(ct) +} + +const ctfmt = {sb, ap, opts + var ct : ctbig# + + ct = std.vanext(ap) + for d : iter.byreverse(ct.dig) + std.sbfmt(sb, "{w=8,p=0,x}.", d) + ;; +} + generic mkctbign = {v : @a, nbit : std.size :: integral,numeric @a var a var val @@ -50,7 +83,21 @@ generic mkctbign = {v : @a, nbit : std.size :: integral,numeric @a if nbit > 32 a.dig[1] = (val >> 32 : uint32) ;; - -> a + -> clip(a) +} + +const ctzero = {nbit + -> std.mk([ + .nbit=nbit, + .dig=std.slzalloc(ndig(nbit)), + ]) +} + +const ctdup = {v + -> std.mk([ + .nbit=v.nbit, + .dig=std.sldup(v.dig) + ]) } const ct2big = {ct @@ -60,17 +107,17 @@ const ct2big = {ct ]) } -const big2ct = {ct, nbit +const big2ct = {big, nbit var v, n, l n = ndig(nbit) - l = std.min(n, ct.dig.len) + l = std.min(n, big.dig.len) v = std.slzalloc(n) - std.slcp(v, ct.dig[:l]) - -> std.mk([ + std.slcp(v[:l], big.dig[:l]) + -> clip(std.mk([ .nbit=nbit, .dig=v, - ]) + ])) } const mkctbigle = {v, nbit @@ -84,26 +131,89 @@ const mkctbigle = {v, nbit a = std.slzalloc(ndig(nbit)) for i = 0; i + 4 <= v.len; i += 4 a[o++] = \ - (v[i + 0] << 0 : uint32) | \ - (v[i + 1] << 8 : uint32) | \ - (v[i + 2] << 16 : uint32) | \ - (v[i + 3] << 24 : uint32) + ((v[i + 0] : uint32) << 0) | \ + ((v[i + 1] : uint32) << 8) | \ + ((v[i + 2] : uint32) << 16) | \ + ((v[i + 3] : uint32) << 24) ;; - last = 0 - for i; i < v.len; i++ - off = i & 0x3 - last |= (v[off] : uint32) << (8 *off) + if i != v.len + last = 0 + for i; i < v.len; i++ + off = i & 0x3 + last |= (v[i] : uint32) << (8 *off) + ;; + a[o++] = last ;; - a[o++] = last - -> std.mk([.nbit=nbit, .dig=a]) + -> clip(std.mk([.nbit=nbit, .dig=a])) } -const ctlike = {v - -> std.mk([ - .nbit = v.nbit, - .dig=std.slzalloc(v.dig.len), - ]) +const mkctbigbe = {v, nbit + var a, i, o, tail : byte[4] + + /* + It's ok to depend on the length of v here: we can leak the + size of the numbers. + */ + o = 0 + a = std.slzalloc(ndig(nbit)) + for i = v.len ; i >= 4; i -= 4 + a[o++] = std.getbe32(v[i-4:i]) + ;; + + if i != 0 + std.slfill(tail[:], 0) + std.slcp(tail[4-i:], v[:i]) + a[o++] = std.getbe32(tail[:]) + ;; + -> clip(std.mk([.nbit=nbit, .dig=a])) +} + +const ctbytesle = {v + var d, i, n, o, ret + + o = 0 + n = (v.nbit + 7) / 8 + ret = std.slalloc(n) + for i = 0; i * 4 < n; i++ + d = v.dig[i] + ret[o++] = (d >> 0 : byte) + ret[o++] = (d >> 8 : byte) + ret[o++] = (d >> 16 : byte) + ret[o++] = (d >> 24 : byte) + ;; + + if i * 4 != n + d = v.dig[i] + for ; i < n; i++ + ret[o++] = (d : byte) + d >>= 8 + ;; + ;; + -> ret +} + +const ctbytesbe = {v : ctbig# + var d : uint32, i, n, o, ret + + i = v.dig.len - 1 + o = 0 + n = (v.nbit + 7) / 8 + ret = std.slalloc(n) + if n & 0x3 != 0 + d = v.dig[i--] + for var j = n & 0x3 + 1; j > 0; j-- + ret[o++] = (d >> 8*(j - 1 : uint32): byte) + ;; + ;; + for ; i >= 0 ; i-- + d = v.dig[i] + ret[o++] = (d >> 24 : byte) + ret[o++] = (d >> 16 : byte) + ret[o++] = (d >> 8 : byte) + ret[o++] = (d >> 0 : byte) + ;; + -> ret } const ctbigdup = {v @@ -119,21 +229,29 @@ const ctfree = {v } const ctadd = {r, a, b - var v, i, carry, n + ctaddcc(r, a, b, 1) +} + +const ctaddcc = {r, a, b, ctl + var v, i, carry checksz(a, b) checksz(a, r) carry = 0 - n = max(a.dig.len, b.dig.len) - for i = 0; i < n; i++ + for i = 0; i < a.dig.len; i++ v = (a.dig[i] : uint64) + (b.dig[i] : uint64) + carry; - r.dig[i] = (v : uint32) - carry >>= 32 + r.dig[i] = mux(ctl, (v : uint32), r.dig[i]) + carry = v >> 32 ;; + clip(r) } const ctsub = {r, a, b + ctsubcc(r, a, b, 1) +} + +const ctsubcc = {r, a, b, ctl var borrow, v, i checksz(a, b) @@ -143,9 +261,10 @@ const ctsub = {r, a, b for i = 0; i < a.dig.len; i++ v = (a.dig[i] : uint64) - (b.dig[i] : uint64) - borrow borrow = (v & (1<<63)) >> 63 - v = mux(borrow, v + Base, v) - r.dig[i] = (v : uint32) + r.dig[i] = mux(ctl, (v : uint32), r.dig[i]) ;; + clip(r) + -> borrow } const ctmul = {r, a, b @@ -176,17 +295,201 @@ const ctmul = {r, a, b std.slfree(a.dig) ;; r.dig = w[:a.dig.len] + clip(r) +} + +/* + * Returns the top digit in the number that has + * a bit set. This is useful for finding our division. + */ + const topfull = {n : ctbig# + var top + + top = 0 + for var i = 0; i < n.dig.len; i++ + top = mux(n.dig[i], i, top) + ;; + -> 0 +} + +const unalignedword = {v, bit + var lo, hi, s, i + + s = (bit & 0x1f : uint32) + i = (bit >> 5 : uint32) + lo = v.dig[i] + if s == 0 + hi = 0 + else + hi = v.dig[i + 1] + ;; + -> (lo >> s) | (hi << (32 - s)) } -//const ctmodpow = {res, a, b -// /* find rinv, mprime */ -// -// /* convert to monty space */ -// -// /* do the modpow */ -// -// /* and come back */ -//} +/* + * Multiplies by 2**32 mod m + */ +const growmod = {r, a, k, m + var a0, a1, b0, hi, g, q, tb, e + var chf, clow, under, over + var cc : uint64 + + checksz(a, m) + std.assert(a.dig.len > 1, "bad modulus\n") + std.assert(m.dig[m.dig.len - 1] & (1 << 31) != 0, "top of mod not set: m={}, nbit={}\n", m, m.nbit) + std.assert(m.nbit % 32 == 0, "ragged sizes not yet supported: a.nbit=={}\n", a.nbit) + + a0 = (unalignedword(a, a.nbit - 32) : uint64) << 32 + a1 = (unalignedword(a, a.nbit - 64) : uint64) << 0 + b0 = (unalignedword(m, m.nbit - 32) : uint64) + + /* + * We hold the top digit here, so + * this keeps the number of digits the same, and + * as a result, keeps checksz() happy. + */ + hi = a.dig[a.dig.len - 1] + + /* Do the multiplication of x by 2**32 */ + std.slcp(r.dig[1:], a.dig[:a.dig.len-1]) + r.dig[0] = k + g = ((a0 + a1) / b0 : uint32) + e = eq(a0, b0) + q = mux((e : uint32), 0xffffffff, mux(eq(g, 0), 0, g - 1)); + + cc = 0; + tb = 1; + for var u = 0; u < r.dig.len; u++ + var mw, zw, xw, nxw + var zl : uint64 + + mw = m.dig[u]; + zl = (mw : uint64) * (q : uint64) + cc + cc = zl >> 32 + zw = (zl : uint32) + xw = r.dig[u] + nxw = xw - zw; + cc += (gt(nxw, xw) : uint64) + r.dig[u] = nxw; + tb = mux(eq(nxw, mw), tb, gt(nxw, mw)); + ;; + + /* + * We can either underestimate or overestimate q, + * - If we overestimated, either cc < hi, or cc == hi && tb != 0. + * - If we overestimated, cc > hi. + * - Otherwise, we got it exactly right. + * + * If we overestimated, we need to subtract 'm' once. If we + * underestimated, we need to add it once. + */ + chf = (cc >> 32 : uint32) + clow = (cc >> 0 : uint32) + over = chf | gt(clow, hi); + under = ~over & (tb | (~chf & lt(clow, hi))); + ctaddcc(r, r, m, over); + ctsubcc(r, r, m, under); + clip(r) + +} + +const tomonty = {r, x, m + checksz(x, r) + checksz(x, m) + + std.slcp(r.dig, x.dig) + for var i = 0; i < m.dig.len; i++ + growmod(r, r, 0, m) + ;; +} + +const ccopy = {r, v, ctl + checksz(r, v) + for var i = 0; i < r.dig.len; i++ + r.dig[i] = mux(ctl, v.dig[i], r.dig[i]) + ;; +} + +const muladd = {a, b, k + -> (a : uint64) * (b : uint64) + (k : uint64) +} + +const montymul = {r : ctbig#, x : ctbig#, y : ctbig#, m : ctbig#, m0i : uint32 + var dh : uint64 + var s + + checksz(x, y) + checksz(x, m) + checksz(x, r) + + std.slfill(r.dig, 0) + dh = 0 + for var u = 0; u < x.dig.len; u++ + var f : uint32, xu : uint32 + var r1 : uint64, r2 : uint64, zh : uint64 + + xu = x.dig[u] + f = (r.dig[0] + x.dig[u] * y.dig[0]) * m0i; + r1 = 0; + r2 = 0; + for var v = 0; v < y.dig.len; v++ + var z : uint64 + var t : uint32 + + z = muladd(xu, y.dig[v], r.dig[v]) + r1 + r1 = z >> 32 + t = (z : uint32) + z = muladd(f, m.dig[v], t) + r2 + r2 = z >> 32 + if v != 0 + r.dig[v - 1] = (z : uint32) + ;; + ;; + zh = dh + r1 + r2; + r.dig[r.dig.len - 1] = (zh : uint32) + dh = zh >> 32; + ;; + + /* + * r may still be greater than m at that point; notably, the + * 'dh' word may be non-zero. + */ + s = ne(dh, 0) | (ctge(r, m) : uint64) + ctsubcc(r, r, m, (s : uint32)) +} + +const ninv32 = {x + var y + + y = 2 - x + y *= 2 - y * x + y *= 2 - y * x + y *= 2 - y * x + y *= 2 - y * x + -> mux(x & 1, -y, 0) +} + +const ctmodpow = {r, a, e, m + var t1, t2, m0i, ctl + var n = 0 + + t1 = ctdup(a) + t2 = ctzero(a.nbit) + m0i = ninv32(m.dig[0]) + + tomonty(t1, a, m); + std.slfill(r.dig, 0); + r.dig[0] = 1; + for var i = 0; i < e.nbit; i++ + ctl = (e.dig[i>>5] >> (i & 0x1f : uint32)) & 1 + montymul(t2, r, t1, m, m0i) + ccopy(r, t2, ctl); + montymul(t2, t1, t1, m, m0i); + std.slcp(t1.dig, t2.dig); + ;; + ctfree(t1) + ctfree(t2) +} const ctiszero = {a var z, zz @@ -200,17 +503,14 @@ const ctiszero = {a } const cteq = {a, b - var z, d, e + var nz checksz(a, b) - - e = 1 + nz = 0 for var i = 0; i < a.dig.len; i++ - z = a.dig[i] - b.dig[i] - d = mux(z, 1, 0) - e = mux(e, d, 0) + nz = nz | a.dig[i] - b.dig[i] ;; - -> (e : bool) + -> (eq(nz, 0) : bool) } const ctne = {a, b @@ -221,17 +521,7 @@ const ctne = {a, b } const ctgt = {a, b - var e, d, g - - checksz(a, b) - - g = 0 - for var i = 0; i < a.dig.len; i++ - e = not(a.dig[i] - b.dig[i]) - d = gt(a.dig[i], b.dig[i]) - g = mux(e, g, d) - ;; - -> (g : bool) + -> (ctsubcc(b, b, a, 0) : bool) } const ctge = {a, b @@ -242,17 +532,7 @@ const ctge = {a, b } const ctlt = {a, b - var e, d, l - - checksz(a, b) - - l = 0 - for var i = 0; i < a.dig.len; i++ - e = not(a.dig[i] - b.dig[i]) - d = gt(a.dig[i], b.dig[i]) - l = mux(e, l, d) - ;; - -> (l : bool) + -> (ctsubcc(a, a, b, 0) : bool) } const ctle = {a, b @@ -263,10 +543,20 @@ const ctle = {a, b } const ndig = {nbit - -> (nbit + 8*sizeof(uint32) - 1)/sizeof(uint32) + -> (nbit + 8*sizeof(uint32) - 1)/(8*sizeof(uint32)) } const checksz = {a, b std.assert(a.nbit == b.nbit, "mismatched bit sizes") std.assert(a.dig.len == b.dig.len, "mismatched backing sizes") } + +const clip = {v + var mask, edge : uint64 + + edge = (v.nbit : uint64) & (Bits - 1) + mask = mux(edge, (1 << edge) - 1, ~0) + v.dig[v.dig.len - 1] &= (mask : uint32) + -> v +} + diff --git a/lib/crypto/rsa.myr b/lib/crypto/rsa.myr new file mode 100644 index 0000000..c05ced1 --- /dev/null +++ b/lib/crypto/rsa.myr @@ -0,0 +1,107 @@ +use std + +use "ct" +use "ctbig" +use "rand" + +pkg crypto = + const rsapub_pkcs15 : (msg : byte[:], exp : byte[:], mod : byte[:] -> byte[:]) + + /* + * For unit testing, we need constant output. That means + * to use a constant, deterministic padding. As a result, + * if we pass a non-zero seed size here, we use that seed. + */ + pkglocal const rsapubseed_pkcs15 : (\ + msg : byte[:], + exp : byte[:], + mod : byte[:], + seed : byte[:] -> byte[:]) +;; + +const rsapub_pkcs15 = {msgbuf, expbuf, modbuf + -> rsapubseed_pkcs15(msgbuf, expbuf, modbuf, "") +} + +const rsapubseed_pkcs15 = {msgbuf, expbuf, modbuf, padbuf + var ret, res, msg, exp, mod, nbit + + nbit = bitcount(modbuf) + res = ctzero(nbit) + msg = decodepad(msgbuf, nbit, padbuf) + exp = decode(expbuf, nbit) + mod = decode(modbuf, nbit) + + ctmodpow(res, msg, exp, mod) + ret = ctbytesbe(res) + + ctfree(res) + ctfree(msg) + ctfree(exp) + ctfree(mod) + -> ret +} + +const decodepad = {msg, len, padbuf + var mpad, m + + mpad = pad(msg, (len + 7) / 8, padbuf) + m = mkctbigbe(mpad, len) + std.slfree(mpad) + -> m +} + +const decode = {msg, len + -> mkctbigbe(msg, len) +} + +const pad = {msg, nbytes, padbuf + var buf, pslen + + std.assert(msg.len < nbytes - 11, "overlong message") + buf = std.slalloc(nbytes) + + buf[0] = 0 + buf[1] = 2 + pslen = nbytes - msg.len - 3 + if padbuf.len > 0 + std.slcp(buf[2:pslen+2], padbuf) + else + randbytes(buf[2:pslen+2]) + for var i = 0; i < pslen; i++ + while buf[i + 2] == 0 + randbytes(buf[i+2:i+3]) + ;; + ;; + ;; + buf[pslen + 2] = 0 + std.slcp(buf[pslen+3:], msg) + + -> buf +} + +/* + * Count the number of bits in a pkcs15 modulus. This assumes + * that we're representing the number in a big endian format. + */ +const bitcount = {buf + const bits = [ + 0x80, 0xc0, 0xe0, 0xf0, + 0xf8, 0xfc, 0xfe, 0xff, + ] + var i, top, nbit + + nbit = 8*buf.len + for i = 0; buf[i] == 0 && i < buf.len; i++ + nbit -= 0 + i++ + ;; + top = buf[i] + for b : bits[:] + if top & b != 0 + break + ;; + nbit-- + ;; + -> nbit +} diff --git a/lib/crypto/test/ctbig.myr b/lib/crypto/test/ctbig.myr new file mode 100644 index 0000000..44c031a --- /dev/null +++ b/lib/crypto/test/ctbig.myr @@ -0,0 +1,233 @@ +use std +use crypto +use testr + +const Nbit = 128 +const Nfunky = 79 + +const main = { + testr.run([ + [.name="clip", .fn={ctx + var v = [ + .nbit=32, + .dig=[0xffffffff][:] + ] + crypto.clip(&v) + testr.eq(ctx, v.dig[0], 0xffffffff) + v = [ + .nbit=31, + .dig=[0xffffffff][:] + ] + crypto.clip(&v) + testr.eq(ctx, v.dig[0], 0x7fffffff) + }], + [.name="mkbig-le", .fn={ctx + docvt(ctx, crypto.mkctbigle, Nbit, + "6618611909121", + "\x01\x02\x03\x04\x05\x06") + }], + [.name="mkbig-be", .fn={ctx + docvt(ctx, crypto.mkctbigbe, Nbit, + "1108152157446", + "\x00\x01\x02\x03\x04\x05\x06") + }], + /* normal */ + [.name="add", .fn={ctx + do2(ctx, crypto.ctadd, Nbit, + "5192296858610368357189246603769160", + "5192296858534810493479828944327220", + "75557863709417659441940") + }], + [.name="sub", .fn={ctx + do2(ctx, crypto.ctsub, Nbit, + "5192296858459252629770411284885280", + "5192296858534810493479828944327220", + "75557863709417659441940") + }], + [.name="mul", .fn={ctx + do2(ctx, crypto.ctmul, Nbit, + "392318858376010676506814412592879878824393346033951606800", + "5192296858534810493479828944327220", + "75557863709417659441940") + }], + [.name="growmod", .fn={ctx + do2(ctx, growmod0, Nbit, + "259016584597313952181375284077740334036", + "137304361882109849168381018424069802644", + "279268927326277818181333274586733399084") + }], + /* comparisons */ + [.name="lt-less", .fn={ctx + dobool(ctx, crypto.ctlt, Nbit, + true, + "137304361882109849168381018424069802644", + "279268927326277818181333274586733399084") + }], + [.name="lt-equal", .fn={ctx + dobool(ctx, crypto.ctlt, Nbit, + false, + "137304361882109849168381018424069802644", + "137304361882109849168381018424069802644") + }], + [.name="lt-greater", .fn={ctx + dobool(ctx, crypto.ctlt, Nbit, + false, + "279268927326277818181333274586733399084", + "137304361882109849168381018424069802644") + }], + [.name="gt-less", .fn={ctx + dobool(ctx, crypto.ctgt, Nbit, + false, + "137304361882109849168381018424069802644", + "279268927326277818181333274586733399084") + }], + [.name="gt-equal", .fn={ctx + dobool(ctx, crypto.ctgt, Nbit, + false, + "137304361882109849168381018424069802644", + "137304361882109849168381018424069802644") + }], + [.name="gt-greater", .fn={ctx + dobool(ctx, crypto.ctgt, Nbit, + true, + "279268927326277818181333274586733399084", + "137304361882109849168381018424069802644") + }], + [.name="growmodsmall", .fn={ctx + do2(ctx, growmod0, Nbit, + "30064771072", + "7", + "279268927326277818181333274586733399084") + }], + [.name="addfunky", .fn={ctx + do2(ctx, crypto.ctadd, Nfunky, + "75540728658750274549064", + "5192296858534810493479828944327220", + "75557863709417659441940") + }], + [.name="subfunky", .fn={ctx + do2(ctx, crypto.ctsub, Nfunky, + "528887911047229543018272", + "5192296858534810493479828944327220", + "75557863709417659441940") + }], + [.name="mulfunky", .fn={ctx + do2(ctx, crypto.ctmul, Nfunky, + "434472066238453871708176", + "5192296858534810493479828944327220", + "75557863709417659441940") + }], + [.name="modpow-nop", .fn={ctx + do3(ctx, crypto.ctmodpow, Nbit, + "1231231254019581241243091223098123", + "1231231254019581241243091223098123", + "1", + "238513807008428752753137056878245001837") + }], + [.name="modpow-small", .fn={ctx + do3(ctx, crypto.ctmodpow, Nbit, + "190803258902817973474500147337505443108", + "1231231254019581241243091223098123", + "7", + "238513807008428752753137056878245001837") + }], + [.name="modpow", .fn={ctx + do3(ctx, crypto.ctmodpow, Nbit, + "134487661739548107356399382114451163287", + "1231231254019581241243091223098123", + "312312091230", + "238513807008428752753137056878245001837") + }], + ][:]) +} + +const growmod0 = {r, a, b + crypto.growmod(r, a, 0, b) +} + +const dobool = {ctx, op, nbit, e, astr, bstr + var r, a, ai, b, bi + + r = crypto.ctzero(nbit) + ai = std.get(std.bigparse(astr)) + bi = std.get(std.bigparse(bstr)) + a = crypto.big2ct(ai, nbit) + b = crypto.big2ct(bi, nbit) + + std.bigfree(ai) + std.bigfree(bi) + testr.eq(ctx, op(a, b), e) + + crypto.ctfree(a) + crypto.ctfree(b) +} + +const docvt = {ctx, op, nbit, estr, buf + var v, e, ei + + ei = std.get(std.bigparse(estr)) + e = crypto.big2ct(ei, nbit) + std.bigfree(ei) + + v = op(buf, nbit) + testr.eq(ctx, v, e) + + crypto.ctfree(e) + crypto.ctfree(v) +} + +const do2 = {ctx, op, nbit, estr, astr, bstr + var r, a, ai, b, bi, e, ei + + r = crypto.ctzero(nbit) + ei = std.get(std.bigparse(estr)) + ai = std.get(std.bigparse(astr)) + bi = std.get(std.bigparse(bstr)) + e = crypto.big2ct(ei, nbit) + a = crypto.big2ct(ai, nbit) + b = crypto.big2ct(bi, nbit) + + std.bigfree(ei) + std.bigfree(ai) + std.bigfree(bi) + + op(r, a, b) + + testr.eq(ctx, r, e) + + crypto.ctfree(r) + crypto.ctfree(e) + crypto.ctfree(a) + crypto.ctfree(b) +} + + +const do3 = {ctx, op, nbit, estr, astr, bstr, cstr + var r, a, ai, b, bi, c, ci, e, ei + + r = crypto.ctzero(nbit) + ei = std.get(std.bigparse(estr)) + ai = std.get(std.bigparse(astr)) + bi = std.get(std.bigparse(bstr)) + ci = std.get(std.bigparse(cstr)) + e = crypto.big2ct(ei, nbit) + a = crypto.big2ct(ai, nbit) + b = crypto.big2ct(bi, nbit) + c = crypto.big2ct(ci, nbit) + + std.bigfree(ei) + std.bigfree(ai) + std.bigfree(bi) + + op(r, a, b, c) + + testr.eq(ctx, r, e) + + crypto.ctfree(r) + crypto.ctfree(e) + crypto.ctfree(a) + crypto.ctfree(b) + crypto.ctfree(c) +} + + diff --git a/lib/crypto/test/rsa.myr b/lib/crypto/test/rsa.myr new file mode 100644 index 0000000..c03d9b2 --- /dev/null +++ b/lib/crypto/test/rsa.myr @@ -0,0 +1,65 @@ +use std +use crypto +use iter +use testr + +type pubcase = struct + name : byte[:] + nbit : std.size + msg : byte[:] + exp : byte[:] + mod : byte[:] + seed : byte[:] + ctext : byte[:] +;; + +const main = { + for case : iter.byref(pubcases) + testr.run([ + [.name=case.name, .fn={ctx + var ct + ct = crypto.rsapubseed_pkcs15(case.msg, case.exp, case.mod, case.seed) + testr.eq(ctx, ct, case.ctext) + }], + ][:]) + ;; +} + +const pubcases : pubcase[:] = [ + [ + .name="basic", + .nbit=1024, + .mod=\ + "\xa8\xb3\xb2\x84\xaf\x8e\xb5\x0b\x38\x70\x34\xa8\x60\xf1\x46\xc4" \ + "\x91\x9f\x31\x87\x63\xcd\x6c\x55\x98\xc8\xae\x48\x11\xa1\xe0\xab" \ + "\xc4\xc7\xe0\xb0\x82\xd6\x93\xa5\xe7\xfc\xed\x67\x5c\xf4\x66\x85" \ + "\x12\x77\x2c\x0c\xbc\x64\xa7\x42\xc6\xc6\x30\xf5\x33\xc8\xcc\x72" \ + "\xf6\x2a\xe8\x33\xc4\x0b\xf2\x58\x42\xe9\x84\xbb\x78\xbd\xbf\x97" \ + "\xc0\x10\x7d\x55\xbd\xb6\x62\xf5\xc4\xe0\xfa\xb9\x84\x5c\xb5\x14" \ + "\x8e\xf7\x39\x2d\xd3\xaa\xff\x93\xae\x1e\x6b\x66\x7b\xb3\xd4\x24" \ + "\x76\x16\xd4\xf5\xba\x10\xd4\xcf\xd2\x26\xde\x88\xd3\x9f\x16\xfb", + .exp="\x01\x00\x01", + .msg=\ + "\x66\x28\x19\x4e\x12\x07\x3d\xb0\x3b\xa9\x4c\xda\x9e\xf9\x53\x23" \ + "\x97\xd5\x0d\xba\x79\xb9\x87\x00\x4a\xfe\xfe\x34", + .seed=\ + "\x01\x73\x41\xae\x38\x75\xd5\xf8\x71\x01\xf8\xcc\x4f\xa9\xb9\xbc" \ + "\x15\x6b\xb0\x46\x28\xfc\xcd\xb2\xf4\xf1\x1e\x90\x5b\xd3\xa1\x55" \ + "\xd3\x76\xf5\x93\xbd\x73\x04\x21\x08\x74\xeb\xa0\x8a\x5e\x22\xbc" \ + "\xcc\xb4\xc9\xd3\x88\x2a\x93\xa5\x4d\xb0\x22\xf5\x03\xd1\x63\x38" \ + "\xb6\xb7\xce\x16\xdc\x7f\x4b\xbf\x9a\x96\xb5\x97\x72\xd6\x60\x6e" \ + "\x97\x47\xc7\x64\x9b\xf9\xe0\x83\xdb\x98\x18\x84\xa9\x54\xab\x3c" \ + "\x6f", + + .ctext=\ + "\x50\xb4\xc1\x41\x36\xbd\x19\x8c\x2f\x3c\x3e\xd2\x43\xfc\xe0\x36" \ + "\xe1\x68\xd5\x65\x17\x98\x4a\x26\x3c\xd6\x64\x92\xb8\x08\x04\xf1" \ + "\x69\xd2\x10\xf2\xb9\xbd\xfb\x48\xb1\x2f\x9e\xa0\x50\x09\xc7\x7d" \ + "\xa2\x57\xcc\x60\x0c\xce\xfe\x3a\x62\x83\x78\x9d\x8e\xa0\xe6\x07" \ + "\xac\x58\xe2\x69\x0e\xc4\xeb\xc1\x01\x46\xe8\xcb\xaa\x5e\xd4\xd5" \ + "\xcc\xe6\xfe\x7b\x0f\xf9\xef\xc1\xea\xbb\x56\x4d\xbf\x49\x82\x85" \ + "\xf4\x49\xee\x61\xdd\x7b\x42\xee\x5b\x58\x92\xcb\x90\x60\x1f\x30" \ + "\xcd\xa0\x7b\xf2\x64\x89\x31\x0b\xcd\x23\xb5\x28\xce\xab\x3c\x31", + ] +][:] + diff --git a/lib/regex/interp.myr b/lib/regex/interp.myr index 15e2230..6db8495 100644 --- a/lib/regex/interp.myr +++ b/lib/regex/interp.myr @@ -173,7 +173,13 @@ const getidxmatches = {re, thr -> `std.Some ret } -/* returns a matching thread, or Zthr if no threads matched */ +/* + * Run manages the virtual machine state, and schedules the + * regex threads. Each linear match runs in its own thread. + * When a new thread is created, it is carefully scheduled + * after the current thread, to ensure that match order is + * preserved. + */ const run = {re, str, idx, wholestr var bestmatch var consumed @@ -189,7 +195,13 @@ const run = {re, str, idx, wholestr states = std.mkbs() re.runq = mkthread(re, 0) if re.debug - /* The last run could have left things here, since we need this info after the run */ + /* + If we're in debug mode, then we keep + the traces around, so we can show them + to the user. To avoid leaking, we need + to free the traces from the last run + when we start a new one. + */ for bs : re.traces std.bsfree(bs) ;; @@ -206,16 +218,34 @@ const run = {re, str, idx, wholestr if re.trace std.put("switch\n") ;; - /* set up the next thread */ thr = re.runq re.runq = thr.next ip = thr.ip + /* + Stepping continues until the first + non-consuming operator is seen. This + keeps all the threads in lockstep, + which means that when a match is + encountered, we know all the other + threads have seen what they need + to, and we can terminate them. + */ consumed = step(re, thr, -1) while !consumed consumed = step(re, thr, ip) ;; + /* + * Because threads have no memory, + * their ip (and current input + * character, which is the same + * thanks to the above mentioned + * lockstep) uniquely identify them. + * As a result, if we have two + * threads with the same ip, one of + * them can be culled. + */ if std.bshas(states, thr.ip) die(re, thr) ;; @@ -259,10 +289,26 @@ const run = {re, str, idx, wholestr -> bestmatch } -/* - Steps forward one instruction. Returns true if a byte of input was - consumed, false otherwise. -*/ +/* + * Step executes a single step of the compiled regex. + * + * Operations fall into two overall categories. Consuming + * operators advance the match, and nonconsuming operators + * change the state of the regex virtual machine. + * + * Consuming operators are simple: They check if the current + * character matches a criteria, and then advance the regex. + * + * Nonconsuming operators can do one of several things. They + * can fork the vm, record a successful match, or mark a + * thread as a failure. + * + * A thread continues to run forward until a consuming + * opcode is encountered, after which it must switch. + * This is in order to keep all threads in lockstep + * operating over the same characters, and finishing + * at the same time. + */ const step = {re, thr, curip var str, nthr, inst @@ -275,7 +321,7 @@ const step = {re, thr, curip std.bsput(re.traces[thr.tid], thr.ip) ;; match inst & 0xf - /* Char matching. Consume exactly one byte from the string. */ + /* Consuming opcodes */ | OpRange: var lo = (inst >> 4 : byte) var hi = (inst >> 16 : byte) @@ -308,10 +354,7 @@ const step = {re, thr, curip ;; thr.ip = lip -> false - /* - Non-consuming. All of these return false, and expect step to be - called again until exactly one byte is consumed from the string. - */ + /* Non-consuming opcodes. */ | OpJmp: var ip = (inst >> 4 : std.size) thr.ip = ip @@ -345,7 +388,6 @@ const step = {re, thr, curip else die(re, thr) ;; - /* check for word characters */ | OpBow: if iswordchar(str[re.strp:]) && (re.strp == 0 || !iswordchar(prevchar(str, re.strp))) thr.ip++ @@ -443,7 +485,6 @@ const itrace = {re, thr, inst ;; } -/* must be called with i >= 1 */ const prevchar = {s, i std.assert(i != 0, "prevchar must be called with i >= 1\n") i-- diff --git a/lib/regex/redump.myr b/lib/regex/redump.myr index 4a4fe8f..6ac04ce 100644 --- a/lib/regex/redump.myr +++ b/lib/regex/redump.myr @@ -68,6 +68,21 @@ const dump = {re, fd ;; } +/* + * Renders a match in a way that's pleasant to read. There are + * two cases here. + * + * 1) The pattern matched. In this case, we want to show the + * regions of the pattern that contributed to the match. + * + * 2) The pattern did not match. In this case, we want to show + * the location of the failed match. + * + * In both cases, we render a caret that describes the position + * of the match. Unfortunately, for the coverage code we don't + * have a great way of mapping whole subranges, so the caret can + * be slightly truncated. Fixing this isn't worth hte complexity. + */ const show = {re, ln, mg match mg | `std.Some rl: @@ -81,13 +96,21 @@ const show = {re, ln, mg | `std.None: std.put("Match failed at {}:\n", re.lastip) std.put("\t{}\n", re.pat) - caret(re, re.pcidx[re.lastip]) + showpos(re, re.pcidx[re.lastip]) std.put("\t{}\n", ln) - caret(re, re.strp - 1) + showpos(re, re.strp - 1) ;; } -const caret = {re, idx +/* + * Simple position carets for failures: Draws out + * an arrow of the form: + * + * ~~~~~^ + * + * from the start of the line. + */ +const showpos = {re, idx std.put("\t") for var i = 0; i < idx; i++ std.put("~") @@ -95,6 +118,13 @@ const caret = {re, idx std.put("^\n") } +/* + * Coverage carets for success. This tries to output + * a '^' for every section of the string that matched. + * + * (this|that) + * ^^^^ + */ const showcoverage = {re var hit var idx diff --git a/lib/std/bigint.myr b/lib/std/bigint.myr index d708f7d..afa65c1 100644 --- a/lib/std/bigint.myr +++ b/lib/std/bigint.myr @@ -741,7 +741,6 @@ const bigdivmod = {a : bigint#, b : bigint# -> (bigint#, bigint#) ;; /* undo the biasing for remainder */ bigshri(u, shift) - trim(q) bigfree(v) -> (trim(q), trim(u)) } diff --git a/lib/std/env+posixy.myr b/lib/std/env+posixy.myr index 7ee9e43..cf4d8f7 100644 --- a/lib/std/env+posixy.myr +++ b/lib/std/env+posixy.myr @@ -59,21 +59,25 @@ const setenv = {name, val lock(envlck) for envp : environ - if envp != Zenvp - env = cstrconvp(envp) - n = min(name.len, env.len - 1) - if eq(name, env[:n]) && env[n] == ('=' : byte) - found = true - break - ;; - idx++ + if envp == Zenvp + break + ;; + + env = cstrconvp(envp) + n = min(name.len, env.len - 1) + if eq(name, env[:n]) && env[n] == ('=' : byte) + found = true + break ;; + idx++ ;; - if !found - idx = env.len - 1 + if found + std.slfree(cstrconvp(environ[idx])) + else + idx = environ.len - 1 std.slpush(&environ, Zenvp) ;; - e = cstrconvp(environ[idx]) + environ[idx] = (e : byte#) sys.__cenvp = (environ : byte##) unlock(envlck) } diff --git a/lib/std/fmt.myr b/lib/std/fmt.myr index c26d5c4..c7e7eda 100644 --- a/lib/std/fmt.myr +++ b/lib/std/fmt.myr @@ -492,7 +492,12 @@ const strfmt = {sb, str, params | ("p", pad): p = decode(pad) | ("r", ""): raw = true | ("e", ""): esc = true - | _: std.die("unreachable\n") + | (opt, arg): + std.write(2, "fmt: ") + std.write(2, opt) + std.write(2, "arg: ") + std.write(2, arg) + std.die("unreachable\n") ;; ;; iassert(p >= 0, "pad must be >= 0") diff --git a/lib/std/hashfuncs.myr b/lib/std/hashfuncs.myr index 013bfde..96eb91a 100644 --- a/lib/std/hashfuncs.myr +++ b/lib/std/hashfuncs.myr @@ -18,6 +18,12 @@ pkg std = } ;; + impl equatable bool = + eq = {a, b + -> a == b + } + ;; + impl equatable @a :: integral,numeric @a = eq = {a, b -> a == b diff --git a/lib/std/strfind.myr b/lib/std/strfind.myr index 3645f8c..f446f69 100644 --- a/lib/std/strfind.myr +++ b/lib/std/strfind.myr @@ -8,19 +8,16 @@ pkg std = ;; const strfind = {haystack, needle - -> strfindin(haystack, needle, 0, haystack.len) + -> strfindin(haystack, needle, 0, haystack.len, 1) } const strrfind = {haystack, needle - -> strfindin(haystack, needle, haystack.len - 1, -1) + -> strfindin(haystack, needle, haystack.len - 1, -1, -1) } -const strfindin = {haystack, needle, start, end - var inc : size - - inc = 1 - if start > end - inc = -1 +const strfindin = {haystack, needle, start, end, inc + if haystack.len == 0 && needle.len == 0 + -> `std.Some 0 ;; for var i = start; i != end; i += inc /* @@ -30,14 +27,12 @@ const strfindin = {haystack, needle, start, end if i + needle.len > haystack.len continue ;; - if haystack[i] == needle[0] - for var j = 0; j < needle.len; j++ - if haystack[i + j] != needle[j] - goto nextiter - ;; + for var j = 0; j < needle.len; j++ + if haystack[i + j] != needle[j] + goto nextiter ;; - -> `Some i ;; + -> `Some i :nextiter ;; -> `None diff --git a/lib/std/test/fltbits.myr b/lib/std/test/fltbits.myr index 3907a0f..6493231 100644 --- a/lib/std/test/fltbits.myr +++ b/lib/std/test/fltbits.myr @@ -1,8 +1,18 @@ use std - use testr +var testnan + const main = { + var si + + /* Floating point mode traps on 9front. */ + std.getsysinfo(&si) + match si.system + | "Plan9": testnan = false + | _: testnan = true + ;; + testr.run([ [.name = "isnan", .fn = isnan01], [.name = "bits-roundtrip-32", .fn = bitsround32], @@ -15,24 +25,26 @@ const main = { } const isnan01 = {c - testr.check(c, std.isnan(std.flt64nan()), "std.flt64nan() should give a NaN") - testr.check(c, std.isnan(std.flt32nan()), "std.flt32nan() should give a NaN") - - /* - a NaN should be {any sign bit}, then {8 or 11 exponent - bits, all 1}, then {any non-zero sequence of 23 or 52 - bits} - */ - testr.check(c, std.isnan(std.flt64frombits(0xfff0000500000000ul)), "0xfff0000500000000 should be a NaN") - testr.check(c, std.isnan(std.flt64frombits(0x7ff0000500000000ul)), "0x7ff0000500000000 should be a NaN") - testr.check(c, std.isnan(std.flt32frombits(0xff800090)), "0xff800090 should be a NaN") - testr.check(c, std.isnan(std.flt32frombits(0x7f800090)), "0x7f800090 should be a NaN") - - /* if the significand bits are all 0, it's an infinity instead */ - testr.check(c, !std.isnan(std.flt64frombits(0x7ff0000000000000ul)), "Infinities[1] should not be NaNs") - testr.check(c, !std.isnan(std.flt64frombits(0xfff0000000000000ul)), "Infinities[2] should not be NaNs") - testr.check(c, !std.isnan(std.flt32frombits(0xff800000)), "Infinities[3] should not be NaNs") - testr.check(c, !std.isnan(std.flt32frombits(0x7f800000)), "Infinities[4] should not be NaNs") + if testnan + testr.check(c, std.isnan(std.flt64nan()), "std.flt64nan() should give a NaN") + testr.check(c, std.isnan(std.flt32nan()), "std.flt32nan() should give a NaN") + + /* + a NaN should be {any sign bit}, then {8 or 11 exponent + bits, all 1}, then {any non-zero sequence of 23 or 52 + bits} + */ + testr.check(c, std.isnan(std.flt64frombits(0xfff0000500000000ul)), "0xfff0000500000000 should be a NaN") + testr.check(c, std.isnan(std.flt64frombits(0x7ff0000500000000ul)), "0x7ff0000500000000 should be a NaN") + testr.check(c, std.isnan(std.flt32frombits(0xff800090)), "0xff800090 should be a NaN") + testr.check(c, std.isnan(std.flt32frombits(0x7f800090)), "0x7f800090 should be a NaN") + + /* if the significand bits are all 0, it's an infinity instead */ + testr.check(c, !std.isnan(std.flt64frombits(0x7ff0000000000000ul)), "Infinities[1] should not be NaNs") + testr.check(c, !std.isnan(std.flt64frombits(0xfff0000000000000ul)), "Infinities[2] should not be NaNs") + testr.check(c, !std.isnan(std.flt32frombits(0xff800000)), "Infinities[3] should not be NaNs") + testr.check(c, !std.isnan(std.flt32frombits(0x7f800000)), "Infinities[4] should not be NaNs") + ;; } const bitsround32 = {c @@ -46,9 +58,11 @@ const bitsround32 = {c testr.check(c, u == v, "bits -> flt -> bits non-identity: {} != {}", u, v) ;; - var nan_f = std.flt32frombits(0xff800090) - var nan_g = std.flt32frombits(std.flt32bits(nan_f)) - testr.check(c, nan_f == nan_g, "flt -> bits -> flt non-identity for nan") + if testnan + var nan_f = std.flt32frombits(0xff800090) + var nan_g = std.flt32frombits(std.flt32bits(nan_f)) + testr.check(c, nan_f == nan_g, "flt -> bits -> flt non-identity for nan") + ;; var inf_f = std.flt32frombits(0x7f800000) var inf_g = std.flt32frombits(std.flt32bits(inf_f)) @@ -66,9 +80,11 @@ const bitsround64 = {c testr.check(c, u == v, "bits -> flt -> bits non-identity: {} != {}", u, v) ;; - var nan_f = std.flt64frombits(0x7ff000000000a000ul) - var nan_g = std.flt64frombits(std.flt64bits(nan_f)) - testr.check(c, nan_f == nan_g, "flt -> bits -> flt non-identity for nan") + if testnan + var nan_f = std.flt64frombits(0x7ff000000000a000ul) + var nan_g = std.flt64frombits(std.flt64bits(nan_f)) + testr.check(c, nan_f == nan_g, "flt -> bits -> flt non-identity for nan") + ;; var inf_f = std.flt64frombits(0xfff0000000000000ul) var inf_g = std.flt64frombits(std.flt64bits(inf_f)) diff --git a/lib/sys/bld.sub b/lib/sys/bld.sub index abf90f5..6bc266b 100644 --- a/lib/sys/bld.sub +++ b/lib/sys/bld.sub @@ -5,10 +5,13 @@ lib sys = sys+netbsd-x64.myr sys+linux-x64.myr sys+osx-x64.myr + sys+plan9-x64.myr + + # openbsd versions. sys+openbsd-x64.myr sys+openbsd:6.1-x64.myr sys+openbsd:6.2-x64.myr - sys+plan9-x64.myr + sys+openbsd:6.3-x64.myr syscall+freebsd-x64.s syscall+netbsd-x64.s diff --git a/lib/sys/sys+openbsd-x64.myr b/lib/sys/sys+openbsd-x64.myr index 7b0df69..454567a 100644 --- a/lib/sys/sys+openbsd-x64.myr +++ b/lib/sys/sys+openbsd-x64.myr @@ -215,6 +215,7 @@ pkg sys = const Mfixed : mopt = 0x10 const Mfile : mopt = 0x0 const Manon : mopt = 0x1000 + const Mstack : mopt = 0x4000 const Mnoreplace : mopt = 0x0800 /* file types */ diff --git a/lib/sys/sys+openbsd:6.2-x64.myr b/lib/sys/sys+openbsd:6.2-x64.myr index 4a1f0e5..62bc1d2 100644 --- a/lib/sys/sys+openbsd:6.2-x64.myr +++ b/lib/sys/sys+openbsd:6.2-x64.myr @@ -348,6 +348,7 @@ pkg sys = const Mfixed : mopt = 0x10 const Mfile : mopt = 0x0 const Manon : mopt = 0x1000 + const Mstack : mopt = 0x4000 const Mnoreplace : mopt = 0x0800 /* file types */ diff --git a/lib/sys/sys+openbsd:6.3-x64.myr b/lib/sys/sys+openbsd:6.3-x64.myr new file mode 100644 index 0000000..82a6b17 --- /dev/null +++ b/lib/sys/sys+openbsd:6.3-x64.myr @@ -0,0 +1,1759 @@ +/* + generated-ish source + stitched for openbsd:6.3 arch:x64 + edit with caution. + */ +pkg sys = + type size = int64 /* spans entire address space */ + type usize = uint64 /* unsigned size */ + type off = int64 /* file offsets */ + type intptr = uint64/* can hold any pointer losslessly */ + type time = int64 /* milliseconds since epoch */ + type pid = int32 /* process id */ + type scno = int64 /*syscall*/ + type fdopt = int64 /* fd options */ + type fd = int32 /* fd */ + type whence = uint64 /* seek from whence */ + type mprot = int64 /* memory protection */ + type mopt = int64 /* memory mapping options */ + type socktype = int64 /* socket type */ + type sockproto = int64 /* socket protocol */ + type sockopt = int32 /* socket option */ + type sockfam = uint8 /* socket family */ + type filemode = uint32 + type filetype = uint8 + type fcntlcmd = int64 + type signo = int32 + type sigflags = int32 + type sigset = uint32 + type msg = void + type gid = uint32 + + const Futexwait : int = 1 + const Futexwake : int = 2 + const Futexrequeue : int = 3 + + + type clock = union + `Clockrealtime + `Clockmonotonic + `Clockproccputime + `Clockthreadcputime + `Clockuptime + ;; + + type waitstatus = union + `Waitfail int32 + `Waitexit int32 + `Waitsig int32 + `Waitstop int32 + ;; + + type rlimit = struct + cur : uint64 /* current (soft) limit */ + max : uint64 /* maximum value for rlim_cur */ + ;; + + type timespec = struct + sec : uint64 + nsec : uint64 + ;; + + type timeval = struct + sec : uint64 + usec : uint64 + ;; + + type timezone = struct + minwest : int32 /* minutes west of Greenwich */ + dsttime : int32 /* type of dst correction */ + ;; + + type pollfd = struct + fd : fd + events : uint16 + revents : uint16 + ;; + + type itimerval = struct + interval : timeval /* timer interval */ + value : timeval /* current value */ + ;; + + type sigaction = struct + handler : byte# /* code pointer */ + mask : sigset + flags : sigflags + ;; + /* + * Information pushed on stack when a signal is delivered. + * This is used by the kernel to restore state following + * execution of the signal handler. It is also made available + * to the handler to allow it to restore state properly if + * a non-standard exit is performed. + */ + type sigcontext = struct + /* plain match trapframe */ + rdi : int64 + rsi : int64 + rdx : int64 + rcx : int64 + r8 : int64 + r9 : int64 + r10 : int64 + r11 : int64 + r12 : int64 + r13 : int64 + r14 : int64 + r15 : int64 + rbp : int64 + rbx : int64 + rax : int64 + gs : int64 + fs : int64 + es : int64 + ds : int64 + trapno : int64 + err : int64 + rip : int64 + cs : int64 + rflags : int64 + rsp : int64 + ss : int64 + + fpstate : fxsave64# + __pad : int32 + mask : int32 + cookie : int64 + ;; + + type sigaltstack = struct + sp : void# + size : size + flags : int32 + ;; + + type fxsave64 = struct + fcw : int16 + fsw : int16 + ftw : int8 + unused1 : int8 + fop : int16 + rip : int64 + rdp : int64 + mxcsr : int32 + mxcsrmask : int32 + st : int64[8][2] /* 8 normal FP regs */ + xmm : int64[16][2] /* 16 SSE2 registers */ + unused3 : int8[96] + ;; + + const Simaxsz = 128 + const Sipad = (Simaxsz / 4) - 3 + type siginfo = struct + signo : int + code : int + errno : int + pad : int[Sipad] + ;; + + type rusage = struct + utime : timeval /* user time */ + stime : timeval /* system time */ + maxrss : uint64 /* max resident set size*/ + ixrss : uint64 /* shared text size */ + idrss : uint64 /* unshared data size */ + isrss : uint64 /* unshared stack size */ + minflt : uint64 /* page reclaims */ + majflt : uint64 /* page faults */ + nswap : uint64 /* swaps */ + inblock : uint64 /* block input ops */ + oublock : uint64 /* block output ops */ + msgsnd : uint64 /* messages sent */ + msgrcv : uint64 /* messages received */ + nsignals : uint64 /* signals received */ + nvcsw : uint64 /* voluntary context switches */ + nivcsw : uint64 /* involuntary context switches */ + ;; + + type tforkparams = struct + tcb : void# + tid : pid# + stk : byte# + ;; + + type statbuf = struct + mode : filemode + dev : uint32 + ino : uint64 + nlink : uint32 + uid : uint32 + gid : uint32 + rdev : uint32 + atime : timespec + mtime : timespec + ctime : timespec + size : off + blocks : int64 + blksize : uint32 + flags : uint32 + gen : uint32 + birthtim : timespec + ;; + + type semun = struct + semarr : void# + ;; + + const Mfsnamelen = 16 /* length of fs type name, including nul */ + const Mnamelen = 90 /* length of buffer for returned name */ + + type statfs = struct + flags : uint32 /* copy of mount flags */ + bsize : uint32 /* file system block size */ + iosize : uint32 /* optimal transfer block size */ + + /* unit is f_bsize */ + blocks : uint64 /* total data blocks in file system */ + bfree : uint64 /* free blocks in fs */ + bavail : int64 /* free blocks avail to non-superuser */ + + files : int64 /* total file nodes in file system */ + ffree : int64 /* free file nodes in fs */ + favail : int64 /* free file nodes avail to non-root */ + + syncwr : int64 /* count of sync writes since mount */ + syncrd : int64 /* count of sync reads since mount */ + asyncwr : int64 /* count of async writes since mount */ + asyncrd : int64 /* count of async reads since mount */ + + fsid : fsid /* file system id */ + namemax : uint32 /* maximum filename length */ + owner : uid /* user that mounted the file system */ + ctime : uint64 /* last mount [-u] time */ + + fstypename : byte[Mfsnamelen]; /* fs type name */ + mntonname : byte[Mnamelen]; /* directory on which mounted */ + mntfromname : byte[Mnamelen]; /* mounted file system */ + mntfromspec : byte[Mnamelen]; /* special for mount request */ + ///union mount_info mount_info; /* per-filesystem mount options */ + __mountinfo : byte[160]; /* storage for 'union mount_info' */ + ;; + + type utsname = struct + system : byte[32] + node : byte[32] + release : byte[32] + version : byte[32] + machine : byte[32] + ;; + + type sockaddr = struct + len : byte + fam : sockfam + data : byte[14] /* what is the *actual* length? */ + ;; + + type sockaddr_in = struct + len : byte + fam : sockfam + port : uint16 + addr : byte[4] + zero : byte[8] + ;; + + type sockaddr_in6 = struct + len : byte + fam : sockfam + port : uint16 + flow : uint32 + addr : byte[16] + scope : uint32 + ;; + + type sockaddr_un = struct + len : uint8 + fam : sockfam + path : byte[104] + ;; + + type sockaddr_storage = struct + len : byte + fam : sockfam + __pad1 : byte[6] + __align : int64 + __pad2 : byte[240] + ;; + + type dirent = struct + fileno : uint64 + off : uint64 + reclen : uint16 + ftype : uint8 + namlen : uint8 + __pad : byte[4] + name : byte[256] + ;; + + type iovec = struct + base : byte# + len : uint64 + ;; + + /* open options */ + const Ordonly : fdopt = 0x0 + const Owronly : fdopt = 0x1 + const Ordwr : fdopt = 0x2 + const Oappend : fdopt = 0x8 + const Ondelay : fdopt = 0x4 + const Oshlock : fdopt = 0x10 /* open with shared file lock */ + const Oexlock : fdopt = 0x20 /* open with exclusive file lock */ + const Oasync : fdopt = 0x40 /* signal pgrp when data ready */ + const Osync : fdopt = 0x80 /* backwards compatibility */ + const Onofollow : fdopt = 0x100 + const Ocreat : fdopt = 0x200 + const Otrunc : fdopt = 0x400 + const Oexcl : fdopt = 0x800 + const Ocloexec : fdopt = 0x10000 + const Odsync : fdopt = Osync /* synchronous data writes */ + const Orsync : fdopt = Osync /* synchronous reads */ + const Odir : fdopt = 0x20000 + + /* poll options */ + const Pollin : uint16 = 0x0001 + const Pollpri : uint16 = 0x0002 + const Pollout : uint16 = 0x0004 + const Pollerr : uint16 = 0x0008 + const Pollhup : uint16 = 0x0010 + const Pollnval : uint16 = 0x0020 + const Pollnorm : uint16 = 0x0040 + const Pollrdband: uint16 = 0x0080 + const Pollwrband: uint16 = 0x0100 + + /* stat modes */ + const Sifmt : filemode = 0xf000 + const Sififo : filemode = 0x1000 + const Sifchr : filemode = 0x2000 + const Sifdir : filemode = 0x4000 + const Sifblk : filemode = 0x6000 + const Sifreg : filemode = 0x8000 + const Siflnk : filemode = 0xa000 + const Sifsock : filemode = 0xc000 + const Sisvtx : filemode = 0x0200 + + /* mmap protection */ + const Mprotnone : mprot = 0x0 + const Mprotrd : mprot = 0x1 + const Mprotwr : mprot = 0x2 + const Mprotexec : mprot = 0x4 + const Mprotrw : mprot = 0x3 + + /* mmap options */ + const Mshared : mopt = 0x1 + const Mpriv : mopt = 0x2 + const Mfixed : mopt = 0x10 + const Mfile : mopt = 0x0 + const Manon : mopt = 0x1000 + const Mstack : mopt = 0x4000 + const Mnoreplace : mopt = 0x0800 + + /* file types */ + const Dtunknown : filetype = 0 + const Dtfifo : filetype = 1 + const Dtchr : filetype = 2 + const Dtdir : filetype = 4 + const Dtblk : filetype = 6 + const Dtreg : filetype = 8 + const Dtlnk : filetype = 10 + const Dtsock : filetype = 12 + + /* socket families. INCOMPLETE. */ + const Afunspec : sockfam = 0 + const Afunix : sockfam = 1 + const Afinet : sockfam = 2 + const Afinet6 : sockfam = 24 + + /* socket types. */ + const Sockstream : socktype = 1 + const Sockdgram : socktype = 2 + const Sockraw : socktype = 3 + const Sockrdm : socktype = 4 + const Sockseqpacket : socktype = 5 + + /* socket options */ + const Sodebug : sockopt = 0x0001 /* turn on debugging info recording */ + const Soacceptconn : sockopt = 0x0002 /* socket has had listen() */ + const Soreuseaddr : sockopt = 0x0004 /* allow local address reuse */ + const Sokeepalive : sockopt = 0x0008 /* keep connections alive */ + const Sodontroute : sockopt = 0x0010 /* just use interface addresses */ + const Sobroadcast : sockopt = 0x0020 /* permit sending of broadcast msgs */ + const Souseloopback : sockopt = 0x0040 /* bypass hardware when possible */ + const Solinger : sockopt = 0x0080 /* linger on close if data present */ + const Sooobinline : sockopt = 0x0100 /* leave received OOB data in line */ + const Soreuseport : sockopt = 0x0200 /* allow local address & port reuse */ + const Sotimestamp : sockopt = 0x0800 /* timestamp received dgram traffic */ + const Sobindany : sockopt = 0x1000 /* allow bind to any address */ + const Sosndbuf : sockopt = 0x1001 /* send buffer size */ + const Sorcvbuf : sockopt = 0x1002 /* receive buffer size */ + const Sosndlowat : sockopt = 0x1003 /* send low-water mark */ + const Sorcvlowat : sockopt = 0x1004 /* receive low-water mark */ + const Sosndtimeo : sockopt = 0x1005 /* send timeout */ + const Sorcvtimeo : sockopt = 0x1006 /* receive timeout */ + const Soerror : sockopt = 0x1007 /* get error status and clear */ + const Sotype : sockopt = 0x1008 /* get socket type */ + const Sonetproc : sockopt = 0x1020 /* multiplex; network processing */ + const Sortable : sockopt = 0x1021 /* routing table to be used */ + const Sopeercred : sockopt = 0x1022 /* get connect-time credentials */ + const Sosplice : sockopt = 0x1023 /* splice data to other socket */ + + /* socket option levels */ + const Solsocket : sockproto = 0xffff + + /* network protocols */ + const Ipproto_ip : sockproto = 0 + const Ipproto_icmp : sockproto = 1 + const Ipproto_tcp : sockproto = 6 + const Ipproto_udp : sockproto = 17 + const Ipproto_raw : sockproto = 255 + + const Seekset : whence = 0 + const Seekcur : whence = 1 + const Seekend : whence = 2 + + /* system specific constants */ + const Maxpathlen : size = 1024 + + /* fcntl constants */ + const Fdupfd : fcntlcmd = 0 /* duplicate file descriptor */ + const Fgetfd : fcntlcmd = 1 /* get file descriptor flags */ + const Fsetfd : fcntlcmd = 2 /* set file descriptor flags */ + const Fgetfl : fcntlcmd = 3 /* get file status flags */ + const Fsetfl : fcntlcmd = 4 /* set file status flags */ + const Fgetown : fcntlcmd = 5 /* get SIGIO/SIGURG proc/pgrp */ + const Fsetown : fcntlcmd = 6 /* set SIGIO/SIGURG proc/pgrp */ + const Fogetlk : fcntlcmd = 7 /* get record locking information */ + const Fosetlk : fcntlcmd = 8 /* set record locking information */ + + /* return value for a failed mapping */ + const Mapbad : byte# = (-1 : byte#) + + /* signal flags */ + const Saonstack : sigflags = 0x0001 /* take signal on signal stack */ + const Sarestart : sigflags = 0x0002 /* restart system on signal return */ + const Saresethand : sigflags = 0x0004 /* reset to SIG_DFL when taking signal */ + const Sanodefer : sigflags = 0x0010 /* don't mask the signal we're delivering */ + const Sanocldwait : sigflags = 0x0020 /* don't create zombies (assign to pid 1) */ + const Sanocldstop : sigflags = 0x0008 /* do not generate SIGCHLD on child stop */ + const Sasiginfo : sigflags = 0x0040 /* generate siginfo_t */ + + /* signals */ + const Sighup : signo = 1 /* hangup */ + const Sigint : signo = 2 /* interrupt */ + const Sigquit : signo = 3 /* quit */ + const Sigill : signo = 4 /* illegal instruction (not reset when caught) */ + const Sigtrap : signo = 5 /* trace trap (not reset when caught) */ + const Sigabrt : signo = 6 /* abort() */ + const Sigiot : signo = Sigabrt /* compatibility */ + const Sigemt : signo = 7 /* EMT instruction */ + const Sigfpe : signo = 8 /* floating point exception */ + const Sigkill : signo = 9 /* kill (cannot be caught or ignored) */ + const Sigbus : signo = 10 /* bus error */ + const Sigsegv : signo = 11 /* segmentation violation */ + const Sigsys : signo = 12 /* bad argument to system call */ + const Sigpipe : signo = 13 /* write on a pipe with no one to read it */ + const Sigalrm : signo = 14 /* alarm clock */ + const Sigterm : signo = 15 /* software termination signal from kill */ + const Sigurg : signo = 16 /* urgent condition on IO channel */ + const Sigstop : signo = 17 /* sendable stop signal not from tty */ + const Sigtstp : signo = 18 /* stop signal from tty */ + const Sigcont : signo = 19 /* continue a stopped process */ + const Sigchld : signo = 20 /* to parent on child stop or exit */ + const Sigttin : signo = 21 /* to readers pgrp upon background tty read */ + const Sigttou : signo = 22 /* like TTIN for output if (tp->t_local<OSTOP) */ + const Sigio : signo = 23 /* input/output possible signal */ + const Sigxcpu : signo = 24 /* exceeded CPU time limit */ + const Sigxfsz : signo = 25 /* exceeded file size limit */ + const Sigvtalrm : signo = 26 /* virtual time alarm */ + const Sigprof : signo = 27 /* profiling time alarm */ + const Sigwinch : signo = 28 /* window size changes */ + const Siginfo : signo = 29 /* information request */ + const Sigusr1 : signo = 30 /* user defined signal 1 */ + const Sigusr2 : signo = 31 /* user defined signal 2 */ + const Sigthr : signo = 32 /* thread library AST */ + + extern const syscall : (sc:scno, args:... -> int64) + extern var __cenvp : byte## + type dev = int32 + type uid = uint32 + type fd_mask = uint32 + type uintptr = uint64 + type clockid = int32 + type id = uint32 + type key = int64 + type shmatt = int16 + + type tfork = struct + tcb : void# + tid : pid# + stack : void# + + ;; + + type msghdr = struct + name : void# + namelen : int32 + iov : iovec# + iovlen : uint + control : void# + controllen : int32 + flags : int + + ;; + + type fsid = struct + val : int32[2] + + ;; + + type fid = struct + len : uint16 + reserved : uint16 + data : byte[16] + + ;; + + type fhandle = struct + fsid : fsid + fid : fid + + ;; + + type fdset = struct + bits : fd_mask[32] + + ;; + + type kevent = struct + ident : uintptr + filter : int16 + flags : uint16 + fflags : uint + data : int64 + udata : void# + + ;; + + type kbind = struct + addr : void# + size : size + + ;; + + type sembuf = struct + num : uint16 + op : int16 + flg : int16 + + ;; + + type ipc_perm = struct + cuid : uid + cgid : gid + uid : uid + gid : gid + mode : filemode + seq : uint16 + key : key + + ;; + + type shmid_ds = struct + perm : ipc_perm + segsz : int + lpid : pid + cpid : pid + nattch : shmatt + atime : time + atimensec : int64 + dtime : time + dtimensec : int64 + ctime : time + ctimensec : int64 + internal : void# + + ;; + + type msqid_ds = struct + perm : ipc_perm + first : msg# + last : msg# + cbytes : uint64 + qnum : uint64 + qbytes : uint64 + lspid : pid + lrpid : pid + stime : time + pad1 : int64 + rtime : time + pad2 : int64 + ctime : time + pad3 : int64 + pad4 : int64[4] + + ;; + + + const Sysexit : scno = 1 + const Sysfork : scno = 2 + const Sysread : scno = 3 + const Syswrite : scno = 4 + const Sysopen : scno = 5 + const Sysclose : scno = 6 + const Sysgetentropy : scno = 7 + const Sys__tfork : scno = 8 + const Syslink : scno = 9 + const Sysunlink : scno = 10 + const Syswait4 : scno = 11 + const Syschdir : scno = 12 + const Sysfchdir : scno = 13 + const Sysmknod : scno = 14 + const Syschmod : scno = 15 + const Syschown : scno = 16 + const Sysobreak : scno = 17 + const Sysgetdtablecount : scno = 18 + const Sysgetrusage : scno = 19 + const Sysgetpid : scno = 20 + const Sysmount : scno = 21 + const Sysunmount : scno = 22 + const Syssetuid : scno = 23 + const Sysgetuid : scno = 24 + const Sysgeteuid : scno = 25 + const Sysptrace : scno = 26 + const Sysrecvmsg : scno = 27 + const Syssendmsg : scno = 28 + const Sysrecvfrom : scno = 29 + const Sysaccept : scno = 30 + const Sysgetpeername : scno = 31 + const Sysgetsockname : scno = 32 + const Sysaccess : scno = 33 + const Syschflags : scno = 34 + const Sysfchflags : scno = 35 + const Syssync : scno = 36 + const Sysstat : scno = 38 + const Sysgetppid : scno = 39 + const Syslstat : scno = 40 + const Sysdup : scno = 41 + const Sysfstatat : scno = 42 + const Sysgetegid : scno = 43 + const Sysprofil : scno = 44 + const Sysktrace : scno = 45 + const Syssigaction : scno = 46 + const Sysgetgid : scno = 47 + const Syssigprocmask : scno = 48 + const Syssetlogin : scno = 50 + const Sysacct : scno = 51 + const Syssigpending : scno = 52 + const Sysfstat : scno = 53 + const Sysioctl : scno = 54 + const Sysreboot : scno = 55 + const Sysrevoke : scno = 56 + const Syssymlink : scno = 57 + const Sysreadlink : scno = 58 + const Sysexecve : scno = 59 + const Sysumask : scno = 60 + const Syschroot : scno = 61 + const Sysgetfsstat : scno = 62 + const Sysstatfs : scno = 63 + const Sysfstatfs : scno = 64 + const Sysfhstatfs : scno = 65 + const Sysvfork : scno = 66 + const Sysgettimeofday : scno = 67 + const Syssettimeofday : scno = 68 + const Syssetitimer : scno = 69 + const Sysgetitimer : scno = 70 + const Sysselect : scno = 71 + const Syskevent : scno = 72 + const Sysmunmap : scno = 73 + const Sysmprotect : scno = 74 + const Sysmadvise : scno = 75 + const Sysutimes : scno = 76 + const Sysfutimes : scno = 77 + const Sysmincore : scno = 78 + const Sysgetgroups : scno = 79 + const Syssetgroups : scno = 80 + const Sysgetpgrp : scno = 81 + const Syssetpgid : scno = 82 + const Sysfutex : scno = 83 + const Sysutimensat : scno = 84 + const Sysfutimens : scno = 85 + const Syskbind : scno = 86 + const Sysclock_gettime : scno = 87 + const Sysclock_settime : scno = 88 + const Sysclock_getres : scno = 89 + const Sysdup2 : scno = 90 + const Sysnanosleep : scno = 91 + const Sysfcntl : scno = 92 + const Sysaccept4 : scno = 93 + const Sys__thrsleep : scno = 94 + const Sysfsync : scno = 95 + const Syssetpriority : scno = 96 + const Syssocket : scno = 97 + const Sysconnect : scno = 98 + const Sysgetdents : scno = 99 + const Sysgetpriority : scno = 100 + const Syspipe2 : scno = 101 + const Sysdup3 : scno = 102 + const Syssigreturn : scno = 103 + const Sysbind : scno = 104 + const Syssetsockopt : scno = 105 + const Syslisten : scno = 106 + const Syschflagsat : scno = 107 + const Syspledge : scno = 108 + const Sysppoll : scno = 109 + const Syspselect : scno = 110 + const Syssigsuspend : scno = 111 + const Syssendsyslog : scno = 112 + const Sysgetsockopt : scno = 118 + const Systhrkill : scno = 119 + const Sysreadv : scno = 120 + const Syswritev : scno = 121 + const Syskill : scno = 122 + const Sysfchown : scno = 123 + const Sysfchmod : scno = 124 + const Syssetreuid : scno = 126 + const Syssetregid : scno = 127 + const Sysrename : scno = 128 + const Sysflock : scno = 131 + const Sysmkfifo : scno = 132 + const Syssendto : scno = 133 + const Sysshutdown : scno = 134 + const Syssocketpair : scno = 135 + const Sysmkdir : scno = 136 + const Sysrmdir : scno = 137 + const Sysadjtime : scno = 140 + const Sysgetlogin_r : scno = 141 + const Syssetsid : scno = 147 + const Sysquotactl : scno = 148 + const Sysnfssvc : scno = 155 + const Sysgetfh : scno = 161 + const Syssysarch : scno = 165 + const Syspread : scno = 173 + const Syspwrite : scno = 174 + const Syssetgid : scno = 181 + const Syssetegid : scno = 182 + const Sysseteuid : scno = 183 + const Syspathconf : scno = 191 + const Sysfpathconf : scno = 192 + const Sysswapctl : scno = 193 + const Sysgetrlimit : scno = 194 + const Syssetrlimit : scno = 195 + const Sysmmap : scno = 197 + const Syslseek : scno = 199 + const Systruncate : scno = 200 + const Sysftruncate : scno = 201 + const Syssysctl : scno = 202 + const Sysmlock : scno = 203 + const Sysmunlock : scno = 204 + const Sysgetpgid : scno = 207 + const Sysutrace : scno = 209 + const Syssemget : scno = 221 + const Sysmsgget : scno = 225 + const Sysmsgsnd : scno = 226 + const Sysmsgrcv : scno = 227 + const Sysshmat : scno = 228 + const Sysshmdt : scno = 230 + const Sysminherit : scno = 250 + const Syspoll : scno = 252 + const Sysissetugid : scno = 253 + const Syslchown : scno = 254 + const Sysgetsid : scno = 255 + const Sysmsync : scno = 256 + const Syspipe : scno = 263 + const Sysfhopen : scno = 264 + const Syspreadv : scno = 267 + const Syspwritev : scno = 268 + const Syskqueue : scno = 269 + const Sysmlockall : scno = 271 + const Sysmunlockall : scno = 272 + const Sysgetresuid : scno = 281 + const Syssetresuid : scno = 282 + const Sysgetresgid : scno = 283 + const Syssetresgid : scno = 284 + const Sysmquery : scno = 286 + const Sysclosefrom : scno = 287 + const Syssigaltstack : scno = 288 + const Sysshmget : scno = 289 + const Syssemop : scno = 290 + const Sysfhstat : scno = 294 + const Sys__semctl : scno = 295 + const Sysshmctl : scno = 296 + const Sysmsgctl : scno = 297 + const Syssched_yield : scno = 298 + const Sysgetthrid : scno = 299 + const Sys__thrwakeup : scno = 301 + const Sys__threxit : scno = 302 + const Sys__thrsigdivert : scno = 303 + const Sys__getcwd : scno = 304 + const Sysadjfreq : scno = 305 + const Syssetrtable : scno = 310 + const Sysgetrtable : scno = 311 + const Sysfaccessat : scno = 313 + const Sysfchmodat : scno = 314 + const Sysfchownat : scno = 315 + const Syslinkat : scno = 317 + const Sysmkdirat : scno = 318 + const Sysmkfifoat : scno = 319 + const Sysmknodat : scno = 320 + const Sysopenat : scno = 321 + const Sysreadlinkat : scno = 322 + const Sysrenameat : scno = 323 + const Syssymlinkat : scno = 324 + const Sysunlinkat : scno = 325 + const Sys__set_tcb : scno = 329 + const Sys__get_tcb : scno = 330 + + /* start manual overrides { */ + 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) + const waitstatus : (st : int32 -> waitstatus) + extern const __tfork_thread : (tfp : tforkparams#, sz : size, fn : void#, arg : void# -> pid) + 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) + const sigaction : (sig : signo, act : sigaction#, oact : sigaction# -> int) + const sigprocmask : (how : int32, set : sigset#, oset : sigset# -> int) + const pipe : (fds : fd[2]# -> int64) + const dup : (fd : fd -> fd) + const dup2 : (src : fd, dst : fd -> fd) + const fcntl : (fd : fd, cmd : fcntlcmd, args : byte# -> int64) + 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) + const munmap : (addr:byte#, len:size -> int64) + const mmap : (addr:byte#, len:size, prot:mprot, flags:mopt, fd:fd, off:off -> byte#) + 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) + const uname : (buf : utsname# -> int) + const sysctl : (mib : int[:], \ + old : void#, oldsz : size#, \ + new : void#, newsz : size# \ + -> int) + extern const cstring : (str : byte[:] -> byte#) + extern const alloca : (sz : size -> byte#) + extern const __freebsd_pipe : (fds : fd[2]# -> int64) + /* } end manual overrides */ + + const getentropy : (buf : void#, nbyte : size -> int) + const __tfork : (param : tfork#, psize : size -> int) + const link : (path : byte#, link : byte# -> int) + const fchdir : (fd : int -> int) + const mknod : (path : byte#, mode : filemode, dev : dev -> int) + const chmod : (path : byte#, mode : filemode -> int) + const chown : (path : byte#, uid : uid, gid : gid -> int) + const obreak : (nsize : byte# -> int) + const getdtablecount : ( -> int) + const getrusage : (who : int, rusage : rusage# -> int) + const mount : (kind : byte#, path : byte#, flags : int, data : void# -> int) + const unmount : (path : byte#, flags : int -> int) + const setuid : (uid : uid -> int) + const getuid : ( -> uid) + const geteuid : ( -> uid) + const ptrace : (req : int, pid : pid, addr : void#, data : int -> int) + const recvmsg : (s : int, msg : msghdr#, flags : int -> size) + const sendmsg : (s : int, msg : msghdr#, flags : int -> size) + const recvfrom : (s : int, buf : void#, len : size, flags : int, from : sockaddr#, fromlenaddr : int32# -> size) + const getpeername : (fdes : int, asa : sockaddr#, alen : int32# -> int) + const getsockname : (fdes : int, asa : sockaddr#, alen : int32# -> int) + const access : (path : byte#, amode : int -> int) + const chflags : (path : byte#, flags : uint -> int) + const fchflags : (fd : int, flags : uint -> int) + const sync : ( -> void) + const getppid : ( -> pid) + const fstatat : (fd : int, path : byte#, buf : statbuf#, flag : int -> int) + const getegid : ( -> gid) + const profil : (samples : void#, size : size, offset : uint64, scale : uint -> int) + const ktrace : (fname : byte#, ops : int, facs : int, pid : pid -> int) + const getgid : ( -> gid) + const setlogin : (namebuf : byte# -> int) + const acct : (path : byte# -> int) + const sigpending : ( -> int) + const reboot : (opt : int -> int) + const revoke : (path : byte# -> int) + const symlink : (path : byte#, link : byte# -> int) + const readlink : (path : byte#, buf : byte#, count : size -> size) + const umask : (newmask : filemode -> filemode) + const chroot : (path : byte# -> int) + const getfsstat : (buf : statfs#, bufsize : size, flags : int -> int) + const statfs : (path : byte#, buf : statfs# -> int) + const fstatfs : (fd : int, buf : statfs# -> int) + const fhstatfs : (fhp : fhandle#, buf : statfs# -> int) + const vfork : ( -> int) + const gettimeofday : (tp : timeval#, tzp : timezone# -> int) + const settimeofday : (tv : timeval#, tzp : timezone# -> int) + const setitimer : (which : int, itv : itimerval#, oitv : itimerval# -> int) + const getitimer : (which : int, itv : itimerval# -> int) + const select : (nd : int, _in : fdset#, ou : fdset#, ex : fdset#, tv : timeval# -> int) + const kevent : (fd : int, changelist : kevent#, nchanges : int, eventlist : kevent#, nevents : int, timeout : timespec# -> int) + const mprotect : (addr : void#, len : size, prot : int -> int) + const madvise : (addr : void#, len : size, behav : int -> int) + const utimes : (path : byte#, tptr : timeval# -> int) + const futimes : (fd : int, tptr : timeval# -> int) + const mincore : (addr : void#, len : size, vec : byte# -> int) + const getgroups : (gidsetsize : int, gidset : gid# -> int) + const setgroups : (gidsetsize : int, gidset : gid# -> int) + const getpgrp : ( -> int) + const setpgid : (pid : pid, pgid : pid -> int) + const futex : (f : uint32#, op : int, val : int, timeout : timespec#, g : uint32# -> int) + const utimensat : (fd : int, path : byte#, times : timespec#, flag : int -> int) + const futimens : (fd : int, times : timespec# -> int) + const kbind : (param : kbind#, psize : size, proc_cookie : int64 -> int) + const accept4 : (s : int, name : sockaddr#, anamelen : int32#, flags : int -> int) + const __thrsleep : (ident : void#, clock_id : clockid, tp : timespec#, lock : void#, abort : int# -> int) + const fsync : (fd : int -> int) + const setpriority : (which : int, who : id, prio : int -> int) + const getpriority : (which : int, who : id -> int) + const pipe2 : (fdp : int#, flags : int -> int) + const dup3 : (from : int, to : int, flags : int -> int) + const sigreturn : (sigcntxp : sigcontext# -> int) + const chflagsat : (fd : int, path : byte#, flags : uint, atflags : int -> int) + const pledge : (promises : byte#, execpromises : byte# -> int) + const ppoll : (fds : pollfd#, nfds : uint, ts : timespec#, mask : sigset# -> int) + const pselect : (nd : int, _in : fdset#, ou : fdset#, ex : fdset#, ts : timespec#, mask : sigset# -> int) + const sigsuspend : (mask : int -> int) + const sendsyslog : (buf : byte#, nbyte : size, flags : int -> int) + const thrkill : (tid : pid, signum : int, tcb : void# -> int) + const fchown : (fd : int, uid : uid, gid : gid -> int) + const fchmod : (fd : int, mode : filemode -> int) + const setreuid : (ruid : uid, euid : uid -> int) + const setregid : (rgid : gid, egid : gid -> int) + const rename : (from : byte#, to : byte# -> int) + const flock : (fd : int, how : int -> int) + const mkfifo : (path : byte#, mode : filemode -> int) + const sendto : (s : int, buf : void#, len : size, flags : int, to : sockaddr#, tolen : int32 -> size) + const shutdown : (s : int, how : int -> int) + const socketpair : (domain : int, kind : int, protocol : int, rsv : int# -> int) + const rmdir : (path : byte# -> int) + const adjtime : (delta : timeval#, olddelta : timeval# -> int) + const getlogin_r : (namebuf : byte#, namelen : uint -> int) + const setsid : ( -> int) + const quotactl : (path : byte#, cmd : int, uid : int, arg : byte# -> int) + const nfssvc : (flag : int, argp : void# -> int) + const getfh : (fname : byte#, fhp : fhandle# -> int) + const sysarch : (op : int, parms : void# -> int) + const setgid : (gid : gid -> int) + const setegid : (egid : gid -> int) + const seteuid : (euid : uid -> int) + const pathconf : (path : byte#, name : int -> int64) + const fpathconf : (fd : int, name : int -> int64) + const swapctl : (cmd : int, arg : void#, misc : int -> int) + const getrlimit : (which : int, rlp : rlimit# -> int) + const setrlimit : (which : int, rlp : rlimit# -> int) + const truncate : (path : byte#, pad : int, length : off -> int) + const ftruncate : (fd : int, pad : int, length : off -> int) + const mlock : (addr : void#, len : size -> int) + const munlock : (addr : void#, len : size -> int) + const getpgid : (pid : pid -> pid) + const utrace : (label : byte#, addr : void#, len : size -> int) + const semget : (key : key, nsems : int, semflg : int -> int) + const msgget : (key : key, msgflg : int -> int) + const msgsnd : (msqid : int, msgp : void#, msgsz : size, msgflg : int -> int) + const msgrcv : (msqid : int, msgp : void#, msgsz : size, msgtyp : int64, msgflg : int -> int) + const shmat : (shmid : int, shmaddr : void#, shmflg : int -> void) + const shmdt : (shmaddr : void# -> int) + const minherit : (addr : void#, len : size, inherit : int -> int) + const issetugid : ( -> int) + const lchown : (path : byte#, uid : uid, gid : gid -> int) + const getsid : (pid : pid -> pid) + const msync : (addr : void#, len : size, flags : int -> int) + const fhopen : (fhp : fhandle#, flags : int -> int) + const preadv : (fd : int, iovp : iovec#, iovcnt : int, pad : int, offset : off -> size) + const pwritev : (fd : int, iovp : iovec#, iovcnt : int, pad : int, offset : off -> size) + const kqueue : ( -> int) + const mlockall : (flags : int -> int) + const munlockall : ( -> int) + const getresuid : (ruid : uid#, euid : uid#, suid : uid# -> int) + const setresuid : (ruid : uid, euid : uid, suid : uid -> int) + const getresgid : (rgid : gid#, egid : gid#, sgid : gid# -> int) + const setresgid : (rgid : gid, egid : gid, sgid : gid -> int) + const mquery : (addr : void#, len : size, prot : int, flags : int, fd : int, pad : int64, pos : off -> void) + const closefrom : (fd : int -> int) + const sigaltstack : (nss : sigaltstack#, oss : sigaltstack# -> int) + const shmget : (key : key, size : size, shmflg : int -> int) + const semop : (semid : int, sops : sembuf#, nsops : size -> int) + const fhstat : (fhp : fhandle#, sb : statbuf# -> int) + const __semctl : (semid : int, semnum : int, cmd : int, arg : semun# -> int) + const shmctl : (shmid : int, cmd : int, buf : shmid_ds# -> int) + const msgctl : (msqid : int, cmd : int, buf : msqid_ds# -> int) + const sched_yield : ( -> int) + const getthrid : ( -> pid) + const __thrwakeup : (ident : void#, n : int -> int) + const __threxit : (notdead : pid# -> void) + const __thrsigdivert : (sigmask : sigset, info : siginfo#, timeout : timespec# -> int) + const adjfreq : (freq : int64#, oldfreq : int64# -> int) + const setrtable : (rtableid : int -> int) + const getrtable : ( -> int) + const faccessat : (fd : int, path : byte#, amode : int, flag : int -> int) + const fchmodat : (fd : int, path : byte#, mode : filemode, flag : int -> int) + const fchownat : (fd : int, path : byte#, uid : uid, gid : gid, flag : int -> int) + const linkat : (fd1 : int, path1 : byte#, fd2 : int, path2 : byte#, flag : int -> int) + const mkdirat : (fd : int, path : byte#, mode : filemode -> int) + const mkfifoat : (fd : int, path : byte#, mode : filemode -> int) + const mknodat : (fd : int, path : byte#, mode : filemode, dev : dev -> int) + const openat : (fd : int, path : byte#, flags : int, mode : filemode -> int) + const readlinkat : (fd : int, path : byte#, buf : byte#, count : size -> size) + const renameat : (fromfd : int, from : byte#, tofd : int, to : byte# -> int) + const symlinkat : (path : byte#, fd : int, link : byte# -> int) + const unlinkat : (fd : int, path : byte#, flag : int -> int) + const __set_tcb : (tcb : void# -> void) + const __get_tcb : ( -> void) +;; + + /* start manual overrides { */ + /* process control */ + /* wrappers to extract wait status */ + + /* fd manipulation */ + + /* signals */ + + /* fd stuff */ + /* NB: the C ABI uses '...' for the args. */ + + /* networking */ + + /* memory mapping */ + + /* time - doublecheck if this is right */ + + /* system information */ + + /* + 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)} + + + + /* 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, .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 + ;; + } + + /* } end manual overrides */ +const getentropy = {buf, nbyte + -> (syscall(Sysgetentropy, a(buf), a(nbyte)) : int) +} +const __tfork = {param, psize + -> (syscall(Sys__tfork, a(param), a(psize)) : int) +} +const link = {path, link + -> (syscall(Syslink, a(path), a(link)) : int) +} +const fchdir = {fd + -> (syscall(Sysfchdir, a(fd)) : int) +} +const mknod = {path, mode, dev + -> (syscall(Sysmknod, a(path), a(mode), a(dev)) : int) +} +const chmod = {path, mode + -> (syscall(Syschmod, a(path), a(mode)) : int) +} +const chown = {path, uid, gid + -> (syscall(Syschown, a(path), a(uid), a(gid)) : int) +} +const obreak = {nsize + -> (syscall(Sysobreak, a(nsize)) : int) +} +const getdtablecount = { + -> (syscall(Sysgetdtablecount) : int) +} +const getrusage = {who, rusage + -> (syscall(Sysgetrusage, a(who), a(rusage)) : int) +} +const mount = {kind, path, flags, data + -> (syscall(Sysmount, a(kind), a(path), a(flags), a(data)) : int) +} +const unmount = {path, flags + -> (syscall(Sysunmount, a(path), a(flags)) : int) +} +const setuid = {uid + -> (syscall(Syssetuid, a(uid)) : int) +} +const getuid = { + -> (syscall(Sysgetuid) : uid) +} +const geteuid = { + -> (syscall(Sysgeteuid) : uid) +} +const ptrace = {req, pid, addr, data + -> (syscall(Sysptrace, a(req), a(pid), a(addr), a(data)) : int) +} +const recvmsg = {s, msg, flags + -> (syscall(Sysrecvmsg, a(s), a(msg), a(flags)) : size) +} +const sendmsg = {s, msg, flags + -> (syscall(Syssendmsg, a(s), a(msg), a(flags)) : size) +} +const recvfrom = {s, buf, len, flags, from, fromlenaddr + -> (syscall(Sysrecvfrom, a(s), a(buf), a(len), a(flags), a(from), a(fromlenaddr)) : size) +} +const getpeername = {fdes, asa, alen + -> (syscall(Sysgetpeername, a(fdes), a(asa), a(alen)) : int) +} +const getsockname = {fdes, asa, alen + -> (syscall(Sysgetsockname, a(fdes), a(asa), a(alen)) : int) +} +const access = {path, amode + -> (syscall(Sysaccess, a(path), a(amode)) : int) +} +const chflags = {path, flags + -> (syscall(Syschflags, a(path), a(flags)) : int) +} +const fchflags = {fd, flags + -> (syscall(Sysfchflags, a(fd), a(flags)) : int) +} +const sync = { + -> (syscall(Syssync) : void) +} +const getppid = { + -> (syscall(Sysgetppid) : pid) +} +const fstatat = {fd, path, buf, flag + -> (syscall(Sysfstatat, a(fd), a(path), a(buf), a(flag)) : int) +} +const getegid = { + -> (syscall(Sysgetegid) : gid) +} +const profil = {samples, size, offset, scale + -> (syscall(Sysprofil, a(samples), a(size), a(offset), a(scale)) : int) +} +const ktrace = {fname, ops, facs, pid + -> (syscall(Sysktrace, a(fname), a(ops), a(facs), a(pid)) : int) +} +const getgid = { + -> (syscall(Sysgetgid) : gid) +} +const setlogin = {namebuf + -> (syscall(Syssetlogin, a(namebuf)) : int) +} +const acct = {path + -> (syscall(Sysacct, a(path)) : int) +} +const sigpending = { + -> (syscall(Syssigpending) : int) +} +const reboot = {opt + -> (syscall(Sysreboot, a(opt)) : int) +} +const revoke = {path + -> (syscall(Sysrevoke, a(path)) : int) +} +const symlink = {path, link + -> (syscall(Syssymlink, a(path), a(link)) : int) +} +const readlink = {path, buf, count + -> (syscall(Sysreadlink, a(path), a(buf), a(count)) : size) +} +const umask = {newmask + -> (syscall(Sysumask, a(newmask)) : filemode) +} +const chroot = {path + -> (syscall(Syschroot, a(path)) : int) +} +const getfsstat = {buf, bufsize, flags + -> (syscall(Sysgetfsstat, a(buf), a(bufsize), a(flags)) : int) +} +const statfs = {path, buf + -> (syscall(Sysstatfs, a(path), a(buf)) : int) +} +const fstatfs = {fd, buf + -> (syscall(Sysfstatfs, a(fd), a(buf)) : int) +} +const fhstatfs = {fhp, buf + -> (syscall(Sysfhstatfs, a(fhp), a(buf)) : int) +} +const vfork = { + -> (syscall(Sysvfork) : int) +} +const gettimeofday = {tp, tzp + -> (syscall(Sysgettimeofday, a(tp), a(tzp)) : int) +} +const settimeofday = {tv, tzp + -> (syscall(Syssettimeofday, a(tv), a(tzp)) : int) +} +const setitimer = {which, itv, oitv + -> (syscall(Syssetitimer, a(which), a(itv), a(oitv)) : int) +} +const getitimer = {which, itv + -> (syscall(Sysgetitimer, a(which), a(itv)) : int) +} +const select = {nd, _in, ou, ex, tv + -> (syscall(Sysselect, a(nd), a(_in), a(ou), a(ex), a(tv)) : int) +} +const kevent = {fd, changelist, nchanges, eventlist, nevents, timeout + -> (syscall(Syskevent, a(fd), a(changelist), a(nchanges), a(eventlist), a(nevents), a(timeout)) : int) +} +const mprotect = {addr, len, prot + -> (syscall(Sysmprotect, a(addr), a(len), a(prot)) : int) +} +const madvise = {addr, len, behav + -> (syscall(Sysmadvise, a(addr), a(len), a(behav)) : int) +} +const utimes = {path, tptr + -> (syscall(Sysutimes, a(path), a(tptr)) : int) +} +const futimes = {fd, tptr + -> (syscall(Sysfutimes, a(fd), a(tptr)) : int) +} +const mincore = {addr, len, vec + -> (syscall(Sysmincore, a(addr), a(len), a(vec)) : int) +} +const getgroups = {gidsetsize, gidset + -> (syscall(Sysgetgroups, a(gidsetsize), a(gidset)) : int) +} +const setgroups = {gidsetsize, gidset + -> (syscall(Syssetgroups, a(gidsetsize), a(gidset)) : int) +} +const getpgrp = { + -> (syscall(Sysgetpgrp) : int) +} +const setpgid = {pid, pgid + -> (syscall(Syssetpgid, a(pid), a(pgid)) : int) +} +const futex = {f, op, val, timeout, g + -> (syscall(Sysfutex, a(f), a(op), a(val), a(timeout), a(g)) : int) +} +const utimensat = {fd, path, times, flag + -> (syscall(Sysutimensat, a(fd), a(path), a(times), a(flag)) : int) +} +const futimens = {fd, times + -> (syscall(Sysfutimens, a(fd), a(times)) : int) +} +const kbind = {param, psize, proc_cookie + -> (syscall(Syskbind, a(param), a(psize), a(proc_cookie)) : int) +} +const accept4 = {s, name, anamelen, flags + -> (syscall(Sysaccept4, a(s), a(name), a(anamelen), a(flags)) : int) +} +const __thrsleep = {ident, clock_id, tp, lock, abort + -> (syscall(Sys__thrsleep, a(ident), a(clock_id), a(tp), a(lock), a(abort)) : int) +} +const fsync = {fd + -> (syscall(Sysfsync, a(fd)) : int) +} +const setpriority = {which, who, prio + -> (syscall(Syssetpriority, a(which), a(who), a(prio)) : int) +} +const getpriority = {which, who + -> (syscall(Sysgetpriority, a(which), a(who)) : int) +} +const pipe2 = {fdp, flags + -> (syscall(Syspipe2, a(fdp), a(flags)) : int) +} +const dup3 = {from, to, flags + -> (syscall(Sysdup3, a(from), a(to), a(flags)) : int) +} +const sigreturn = {sigcntxp + -> (syscall(Syssigreturn, a(sigcntxp)) : int) +} +const chflagsat = {fd, path, flags, atflags + -> (syscall(Syschflagsat, a(fd), a(path), a(flags), a(atflags)) : int) +} +const pledge = {promises, execpromises + -> (syscall(Syspledge, a(promises), a(execpromises)) : int) +} +const ppoll = {fds, nfds, ts, mask + -> (syscall(Sysppoll, a(fds), a(nfds), a(ts), a(mask)) : int) +} +const pselect = {nd, _in, ou, ex, ts, mask + -> (syscall(Syspselect, a(nd), a(_in), a(ou), a(ex), a(ts), a(mask)) : int) +} +const sigsuspend = {mask + -> (syscall(Syssigsuspend, a(mask)) : int) +} +const sendsyslog = {buf, nbyte, flags + -> (syscall(Syssendsyslog, a(buf), a(nbyte), a(flags)) : int) +} +const thrkill = {tid, signum, tcb + -> (syscall(Systhrkill, a(tid), a(signum), a(tcb)) : int) +} +const fchown = {fd, uid, gid + -> (syscall(Sysfchown, a(fd), a(uid), a(gid)) : int) +} +const fchmod = {fd, mode + -> (syscall(Sysfchmod, a(fd), a(mode)) : int) +} +const setreuid = {ruid, euid + -> (syscall(Syssetreuid, a(ruid), a(euid)) : int) +} +const setregid = {rgid, egid + -> (syscall(Syssetregid, a(rgid), a(egid)) : int) +} +const rename = {from, to + -> (syscall(Sysrename, a(from), a(to)) : int) +} +const flock = {fd, how + -> (syscall(Sysflock, a(fd), a(how)) : int) +} +const mkfifo = {path, mode + -> (syscall(Sysmkfifo, a(path), a(mode)) : int) +} +const sendto = {s, buf, len, flags, to, tolen + -> (syscall(Syssendto, a(s), a(buf), a(len), a(flags), a(to), a(tolen)) : size) +} +const shutdown = {s, how + -> (syscall(Sysshutdown, a(s), a(how)) : int) +} +const socketpair = {domain, kind, protocol, rsv + -> (syscall(Syssocketpair, a(domain), a(kind), a(protocol), a(rsv)) : int) +} +const rmdir = {path + -> (syscall(Sysrmdir, a(path)) : int) +} +const adjtime = {delta, olddelta + -> (syscall(Sysadjtime, a(delta), a(olddelta)) : int) +} +const getlogin_r = {namebuf, namelen + -> (syscall(Sysgetlogin_r, a(namebuf), a(namelen)) : int) +} +const setsid = { + -> (syscall(Syssetsid) : int) +} +const quotactl = {path, cmd, uid, arg + -> (syscall(Sysquotactl, a(path), a(cmd), a(uid), a(arg)) : int) +} +const nfssvc = {flag, argp + -> (syscall(Sysnfssvc, a(flag), a(argp)) : int) +} +const getfh = {fname, fhp + -> (syscall(Sysgetfh, a(fname), a(fhp)) : int) +} +const sysarch = {op, parms + -> (syscall(Syssysarch, a(op), a(parms)) : int) +} +const setgid = {gid + -> (syscall(Syssetgid, a(gid)) : int) +} +const setegid = {egid + -> (syscall(Syssetegid, a(egid)) : int) +} +const seteuid = {euid + -> (syscall(Sysseteuid, a(euid)) : int) +} +const pathconf = {path, name + -> (syscall(Syspathconf, a(path), a(name)) : int64) +} +const fpathconf = {fd, name + -> (syscall(Sysfpathconf, a(fd), a(name)) : int64) +} +const swapctl = {cmd, arg, misc + -> (syscall(Sysswapctl, a(cmd), a(arg), a(misc)) : int) +} +const getrlimit = {which, rlp + -> (syscall(Sysgetrlimit, a(which), a(rlp)) : int) +} +const setrlimit = {which, rlp + -> (syscall(Syssetrlimit, a(which), a(rlp)) : int) +} +const truncate = {path, pad, length + -> (syscall(Systruncate, a(path), a(pad), a(length)) : int) +} +const ftruncate = {fd, pad, length + -> (syscall(Sysftruncate, a(fd), a(pad), a(length)) : int) +} +const mlock = {addr, len + -> (syscall(Sysmlock, a(addr), a(len)) : int) +} +const munlock = {addr, len + -> (syscall(Sysmunlock, a(addr), a(len)) : int) +} +const getpgid = {pid + -> (syscall(Sysgetpgid, a(pid)) : pid) +} +const utrace = {label, addr, len + -> (syscall(Sysutrace, a(label), a(addr), a(len)) : int) +} +const semget = {key, nsems, semflg + -> (syscall(Syssemget, a(key), a(nsems), a(semflg)) : int) +} +const msgget = {key, msgflg + -> (syscall(Sysmsgget, a(key), a(msgflg)) : int) +} +const msgsnd = {msqid, msgp, msgsz, msgflg + -> (syscall(Sysmsgsnd, a(msqid), a(msgp), a(msgsz), a(msgflg)) : int) +} +const msgrcv = {msqid, msgp, msgsz, msgtyp, msgflg + -> (syscall(Sysmsgrcv, a(msqid), a(msgp), a(msgsz), a(msgtyp), a(msgflg)) : int) +} +const shmat = {shmid, shmaddr, shmflg + -> (syscall(Sysshmat, a(shmid), a(shmaddr), a(shmflg)) : void) +} +const shmdt = {shmaddr + -> (syscall(Sysshmdt, a(shmaddr)) : int) +} +const minherit = {addr, len, inherit + -> (syscall(Sysminherit, a(addr), a(len), a(inherit)) : int) +} +const issetugid = { + -> (syscall(Sysissetugid) : int) +} +const lchown = {path, uid, gid + -> (syscall(Syslchown, a(path), a(uid), a(gid)) : int) +} +const getsid = {pid + -> (syscall(Sysgetsid, a(pid)) : pid) +} +const msync = {addr, len, flags + -> (syscall(Sysmsync, a(addr), a(len), a(flags)) : int) +} +const fhopen = {fhp, flags + -> (syscall(Sysfhopen, a(fhp), a(flags)) : int) +} +const preadv = {fd, iovp, iovcnt, pad, offset + -> (syscall(Syspreadv, a(fd), a(iovp), a(iovcnt), a(pad), a(offset)) : size) +} +const pwritev = {fd, iovp, iovcnt, pad, offset + -> (syscall(Syspwritev, a(fd), a(iovp), a(iovcnt), a(pad), a(offset)) : size) +} +const kqueue = { + -> (syscall(Syskqueue) : int) +} +const mlockall = {flags + -> (syscall(Sysmlockall, a(flags)) : int) +} +const munlockall = { + -> (syscall(Sysmunlockall) : int) +} +const getresuid = {ruid, euid, suid + -> (syscall(Sysgetresuid, a(ruid), a(euid), a(suid)) : int) +} +const setresuid = {ruid, euid, suid + -> (syscall(Syssetresuid, a(ruid), a(euid), a(suid)) : int) +} +const getresgid = {rgid, egid, sgid + -> (syscall(Sysgetresgid, a(rgid), a(egid), a(sgid)) : int) +} +const setresgid = {rgid, egid, sgid + -> (syscall(Syssetresgid, a(rgid), a(egid), a(sgid)) : int) +} +const mquery = {addr, len, prot, flags, fd, pad, pos + -> (syscall(Sysmquery, a(addr), a(len), a(prot), a(flags), a(fd), a(pad), a(pos)) : void) +} +const closefrom = {fd + -> (syscall(Sysclosefrom, a(fd)) : int) +} +const sigaltstack = {nss, oss + -> (syscall(Syssigaltstack, a(nss), a(oss)) : int) +} +const shmget = {key, size, shmflg + -> (syscall(Sysshmget, a(key), a(size), a(shmflg)) : int) +} +const semop = {semid, sops, nsops + -> (syscall(Syssemop, a(semid), a(sops), a(nsops)) : int) +} +const fhstat = {fhp, sb + -> (syscall(Sysfhstat, a(fhp), a(sb)) : int) +} +const __semctl = {semid, semnum, cmd, arg + -> (syscall(Sys__semctl, a(semid), a(semnum), a(cmd), a(arg)) : int) +} +const shmctl = {shmid, cmd, buf + -> (syscall(Sysshmctl, a(shmid), a(cmd), a(buf)) : int) +} +const msgctl = {msqid, cmd, buf + -> (syscall(Sysmsgctl, a(msqid), a(cmd), a(buf)) : int) +} +const sched_yield = { + -> (syscall(Syssched_yield) : int) +} +const getthrid = { + -> (syscall(Sysgetthrid) : pid) +} +const __thrwakeup = {ident, n + -> (syscall(Sys__thrwakeup, a(ident), a(n)) : int) +} +const __threxit = {notdead + -> (syscall(Sys__threxit, a(notdead)) : void) +} +const __thrsigdivert = {sigmask, info, timeout + -> (syscall(Sys__thrsigdivert, a(sigmask), a(info), a(timeout)) : int) +} +const adjfreq = {freq, oldfreq + -> (syscall(Sysadjfreq, a(freq), a(oldfreq)) : int) +} +const setrtable = {rtableid + -> (syscall(Syssetrtable, a(rtableid)) : int) +} +const getrtable = { + -> (syscall(Sysgetrtable) : int) +} +const faccessat = {fd, path, amode, flag + -> (syscall(Sysfaccessat, a(fd), a(path), a(amode), a(flag)) : int) +} +const fchmodat = {fd, path, mode, flag + -> (syscall(Sysfchmodat, a(fd), a(path), a(mode), a(flag)) : int) +} +const fchownat = {fd, path, uid, gid, flag + -> (syscall(Sysfchownat, a(fd), a(path), a(uid), a(gid), a(flag)) : int) +} +const linkat = {fd1, path1, fd2, path2, flag + -> (syscall(Syslinkat, a(fd1), a(path1), a(fd2), a(path2), a(flag)) : int) +} +const mkdirat = {fd, path, mode + -> (syscall(Sysmkdirat, a(fd), a(path), a(mode)) : int) +} +const mkfifoat = {fd, path, mode + -> (syscall(Sysmkfifoat, a(fd), a(path), a(mode)) : int) +} +const mknodat = {fd, path, mode, dev + -> (syscall(Sysmknodat, a(fd), a(path), a(mode), a(dev)) : int) +} +const openat = {fd, path, flags, mode + -> (syscall(Sysopenat, a(fd), a(path), a(flags), a(mode)) : int) +} +const readlinkat = {fd, path, buf, count + -> (syscall(Sysreadlinkat, a(fd), a(path), a(buf), a(count)) : size) +} +const renameat = {fromfd, from, tofd, to + -> (syscall(Sysrenameat, a(fromfd), a(from), a(tofd), a(to)) : int) +} +const symlinkat = {path, fd, link + -> (syscall(Syssymlinkat, a(path), a(fd), a(link)) : int) +} +const unlinkat = {fd, path, flag + -> (syscall(Sysunlinkat, a(fd), a(path), a(flag)) : int) +} +const __set_tcb = {tcb + -> (syscall(Sys__set_tcb, a(tcb)) : void) +} +const __get_tcb = { + -> (syscall(Sys__get_tcb) : void) +} diff --git a/lib/testr/testr.myr b/lib/testr/testr.myr index bbb99fe..9d8c55f 100644 --- a/lib/testr/testr.myr +++ b/lib/testr/testr.myr @@ -149,21 +149,21 @@ const benchspec = {ts, sub const testspec = {ts, sub var ctx : ctx - var dorun, jmpbuf + var jmpbuf ctx.ok = true ctx.reason = "" ctx.jmpbuf = &jmpbuf - dorun = matchtest(ts.name, sub) + if !matchtest(ts.name, sub) + -> void + ;; std.put("test {} <<{{!\n", ts.name) - if !std.setjmp(&jmpbuf) && dorun + if !std.setjmp(&jmpbuf) ts.fn(&ctx) ;; - if !dorun - std.put("!}}>> skip filtered\n") - elif ctx.ok + if ctx.ok std.put("!}}>> ok\n") else std.put("!}}>> fail {}\n", ctx.reason) diff --git a/lib/thread/spawn+openbsd.myr b/lib/thread/spawn+openbsd.myr index 1cdf230..c925349 100644 --- a/lib/thread/spawn+openbsd.myr +++ b/lib/thread/spawn+openbsd.myr @@ -53,7 +53,7 @@ const spawnstk = {fn, sz const getstk = {sz var p, m - p = sys.mmap((0 : byte#), sz, sys.Mprotrw, sys.Mpriv | sys.Manon, -1, 0) + p = sys.mmap((0 : byte#), sz, sys.Mprotrw, sys.Mpriv | sys.Manon | sys.Mstack, -1, 0) if p == sys.Mapbad -> p ;; diff --git a/mbld/bld.sub b/mbld/bld.sub index 7374bb3..7e9bda3 100644 --- a/mbld/bld.sub +++ b/mbld/bld.sub @@ -1,6 +1,7 @@ bin mbld = build.myr - cpufeatures+x64.s + cpufeatures+posixy-x64.s + cpufeatures+plan9-x64.s deps.myr libs.myr install.myr diff --git a/mbld/cpufeatures+plan9-x64.s b/mbld/cpufeatures+plan9-x64.s new file mode 100644 index 0000000..645d01a --- /dev/null +++ b/mbld/cpufeatures+plan9-x64.s @@ -0,0 +1,8 @@ +TEXT bld$cpufeatures+0(SB),$0 + MOVL $0x1,AX + CPUID + MOVL CX, AX + MOVL DX, DX + ROLQ $32, DX + ORQ DX, AX + RET diff --git a/mbld/cpufeatures+x64.s b/mbld/cpufeatures+posixy-x64.s index 8202ca1..889c6f1 100644 --- a/mbld/cpufeatures+x64.s +++ b/mbld/cpufeatures+posixy-x64.s @@ -1,7 +1,7 @@ .globl bld$cpufeatures -.globl bld$_cpufeatures +.globl _bld$cpufeatures bld$cpufeatures: -bld$_cpufeatures: +_bld$cpufeatures: mov $0x1, %eax cpuid mov %ecx, %eax diff --git a/mbld/deps.myr b/mbld/deps.myr index 51bddb0..53b5a8f 100644 --- a/mbld/deps.myr +++ b/mbld/deps.myr @@ -333,7 +333,6 @@ const addalt = {b, mt, kind, f std.slpush(&libs, d) ;; myrcmd(b, n, mt, sp, true) - std.slfree(mt.incpath) n = node(g, tp) generates(g, n, tp) @@ -484,6 +483,7 @@ const myrcmd = {b, n, mt, src, istest pushopt(&n.cmd, "-I", inc) ;; if istest + std.slpush(&n.cmd, "-T") for (dir, _, _) : mt.tstdeps pushopt(&n.cmd, "-I", std.pathcat(opt_objdir, dir)) ;; diff --git a/mbld/test.myr b/mbld/test.myr index 4d4b2ed..bf666fd 100644 --- a/mbld/test.myr +++ b/mbld/test.myr @@ -28,21 +28,11 @@ const go = {b, targs, kind, isbench if !buildtarg(b, kind) std.exit(1) ;; - if targs.len == 0 - tests = std.htgetv(b.deps.targs, kind, [][:]) - else - tests = [][:] - for t : targs - match std.htget(b.deps.targs, t) - | `std.Some tl: std.sljoin(&tests, tl) - | `std.None: std.fatal("unknown test {}\n", t) - ;; - ;; - ;; + tests = std.htgetv(b.deps.targs, kind, [][:]) ok = true failed = [][:] for t : tests - if !runtest(b, t, isbench, &failed) + if !runtest(b, t, targs, isbench, &failed) ok = false ;; ;; @@ -71,14 +61,30 @@ const printfailed = {failed ;; } -const runtest = {b, n, isbench, failed +const runtest = {b, n, targs, isbench, failed var dir, res, log, logfd - var sub + var sub, found + if targs.len > 0 + found = false + for t : targs + found = found || matchtest(n.lbl, t) + ;; + if !found + -> true + ;; + ;; mbldput("run {}: ", n.lbl) dir = std.pathcat(b.basedir, n.wdir) std.chdir(dir) std.slfree(dir) + + if targs.len > 0 + match std.strfind(targs[0], ":") + | `std.Some i: std.setenv("MTEST_SUBSET", targs[0][i+1:]) + | `std.None: /* ok */ + ;; + ;; match std.spork(n.cmd) | `std.Err m: std.fatal("\nunable to run test: {}\n", m) @@ -116,3 +122,9 @@ const runtest = {b, n, isbench, failed -> res } +const matchtest = {name, pat + match std.strfind(pat, ":") + | `std.Some i: -> std.strhas(name, pat[:i]) + | `std.None: -> std.strhas(name, pat) + ;; +} diff --git a/mk/bootstrap/bootstrap+Darwin-x86_64.sh b/mk/bootstrap/bootstrap+Darwin-x86_64.sh index ae2dbce..220420d 100755 --- a/mk/bootstrap/bootstrap+Darwin-x86_64.sh +++ b/mk/bootstrap/bootstrap+Darwin-x86_64.sh @@ -4,7 +4,7 @@ pwd=`pwd` set -x $pwd/6/6m -I lib/sys -I lib/std -I lib/bio -I lib/regex -I lib/thread mbld/config.myr - as -g -o mbld/cpufeatures.o mbld/cpufeatures+x64.s + as -g -o mbld/cpufeatures.o mbld/cpufeatures+posixy-x64.s as -g -o lib/thread/start.o lib/thread/start+osx-x64.s as -g -o lib/thread/atomic-impl.o lib/thread/atomic-impl+x64.s as -g -o lib/std/getbp.o lib/std/getbp+posixy-x64.s diff --git a/mk/bootstrap/bootstrap+FreeBSD-amd64.sh b/mk/bootstrap/bootstrap+FreeBSD-amd64.sh index 63c27dc..fe149c9 100755 --- a/mk/bootstrap/bootstrap+FreeBSD-amd64.sh +++ b/mk/bootstrap/bootstrap+FreeBSD-amd64.sh @@ -4,7 +4,7 @@ pwd=`pwd` set -x $pwd/6/6m -I lib/sys -I lib/std -I lib/bio -I lib/regex -I lib/thread mbld/config.myr - as -g -o mbld/cpufeatures.o mbld/cpufeatures+x64.s + as -g -o mbld/cpufeatures.o mbld/cpufeatures+posixy-x64.s as -g -o lib/thread/exit.o lib/thread/exit+freebsd-x64.s as -g -o lib/thread/atomic-impl.o lib/thread/atomic-impl+x64.s as -g -o lib/std/getbp.o lib/std/getbp+posixy-x64.s diff --git a/mk/bootstrap/bootstrap+Linux-x86_64.sh b/mk/bootstrap/bootstrap+Linux-x86_64.sh index 91c5c38..c27e044 100755 --- a/mk/bootstrap/bootstrap+Linux-x86_64.sh +++ b/mk/bootstrap/bootstrap+Linux-x86_64.sh @@ -4,7 +4,7 @@ pwd=`pwd` set -x $pwd/6/6m -I lib/sys -I lib/std -I lib/bio -I lib/regex -I lib/thread mbld/config.myr - as -g -o mbld/cpufeatures.o mbld/cpufeatures+x64.s + as -g -o mbld/cpufeatures.o mbld/cpufeatures+posixy-x64.s as -g -o lib/thread/exit.o lib/thread/exit+linux-x64.s as -g -o lib/thread/atomic-impl.o lib/thread/atomic-impl+x64.s as -g -o lib/std/getbp.o lib/std/getbp+posixy-x64.s diff --git a/mk/bootstrap/bootstrap+NetBSD-amd64.sh b/mk/bootstrap/bootstrap+NetBSD-amd64.sh index 54d79c4..e089748 100755 --- a/mk/bootstrap/bootstrap+NetBSD-amd64.sh +++ b/mk/bootstrap/bootstrap+NetBSD-amd64.sh @@ -4,7 +4,7 @@ pwd=`pwd` set -x $pwd/6/6m -I lib/sys -I lib/std -I lib/bio -I lib/regex -I lib/thread mbld/config.myr - as -g -o mbld/cpufeatures.o mbld/cpufeatures+x64.s + as -g -o mbld/cpufeatures.o mbld/cpufeatures+posixy-x64.s as -g -o lib/thread/atomic-impl.o lib/thread/atomic-impl+x64.s as -g -o lib/std/getbp.o lib/std/getbp+posixy-x64.s $pwd/6/6m -I . -I lib/sys lib/std/option.myr diff --git a/mk/bootstrap/bootstrap+OpenBSD-amd64.sh b/mk/bootstrap/bootstrap+OpenBSD-amd64.sh index ecda364..bcd0b7d 100755 --- a/mk/bootstrap/bootstrap+OpenBSD-amd64.sh +++ b/mk/bootstrap/bootstrap+OpenBSD-amd64.sh @@ -4,7 +4,7 @@ pwd=`pwd` set -x $pwd/6/6m -I lib/sys -I lib/std -I lib/bio -I lib/regex -I lib/thread mbld/config.myr - as -g -o mbld/cpufeatures.o mbld/cpufeatures+x64.s + as -g -o mbld/cpufeatures.o mbld/cpufeatures+posixy-x64.s as -g -o lib/thread/exit.o lib/thread/exit+openbsd-x64.s as -g -o lib/thread/atomic-impl.o lib/thread/atomic-impl+x64.s as -g -o lib/std/getbp.o lib/std/getbp+posixy-x64.s @@ -142,5 +142,5 @@ set -x $pwd/6/6m -I lib/sys -I lib/std -I lib/bio -I lib/regex -I lib/thread mbld/test.myr $pwd/6/6m -I lib/sys -I lib/std -I lib/bio -I lib/regex -I lib/thread mbld/deps.myr $pwd/6/6m -I lib/sys -I lib/std -I lib/bio -I lib/regex -I lib/thread mbld/main.myr - ld -nopie --gc-sections -o mbld/mbld $pwd/rt/_myrrt.o mbld/deps.o mbld/main.o mbld/util.o mbld/cpufeatures+x64.s mbld/libs.o mbld/syssel.o mbld/config.o mbld/opts.o mbld/subtest.o mbld/types.o mbld/test.o mbld/install.o mbld/parse.o mbld/build.o -Llib/thread -lthread -Llib/bio -lbio -Llib/regex -lregex -Llib/std -lstd -Llib/sys -lsys + ld -nopie --gc-sections -o mbld/mbld $pwd/rt/_myrrt.o mbld/deps.o mbld/main.o mbld/util.o mbld/cpufeatures.o mbld/libs.o mbld/syssel.o mbld/config.o mbld/opts.o mbld/subtest.o mbld/types.o mbld/test.o mbld/install.o mbld/parse.o mbld/build.o -Llib/thread -lthread -Llib/bio -lbio -Llib/regex -lregex -Llib/std -lstd -Llib/sys -lsys true diff --git a/mk/bootstrap/bootstrap+Plan9-amd64.sh b/mk/bootstrap/bootstrap+Plan9-amd64.sh index 8b45e53..cce2b4c 100755 --- a/mk/bootstrap/bootstrap+Plan9-amd64.sh +++ b/mk/bootstrap/bootstrap+Plan9-amd64.sh @@ -4,7 +4,7 @@ pwd=`pwd` set -x $pwd/6/6.out -I lib/sys -I lib/std -I lib/bio -I lib/regex -I lib/thread mbld/config+plan9-x64.myr - 6a -o mbld/cpufeatures.6 mbld/cpufeatures+x64.s + 6a -o mbld/cpufeatures.6 mbld/cpufeatures+plan9-x64.s 6a -o lib/thread/atomic-impl.6 lib/thread/atomic-impl+plan9-x64.s 6a -o lib/std/getbp.6 lib/std/getbp+plan9-x64.s $pwd/6/6.out -I lib/sys lib/std/errno+plan9.myr diff --git a/parse/infer.c b/parse/infer.c index bb1ea59..58399b0 100644 --- a/parse/infer.c +++ b/parse/infer.c @@ -29,6 +29,7 @@ struct Traitmap { size_t nfiltertr; }; +int allowhidden; static void infernode(Node **np, Type *ret, int *sawret); static void inferexpr(Node **np, Type *ret, int *sawret); @@ -69,6 +70,8 @@ static size_t nspecializations; static Stab **specializationscope; static size_t nspecializationscope; static Traitmap *traitmap; +static Bitset *tytraits[Ntypes]; + static void ctxstrcall(char *buf, size_t sz, Node *n) @@ -685,7 +688,7 @@ mktylike(Srcloc l, Ty other) t = mktyvar(l); /* not perfect in general, but good enough for all places mktylike is used. */ - t->trneed = bsdup(traitmap->sub[other]->traits); + t->trneed = bsdup(tytraits[other]); return t; } @@ -958,7 +961,7 @@ static void verifytraits(Node *ctx, Type *a, Type *b) { char traitbuf[64], abuf[64], bbuf[64]; - char asrc[64], bsrc[64]; + char asrc[128], bsrc[128]; Bitset *abs, *bbs; size_t i, n; Srcloc l; @@ -979,10 +982,11 @@ verifytraits(Node *ctx, Type *a, Type *b) n = 0; *traitbuf = 0; for (i = 0; bsiter(abs, &i); i++) { - if (!bshas(bbs, i)) + if (!bshas(bbs, i)) { n += bprintf(traitbuf + n, sizeof(traitbuf) - n, "%s%s", sep, - namestr(traittab[i]->name)); - sep = ","; + namestr(traittab[i]->name)); + sep = ","; + } } tyfmt(abuf, sizeof abuf, a); tyfmt(bbuf, sizeof bbuf, b); @@ -1320,7 +1324,7 @@ initvar(Node *n, Node *s) Type *t, *param; Tysubst *subst; - if (s->decl.ishidden) + if (s->decl.ishidden && !allowhidden) fatal(n, "attempting to refer to hidden decl %s", ctxstr(n)); param = n->expr.param; @@ -2787,41 +2791,47 @@ builtintraits(void) /* char::(numeric,integral) */ for (i = 0; i < Ntypes; i++) - traitmap->sub[i] = mktraitmap(); + tytraits[i] = mkbs(); - bsput(traitmap->sub[Tychar]->traits, Tcnum); - bsput(traitmap->sub[Tychar]->traits, Tcint); + bsput(tytraits[Tychar], Tcnum); + bsput(tytraits[Tychar], Tcint); - bsput(traitmap->sub[Tybyte]->traits, Tcnum); - bsput(traitmap->sub[Tybyte]->traits, Tcint); + bsput(tytraits[Tybyte], Tcnum); + bsput(tytraits[Tybyte], Tcint); /* <integer types>::(numeric,integral) */ for (i = Tyint8; i < Tyflt32; i++) { - bsput(traitmap->sub[i]->traits, Tcnum); - bsput(traitmap->sub[i]->traits, Tcint); + bsput(tytraits[i], Tcnum); + bsput(tytraits[i], Tcint); } /* <floats>::(numeric,floating) */ - bsput(traitmap->sub[Tyflt32]->traits, Tcnum); - bsput(traitmap->sub[Tyflt32]->traits, Tcflt); - bsput(traitmap->sub[Tyflt64]->traits, Tcnum); - bsput(traitmap->sub[Tyflt64]->traits, Tcflt); + bsput(tytraits[Tyflt32], Tcnum); + bsput(tytraits[Tyflt32], Tcflt); + bsput(tytraits[Tyflt64], Tcnum); + bsput(tytraits[Tyflt64], Tcflt); /* @a*::(sliceable) */ - bsput(traitmap->sub[Typtr]->traits, Tcslice); + bsput(tytraits[Typtr], Tcslice); /* @a[:]::(indexable,sliceable) */ - bsput(traitmap->sub[Tyslice]->traits, Tcidx); - bsput(traitmap->sub[Tyslice]->traits, Tcslice); - bsput(traitmap->sub[Tyslice]->traits, Tciter); + bsput(tytraits[Tyslice], Tcidx); + bsput(tytraits[Tyslice], Tcslice); + bsput(tytraits[Tyslice], Tciter); /* @a[SZ]::(indexable,sliceable) */ - bsput(traitmap->sub[Tyarray]->traits, Tcidx); - bsput(traitmap->sub[Tyarray]->traits, Tcslice); - bsput(traitmap->sub[Tyarray]->traits, Tciter); + bsput(tytraits[Tyarray], Tcidx); + bsput(tytraits[Tyarray], Tcslice); + bsput(tytraits[Tyarray], Tciter); /* @a::function */ - bsput(traitmap->sub[Tyfunc]->traits, Tcfunc); + bsput(tytraits[Tyfunc], Tcfunc); + + for (i = 0; i < Ntypes; i++) { + traitmap->sub[i] = mktraitmap(); + bsunion(traitmap->sub[i]->traits, tytraits[i]); + } + } static Trait* diff --git a/parse/parse.h b/parse/parse.h index 11b28ac..62392ca 100644 --- a/parse/parse.h +++ b/parse/parse.h @@ -378,6 +378,7 @@ extern Node **nodes; /* node id -> node map */ extern size_t ndecls; extern Node **exportimpls; extern size_t nexportimpls; +extern int allowhidden; /* property tables */ extern int opispure[]; diff --git a/parse/stab.c b/parse/stab.c index 7e1b8c0..0319d13 100644 --- a/parse/stab.c +++ b/parse/stab.c @@ -663,13 +663,17 @@ bindtype_rec(Tyenv *e, Type *t, Bitset *visited) switch (t->type) { case Typaram: tt = htget(e->tab, t); - if (tt && tt != t) + if (tt && tt != t) { tytab[t->tid] = tt; - else if (!boundtype(t)) + for (i = 0; i < t->nspec; i++) + lappend(&tt->spec, &tt->nspec, t->spec[i]); + } else if (!boundtype(t)) { htput(e->tab, t, t); - for (i = 0; i < t->nspec; i++) + } + for (i = 0; i < t->nspec; i++) { if (t->spec[i]->aux) bindtype_rec(e, t->spec[i]->aux, visited); + } break; case Tygeneric: for (i = 0; i < t->ngparam; i++) diff --git a/support/syscall-gen/gensys.sh b/support/syscall-gen/gensys.sh index c703642..51415a4 100755 --- a/support/syscall-gen/gensys.sh +++ b/support/syscall-gen/gensys.sh @@ -37,7 +37,7 @@ hdrgen() { ' < syscalls+$1.h | tee sysjoined.txt | awk -f gencalls.awk $1 $2 > sys+$1-$2.myr } -rm -f have.txt want.txt gentypes+$1-$2.frag +#rm -f have.txt want.txt gentypes+$1-$2.frag touch have.txt if [ `uname` = Linux ]; then diff --git a/support/syscall-gen/gentypes+openbsd:6.3-x64.frag b/support/syscall-gen/gentypes+openbsd:6.3-x64.frag new file mode 100644 index 0000000..00f9cd1 --- /dev/null +++ b/support/syscall-gen/gentypes+openbsd:6.3-x64.frag @@ -0,0 +1,119 @@ +type dev = int32 +type uid = uint32 +type fd_mask = uint32 +type uintptr = uint64 +type clockid = int32 +type id = uint32 +type key = int64 +type shmatt = int16 + +type tfork = struct + tcb : void# + tid : pid# + stack : void# + +;; + +type msghdr = struct + name : void# + namelen : int32 + iov : iovec# + iovlen : uint + control : void# + controllen : int32 + flags : int + +;; + +type fsid = struct + val : int32[2] + +;; + +type fid = struct + len : uint16 + reserved : uint16 + data : byte[16] + +;; + +type fhandle = struct + fsid : fsid + fid : fid + +;; + +type fdset = struct + bits : fd_mask[32] + +;; + +type kevent = struct + ident : uintptr + filter : int16 + flags : uint16 + fflags : uint + data : int64 + udata : void# + +;; + +type kbind = struct + addr : void# + size : size + +;; + +type sembuf = struct + num : uint16 + op : int16 + flg : int16 + +;; + +type ipc_perm = struct + cuid : uid + cgid : gid + uid : uid + gid : gid + mode : filemode + seq : uint16 + key : key + +;; + +type shmid_ds = struct + perm : ipc_perm + segsz : int + lpid : pid + cpid : pid + nattch : shmatt + atime : time + atimensec : int64 + dtime : time + dtimensec : int64 + ctime : time + ctimensec : int64 + internal : void# + +;; + +type msqid_ds = struct + perm : ipc_perm + first : msg# + last : msg# + cbytes : uint64 + qnum : uint64 + qbytes : uint64 + lspid : pid + lrpid : pid + stime : time + pad1 : int64 + rtime : time + pad2 : int64 + ctime : time + pad3 : int64 + pad4 : int64[4] + +;; + 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..4cc3843 --- /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, .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/types+openbsd:6.2-x64.frag b/support/syscall-gen/types+openbsd:6.2-x64.frag index 0d28f2e..8d48229 100644 --- a/support/syscall-gen/types+openbsd:6.2-x64.frag +++ b/support/syscall-gen/types+openbsd:6.2-x64.frag @@ -17,7 +17,7 @@ type sockfam = uint8 /* socket family */ type filemode = uint32 type filetype = uint8 type fcntlcmd = int64 -ype signo = int32 +type signo = int32 type sigflags = int32 type sigset = uint32 type msg = void diff --git a/support/syscall-gen/types+openbsd:6.3-x64.frag b/support/syscall-gen/types+openbsd:6.3-x64.frag new file mode 100644 index 0000000..cd204e5 --- /dev/null +++ b/support/syscall-gen/types+openbsd:6.3-x64.frag @@ -0,0 +1,479 @@ +type size = int64 /* spans entire address space */ +type usize = uint64 /* unsigned size */ +type off = int64 /* file offsets */ +type intptr = uint64/* can hold any pointer losslessly */ +type time = int64 /* milliseconds since epoch */ +type pid = int32 /* process id */ +type scno = int64 /*syscall*/ +type fdopt = int64 /* fd options */ +type fd = int32 /* fd */ +type whence = uint64 /* seek from whence */ +type mprot = int64 /* memory protection */ +type mopt = int64 /* memory mapping options */ +type socktype = int64 /* socket type */ +type sockproto = int64 /* socket protocol */ +type sockopt = int32 /* socket option */ +type sockfam = uint8 /* socket family */ +type filemode = uint32 +type filetype = uint8 +type fcntlcmd = int64 +type signo = int32 +type sigflags = int32 +type sigset = uint32 +type msg = void +type gid = uint32 + +const Futexwait : int = 1 +const Futexwake : int = 2 +const Futexrequeue : int = 3 + + +type clock = union + `Clockrealtime + `Clockmonotonic + `Clockproccputime + `Clockthreadcputime + `Clockuptime +;; + +type waitstatus = union + `Waitfail int32 + `Waitexit int32 + `Waitsig int32 + `Waitstop int32 +;; + +type rlimit = struct + cur : uint64 /* current (soft) limit */ + max : uint64 /* maximum value for rlim_cur */ +;; + +type timespec = struct + sec : uint64 + nsec : uint64 +;; + +type timeval = struct + sec : uint64 + usec : uint64 +;; + +type timezone = struct + minwest : int32 /* minutes west of Greenwich */ + dsttime : int32 /* type of dst correction */ +;; + +type pollfd = struct + fd : fd + events : uint16 + revents : uint16 +;; + +type itimerval = struct + interval : timeval /* timer interval */ + value : timeval /* current value */ +;; + +type sigaction = struct + handler : byte# /* code pointer */ + mask : sigset + flags : sigflags +;; +/* + * Information pushed on stack when a signal is delivered. + * This is used by the kernel to restore state following + * execution of the signal handler. It is also made available + * to the handler to allow it to restore state properly if + * a non-standard exit is performed. + */ +type sigcontext = struct + /* plain match trapframe */ + rdi : int64 + rsi : int64 + rdx : int64 + rcx : int64 + r8 : int64 + r9 : int64 + r10 : int64 + r11 : int64 + r12 : int64 + r13 : int64 + r14 : int64 + r15 : int64 + rbp : int64 + rbx : int64 + rax : int64 + gs : int64 + fs : int64 + es : int64 + ds : int64 + trapno : int64 + err : int64 + rip : int64 + cs : int64 + rflags : int64 + rsp : int64 + ss : int64 + + fpstate : fxsave64# + __pad : int32 + mask : int32 + cookie : int64 +;; + +type sigaltstack = struct + sp : void# + size : size + flags : int32 +;; + +type fxsave64 = struct + fcw : int16 + fsw : int16 + ftw : int8 + unused1 : int8 + fop : int16 + rip : int64 + rdp : int64 + mxcsr : int32 + mxcsrmask : int32 + st : int64[8][2] /* 8 normal FP regs */ + xmm : int64[16][2] /* 16 SSE2 registers */ + unused3 : int8[96] +;; + +const Simaxsz = 128 +const Sipad = (Simaxsz / 4) - 3 +type siginfo = struct + signo : int + code : int + errno : int + pad : int[Sipad] +;; + +type rusage = struct + utime : timeval /* user time */ + stime : timeval /* system time */ + maxrss : uint64 /* max resident set size*/ + ixrss : uint64 /* shared text size */ + idrss : uint64 /* unshared data size */ + isrss : uint64 /* unshared stack size */ + minflt : uint64 /* page reclaims */ + majflt : uint64 /* page faults */ + nswap : uint64 /* swaps */ + inblock : uint64 /* block input ops */ + oublock : uint64 /* block output ops */ + msgsnd : uint64 /* messages sent */ + msgrcv : uint64 /* messages received */ + nsignals : uint64 /* signals received */ + nvcsw : uint64 /* voluntary context switches */ + nivcsw : uint64 /* involuntary context switches */ +;; + +type tforkparams = struct + tcb : void# + tid : pid# + stk : byte# +;; + +type statbuf = struct + mode : filemode + dev : uint32 + ino : uint64 + nlink : uint32 + uid : uint32 + gid : uint32 + rdev : uint32 + atime : timespec + mtime : timespec + ctime : timespec + size : off + blocks : int64 + blksize : uint32 + flags : uint32 + gen : uint32 + birthtim : timespec +;; + +type semun = struct + semarr : void# +;; + +const Mfsnamelen = 16 /* length of fs type name, including nul */ +const Mnamelen = 90 /* length of buffer for returned name */ + +type statfs = struct + flags : uint32 /* copy of mount flags */ + bsize : uint32 /* file system block size */ + iosize : uint32 /* optimal transfer block size */ + + /* unit is f_bsize */ + blocks : uint64 /* total data blocks in file system */ + bfree : uint64 /* free blocks in fs */ + bavail : int64 /* free blocks avail to non-superuser */ + + files : int64 /* total file nodes in file system */ + ffree : int64 /* free file nodes in fs */ + favail : int64 /* free file nodes avail to non-root */ + + syncwr : int64 /* count of sync writes since mount */ + syncrd : int64 /* count of sync reads since mount */ + asyncwr : int64 /* count of async writes since mount */ + asyncrd : int64 /* count of async reads since mount */ + + fsid : fsid /* file system id */ + namemax : uint32 /* maximum filename length */ + owner : uid /* user that mounted the file system */ + ctime : uint64 /* last mount [-u] time */ + + fstypename : byte[Mfsnamelen]; /* fs type name */ + mntonname : byte[Mnamelen]; /* directory on which mounted */ + mntfromname : byte[Mnamelen]; /* mounted file system */ + mntfromspec : byte[Mnamelen]; /* special for mount request */ + ///union mount_info mount_info; /* per-filesystem mount options */ + __mountinfo : byte[160]; /* storage for 'union mount_info' */ +;; + +type utsname = struct + system : byte[32] + node : byte[32] + release : byte[32] + version : byte[32] + machine : byte[32] +;; + +type sockaddr = struct + len : byte + fam : sockfam + data : byte[14] /* what is the *actual* length? */ +;; + +type sockaddr_in = struct + len : byte + fam : sockfam + port : uint16 + addr : byte[4] + zero : byte[8] +;; + +type sockaddr_in6 = struct + len : byte + fam : sockfam + port : uint16 + flow : uint32 + addr : byte[16] + scope : uint32 +;; + +type sockaddr_un = struct + len : uint8 + fam : sockfam + path : byte[104] +;; + +type sockaddr_storage = struct + len : byte + fam : sockfam + __pad1 : byte[6] + __align : int64 + __pad2 : byte[240] +;; + +type dirent = struct + fileno : uint64 + off : uint64 + reclen : uint16 + ftype : uint8 + namlen : uint8 + __pad : byte[4] + name : byte[256] +;; + +type iovec = struct + base : byte# + len : uint64 +;; + +/* open options */ +const Ordonly : fdopt = 0x0 +const Owronly : fdopt = 0x1 +const Ordwr : fdopt = 0x2 +const Oappend : fdopt = 0x8 +const Ondelay : fdopt = 0x4 +const Oshlock : fdopt = 0x10 /* open with shared file lock */ +const Oexlock : fdopt = 0x20 /* open with exclusive file lock */ +const Oasync : fdopt = 0x40 /* signal pgrp when data ready */ +const Osync : fdopt = 0x80 /* backwards compatibility */ +const Onofollow : fdopt = 0x100 +const Ocreat : fdopt = 0x200 +const Otrunc : fdopt = 0x400 +const Oexcl : fdopt = 0x800 +const Ocloexec : fdopt = 0x10000 +const Odsync : fdopt = Osync /* synchronous data writes */ +const Orsync : fdopt = Osync /* synchronous reads */ +const Odir : fdopt = 0x20000 + +/* poll options */ +const Pollin : uint16 = 0x0001 +const Pollpri : uint16 = 0x0002 +const Pollout : uint16 = 0x0004 +const Pollerr : uint16 = 0x0008 +const Pollhup : uint16 = 0x0010 +const Pollnval : uint16 = 0x0020 +const Pollnorm : uint16 = 0x0040 +const Pollrdband: uint16 = 0x0080 +const Pollwrband: uint16 = 0x0100 + +/* stat modes */ +const Sifmt : filemode = 0xf000 +const Sififo : filemode = 0x1000 +const Sifchr : filemode = 0x2000 +const Sifdir : filemode = 0x4000 +const Sifblk : filemode = 0x6000 +const Sifreg : filemode = 0x8000 +const Siflnk : filemode = 0xa000 +const Sifsock : filemode = 0xc000 +const Sisvtx : filemode = 0x0200 + +/* mmap protection */ +const Mprotnone : mprot = 0x0 +const Mprotrd : mprot = 0x1 +const Mprotwr : mprot = 0x2 +const Mprotexec : mprot = 0x4 +const Mprotrw : mprot = 0x3 + +/* mmap options */ +const Mshared : mopt = 0x1 +const Mpriv : mopt = 0x2 +const Mfixed : mopt = 0x10 +const Mfile : mopt = 0x0 +const Manon : mopt = 0x1000 +const Mstack : mopt = 0x4000 +const Mnoreplace : mopt = 0x0800 + +/* file types */ +const Dtunknown : filetype = 0 +const Dtfifo : filetype = 1 +const Dtchr : filetype = 2 +const Dtdir : filetype = 4 +const Dtblk : filetype = 6 +const Dtreg : filetype = 8 +const Dtlnk : filetype = 10 +const Dtsock : filetype = 12 + +/* socket families. INCOMPLETE. */ +const Afunspec : sockfam = 0 +const Afunix : sockfam = 1 +const Afinet : sockfam = 2 +const Afinet6 : sockfam = 24 + +/* socket types. */ +const Sockstream : socktype = 1 +const Sockdgram : socktype = 2 +const Sockraw : socktype = 3 +const Sockrdm : socktype = 4 +const Sockseqpacket : socktype = 5 + +/* socket options */ +const Sodebug : sockopt = 0x0001 /* turn on debugging info recording */ +const Soacceptconn : sockopt = 0x0002 /* socket has had listen() */ +const Soreuseaddr : sockopt = 0x0004 /* allow local address reuse */ +const Sokeepalive : sockopt = 0x0008 /* keep connections alive */ +const Sodontroute : sockopt = 0x0010 /* just use interface addresses */ +const Sobroadcast : sockopt = 0x0020 /* permit sending of broadcast msgs */ +const Souseloopback : sockopt = 0x0040 /* bypass hardware when possible */ +const Solinger : sockopt = 0x0080 /* linger on close if data present */ +const Sooobinline : sockopt = 0x0100 /* leave received OOB data in line */ +const Soreuseport : sockopt = 0x0200 /* allow local address & port reuse */ +const Sotimestamp : sockopt = 0x0800 /* timestamp received dgram traffic */ +const Sobindany : sockopt = 0x1000 /* allow bind to any address */ +const Sosndbuf : sockopt = 0x1001 /* send buffer size */ +const Sorcvbuf : sockopt = 0x1002 /* receive buffer size */ +const Sosndlowat : sockopt = 0x1003 /* send low-water mark */ +const Sorcvlowat : sockopt = 0x1004 /* receive low-water mark */ +const Sosndtimeo : sockopt = 0x1005 /* send timeout */ +const Sorcvtimeo : sockopt = 0x1006 /* receive timeout */ +const Soerror : sockopt = 0x1007 /* get error status and clear */ +const Sotype : sockopt = 0x1008 /* get socket type */ +const Sonetproc : sockopt = 0x1020 /* multiplex; network processing */ +const Sortable : sockopt = 0x1021 /* routing table to be used */ +const Sopeercred : sockopt = 0x1022 /* get connect-time credentials */ +const Sosplice : sockopt = 0x1023 /* splice data to other socket */ + +/* socket option levels */ +const Solsocket : sockproto = 0xffff + +/* network protocols */ +const Ipproto_ip : sockproto = 0 +const Ipproto_icmp : sockproto = 1 +const Ipproto_tcp : sockproto = 6 +const Ipproto_udp : sockproto = 17 +const Ipproto_raw : sockproto = 255 + +const Seekset : whence = 0 +const Seekcur : whence = 1 +const Seekend : whence = 2 + +/* system specific constants */ +const Maxpathlen : size = 1024 + +/* fcntl constants */ +const Fdupfd : fcntlcmd = 0 /* duplicate file descriptor */ +const Fgetfd : fcntlcmd = 1 /* get file descriptor flags */ +const Fsetfd : fcntlcmd = 2 /* set file descriptor flags */ +const Fgetfl : fcntlcmd = 3 /* get file status flags */ +const Fsetfl : fcntlcmd = 4 /* set file status flags */ +const Fgetown : fcntlcmd = 5 /* get SIGIO/SIGURG proc/pgrp */ +const Fsetown : fcntlcmd = 6 /* set SIGIO/SIGURG proc/pgrp */ +const Fogetlk : fcntlcmd = 7 /* get record locking information */ +const Fosetlk : fcntlcmd = 8 /* set record locking information */ + +/* return value for a failed mapping */ +const Mapbad : byte# = (-1 : byte#) + +/* signal flags */ +const Saonstack : sigflags = 0x0001 /* take signal on signal stack */ +const Sarestart : sigflags = 0x0002 /* restart system on signal return */ +const Saresethand : sigflags = 0x0004 /* reset to SIG_DFL when taking signal */ +const Sanodefer : sigflags = 0x0010 /* don't mask the signal we're delivering */ +const Sanocldwait : sigflags = 0x0020 /* don't create zombies (assign to pid 1) */ +const Sanocldstop : sigflags = 0x0008 /* do not generate SIGCHLD on child stop */ +const Sasiginfo : sigflags = 0x0040 /* generate siginfo_t */ + +/* signals */ +const Sighup : signo = 1 /* hangup */ +const Sigint : signo = 2 /* interrupt */ +const Sigquit : signo = 3 /* quit */ +const Sigill : signo = 4 /* illegal instruction (not reset when caught) */ +const Sigtrap : signo = 5 /* trace trap (not reset when caught) */ +const Sigabrt : signo = 6 /* abort() */ +const Sigiot : signo = Sigabrt /* compatibility */ +const Sigemt : signo = 7 /* EMT instruction */ +const Sigfpe : signo = 8 /* floating point exception */ +const Sigkill : signo = 9 /* kill (cannot be caught or ignored) */ +const Sigbus : signo = 10 /* bus error */ +const Sigsegv : signo = 11 /* segmentation violation */ +const Sigsys : signo = 12 /* bad argument to system call */ +const Sigpipe : signo = 13 /* write on a pipe with no one to read it */ +const Sigalrm : signo = 14 /* alarm clock */ +const Sigterm : signo = 15 /* software termination signal from kill */ +const Sigurg : signo = 16 /* urgent condition on IO channel */ +const Sigstop : signo = 17 /* sendable stop signal not from tty */ +const Sigtstp : signo = 18 /* stop signal from tty */ +const Sigcont : signo = 19 /* continue a stopped process */ +const Sigchld : signo = 20 /* to parent on child stop or exit */ +const Sigttin : signo = 21 /* to readers pgrp upon background tty read */ +const Sigttou : signo = 22 /* like TTIN for output if (tp->t_local<OSTOP) */ +const Sigio : signo = 23 /* input/output possible signal */ +const Sigxcpu : signo = 24 /* exceeded CPU time limit */ +const Sigxfsz : signo = 25 /* exceeded file size limit */ +const Sigvtalrm : signo = 26 /* virtual time alarm */ +const Sigprof : signo = 27 /* profiling time alarm */ +const Sigwinch : signo = 28 /* window size changes */ +const Siginfo : signo = 29 /* information request */ +const Sigusr1 : signo = 30 /* user defined signal 1 */ +const Sigusr2 : signo = 31 /* user defined signal 2 */ +const Sigthr : signo = 32 /* thread library AST */ + +extern const syscall : (sc:scno, args:... -> int64) +extern var __cenvp : byte## diff --git a/test/data/strfind-expected b/test/data/strfind-expected index 04e7a1c..4e6ab82 100644 --- a/test/data/strfind-expected +++ b/test/data/strfind-expected @@ -1,4 +1,4 @@ -No match +Found 0 No match No match Found 0 |