diff options
-rw-r--r-- | src/cmd/acid/Notes | 30 | ||||
-rw-r--r-- | src/cmd/acid/acid.h | 11 | ||||
-rw-r--r-- | src/cmd/acid/builtin.c | 166 | ||||
-rw-r--r-- | src/cmd/acid/dbg.y | 3 | ||||
-rw-r--r-- | src/cmd/acid/exec.c | 187 | ||||
-rw-r--r-- | src/cmd/acid/expr.c | 129 | ||||
-rw-r--r-- | src/cmd/acid/main.c | 114 | ||||
-rw-r--r-- | src/cmd/acid/print.c | 4 | ||||
-rw-r--r-- | src/cmd/acid/proc.c | 51 | ||||
-rw-r--r-- | src/cmd/acid/util.c | 5 |
10 files changed, 526 insertions, 174 deletions
diff --git a/src/cmd/acid/Notes b/src/cmd/acid/Notes index 597bf58c..90cfc2a5 100644 --- a/src/cmd/acid/Notes +++ b/src/cmd/acid/Notes @@ -20,6 +20,8 @@ map() returns 5-tuples: (name, filename, base, end, offset) map() expects a 5-tuple too +new acid maps() prints maps nicely. + strace expects a list of register names and values like {"PC", *PC, "SP", *SP} @@ -41,6 +43,34 @@ new builtin deltextfile(file) removes a file from the set of open text files. both textfile and deltextfile update symbols. +new types: register is something that when dereferenced gives you + the registers. the Ureg is no longer mapped at 0. + refconst is something that gives a constant when dereferenced. + +new builtin register("AX") creates register values +new builtin refconst(0x123) creates refconst values + +new builtin var("foo") is equivalent to the variable foo + (it returns foo but can also be used as the lhs of an assignment). + +new acid function getregs() returns a list of the current values of registers. +new acid function setregs() sets the current registers to those values. + note that getregs and setregs operate on register locations, not the + register values themselves. +new acid function resetregs() sets registers to register("AX"), etc. +new acid function clearregs() sets all registers to constant -1. + +the default register settings are as in resetregs(), not small numbers. +the Ureg is not mapped at 0 anymore. + +new acid variables coretext, pids, systype, corefile, cmdline. + +new behavior: local variable lookup, stk, etc., use the acid values of registers + (*PC, *SP, and so on), so the thread support code can change the context + completely. + +unary + is applicable to more data types and prints more often. + ==== yet to be done: diff --git a/src/cmd/acid/acid.h b/src/cmd/acid/acid.h index 44718009..866816e8 100644 --- a/src/cmd/acid/acid.h +++ b/src/cmd/acid/acid.h @@ -44,6 +44,7 @@ Extern int interactive; Extern Node* code; Extern int na; Extern int wtflag; +Extern Regs* acidregs; Extern Regs* correg; Extern Map* cormap; Extern Map* symmap; @@ -76,6 +77,8 @@ enum TSTRING, TLIST, TCODE, + TREG, + TCON, NUMT, }; @@ -129,6 +132,8 @@ struct Store String* string; List* l; Node* cc; + char* reg; + Node* con; } u; }; @@ -182,6 +187,7 @@ struct String int len; }; +int acidregsrw(Regs*, char*, ulong*, int); List* addlist(List*, List*); void addvarsym(Fhdr*); List* al(int); @@ -212,6 +218,7 @@ void gc(void); char* getstatus(int); void* gmalloc(long); void indir(Map*, ulong, char, Node*); +void indirreg(Regs*, char*, char, Node*); void initexpr(void); void initprint(void); void installbuiltin(void); @@ -257,7 +264,8 @@ void userinit(void); void varreg(void); void varsym(void); void whatis(Lsym*); -void windir(Map*, Node*, Node*, Node*); +void windir(Map*, Node, Node*, Node*); +void windirreg(Regs*, char*, Node*, Node*); void yyerror(char*, ...); int yylex(void); int yyparse(void); @@ -313,5 +321,6 @@ enum OFMT, OEVAL, OWHAT, + OUPLUS, NUMO, }; diff --git a/src/cmd/acid/builtin.c b/src/cmd/acid/builtin.c index 490c4521..316c4921 100644 --- a/src/cmd/acid/builtin.c +++ b/src/cmd/acid/builtin.c @@ -44,6 +44,9 @@ void regexp(Node*, Node*); void textfile(Node*, Node*); void deltextfile(Node*, Node*); void stringn(Node*, Node*); +void xregister(Node*, Node*); +void refconst(Node*, Node*); +void dolook(Node*, Node*); typedef struct Btab Btab; struct Btab @@ -52,13 +55,12 @@ struct Btab void (*fn)(Node*, Node*); } tab[] = { + "access", doaccess, "atof", cvtatof, "atoi", cvtatoi, "deltextfile", deltextfile, "error", doerror, "file", getfile, - "readfile", readfile, - "access", doaccess, "filepc", filepc, "fnbound", funcbound, "fmt", fmt, @@ -76,8 +78,11 @@ struct Btab "print", bprint, "printto", printto, "rc", rc, + "readfile", readfile, "reason", reason, + "refconst", refconst, "regexp", regexp, + "register", xregister, "setproc", setproc, "start", start, "startstop", startstop, @@ -87,6 +92,7 @@ struct Btab "stringn", stringn, "sysstop", sysstop, "textfile", textfile, + "var", dolook, "waitstop", waitstop, 0 }; @@ -317,6 +323,65 @@ xkill(Node *r, Node *args) } void +xregister(Node *r, Node *args) +{ + Regdesc *rp; + Node res; + + if(args == 0) + error("register(string): arg count"); + expr(args, &res); + if(res.type != TSTRING) + error("register(string): arg type"); + + if((rp = regdesc(res.store.u.string->string)) == nil) + error("no such register"); + + r->op = OCONST; + r->type = TREG; + r->store.fmt = rp->format; + r->store.u.reg = rp->name; +} + +void +refconst(Node *r, Node *args) +{ + Node *n; + + if(args == 0) + error("refconst(expr): arg count"); + + n = an(OCONST, ZN, ZN); + expr(args, n); + + r->op = OCONST; + r->type = TCON; + r->store.u.con = n; +} + +void +dolook(Node *r, Node *args) +{ + Node res; + Lsym *l; + + if(args == 0) + error("var(string): arg count"); + expr(args, &res); + if(res.type != TSTRING) + error("var(string): arg type"); + + r->op = OCONST; + if((l = look(res.store.u.string->string)) == nil || l->v->set == 0){ + r->type = TLIST; + r->store.u.l = nil; + }else{ + r->type = l->v->type; + r->store = l->v->store; + } +} + +void status(Node *r, Node *args) { Node res; @@ -350,7 +415,7 @@ reason(Node *r, Node *args) r->op = OCONST; r->type = TSTRING; r->store.fmt = 's'; - r->store.u.string = strnode((*mach->exc)(cormap, correg)); + r->store.u.string = strnode((*mach->exc)(cormap, acidregs)); } void @@ -367,7 +432,7 @@ follow(Node *r, Node *args) if(res.type != TINT) error("follow(addr): arg type"); - n = (*mach->foll)(cormap, correg, res.store.u.ival, f); + n = (*mach->foll)(cormap, acidregs, res.store.u.ival, f); if (n < 0) error("follow(addr): %r"); tail = &r->store.u.l; @@ -953,7 +1018,7 @@ straceregrw(Regs *regs, char *name, ulong *val, int isr) *val = sregs[i].val; return 0; } - return rget(correg, name, val); + return rget(acidregs, name, val); } void @@ -1058,6 +1123,65 @@ patom(char type, Store *res) int i; char buf[512]; extern char *typenames[]; + Node *n; + + switch(type){ + case TREG: + Bprint(bout, "register(\"%s\")", res->u.reg); + return; + case TCON: + Bprint(bout, "refconst("); + n = res->u.con; + patom(n->type, &n->store); + Bprint(bout, ")"); + return; + } + + switch(res->fmt){ + case 'c': + case 'C': + case 'r': + case 'B': + case 'b': + case 'X': + case 'x': + case 'W': + case 'D': + case 'd': + case 'u': + case 'U': + case 'Z': + case 'V': + case 'Y': + case 'o': + case 'O': + case 'q': + case 'Q': + case 'a': + case 'A': + case 'I': + case 'i': + if(type != TINT){ + badtype: + Bprint(bout, "*%s\\%c*", typenames[(uchar)type], res->fmt); + return; + } + break; + + case 'f': + case 'F': + if(type != TFLOAT) + goto badtype; + break; + + case 's': + case 'g': + case 'G': + case 'R': + if(type != TSTRING) + goto badtype; + break; + } switch(res->fmt) { case 'c': @@ -1129,24 +1253,15 @@ patom(char type, Store *res) break; case 'f': case 'F': - if(type != TFLOAT) - Bprint(bout, "*%c<%s>*", res->fmt, typenames[(uchar)type]); - else - Bprint(bout, "%g", res->u.fval); + Bprint(bout, "%g", res->u.fval); break; case 's': case 'g': case 'G': - if(type != TSTRING) - Bprint(bout, "*%c<%s>*", res->fmt, typenames[(uchar)type]); - else - Bwrite(bout, res->u.string->string, res->u.string->len); + Bwrite(bout, res->u.string->string, res->u.string->len); break; case 'R': - if(type != TSTRING) - Bprint(bout, "*%c<%s>*", res->fmt, typenames[(uchar)type]); - else - Bprint(bout, "%S", (Rune*)res->u.string->string); + Bprint(bout, "%S", (Rune*)res->u.string->string); break; case 'a': case 'A': @@ -1155,14 +1270,10 @@ patom(char type, Store *res) break; case 'I': case 'i': - if(type != TINT) - Bprint(bout, "*%c<%s>*", res->fmt, typenames[(uchar)type]); - else { - if (symmap == nil || (*mach->das)(symmap, res->u.ival, res->fmt, buf, sizeof(buf)) < 0) - Bprint(bout, "no instruction"); - else - Bprint(bout, "%s", buf); - } + if (symmap == nil || (*mach->das)(symmap, res->u.ival, res->fmt, buf, sizeof(buf)) < 0) + Bprint(bout, "no instruction"); + else + Bprint(bout, "%s", buf); break; } } @@ -1406,6 +1517,7 @@ textfile(Node *r, Node *args) unmapfile(corhdr, cormap); mapfile(fp, base, cormap, nil); free(correg); + correg = nil; mapfile(corhdr, 0, cormap, &correg); } if(symopen(fp) < 0) @@ -1476,8 +1588,6 @@ deltextfile(Node *r, Node *args) error("symbol file %s not open", file); } -int xget1(Map *m, ulong addr, u8int *a, int n); - void stringn(Node *r, Node *args) { @@ -1507,7 +1617,7 @@ stringn(Node *r, Node *args) r->type = TSTRING; for(i=0; i<n; i++){ - ret = xget1(cormap, addr, (uchar*)&buf[i], 1); + ret = get1(cormap, addr, (uchar*)&buf[i], 1); if(ret < 0){ free(buf); error("indir: %r"); diff --git a/src/cmd/acid/dbg.y b/src/cmd/acid/dbg.y index afdf538c..3d1886c7 100644 --- a/src/cmd/acid/dbg.y +++ b/src/cmd/acid/dbg.y @@ -282,8 +282,7 @@ monexpr : term } | '+' monexpr { - $$ = con(0); - $$ = an(OADD, $2, $$); + $$ = an(OUPLUS, $2, ZN); } | '-' monexpr { diff --git a/src/cmd/acid/exec.c b/src/cmd/acid/exec.c index edf2690e..2022da53 100644 --- a/src/cmd/acid/exec.c +++ b/src/cmd/acid/exec.c @@ -202,56 +202,6 @@ convflt(Node *r, char *flt) } } -static char* -regbyoff(ulong addr) -{ - Regdesc *r; - - if(mach == nil) - error("no mach, no registers"); - for(r=mach->reglist; r->name; r++) - if(r->offset == addr) - return r->name; - error("no register at %#lux", addr); - return nil; -} - -int -xget1(Map *m, ulong addr, u8int *a, int n) -{ - if(addr < 0x100 && correg) - return lget1(m, correg, locreg(regbyoff(addr)), a, n); - else - return get1(m, addr, a, n); -} - -int -xget2(Map *m, ulong addr, u16int *a) -{ - if(addr < 0x100 && correg) - return lget2(m, correg, locreg(regbyoff(addr)), a); - else - return get2(m, addr, a); -} - -int -xget4(Map *m, ulong addr, u32int *a) -{ - if(addr < 0x100 && correg) - return lget4(m, correg, locreg(regbyoff(addr)), a); - else - return get4(m, addr, a); -} - -int -xget8(Map *m, ulong addr, u64int *a) -{ - if(addr < 0x100 && correg) - return lget8(m, correg, locreg(regbyoff(addr)), a); - else - return get8(m, addr, a); -} - void indir(Map *m, ulong addr, char fmt, Node *r) { @@ -272,7 +222,7 @@ indir(Map *m, ulong addr, char fmt, Node *r) case 'C': case 'b': r->type = TINT; - ret = xget1(m, addr, &cval, 1); + ret = get1(m, addr, &cval, 1); if (ret < 0) error("indir: %r"); r->store.u.ival = cval; @@ -284,7 +234,7 @@ indir(Map *m, ulong addr, char fmt, Node *r) case 'q': case 'r': r->type = TINT; - ret = xget2(m, addr, &sval); + ret = get2(m, addr, &sval); if (ret < 0) error("indir: %r"); r->store.u.ival = sval; @@ -298,7 +248,7 @@ indir(Map *m, ulong addr, char fmt, Node *r) case 'O': case 'Q': r->type = TINT; - ret = xget4(m, addr, &ival); + ret = get4(m, addr, &ival); if (ret < 0) error("indir: %r"); r->store.u.ival = ival; @@ -308,7 +258,7 @@ indir(Map *m, ulong addr, char fmt, Node *r) case 'Y': case 'Z': r->type = TINT; - ret = xget8(m, addr, &vval); + ret = get8(m, addr, &vval); if (ret < 0) error("indir: %r"); r->store.u.ival = vval; @@ -316,7 +266,7 @@ indir(Map *m, ulong addr, char fmt, Node *r) case 's': r->type = TSTRING; for(i = 0; i < sizeof(buf)-1; i++) { - ret = xget1(m, addr, (uchar*)&buf[i], 1); + ret = get1(m, addr, (uchar*)&buf[i], 1); if (ret < 0) error("indir: %r"); addr++; @@ -331,7 +281,7 @@ indir(Map *m, ulong addr, char fmt, Node *r) case 'R': r->type = TSTRING; for(i = 0; i < sizeof(buf)-2; i += 2) { - ret = xget1(m, addr, (uchar*)&buf[i], 2); + ret = get1(m, addr, (uchar*)&buf[i], 2); if (ret < 0) error("indir: %r"); addr += 2; @@ -351,14 +301,14 @@ indir(Map *m, ulong addr, char fmt, Node *r) r->store.u.string = strnode(buf); break; case 'f': - ret = xget1(m, addr, (uchar*)buf, mach->szfloat); + ret = get1(m, addr, (uchar*)buf, mach->szfloat); if (ret < 0) error("indir: %r"); mach->ftoa32(buf, sizeof(buf), (void*) buf); convflt(r, buf); break; case 'g': - ret = xget1(m, addr, (uchar*)buf, mach->szfloat); + ret = get1(m, addr, (uchar*)buf, mach->szfloat); if (ret < 0) error("indir: %r"); mach->ftoa32(buf, sizeof(buf), (void*) buf); @@ -366,14 +316,14 @@ indir(Map *m, ulong addr, char fmt, Node *r) r->store.u.string = strnode(buf); break; case 'F': - ret = xget1(m, addr, (uchar*)buf, mach->szdouble); + ret = get1(m, addr, (uchar*)buf, mach->szdouble); if (ret < 0) error("indir: %r"); mach->ftoa64(buf, sizeof(buf), (void*) buf); convflt(r, buf); break; case '3': /* little endian ieee 80 with hole in bytes 8&9 */ - ret = xget1(m, addr, (uchar*)reg, 10); + ret = get1(m, addr, (uchar*)reg, 10); if (ret < 0) error("indir: %r"); memmove(reg+10, reg+8, 2); /* open hole */ @@ -382,14 +332,14 @@ indir(Map *m, ulong addr, char fmt, Node *r) convflt(r, buf); break; case '8': /* big-endian ieee 80 */ - ret = xget1(m, addr, (uchar*)reg, 10); + ret = get1(m, addr, (uchar*)reg, 10); if (ret < 0) error("indir: %r"); beieeeftoa80(buf, sizeof(buf), reg); convflt(r, buf); break; case 'G': - ret = xget1(m, addr, (uchar*)buf, mach->szdouble); + ret = get1(m, addr, (uchar*)buf, mach->szdouble); if (ret < 0) error("indir: %r"); mach->ftoa64(buf, sizeof(buf), (void*) buf); @@ -400,21 +350,70 @@ indir(Map *m, ulong addr, char fmt, Node *r) } void -windir(Map *m, Node *addr, Node *rval, Node *r) +indirreg(Regs *regs, char *name, char fmt, Node *r) +{ + ulong val; + + if(regs == 0) + error("no register set for *%s=", name); + + r->op = OCONST; + r->store.fmt = fmt; + switch(fmt){ + default: + error("bad pointer format '%c' for *%s", fmt, name); + case 'c': + case 'C': + case 'b': + case 'x': + case 'd': + case 'u': + case 'o': + case 'q': + case 'r': + case 'a': + case 'A': + case 'B': + case 'X': + case 'D': + case 'U': + case 'O': + case 'Q': + case 'V': + case 'W': + case 'Y': + case 'Z': + if(rget(regs, name, &val) < 0) + error("reading %s: %r", name); + r->type = TINT; + r->store.u.ival = val; + break; + case 'f': + case 'g': + case 'F': + case '3': + case '8': + case 'G': + error("floating point registers not supported"); + break; + } +} + +void +windir(Map *m, Node aes, Node *rval, Node *r) { uchar cval; ushort sval; - Node res, aes; + Node res; int ret; if(m == 0) error("no map for */@="); - expr(rval, &res); - expr(addr, &aes); - if(aes.type != TINT) - error("bad type lhs of @/*"); + error("bad type lhs of */@="); + + expr(rval, &res); if(m != cormap && wtflag == 0) error("not in write mode"); @@ -466,6 +465,58 @@ windir(Map *m, Node *addr, Node *rval, Node *r) } void +windirreg(Regs *regs, char *name, Node *rval, Node *r) +{ + Node res; + + if(regs == 0) + error("no register set for *%s=", name); + + expr(rval, &res); + + r->type = res.type; + r->store.fmt = res.store.fmt; + r->store = res.store; + + switch(res.store.fmt){ + default: + error("bad format '%c' for *%s=", res.store.fmt, name); + case 'c': + case 'C': + case 'b': + case 'x': + case 'd': + case 'u': + case 'o': + case 'q': + case 'r': + case 'a': + case 'A': + case 'B': + case 'X': + case 'D': + case 'U': + case 'O': + case 'Q': + case 'V': + case 'W': + case 'Y': + case 'Z': + if(rput(regs, name, res.store.u.ival) < 0) + error("writing %s: %r", name); + break; + case 'f': + case 'g': + case 'F': + case '3': + case '8': + case 'G': + error("floating point registers not supported"); + break; + } +} + +void call(char *fn, Node *parameters, Node *local, Node *body, Node *retexp) { int np, i; diff --git a/src/cmd/acid/expr.c b/src/cmd/acid/expr.c index 9cfac9e3..6a0430dc 100644 --- a/src/cmd/acid/expr.c +++ b/src/cmd/acid/expr.c @@ -63,11 +63,29 @@ fmtsize(Value *v) } } -void +Lsym* chklval(Node *lp) { - if(lp->op != ONAME) - error("need l-value"); + Node res; + Lsym *s; + + if(lp->op == ONAME) + return lp->sym; + + if(lp->op == OCALL){ + s = chklval(lp->left); + if(strcmp(s->name, "var") == 0 + && (lp->builtin || s->proc == 0)){ + if(lp->right == 0) + error("var(string): arg count"); + expr(lp->right, &res); + if(res.type != TSTRING) + error("var(string): arg type"); + return mkvar(res.store.u.string->string); + } + } + error("need l-value"); + return nil; } void @@ -107,12 +125,24 @@ oindm(Node *n, Node *res) if(m == 0) m = symmap; expr(n->left, &l); - if(l.type != TINT) + switch(l.type){ + default: error("bad type for *"); - if(m == 0) - error("no map for *"); - indir(m, l.store.u.ival, l.store.fmt, res); - res->store.comt = l.store.comt; + case TINT: + if(m == 0) + error("no map for *"); + indir(m, l.store.u.ival, l.store.fmt, res); + res->store.comt = l.store.comt; + break; + case TREG: + indirreg(correg, l.store.u.reg, l.store.fmt, res); + res->store.comt = l.store.comt; + break; + case TCON: + *res = *l.store.u.con; + res->store.comt = l.store.comt; + break; + } } void @@ -145,7 +175,7 @@ oframe(Node *n, Node *res) while(*p && *p == '$') p++; lp = n->left; - if(localaddr(cormap, correg, p, lp->sym->name, &ival) < 0) + if(localaddr(cormap, acidregs, p, lp->sym->name, &ival) < 0) error("colon: %r"); res->store.u.ival = ival; @@ -296,19 +326,24 @@ void oasgn(Node *n, Node *res) { Node *lp, r; + Node aes; Value *v; lp = n->left; switch(lp->op) { case OINDM: - windir(cormap, lp->left, n->right, res); + expr(lp->left, &aes); + if(aes.type == TREG) + windirreg(correg, aes.store.u.reg, n->right, res); + else + windir(cormap, aes, n->right, res); break; case OINDC: - windir(symmap, lp->left, n->right, res); + expr(lp->left, &aes); + windir(symmap, aes, n->right, res); break; default: - chklval(lp); - v = lp->sym->v; + v = chklval(lp)->v; expr(n->right, &r); v->set = 1; v->type = r.type; @@ -871,8 +906,7 @@ oeinc(Node *n, Node *res) { Value *v; - chklval(n->left); - v = n->left->sym->v; + v = chklval(n->left)->v; res->op = OCONST; res->type = v->type; switch(v->type) { @@ -899,8 +933,7 @@ opinc(Node *n, Node *res) { Value *v; - chklval(n->left); - v = n->left->sym->v; + v = chklval(n->left)->v; res->op = OCONST; res->type = v->type; res->store = v->store; @@ -932,9 +965,7 @@ ocall(Node *n, Node *res) res->type = TLIST; res->store.u.l = 0; - chklval(n->left); - s = n->left->sym; - + s = chklval(n->left); if(n->builtin && !s->builtin){ error("no builtin %s", s->name); return; @@ -959,6 +990,12 @@ ofmt(Node *n, Node *res) } void +ouplus(Node *n, Node *res) +{ + expr(n->left, res); +} + +void owhat(Node *n, Node *res) { res->op = OCONST; /* Default return value */ @@ -1021,6 +1058,7 @@ initexpop(void) expop[OFMT] = ofmt; expop[OEVAL] = oeval; expop[OWHAT] = owhat; + expop[OUPLUS] = ouplus; } void @@ -1030,3 +1068,54 @@ initexpr(void) initexpop(); } +int +acidregsrw(Regs *r, char *name, ulong *u, int isr) +{ + Lsym *l; + Value *v; + Node *n; + ulong addr; + u32int u32; + + if(!isr){ + werrstr("cannot write registers"); + return -1; + } + USED(r); + l = look(name); + if(l == nil){ + werrstr("register %s not found", name); + return -1; + } + v = l->v; + switch(v->type){ + default: + werrstr("*%s: bad type", name); + return -1; + case TREG: + if(correg == nil){ + werrstr("*%s: register %s not mapped", name, v->store.u.reg); + return -1; + } + return rget(correg, v->store.u.reg, u); + case TCON: + n = v->store.u.con; + if(n->op != OCONST || n->type != TINT){ + werrstr("*%s: bad register constant", name); + return -1; + } + *u = n->store.u.ival; + return 0; + case TINT: + if(cormap == nil){ + werrstr("*%s: core not mapped", name); + return -1; + } + addr = v->store.u.ival; + /* XXX should use format to determine size */ + if(get4(cormap, addr, &u32) < 0) + return -1; + *u = u32; + return 0; + } +} diff --git a/src/cmd/acid/main.c b/src/cmd/acid/main.c index 87f59798..e885b01d 100644 --- a/src/cmd/acid/main.c +++ b/src/cmd/acid/main.c @@ -106,6 +106,8 @@ main(int argc, char *argv[]) pushfile(0); loadvars(); installbuiltin(); + acidregs = mallocz(sizeof *acidregs, 1); + acidregs->rw = acidregsrw; if(mtype && machbyname(mtype) == 0) print("unknown machine %s", mtype); @@ -172,16 +174,29 @@ main(int argc, char *argv[]) */ } +void +setstring(char *var, char *s) +{ + Lsym *l; + Value *v; + + l = mkvar(var); + v = l->v; + v->store.fmt = 's'; + v->set = 1; + v->store.u.string = strnode(s ? s : ""); + v->type = TSTRING; +} + static int attachfiles(int argc, char **argv) { int fd; volatile int pid; - char *s; + char *s, *t; int i, omode; Fhdr *hdr; Lsym *l; - Value *v; pid = 0; interactive = 0; @@ -220,7 +235,6 @@ attachfiles(int argc, char **argv) } fprint(2, "%s: %s %s %s\n", argv[i], hdr->aname, hdr->mname, hdr->fname); if(hdr->ftype == FCORE){ - fprint(2, "cmd: %s\n", hdr->cmd); if(pid){ fprint(2, "already have pid %d; ignoring core %s\n", pid, argv[i]); uncrackhdr(hdr); @@ -252,12 +266,28 @@ attachfiles(int argc, char **argv) symfil = s; } } - /* XXX pull command from core */ + if(corhdr){ + /* + * prog gives only the basename of the command, + * so try the command line for a path. + */ + if((s = strdup(corhdr->cmdline)) != nil){ + t = strchr(s, ' '); + if(t) + *t = 0; + if((t = searchpath(s)) != nil){ + fprint(2, "core: text %s\n", t); + symfil = t; + } + free(s); + } + } if((symhdr = crackhdr(symfil, omode)) == nil){ fprint(2, "crackhdr %s: %r\n", symfil); symfil = nil; - } + }else + fprint(2, "%s: %s %s %s\n", symfil, symhdr->aname, symhdr->mname, symhdr->fname); } if(symhdr) @@ -281,33 +311,15 @@ attachfiles(int argc, char **argv) } Run: - l = mkvar("objtype"); - v = l->v; - v->store.fmt = 's'; - v->set = 1; - v->store.u.string = strnode(mach->name); - v->type = TSTRING; - - l = mkvar("textfile"); - v = l->v; - v->store.fmt = 's'; - v->set = 1; - v->store.u.string = strnode(symfil ? symfil : ""); - v->type = TSTRING; - - l = mkvar("systype"); - v = l->v; - v->store.fmt = 's'; - v->set = 1; - v->store.u.string = strnode(symhdr ? symhdr->aname : ""); - v->type = TSTRING; + setstring("objtype", mach->name); + setstring("textfile", symfil); + setstring("systype", symhdr ? symhdr->aname : ""); + setstring("corefile", corfil); - l = mkvar("corefile"); - v = l->v; - v->store.fmt = 's'; - v->set = 1; - v->store.u.string = strnode(corfil ? corfil : ""); - v->type = TSTRING; + l = mkvar("pids"); + l->v->set = 1; + l->v->type = TLIST; + l->v->store.u.l = nil; if(pid) sproc(pid); @@ -320,6 +332,11 @@ Run: void setcore(Fhdr *hdr) { + int i; + Lsym *l; + Value *v; + List **tail, *tl; + unmapproc(cormap); unmapfile(corhdr, cormap); free(correg); @@ -331,6 +348,31 @@ setcore(Fhdr *hdr) error("mapfile %s: %r", hdr->filename); corhdr = hdr; corfil = hdr->filename; + + l = mkvar("pid"); + v = l->v; + v->store.fmt = 'D'; + v->set = 1; + v->store.u.ival = hdr->pid; + + setstring("corefile", corfil); + setstring("cmdline", hdr->cmdline); + + l = mkvar("pids"); + l->v->set = 1; + l->v->type = TLIST; + l->v->store.u.l = nil; + tail = &l->v->store.u.l; + for(i=0; i<hdr->nthread; i++){ + tl = al(TINT); + tl->store.u.ival = hdr->thread[i].id; + tl->store.fmt = 'X'; + *tail = tl; + tail = &tl->next; + } + + if(hdr->nthread) + sproc(hdr->thread[0].id); } void @@ -338,16 +380,21 @@ die(void) { Lsym *s; List *f; + int first; Bprint(bout, "\n"); + first = 1; s = look("proclist"); if(s && s->v->type == TLIST) { for(f = s->v->store.u.l; f; f = f->next){ detachproc((int)f->store.u.ival); - Bprint(bout, "/bin/kill -9 %d\n", (int)f->store.u.ival); + Bprint(bout, "%s %d", first ? "/bin/kill -9" : "", (int)f->store.u.ival); + first = 0; } } + if(!first) + Bprint(bout, "\n"); exits(0); } @@ -545,6 +592,9 @@ gc(void) case TCODE: marktree(v->store.u.cc); break; + case TCON: + marktree(v->store.u.con); + break; } } } diff --git a/src/cmd/acid/print.c b/src/cmd/acid/print.c index 0c66e024..58acdfc9 100644 --- a/src/cmd/acid/print.c +++ b/src/cmd/acid/print.c @@ -401,6 +401,10 @@ pexpr(Node *n) if(n->sym) Bprint(bout, " %s", n->sym->name); break; + case OUPLUS: + Bprint(bout, "+"); + pexpr(l); + break; } } diff --git a/src/cmd/acid/proc.c b/src/cmd/acid/proc.c index a0aed614..02c44533 100644 --- a/src/cmd/acid/proc.c +++ b/src/cmd/acid/proc.c @@ -21,30 +21,39 @@ sproc(int xpid) if(pid == xpid) return; - if(xpid <= 0) - error("bad pid"); - - unmapproc(cormap); - unmapfile(corhdr, cormap); - free(correg); - correg = nil; - - if(mapproc(xpid, cormap, &correg) < 0) - error("setproc %d: %r", xpid); - - /* XXX check text file here? */ - + if(corhdr){ + free(correg); + correg = nil; + correg = coreregs(corhdr, xpid); + if(correg == nil) + error("no such pid in core dump"); + }else{ + /* XXX should only change register set here if cormap already mapped */ + if(xpid <= 0) + error("bad pid"); + unmapproc(cormap); + unmapfile(corhdr, cormap); + free(correg); + correg = nil; + + if(mapproc(xpid, cormap, &correg) < 0) + error("setproc %d: %r", xpid); + + /* XXX check text file here? */ + + for(i=0; i<cormap->nseg; i++){ + if(cormap->seg[i].file == nil){ + if(strcmp(cormap->seg[i].name, "data") == 0) + cormap->seg[i].name = "*data"; + if(strcmp(cormap->seg[i].name, "text") == 0) + cormap->seg[i].name = "*text"; + } + } + } pid = xpid; s = look("pid"); s->v->store.u.ival = pid; - for(i=0; i<cormap->nseg; i++) - if(cormap->seg[i].file == nil){ - if(strcmp(cormap->seg[i].name, "data") == 0) - cormap->seg[i].name = "*data"; - if(strcmp(cormap->seg[i].name, "text") == 0) - cormap->seg[i].name = "*text"; - } install(pid); } @@ -165,6 +174,7 @@ install(int pid) s->v->set = 1; } +/* static int installed(int pid) { @@ -175,6 +185,7 @@ installed(int pid) return 1; return 0; } +*/ void deinstall(int pid) diff --git a/src/cmd/acid/util.c b/src/cmd/acid/util.c index 355fd5b7..3ea3c4c0 100644 --- a/src/cmd/acid/util.c +++ b/src/cmd/acid/util.c @@ -61,7 +61,6 @@ varsym(void) continue; addvarsym(fp); } - if(l->v->store.u.l == nil) print("no debugging symbols\n"); } @@ -217,9 +216,9 @@ varreg(void) l = mkvar(r->name); v = l->v; v->set = 1; - v->store.u.ival = r->offset; + v->store.u.reg = r->name; v->store.fmt = r->format; - v->type = TINT; + v->type = TREG; li = al(TSTRING); li->store.u.string = strnode(r->name); |