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)
332 error("register(string): arg count");
334 if(res.type != TSTRING)
335 error("register(string): arg type");
337 if((rp = regdesc(res.store.u.string->string)) == nil)
338 error("no such register");
342 r->store.fmt = rp->format;
343 r->store.u.reg = rp->name;
347 refconst(Node *r, Node *args)
352 error("refconst(expr): arg count");
354 n = an(OCONST, ZN, ZN);
363 dolook(Node *r, Node *args)
369 error("var(string): arg count");
371 if(res.type != TSTRING)
372 error("var(string): arg type");
375 if((l = look(res.store.u.string->string)) == nil || l->v->set == 0){
379 r->type = l->v->type;
380 r->store = l->v->store;
385 status(Node *r, Node *args)
392 error("status(pid): no pid");
395 error("status(pid): arg type");
397 p = getstatus(res.store.u.ival);
398 r->store.u.string = strnode(p);
405 reason(Node *r, Node *args)
410 error("reason(cause): no cause");
413 error("reason(cause): arg type");
418 r->store.u.string = strnode((*mach->exc)(cormap, acidregs));
422 follow(Node *r, Node *args)
430 error("follow(addr): no addr");
433 error("follow(addr): arg type");
435 n = (*mach->foll)(cormap, acidregs, res.store.u.ival, f);
437 error("follow(addr): %r");
438 tail = &r->store.u.l;
439 for(i = 0; i < n; i++) {
441 l->store.u.ival = f[i];
449 funcbound(Node *r, Node *args)
457 error("fnbound(addr): no addr");
460 error("fnbound(addr): arg type");
462 n = fnbound(res.store.u.ival, bounds);
464 r->store.u.l = al(TINT);
466 l->store.u.ival = bounds[0];
470 l->store.u.ival = bounds[1];
476 setproc(Node *r, Node *args)
482 error("setproc(pid): no pid");
485 error("setproc(pid): arg type");
487 sproc(res.store.u.ival);
491 filepc(Node *r, Node *args)
499 error("filepc(filename:line): arg count");
501 if(res.type != TSTRING)
502 error("filepc(filename:line): arg type");
504 p = strchr(res.store.u.string->string, ':');
506 error("filepc(filename:line): bad arg format");
510 i = file2pc(res.store.u.string->string, atoi(p), &v);
513 error("filepc(filename:line): can't find address");
522 interpret(Node *r, Node *args)
528 error("interpret(string): arg count");
530 if(res.type != TSTRING)
531 error("interpret(string): arg type");
537 r->store.u.ival = yyparse();
546 include(Node *r, Node *args)
548 char *file, *libfile;
549 static char buf[1024];
554 error("include(string): arg count");
556 if(res.type != TSTRING)
557 error("include(string): arg type");
562 file = res.store.u.string->string;
563 if(access(file, AREAD) < 0 && file[0] != '/'){
564 snprint(buf, sizeof buf, "#9/acid/%s", file);
565 libfile = unsharp(buf);
566 if(access(libfile, AREAD) >= 0){
567 strecpy(buf, buf+sizeof buf, libfile);
576 r->store.u.ival = yyparse();
585 includepipe(Node *r, Node *args)
588 int i, isave, pid, pip[2];
594 error("includepipe(string): arg count");
596 if(res.type != TSTRING)
597 error("includepipe(string): arg type");
603 argv[2] = res.store.u.string->string;
618 open("/dev/null", OREAD);
625 sysfatal("exec rc: %r");
633 r->store.u.ival = yyparse();
642 if(w->msg && w->msg[0])
643 error("includepipe(\"%s\"): %s", argv[2], w->msg); /* leaks w */
648 rc(Node *r, Node *args)
652 char *p, *q, *argv[4];
657 error("rc(string): arg count");
659 if(res.type != TSTRING)
660 error("rc(string): arg type");
664 argv[2] = res.store.u.string->string;
685 r->store.u.string = strnode(p);
691 doerror(Node *r, Node *args)
697 error("error(string): arg count");
699 if(res.type != TSTRING)
700 error("error(string): arg type");
702 error(res.store.u.string->string);
706 doaccess(Node *r, Node *args)
711 error("access(filename): arg count");
713 if(res.type != TSTRING)
714 error("access(filename): arg type");
720 if(access(res.store.u.string->string, 4) == 0)
725 readfile(Node *r, Node *args)
733 error("readfile(filename): arg count");
735 if(res.type != TSTRING)
736 error("readfile(filename): arg type");
738 fd = open(res.store.u.string->string, OREAD);
743 if(db == nil || db->length == 0)
750 n = read(fd, buf, n);
755 r->store.u.string = strnodlen(buf, n);
763 getfile(Node *r, Node *args)
773 error("file(filename): arg count");
775 if(res.type != TSTRING)
776 error("file(filename): arg type");
782 p = res.store.u.string->string;
783 bp = Bopen(p, OREAD);
789 p = Brdline(bp, '\n');
795 Bread(bp, s->string, n);
798 s = strnodlen(p, n-1);
801 new->store.u.string = s;
802 new->store.fmt = 's';
810 cvtatof(Node *r, Node *args)
815 error("atof(string): arg count");
817 if(res.type != TSTRING)
818 error("atof(string): arg type");
822 r->store.u.fval = atof(res.store.u.string->string);
827 cvtatoi(Node *r, Node *args)
832 error("atoi(string): arg count");
834 if(res.type != TSTRING)
835 error("atoi(string): arg type");
839 r->store.u.ival = strtoul(res.store.u.string->string, 0, 0);
844 cvtitoa(Node *r, Node *args)
853 error("itoa(number [, printformat]): arg count");
856 if(na == 0 || na > 2)
860 error("itoa(integer): arg type");
861 ival = (int)res.store.u.ival;
865 if(res.type != TSTRING)
866 error("itoa(integer, string): arg type");
867 fmt = res.store.u.string->string;
870 sprint(buf, fmt, ival);
873 r->store.u.string = strnode(buf);
881 List *l, *n, **t, *h;
885 for(i = 0; i < m->nseg; i++) {
891 l->store.u.string = strnode(m->seg[i].name);
893 l->next = al(TSTRING);
895 l->store.u.string = strnode(m->seg[i].file ? m->seg[i].file : "");
899 l->store.u.ival = m->seg[i].base;
903 l->store.u.ival = m->seg[i].base + m->seg[i].size;
907 l->store.u.ival = m->seg[i].offset;
914 map(Node *r, Node *args)
920 Node *av[Maxarg], res;
927 if(res.type != TLIST)
928 error("map(list): map needs a list");
929 if(listlen(res.store.u.l) != 5)
930 error("map(list): list must have 5 entries");
933 if(l->type != TSTRING)
934 error("map name must be a string");
935 nam = l->store.u.string->string;
937 if(l->type != TSTRING)
938 error("map file must be a string");
939 fil = l->store.u.string->string;
941 i = findseg(m, nam, fil);
944 i = findseg(m, nam, fil);
947 error("%s %s is not a map entry", nam, fil);
950 error("map entry not int");
951 m->seg[i].base = l->store.u.ival;
953 if (strcmp(ent, "text") == 0)
954 textseg(l->store.u.ival, &fhdr);
958 error("map entry not int");
959 m->seg[i].size = l->store.u.ival - m->seg[i].base;
962 error("map entry not int");
963 m->seg[i].offset = l->store.u.ival;
969 r->store.u.l = mapent(symmap);
971 if(r->store.u.l == 0)
972 r->store.u.l = mapent(cormap);
974 for(l = r->store.u.l; l->next; l = l->next)
976 l->next = mapent(cormap);
982 flatten(Node **av, Node *n)
989 flatten(av, n->left);
990 flatten(av, n->right);
995 error("too many function arguments");
1008 straceregrw(Regs *regs, char *name, ulong *val, int isr)
1013 werrstr("saved registers cannot be written");
1016 for(i=0; i<nsregs; i++)
1017 if(strcmp(sregs[i].name, name) == 0){
1018 *val = sregs[i].val;
1021 return rget(acidregs, name, val);
1025 strace(Node *r, Node *args)
1027 Node *av[Maxarg], res;
1035 error("strace(list): want one arg");
1038 if(res.type != TLIST)
1039 error("strace(list): strace needs a list");
1042 error("strace(list): strace needs an even-length list");
1043 for(nsregs=0; l; nsregs++){
1044 if(l->type != TSTRING)
1045 error("strace({r,v,r,v,...}): non-string name");
1046 sregs[nsregs].name = l->store.u.string->string;
1047 if(regdesc(sregs[nsregs].name) == nil)
1048 error("strace: bad register '%s'", sregs[nsregs].name);
1052 error("cannot happen in strace");
1054 error("strace: non-int value for %s", sregs[nsregs].name);
1055 sregs[nsregs].val = l->store.u.ival;
1058 regs.rw = straceregrw;
1061 if(stacktrace(cormap, ®s, trlist) <= 0)
1062 error("no stack frame");
1064 r->store.u.l = tracelist;
1074 regexp(Node *r, Node *args)
1083 error("regexp(pattern, string): arg count");
1085 if(res.type != TSTRING)
1086 error("regexp(pattern, string): pattern must be string");
1087 rp = regcomp(res.store.u.string->string);
1092 if(res.type != TSTRING)
1093 error("regexp(pattern, string): bad string");
1097 r->store.u.ival = regexec(rp, res.store.u.string->string, 0, 0);
1101 char vfmt[] = "aBbcCdDfFgGiIoOqQrRsSuUVxXYZ";
1104 fmt(Node *r, Node *args)
1112 error("fmt(obj, fmt): arg count");
1114 if(res.type != TINT || strchr(vfmt, res.store.u.ival) == 0)
1115 error("fmt(obj, fmt): bad format '%c'", (char)res.store.u.ival);
1117 r->store.fmt = res.store.u.ival;
1121 patom(char type, Store *res)
1125 extern char *typenames[];
1130 Bprint(bout, "register(\"%s\")", res->u.reg);
1133 Bprint(bout, "refconst(");
1135 patom(n->type, &n->store);
1166 Bprint(bout, "*%s\\%c*", typenames[(uchar)type], res->fmt);
1188 Bprint(bout, "%c", (int)res->u.ival);
1191 if(res->u.ival < ' ' || res->u.ival >= 0x7f)
1192 Bprint(bout, "%3d", (int)res->u.ival&0xff);
1194 Bprint(bout, "%3c", (int)res->u.ival);
1197 Bprint(bout, "%C", (int)res->u.ival);
1200 memset(buf, '0', 34);
1202 for(i = 0; i < 32; i++) {
1203 if(res->u.ival & (1<<i))
1207 Bprint(bout, "%s", buf);
1210 Bprint(bout, "%.2x", (int)res->u.ival&0xff);
1213 Bprint(bout, "%.8lux", (ulong)res->u.ival);
1216 Bprint(bout, "%.4lux", (ulong)res->u.ival&0xffff);
1219 Bprint(bout, "%.16llux", res->u.ival);
1222 Bprint(bout, "%d", (int)res->u.ival);
1225 Bprint(bout, "%d", (ushort)res->u.ival);
1228 Bprint(bout, "%d", (int)res->u.ival&0xffff);
1231 Bprint(bout, "%lud", (ulong)res->u.ival);
1234 Bprint(bout, "%llud", res->u.ival);
1237 Bprint(bout, "%lld", res->u.ival);
1240 Bprint(bout, "%.16llux", res->u.ival);
1243 Bprint(bout, "0%.11uo", (int)res->u.ival&0xffff);
1246 Bprint(bout, "0%.6uo", (int)res->u.ival);
1249 Bprint(bout, "0%.11o", (short)(res->u.ival&0xffff));
1252 Bprint(bout, "0%.6o", (int)res->u.ival);
1256 Bprint(bout, "%g", res->u.fval);
1261 Bwrite(bout, res->u.string->string, res->u.string->len);
1264 Bprint(bout, "%S", (Rune*)res->u.string->string);
1268 symoff(buf, sizeof(buf), res->u.ival, CANY);
1269 Bprint(bout, "%s", buf);
1273 if (symmap == nil || (*mach->das)(symmap, res->u.ival, res->fmt, buf, sizeof(buf)) < 0)
1274 Bprint(bout, "no instruction");
1276 Bprint(bout, "%s", buf);
1291 if(res->fmt == 'c'){
1292 Bprint(bout, "\'%c\'", (int)res->u.ival);
1294 }else if(res->fmt == 'r'){
1295 Bprint(bout, "\'%C\'", (int)res->u.ival);
1300 patom(l->type, &l->store);
1304 patom(l->type, &l->store);
1308 blprint(l->store.u.l);
1311 pcode(l->store.u.cc, 0);
1327 if(res.store.fmt != 'a' && res.store.fmt != 'A')
1330 if(res.store.comt == 0 || res.store.comt->base == 0)
1333 sl = res.store.comt->base;
1337 n = an(ONAME, ZN, ZN);
1339 n = an(OCALL, n, &res);
1344 print("(%s)", sl->name);
1349 bprint(Node *r, Node *args)
1352 Node res, *av[Maxarg];
1358 for(i = 0; i < nas; i++) {
1364 patom(res.type, &res.store);
1367 pcode(res.store.u.cc, 0);
1370 blprint(res.store.u.l);
1379 printto(Node *r, Node *args)
1384 Node res, *av[Maxarg];
1392 if(res.type != TSTRING)
1393 error("printto(string, ...): need string");
1395 fd = create(res.store.u.string->string, OWRITE, 0666);
1397 fd = open(res.store.u.string->string, OWRITE);
1399 error("printto: open %s: %r", res.store.u.string->string);
1401 b = gmalloc(sizeof(Biobuf));
1402 Binit(b, fd, OWRITE);
1408 for(i = 1; i < nas; i++) {
1414 patom(res.type, &res.store);
1417 blprint(res.store.u.l);
1431 pcfile(Node *r, Node *args)
1437 error("pcfile(addr): arg count");
1439 if(res.type != TINT)
1440 error("pcfile(addr): arg type");
1444 if(fileline(res.store.u.ival, buf, sizeof(buf)) < 0) {
1445 r->store.u.string = strnode("?file?");
1448 p = strrchr(buf, ':');
1450 error("pcfile(addr): funny file %s", buf);
1452 r->store.u.string = strnode(buf);
1456 pcline(Node *r, Node *args)
1462 error("pcline(addr): arg count");
1464 if(res.type != TINT)
1465 error("pcline(addr): arg type");
1469 if(fileline(res.store.u.ival, buf, sizeof(buf)) < 0) {
1470 r->store.u.ival = 0;
1474 p = strrchr(buf, ':');
1476 error("pcline(addr): funny file %s", buf);
1477 r->store.u.ival = atoi(p+1);
1481 textfile(Node *r, Node *args)
1486 Node res, *av[Maxarg];
1487 List *l, *l2, **tail, *list, *tl;
1494 if(res.type != TLIST)
1495 error("textfile(list): textfile needs a list");
1496 if(listlen(res.store.u.l) != 2)
1497 error("textfile(list): list must have 2 entries");
1500 if(l->type != TSTRING)
1501 error("textfile name must be a string");
1502 file = l->store.u.string->string;
1506 error("textfile base must be an int");
1507 base = l->store.u.ival;
1509 if((fp = crackhdr(file, OREAD)) == nil)
1510 error("crackhdr %s: %r", file);
1513 fprint(2, "%s: %s %s %s\n", file, fp->aname, fp->mname, fp->fname);
1514 if(mapfile(fp, base, symmap, nil) < 0)
1515 fprint(2, "mapping %s: %r\n", file);
1517 unmapfile(corhdr, cormap);
1518 mapfile(fp, base, cormap, nil);
1521 mapfile(corhdr, 0, cormap, &correg);
1524 fprint(2, "symopen %s: %r\n", file);
1532 for(fp=fhdrlist; fp; fp=fp->next){
1533 if(fp->ftype == FCORE)
1540 tl->store.u.l = list;
1541 list->store.u.string = strnode(fp->filename);
1542 list->store.fmt = 's';
1543 list->next = al(TINT);
1545 list->store.fmt = 'X';
1546 list->store.u.ival = fp->base;
1554 deltextfile(Node *r, Node *args)
1559 Node res, *av[Maxarg];
1565 error("deltextfile(string): arg count");
1568 if(res.type != TSTRING)
1569 error("deltextfile(string): arg type");
1570 file = res.store.u.string->string;
1573 for(fp=fhdrlist; fp; fp=fpnext){
1575 if(fp->ftype == FCORE)
1577 if(strcmp(file, fp->filename) == 0){
1580 error("cannot remove symbols from main text file");
1581 unmapfile(fp, symmap);
1588 error("symbol file %s not open", file);
1592 stringn(Node *r, Node *args)
1596 Node res, *av[Maxarg];
1602 error("stringn(addr, n): arg count");
1605 if(res.type != TINT)
1606 error("stringn(addr, n): arg type");
1607 addr = res.store.u.ival;
1610 if(res.type != TINT)
1611 error("stringn(addr,n): arg type");
1612 n = res.store.u.ival;
1616 error("out of memory");
1620 ret = get1(cormap, addr, (uchar*)&buf[i], 1);
1628 r->store.u.string = strnode(buf);