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*);
48 typedef struct Btab Btab;
52 void (*fn)(Node*, Node*);
57 "deltextfile", deltextfile,
67 "includepipe", includepipe,
68 "interpret", interpret,
83 "startstop", startstop,
97 prnt = malloc(sizeof(Node));
98 memset(prnt, 0, sizeof(Node));
100 prnt->left = malloc(sizeof(Node));
101 memset(prnt->left, 0, sizeof(Node));
115 s = enter(b->name, Tid);
125 match(Node *r, Node *args)
135 error("match(obj, list): arg count");
138 if(resl.type != TLIST)
139 error("match(obj, list): need list");
145 r->store.u.ival = -1;
148 for(f = resl.store.u.l; f; f = f->next) {
149 if(resi.type == f->type) {
152 if(resi.store.u.ival == f->store.u.ival) {
158 if(resi.store.u.fval == f->store.u.fval) {
164 if(scmp(resi.store.u.string, f->store.u.string)) {
170 error("match(obj, list): not defined for list");
178 newproc(Node *r, Node *args)
183 char *argv[Maxarg], buf[Strsize];
190 if(res.type != TSTRING)
191 error("newproc(): arg not string");
192 if(res.store.u.string->len >= sizeof(buf))
193 error("newproc(): too many arguments");
194 memmove(buf, res.store.u.string->string, res.store.u.string->len);
195 buf[res.store.u.string->len] = '\0';
197 e = buf+res.store.u.string->len;
199 while(p < e && (*p == '\t' || *p == ' '))
205 error("newproc: too many arguments");
206 while(p < e && *p != '\t' && *p != ' ')
214 r->store.u.ival = nproc(argv);
218 startstop(Node *r, Node *args)
224 error("startstop(pid): no pid");
227 error("startstop(pid): arg type");
229 msg(res.store.u.ival, "startstop");
230 notes(res.store.u.ival);
231 dostop(res.store.u.ival);
235 waitstop(Node *r, Node *args)
241 error("waitstop(pid): no pid");
244 error("waitstop(pid): arg type");
247 msg(res.store.u.ival, "waitstop");
248 notes(res.store.u.ival);
249 dostop(res.store.u.ival);
253 sysstop(Node *r, Node *args)
259 error("waitstop(pid): no pid");
262 error("waitstop(pid): arg type");
265 msg(res.store.u.ival, "sysstop");
266 notes(res.store.u.ival);
267 dostop(res.store.u.ival);
271 start(Node *r, Node *args)
277 error("start(pid): no pid");
280 error("start(pid): arg type");
282 msg(res.store.u.ival, "start");
286 stop(Node *r, Node *args)
292 error("stop(pid): no pid");
295 error("stop(pid): arg type");
298 msg(res.store.u.ival, "stop");
299 notes(res.store.u.ival);
300 dostop(res.store.u.ival);
304 xkill(Node *r, Node *args)
310 error("kill(pid): no pid");
313 error("kill(pid): arg type");
315 msg(res.store.u.ival, "kill");
316 deinstall(res.store.u.ival);
320 status(Node *r, Node *args)
327 error("status(pid): no pid");
330 error("status(pid): arg type");
332 p = getstatus(res.store.u.ival);
333 r->store.u.string = strnode(p);
340 reason(Node *r, Node *args)
345 error("reason(cause): no cause");
348 error("reason(cause): arg type");
353 r->store.u.string = strnode((*mach->exc)(cormap, correg));
357 follow(Node *r, Node *args)
365 error("follow(addr): no addr");
368 error("follow(addr): arg type");
370 n = (*mach->foll)(cormap, correg, res.store.u.ival, f);
372 error("follow(addr): %r");
373 tail = &r->store.u.l;
374 for(i = 0; i < n; i++) {
376 l->store.u.ival = f[i];
384 funcbound(Node *r, Node *args)
392 error("fnbound(addr): no addr");
395 error("fnbound(addr): arg type");
397 n = fnbound(res.store.u.ival, bounds);
399 r->store.u.l = al(TINT);
401 l->store.u.ival = bounds[0];
405 l->store.u.ival = bounds[1];
411 setproc(Node *r, Node *args)
417 error("setproc(pid): no pid");
420 error("setproc(pid): arg type");
422 sproc(res.store.u.ival);
426 filepc(Node *r, Node *args)
434 error("filepc(filename:line): arg count");
436 if(res.type != TSTRING)
437 error("filepc(filename:line): arg type");
439 p = strchr(res.store.u.string->string, ':');
441 error("filepc(filename:line): bad arg format");
445 i = file2pc(res.store.u.string->string, atoi(p), &v);
448 error("filepc(filename:line): can't find address");
457 interpret(Node *r, Node *args)
463 error("interpret(string): arg count");
465 if(res.type != TSTRING)
466 error("interpret(string): arg type");
472 r->store.u.ival = yyparse();
481 include(Node *r, Node *args)
483 char *file, *libfile;
484 static char buf[1024];
489 error("include(string): arg count");
491 if(res.type != TSTRING)
492 error("include(string): arg type");
497 file = res.store.u.string->string;
498 if(access(file, AREAD) < 0 && file[0] != '/'){
499 snprint(buf, sizeof buf, "#9/acid/%s", file);
500 libfile = unsharp(buf);
501 if(access(libfile, AREAD) >= 0){
502 strecpy(buf, buf+sizeof buf, libfile);
511 r->store.u.ival = yyparse();
520 includepipe(Node *r, Node *args)
523 int i, isave, pid, pip[2];
529 error("includepipe(string): arg count");
531 if(res.type != TSTRING)
532 error("includepipe(string): arg type");
538 argv[2] = res.store.u.string->string;
553 open("/dev/null", OREAD);
560 sysfatal("exec rc: %r");
568 r->store.u.ival = yyparse();
577 if(w->msg && w->msg[0])
578 error("includepipe(\"%s\"): %s", argv[2], w->msg); /* leaks w */
583 rc(Node *r, Node *args)
587 char *p, *q, *argv[4];
592 error("rc(string): arg count");
594 if(res.type != TSTRING)
595 error("rc(string): arg type");
599 argv[2] = res.store.u.string->string;
620 r->store.u.string = strnode(p);
626 doerror(Node *r, Node *args)
632 error("error(string): arg count");
634 if(res.type != TSTRING)
635 error("error(string): arg type");
637 error(res.store.u.string->string);
641 doaccess(Node *r, Node *args)
646 error("access(filename): arg count");
648 if(res.type != TSTRING)
649 error("access(filename): arg type");
655 if(access(res.store.u.string->string, 4) == 0)
660 readfile(Node *r, Node *args)
668 error("readfile(filename): arg count");
670 if(res.type != TSTRING)
671 error("readfile(filename): arg type");
673 fd = open(res.store.u.string->string, OREAD);
678 if(db == nil || db->length == 0)
685 n = read(fd, buf, n);
690 r->store.u.string = strnodlen(buf, n);
698 getfile(Node *r, Node *args)
708 error("file(filename): arg count");
710 if(res.type != TSTRING)
711 error("file(filename): arg type");
717 p = res.store.u.string->string;
718 bp = Bopen(p, OREAD);
724 p = Brdline(bp, '\n');
730 Bread(bp, s->string, n);
733 s = strnodlen(p, n-1);
736 new->store.u.string = s;
737 new->store.fmt = 's';
745 cvtatof(Node *r, Node *args)
750 error("atof(string): arg count");
752 if(res.type != TSTRING)
753 error("atof(string): arg type");
757 r->store.u.fval = atof(res.store.u.string->string);
762 cvtatoi(Node *r, Node *args)
767 error("atoi(string): arg count");
769 if(res.type != TSTRING)
770 error("atoi(string): arg type");
774 r->store.u.ival = strtoul(res.store.u.string->string, 0, 0);
779 cvtitoa(Node *r, Node *args)
788 error("itoa(number [, printformat]): arg count");
791 if(na == 0 || na > 2)
795 error("itoa(integer): arg type");
796 ival = (int)res.store.u.ival;
800 if(res.type != TSTRING)
801 error("itoa(integer, string): arg type");
802 fmt = res.store.u.string->string;
805 sprint(buf, fmt, ival);
808 r->store.u.string = strnode(buf);
816 List *l, *n, **t, *h;
820 for(i = 0; i < m->nseg; i++) {
826 l->store.u.string = strnode(m->seg[i].name);
828 l->next = al(TSTRING);
830 l->store.u.string = strnode(m->seg[i].file ? m->seg[i].file : "");
834 l->store.u.ival = m->seg[i].base;
838 l->store.u.ival = m->seg[i].base + m->seg[i].size;
842 l->store.u.ival = m->seg[i].offset;
849 map(Node *r, Node *args)
855 Node *av[Maxarg], res;
862 if(res.type != TLIST)
863 error("map(list): map needs a list");
864 if(listlen(res.store.u.l) != 5)
865 error("map(list): list must have 5 entries");
868 if(l->type != TSTRING)
869 error("map name must be a string");
870 nam = l->store.u.string->string;
872 if(l->type != TSTRING)
873 error("map file must be a string");
874 fil = l->store.u.string->string;
876 i = findseg(m, nam, fil);
879 i = findseg(m, nam, fil);
882 error("%s %s is not a map entry", nam, fil);
885 error("map entry not int");
886 m->seg[i].base = l->store.u.ival;
888 if (strcmp(ent, "text") == 0)
889 textseg(l->store.u.ival, &fhdr);
893 error("map entry not int");
894 m->seg[i].size = l->store.u.ival - m->seg[i].base;
897 error("map entry not int");
898 m->seg[i].offset = l->store.u.ival;
904 r->store.u.l = mapent(symmap);
906 if(r->store.u.l == 0)
907 r->store.u.l = mapent(cormap);
909 for(l = r->store.u.l; l->next; l = l->next)
911 l->next = mapent(cormap);
917 flatten(Node **av, Node *n)
924 flatten(av, n->left);
925 flatten(av, n->right);
930 error("too many function arguments");
943 straceregrw(Regs *regs, char *name, ulong *val, int isr)
948 werrstr("saved registers cannot be written");
951 for(i=0; i<nsregs; i++)
952 if(strcmp(sregs[i].name, name) == 0){
956 return rget(correg, name, val);
960 strace(Node *r, Node *args)
962 Node *av[Maxarg], res;
970 error("strace(list): want one arg");
973 if(res.type != TLIST)
974 error("strace(list): strace needs a list");
977 error("strace(list): strace needs an even-length list");
978 for(nsregs=0; l; nsregs++){
979 if(l->type != TSTRING)
980 error("strace({r,v,r,v,...}): non-string name");
981 sregs[nsregs].name = l->store.u.string->string;
982 if(regdesc(sregs[nsregs].name) == nil)
983 error("strace: bad register '%s'", sregs[nsregs].name);
987 error("cannot happen in strace");
989 error("strace: non-int value for %s", sregs[nsregs].name);
990 sregs[nsregs].val = l->store.u.ival;
993 regs.rw = straceregrw;
996 if(stacktrace(cormap, ®s, trlist) <= 0)
997 error("no stack frame");
999 r->store.u.l = tracelist;
1009 regexp(Node *r, Node *args)
1018 error("regexp(pattern, string): arg count");
1020 if(res.type != TSTRING)
1021 error("regexp(pattern, string): pattern must be string");
1022 rp = regcomp(res.store.u.string->string);
1027 if(res.type != TSTRING)
1028 error("regexp(pattern, string): bad string");
1032 r->store.u.ival = regexec(rp, res.store.u.string->string, 0, 0);
1036 char vfmt[] = "aBbcCdDfFgGiIoOqQrRsSuUVxXYZ";
1039 fmt(Node *r, Node *args)
1047 error("fmt(obj, fmt): arg count");
1049 if(res.type != TINT || strchr(vfmt, res.store.u.ival) == 0)
1050 error("fmt(obj, fmt): bad format '%c'", (char)res.store.u.ival);
1052 r->store.fmt = res.store.u.ival;
1056 patom(char type, Store *res)
1060 extern char *typenames[];
1064 Bprint(bout, "%c", (int)res->u.ival);
1067 if(res->u.ival < ' ' || res->u.ival >= 0x7f)
1068 Bprint(bout, "%3d", (int)res->u.ival&0xff);
1070 Bprint(bout, "%3c", (int)res->u.ival);
1073 Bprint(bout, "%C", (int)res->u.ival);
1076 memset(buf, '0', 34);
1078 for(i = 0; i < 32; i++) {
1079 if(res->u.ival & (1<<i))
1083 Bprint(bout, "%s", buf);
1086 Bprint(bout, "%.2x", (int)res->u.ival&0xff);
1089 Bprint(bout, "%.8lux", (ulong)res->u.ival);
1092 Bprint(bout, "%.4lux", (ulong)res->u.ival&0xffff);
1095 Bprint(bout, "%.16llux", res->u.ival);
1098 Bprint(bout, "%d", (int)res->u.ival);
1101 Bprint(bout, "%d", (ushort)res->u.ival);
1104 Bprint(bout, "%d", (int)res->u.ival&0xffff);
1107 Bprint(bout, "%lud", (ulong)res->u.ival);
1110 Bprint(bout, "%llud", res->u.ival);
1113 Bprint(bout, "%lld", res->u.ival);
1116 Bprint(bout, "%.16llux", res->u.ival);
1119 Bprint(bout, "0%.11uo", (int)res->u.ival&0xffff);
1122 Bprint(bout, "0%.6uo", (int)res->u.ival);
1125 Bprint(bout, "0%.11o", (short)(res->u.ival&0xffff));
1128 Bprint(bout, "0%.6o", (int)res->u.ival);
1133 Bprint(bout, "*%c<%s>*", res->fmt, typenames[(uchar)type]);
1135 Bprint(bout, "%g", res->u.fval);
1141 Bprint(bout, "*%c<%s>*", res->fmt, typenames[(uchar)type]);
1143 Bwrite(bout, res->u.string->string, res->u.string->len);
1147 Bprint(bout, "*%c<%s>*", res->fmt, typenames[(uchar)type]);
1149 Bprint(bout, "%S", (Rune*)res->u.string->string);
1153 symoff(buf, sizeof(buf), res->u.ival, CANY);
1154 Bprint(bout, "%s", buf);
1159 Bprint(bout, "*%c<%s>*", res->fmt, typenames[(uchar)type]);
1161 if (symmap == nil || (*mach->das)(symmap, res->u.ival, res->fmt, buf, sizeof(buf)) < 0)
1162 Bprint(bout, "no instruction");
1164 Bprint(bout, "%s", buf);
1180 if(res->fmt == 'c'){
1181 Bprint(bout, "\'%c\'", (int)res->u.ival);
1183 }else if(res->fmt == 'r'){
1184 Bprint(bout, "\'%C\'", (int)res->u.ival);
1189 patom(l->type, &l->store);
1193 patom(l->type, &l->store);
1197 blprint(l->store.u.l);
1200 pcode(l->store.u.cc, 0);
1216 if(res.store.fmt != 'a' && res.store.fmt != 'A')
1219 if(res.store.comt == 0 || res.store.comt->base == 0)
1222 sl = res.store.comt->base;
1226 n = an(ONAME, ZN, ZN);
1228 n = an(OCALL, n, &res);
1233 print("(%s)", sl->name);
1238 bprint(Node *r, Node *args)
1241 Node res, *av[Maxarg];
1247 for(i = 0; i < nas; i++) {
1253 patom(res.type, &res.store);
1256 pcode(res.store.u.cc, 0);
1259 blprint(res.store.u.l);
1268 printto(Node *r, Node *args)
1273 Node res, *av[Maxarg];
1281 if(res.type != TSTRING)
1282 error("printto(string, ...): need string");
1284 fd = create(res.store.u.string->string, OWRITE, 0666);
1286 fd = open(res.store.u.string->string, OWRITE);
1288 error("printto: open %s: %r", res.store.u.string->string);
1290 b = gmalloc(sizeof(Biobuf));
1291 Binit(b, fd, OWRITE);
1297 for(i = 1; i < nas; i++) {
1303 patom(res.type, &res.store);
1306 blprint(res.store.u.l);
1320 pcfile(Node *r, Node *args)
1326 error("pcfile(addr): arg count");
1328 if(res.type != TINT)
1329 error("pcfile(addr): arg type");
1333 if(fileline(res.store.u.ival, buf, sizeof(buf)) < 0) {
1334 r->store.u.string = strnode("?file?");
1337 p = strrchr(buf, ':');
1339 error("pcfile(addr): funny file %s", buf);
1341 r->store.u.string = strnode(buf);
1345 pcline(Node *r, Node *args)
1351 error("pcline(addr): arg count");
1353 if(res.type != TINT)
1354 error("pcline(addr): arg type");
1358 if(fileline(res.store.u.ival, buf, sizeof(buf)) < 0) {
1359 r->store.u.ival = 0;
1363 p = strrchr(buf, ':');
1365 error("pcline(addr): funny file %s", buf);
1366 r->store.u.ival = atoi(p+1);
1370 textfile(Node *r, Node *args)
1375 Node res, *av[Maxarg];
1376 List *l, *l2, **tail, *list, *tl;
1383 if(res.type != TLIST)
1384 error("textfile(list): textfile needs a list");
1385 if(listlen(res.store.u.l) != 2)
1386 error("textfile(list): list must have 2 entries");
1389 if(l->type != TSTRING)
1390 error("textfile name must be a string");
1391 file = l->store.u.string->string;
1395 error("textfile base must be an int");
1396 base = l->store.u.ival;
1398 if((fp = crackhdr(file, OREAD)) == nil)
1399 error("crackhdr %s: %r", file);
1402 fprint(2, "%s: %s %s %s\n", file, fp->aname, fp->mname, fp->fname);
1403 if(mapfile(fp, base, symmap, nil) < 0)
1404 fprint(2, "mapping %s: %r\n", file);
1406 unmapfile(corhdr, cormap);
1407 mapfile(fp, base, cormap, nil);
1409 mapfile(corhdr, 0, cormap, &correg);
1412 fprint(2, "symopen %s: %r\n", file);
1420 for(fp=fhdrlist; fp; fp=fp->next){
1421 if(fp->ftype == FCORE)
1428 tl->store.u.l = list;
1429 list->store.u.string = strnode(fp->filename);
1430 list->store.fmt = 's';
1431 list->next = al(TINT);
1433 list->store.fmt = 'X';
1434 list->store.u.ival = fp->base;
1442 deltextfile(Node *r, Node *args)
1447 Node res, *av[Maxarg];
1453 error("deltextfile(string): arg count");
1456 if(res.type != TSTRING)
1457 error("deltextfile(string): arg type");
1458 file = res.store.u.string->string;
1461 for(fp=fhdrlist; fp; fp=fpnext){
1463 if(fp->ftype == FCORE)
1465 if(strcmp(file, fp->filename) == 0){
1468 error("cannot remove symbols from main text file");
1469 unmapfile(fp, symmap);
1476 error("symbol file %s not open", file);
1479 int xget1(Map *m, ulong addr, u8int *a, int n);
1482 stringn(Node *r, Node *args)
1486 Node res, *av[Maxarg];
1492 error("stringn(addr, n): arg count");
1495 if(res.type != TINT)
1496 error("stringn(addr, n): arg type");
1497 addr = res.store.u.ival;
1500 if(res.type != TINT)
1501 error("stringn(addr,n): arg type");
1502 n = res.store.u.ival;
1506 error("out of memory");
1510 ret = xget1(cormap, addr, (uchar*)&buf[i], 1);
1518 r->store.u.string = strnode(buf);