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*);
47 typedef struct Btab Btab;
51 void (*fn)(Node*, Node*);
56 "deltextfile", deltextfile,
66 "includepipe", includepipe,
67 "interpret", interpret,
82 "startstop", startstop,
95 prnt = malloc(sizeof(Node));
96 memset(prnt, 0, sizeof(Node));
98 prnt->left = malloc(sizeof(Node));
99 memset(prnt->left, 0, sizeof(Node));
113 s = enter(b->name, Tid);
123 match(Node *r, Node *args)
133 error("match(obj, list): arg count");
136 if(resl.type != TLIST)
137 error("match(obj, list): need list");
143 r->store.u.ival = -1;
146 for(f = resl.store.u.l; f; f = f->next) {
147 if(resi.type == f->type) {
150 if(resi.store.u.ival == f->store.u.ival) {
156 if(resi.store.u.fval == f->store.u.fval) {
162 if(scmp(resi.store.u.string, f->store.u.string)) {
168 error("match(obj, list): not defined for list");
176 newproc(Node *r, Node *args)
181 char *argv[Maxarg], buf[Strsize];
188 if(res.type != TSTRING)
189 error("newproc(): arg not string");
190 if(res.store.u.string->len >= sizeof(buf))
191 error("newproc(): too many arguments");
192 memmove(buf, res.store.u.string->string, res.store.u.string->len);
193 buf[res.store.u.string->len] = '\0';
195 e = buf+res.store.u.string->len;
197 while(p < e && (*p == '\t' || *p == ' '))
203 error("newproc: too many arguments");
204 while(p < e && *p != '\t' && *p != ' ')
212 r->store.u.ival = nproc(argv);
216 startstop(Node *r, Node *args)
222 error("startstop(pid): no pid");
225 error("startstop(pid): arg type");
227 msg(res.store.u.ival, "startstop");
228 notes(res.store.u.ival);
229 dostop(res.store.u.ival);
233 waitstop(Node *r, Node *args)
239 error("waitstop(pid): no pid");
242 error("waitstop(pid): arg type");
245 msg(res.store.u.ival, "waitstop");
246 notes(res.store.u.ival);
247 dostop(res.store.u.ival);
251 sysstop(Node *r, Node *args)
257 error("waitstop(pid): no pid");
260 error("waitstop(pid): arg type");
263 msg(res.store.u.ival, "sysstop");
264 notes(res.store.u.ival);
265 dostop(res.store.u.ival);
269 start(Node *r, Node *args)
275 error("start(pid): no pid");
278 error("start(pid): arg type");
280 msg(res.store.u.ival, "start");
284 stop(Node *r, Node *args)
290 error("stop(pid): no pid");
293 error("stop(pid): arg type");
296 msg(res.store.u.ival, "stop");
297 notes(res.store.u.ival);
298 dostop(res.store.u.ival);
302 xkill(Node *r, Node *args)
308 error("kill(pid): no pid");
311 error("kill(pid): arg type");
313 msg(res.store.u.ival, "kill");
314 deinstall(res.store.u.ival);
318 status(Node *r, Node *args)
325 error("status(pid): no pid");
328 error("status(pid): arg type");
330 p = getstatus(res.store.u.ival);
331 r->store.u.string = strnode(p);
338 reason(Node *r, Node *args)
343 error("reason(cause): no cause");
346 error("reason(cause): arg type");
351 r->store.u.string = strnode((*mach->exc)(cormap, correg));
355 follow(Node *r, Node *args)
363 error("follow(addr): no addr");
366 error("follow(addr): arg type");
368 n = (*mach->foll)(cormap, correg, res.store.u.ival, f);
370 error("follow(addr): %r");
371 tail = &r->store.u.l;
372 for(i = 0; i < n; i++) {
374 l->store.u.ival = f[i];
382 funcbound(Node *r, Node *args)
390 error("fnbound(addr): no addr");
393 error("fnbound(addr): arg type");
395 n = fnbound(res.store.u.ival, bounds);
397 r->store.u.l = al(TINT);
399 l->store.u.ival = bounds[0];
403 l->store.u.ival = bounds[1];
409 setproc(Node *r, Node *args)
415 error("setproc(pid): no pid");
418 error("setproc(pid): arg type");
420 sproc(res.store.u.ival);
424 filepc(Node *r, Node *args)
432 error("filepc(filename:line): arg count");
434 if(res.type != TSTRING)
435 error("filepc(filename:line): arg type");
437 p = strchr(res.store.u.string->string, ':');
439 error("filepc(filename:line): bad arg format");
443 i = file2pc(res.store.u.string->string, atoi(p), &v);
446 error("filepc(filename:line): can't find address");
455 interpret(Node *r, Node *args)
461 error("interpret(string): arg count");
463 if(res.type != TSTRING)
464 error("interpret(string): arg type");
470 r->store.u.ival = yyparse();
479 include(Node *r, Node *args)
481 char *file, *libfile;
482 static char buf[1024];
487 error("include(string): arg count");
489 if(res.type != TSTRING)
490 error("include(string): arg type");
495 file = res.store.u.string->string;
496 if(access(file, AREAD) < 0 && file[0] != '/'){
497 snprint(buf, sizeof buf, "#9/acid/%s", file);
498 libfile = unsharp(buf);
499 if(access(libfile, AREAD) >= 0){
500 strecpy(buf, buf+sizeof buf, libfile);
509 r->store.u.ival = yyparse();
518 includepipe(Node *r, Node *args)
521 int i, isave, pid, pip[2];
527 error("includepipe(string): arg count");
529 if(res.type != TSTRING)
530 error("includepipe(string): arg type");
536 argv[2] = res.store.u.string->string;
551 open("/dev/null", OREAD);
558 sysfatal("exec rc: %r");
566 r->store.u.ival = yyparse();
575 if(w->msg && w->msg[0])
576 error("includepipe(\"%s\"): %s", argv[2], w->msg); /* leaks w */
581 rc(Node *r, Node *args)
585 char *p, *q, *argv[4];
590 error("rc(string): arg count");
592 if(res.type != TSTRING)
593 error("rc(string): arg type");
597 argv[2] = res.store.u.string->string;
618 r->store.u.string = strnode(p);
624 doerror(Node *r, Node *args)
630 error("error(string): arg count");
632 if(res.type != TSTRING)
633 error("error(string): arg type");
635 error(res.store.u.string->string);
639 doaccess(Node *r, Node *args)
644 error("access(filename): arg count");
646 if(res.type != TSTRING)
647 error("access(filename): arg type");
653 if(access(res.store.u.string->string, 4) == 0)
658 readfile(Node *r, Node *args)
666 error("readfile(filename): arg count");
668 if(res.type != TSTRING)
669 error("readfile(filename): arg type");
671 fd = open(res.store.u.string->string, OREAD);
676 if(db == nil || db->length == 0)
683 n = read(fd, buf, n);
688 r->store.u.string = strnodlen(buf, n);
696 getfile(Node *r, Node *args)
706 error("file(filename): arg count");
708 if(res.type != TSTRING)
709 error("file(filename): arg type");
715 p = res.store.u.string->string;
716 bp = Bopen(p, OREAD);
722 p = Brdline(bp, '\n');
728 Bread(bp, s->string, n);
731 s = strnodlen(p, n-1);
734 new->store.u.string = s;
735 new->store.fmt = 's';
743 cvtatof(Node *r, Node *args)
748 error("atof(string): arg count");
750 if(res.type != TSTRING)
751 error("atof(string): arg type");
755 r->store.u.fval = atof(res.store.u.string->string);
760 cvtatoi(Node *r, Node *args)
765 error("atoi(string): arg count");
767 if(res.type != TSTRING)
768 error("atoi(string): arg type");
772 r->store.u.ival = strtoul(res.store.u.string->string, 0, 0);
777 cvtitoa(Node *r, Node *args)
786 error("itoa(number [, printformat]): arg count");
789 if(na == 0 || na > 2)
793 error("itoa(integer): arg type");
794 ival = (int)res.store.u.ival;
798 if(res.type != TSTRING)
799 error("itoa(integer, string): arg type");
800 fmt = res.store.u.string->string;
803 sprint(buf, fmt, ival);
806 r->store.u.string = strnode(buf);
814 List *l, *n, **t, *h;
818 for(i = 0; i < m->nseg; i++) {
824 l->store.u.string = strnode(m->seg[i].name);
826 l->next = al(TSTRING);
828 l->store.u.string = strnode(m->seg[i].file ? m->seg[i].file : "");
832 l->store.u.ival = m->seg[i].base;
836 l->store.u.ival = m->seg[i].base + m->seg[i].size;
840 l->store.u.ival = m->seg[i].offset;
847 map(Node *r, Node *args)
853 Node *av[Maxarg], res;
860 if(res.type != TLIST)
861 error("map(list): map needs a list");
862 if(listlen(res.store.u.l) != 5)
863 error("map(list): list must have 5 entries");
866 if(l->type != TSTRING)
867 error("map name must be a string");
868 nam = l->store.u.string->string;
870 if(l->type != TSTRING)
871 error("map file must be a string");
872 fil = l->store.u.string->string;
874 i = findseg(m, nam, fil);
877 i = findseg(m, nam, fil);
880 error("%s %s is not a map entry", nam, fil);
883 error("map entry not int");
884 m->seg[i].base = l->store.u.ival;
886 if (strcmp(ent, "text") == 0)
887 textseg(l->store.u.ival, &fhdr);
891 error("map entry not int");
892 m->seg[i].size = l->store.u.ival - m->seg[i].base;
895 error("map entry not int");
896 m->seg[i].offset = l->store.u.ival;
902 r->store.u.l = mapent(symmap);
904 if(r->store.u.l == 0)
905 r->store.u.l = mapent(cormap);
907 for(l = r->store.u.l; l->next; l = l->next)
909 l->next = mapent(cormap);
915 flatten(Node **av, Node *n)
922 flatten(av, n->left);
923 flatten(av, n->right);
928 error("too many function arguments");
941 straceregrw(Regs *regs, char *name, ulong *val, int isr)
946 werrstr("saved registers cannot be written");
949 for(i=0; i<nsregs; i++)
950 if(strcmp(sregs[i].name, name) == 0){
954 return rget(correg, name, val);
958 strace(Node *r, Node *args)
960 Node *av[Maxarg], res;
968 error("strace(list): want one arg");
971 if(res.type != TLIST)
972 error("strace(list): strace needs a list");
975 error("strace(list): strace needs an even-length list");
976 for(nsregs=0; l; nsregs++){
977 if(l->type != TSTRING)
978 error("strace({r,v,r,v,...}): non-string name");
979 sregs[nsregs].name = l->store.u.string->string;
980 if(regdesc(sregs[nsregs].name) == nil)
981 error("strace: bad register '%s'", sregs[nsregs].name);
985 error("cannot happen in strace");
987 error("strace: non-int value for %s", sregs[nsregs].name);
988 sregs[nsregs].val = l->store.u.ival;
991 regs.rw = straceregrw;
994 if(stacktrace(cormap, ®s, trlist) <= 0)
995 error("no stack frame");
997 r->store.u.l = tracelist;
1007 regexp(Node *r, Node *args)
1016 error("regexp(pattern, string): arg count");
1018 if(res.type != TSTRING)
1019 error("regexp(pattern, string): pattern must be string");
1020 rp = regcomp(res.store.u.string->string);
1025 if(res.type != TSTRING)
1026 error("regexp(pattern, string): bad string");
1030 r->store.u.ival = regexec(rp, res.store.u.string->string, 0, 0);
1034 char vfmt[] = "aBbcCdDfFgGiIoOqQrRsSuUVxXYZ";
1037 fmt(Node *r, Node *args)
1045 error("fmt(obj, fmt): arg count");
1047 if(res.type != TINT || strchr(vfmt, res.store.u.ival) == 0)
1048 error("fmt(obj, fmt): bad format '%c'", (char)res.store.u.ival);
1050 r->store.fmt = res.store.u.ival;
1054 patom(char type, Store *res)
1058 extern char *typenames[];
1062 Bprint(bout, "%c", (int)res->u.ival);
1065 if(res->u.ival < ' ' || res->u.ival >= 0x7f)
1066 Bprint(bout, "%3d", (int)res->u.ival&0xff);
1068 Bprint(bout, "%3c", (int)res->u.ival);
1071 Bprint(bout, "%C", (int)res->u.ival);
1074 memset(buf, '0', 34);
1076 for(i = 0; i < 32; i++) {
1077 if(res->u.ival & (1<<i))
1081 Bprint(bout, "%s", buf);
1084 Bprint(bout, "%.2x", (int)res->u.ival&0xff);
1087 Bprint(bout, "%.8lux", (ulong)res->u.ival);
1090 Bprint(bout, "%.4lux", (ulong)res->u.ival&0xffff);
1093 Bprint(bout, "%.16llux", res->u.ival);
1096 Bprint(bout, "%d", (int)res->u.ival);
1099 Bprint(bout, "%d", (ushort)res->u.ival);
1102 Bprint(bout, "%d", (int)res->u.ival&0xffff);
1105 Bprint(bout, "%lud", (ulong)res->u.ival);
1108 Bprint(bout, "%llud", res->u.ival);
1111 Bprint(bout, "%lld", res->u.ival);
1114 Bprint(bout, "%.16llux", res->u.ival);
1117 Bprint(bout, "0%.11uo", (int)res->u.ival&0xffff);
1120 Bprint(bout, "0%.6uo", (int)res->u.ival);
1123 Bprint(bout, "0%.11o", (short)(res->u.ival&0xffff));
1126 Bprint(bout, "0%.6o", (int)res->u.ival);
1131 Bprint(bout, "*%c<%s>*", res->fmt, typenames[(uchar)type]);
1133 Bprint(bout, "%g", res->u.fval);
1139 Bprint(bout, "*%c<%s>*", res->fmt, typenames[(uchar)type]);
1141 Bwrite(bout, res->u.string->string, res->u.string->len);
1145 Bprint(bout, "*%c<%s>*", res->fmt, typenames[(uchar)type]);
1147 Bprint(bout, "%S", (Rune*)res->u.string->string);
1151 symoff(buf, sizeof(buf), res->u.ival, CANY);
1152 Bprint(bout, "%s", buf);
1157 Bprint(bout, "*%c<%s>*", res->fmt, typenames[(uchar)type]);
1159 if (symmap == nil || (*mach->das)(symmap, res->u.ival, res->fmt, buf, sizeof(buf)) < 0)
1160 Bprint(bout, "no instruction");
1162 Bprint(bout, "%s", buf);
1178 if(res->fmt == 'c'){
1179 Bprint(bout, "\'%c\'", (int)res->u.ival);
1181 }else if(res->fmt == 'r'){
1182 Bprint(bout, "\'%C\'", (int)res->u.ival);
1187 patom(l->type, &l->store);
1191 patom(l->type, &l->store);
1195 blprint(l->store.u.l);
1198 pcode(l->store.u.cc, 0);
1214 if(res.store.fmt != 'a' && res.store.fmt != 'A')
1217 if(res.store.comt == 0 || res.store.comt->base == 0)
1220 sl = res.store.comt->base;
1224 n = an(ONAME, ZN, ZN);
1226 n = an(OCALL, n, &res);
1231 print("(%s)", sl->name);
1236 bprint(Node *r, Node *args)
1239 Node res, *av[Maxarg];
1245 for(i = 0; i < nas; i++) {
1251 patom(res.type, &res.store);
1254 pcode(res.store.u.cc, 0);
1257 blprint(res.store.u.l);
1266 printto(Node *r, Node *args)
1271 Node res, *av[Maxarg];
1279 if(res.type != TSTRING)
1280 error("printto(string, ...): need string");
1282 fd = create(res.store.u.string->string, OWRITE, 0666);
1284 fd = open(res.store.u.string->string, OWRITE);
1286 error("printto: open %s: %r", res.store.u.string->string);
1288 b = gmalloc(sizeof(Biobuf));
1289 Binit(b, fd, OWRITE);
1295 for(i = 1; i < nas; i++) {
1301 patom(res.type, &res.store);
1304 blprint(res.store.u.l);
1318 pcfile(Node *r, Node *args)
1324 error("pcfile(addr): arg count");
1326 if(res.type != TINT)
1327 error("pcfile(addr): arg type");
1331 if(fileline(res.store.u.ival, buf, sizeof(buf)) < 0) {
1332 r->store.u.string = strnode("?file?");
1335 p = strrchr(buf, ':');
1337 error("pcfile(addr): funny file %s", buf);
1339 r->store.u.string = strnode(buf);
1343 pcline(Node *r, Node *args)
1349 error("pcline(addr): arg count");
1351 if(res.type != TINT)
1352 error("pcline(addr): arg type");
1356 if(fileline(res.store.u.ival, buf, sizeof(buf)) < 0) {
1357 r->store.u.ival = 0;
1361 p = strrchr(buf, ':');
1363 error("pcline(addr): funny file %s", buf);
1364 r->store.u.ival = atoi(p+1);
1368 textfile(Node *r, Node *args)
1373 Node res, *av[Maxarg];
1374 List *l, *l2, **tail, *list, *tl;
1381 if(res.type != TLIST)
1382 error("textfile(list): textfile needs a list");
1383 if(listlen(res.store.u.l) != 2)
1384 error("textfile(list): list must have 2 entries");
1387 if(l->type != TSTRING)
1388 error("textfile name must be a string");
1389 file = l->store.u.string->string;
1393 error("textfile base must be an int");
1394 base = l->store.u.ival;
1396 if((fp = crackhdr(file, OREAD)) == nil)
1397 error("crackhdr %s: %r", file);
1400 fprint(2, "%s: %s %s %s\n", file, fp->aname, fp->mname, fp->fname);
1401 if(mapfile(fp, base, symmap, nil) < 0)
1402 fprint(2, "mapping %s: %r\n", file);
1404 unmapfile(corhdr, cormap);
1405 mapfile(fp, base, cormap, nil);
1407 mapfile(corhdr, 0, cormap, &correg);
1410 fprint(2, "syminit %s: %r\n", file);
1418 for(fp=fhdrlist; fp; fp=fp->next){
1419 if(fp->ftype == FCORE)
1426 tl->store.u.l = list;
1427 list->store.u.string = strnode(fp->filename);
1428 list->store.fmt = 's';
1429 list->next = al(TINT);
1431 list->store.fmt = 'X';
1432 list->store.u.ival = fp->base;
1440 deltextfile(Node *r, Node *args)
1445 Node res, *av[Maxarg];
1451 error("deltextfile(string): arg count");
1454 if(res.type != TSTRING)
1455 error("deltextfile(string): arg type");
1456 file = res.store.u.string->string;
1459 for(fp=fhdrlist; fp; fp=fpnext){
1461 if(fp->ftype == FCORE)
1463 if(strcmp(file, fp->filename) == 0){
1466 error("cannot remove symbols from main text file");
1467 unmapfile(fp, symmap);
1474 error("symbol file %s not open", file);