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 */
183 s = look("proclist");
184 if(s && s->v->type == TLIST) {
185 for(f = s->v->l; f; f = f->next)
186 Bprint(bout, "echo kill > /proc/%d/ctl\n", (int)f->ival);
192 loadmoduleobjtype(void)
196 buf = smprint("/sys/lib/acid/%s", mach->name);
209 n = an(ONAME, ZN, ZN);
211 n = an(OCALL, n, ZN);
225 buf = smprint("%s/lib/acid", p);
236 callhook("acidinit");
264 symmap = newmap(0, 1);
266 print("%s: (error) loadmap: cannot make symbol map\n", argv0);
273 setmap(symmap, text, 0, length, 0, "binary");
277 if(!crackhdr(text, &fhdr)) {
278 print("can't decode file header\n");
282 symmap = loadmap(0, text, &fhdr);
284 print("%s: (error) loadmap: cannot make symbol map\n", argv0);
286 if(syminit(text, &fhdr) < 0) {
287 print("%s: (error) syminit: %r", argv0);
290 print("%s:%s\n", s, fhdr.name);
292 if(mach->sbreg && lookup(0, mach->sbreg, &sym)) {
293 mach->sb = sym.value;
294 l = enter("SB", Tid);
296 l->v->ival = mach->sb;
301 l = mkvar("objtype");
305 v->string = strnode(mach->name);
308 l = mkvar("textfile");
312 v->string = strnode(s);
315 machbytype(fhdr.type);
320 an(int op, Node *l, Node *r)
324 n = gmalloc(sizeof(Node));
325 memset(n, 0, sizeof(Node));
339 l = gmalloc(sizeof(List));
340 memset(l, 0, sizeof(List));
352 n = an(OCONST, ZN, ZN);
360 fatal(char *fmt, ...)
366 vseprint(buf, buf+sizeof(buf), fmt, arg);
368 fprint(2, "%s: %L (fatal problem) %s\n", argv0, buf);
373 yyerror(char *fmt, ...)
378 if(strcmp(fmt, "syntax error") == 0) {
379 yyerror("syntax error, near symbol '%s'", symbol);
383 vseprint(buf, buf+sizeof(buf), fmt, arg);
385 print("%L: %s\n", buf);
404 n->string->gcmark = 1;
422 l->string->gcmark = 1;
448 for(m = gcl; m; m = m->gclink)
452 for(i = 0; i < Hashsize; i++) {
453 for(f = hash[i]; f; f = f->hash) {
457 for(v = f->v; v; v = v->pop) {
460 v->string->gcmark = 1;
475 for(m = gcl; m; m = next) {
479 free(m); /* Sleazy reliance on my malloc */
494 fatal("out of memory");
499 checkqid(int f1, int pid)
510 print("checkqid: (qid not checked) dirfstat: %r\n");
514 snprint(buf, sizeof(buf), "/proc/%d/text", pid);
515 fd = open(buf, OREAD);
516 if(fd < 0 || (d2 = dirfstat(fd)) == nil){
517 print("checkqid: (qid not checked) dirstat %s: %r\n", buf);
526 if(d1->qid.path != d2->qid.path || d1->qid.vers != d2->qid.vers || d1->qid.type != d2->qid.type){
527 print("path %llux %llux vers %lud %lud type %d %d\n",
528 d1->qid.path, d2->qid.path, d1->qid.vers, d2->qid.vers, d1->qid.type, d2->qid.type);
529 print("warning: image does not match text for pid %d\n", pid);
536 catcher(void *junk, char *s)
540 if(strstr(s, "interrupt")) {
553 cpu = getenv("cputype");
555 sysfatal("$cputype not set");
556 p = getenv("terminal");
557 if(p == 0 || (p=strchr(p, ' ')) == 0 || p[1] == ' ' || p[1] == 0)
558 sysfatal("$terminal not set");
571 kernel = smprint("/%s/9%s", cpu, p);
580 if(*s < '0' || *s > '9')
590 f->flags ^= FmtSharp;