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:
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;