all the .ed files updated, makea still needs more work - vx32 - Local 9vx git repository for patches.
Log
Files
Refs
---
commit 0e345fe6a6994b2df8dd744e9b0e68ce9026a293
parent a3985efe6946ed22480d95497c21a5fce3d8c678
Author: yiyus 
Date:   Wed, 21 Jul 2010 21:20:48 +0200

all the .ed files updated, makea still needs more work

Diffstat:
  src/9vx/a/segment.c                 |       3 +--
  src/9vx/a/segment.ed                |       3 ++-
  src/9vx/a/swap.c                    |       7 +++----
  src/9vx/a/swap.ed                   |       3 +++
  src/9vx/a/sysfile.c                 |       5 +++--
  src/9vx/a/sysfile.ed                |     176 ++++++++++++++++++++++++++++++-
  src/9vx/a/sysproc.c                 |       7 ++++---
  src/9vx/a/sysproc.ed                |     424 ++++++++++++++++++++++++++++++-
  src/9vx/a/systab.ed                 |       1 +

9 files changed, 612 insertions(+), 17 deletions(-)
---
diff --git a/src/9vx/a/segment.c b/src/9vx/a/segment.c
@@ -483,8 +483,6 @@ ibrk(ulong addr, int seg)
                 if(ns == 0 || ns == s)
                         continue;
                 if(newtop >= ns->base && newtop < ns->top) {
-print("grow segment %d -> %p would overlap %d [%p-%p]\n",
-        seg, newtop, i, ns->base, ns->top);
                         qunlock(&s->lk);
                         error(Esoverlap);
                 }
@@ -648,6 +646,7 @@ segattach(Proc *p, ulong attr, char *name, ulong va, ulong len)
                 error(Ebadarg);
 
         vmemchr(name, 0, ~0);
+
         for(sno = 0; sno < NSEG; sno++)
                 if(p->seg[sno] == nil && sno != ESEG)
                         break;
diff --git a/src/9vx/a/segment.ed b/src/9vx/a/segment.ed
@@ -1,4 +1,3 @@
-/^addphysseg/-1,/^        return/+1d
 ,s!Lock;!Lock lk;!
 ,s!lock(s)!lock(\&s->ref.lk)!g
 ,s!lock(i)!lock(\&i->ref.lk)!g
@@ -24,3 +23,5 @@
 /^}/i
 #endif
 .
+/validaddr/d
+/^syssegflush/s/ulong/uint32/
diff --git a/src/9vx/a/swap.c b/src/9vx/a/swap.c
@@ -67,7 +67,7 @@ putswap(Page *p)
                         swapalloc.last = idx;
         }
         if(*idx >= 254)
-                panic("putswap %lux == %ud", p, *idx);
+                panic("putswap %#p == %ud", p, *idx);
         unlock(&swapalloc.lk);
 }
 
@@ -107,7 +107,7 @@ pager(void *junk)
         Proc *p, *ep;
 
         if(waserror())
-                panic("pager: os error\n");
+                panic("pager: os error");
 
         p = proctab(0);
         ep = &p[conf.nproc];
@@ -115,7 +115,6 @@ pager(void *junk)
 loop:
         up->psstate = "Idle";
         sleep(&swapalloc.r, needpages, 0);
