improved truss output per nemo and other comments devram. Fix p->syscalltrace handling, make sure freed in pexit if needed and set to 0 in newproc - vx32 - Local 9vx git repository for patches.
       
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
 (DIR) commit aea78725bd855b6f345dbd843628577b42ea4bbd
 (DIR) parent d8ca118560a6bbcfc61884ea0ea88756dad39432
 (HTM) Author: rminnich@nox.hsd1.ca.comcast.net <none@none>
       Date:   Tue, 13 Apr 2010 14:15:55 -0700
       
       improved truss output per nemo and other comments
       devram.
       Fix p->syscalltrace handling, make sure freed in pexit if needed
       and set to 0 in newproc
       
       Diffstat:
         src/9vx/a/devram.c                  |     394 +++++++++++++++++++++++++++++++
         src/9vx/a/proc.c                    |       3 +++
         src/9vx/trap.c                      |     422 ++++++++++++++-----------------
       
       3 files changed, 580 insertions(+), 239 deletions(-)
       ---
 (DIR) diff --git a/src/9vx/a/devram.c b/src/9vx/a/devram.c
       @@ -0,0 +1,394 @@
       +#include        "u.h"
       +#include        "lib.h"
       +#include        "mem.h"
       +#include        "dat.h"
       +#include        "fns.h"
       +#include        "error.h"
       +
       +#include        "netif.h"
       +
       +ttypedef struct Ram        Ram;
       +struct Ram
       +{
       +        QLock lk;
       +        Ram        *next;
       +        int        ref;
       +        /* simple for now */
       +        unsigned char **pages;
       +        int pagecount;
       +        int size;
       +        int        qref[2];
       +        ulong        path;
       +};
       +
       +struct
       +{
       +        Lock lk;
       +        ulong        path;
       +} ramalloc;
       +
       +enum
       +{
       +        Qdir,
       +        Qdata0,
       +        Qctl,
       +};
       +
       +Dirtab ramdir[] =
       +{
       +        ".",                {Qdir,0,QTDIR},        0,                DMDIR|0500,
       +        "data",                {Qdata0},        0,                0600,
       +        "ctl",        {Qctl},        0,                0600,
       +};
       +#define NPIPEDIR 3
       +
       +static void
       +raminit(void)
       +{
       +}
       +
       +/*
       + *  create a ram, no streams are created until an open
       + */
       +static Chan*
       +ramattach(char *spec)
       +{
       +        Ram *p;
       +        Chan *c;
       +
       +        c = devattach('R', spec);
       +        p = malloc(sizeof(Ram));
       +        if(p == 0)
       +                exhausted("memory");
       +        p->ref = 1;
       +        p->size = 0;
       +        p->pagecount = 1;
       +        p->pages = mallocz(sizeof(char *), 1);
       +        p->pages[0] = mallocz(BY2PG, 1);
       +        lock(&ramalloc.lk);
       +        p->path = ++ramalloc.path;
       +        unlock(&ramalloc.lk);
       +
       +        mkqid(&c->qid, NETQID(2*p->path, Qdir), 0, QTDIR);
       +        c->aux = p;
       +        c->dev = 0;
       +        return c;
       +}
       +
       +static int
       +ramgen(Chan *c, char *name, Dirtab *tab, int ntab, int i, Dir *dp)
       +{
       +        Qid q;
       +        int len;
       +        Ram *p;
       +
       +        if(i == DEVDOTDOT){
       +                devdir(c, c->qid, "#R", 0, eve, DMDIR|0555, dp);
       +                return 1;
       +        }
       +        i++;        /* skip . */
       +        if(tab==0 || i>=ntab)
       +                return -1;
       +
       +        tab += i;
       +        p = c->aux;
       +        switch((ulong)tab->qid.path){
       +        case Qdata0:
       +                len = p->size;
       +                break;
       +        case Qctl:
       +                len = 0;
       +                break;
       +        default:
       +                len = tab->length;
       +                break;
       +        }
       +        mkqid(&q, NETQID(NETID(c->qid.path), tab->qid.path), 0, QTFILE);
       +        devdir(c, q, tab->name, len, eve, tab->perm, dp);
       +        return 1;
       +}
       +
       +
       +static Walkqid*
       +ramwalk(Chan *c, Chan *nc, char **name, int nname)
       +{
       +        Walkqid *wq;
       +        Ram *p;
       +
       +        wq = devwalk(c, nc, name, nname, ramdir, NPIPEDIR, ramgen);
       +        if(wq != nil && wq->clone != nil && wq->clone != c){
       +                p = c->aux;
       +                qlock(&p->lk);
       +                p->ref++;
       +                if(c->flag & COPEN){
       +                        print("channel open in ramwalk\n");
       +                        switch(NETTYPE(c->qid.path)){
       +                        case Qdata0:
       +                                p->qref[0]++;
       +                                break;
       +                        case Qctl:
       +                                p->qref[1]++;
       +                                break;
       +                        }
       +                }
       +                qunlock(&p->lk);
       +        }
       +        return wq;
       +}
       +
       +static int
       +ramstat(Chan *c, uchar *db, int n)
       +{
       +        Ram *p;
       +        Dir dir;
       +
       +        p = c->aux;
       +
       +        switch(NETTYPE(c->qid.path)){
       +        case Qdir:
       +                devdir(c, c->qid, ".", 0, eve, DMDIR|0555, &dir);
       +                break;
       +        case Qdata0:
       +                devdir(c, c->qid, "data", p->size, eve, 0600, &dir);
       +                break;
       +        case Qctl:
       +                devdir(c, c->qid, "ctl", 0, eve, 0600, &dir);
       +                break;
       +        default:
       +                panic("ramstat");
       +        }
       +        n = convD2M(&dir, db, n);
       +        if(n < BIT16SZ)
       +                error(Eshortstat);
       +        return n;
       +}
       +
       +/*
       + *  if the stream doesn't exist, create it
       + */
       +static Chan*
       +ramopen(Chan *c, int omode)
       +{
       +        Ram *p;
       +
       +        if(c->qid.type & QTDIR){
       +                if(omode != OREAD)
       +                        error(Ebadarg);
       +                c->mode = omode;
       +                c->flag |= COPEN;
       +                c->offset = 0;
       +                return c;
       +        }
       +
       +        p = c->aux;
       +        qlock(&p->lk);
       +        switch(NETTYPE(c->qid.path)){
       +        case Qdata0:
       +                p->qref[0]++;
       +                break;
       +        case Qctl:
       +                p->qref[1]++;
       +                break;
       +        }
       +        qunlock(&p->lk);
       +
       +        c->mode = openmode(omode);
       +        c->flag |= COPEN;
       +        c->offset = 0;
       +        c->iounit = qiomaxatomic;
       +        return c;
       +}
       +
       +static void
       +ramclose(Chan *c)
       +{
       +        Ram *p;
       +
       +        p = c->aux;
       +        qlock(&p->lk);
       +
       +        if(c->flag & COPEN){
       +                switch(NETTYPE(c->qid.path)){
       +                case Qdata0:
       +                        p->qref[0]--;
       +                        break;
       +                case Qctl:
       +                        p->qref[1]--;
       +                        break;
       +                }
       +        }
       +
       +        /*
       +         *  free the structure on last close
       +         */
       +        p->ref--;
       +        if(p->ref == 0){
       +                int i;
       +                qunlock(&p->lk);
       +                for(i = 0; i < p->pagecount; i++)
       +                        free(p->pages[i]);
       +                free(p->pages);
       +                free(p);
       +        } else
       +                qunlock(&p->lk);
       +}
       +
       +static long rampageread(Ram *p, void *va, long n, vlong offset)
       +{
       +        int i;
       +        long total = n, offinpage, leninpage;
       +
       +        /* figure out what range we can actually read */
       +        if (offset > p->size)
       +                return 0;
       +        if (offset + n > p->size) 
       +                n = p->size - offset;
       +        /* granular copy */
       +        for(i = offset / BY2PG; n > 0; i++) {
       +                /* i is the page */
       +                offinpage = offset & (BY2PG - 1);
       +                leninpage = BY2PG - offinpage;
       +                /* unless there is too little left ... */
       +                if (leninpage > n)
       +                        leninpage = n;
       +                memcpy(va, p->pages[i] + offinpage, leninpage);
       +                offset += offinpage;
       +                n -= leninpage; 
       +                va += leninpage;
       +        }
       +        return total;
       +}
       +
       +static long
       +ramread(Chan *c, void *va, long n, vlong offset)
       +{
       +        Ram *p;
       +        char *buf, *s, *e;
       +
       +        p = c->aux;
       +
       +        switch(NETTYPE(c->qid.path)){
       +        case Qdir:
       +                return devdirread(c, va, n, ramdir, NPIPEDIR, ramgen);
       +        case Qdata0:
       +                return rampageread(p, va, n, offset);
       +        case Qctl:
       +                buf = smalloc(8192);
       +                s = buf;
       +                e = buf + 8192;
       +                s = seprint(s, e, "pages %p count %d ", p->pages, p->pagecount);
       +                seprint(s, e, "size %d\n", p->size);
       +                n = readstr(offset, va, n, buf);
       +                free(buf);
       +                return n;
       +        default:
       +                panic("ramread");
       +        }
       +        return -1;        /* not reached */
       +}
       +
       +/* for the range offset .. offset + n, make sure we have pages */
       +static void pages(Ram *p, long n, vlong offset)
       +{
       +        int i;
       +        int newpagecount;
       +        unsigned char **newpages;
       +        newpagecount = (offset + n + BY2PG-1)/BY2PG;
       +        if (newpagecount > p->pagecount) {
       +                newpages = mallocz(sizeof(char *) * newpagecount, 1);
       +                if (! newpages)
       +                        error("No more pages in devram");
       +                memcpy(newpages, p->pages, sizeof(char *) * p->pagecount);
       +                free(p->pages);
       +                p->pages = newpages;
       +                p->pagecount = newpagecount;
       +                /* now allocate them */
       +                for(i = offset / BY2PG; i < newpagecount; i++) {
       +                        if (p->pages[i])
       +                                continue;
       +                        p->pages[i] = mallocz(BY2PG, 1);
       +                }
       +        }
       +}
       +static long rampagewrite(Ram *p, void *va, long n, vlong offset)
       +{
       +        int i;
       +        long total = n, offinpage, leninpage;
       +        long newsize;
       +        pages(p, n, offset);
       +        
       +        /* granular copy */
       +        newsize = offset + n;
       +        for(i = offset / BY2PG; n > 0; i++) {
       +                /* i is the page */
       +                offinpage = offset & (BY2PG - 1);
       +                leninpage = BY2PG - offinpage;
       +                /* unless there is too little left ... */
       +                if (leninpage > n)
       +                        leninpage = n;
       +                memcpy(p->pages[i] + offinpage, va, leninpage);
       +                offset += leninpage;
       +                n -= leninpage; 
       +                va += leninpage;
       +        }
       +        p->size = newsize > p->size? newsize : p->size;
       +        return total;
       +}
       +static long
       +ramwrite(Chan *c, void *va, long n, vlong offset)
       +{
       +        Ram *p;
       +
       +        if(!islo())
       +                print("ramwrite hi %lux\n", getcallerpc(&c));
       +        p = c->aux;
       +        switch(NETTYPE(c->qid.path)){
       +        case Qdata0:
       +                n = rampagewrite(p, va, n, offset);
       +                break;
       +
       +        case Qctl:
       +                if (strcmp(va, "free") == 0) {
       +                        int i;
       +                        unsigned char **new = mallocz(sizeof(char *), 1);
       +                        unsigned char *page = p->pages[0];
       +                        for(i = 1; i < p->pagecount; i++)
       +                                free(p->pages[i]);
       +                        free(p->pages);
       +                        p->pages = new;
       +                        p->pages[0] = page;
       +                        p->size = 0;
       +                        p->pagecount = 1;
       +                } else {
       +                        error("bad command");
       +                }
       +                break;
       +
       +        default:
       +                panic("ramwrite");
       +        }
       +
       +        return n;
       +}
       +
       +
       +Dev ramdevtab = {
       +        'R',
       +        "ram",
       +
       +        devreset,
       +        raminit,
       +        devshutdown,
       +        ramattach,
       +        ramwalk,
       +        ramstat,
       +        ramopen,
       +        devcreate,
       +        ramclose,
       +        ramread,
       +        devbread,
       +        ramwrite,
       +        devbwrite,
       +        devremove,
       +        devwstat,
       +};
 (DIR) diff --git a/src/9vx/a/proc.c b/src/9vx/a/proc.c
       @@ -620,6 +620,7 @@ newproc(void)
                        p->procctl = Proc_tracesyscall;
                else
                        p->procctl = 0;
       +        p->syscalltrace = 0;
                p->notepending = 0;
                p->ureg = 0;
                p->privatemem = 0;
       @@ -1051,6 +1052,8 @@ pexit(char *exitstr, int freemem)
                Chan *dot;
                void (*pt)(Proc*, int, vlong);
        
       +        if (up->syscalltrace)
       +                free(up->syscalltrace);
                up->alarm = 0;
                if (up->timer.tt)
                        timerdel(&up->timer);
 (DIR) diff --git a/src/9vx/trap.c b/src/9vx/trap.c
       @@ -183,325 +183,243 @@ syscallprint(Ureg *ureg)
        {
                uint32 *sp = (uint32*)(up->pmmu.uzero + ureg->usp);
                int syscallno = ureg->ax;
       +        char *prefix;
       +        vlong offset = 0;
       +        char *special = "";
       +
       +        /* accomodate process-private system calls */
       +        /* special! */
       +        if ((syscallno == RFORK)  && (sp[2] & RFPROC))
       +                special="Proc";
       +
       +        if (syscallno > nelem(sysctab))
       +                prefix = smprint("%d %s %d %#ux", up->pid, up->text, syscallno, sp[0]);
       +        else
       +                prefix = smprint("%d %s %s%s %#ux", up->pid, up->text, special, sysctab[syscallno], sp[0]);
        
                /* should never happen -- arguably, this should panic. */
                if (up->syscalltrace)
                        free(up->syscalltrace);
                switch(syscallno) {
                case SYSR1:
       -        up->syscalltrace = smprint("%d [%s] %s %#ux %08ux %08ux %08ux %08uxh",
       -                up->pid, up->text,
       -                sysctab[ureg->ax], sp[0], sp[1], sp[2], sp[3]);
       -        break;
       +                up->syscalltrace = smprint("%s %08ux %08ux %08ux", prefix, sp[1], sp[2], sp[3]);
       +                break;
                case _ERRSTR:
       -        up->syscalltrace = smprint("%d [%s] %s %#ux %08ux",
       -                up->pid, up->text,
       -                sysctab[ureg->ax], sp[0], sp[1]);
       -        break;
       +                up->syscalltrace = smprint("%s %#ux/", prefix, sp[1]);
       +                break;
                case BIND:{
                        char *s1 =  uvalidaddr(sp[1], 1, 0);
                        char *s2 =  uvalidaddr(sp[2], 1, 0);
       -        up->syscalltrace = smprint("%d [%s] %s %#ux %08x=%s  %08x=%s flags %08uxh",
       -                up->pid, up->text,
       -                sysctab[ureg->ax], sp[0], sp[1], s1, sp[2], s2, sp[3]);
       -        break;
       +                up->syscalltrace = smprint("%s %08x/%s  %08x/%s %#ux", prefix,  sp[1], s1, sp[2], s2, sp[3]);
       +                break;
                }
                case CHDIR:{
                        char *s =  uvalidaddr(sp[1], 1, 0);
       -        up->syscalltrace = smprint("%d [%s] %s %#ux %08x=%s  ",
       -                up->pid, up->text,
       -                sysctab[ureg->ax], sp[0], sp[1], s);
       +                up->syscalltrace = smprint("%s %08x/%s  ", prefix, 
       +                sp[1], s);
                break;
                }
                case CLOSE:
       -        up->syscalltrace = smprint("%d [%s] %s %#ux %d",
       -                up->pid, up->text,
       -                sysctab[ureg->ax], sp[0], sp[1]);
       -        break;
       +                up->syscalltrace = smprint("%s %d", prefix, sp[1]);
       +                break;
                case DUP:
       -        up->syscalltrace = smprint("%d [%s] %s %#ux %08ux %08ux",
       -                up->pid, up->text,
       -                sysctab[ureg->ax], sp[0], sp[1], sp[2]);
       -        break;
       +                up->syscalltrace = smprint("%s %08ux %08ux", prefix, sp[1], sp[2]);
       +                break;
                case ALARM:
       -        up->syscalltrace = smprint("%d [%s] %s %#ux %08ux ms",
       -                up->pid, up->text,
       -                sysctab[ureg->ax], sp[0], sp[1]);
       -        break;
       +                up->syscalltrace = smprint("%s %08ux ", prefix, sp[1]);
       +                break;
                case EXEC: {
                        char *name =uvalidaddr(sp[1], 1, 0);
                        uint32 *argv = uvalidaddr(sp[2], 1, 0);
                        int j = 0, i;
                        up->syscalltrace = mallocz(4096,1);
       -                j += snprint(up->syscalltrace, 4096, "%d [%s] %s %#ux %08ux=%s %08ux=(",
       -                up->pid, up->text,
       -                sysctab[ureg->ax], sp[0], sp[1], name, sp[2]);
       +                j += snprint(up->syscalltrace, 4096, "%08ux/%s ",sp[1], name);
                        /* more than 4096 of args, we just don't do */
       -                for(i = 0; argv[i] && (j > 0); i++) {
       +                for(i = 0; argv[i] && (j > 5); i++) {
                                char *str = uvalidaddr(argv[i], 1, 0);
       -                        j += snprint(up->syscalltrace+j,4096-j, "[%d]=%s ", i, str);
       +                        j += snprint(up->syscalltrace+j,4096-j, "%08ux/%s ", argv[i], str);
                        }
       -                snprint(up->syscalltrace+j,4096-j, ")");
       -        break;
       +                /* assume */
       +                if (j == 5)
       +                        snprint(up->syscalltrace+j,4096-j, " ...");
       +                break;
                }
                case EXITS:{
       -                char *msg = sp[1] ? uvalidaddr(sp[1], 1, 0) : "NULL";
       -        up->syscalltrace = smprint("%d [%s] %s %#ux %08ux=%s",
       -                up->pid, up->text,
       -                sysctab[ureg->ax], sp[0], sp[1], msg);
       -        break;
       +                char *msg = sp[1] ? uvalidaddr(sp[1], 1, 0) : "";
       +                up->syscalltrace = smprint("%s %08ux", prefix, sp[1], msg);
       +                break;
                }
                case _FSESSION:
       -        up->syscalltrace = smprint("%d [%s] %s %#ux %08ux %08ux %08ux %08uxh",
       -                up->pid, up->text,
       -                sysctab[ureg->ax], sp[0], sp[1], sp[2], sp[3]);
       -        break;
       +                up->syscalltrace = smprint("%s %08ux %08ux %08ux", prefix, sp[1], sp[2], sp[3]);
       +                break;
                case FAUTH:{
                        char *aname = uvalidaddr(sp[2], 1, 0);
       -        up->syscalltrace = smprint("%d [%s] %s %#ux %08ux %08ux=%s",
       -                up->pid, up->text,
       -                sysctab[ureg->ax], sp[0], sp[1], aname);
       -        break;
       +                up->syscalltrace = smprint("%s %08ux %08ux/%s", prefix, sp[1], aname);
       +                break;
                }
                case _FSTAT:{
       -        up->syscalltrace = smprint("%d [%s] %s %#ux %08ux %#ux %08ux",
       -                up->pid, up->text,
       -                sysctab[ureg->ax], sp[0], sp[1], sp[2], sp[3]);
       -        break;
       +                up->syscalltrace = smprint("%s %08ux %#ux %08ux", prefix, sp[1], sp[2], sp[3]);
       +                break;
                }
                case SEGBRK:
       -        up->syscalltrace = smprint("%d [%s] %s %#ux %08ux",
       -                up->pid, up->text,
       -                sysctab[ureg->ax], sp[0], sp[1]);
       -        break;
       +                up->syscalltrace = smprint("%s %#ux %#ux", prefix, sp[1], sp[2]);
       +                break;
                case _MOUNT:{
                        char *old =uvalidaddr(sp[3], 1, 0);
       -                //char *aname = uvalidaddr(sp[5], 1, 0);
       -        up->syscalltrace = smprint("%d [%s] %s %#ux %d %d %08ux=%s %08ux %#ux",
       -                up->pid, up->text,
       -                sysctab[ureg->ax], sp[0], sp[1], sp[2], sp[3], old, sp[4],sp[5]);
       -        break;
       +                char *aname = sp[5] ? uvalidaddr(sp[5], 1, 0) : "";
       +                up->syscalltrace = smprint("%s %d %d %08ux=%s %08ux %#ux/%s", prefix, 
       +                        sp[1], sp[2], sp[3], old, sp[4],sp[5], aname);
       +                break;
                }
                case OPEN: {
                        char *s;
                        s = uvalidaddr(sp[1], 1, 0);
       -                up->syscalltrace = smprint("%d [%s] %s %#ux %08x=%s %08ux",
       -                        up->pid, up->text,
       -                        sysctab[ureg->ax], sp[0], sp[1], s, sp[2]);
       -        break;
       -        }
       -        case _READ: {
       -        up->syscalltrace = smprint("%d [%s] %s %#ux %d %08ux %08ux %08uxh",
       -                up->pid, up->text,
       -                sysctab[ureg->ax], sp[0], sp[1], sp[2], sp[3]);
       -        break;
       +                up->syscalltrace = smprint("%s %08x/%s %08ux", prefix, sp[1], s, sp[2]);
       +                break;
                }
                case OSEEK:
       -        up->syscalltrace = smprint("%d [%s] %s %#ux %08ux %08ux %08ux %08uxh",
       -                up->pid, up->text,
       -                sysctab[ureg->ax], sp[0], sp[1], sp[2], sp[3]);
       -        break;
       +                up->syscalltrace = smprint("%s %08ux %08ux", prefix, sp[1], sp[2]);
       +                break;
                case SLEEP: {
       -        up->syscalltrace = smprint("%d [%s] %s %#ux %d",
       -                up->pid, up->text,
       -                sysctab[ureg->ax], sp[0], sp[1]);
       -        break;
       +                up->syscalltrace = smprint("%s %d", prefix, sp[1]);
       +                break;
                }
                case _STAT:{
                        char *name = uvalidaddr(sp[1], 1, 0);
       -        up->syscalltrace = smprint("%d [%s] %s %#ux %08ux=%s %#ux %d",
       -                up->pid, up->text,
       -                sysctab[ureg->ax], sp[0], sp[1], name, sp[2], sp[3]);
       -        break;
       +                up->syscalltrace = smprint("%s %08ux/%s %#ux %d", prefix,  sp[1], name, sp[2], sp[3]);
       +                break;
                }
                case RFORK:{
       -                uint32 flags = sp[1];
       -        up->syscalltrace = smprint("%d [%s] %s%s %#ux %08ux",
       -                up->pid, up->text,
       -                flags & RFPROC ? "Proc" : "",sysctab[ureg->ax], sp[0], sp[1] );
       -        break;
       +                up->syscalltrace = smprint("%s %08ux", prefix, sp[1] );
       +                break;
                }
       -        case _WRITE:
       -        up->syscalltrace = smprint("%d [%s] %s %#ux %d %#ux %d %08uxh",
       -                up->pid, up->text,
       -                sysctab[ureg->ax], sp[0], sp[1], sp[2], sp[3]);
       -        break;
                case PIPE: 
       -        up->syscalltrace = smprint("%d [%s] %s %#ux",
       -                up->pid, up->text,
       -                sysctab[ureg->ax], sp[0]);
       -        break;
       +                up->syscalltrace = smprint("%s", prefix);
       +                break;
                case CREATE:{
                        char *name = uvalidaddr(sp[1], 1, 0);
       -        up->syscalltrace = smprint("%d [%s] %s %#ux %#ux=%s %08ux %08ux",
       -                up->pid, up->text,
       -                sysctab[ureg->ax], sp[0], sp[1], name, sp[2], sp[3]);
       -        break;
       +                up->syscalltrace = smprint("%s %#ux/\"%s\" %08ux %08ux", prefix, sp[1], name, sp[2], sp[3]);
       +                break;
                }
                case FD2PATH:
       -        up->syscalltrace = smprint("%d [%s] %s %#ux %d %#ux %d",
       -                up->pid, up->text,
       -                sysctab[ureg->ax], sp[0], sp[1], sp[2], sp[3]);
       -        break;
       +                up->syscalltrace = smprint("%s %d %#ux %d", prefix, sp[1], sp[2], sp[3]);
       +                break;
                case BRK_:
       -        up->syscalltrace = smprint("%d [%s] %s %#ux %08ux %08ux %08ux %08uxh",
       -                up->pid, up->text,
       -                sysctab[ureg->ax], sp[0], sp[1], sp[2], sp[3]);
       -        break;
       +                up->syscalltrace = smprint("%s %08ux %08ux %08ux", prefix, 
       +                sp[1], sp[2], sp[3]);
       +                break;
                case REMOVE:{
                        char *name = uvalidaddr(sp[1], 1, 0);
       -        up->syscalltrace = smprint("%d [%s] %s %#ux %#ux=%s",
       -                up->pid, up->text,
       -                sysctab[ureg->ax], sp[0], sp[1], name);
       -        break;
       +                up->syscalltrace = smprint("%s %#ux/%s", prefix, 
       +                sp[1], name);
       +                break;
                }
       +        /* deprecated */
                case _WSTAT:
       -        up->syscalltrace = smprint("%d [%s] %s %#ux %08ux %08ux %08ux %08uxh",
       -                up->pid, up->text,
       -                sysctab[ureg->ax], sp[0], sp[1], sp[2], sp[3]);
       -        break;
       +                up->syscalltrace = smprint("%s %08ux %08ux %08ux", prefix, sp[1], sp[2], sp[3]);
       +                break;
                case _FWSTAT:
       -        up->syscalltrace = smprint("%d [%s] %s %#ux %08ux %08ux %08ux %08uxh",
       -                up->pid, up->text,
       -                sysctab[ureg->ax], sp[0], sp[1], sp[2], sp[3]);
       -        break;
       +                up->syscalltrace = smprint("%s %08ux %08ux %08ux", prefix, sp[1], sp[2], sp[3]);
       +                break;
                case NOTIFY:
       -        up->syscalltrace = smprint("%d [%s] %s %#ux %08ux %08ux %08ux %08uxh",
       -                up->pid, up->text,
       -                sysctab[ureg->ax], sp[0], sp[1], sp[2], sp[3]);
       -        break;
       +                up->syscalltrace = smprint("%s %08ux %08ux %08ux", prefix, sp[1], sp[2], sp[3]);
       +                break;
                case NOTED:
       -        up->syscalltrace = smprint("%d [%s] %s %#ux %08ux %08ux %08ux %08uxh",
       -                up->pid, up->text,
       -                sysctab[ureg->ax], sp[0], sp[1], sp[2], sp[3]);
       -        break;
       +                up->syscalltrace = smprint("%s %08ux %08ux %08ux", prefix, sp[1], sp[2], sp[3]);
       +                break;
                case SEGATTACH:
       -        up->syscalltrace = smprint("%d [%s] %s %#ux %08ux %08ux %08ux %08uxh",
       -                up->pid, up->text,
       -                sysctab[ureg->ax], sp[0], sp[1], sp[2], sp[3]);
       -        break;
       +                up->syscalltrace = smprint("%s %08ux %08ux %08ux", prefix, sp[1], sp[2], sp[3]);
       +                break;
                case SEGDETACH:
       -        up->syscalltrace = smprint("%d [%s] %s %#ux %08ux %08ux %08ux %08uxh",
       -                up->pid, up->text,
       -                sysctab[ureg->ax], sp[0], sp[1], sp[2], sp[3]);
       -        break;
       +                up->syscalltrace = smprint("%s %08ux %08ux %08ux", prefix, sp[1], sp[2], sp[3]);
       +                break;
                case SEGFREE:
       -        up->syscalltrace = smprint("%d [%s] %s %#ux %08ux %08ux %08ux %08uxh",
       -                up->pid, up->text,
       -                sysctab[ureg->ax], sp[0], sp[1], sp[2], sp[3]);
       -        break;
       +                up->syscalltrace = smprint("%s %08ux %08ux %08ux", prefix, sp[1], sp[2], sp[3]);
       +                break;
                case SEGFLUSH:
       -        up->syscalltrace = smprint("%d [%s] %s %#ux %08ux %08ux %08ux %08uxh",
       -                up->pid, up->text,
       -                sysctab[ureg->ax], sp[0], sp[1], sp[2], sp[3]);
       -        break;
       +                up->syscalltrace = smprint("%s %08ux %08ux %08ux", prefix, sp[1], sp[2], sp[3]);
       +                break;
                case RENDEZVOUS:
       -        up->syscalltrace = smprint("%d [%s] %s %#ux %08ux %08ux %08ux %08uxh",
       -                up->pid, up->text,
       -                sysctab[ureg->ax], sp[0], sp[1], sp[2], sp[3]);
       -        break;
       +                up->syscalltrace = smprint("%s %08ux %08ux %08ux", prefix, 
       +                sp[1], sp[2], sp[3]);
       +                break;
                case UNMOUNT:{
                        char *name = uvalidaddr(sp[1], 1, 0);
       -        up->syscalltrace = smprint("%d [%s] %s %#ux %#ux=%s",
       -                up->pid, up->text,
       -                sysctab[ureg->ax], sp[0], sp[1], name);
       -        break;
       +                up->syscalltrace = smprint("%s %#ux/%s", prefix, sp[1], name);
       +                break;
                }
                case _WAIT:
       -        up->syscalltrace = smprint("%d [%s] %s %#ux %08ux %08ux %08ux %08uxh",
       -                up->pid, up->text,
       -                sysctab[ureg->ax], sp[0], sp[1], sp[2], sp[3]);
       -        break;
       +                up->syscalltrace = smprint("%s %08ux %08ux %08ux", prefix, sp[1], sp[2], sp[3]);
       +                break;
                case SEMACQUIRE:
       -        up->syscalltrace = smprint("%d [%s] %s %#ux %08ux %08ux %08ux %08uxh",
       -                up->pid, up->text,
       -                sysctab[ureg->ax], sp[0], sp[1], sp[2], sp[3]);
       -        break;
       +                up->syscalltrace = smprint("%s %08ux %#ux %d", prefix, sp[1], sp[2], sp[3]);
       +                break;
                case SEMRELEASE:
       -        up->syscalltrace = smprint("%d [%s] %s %#ux %08ux %08ux %08ux %08uxh",
       -                up->pid, up->text,
       -                sysctab[ureg->ax], sp[0], sp[1], sp[2], sp[3]);
       -        break;
       +                up->syscalltrace = smprint("%s %08ux %#ux %d", prefix, sp[1], sp[2], sp[3]);
       +                break;
                case SEEK:
       -        up->syscalltrace = smprint("%d [%s] %s %#ux %08ux %08ux %08ux %08uxh",
       -                up->pid, up->text,
       -                sysctab[ureg->ax], sp[0], sp[1], sp[2], sp[3]);
       -        break;
       -        case FVERSION:
       -        up->syscalltrace = smprint("%d [%s] %s %#ux %08ux %08ux %08ux %08uxh",
       -                up->pid, up->text,
       -                sysctab[ureg->ax], sp[0], sp[1], sp[2], sp[3]);
       -        break;
       +                up->syscalltrace = smprint("%s %08ux %016ux %08ux", prefix, sp[1], *(vlong *)&sp[2], sp[4]);
       +                break;
       +        case FVERSION:{
       +                char *version = uvalidaddr(sp[1], 1, 0);
       +                up->syscalltrace = smprint("%s %08ux %08ux %08ux/%s", prefix, sp[1], sp[2], sp[3], version);
       +                break;
       +        }
                case ERRSTR:
       -        up->syscalltrace = smprint("%d [%s] %s %#ux %08ux %08ux %08ux %08uxh",
       -                up->pid, up->text,
       -                sysctab[ureg->ax], sp[0], sp[1], sp[2], sp[3]);
       -        break;
       -        case STAT:
       -        up->syscalltrace = smprint("%d [%s] %s %#ux %08ux %08ux %08ux %08uxh",
       -                up->pid, up->text,
       -                sysctab[ureg->ax], sp[0], sp[1], sp[2], sp[3]);
       -        break;
       -        case FSTAT:
       -        up->syscalltrace = smprint("%d [%s] %s %#ux %08ux %08ux %08ux %08uxh",
       -                up->pid, up->text,
       -                sysctab[ureg->ax], sp[0], sp[1], sp[2], sp[3]);
       -        break;
       +                up->syscalltrace = smprint("%s %#ux/", prefix, sp[1]);
       +                break;
                case WSTAT:
       -        up->syscalltrace = smprint("%d [%s] %s %#ux %08ux %08ux %08ux %08uxh",
       -                up->pid, up->text,
       -                sysctab[ureg->ax], sp[0], sp[1], sp[2], sp[3]);
       -        break;
       +        case STAT:{
       +                char *name = uvalidaddr(sp[1], 1, 0);
       +                up->syscalltrace = smprint("%s %08ux %08ux/%s %08ux", prefix, sp[1], sp[2], name, sp[3]);
       +                break;
       +        }
       +        case FSTAT:
                case FWSTAT:
       -        up->syscalltrace = smprint("%d [%s] %s %#ux %08ux %08ux %08ux %08uxh",
       -                up->pid, up->text,
       -                sysctab[ureg->ax], sp[0], sp[1], sp[2], sp[3]);
       -        break;
       +                up->syscalltrace = smprint("%s %08ux %08ux %08ux", prefix, sp[1], sp[2], sp[3]);
       +                break;
                case MOUNT:{
                        char *old =uvalidaddr(sp[3], 1, 0);
       -                //char *aname = uvalidaddr(sp[5], 1, 0);
       -        up->syscalltrace = smprint("%d [%s] %s %#ux %d %d %08ux=%s %08ux %#ux",
       -                up->pid, up->text,
       -                sysctab[ureg->ax], sp[0], sp[1], sp[2], sp[3], old, sp[4],sp[5]);
       -        break;
       +                char *aname = sp[5]? uvalidaddr(sp[5], 1, 0) : "";
       +                up->syscalltrace = smprint("%s %d %d %08ux=%s %08ux %#ux/", prefix, sp[1], sp[2], sp[3], old, sp[4],sp[5], aname);
       +                break;
                }
                case AWAIT:
       -        up->syscalltrace = smprint("%d [%s] %s %#ux %08ux %08ux %08ux %08uxh",
       -                up->pid, up->text,
       -                sysctab[ureg->ax], sp[0], sp[1], sp[2], sp[3]);
       -        break;
       -        case PREAD:{
       -        up->syscalltrace = smprint("%d [%s] %s %#ux %d %#ux %d",
       -                up->pid, up->text,
       -                sysctab[ureg->ax], sp[0], sp[1], sp[2], sp[3]);
       -        break;
       -        }
       +                up->syscalltrace = smprint("%s %08ux %#ux", prefix, sp[1], sp[2]);
       +                break;
       +        case _READ: 
       +        case PREAD:
       +                up->syscalltrace = smprint("%s %d %#ux", prefix, sp[1], sp[2]);
       +                break;
       +        case _WRITE:
       +                offset = -1;
                case PWRITE:{
                        int len = sp[3] > 64 ? 64 : sp[3];
                          char *s = uvalidaddr(sp[2], len, 0);
                        int i;
                        char a[65];
       +                if (! offset)
       +                        offset = *(vlong *)&sp[4];
                        memset(a, 0, sizeof(a));
                        for(i = 0; i < len; i++)
                                a[i] = isgraph(s[i]) ? s[i] : '.';
       -        up->syscalltrace = smprint("%d [%s] %s %#ux %d %#ux='%s' %d",
       -                up->pid, up->text,
       -                sysctab[ureg->ax], sp[0], sp[1], sp[2], a, sp[3]);
       -        break;
       +                up->syscalltrace = smprint("%s %d %#ux/\"%s\" %d %#ullx", prefix, sp[1], sp[2], a, sp[3], offset);
       +                break;
                }
                }
       -        
       +        free(prefix);        
        }
        
        static void
       -retprint(Ureg *ureg, int syscallno)
       +retprint(Ureg *ureg, int syscallno, uvlong start, uvlong stop)
        {
       +        char *prefix = nil;
       +        int errstrlen = 0;
                /* should never happen */
                if (up->syscalltrace)
                        free(up->syscalltrace);
                switch(syscallno) {
                        case SYSR1:
       -                case _ERRSTR:
                        case BIND:
                        case CHDIR:
                        case CLOSE:
       @@ -515,7 +433,6 @@ retprint(Ureg *ureg, int syscallno)
                        case SEGBRK:
                        case _MOUNT:
                        case OPEN:
       -                case _READ:
                        case OSEEK:
                        case SLEEP:
                        case _STAT:
       @@ -539,49 +456,73 @@ retprint(Ureg *ureg, int syscallno)
                        case SEMRELEASE:
                        case SEEK:
                        case FVERSION:
       -                case ERRSTR:
                        case STAT:
                        case FSTAT:
                        case WSTAT:
                        case FWSTAT:
                        case MOUNT:
       -                case AWAIT:
                        case PWRITE:
       -                default: 
       -                        if(ureg->ax == -1)
       -                                up->syscalltrace = smprint("= %s\n", up->syserrstr);
       -                        else
       -                                up->syscalltrace = smprint("= %#ux\n", ureg->ax);
       -                break;
                        case RFORK:
       -                        if(ureg->ax == -1)
       -                                up->syscalltrace = smprint("= %s\n", up->syserrstr);
       -                        else
       -                                up->syscalltrace = smprint("= %d\n", ureg->ax);
       +                default: 
                        break;
       +                case AWAIT:{
       +                        /* already filled in but we need the pointer -- only check read */
       +                        char *msg = uvalidaddr(up->s.args[0], 1, 0), *msgp;
       +                        if (ureg->ax > 0){
       +                                msgp = mallocz(ureg->ax+1, 1);
       +                                memmove(msgp, msg, ureg->ax);
       +                                prefix = smprint("/\"%s\" %d", msgp, up->s.args[1]);
       +                                free(msgp);
       +                        } else {
       +                                prefix = smprint("\"\" %d", up->s.args[1]);
       +                        }
       +                        break;
       +                }
       +                case _ERRSTR:
       +                        errstrlen = 64;
       +                case ERRSTR:{
       +                        /* already filled in but we need the pointer -- only check read */
       +                        char *msg = uvalidaddr(up->s.args[0], 1, 0);
       +                        if (! errstrlen)
       +                                errstrlen = up->s.args[1];
       +                        if (ureg->ax > 0){
       +                                prefix = smprint("/\"%s\" %d", msg, errstrlen);
       +                        } else {
       +                                prefix = smprint("\"\" %d", errstrlen);
       +                        }
       +                        break;
       +                }
                        case FD2PATH:
       -                        if(ureg->ax == -1)
       -                                up->syscalltrace = smprint("= %s\n", up->syserrstr);
       +                        if(ureg->ax != -1)
       +                                up->syscalltrace = smprint("/%s\n", up->syserrstr);
                                else {
       -                                char *s = uvalidaddr(up->s.args[1], up->s.args[2], 0);
       -                                up->syscalltrace = smprint("= %#ux='%s'\n", ureg->ax, s);
       +                                char *s = uvalidaddr(up->s.args[1], up->s.args[1], 0);
       +                                up->syscalltrace = smprint("/\"%s\" %d", s, up->s.args[2]);
                                }
       -                break;
       +                        break;
       +                case _READ:
                        case PREAD:
                                if(ureg->ax == -1)
       -                                up->syscalltrace = smprint("= %s\n", up->syserrstr);
       +                                prefix = smprint("/\"\" %d 0x%ullx", up->s.args[2], *(vlong *)&up->s.args[3]);
                                else {
       -                                int len = up->s.args[2] > 64 ? 64 : up->s.args[2];
       +                                int len = ureg->ax > 64 ? 64 : ureg->ax;
                                        char *s = uvalidaddr(up->s.args[1], len, 0);
                                        char a[65];
                                        int i;
                                        memset(a, 0, sizeof(a));
                                        for(i = 0; i < len; i++)
                                                a[i] = isgraph(s[i]) ? s[i] : '.';
       -                                up->syscalltrace = smprint("= %#ux='%s'\n", ureg->ax, a);
       +                                prefix = smprint("/\"%s\" %d 0x%ullx", a, up->s.args[2], *(vlong *)&up->s.args[3]);
                                }
                        break;
                }
       +
       +        if (prefix){
       +                up->syscalltrace = smprint("%s = %d %s %#ullx %#ullx \n", prefix, ureg->ax, ureg->ax == -1 ? up->errstr : "\"\"", start, stop);
       +                free(prefix);
       +        } else {
       +                up->syscalltrace = smprint(" = %d %s %#ullx %#ullx\n", ureg->ax, ureg->ax == -1  ? up->errstr : "\"\"", start, stop);
       +        }
                
        }
        /*
       @@ -596,6 +537,7 @@ syscall(Ureg *ureg)
                long        ret;
                int s;
                ulong scallnr;
       +        vlong startnsec = 0ULL, stopnsec = 0ULL;
        
                cycles(&up->kentry);
                m->syscall++;
       @@ -610,6 +552,7 @@ syscall(Ureg *ureg)
                        if (up->syscalltrace)
                                free(up->syscalltrace);
                        up->syscalltrace = NULL;
       +                startnsec = todget(nil);
                }
        
                scallnr = ureg->ax;
       @@ -669,8 +612,9 @@ syscall(Ureg *ureg)
                ureg->ax = ret;
        
                if(up->procctl == Proc_tracesyscall){
       +                stopnsec = todget(nil);
                        up->procctl = Proc_stopme;
       -                retprint(ureg, scallnr);
       +                retprint(ureg, scallnr, startnsec, stopnsec);
                        s = splhi();
                        procctl(up);
                        splx(s);