vx32

Local 9vx git repository for patches.
git clone git://r-36.net/vx32
Log | Files | Refs

commit 134707956d7d6de532ab5b4f9e5ae385e8c35cde
parent 07aabcf40153d6d889d70686e1b814f53a4f4ca2
Author: rminnich@nox.hsd1.ca.comcast.net <none@none>
Date:   Tue, 20 Apr 2010 01:39:41 -0700

This incorporates Russ's comments. Not tested.

Diffstat:
src/9vx/Makefrag | 2+-
src/9vx/a/AUTOGEN | 1-
src/9vx/a/devproc.c | 10+++++-----
src/9vx/a/devram.c | 394-------------------------------------------------------------------------------
src/9vx/a/portdat.h | 1-
src/9vx/a/proc.c | 10+++++-----
src/9vx/devram.c | 405+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/9vx/trap.c | 513++++++++++++++++++++++++++++++++++++++++---------------------------------------
8 files changed, 675 insertions(+), 661 deletions(-)

diff --git a/src/9vx/Makefrag b/src/9vx/Makefrag @@ -33,6 +33,7 @@ PLAN9_OBJS = \ devip-posix.o \ devmntloop.o \ devmouse.o \ + devram.o \ devtab.o \ factotum.o \ kprocdev.o \ @@ -74,7 +75,6 @@ PLAN9_A_OBJS = \ devmnt.o \ devproc.o \ devpipe.o \ - devram.o \ devroot.o \ devsd.o \ devsrv.o \ diff --git a/src/9vx/a/AUTOGEN b/src/9vx/a/AUTOGEN @@ -38,7 +38,6 @@ autofiles=" /sys/src/9/port/devmnt.c /sys/src/9/port/devpipe.c /sys/src/9/port/devproc.c -/sys/src/9/port/devram.c /sys/src/9/port/devroot.c /sys/src/9/port/devsrv.c /sys/src/9/port/devtls.c diff --git a/src/9vx/a/devproc.c b/src/9vx/a/devproc.c @@ -31,7 +31,7 @@ enum Qtext, Qwait, Qprofile, - Qtruss, + Qsyscall, }; enum @@ -85,7 +85,7 @@ Dirtab procdir[] = "text", {Qtext}, 0, 0000, "wait", {Qwait}, 0, 0400, "profile", {Qprofile}, 0, 0400, - "truss", {Qtruss}, 0, 0400, + "syscall", {Qsyscall}, 0, 0400, }; static @@ -399,7 +399,7 @@ procopen(Chan *c, int omode) case Qwait: case Qregs: case Qfpregs: - case Qtruss: + case Qsyscall: nonone(p); break; @@ -709,8 +709,8 @@ procread(Chan *c, void *va, long n, vlong off) memmove(a, &up->genbuf[offset], n); return n; - case Qtruss: - if (! p->syscalltrace) + case Qsyscall: + if(!p->syscalltrace) return 0; n = readstr(offset, a, n, p->syscalltrace); return n; diff --git a/src/9vx/a/devram.c b/src/9vx/a/devram.c @@ -1,394 +0,0 @@ -#include "u.h" -#include "lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "error.h" - -#include "netif.h" - -typedef 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, -}; diff --git a/src/9vx/a/portdat.h b/src/9vx/a/portdat.h @@ -754,7 +754,6 @@ struct Proc PMMU pmmu; /* syscall trace */ char *syscalltrace; - }; enum diff --git a/src/9vx/a/proc.c b/src/9vx/a/proc.c @@ -616,7 +616,7 @@ newproc(void) p->fpstate = FPinit; p->kp = 0; p->procctl = 0; - if(up && (up->procctl == Proc_tracesyscall)) + if(up && up->procctl == Proc_tracesyscall) p->procctl = Proc_tracesyscall; else p->procctl = 0; @@ -839,7 +839,7 @@ twakeup(Ureg *ureg, Timer *t) void tsleep(Rendez *r, int (*fn)(void*), void *arg, ulong ms) { - if (up->timer.tt){ + if(up->timer.tt){ print("tsleep: timer active: mode %d, tf 0x%lux\n", up->timer.tmode, up->timer.tf); timerdel(&up->timer); } @@ -856,7 +856,7 @@ tsleep(Rendez *r, int (*fn)(void*), void *arg, ulong ms) nexterror(); } sleep(r, tfn, arg); - if (up->timer.tt) + if(up->timer.tt) timerdel(&up->timer); up->timer.twhen = 0; poperror(); @@ -1052,10 +1052,10 @@ pexit(char *exitstr, int freemem) Chan *dot; void (*pt)(Proc*, int, vlong); - if (up->syscalltrace) + if(up->syscalltrace) free(up->syscalltrace); up->alarm = 0; - if (up->timer.tt) + if(up->timer.tt) timerdel(&up->timer); pt = proctrace; if(pt) diff --git a/src/9vx/devram.c b/src/9vx/devram.c @@ -0,0 +1,405 @@ +#include "u.h" +#include "lib.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" +#include "error.h" + +#include "netif.h" + +typedef struct Ram Ram; +struct Ram +{ + QLock lk; + Ram *next; + int ref; + /* simple for now */ + uchar **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, offinpage, leninpage; + + total = n; + + /* 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; + uchar **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, offinpage, leninpage; + long newsize; + + total = n; + 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; + int i; + uchar **new; + uchar *page; + + 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) { + new = mallocz(sizeof(char *), 1); + 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, +}; diff --git a/src/9vx/trap.c b/src/9vx/trap.c @@ -178,358 +178,363 @@ dumpregs(Ureg* ureg) */ } +/* rsc: combine these into one? */ +static void +fmtrwdata(Fmt *f, ulong s, int max, char *suffix) +{ + char *es, *t, *src; + int n; + int i; + + src = (char *) s; + uvalidaddr(s, 1, 0); + es = vmemchr((void *)s, 0, max); + n = es - src; + t = smalloc(n+1); + for(i = 0; i < n; i++) + if (isgraph(src[i])) + t[i] = src[i]; + else + t[i] = '.'; + + fmtprint(f, "%08ux/%s%s", s, t, suffix); + free(t); +} + +static void +fmtuserstring(Fmt *f, ulong s, char *suffix) +{ + char *es, *t, *src; + int n; + + src = (char *)s; + uvalidaddr((ulong)s, 1, 0); + es = vmemchr((void *)s, 0, 1<<16); + n = es - src; + t = smalloc(n+1); + memmove(t, src, n); + t[n] = 0; + fmtprint(f, "%08ux/%q%s", s, t, suffix); + free(t); +} + static void syscallprint(Ureg *ureg) { - uint32 *sp = (uint32*)(up->pmmu.uzero + ureg->usp); - int syscallno = ureg->ax; - char *prefix; - vlong offset = 0; - char *special = ""; + uint32 *sp; + int syscallno; + vlong offset; + Fmt fmt; + int len, i; + char *argv; + + sp = (uint32*)(up->pmmu.uzero + ureg->usp); + syscallno = ureg->ax; + offset = 0; + fmtstrinit(&fmt); + fmtprint(&fmt, "%d %s", up->pid, up->text); /* 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]); + if(syscallno > nelem(sysctab)) + fmtprint(&fmt, " %d %#x", syscallno, sp[0]); else - prefix = smprint("%d %s %s%s %#ux", up->pid, up->text, special, sysctab[syscallno], sp[0]); + fmtprint(&fmt, "%s %#ux", sysctab[syscallno], sp[0]); + + if(up->syscalltrace) + free(up->syscalltrace); - if (up->syscalltrace) - panic("syscallprint"); switch(syscallno) { case SYSR1: - up->syscalltrace = smprint("%s %08ux %08ux %08ux", prefix, sp[1], sp[2], sp[3]); + fmtprint(&fmt, "%08ux %08ux %08ux", sp[1], sp[2], sp[3]); break; case _ERRSTR: - up->syscalltrace = smprint("%s %#ux/", prefix, sp[1]); + fmtuserstring(&fmt, sp[1], ""); break; - case BIND:{ - char *s1 = uvalidaddr(sp[1], 1, 0); - char *s2 = uvalidaddr(sp[2], 1, 0); - up->syscalltrace = smprint("%s %08x/%s %08x/%s %#ux", prefix, sp[1], s1, sp[2], s2, sp[3]); + case BIND: + fmtuserstring(&fmt, sp[1], " "); + fmtuserstring(&fmt, sp[2], " "); + fmtprint(&fmt, "%#ux", sp[3]); + break; + case CHDIR: + fmtuserstring(&fmt, sp[1], ""); break; - } - case CHDIR:{ - char *s = uvalidaddr(sp[1], 1, 0); - up->syscalltrace = smprint("%s %08x/%s ", prefix, - sp[1], s); - break; - } case CLOSE: - up->syscalltrace = smprint("%s %d", prefix, sp[1]); + fmtprint(&fmt, "%d", sp[1]); break; case DUP: - up->syscalltrace = smprint("%s %08ux %08ux", prefix, sp[1], sp[2]); + fmtprint(&fmt, "%08ux %08ux", sp[1], sp[2]); break; case ALARM: - up->syscalltrace = smprint("%s %08ux ", prefix, sp[1]); + fmtprint(&fmt, "%08ux ", sp[1]); break; - case EXEC: { - char *execargs; - char *name =uvalidaddr(sp[1], 1, 0); - uint32 *argv = uvalidaddr(sp[2], 1, 0); - int j = 0, i; - execargs = mallocz(4096,1); - j += snprint(execargs, 4096, "%08ux/\"%s\" ",sp[1], name); - /* more than 4096 of args, we just don't do */ - for(i = 0; argv[i] && (j > 5); i++) { - char *str = uvalidaddr(argv[i], 1, 0); - j += snprint(execargs+j,4096-j, "%08ux/%s ", argv[i], str); + case EXEC: + fmtuserstring(&fmt, sp[1], ""); + argv = uvalidaddr(sp[2], 1, 0); + for(i = 0; argv[i]; i++) { + fmtprint(&fmt, " "); + fmtuserstring(&fmt, argv[i], ""); } - /* assume */ - if (j == 5) - snprint(up->syscalltrace+j,4096-j, " ..."); - up->syscalltrace = smprint("%s %s", prefix, execargs); - free(execargs); break; - } - case EXITS:{ - char *msg = sp[1] ? uvalidaddr(sp[1], 1, 0) : ""; - up->syscalltrace = smprint("%s %08ux", prefix, sp[1], msg); + case EXITS: + fmtuserstring(&fmt, sp[1], ""); break; - } case _FSESSION: - up->syscalltrace = smprint("%s %08ux %08ux %08ux", prefix, sp[1], sp[2], sp[3]); + fmtprint(&fmt, "%08ux %08ux %08ux", sp[1], sp[2], sp[3]); break; - case FAUTH:{ - char *aname = uvalidaddr(sp[2], 1, 0); - up->syscalltrace = smprint("%s %08ux %08ux/%s", prefix, sp[1], aname); + case FAUTH: + fmtprint(&fmt, "%08ux", sp[1]); + fmtuserstring(&fmt, sp[2], ""); break; - } - case _FSTAT:{ - up->syscalltrace = smprint("%s %08ux %#ux %08ux", prefix, sp[1], sp[2], sp[3]); + case _FSTAT: + fmtprint(&fmt, "%08ux %#ux %08ux", sp[1], sp[2], sp[3]); break; - } case SEGBRK: - up->syscalltrace = smprint("%s %#ux %#ux", prefix, sp[1], sp[2]); + fmtprint(&fmt, "%#ux %#ux", sp[1], sp[2]); break; - case _MOUNT:{ - char *old =uvalidaddr(sp[3], 1, 0); - 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); + case _MOUNT: + fmtprint(&fmt, "%d %d ", sp[1], sp[2]); + fmtuserstring(&fmt, sp[3], " "); + fmtprint(&fmt, "%08ux ", sp[4]); + fmtuserstring(&fmt, sp[5], ""); break; - } - case OPEN: { - char *s; - s = uvalidaddr(sp[1], 1, 0); - up->syscalltrace = smprint("%s %08x/%s %08ux", prefix, sp[1], s, sp[2]); + case OPEN: + fmtuserstring(&fmt, sp[1], " "); + fmtprint(&fmt, "%08ux", sp[2]); break; - } case OSEEK: - up->syscalltrace = smprint("%s %08ux %08ux", prefix, sp[1], sp[2]); + fmtprint(&fmt, "%08ux %08ux", sp[1], sp[2]); break; - case SLEEP: { - up->syscalltrace = smprint("%s %d", prefix, sp[1]); + case SLEEP: + fmtprint(&fmt, "%d", sp[1]); break; - } - case _STAT:{ - char *name = uvalidaddr(sp[1], 1, 0); - up->syscalltrace = smprint("%s %08ux/%s %#ux %d", prefix, sp[1], name, sp[2], sp[3]); + case _STAT: + fmtuserstring(&fmt, sp[1], " "); + fmtprint(&fmt, "%#ux %d", sp[2], sp[3]); break; - } - case RFORK:{ - up->syscalltrace = smprint("%s %08ux", prefix, sp[1] ); + case RFORK: + fmtprint(&fmt, "%08ux", sp[1] ); break; - } case PIPE: - up->syscalltrace = smprint("%s", prefix); break; - case CREATE:{ - char *name = uvalidaddr(sp[1], 1, 0); - up->syscalltrace = smprint("%s %#ux/\"%s\" %08ux %08ux", prefix, sp[1], name, sp[2], sp[3]); + case CREATE: + fmtuserstring(&fmt, sp[1], " "); + fmtprint(&fmt, "%08ux %08ux", sp[2], sp[3]); break; - } case FD2PATH: - up->syscalltrace = smprint("%s %d %#ux %d", prefix, sp[1], sp[2], sp[3]); + fmtprint(&fmt, "%d ", sp[1]); break; case BRK_: - up->syscalltrace = smprint("%s %08ux %08ux %08ux", prefix, - sp[1], sp[2], sp[3]); + fmtprint(&fmt, "%08ux %08ux %08ux", sp[1], sp[2], sp[3]); break; - case REMOVE:{ - char *name = uvalidaddr(sp[1], 1, 0); - up->syscalltrace = smprint("%s %#ux/%s", prefix, - sp[1], name); + case REMOVE: + fmtuserstring(&fmt, sp[1], " "); break; - } /* deprecated */ case _WSTAT: - up->syscalltrace = smprint("%s %08ux %08ux %08ux", prefix, sp[1], sp[2], sp[3]); + fmtprint(&fmt, "%08ux %08ux %08ux", sp[1], sp[2], sp[3]); break; case _FWSTAT: - up->syscalltrace = smprint("%s %08ux %08ux %08ux", prefix, sp[1], sp[2], sp[3]); + fmtprint(&fmt, "%08ux %08ux %08ux", sp[1], sp[2], sp[3]); break; case NOTIFY: - up->syscalltrace = smprint("%s %08ux %08ux %08ux", prefix, sp[1], sp[2], sp[3]); + fmtprint(&fmt, "%08ux %08ux %08ux", sp[1], sp[2], sp[3]); break; case NOTED: - up->syscalltrace = smprint("%s %08ux %08ux %08ux", prefix, sp[1], sp[2], sp[3]); + fmtprint(&fmt, "%08ux %08ux %08ux", sp[1], sp[2], sp[3]); break; case SEGATTACH: - up->syscalltrace = smprint("%s %08ux %08ux %08ux", prefix, sp[1], sp[2], sp[3]); + fmtprint(&fmt, "%08ux %08ux %08ux", sp[1], sp[2], sp[3]); break; case SEGDETACH: - up->syscalltrace = smprint("%s %08ux %08ux %08ux", prefix, sp[1], sp[2], sp[3]); + fmtprint(&fmt, "%08ux %08ux %08ux", sp[1], sp[2], sp[3]); break; case SEGFREE: - up->syscalltrace = smprint("%s %08ux %08ux %08ux", prefix, sp[1], sp[2], sp[3]); + fmtprint(&fmt, "%08ux %08ux %08ux", sp[1], sp[2], sp[3]); break; case SEGFLUSH: - up->syscalltrace = smprint("%s %08ux %08ux %08ux", prefix, sp[1], sp[2], sp[3]); + fmtprint(&fmt, "%08ux %08ux %08ux", sp[1], sp[2], sp[3]); break; case RENDEZVOUS: - up->syscalltrace = smprint("%s %08ux %08ux %08ux", prefix, - sp[1], sp[2], sp[3]); + fmtprint(&fmt, "%08ux %08ux %08ux", sp[1], sp[2], sp[3]); break; - case UNMOUNT:{ - char *name = uvalidaddr(sp[1], 1, 0); - up->syscalltrace = smprint("%s %#ux/%s", prefix, sp[1], name); + case UNMOUNT: + fmtuserstring(&fmt, sp[1], " "); break; - } case _WAIT: - up->syscalltrace = smprint("%s %08ux %08ux %08ux", prefix, sp[1], sp[2], sp[3]); + fmtprint(&fmt, "%08ux %08ux %08ux", sp[1], sp[2], sp[3]); break; case SEMACQUIRE: - up->syscalltrace = smprint("%s %08ux %#ux %d", prefix, sp[1], sp[2], sp[3]); + fmtprint(&fmt, "%08ux %#ux %d", sp[1], sp[2], sp[3]); break; case SEMRELEASE: - up->syscalltrace = smprint("%s %08ux %#ux %d", prefix, sp[1], sp[2], sp[3]); + fmtprint(&fmt, "%08ux %#ux %d", sp[1], sp[2], sp[3]); break; case SEEK: - up->syscalltrace = smprint("%s %08ux %016ux %08ux", prefix, sp[1], *(vlong *)&sp[2], sp[4]); + fmtprint(&fmt, "%08ux %016ux %08ux", 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); + case FVERSION: + fmtprint(&fmt, "%08ux %08ux ", sp[1], sp[2]); + fmtuserstring(&fmt, sp[5], ""); break; - } case ERRSTR: - up->syscalltrace = smprint("%s %#ux/", prefix, sp[1]); + fmtprint(&fmt, "%#ux/", sp[1]); break; case WSTAT: - 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]); + case STAT: + fmtprint(&fmt, "%08ux ", sp[1]); + fmtuserstring(&fmt, sp[2], " "); + fmtprint(&fmt, "%08ux", sp[3]); break; - } case FSTAT: case FWSTAT: - up->syscalltrace = smprint("%s %08ux %08ux %08ux", prefix, sp[1], sp[2], sp[3]); + fmtprint(&fmt, "%08ux %08ux %08ux", sp[1], sp[2], sp[3]); break; - case MOUNT:{ - char *old =uvalidaddr(sp[3], 1, 0); - 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); + case MOUNT: + fmtprint(&fmt, "%d %d ", sp[1], sp[3]); + fmtuserstring(&fmt, sp[3], " "); + fmtprint(&fmt, "%08ux", sp[4]); + fmtuserstring(&fmt, sp[5], ""); break; - } case AWAIT: - up->syscalltrace = smprint("%s %08ux %#ux", prefix, sp[1], sp[2]); + fmtprint(&fmt, "%08ux %#ux", sp[1], sp[2]); break; case _READ: case PREAD: - up->syscalltrace = smprint("%s %d %#ux", prefix, sp[1], sp[2]); + fmtprint(&fmt, "%d %#ux", 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]; - memset(a, 0, sizeof(a)); - for(i = 0; i < len; i++) - a[i] = isgraph(s[i]) ? s[i] : '.'; - if (! offset) + case PWRITE: + fmtprint(&fmt, "%d ", sp[1]); + if (sp[3] < 64) + len = sp[3]; + else + len = 64; + fmtrwdata(&fmt, sp[2], len, " "); + if(! offset) offset = *(vlong *)&sp[4]; - up->syscalltrace = smprint("%s %d %#ux/\"%s\" %d %#llx", prefix, sp[1], sp[2], a, sp[3], offset); + fmtprint(&fmt, "%d %#llx", sp[3], offset); break; } - } - free(prefix); + up->syscalltrace = fmtstrflush(&fmt); } static void retprint(Ureg *ureg, int syscallno, uvlong start, uvlong stop) { - char *prefix = nil; - int errstrlen = 0; - vlong offset = 0; + int errstrlen, len; + vlong offset; + char *errstr; + Fmt fmt; + + fmtstrinit(&fmt); + len = 0; + errstrlen = 0; + offset = 0; + if (ureg->ax == -1) + errstr = "\"\""; + else + errstr = up->errstr; + + if(up->syscalltrace) + free(up->syscalltrace); - if (up->syscalltrace) - panic("retprint"); switch(syscallno) { - case SYSR1: - case BIND: - case CHDIR: - case CLOSE: - case DUP: - case ALARM: - case EXEC: - case EXITS: - case _FSESSION: - case FAUTH: - case _FSTAT: - case SEGBRK: - case _MOUNT: - case OPEN: - case OSEEK: - case SLEEP: - case _STAT: - case _WRITE: - case PIPE: - case CREATE: - case BRK_: - case REMOVE: - case _WSTAT: - case _FWSTAT: - case NOTIFY: - case NOTED: - case SEGATTACH: - case SEGDETACH: - case SEGFREE: - case SEGFLUSH: - case RENDEZVOUS: - case UNMOUNT: - case _WAIT: - case SEMACQUIRE: - case SEMRELEASE: - case SEEK: - case FVERSION: - case STAT: - case FSTAT: - case WSTAT: - case FWSTAT: - case MOUNT: - case PWRITE: - case RFORK: - default: + case SYSR1: + case BIND: + case CHDIR: + case CLOSE: + case DUP: + case ALARM: + case EXEC: + case EXITS: + case _FSESSION: + case FAUTH: + case _FSTAT: + case SEGBRK: + case _MOUNT: + case OPEN: + case OSEEK: + case SLEEP: + case _STAT: + case _WRITE: + case PIPE: + case CREATE: + case BRK_: + case REMOVE: + case _WSTAT: + case _FWSTAT: + case NOTIFY: + case NOTED: + case SEGATTACH: + case SEGDETACH: + case SEGFREE: + case SEGFLUSH: + case RENDEZVOUS: + case UNMOUNT: + case _WAIT: + case SEMACQUIRE: + case SEMRELEASE: + case SEEK: + case FVERSION: + case STAT: + case FSTAT: + case WSTAT: + case FWSTAT: + case MOUNT: + case PWRITE: + case RFORK: + default: + break; + case AWAIT: + if(ureg->ax > 0){ + fmtuserstring(&fmt, up->s.args[1], ""); + } else { + fmtprint(&fmt, "\"\" %d", up->s.args[1]); + } 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: + if(! errstrlen) + errstrlen = up->s.args[1]; + if(ureg->ax > 0){ + fmtuserstring(&fmt, up->s.args[0], " "); + fmtprint(&fmt, "%d", errstrlen); + } else { + fmtprint(&fmt, "\"\" %d", errstrlen); } - 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; + break; + case FD2PATH: + if(ureg->ax == -1) + fmtprint(&fmt, "\"\" %d", up->s.args[2]); + else { + fmtuserstring(&fmt, up->s.args[1], " "); + fmtprint(&fmt, "%d", errstrlen); } - case FD2PATH: - if(ureg->ax == -1) - up->syscalltrace = smprint("/\"\" %d", up->s.args[2]); - else { - char *s = uvalidaddr(up->s.args[1], 1, 0); - up->syscalltrace = smprint("/\"%s\" %d", s, up->s.args[2]); - } - break; - case _READ: - offset = -1; - case PREAD: - if(ureg->ax == -1) - prefix = smprint("/\"\" %d 0x%ullx", up->s.args[2], *(vlong *)&up->s.args[3]); - else { - 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] : '.'; - if (! offset) - offset = *(vlong *)&up->s.args[3]; - prefix = smprint("/\"%s\" %d %#llx", a, up->s.args[2], offset); - } break; + case _READ: + offset = -1; + case PREAD: + if(ureg->ax == -1) + fmtprint(&fmt, "/\"\" %d 0x%ullx", up->s.args[2], *(vlong *)&up->s.args[3]); + else { + if (ureg->ax > 64) + len = 64; + else + len = ureg->ax; + fmtrwdata(&fmt, up->s.args[1], len, " "); + if(! offset) + offset = *(vlong *)&up->s.args[3]; + fmtprint(&fmt, "%d %#llx", up->s.args[2], offset); + } + 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); - } - + fmtprint(&fmt, " = %d %s %#ullx %#ullx\n", ureg->ax, errstr, start, stop); + + up->syscalltrace = fmtstrflush(&fmt); } /* * Handle a system call. @@ -543,8 +548,9 @@ syscall(Ureg *ureg) long ret; int s; ulong scallnr; - vlong startnsec = 0ULL, stopnsec = 0ULL; + vlong startnsec, stopnsec; + USED(startnsec); cycles(&up->kentry); m->syscall++; up->insyscall = 1; @@ -555,9 +561,9 @@ syscall(Ureg *ureg) up->procctl = Proc_stopme; syscallprint(ureg); procctl(up); - if (up->syscalltrace) + if(up->syscalltrace) free(up->syscalltrace); - up->syscalltrace = NULL; + up->syscalltrace = nil; startnsec = todget(nil); } @@ -624,10 +630,9 @@ syscall(Ureg *ureg) s = splhi(); procctl(up); splx(s); - /* you must have read the string by now. The free above is really not needed */ - if (up->syscalltrace) + if(up->syscalltrace) free(up->syscalltrace); - up->syscalltrace = NULL; + up->syscalltrace = nil; } up->insyscall = 0;