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 waitsyscall(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*);
50 void step1(Node*, Node*);
52 typedef struct Btab Btab;
56 void (*fn)(Node*, Node*);
62 "deltextfile", deltextfile,
70 "includepipe", includepipe,
71 "interpret", interpret,
86 "register", xregister,
89 "startstop", startstop,
98 "waitsyscall", waitsyscall,
105 prnt = malloc(sizeof(Node));
106 memset(prnt, 0, sizeof(Node));
108 prnt->left = malloc(sizeof(Node));
109 memset(prnt->left, 0, sizeof(Node));
123 s = enter(b->name, Tid);
133 match(Node *r, Node *args)
143 error("match(obj, list): arg count");
146 if(resl.type != TLIST)
147 error("match(obj, list): need list");
153 r->store.u.ival = -1;
156 for(f = resl.store.u.l; f; f = f->next) {
157 if(resi.type == f->type) {
160 if(resi.store.u.ival == f->store.u.ival) {
166 if(resi.store.u.fval == f->store.u.fval) {
172 if(scmp(resi.store.u.string, f->store.u.string)) {
178 error("match(obj, list): not defined for list");
186 newproc(Node *r, Node *args)
191 char *argv[Maxarg], buf[Strsize];
198 if(res.type != TSTRING)
199 error("newproc(): arg not string");
200 if(res.store.u.string->len >= sizeof(buf))
201 error("newproc(): too many arguments");
202 memmove(buf, res.store.u.string->string, res.store.u.string->len);
203 buf[res.store.u.string->len] = '\0';
205 e = buf+res.store.u.string->len;
207 while(p < e && (*p == '\t' || *p == ' '))
213 error("newproc: too many arguments");
214 while(p < e && *p != '\t' && *p != ' ')
222 r->store.u.ival = nproc(argv);
226 step1(Node *r, Node *args)
232 error("step1(pid): no pid");
235 error("step1(pid): arg type");
237 msg(res.store.u.ival, "step");
238 notes(res.store.u.ival);
239 dostop(res.store.u.ival);
243 startstop(Node *r, Node *args)
249 error("startstop(pid): no pid");
252 error("startstop(pid): arg type");
254 msg(res.store.u.ival, "startstop");
255 notes(res.store.u.ival);
256 dostop(res.store.u.ival);
260 waitstop(Node *r, Node *args)
266 error("waitstop(pid): no pid");
269 error("waitstop(pid): arg type");
272 msg(res.store.u.ival, "waitstop");
273 notes(res.store.u.ival);
274 dostop(res.store.u.ival);
278 waitsyscall(Node *r, Node *args)
284 error("waitsyscall(pid): no pid");
287 error("waitsycall(pid): arg type");
290 msg(res.store.u.ival, "sysstop");
291 notes(res.store.u.ival);
292 dostop(res.store.u.ival);
296 start(Node *r, Node *args)
302 error("start(pid): no pid");
305 error("start(pid): arg type");
307 msg(res.store.u.ival, "start");
311 stop(Node *r, Node *args)
317 error("stop(pid): no pid");
320 error("stop(pid): arg type");
323 msg(res.store.u.ival, "stop");
324 notes(res.store.u.ival);
325 dostop(res.store.u.ival);
329 xkill(Node *r, Node *args)
335 error("kill(pid): no pid");
338 error("kill(pid): arg type");
340 msg(res.store.u.ival, "kill");
341 deinstall(res.store.u.ival);
345 xregister(Node *r, Node *args)
354 if(na != 1/* && na != 2 */)
355 error("register(name): arg count");
358 if(res.type != TSTRING)
359 error("register(name): arg type: name should be string");
363 if(resid.type != TINT)
364 error("register(name[, threadid]): arg type: threadid should be int");
365 tid = resid.store.u.ival;
367 if((rp = regdesc(res.store.u.string->string)) == nil)
368 error("no such register");
371 r->store.fmt = rp->format;
372 r->store.u.reg.name = rp->name;
373 r->store.u.reg.thread = tid;
377 refconst(Node *r, Node *args)
382 error("refconst(expr): arg count");
384 n = an(OCONST, ZN, ZN);
393 dolook(Node *r, Node *args)
399 error("var(string): arg count");
401 if(res.type != TSTRING)
402 error("var(string): arg type");
405 if((l = look(res.store.u.string->string)) == nil || l->v->set == 0){
409 r->type = l->v->type;
410 r->store = l->v->store;
415 status(Node *r, Node *args)
422 error("status(pid): no pid");
425 error("status(pid): arg type");
427 p = getstatus(res.store.u.ival);
428 r->store.u.string = strnode(p);
435 reason(Node *r, Node *args)
440 error("reason(cause): no cause");
443 error("reason(cause): arg type");
448 r->store.u.string = strnode((*mach->exc)(cormap, acidregs));
452 follow(Node *r, Node *args)
460 error("follow(addr): no addr");
463 error("follow(addr): arg type");
465 n = (*mach->foll)(cormap, acidregs, res.store.u.ival, f);
467 error("follow(addr): %r");
468 tail = &r->store.u.l;
469 for(i = 0; i < n; i++) {
471 l->store.u.ival = f[i];
479 funcbound(Node *r, Node *args)
487 error("fnbound(addr): no addr");
490 error("fnbound(addr): arg type");
492 n = fnbound(res.store.u.ival, bounds);
494 r->store.u.l = al(TINT);
496 l->store.u.ival = bounds[0];
500 l->store.u.ival = bounds[1];
506 setproc(Node *r, Node *args)
512 error("setproc(pid): no pid");
515 error("setproc(pid): arg type");
517 sproc(res.store.u.ival);
521 filepc(Node *r, Node *args)
529 error("filepc(filename:line): arg count");
531 if(res.type != TSTRING)
532 error("filepc(filename:line): arg type");
534 p = strchr(res.store.u.string->string, ':');
536 error("filepc(filename:line): bad arg format");
540 i = file2pc(res.store.u.string->string, atoi(p), &v);
543 error("filepc(filename:line): can't find address");
552 interpret(Node *r, Node *args)
558 error("interpret(string): arg count");
560 if(res.type != TSTRING)
561 error("interpret(string): arg type");
567 r->store.u.ival = yyparse();
576 include(Node *r, Node *args)
578 char *file, *libfile;
579 static char buf[1024];
584 error("include(string): arg count");
586 if(res.type != TSTRING)
587 error("include(string): arg type");
592 file = res.store.u.string->string;
593 if(access(file, AREAD) < 0 && file[0] != '/'){
594 snprint(buf, sizeof buf, "#9/acid/%s", file);
595 libfile = unsharp(buf);
596 if(access(libfile, AREAD) >= 0){
597 strecpy(buf, buf+sizeof buf, libfile);
606 r->store.u.ival = yyparse();
615 includepipe(Node *r, Node *args)
618 int i, isave, pid, pip[2];
624 error("includepipe(string): arg count");
626 if(res.type != TSTRING)
627 error("includepipe(string): arg type");
633 argv[2] = res.store.u.string->string;
648 open("/dev/null", OREAD);
655 sysfatal("exec rc: %r");
663 r->store.u.ival = yyparse();
672 if(w->msg && w->msg[0])
673 error("includepipe(\"%s\"): %s", argv[2], w->msg); /* leaks w */
678 rc(Node *r, Node *args)
682 char *p, *q, *argv[4];
687 error("rc(string): arg count");
689 if(res.type != TSTRING)
690 error("rc(string): arg type");
694 argv[2] = res.store.u.string->string;
715 r->store.u.string = strnode(p);
721 doerror(Node *r, Node *args)
727 error("error(string): arg count");
729 if(res.type != TSTRING)
730 error("error(string): arg type");
732 error(res.store.u.string->string);
736 doaccess(Node *r, Node *args)
741 error("access(filename): arg count");
743 if(res.type != TSTRING)
744 error("access(filename): arg type");
750 if(access(res.store.u.string->string, 4) == 0)
755 readfile(Node *r, Node *args)
763 error("readfile(filename): arg count");
765 if(res.type != TSTRING)
766 error("readfile(filename): arg type");
768 fd = open(res.store.u.string->string, OREAD);
773 if(db == nil || db->length == 0)
780 n = read(fd, buf, n);
785 r->store.u.string = strnodlen(buf, n);
793 getfile(Node *r, Node *args)
803 error("file(filename): arg count");
805 if(res.type != TSTRING)
806 error("file(filename): arg type");
812 p = res.store.u.string->string;
813 bp = Bopen(p, OREAD);
819 p = Brdline(bp, '\n');
825 Bread(bp, s->string, n);
828 s = strnodlen(p, n-1);
831 new->store.u.string = s;
832 new->store.fmt = 's';
840 cvtatof(Node *r, Node *args)
845 error("atof(string): arg count");
847 if(res.type != TSTRING)
848 error("atof(string): arg type");
852 r->store.u.fval = atof(res.store.u.string->string);
857 cvtatoi(Node *r, Node *args)
862 error("atoi(string): arg count");
864 if(res.type != TSTRING)
865 error("atoi(string): arg type");
869 r->store.u.ival = strtoul(res.store.u.string->string, 0, 0);
874 cvtitoa(Node *r, Node *args)
883 error("itoa(number [, printformat]): arg count");
886 if(na == 0 || na > 2)
890 error("itoa(integer): arg type");
891 ival = (int)res.store.u.ival;
895 if(res.type != TSTRING)
896 error("itoa(integer, string): arg type");
897 fmt = res.store.u.string->string;
900 sprint(buf, fmt, ival);
903 r->store.u.string = strnode(buf);
911 List *l, *n, **t, *h;
915 for(i = 0; i < m->nseg; i++) {
921 l->store.u.string = strnode(m->seg[i].name);
923 l->next = al(TSTRING);
925 l->store.u.string = strnode(m->seg[i].file ? m->seg[i].file : "");
929 l->store.u.ival = m->seg[i].base;
933 l->store.u.ival = m->seg[i].base + m->seg[i].size;
937 l->store.u.ival = m->seg[i].offset;
944 map(Node *r, Node *args)
950 Node *av[Maxarg], res;
957 if(res.type != TLIST)
958 error("map(list): map needs a list");
959 if(listlen(res.store.u.l) != 5)
960 error("map(list): list must have 5 entries");
963 if(l->type != TSTRING)
964 error("map name must be a string");
965 nam = l->store.u.string->string;
967 if(l->type != TSTRING)
968 error("map file must be a string");
969 fil = l->store.u.string->string;
971 i = findseg(m, nam, fil);
974 i = findseg(m, nam, fil);
977 error("%s %s is not a map entry", nam, fil);
980 error("map entry not int");
981 m->seg[i].base = l->store.u.ival;
983 if (strcmp(ent, "text") == 0)
984 textseg(l->store.u.ival, &fhdr);
988 error("map entry not int");
989 m->seg[i].size = l->store.u.ival - m->seg[i].base;
992 error("map entry not int");
993 m->seg[i].offset = l->store.u.ival;
999 r->store.u.l = mapent(symmap);
1001 if(r->store.u.l == 0)
1002 r->store.u.l = mapent(cormap);
1004 for(l = r->store.u.l; l->next; l = l->next)
1006 l->next = mapent(cormap);
1012 flatten(Node **av, Node *n)
1019 flatten(av, n->left);
1020 flatten(av, n->right);
1025 error("too many function arguments");
1038 straceregrw(Regs *regs, char *name, ulong *val, int isr)
1043 werrstr("saved registers cannot be written");
1046 for(i=0; i<nsregs; i++)
1047 if(strcmp(sregs[i].name, name) == 0){
1048 *val = sregs[i].val;
1051 return rget(acidregs, name, val);
1055 strace(Node *r, Node *args)
1057 Node *av[Maxarg], res;
1065 error("strace(list): want one arg");
1068 if(res.type != TLIST)
1069 error("strace(list): strace needs a list");
1072 error("strace(list): strace needs an even-length list");
1073 for(nsregs=0; l; nsregs++){
1074 if(l->type != TSTRING)
1075 error("strace({r,v,r,v,...}): non-string name");
1076 sregs[nsregs].name = l->store.u.string->string;
1077 if(regdesc(sregs[nsregs].name) == nil)
1078 error("strace: bad register '%s'", sregs[nsregs].name);
1082 error("cannot happen in strace");
1084 error("strace: non-int value for %s", sregs[nsregs].name);
1085 sregs[nsregs].val = l->store.u.ival;
1088 regs.rw = straceregrw;
1091 if(stacktrace(cormap, ®s, trlist) <= 0)
1092 error("no stack frame");
1094 r->store.u.l = tracelist;
1104 regexp(Node *r, Node *args)
1113 error("regexp(pattern, string): arg count");
1115 if(res.type != TSTRING)
1116 error("regexp(pattern, string): pattern must be string");
1117 rp = regcomp(res.store.u.string->string);
1122 if(res.type != TSTRING)
1123 error("regexp(pattern, string): bad string");
1127 r->store.u.ival = regexec(rp, res.store.u.string->string, 0, 0);
1131 char vfmt[] = "aBbcCdDfFgGiIoOqQrRsSuUVxXYZ";
1134 fmt(Node *r, Node *args)
1142 error("fmt(obj, fmt): arg count");
1144 if(res.type != TINT || strchr(vfmt, res.store.u.ival) == 0)
1145 error("fmt(obj, fmt): bad format '%c'", (char)res.store.u.ival);
1147 r->store.fmt = res.store.u.ival;
1151 patom(char type, Store *res)
1155 extern char *typenames[];
1160 if(res->u.reg.thread)
1161 Bprint(bout, "register(\"%s\", %#ux)", res->u.reg.name, res->u.reg.thread);
1163 Bprint(bout, "register(\"%s\")", res->u.reg.name);
1166 Bprint(bout, "refconst(");
1168 patom(n->type, &n->store);
1199 Bprint(bout, "*%s\\%c*", typenames[(uchar)type], res->fmt);
1221 Bprint(bout, "%c", (int)res->u.ival);
1224 if(res->u.ival < ' ' || res->u.ival >= 0x7f)
1225 Bprint(bout, "%3d", (int)res->u.ival&0xff);
1227 Bprint(bout, "%3c", (int)res->u.ival);
1230 Bprint(bout, "%C", (int)res->u.ival);
1233 memset(buf, '0', 34);
1235 for(i = 0; i < 32; i++) {
1236 if(res->u.ival & (1<<i))
1240 Bprint(bout, "%s", buf);
1243 Bprint(bout, "%#.2x", (int)res->u.ival&0xff);
1246 Bprint(bout, "%#.8lux", (ulong)res->u.ival);
1249 Bprint(bout, "%#.4lux", (ulong)res->u.ival&0xffff);
1252 Bprint(bout, "%#.16llux", res->u.ival);
1255 Bprint(bout, "%d", (int)res->u.ival);
1258 Bprint(bout, "%d", (ushort)res->u.ival);
1261 Bprint(bout, "%d", (int)res->u.ival&0xffff);
1264 Bprint(bout, "%lud", (ulong)res->u.ival);
1267 Bprint(bout, "%llud", res->u.ival);
1270 Bprint(bout, "%lld", res->u.ival);
1273 Bprint(bout, "%#.16llux", res->u.ival);
1276 Bprint(bout, "%#.11uo", (int)res->u.ival&0xffff);
1279 Bprint(bout, "%#.6uo", (int)res->u.ival);
1282 Bprint(bout, "%#.11o", (short)(res->u.ival&0xffff));
1285 Bprint(bout, "%#.6o", (int)res->u.ival);
1289 Bprint(bout, "%g", res->u.fval);
1294 Bwrite(bout, res->u.string->string, res->u.string->len);
1297 Bprint(bout, "%S", (Rune*)res->u.string->string);
1301 symoff(buf, sizeof(buf), res->u.ival, CANY);
1302 Bprint(bout, "%s", buf);
1306 if (symmap == nil || (*mach->das)(symmap, res->u.ival, res->fmt, buf, sizeof(buf)) < 0)
1307 Bprint(bout, "no instruction");
1309 Bprint(bout, "%s", buf);
1324 if(res->fmt == 'c'){
1325 Bprint(bout, "\'%c\'", (int)res->u.ival);
1327 }else if(res->fmt == 'r'){
1328 Bprint(bout, "\'%C\'", (int)res->u.ival);
1333 patom(l->type, &l->store);
1337 patom(l->type, &l->store);
1341 blprint(l->store.u.l);
1344 pcode(l->store.u.cc, 0);
1360 if(res.store.fmt != 'a' && res.store.fmt != 'A')
1363 if(res.store.comt == 0 || res.store.comt->base == 0)
1366 sl = res.store.comt->base;
1370 n = an(ONAME, ZN, ZN);
1372 n = an(OCALL, n, &res);
1377 print("(%s)", sl->name);
1382 bprint(Node *r, Node *args)
1385 Node res, *av[Maxarg];
1391 for(i = 0; i < nas; i++) {
1397 patom(res.type, &res.store);
1400 pcode(res.store.u.cc, 0);
1403 blprint(res.store.u.l);
1412 printto(Node *r, Node *args)
1417 Node res, *av[Maxarg];
1425 if(res.type != TSTRING)
1426 error("printto(string, ...): need string");
1428 fd = create(res.store.u.string->string, OWRITE, 0666);
1430 fd = open(res.store.u.string->string, OWRITE);
1432 error("printto: open %s: %r", res.store.u.string->string);
1434 b = gmalloc(sizeof(Biobuf));
1435 Binit(b, fd, OWRITE);
1441 for(i = 1; i < nas; i++) {
1447 patom(res.type, &res.store);
1450 blprint(res.store.u.l);
1464 pcfile(Node *r, Node *args)
1470 error("pcfile(addr): arg count");
1472 if(res.type != TINT)
1473 error("pcfile(addr): arg type");
1477 if(fileline(res.store.u.ival, buf, sizeof(buf)) < 0) {
1478 r->store.u.string = strnode("?file?");
1481 p = strrchr(buf, ':');
1483 error("pcfile(addr): funny file %s", buf);
1485 r->store.u.string = strnode(buf);
1489 pcline(Node *r, Node *args)
1495 error("pcline(addr): arg count");
1497 if(res.type != TINT)
1498 error("pcline(addr): arg type");
1502 if(fileline(res.store.u.ival, buf, sizeof(buf)) < 0) {
1503 r->store.u.ival = 0;
1507 p = strrchr(buf, ':');
1509 error("pcline(addr): funny file %s", buf);
1510 r->store.u.ival = atoi(p+1);
1514 textfile(Node *r, Node *args)
1519 Node res, *av[Maxarg];
1520 List *l, *l2, **tail, *list, *tl;
1527 if(res.type != TLIST)
1528 error("textfile(list): textfile needs a list");
1529 if(listlen(res.store.u.l) != 2)
1530 error("textfile(list): list must have 2 entries");
1533 if(l->type != TSTRING)
1534 error("textfile name must be a string");
1535 file = l->store.u.string->string;
1539 error("textfile base must be an int");
1540 base = l->store.u.ival;
1542 if((fp = crackhdr(file, OREAD)) == nil)
1543 error("crackhdr %s: %r", file);
1546 fprint(2, "%s: %s %s %s\n", file, fp->aname, fp->mname, fp->fname);
1547 if(mapfile(fp, base, symmap, nil) < 0)
1548 fprint(2, "mapping %s: %r\n", file);
1550 unmapfile(corhdr, cormap);
1551 mapfile(fp, base, cormap, nil);
1554 mapfile(corhdr, 0, cormap, &correg);
1557 fprint(2, "symopen %s: %r\n", file);
1565 for(fp=fhdrlist; fp; fp=fp->next){
1566 if(fp->ftype == FCORE)
1573 tl->store.u.l = list;
1574 list->store.u.string = strnode(fp->filename);
1575 list->store.fmt = 's';
1576 list->next = al(TINT);
1578 list->store.fmt = 'X';
1579 list->store.u.ival = fp->base;
1587 deltextfile(Node *r, Node *args)
1592 Node res, *av[Maxarg];
1598 error("deltextfile(string): arg count");
1601 if(res.type != TSTRING)
1602 error("deltextfile(string): arg type");
1603 file = res.store.u.string->string;
1606 for(fp=fhdrlist; fp; fp=fpnext){
1608 if(fp->ftype == FCORE)
1610 if(strcmp(file, fp->filename) == 0){
1613 error("cannot remove symbols from main text file");
1614 unmapfile(fp, symmap);
1621 error("symbol file %s not open", file);
1625 stringn(Node *r, Node *args)
1629 Node res, *av[Maxarg];
1635 error("stringn(addr, n): arg count");
1638 if(res.type != TINT)
1639 error("stringn(addr, n): arg type");
1640 addr = res.store.u.ival;
1643 if(res.type != TINT)
1644 error("stringn(addr,n): arg type");
1645 n = res.store.u.ival;
1649 error("out of memory");
1653 ret = get1(cormap, addr, (uchar*)&buf[i], 1);
1661 r->store.u.string = strnode(buf);