9 extern int _ifmt(Fmt*);
12 static char prog[128];
17 static int attachfiles(char*, int);
21 void loadmoduleobjtype(void);
26 fprint(2, "usage: acid [-kqw] [-l library] [-m machine] [pid] [file]\n");
31 main(int argc, char *argv[])
68 if(isnumeric(argv[0])) {
69 pid = strtol(argv[0], 0, 0);
70 snprint(prog, sizeof(prog), "/proc/%d/text", pid);
79 fprint(2, "acid: -k requires a pid\n");
86 fmtinstall('x', xfmt);
87 fmtinstall('L', Lfmt);
88 Binit(&bioout, 1, OWRITE);
97 if(mtype && machbyname(mtype) == 0)
98 print("unknown machine %s", mtype);
100 if (attachfiles(aout, pid) < 0)
101 varreg(); /* use default register set on error */
103 loadmodule("/sys/lib/acid/port");
106 for(i = 0; i < nlm; i++) {
107 if(access(lm[i], AREAD) >= 0)
110 s = smprint("/sys/lib/acid/%s", lm[i]);
121 n = an(ONAME, ZN, ZN);
123 n = an(OCALL, n, ZN);
135 Binit(&bioout, 1, OWRITE);
140 Bprint(bout, "acid: ");
152 attachfiles(char *aout, int pid)
158 if(aout) { /* executable given */
160 text = open(aout, ORDWR);
162 text = open(aout, OREAD);
165 error("%s: can't open %s: %r", argv0, aout);
168 if(pid) /* pid given */
181 s = look("proclist");
182 if(s && s->v->type == TLIST) {
183 for(f = s->v->l; f; f = f->next)
184 Bprint(bout, "echo kill > /proc/%d/ctl\n", (int)f->ival);
190 loadmoduleobjtype(void)
194 buf = smprint("/sys/lib/acid/%s", mach->name);
208 buf = smprint("%s/lib/acid", p);
219 l = look("acidinit");
221 n = an(ONAME, ZN, ZN);
223 n = an(OCALL, n, ZN);
253 symmap = newmap(0, 1);
255 print("%s: (error) loadmap: cannot make symbol map\n", argv0);
262 setmap(symmap, text, 0, length, 0, "binary");
266 if(!crackhdr(text, &fhdr)) {
267 print("can't decode file header\n");
271 symmap = loadmap(0, text, &fhdr);
273 print("%s: (error) loadmap: cannot make symbol map\n", argv0);
275 if(syminit(text, &fhdr) < 0) {
276 print("%s: (error) syminit: %r", argv0);
279 print("%s:%s\n", s, fhdr.name);
281 if(mach->sbreg && lookup(0, mach->sbreg, &sym)) {
282 mach->sb = sym.value;
283 l = enter("SB", Tid);
285 l->v->ival = mach->sb;
290 l = mkvar("objtype");
294 v->string = strnode(mach->name);
297 l = mkvar("textfile");
301 v->string = strnode(s);
304 machbytype(fhdr.type);
309 an(int op, Node *l, Node *r)
313 n = gmalloc(sizeof(Node));
314 memset(n, 0, sizeof(Node));
328 l = gmalloc(sizeof(List));
329 memset(l, 0, sizeof(List));
341 n = an(OCONST, ZN, ZN);
349 fatal(char *fmt, ...)
355 vseprint(buf, buf+sizeof(buf), fmt, arg);
357 fprint(2, "%s: %L (fatal problem) %s\n", argv0, buf);
362 yyerror(char *fmt, ...)
367 if(strcmp(fmt, "syntax error") == 0) {
368 yyerror("syntax error, near symbol '%s'", symbol);
372 vseprint(buf, buf+sizeof(buf), fmt, arg);
374 print("%L: %s\n", buf);
393 n->string->gcmark = 1;
411 l->string->gcmark = 1;
437 for(m = gcl; m; m = m->gclink)
441 for(i = 0; i < Hashsize; i++) {
442 for(f = hash[i]; f; f = f->hash) {
446 for(v = f->v; v; v = v->pop) {
449 v->string->gcmark = 1;
464 for(m = gcl; m; m = next) {
468 free(m); /* Sleazy reliance on my malloc */
483 fatal("out of memory");
488 checkqid(int f1, int pid)
499 print("checkqid: (qid not checked) dirfstat: %r\n");
503 snprint(buf, sizeof(buf), "/proc/%d/text", pid);
504 fd = open(buf, OREAD);
505 if(fd < 0 || (d2 = dirfstat(fd)) == nil){
506 print("checkqid: (qid not checked) dirstat %s: %r\n", buf);
515 if(d1->qid.path != d2->qid.path || d1->qid.vers != d2->qid.vers || d1->qid.type != d2->qid.type){
516 print("path %llux %llux vers %lud %lud type %d %d\n",
517 d1->qid.path, d2->qid.path, d1->qid.vers, d2->qid.vers, d1->qid.type, d2->qid.type);
518 print("warning: image does not match text for pid %d\n", pid);
525 catcher(void *junk, char *s)
529 if(strstr(s, "interrupt")) {
542 cpu = getenv("cputype");
544 sysfatal("$cputype not set");
545 p = getenv("terminal");
546 if(p == 0 || (p=strchr(p, ' ')) == 0 || p[1] == ' ' || p[1] == 0)
547 sysfatal("$terminal not set");
560 kernel = smprint("/%s/9%s", cpu, p);
569 if(*s < '0' || *s > '9')
579 f->flags ^= FmtSharp;