-print("uh oh.  someone woke the pager\n");
 
         while(needpages(junk)) {
 
@@ -335,7 +334,7 @@ executeio(void)
 
         for(i = 0; i < ioptr; i++) {
                 if(ioptr > conf.nswppo)
-                        panic("executeio: ioptr %d > %d\n", ioptr, conf.nswppo);
+                        panic("executeio: ioptr %d > %d", ioptr, conf.nswppo);
                 out = iolist[i];
                 k = kmap(out);
                 kaddr = (char*)VA(k);
diff --git a/src/9vx/a/swap.ed b/src/9vx/a/swap.ed
@@ -7,3 +7,6 @@
 ,s;lock(out);lock(\&out->lk);g
 ,s;lock(outp);lock(\&outp->lk);g
 g/swopen/d
+/if(!cpuserver)/;/else/c
+                        if(!cpuserver || freebroken() == 0)
+.
diff --git a/src/9vx/a/sysfile.c b/src/9vx/a/sysfile.c
@@ -175,7 +175,7 @@ sysfd2path(uint32 *arg)
 {
         Chan *c;
         char *buf;
-        
+
         buf = uvalidaddr(arg[1], arg[2], 1);
 
         c = fdtochan(arg[0], -1, 0, 1);
@@ -848,7 +848,7 @@ sseek(vlong *ret, uint32 *arg)
         default:
                 error(Ebadarg);
         }
-        *ret = off;        /* caller translated arg[0] already */
+        *ret = off;
         c->uri = 0;
         c->dri = 0;
         cclose(c);
@@ -983,6 +983,7 @@ syschdir(uint32 *arg)
         return 0;
 }
 
+        // Plan 9 VX added isk parameter.
 long
 bindmount(int ismount, int fd, int afd, char* arg0, char* arg1, ulong flag, char* spec)
 {
diff --git a/src/9vx/a/sysfile.ed b/src/9vx/a/sysfile.ed
@@ -21,17 +21,189 @@
 g/^sys_/ s/ulong \*)/ulong *u)/
 /^bindmount/,/^sysbind/ s/validaddr/if(!isk) validaddr/
 /^bindmount/,/^sysbind/ s/spec = validnamedup/if(isk) kstrdup(\&spec, spec); else &/
