diff options
-rw-r--r-- | sys/src/cmd/vmx/9p.c | 117 | ||||
-rw-r--r-- | sys/src/cmd/vmx/vmxgdb.c | 14 |
2 files changed, 102 insertions, 29 deletions
diff --git a/sys/src/cmd/vmx/9p.c b/sys/src/cmd/vmx/9p.c index 84c3a1419..568cccb51 100644 --- a/sys/src/cmd/vmx/9p.c +++ b/sys/src/cmd/vmx/9p.c @@ -1,32 +1,95 @@ #include <u.h> #include <libc.h> #include <thread.h> +#include <bio.h> +#include <mach.h> #include <fcall.h> #include <9p.h> #include "dat.h" #include "fns.h" extern int regsfd; -char Egreg[] = "the front fell off"; -enum { - Qregs, - Qmem, - Qmax -}; +static char Egreg[] = "the front fell off"; +static File *memfile, *regsfile, *kregsfile, *xregsfile; +static uchar ureg[1024]; -static Dir files[] = { - [Qregs] {.name "regs", .mode 0440}, - [Qmem] {.name "mem", .mode 0440}, -}; +static int +makeureg(void) +{ + extern Mach mi386, mamd64; + char rbuf[4096], *p, *q, *f[2]; + Reglist *r; + uvlong v; + int rc; -void + mach = sizeof(uintptr) == 8 ? &mamd64 : &mi386; + memset(ureg, 0, mach->regsize); + + rc = pread(regsfd, rbuf, sizeof(rbuf)-1, 0); + if(rc < 0) + return -1; + rbuf[rc] = 0; + + for(p = rbuf; (q = strchr(p, '\n')) != nil; p = q + 1){ + *q = 0; + if(tokenize(p, f, nelem(f)) < 2) continue; + for(r = mach->reglist; r->rname != nil; r++){ + if(r->rflags == RINT && cistrcmp(f[0], r->rname) == 0){ + v = strtoull(f[1], nil, 0); + switch(r->rformat){ + case 'Y': + PUT64(ureg, r->roffs, v); + break; + case 'X': + PUT32(ureg, r->roffs, v); + break; + case 'x': + PUT16(ureg, r->roffs, v); + break; + case 'b': + PUT8(ureg, r->roffs, v); + break; + } + break; + } + } + } + return mach->regsize; +} + +static uintptr +off2addr(vlong off) +{ + off <<= 1; + off >>= 1; + return (uintptr)off; +} + +static void srvread(Req *r) { int rc; - switch((int)r->fid->qid.path){ - case Qregs: + if(r->fid->file == memfile){ + r->ofcall.count = vmemread(r->ofcall.data, r->ifcall.count, off2addr(r->ifcall.offset)); + if(r->ofcall.count == 0) + respond(r, "fault"); + else + respond(r, nil); + return; + } + if(r->fid->file == regsfile || r->fid->file == kregsfile){ + rc = makeureg(); + if(rc < 0){ + responderror(r); + return; + } + readbuf(r, ureg, rc); + respond(r, nil); + return; + } + if(r->fid->file == xregsfile){ rc = pread(regsfd, r->ofcall.data, r->ifcall.count, r->ifcall.offset); if(rc < 0) responderror(r); @@ -34,32 +97,40 @@ srvread(Req *r) r->ofcall.count = rc; respond(r, nil); } - break; - case Qmem: - r->ofcall.count = vmemread(r->ofcall.data, r->ifcall.count, r->ifcall.offset); + return; + } + respond(r, Egreg); +} + +static void +srvwrite(Req *r) +{ + if(r->fid->file == memfile){ + r->ofcall.count = vmemwrite(r->ifcall.data, r->ifcall.count, off2addr(r->ifcall.offset)); if(r->ofcall.count == 0) respond(r, "fault"); else respond(r, nil); - break; - default: - respond(r, Egreg); + return; } + respond(r, Egreg); } -Srv vmxsrv = { +static Srv vmxsrv = { .read srvread, + .write srvwrite, }; void init9p(char *srvname) { char *uid; - int i; uid = getuser(); vmxsrv.tree = alloctree(uid, uid, 0770, nil); - for(i = 0; i < Qmax; i++) - createfile(vmxsrv.tree->root, files[i].name, uid, files[i].mode, nil); + memfile = createfile(vmxsrv.tree->root, "mem", uid, 0660, nil); + regsfile = createfile(vmxsrv.tree->root, "regs", uid, 0440, nil); + kregsfile = createfile(vmxsrv.tree->root, "kregs", uid, 0440, nil); + xregsfile = createfile(vmxsrv.tree->root, "xregs", uid, 0440, nil); threadpostmountsrv(&vmxsrv, srvname, nil, 0); } diff --git a/sys/src/cmd/vmx/vmxgdb.c b/sys/src/cmd/vmx/vmxgdb.c index 07aba25c5..79f9f464d 100644 --- a/sys/src/cmd/vmx/vmxgdb.c +++ b/sys/src/cmd/vmx/vmxgdb.c @@ -132,7 +132,7 @@ char * regpacket(void) { char *buf; - char rbuf[8192]; + char rbuf[4096]; int rc; char *p, *q, *f[2]; int pos, i, l; @@ -148,10 +148,7 @@ regpacket(void) return strdup(""); } rbuf[rc] = 0; - p = rbuf; - for(;; p = q + 1){ - q = strchr(p, '\n'); - if(q == nil) break; + for(p = rbuf; (q = strchr(p, '\n')) != nil; p = q + 1){ *q = 0; if(tokenize(p, f, nelem(f)) < 2) continue; v = strtoull(f[1], nil, 0); @@ -183,6 +180,11 @@ memread(char *p) char tbuf[3]; addr = strtoull(p, &q, 16); + + /* avoid negative file offset */ + addr <<= 1; + addr >>= 1; + if(p == q || *q != ',') return strdup("E99"); count = strtoull(q + 1, &p, 16); if(q+1 == p || *p != 0) return strdup("E99"); @@ -213,7 +215,7 @@ main(int, char **) free(p); if(memfd < 0) sysfatal("open: %r"); - p = smprint("%s/regs", vmxroot); + p = smprint("%s/xregs", vmxroot); regsfd = open(p, OREAD); free(p); if(regsfd < 0) sysfatal("open: %r"); |