11 void cvtatof(Node*, Node*);
12 void cvtatoi(Node*, Node*);
13 void cvtitoa(Node*, Node*);
14 void bprint(Node*, Node*);
15 void funcbound(Node*, Node*);
16 void printto(Node*, Node*);
17 void getfile(Node*, Node*);
18 void fmt(Node*, Node*);
19 void pcfile(Node*, Node*);
20 void pcline(Node*, Node*);
21 void setproc(Node*, Node*);
22 void strace(Node*, Node*);
23 void follow(Node*, Node*);
24 void reason(Node*, Node*);
25 void newproc(Node*, Node*);
26 void startstop(Node*, Node*);
27 void match(Node*, Node*);
28 void status(Node*, Node*);
29 void xkill(Node*,Node*);
30 void waitstop(Node*, Node*);
31 void sysstop(Node*, Node*);
32 void stop(Node*, Node*);
33 void start(Node*, Node*);
34 void filepc(Node*, Node*);
35 void doerror(Node*, Node*);
36 void rc(Node*, Node*);
37 void doaccess(Node*, Node*);
38 void map(Node*, Node*);
39 void readfile(Node*, Node*);
40 void interpret(Node*, Node*);
41 void include(Node*, Node*);
42 void includepipe(Node*, Node*);
43 void regexp(Node*, Node*);
44 void textfile(Node*, Node*);
45 void deltextfile(Node*, Node*);
46 void stringn(Node*, Node*);
47 void xregister(Node*, Node*);
48 void refconst(Node*, Node*);
49 void dolook(Node*, Node*);
51 typedef struct Btab Btab;
55 void (*fn)(Node*, Node*);
61 "deltextfile", deltextfile,
69 "includepipe", includepipe,
70 "interpret", interpret,
85 "register", xregister,
88 "startstop", startstop,
103 prnt = malloc(sizeof(Node));
104 memset(prnt, 0, sizeof(Node));
106 prnt->left = malloc(sizeof(Node));
107 memset(prnt->left, 0, sizeof(Node));
121 s = enter(b->name, Tid);
131 match(Node *r, Node *args)
141 error("match(obj, list): arg count");
144 if(resl.type != TLIST)
145 error("match(obj, list): need list");
151 r->store.u.ival = -1;
154 for(f = resl.store.u.l; f; f = f->next) {
155 if(resi.type == f->type) {
158 if(resi.store.u.ival == f->store.u.ival) {
164 if(resi.store.u.fval == f->store.u.fval) {
170 if(scmp(resi.store.u.string, f->store.u.string)) {
176 error("match(obj, list): not defined for list");
184 newproc(Node *r, Node *args)
189 char *argv[Maxarg], buf[Strsize];
196 if(res.type != TSTRING)
197 error("newproc(): arg not string");
198 if(res.store.u.string->len >= sizeof(buf))
199 error("newproc(): too many arguments");
200 memmove(buf, res.store.u.string->string, res.store.u.string->len);
201 buf[res.store.u.string->len] = '\0';
203 e = buf+res.store.u.string->len;
205 while(p < e && (*p == '\t' || *p == ' '))
211 error("newproc: too many arguments");
212 while(p < e && *p != '\t' && *p != ' ')
220 r->store.u.ival = nproc(argv);
224 startstop(Node *r, Node *args)
230 error("startstop(pid): no pid");
233 error("startstop(pid): arg type");
235 msg(res.store.u.ival, "startstop");
236 notes(res.store.u.ival);
237 dostop(res.store.u.ival);
241 waitstop(Node *r, Node *args)
247 error("waitstop(pid): no pid");
250 error("waitstop(pid): arg type");
253 msg(res.store.u.ival, "waitstop");
254 notes(res.store.u.ival);
255 dostop(res.store.u.ival);
259 sysstop(Node *r, Node *args)
265 error("waitstop(pid): no pid");
268 error("waitstop(pid): arg type");
271 msg(res.store.u.ival, "sysstop");
272 notes(res.store.u.ival);
273 dostop(res.store.u.ival);
277 start(Node *r, Node *args)
283 error("start(pid): no pid");
286 error("start(pid): arg type");
288 msg(res.store.u.ival, "start");
292 stop(Node *r, Node *args)
298 error("stop(pid): no pid");
301 error("stop(pid): arg type");
304 msg(res.store.u.ival, "stop");
305 notes(res.store.u.ival);
306 dostop(res.store.u.ival);
310 xkill(Node *r, Node *args)
316 error("kill(pid): no pid");
319 error("kill(pid): arg type");
321 msg(res.store.u.ival, "kill");
322 deinstall(res.store.u.ival);
326 xregister(Node *r, Node *args)
335 if(na != 1/* && na != 2 */)
336 error("register(name): arg count");
339 if(res.type != TSTRING)
340 error("register(name): arg type: name should be string");
344 if(resid.type != TINT)
345 error("register(name[, threadid]): arg type: threadid should be int");
346 tid = resid.store.u.ival;
348 if((rp = regdesc(res.store.u.string->string)) == nil)
349 error("no such register");
352 r->store.fmt = rp->format;
353 r->store.u.reg.name = rp->name;
354 r->store.u.reg.thread = tid;
358 refconst(Node *r, Node *args)
363 error("refconst(expr): arg count");
365 n = an(OCONST, ZN, ZN);
374 dolook(Node *r, Node *args)
380 error("var(string): arg count");
382 if(res.type != TSTRING)
383 error("var(string): arg type");
386 if((l = look(res.store.u.string->string)) == nil || l->v->set == 0){
390 r->type = l->v->type;
391 r->store = l->v->store;
396 status(Node *r, Node *args)
403 error("status(pid): no pid");
406 error("status(pid): arg type");
408 p = getstatus(res.store.u.ival);
409 r->store.u.string = strnode(p);
416 reason(Node *r, Node *args)
421 error("reason(cause): no cause");
424 error("reason(cause): arg type");
429 r->store.u.string = strnode((*mach->exc)(cormap, acidregs));
433 follow(Node *r, Node *args)
441 error("follow(addr): no addr");
444 error("follow(addr): arg type");
446 n = (*mach->foll)(cormap, acidregs, res.store.u.ival, f);
448 error("follow(addr): %r");
449 tail = &r->store.u.l;
450 for(i = 0; i < n; i++) {
452 l->store.u.ival = f[i];
460 funcbound(Node *r, Node *args)
468 error("fnbound(addr): no addr");
471 error("fnbound(addr): arg type");
473 n = fnbound(res.store.u.ival, bounds);
475 r->store.u.l = al(TINT);
477 l->store.u.ival = bounds[0];
481 l->store.u.ival = bounds[1];
487 setproc(Node *r, Node *args)
493 error("setproc(pid): no pid");
496 error("setproc(pid): arg type");
498 sproc(res.store.u.ival);
502 filepc(Node *r, Node *args)
510 error("filepc(filename:line): arg count");
512 if(res.type != TSTRING)
513 error("filepc(filename:line): arg type");
515 p = strchr(res.store.u.string->string, ':');
517 error("filepc(filename:line): bad arg format");
521 i = file2pc(res.store.u.string->string, atoi(p), &v);
524 error("filepc(filename:line): can't find address");
533 interpret(Node *r, Node *args)
539 error("interpret(string): arg count");
541 if(res.type != TSTRING)
542 error("interpret(string): arg type");
548 r->store.u.ival = yyparse();
557 include(Node *r, Node *args)
559 char *file, *libfile;
560 static char buf[1024];
565 error("include(string): arg count");
567 if(res.type != TSTRING)
568 error("include(string): arg type");
573 file = res.store.u.string->string;
574 if(access(file, AREAD) < 0 && file[0] != '/'){
575 snprint(buf, sizeof buf, "#9/acid/%s", file);
576 libfile = unsharp(buf);
577 if(access(libfile, AREAD) >= 0){
578 strecpy(buf, buf+sizeof buf, libfile);
587 r->store.u.ival = yyparse();
596 includepipe(Node *r, Node *args)
599 int i, isave, pid, pip[2];
605 error("includepipe(string): arg count");
607 if(res.type != TSTRING)
608 error("includepipe(string): arg type");
614 argv[2] = res.store.u.string->string;
629 open("/dev/null", OREAD);
636 sysfatal("exec rc: %r");
644 r->store.u.ival = yyparse();
653 if(w->msg && w->msg[0])
654 error("includepipe(\"%s\"): %s", argv[2], w->msg); /* leaks w */
659 rc(Node *r, Node *args)
663 char *p, *q, *argv[4];
668 error("rc(string): arg count");
670 if(res.type != TSTRING)
671 error("rc(string): arg type");
675 argv[2] = res.store.u.string->string;
696 r->store.u.string = strnode(p);
702 doerror(Node *r, Node *args)
708 error("error(string): arg count");
710 if(res.type != TSTRING)
711 error("error(string): arg type");
713 error(res.store.u.string->string);
717 doaccess(Node *r, Node *args)
722 error("access(filename): arg count");
724 if(res.type != TSTRING)
725 error("access(filename): arg type");
731 if(access(res.store.u.string->string, 4) == 0)
736 readfile(Node *r, Node *args)
744 error("readfile(filename): arg count");
746 if(res.type != TSTRING)
747 error("readfile(filename): arg type");
749 fd = open(res.store.u.string->string, OREAD);
754 if(db == nil || db->length == 0)
761 n = read(fd, buf, n);
766 r->store.u.string = strnodlen(buf, n);
774 getfile(Node *r, Node *args)
784 error("file(filename): arg count");
786 if(res.type != TSTRING)
787 error("file(filename): arg type");
793 p = res.store.u.string->string;
794 bp = Bopen(p, OREAD);
800 p = Brdline(bp, '\n');
806 Bread(bp, s->string, n);
809 s = strnodlen(p, n-1);
812 new->store.u.string = s;
813 new->store.fmt = 's';
821 cvtatof(Node *r, Node *args)
826 error("atof(string): arg count");
828 if(res.type != TSTRING)
829 error("atof(string): arg type");
833 r->store.u.fval = atof(res.store.u.string->string);
838 cvtatoi(Node *r, Node *args)
843 error("atoi(string): arg count");
845 if(res.type != TSTRING)
846 error("atoi(string): arg type");
850 r->store.u.ival = strtoul(res.store.u.string->string, 0, 0);
855 cvtitoa(Node *r, Node *args)
864 error("itoa(number [, printformat]): arg count");
867 if(na == 0 || na > 2)
871 error("itoa(integer): arg type");
872 ival = (int)res.store.u.ival;
876 if(res.type != TSTRING)
877 error("itoa(integer, string): arg type");
878 fmt = res.store.u.string->string;
881 sprint(buf, fmt, ival);
884 r->store.u.string = strnode(buf);
892 List *l, *n, **t, *h;
896 for(i = 0; i < m->nseg; i++) {
902 l->store.u.string = strnode(m->seg[i].name);
904 l->next = al(TSTRING);
906 l->store.u.string = strnode(m->seg[i].file ? m->seg[i].file : "");
910 l->store.u.ival = m->seg[i].base;
914 l->store.u.ival = m->seg[i].base + m->seg[i].size;
918 l->store.u.ival = m->seg[i].offset;
925 map(Node *r, Node *args)
931 Node *av[Maxarg], res;
938 if(res.type != TLIST)
939 error("map(list): map needs a list");
940 if(listlen(res.store.u.l) != 5)
941 error("map(list): list must have 5 entries");
944 if(l->type != TSTRING)
945 error("map name must be a string");
946 nam = l->store.u.string->string;
948 if(l->type != TSTRING)
949 error("map file must be a string");
950 fil = l->store.u.string->string;
952 i = findseg(m, nam, fil);
955 i = findseg(m, nam, fil);
958 error("%s %s is not a map entry", nam, fil);
961 error("map entry not int");
962 m->seg[i].base = l->store.u.ival;
964 if (strcmp(ent, "text") == 0)
965 textseg(l->store.u.ival, &fhdr);
969 error("map entry not int");
970 m->seg[i].size = l->store.u.ival - m->seg[i].base;
973 error("map entry not int");
974 m->seg[i].offset = l->store.u.ival;
980 r->store.u.l = mapent(symmap);
982 if(r->store.u.l == 0)
983 r->store.u.l = mapent(cormap);
985 for(l = r->store.u.l; l->next; l = l->next)
987 l->next = mapent(cormap);
993 flatten(Node **av, Node *n)
1000 flatten(av, n->left);
1001 flatten(av, n->right);
1006 error("too many function arguments");
1019 straceregrw(Regs *regs, char *name, ulong *val, int isr)
1024 werrstr("saved registers cannot be written");
1027 for(i=0; i<nsregs; i++)
1028 if(strcmp(sregs[i].name, name) == 0){
1029 *val = sregs[i].val;
1032 return rget(acidregs, name, val);
1036 strace(Node *r, Node *args)
1038 Node *av[Maxarg], res;
1046 error("strace(list): want one arg");
1049 if(res.type != TLIST)
1050 error("strace(list): strace needs a list");
1053 error("strace(list): strace needs an even-length list");
1054 for(nsregs=0; l; nsregs++){
1055 if(l->type != TSTRING)
1056 error("strace({r,v,r,v,...}): non-string name");
1057 sregs[nsregs].name = l->store.u.string->string;
1058 if(regdesc(sregs[nsregs].name) == nil)
1059 error("strace: bad register '%s'", sregs[nsregs].name);
1063 error("cannot happen in strace");
1065 error("strace: non-int value for %s", sregs[nsregs].name);
1066 sregs[nsregs].val = l->store.u.ival;
1069 regs.rw = straceregrw;
1072 if(stacktrace(cormap, ®s, trlist) <= 0)
1073 error("no stack frame");
1075 r->store.u.l = tracelist;
1085 regexp(Node *r, Node *args)
1094 error("regexp(pattern, string): arg count");
1096 if(res.type != TSTRING)
1097 error("regexp(pattern, string): pattern must be string");
1098 rp = regcomp(res.store.u.string->string);
1103 if(res.type != TSTRING)
1104 error("regexp(pattern, string): bad string");
1108 r->store.u.ival = regexec(rp, res.store.u.string->string, 0, 0);
1112 char vfmt[] = "aBbcCdDfFgGiIoOqQrRsSuUVxXYZ";
1115 fmt(Node *r, Node *args)
1123 error("fmt(obj, fmt): arg count");
1125 if(res.type != TINT || strchr(vfmt, res.store.u.ival) == 0)
1126 error("fmt(obj, fmt): bad format '%c'", (char)res.store.u.ival);
1128 r->store.fmt = res.store.u.ival;
1132 patom(char type, Store *res)
1136 extern char *typenames[];
1141 if(res->u.reg.thread)
1142 Bprint(bout, "register(\"%s\", %#ux)", res->u.reg.name, res->u.reg.thread);
1144 Bprint(bout, "register(\"%s\")", res->u.reg.name);
1147 Bprint(bout, "refconst(");
1149 patom(n->type, &n->store);
1180 Bprint(bout, "*%s\\%c*", typenames[(uchar)type], res->fmt);
1202 Bprint(bout, "%c", (int)res->u.ival);
1205 if(res->u.ival < ' ' || res->u.ival >= 0x7f)
1206 Bprint(bout, "%3d", (int)res->u.ival&0xff);
1208 Bprint(bout, "%3c", (int)res->u.ival);
1211 Bprint(bout, "%C", (int)res->u.ival);
1214 memset(buf, '0', 34);
1216 for(i = 0; i < 32; i++) {
1217 if(res->u.ival & (1<<i))
1221 Bprint(bout, "%s", buf);
1224 Bprint(bout, "%#.2x", (int)res->u.ival&0xff);
1227 Bprint(bout, "%#.8lux", (ulong)res->u.ival);
1230 Bprint(bout, "%#.4lux", (ulong)res->u.ival&0xffff);
1233 Bprint(bout, "%#.16llux", res->u.ival);
1236 Bprint(bout, "%d", (int)res->u.ival);
1239 Bprint(bout, "%d", (ushort)res->u.ival);
1242 Bprint(bout, "%d", (int)res->u.ival&0xffff);
1245 Bprint(bout, "%lud", (ulong)res->u.ival);
1248 Bprint(bout, "%llud", res->u.ival);
1251 Bprint(bout, "%lld", res->u.ival);
1254 Bprint(bout, "%#.16llux", res->u.ival);
1257 Bprint(bout, "%#.11uo", (int)res->u.ival&0xffff);
1260 Bprint(bout, "%#.6uo", (int)res->u.ival);
1263 Bprint(bout, "%#.11o", (short)(res->u.ival&0xffff));
1266 Bprint(bout, "%#.6o", (int)res->u.ival);
1270 Bprint(bout, "%g", res->u.fval);
1275 Bwrite(bout, res->u.string->string, res->u.string->len);
1278 Bprint(bout, "%S", (Rune*)res->u.string->string);
1282 symoff(buf, sizeof(buf), res->u.ival, CANY);
1283 Bprint(bout, "%s", buf);
1287 if (symmap == nil || (*mach->das)(symmap, res->u.ival, res->fmt, buf, sizeof(buf)) < 0)
1288 Bprint(bout, "no instruction");
1290 Bprint(bout, "%s", buf);
1305 if(res->fmt == 'c'){
1306 Bprint(bout, "\'%c\'", (int)res->u.ival);
1308 }else if(res->fmt == 'r'){
1309 Bprint(bout, "\'%C\'", (int)res->u.ival);
1314 patom(l->type, &l->store);
1318 patom(l->type, &l->store);
1322 blprint(l->store.u.l);
1325 pcode(l->store.u.cc, 0);
1341 if(res.store.fmt != 'a' && res.store.fmt != 'A')
1344 if(res.store.comt == 0 || res.store.comt->base == 0)
1347 sl = res.store.comt->base;
1351 n = an(ONAME, ZN, ZN);
1353 n = an(OCALL, n, &res);
1358 print("(%s)", sl->name);
1363 bprint(Node *r, Node *args)
1366 Node res, *av[Maxarg];
1372 for(i = 0; i < nas; i++) {
1378 patom(res.type, &res.store);
1381 pcode(res.store.u.cc, 0);
1384 blprint(res.store.u.l);
1393 printto(Node *r, Node *args)
1398 Node res, *av[Maxarg];
1406 if(res.type != TSTRING)
1407 error("printto(string, ...): need string");
1409 fd = create(res.store.u.string->string, OWRITE, 0666);
1411 fd = open(res.store.u.string->string, OWRITE);
1413 error("printto: open %s: %r", res.store.u.string->string);
1415 b = gmalloc(sizeof(Biobuf));
1416 Binit(b, fd, OWRITE);
1422 for(i = 1; i < nas; i++) {
1428 patom(res.type, &res.store);
1431 blprint(res.store.u.l);
1445 pcfile(Node *r, Node *args)
1451 error("pcfile(addr): arg count");
1453 if(res.type != TINT)
1454 error("pcfile(addr): arg type");
1458 if(fileline(res.store.u.ival, buf, sizeof(buf)) < 0) {
1459 r->store.u.string = strnode("?file?");
1462 p = strrchr(buf, ':');
1464 error("pcfile(addr): funny file %s", buf);
1466 r->store.u.string = strnode(buf);
1470 pcline(Node *r, Node *args)
1476 error("pcline(addr): arg count");
1478 if(res.type != TINT)
1479 error("pcline(addr): arg type");
1483 if(fileline(res.store.u.ival, buf, sizeof(buf)) < 0) {
1484 r->store.u.ival = 0;
1488 p = strrchr(buf, ':');
1490 error("pcline(addr): funny file %s", buf);
1491 r->store.u.ival = atoi(p+1);
1495 textfile(Node *r, Node *args)
1500 Node res, *av[Maxarg];
1501 List *l, *l2, **tail, *list, *tl;
1508 if(res.type != TLIST)
1509 error("textfile(list): textfile needs a list");
1510 if(listlen(res.store.u.l) != 2)
1511 error("textfile(list): list must have 2 entries");
1514 if(l->type != TSTRING)
1515 error("textfile name must be a string");
1516 file = l->store.u.string->string;
1520 error("textfile base must be an int");
1521 base = l->store.u.ival;
1523 if((fp = crackhdr(file, OREAD)) == nil)
1524 error("crackhdr %s: %r", file);
1527 fprint(2, "%s: %s %s %s\n", file, fp->aname, fp->mname, fp->fname);
1528 if(mapfile(fp, base, symmap, nil) < 0)
1529 fprint(2, "mapping %s: %r\n", file);
1531 unmapfile(corhdr, cormap);
1532 mapfile(fp, base, cormap, nil);
1535 mapfile(corhdr, 0, cormap, &correg);
1538 fprint(2, "symopen %s: %r\n", file);
1546 for(fp=fhdrlist; fp; fp=fp->next){
1547 if(fp->ftype == FCORE)
1554 tl->store.u.l = list;
1555 list->store.u.string = strnode(fp->filename);
1556 list->store.fmt = 's';
1557 list->next = al(TINT);
1559 list->store.fmt = 'X';
1560 list->store.u.ival = fp->base;
1568 deltextfile(Node *r, Node *args)
1573 Node res, *av[Maxarg];
1579 error("deltextfile(string): arg count");
1582 if(res.type != TSTRING)
1583 error("deltextfile(string): arg type");
1584 file = res.store.u.string->string;
1587 for(fp=fhdrlist; fp; fp=fpnext){
1589 if(fp->ftype == FCORE)
1591 if(strcmp(file, fp->filename) == 0){
1594 error("cannot remove symbols from main text file");
1595 unmapfile(fp, symmap);
1602 error("symbol file %s not open", file);
1606 stringn(Node *r, Node *args)
1610 Node res, *av[Maxarg];
1616 error("stringn(addr, n): arg count");
1619 if(res.type != TINT)
1620 error("stringn(addr, n): arg type");
1621 addr = res.store.u.ival;
1624 if(res.type != TINT)
1625 error("stringn(addr,n): arg type");
1626 n = res.store.u.ival;
1630 error("out of memory");
1634 ret = get1(cormap, addr, (uchar*)&buf[i], 1);
1642 r->store.u.string = strnode(buf);