+g/^[a-z]/ s/ulong/uint32/g
+/^openmode/ s/uint32/ulong/
+/^sysfd2path/ s/^//
+/validaddr/-1;+1c
+        char *buf;
+
+        buf = uvalidaddr(arg[1], arg[2], 1);
+.
+/snprint/ s/(char\*)arg\[1\]/buf/
+/^syspipe/ s/^//
+/validaddr/-1;+1c
+        int *ufd;
+        
+        ufd = uvalidaddr(arg[0], 2*BY2WD, 1);
+.
+/((long\*)arg\[0\])/ s/((long\*)arg\[0\])/ufd/
+/((long\*)arg\[0\])/ s/((long\*)arg\[0\])/ufd/
+/^sysopen/ s/^//
+/^$/i
+        char *name;
+.
+/openmode/a
+        name = uvalidaddr(arg[0], 1, 0);
+        c = namec(name, Aopen, arg[1], 0);
+.
+/if(c)/d
+s/        //
+/validaddr/;/c = namec/d
+/^doread/ s/^//
+/^{/a
+        int dir;
+.
+/validaddr/;/p =/c
+        p = uvalidaddr(arg[1], n, 1);
+.
+/QTDIR/;/c->umh/c
+        dir = c->qid.type&QTDIR;
+        if(dir && mountrockread(c, p, n, &nn)){
+                /* do nothing: mountrockread filled buffer */
+        }else{
+                if(dir && c->umh)
+.
+/else{/;/}/c
+                else
+                        nn = devtab[c->type]->read(c, p, n, off);
+        }
+        if(dir)
+.
+/}else/;/nnn/c
+        else
+                nnn = nn;
+.
+/^dowrite/ s/^//
+/^$/i
+        uchar *p;
+.
+/validaddr/ s/v/p = uv/
+/m = devtab/ s/(void\*)arg\[1\]/p/
+/^sseek/s/(/(vlong *ret, /
+/u\[2\]/ s/ulong/uint32/
+/arg\[0\] = off/ s/\*(vlong\*)arg\[0\]/*ret/
+/^sysseek/s/^//
+/validaddr/;/sseek/c
+        sseek(uvalidaddr(arg[0], BY2V, 1), arg);
+.
+/^sysoseek/s/^//
+/^{/;/^$/s/ulong/uint32/g
+/a\[0\]/ s/=.*/= 0;/
+/sseek/ s/(.*)/(\&o.v, a)/
+/^sysfstat/ s/^//
+/^$/i
+        uchar *p;
+.
+/validaddr/ s/v/p = uv/
+/l = devtab/ s/(.*)/(c, p, l)/
+/^sysstat/ s/^//
+/^$/i
+        uchar *p;
+.
+/validaddr/ s/v/p = uv/
+/validaddr/ s/v/name = uv/
+/c = namec/ s/(char\*)arg\[0\]/name/
+/l = devtab/ s/(.*)/(c, p, l)/
+/l = dirsetname/ s/(uchar\*)arg\[1\]/p/
+/^syschdir/ s/^//
+/^$/i
+        char *name;
+.
+/validaddr/ s/v/name = uv/
+/c = namec/ s/(char\*)arg\[0\]/name/
+/^bindmount/ s/int isk, //
+s/uint32/ulong/
+/isk/d
+/isk/s/if.*else //
+/isk/d
+/isk/d
+/^sysbind/ s/^//
+/return/ s/0, //
+s/(char\*)arg\[0\]/uvalidaddr(arg[0], 1, 0)/
+s/(char\*)arg\[1\]/uvalidaddr(arg[1], 1, 0)/
+/^sysmount/ s/^//
+/return/ s/0, //
+s/(char\*)arg\[2\]/uvalidaddr(arg[2], 1, 0)/
+s/(char\*)arg\[4\]/uvalidaddr(arg[4], 1, 0)/
+/^sys_mount/ s/^//
+/return/ s/0, //
+s/(char\*)arg\[1\]/uvalidaddr(arg[1], 1, 0)/
+s/(char\*)arg\[3\]/uvalidaddr(arg[3], 1, 0)/
+/^sysunmount/ s/^//
+/^$/i
+        char *mount, *mounted;
+.
+/validaddr/;/cmount/c
+        mount = uvalidaddr(arg[1], 1, 0);
+        cmount = namec(mount, Amount, 0, 0);
+.
+/validaddr/ s/v/mounted = uv/
+/cmounted/ s/(char\*)arg\[0\]/mounted/
+/^syscreate/ s/^//
+/^$/i
+        char *name;
+.
+/validaddr/;/c = namec/c
+        name = uvalidaddr(arg[0], 1, 0);
+        c = namec(name, Acreate, arg[1], arg[2]);
+.
+/^sysremove/ s/^//
+/^$/i
+        char *name;
+.
+/validaddr/;/c = namec/c
+        name = uvalidaddr(arg[0], 1, 0);
+        c = namec(name, Aremove, 0, 0);
+.
+/^syswstat/ s/^//
+/^$/i
+        char *name;
+        uchar *p;
+.
+/validaddr/;/return/c
+        p = uvalidaddr(arg[1], l, 0);
+        validstat(p, l);
+        name = uvalidaddr(arg[0], 1, 0);
+        c = namec(name, Aaccess, 0, 0);
+        return wstat(c, p, l);
+.
+/^sysfwstat/ s/^//
+/^$/i
+        uchar *p;
+.
+/validaddr/ s/v/p = uv/
+/validstat/ s/(uchar\*)arg\[1\]/p/
+/return/ s/(uchar\*)arg\[1\]/p/
+/^sys_stat/ s/^//
+/name/ s/;/, *elem;/
+/^$/i
+        uchar *p;
+.
+/validaddr/;/namec/c
+        p = uvalidaddr(arg[1], 116, 1);
+        name = uvalidaddr(arg[0], 1, 0);
+        c = namec(name, Aaccess, 0, 0);
+.
+/name =/;/l =/ s/name/elem/g
+/dirsetelem/ s/elem/name/
+/packoldstat/ s/(uchar\*)arg\[1\]/p/
+/^sys_fstat/ s/^//
+/^$/i
+        uchar *p;
+.
+/validaddr/ s/v/p = uv/
+/packoldstat/ s/(uchar\*)arg\[1\]/p/
 $a
 
 // Plan 9 VX additions
 long
 kbind(char *new, char *old, int flag)
 {
-        return bindmount(1, 0, -1, -1, new, old, flag, nil);
+        return bindmount(0, -1, -1, new, old, flag, nil);
 }
 
 long
-syspassfd(ulong *u)
+syspassfd(uint32 *u)
 {
         error("passfd unimplemented");
         return -1;
diff --git a/src/9vx/a/sysproc.c b/src/9vx/a/sysproc.c
@@ -7,7 +7,7 @@
 #include        "fns.h"
 #include        "error.h"
 
-#include "a.out.h"
+#include        "a.out.h"
 
 int        shargs(char*, int, char**);
 
@@ -644,6 +644,7 @@ sysexits(uint32 *arg)
                         }
                         poperror();
                 }
+
         }else
                 status = nil;
         pexit(status, 1);
@@ -1113,7 +1114,7 @@ syssemacquire(uint32 *arg)
         evenaddr(arg[0]);
         block = arg[1];
         
-        if((s = seg(up, arg[0], 0)) == nil)        /* this can't happen if validaddr succeeded, can it? */
+        if((s = seg(up, arg[0], 0)) == nil)
                 error(Ebadarg);
         if(*addr < 0)
                 error(Ebadarg);
@@ -1130,7 +1131,7 @@ syssemrelease(uint32 *arg)
         evenaddr(arg[0]);
         delta = arg[1];
 
-        if((s = seg(up, arg[0], 0)) == nil)        /* again, this can't happen! */
+        if((s = seg(up, arg[0], 0)) == nil)
                 error(Ebadarg);
         if(delta < 0 || *addr < 0)
                 error(Ebadarg);
diff --git a/src/9vx/a/sysproc.ed b/src/9vx/a/sysproc.ed
@@ -1,15 +1,16 @@
+1i
+#define        WANT_M
+.
 g/"edf.h"/d
 ,s/->ref =/->ref.ref =/g
 ,s/ref(p->dot)/ref(\&p->dot->ref)/g
 ,s/ref(p->fgrp)/ref(\&p->fgrp->ref)/g
 ,s/ref(p->pgrp)/ref(\&p->pgrp->ref)/g
-,s/ref(p->rgrp)/ref(\&p->rgrp->ref)/g
 ,s/ref(p->egrp)/ref(\&p->egrp->ref)/g
 ,s/lock(img)/lock(\&img->ref.lk)/g
 ,s/ref(img)/ref(\&img->ref)/g
 ,s/return0(void\*)/return0(void *v)/g
 ,s/(s = up->seg\[i\])/(&)/g
-/edf.*Admitted/,/else/d
 ,s;MACHP(0)->ticks;msec();g
 /ESEG.*= newseg/a
         flushmmu();        // Needed for Plan 9 VX
@@ -19,10 +20,427 @@ g/"edf.h"/d
 ,s;wakeup(p);wakeup(\&p->rendez);g
 ,s;lock(up->rgrp);lock(\&up->rgrp->ref.lk);g
 ,s;ref(up->rgrp);ref(\&up->rgrp->ref);g
-/sysr1/ s/(ulong\*)/(ulong *x)/
+/sysr1/ s/(ulong\*)/(uint32 *x)/
 /Admitted/,/        yield/c
                 yield();
 .
 /^        checkpagerefs/ c
         vx32sysr1();
 .
+/^sysrfork/ s/ulong/uint32/
+/^l2be/ s/long/uint32/
+-1 s/ulong/uint32/
+/^sysexec/ s/ulong/uint32/
+-1i
+static char Echanged[] = "exec arguments changed underfoot";
+
+.
+/^{/+1;/^}/-1 c
+        char *volatile elem, *volatile file, *ufile;
+        Chan *volatile tc;
+
+        /*
+         * Open the file, remembering the final element and the full name.
+         */
+        file = nil;
+        elem = nil;
+        tc = nil;
+        if(waserror()){
+                if(file)
+                        free(file);
+                if(elem)
+                        free(elem);
+                if(tc)
+                        cclose(tc);
+                nexterror();
+        }
+
+        ufile = uvalidaddr(arg[0], 1, 0);
+        file = validnamedup(ufile, 1);
+        tc = namec(file, Aopen, OEXEC, 0);
+        kstrdup((char**)&elem, up->genbuf);
+
+        /*
+         * Read the header.  If it's a #!, fill in progarg[] with info and repeat.
+         */
+        int i, n, nprogarg;
+        char *progarg[sizeof(Exec)/2+1];
+        char *prog, *p;
+        char line[sizeof(Exec)+1];
+        Exec exec;
+
+        nprogarg = 0;
+        n = devtab[tc->type]->read(tc, &exec, sizeof(Exec), 0);
+        if(n < 2)
+                error(Ebadexec);
+        p = (char*)&exec;
+        if(p[0] == '#' && p[1] == '!'){
+                memmove(line, p, n);
+                nprogarg = shargs(line, n, progarg);
+                if(nprogarg == 0)
+                        error(Ebadexec);
+                
+                /* The original file becomes an extra arg after #! line */
+                progarg[nprogarg++] = file;
+                
+                /*
+                 * Take the #! $0 as a file to open, and replace
+                 * $0 with the original path's name.
+                 */
+                prog = progarg[0];
+                progarg[0] = elem;
+                cclose(tc);
+                tc = nil;        /* in case namec errors out */
+                tc = namec(prog, Aopen, OEXEC, 0);
+                n = devtab[tc->type]->read(tc, &exec, sizeof(Exec), 0);
+                if(n < 2)
+                        error(Ebadexec);
+        }
+
+        /* 
+         * #! has had its chance, now we need a real binary
+         */
+        uint32 magic, entry, text, etext, data, edata, bss, ebss;
+
+        magic = l2be(exec.magic);
+        if(n != sizeof(Exec) || l2be(exec.magic) != AOUT_MAGIC)
+                error(Ebadexec);
+
+        entry = l2be(exec.entry);
+        text = l2be(exec.text);
+        data = l2be(exec.data);
+        bss = l2be(exec.bss);
+        etext = ROUND(UTZERO+sizeof(Exec)+text, BY2PG);
+        edata = ROUND(etext + data, BY2PG);
+        ebss = ROUND(etext + data + bss, BY2PG);
+        
+//iprint("entry %#lux text %#lux data %#lux bss %#lux\n", entry, text, data, bss);
+//iprint("etext %#lux edata %#lux ebss %#lux\n", etext, edata, ebss);
+
+        if(entry < UTZERO+sizeof(Exec) || entry >= UTZERO+sizeof(Exec)+text)
+                error(Ebadexec);
+        
+        /* many overflow possibilities */
+        if(text >= USTKTOP || data >= USTKTOP || bss >= USTKTOP
+        || etext >= USTKTOP || edata >= USTKTOP || ebss >= USTKTOP
+        || etext >= USTKTOP || edata < etext || ebss < edata)
+                error(Ebadexec);
+
+        /*
+         * Copy argv into new stack segment temporarily mapped elsewhere.
+         * Be careful: multithreaded program could be changing argv during this.
+         * Pass 1: count number of arguments, string bytes.
+         */
+        int nargv, strbytes;
+        uint32 argp, ssize, spage;
+
+        strbytes = 0;
+        for(i=0; i 0 && nargv == 0)
+                        continue;        /* going to skip argv[0] on #! */
+                strbytes += n;
+        }
+        if(nargv == 0)
+                error("exec missing argv");
+
+        /* 
+         * Skip over argv[0] if using #!.  Waited until now so that
+         * string would still be checked for validity during loop.
+         */
+        if(nprogarg > 0){
+                nargv--;
+                arg[1] += BY2WD;
+        }
+
+        ssize = BY2WD*((nprogarg+nargv)+1) + ROUND(strbytes, BY2WD) + sizeof(Tos);
+
+        /*
+         * 8-byte align SP for those (e.g. sparc) that need it.
+         * execregs() will subtract another 4 bytes for argc.
+         */
+        if((ssize+4) & 7)
+                ssize += 4;
+        spage = (ssize+(BY2PG-1)) >> PGSHIFT;
+
+        /*
+         * Pass 2: build the stack segment, being careful not to assume
+         * that the counts from pass 1 are still valid.
+         */
+        if(spage > TSTKSIZ)
+                error(Enovmem);
+
+        qlock(&up->seglock);
+        if(waserror()){
+                if(up->seg[ESEG]){
+                        putseg(up->seg[ESEG]);
+                        up->seg[ESEG] = nil;
+                }
+                qunlock(&up->seglock);
+                nexterror();
+        }
+        up->seg[ESEG] = newseg(SG_STACK, TSTKTOP-USTKSIZE, USTKSIZE/BY2PG);
+        flushmmu();        // Needed for Plan 9 VX  XXX really?
+
+        /*
+         * Top-of-stack structure.
+         */
+        uchar *uzero;
+        uzero = up->pmmu.uzero;
+        Tos *tos;
+        uint32 utos;
+        utos = USTKTOP - sizeof(Tos);
+        tos = (Tos*)(uzero + utos + TSTKTOP - USTKTOP);
+        tos->cyclefreq = m->cyclefreq;
+        cycles((uvlong*)&tos->pcycles);
+        tos->pcycles = -tos->pcycles;
+        tos->kcycles = tos->pcycles;
+        tos->clock = 0;
+
+        /*
+         * Argument pointers and strings, together.
+         */
+        char *bp, *ep;
+        uint32 *targp;
+        uint32 ustrp, uargp;
+
+        ustrp = utos - ROUND(strbytes, BY2WD);
+        uargp = ustrp - BY2WD*((nprogarg+nargv)+1);
+        bp = (char*)(uzero + ustrp + TSTKTOP - USTKTOP);
+        ep = bp + strbytes;
+        p = bp;
+        targp = (uint32*)(uzero + uargp + TSTKTOP - USTKTOP);
+        
+        /* #! args are trusted */
+        for(i=0; i ep - p)
+                        error(Echanged);
+                memmove(p, progarg[i], n);
+                p += n;
+                *targp++ = ustrp;
+                ustrp += n;
+        }
+        
+        /* the rest are not */
+        argp = arg[1];
+        for(i=0; i ep - p)
+                        error(Echanged);
+                memmove(p, str, n);
+                p += n;
+                *targp++ = ustrp;
+                ustrp += n;
+        }
+
+        if(*(uint32*)uvalidaddr(argp, BY2WD, 0) != 0)
+                error(Echanged);        
+        *targp = 0;
+
+        /*
+         * But wait, there's more: prepare an arg copy for up->args
+         * using the copy we just made in the temporary segment.
+         */
+        char *args;
+        int nargs;
+
+        n = p - bp;        /* includes NUL on last arg, so must be > 0 */
+        if(n <= 0)        /* nprogarg+nargv > 0; checked above */
+                error(Egreg);
+        if(n > 128)
+                n = 128;
+        args = smalloc(n);
+        if(waserror()){
+                free(args);
+                nexterror();
+        }
+        memmove(args, bp, n);
+        /* find beginning of UTF character boundary to place final NUL */
+        while(n > 0 && (args[n-1]&0xC0) == 0x80)
+                n--;
+        args[n-1] = '\0';
+        nargs = n;
+
+        /*
+         * Now we're ready to commit.
+         */
+        free(up->text);
+        up->text = elem;
+        free(up->args);
+        up->args = args;
+        up->nargs = n;
+        elem = nil;
+        poperror();        /* args */
+
+        /*
+         * Free old memory.  Special segments maintained across exec.
+         */
+        Segment *s;
+        for(i = SSEG; i <= BSEG; i++) {
+                putseg(up->seg[i]);
+                up->seg[i] = nil;        /* in case of error */
+        }
+        for(i = BSEG+1; i< NSEG; i++) {
+                s = up->seg[i];
+                if(s && (s->type&SG_CEXEC)) {
+                        putseg(s);
+                        up->seg[i] = nil;
+                }
+        }
+        
+        /*
+         * Close on exec
+         */
+        Fgrp *f;
+        f = up->fgrp;
+        for(i=0; i<=f->maxfd; i++)
+                fdclose(i, CCEXEC);
+
+        /* Text.  Shared. Attaches to cache image if possible */
+        /* attachimage returns a locked cache image */
+        Image *img;
+        Segment *ts;
+        img = attachimage(SG_TEXT|SG_RONLY, tc, UTZERO, (etext-UTZERO)>>PGSHIFT);
+        ts = img->s;
+        up->seg[TSEG] = ts;
+        ts->flushme = 1;
+        ts->fstart = 0;
+        ts->flen = sizeof(Exec)+text;
+        unlock(&img->ref.lk);
+
+        /* Data. Shared. */
+        s = newseg(SG_DATA, etext, (edata-etext)>>PGSHIFT);
+        up->seg[DSEG] = s;
+
+        /* Attached by hand */
+        incref(&img->ref);
+        s->image = img;
+        s->fstart = ts->fstart+ts->flen;
+        s->flen = data;
+
+        /* BSS. Zero fill on demand */
+        up->seg[BSEG] = newseg(SG_BSS, edata, (ebss-edata)>>PGSHIFT);
+
+        /*
+         * Move the stack
+         */
+        s = up->seg[ESEG];
+        up->seg[ESEG] = 0;
+        up->seg[SSEG] = s;
+        qunlock(&up->seglock);
+        poperror();        /* seglock */
+
+        s->base = USTKTOP-USTKSIZE;
+        s->top = USTKTOP;
+        relocateseg(s, USTKTOP-TSTKTOP);
+
+        /*
+         *  '/' processes are higher priority (hack to make /ip more responsive).
+         */
+        if(devtab[tc->type]->dc == L'/')
+                up->basepri = PriRoot;
+        up->priority = up->basepri;
+        poperror();        /* tc, elem, file */
+        cclose(tc);
+        free(file);
+        // elem is now up->text
+
+        /*
+         *  At this point, the mmu contains info about the old address
+         *  space and needs to be flushed
+         */
+        flushmmu();
+        qlock(&up->debug);
+        up->nnote = 0;
+        up->notify = 0;
+        up->notified = 0;
+        up->privatemem = 0;
+        procsetup(up);
+        qunlock(&up->debug);
+        if(up->hang)
+                up->procctl = Proc_stopme;
+
+        return execregs(entry, USTKTOP - uargp, nprogarg+nargv);
+.
+/^syssleep/s/ulong/uint32/
+/^sysalarm/s/ulong/uint32/
+/^sysexits/s/ulong/uint32/
+/status/;/if(status)/ c
+        char *status;
+        char *inval = "invalid exit string";
+        char buf[ERRMAX];
+
+        if(arg[0]){
+.
+/validaddr/c
+                        status = uvalidaddr(arg[0], 1, 0);
+.
+/^        }/ c
+        }else
+                status = nil;
+.
+/^sys_wait/s/ulong/uint32/
+/validaddr(arg\[0\], sizeof(OWaitmsg), 1)/ c
+        ow = uvalidaddr(arg[0], sizeof(OWaitmsg), 1);
+.
+/ow =/d
+/^sysawait/s/ulong/uint32/
+/ulong n/ s/ulong/uint32/
+a
+        char *buf;
+.
+/validaddr/ s/v/buf = uv/
+/i = / s/(char\*)arg\[0\]/buf/
+/^generrstr/ s/char \*buf/uint32 addr/
+/^$/i
+        char *buf;
+.
+/validaddr/ s/v/buf = uv/
+s/(ulong)buf/addr/
+/^syserrstr/s/ulong/uint32/
+/return/s/(char\*)//
+/^sys_errstr/s/ulong/uint32/
+/return/s/(char\*)//
+/^sysnotify/s/ulong/uint32/
+/validaddr/;/up->notify/c
+                uvalidaddr(arg[0], 1, 0);
+        up->notify = arg[0];        /* checked again when used */
+.
+/^sysnoted/s/ulong/uint32/
+/^syssegbrk/s/ulong/uint32/
+/addr/s/ulong/uint32/
+/^syssegattach/s/ulong/uint32/
+/return/s/(char\*)arg\[1\]/uvalidaddr(arg[1], 1, 0)/
+/^syssegdetach/s/ulong/uint32/
+/addr/s/ulong/uint32/
+/^syssegfree/s/ulong/uint32/
+/from/s/ulong/uint32/
+/^sysbrk_/s/ulong/uint32/
+/^sysrendezvous/s/ulong/uint32/
+/^syssemacquire/s/ulong/uint32/
+/validaddr/ s/v/addr = uv/
+/addr =/d
+/(ulong)addr/s/(ulong)addr/arg[0]/
+/^syssemrelease/s/ulong/uint32/
+/validaddr/ s/v/addr = uv/
+/addr =/d
+/(ulong)addr/s/(ulong)addr/arg[0]/
diff --git a/src/9vx/a/systab.ed b/src/9vx/a/systab.ed
@@ -1 +1,2 @@
 ,s!"/sys/src/libc/9syscall/!"!
+/Syscall/s/ulong/uint32/