1 564ca709 2004-04-19 devnull #include <u.h>
2 564ca709 2004-04-19 devnull #include <libc.h>
3 564ca709 2004-04-19 devnull #include <bio.h>
4 564ca709 2004-04-19 devnull #include <ctype.h>
5 564ca709 2004-04-19 devnull #include <mach.h>
6 564ca709 2004-04-19 devnull #include <regexp.h>
7 564ca709 2004-04-19 devnull #define Extern extern
8 564ca709 2004-04-19 devnull #include "acid.h"
9 564ca709 2004-04-19 devnull #include "y.tab.h"
11 564ca709 2004-04-19 devnull void cvtatof(Node*, Node*);
12 564ca709 2004-04-19 devnull void cvtatoi(Node*, Node*);
13 564ca709 2004-04-19 devnull void cvtitoa(Node*, Node*);
14 564ca709 2004-04-19 devnull void bprint(Node*, Node*);
15 564ca709 2004-04-19 devnull void funcbound(Node*, Node*);
16 564ca709 2004-04-19 devnull void printto(Node*, Node*);
17 564ca709 2004-04-19 devnull void getfile(Node*, Node*);
18 564ca709 2004-04-19 devnull void fmt(Node*, Node*);
19 564ca709 2004-04-19 devnull void pcfile(Node*, Node*);
20 564ca709 2004-04-19 devnull void pcline(Node*, Node*);
21 564ca709 2004-04-19 devnull void setproc(Node*, Node*);
22 564ca709 2004-04-19 devnull void strace(Node*, Node*);
23 564ca709 2004-04-19 devnull void follow(Node*, Node*);
24 564ca709 2004-04-19 devnull void reason(Node*, Node*);
25 564ca709 2004-04-19 devnull void newproc(Node*, Node*);
26 564ca709 2004-04-19 devnull void startstop(Node*, Node*);
27 564ca709 2004-04-19 devnull void match(Node*, Node*);
28 564ca709 2004-04-19 devnull void status(Node*, Node*);
29 564ca709 2004-04-19 devnull void xkill(Node*,Node*);
30 564ca709 2004-04-19 devnull void waitstop(Node*, Node*);
31 564ca709 2004-04-19 devnull void sysstop(Node*, Node*);
32 564ca709 2004-04-19 devnull void stop(Node*, Node*);
33 564ca709 2004-04-19 devnull void start(Node*, Node*);
34 564ca709 2004-04-19 devnull void filepc(Node*, Node*);
35 564ca709 2004-04-19 devnull void doerror(Node*, Node*);
36 564ca709 2004-04-19 devnull void rc(Node*, Node*);
37 564ca709 2004-04-19 devnull void doaccess(Node*, Node*);
38 564ca709 2004-04-19 devnull void map(Node*, Node*);
39 564ca709 2004-04-19 devnull void readfile(Node*, Node*);
40 564ca709 2004-04-19 devnull void interpret(Node*, Node*);
41 564ca709 2004-04-19 devnull void include(Node*, Node*);
42 564ca709 2004-04-19 devnull void includepipe(Node*, Node*);
43 564ca709 2004-04-19 devnull void regexp(Node*, Node*);
44 564ca709 2004-04-19 devnull void textfile(Node*, Node*);
45 564ca709 2004-04-19 devnull void deltextfile(Node*, Node*);
46 709efa01 2004-09-23 devnull void stringn(Node*, Node*);
47 4f2ac1b7 2005-01-23 devnull void xregister(Node*, Node*);
48 4f2ac1b7 2005-01-23 devnull void refconst(Node*, Node*);
49 4f2ac1b7 2005-01-23 devnull void dolook(Node*, Node*);
51 564ca709 2004-04-19 devnull typedef struct Btab Btab;
52 564ca709 2004-04-19 devnull struct Btab
54 564ca709 2004-04-19 devnull char *name;
55 564ca709 2004-04-19 devnull void (*fn)(Node*, Node*);
56 564ca709 2004-04-19 devnull } tab[] =
58 4f2ac1b7 2005-01-23 devnull "access", doaccess,
59 564ca709 2004-04-19 devnull "atof", cvtatof,
60 564ca709 2004-04-19 devnull "atoi", cvtatoi,
61 564ca709 2004-04-19 devnull "deltextfile", deltextfile,
62 564ca709 2004-04-19 devnull "error", doerror,
63 564ca709 2004-04-19 devnull "file", getfile,
64 564ca709 2004-04-19 devnull "filepc", filepc,
65 564ca709 2004-04-19 devnull "fnbound", funcbound,
66 564ca709 2004-04-19 devnull "fmt", fmt,
67 564ca709 2004-04-19 devnull "follow", follow,
68 564ca709 2004-04-19 devnull "include", include,
69 564ca709 2004-04-19 devnull "includepipe", includepipe,
70 564ca709 2004-04-19 devnull "interpret", interpret,
71 564ca709 2004-04-19 devnull "itoa", cvtitoa,
72 564ca709 2004-04-19 devnull "kill", xkill,
73 564ca709 2004-04-19 devnull "map", map,
74 564ca709 2004-04-19 devnull "match", match,
75 564ca709 2004-04-19 devnull "newproc", newproc,
76 564ca709 2004-04-19 devnull "pcfile", pcfile,
77 564ca709 2004-04-19 devnull "pcline", pcline,
78 564ca709 2004-04-19 devnull "print", bprint,
79 564ca709 2004-04-19 devnull "printto", printto,
80 564ca709 2004-04-19 devnull "rc", rc,
81 4f2ac1b7 2005-01-23 devnull "readfile", readfile,
82 564ca709 2004-04-19 devnull "reason", reason,
83 4f2ac1b7 2005-01-23 devnull "refconst", refconst,
84 564ca709 2004-04-19 devnull "regexp", regexp,
85 4f2ac1b7 2005-01-23 devnull "register", xregister,
86 564ca709 2004-04-19 devnull "setproc", setproc,
87 564ca709 2004-04-19 devnull "start", start,
88 564ca709 2004-04-19 devnull "startstop", startstop,
89 564ca709 2004-04-19 devnull "status", status,
90 564ca709 2004-04-19 devnull "stop", stop,
91 564ca709 2004-04-19 devnull "strace", strace,
92 709efa01 2004-09-23 devnull "stringn", stringn,
93 564ca709 2004-04-19 devnull "sysstop", sysstop,
94 564ca709 2004-04-19 devnull "textfile", textfile,
95 4f2ac1b7 2005-01-23 devnull "var", dolook,
96 564ca709 2004-04-19 devnull "waitstop", waitstop,
101 564ca709 2004-04-19 devnull mkprint(Lsym *s)
103 564ca709 2004-04-19 devnull prnt = malloc(sizeof(Node));
104 564ca709 2004-04-19 devnull memset(prnt, 0, sizeof(Node));
105 564ca709 2004-04-19 devnull prnt->op = OCALL;
106 564ca709 2004-04-19 devnull prnt->left = malloc(sizeof(Node));
107 564ca709 2004-04-19 devnull memset(prnt->left, 0, sizeof(Node));
108 564ca709 2004-04-19 devnull prnt->left->sym = s;
112 564ca709 2004-04-19 devnull installbuiltin(void)
114 564ca709 2004-04-19 devnull Btab *b;
115 564ca709 2004-04-19 devnull Lsym *s;
117 564ca709 2004-04-19 devnull b = tab;
118 564ca709 2004-04-19 devnull while(b->name) {
119 564ca709 2004-04-19 devnull s = look(b->name);
120 564ca709 2004-04-19 devnull if(s == 0)
121 564ca709 2004-04-19 devnull s = enter(b->name, Tid);
123 564ca709 2004-04-19 devnull s->builtin = b->fn;
124 564ca709 2004-04-19 devnull if(b->fn == bprint)
125 564ca709 2004-04-19 devnull mkprint(s);
131 564ca709 2004-04-19 devnull match(Node *r, Node *args)
134 564ca709 2004-04-19 devnull List *f;
135 564ca709 2004-04-19 devnull Node *av[Maxarg];
136 564ca709 2004-04-19 devnull Node resi, resl;
139 564ca709 2004-04-19 devnull flatten(av, args);
140 564ca709 2004-04-19 devnull if(na != 2)
141 564ca709 2004-04-19 devnull error("match(obj, list): arg count");
143 564ca709 2004-04-19 devnull expr(av[1], &resl);
144 564ca709 2004-04-19 devnull if(resl.type != TLIST)
145 564ca709 2004-04-19 devnull error("match(obj, list): need list");
146 564ca709 2004-04-19 devnull expr(av[0], &resi);
148 564ca709 2004-04-19 devnull r->op = OCONST;
149 564ca709 2004-04-19 devnull r->type = TINT;
150 564ca709 2004-04-19 devnull r->store.fmt = 'D';
151 564ca709 2004-04-19 devnull r->store.u.ival = -1;
154 564ca709 2004-04-19 devnull for(f = resl.store.u.l; f; f = f->next) {
155 564ca709 2004-04-19 devnull if(resi.type == f->type) {
156 564ca709 2004-04-19 devnull switch(resi.type) {
157 564ca709 2004-04-19 devnull case TINT:
158 564ca709 2004-04-19 devnull if(resi.store.u.ival == f->store.u.ival) {
159 564ca709 2004-04-19 devnull r->store.u.ival = i;
163 564ca709 2004-04-19 devnull case TFLOAT:
164 564ca709 2004-04-19 devnull if(resi.store.u.fval == f->store.u.fval) {
165 564ca709 2004-04-19 devnull r->store.u.ival = i;
169 564ca709 2004-04-19 devnull case TSTRING:
170 564ca709 2004-04-19 devnull if(scmp(resi.store.u.string, f->store.u.string)) {
171 564ca709 2004-04-19 devnull r->store.u.ival = i;
175 564ca709 2004-04-19 devnull case TLIST:
176 564ca709 2004-04-19 devnull error("match(obj, list): not defined for list");
184 564ca709 2004-04-19 devnull newproc(Node *r, Node *args)
187 564ca709 2004-04-19 devnull Node res;
188 564ca709 2004-04-19 devnull char *p, *e;
189 564ca709 2004-04-19 devnull char *argv[Maxarg], buf[Strsize];
192 564ca709 2004-04-19 devnull argv[0] = symfil;
194 564ca709 2004-04-19 devnull if(args) {
195 564ca709 2004-04-19 devnull expr(args, &res);
196 564ca709 2004-04-19 devnull if(res.type != TSTRING)
197 564ca709 2004-04-19 devnull error("newproc(): arg not string");
198 564ca709 2004-04-19 devnull if(res.store.u.string->len >= sizeof(buf))
199 564ca709 2004-04-19 devnull error("newproc(): too many arguments");
200 564ca709 2004-04-19 devnull memmove(buf, res.store.u.string->string, res.store.u.string->len);
201 564ca709 2004-04-19 devnull buf[res.store.u.string->len] = '\0';
202 564ca709 2004-04-19 devnull p = buf;
203 564ca709 2004-04-19 devnull e = buf+res.store.u.string->len;
204 564ca709 2004-04-19 devnull for(;;) {
205 564ca709 2004-04-19 devnull while(p < e && (*p == '\t' || *p == ' '))
206 564ca709 2004-04-19 devnull *p++ = '\0';
207 564ca709 2004-04-19 devnull if(p >= e)
209 564ca709 2004-04-19 devnull argv[i++] = p;
210 564ca709 2004-04-19 devnull if(i >= Maxarg)
211 564ca709 2004-04-19 devnull error("newproc: too many arguments");
212 564ca709 2004-04-19 devnull while(p < e && *p != '\t' && *p != ' ')
216 564ca709 2004-04-19 devnull argv[i] = 0;
217 564ca709 2004-04-19 devnull r->op = OCONST;
218 564ca709 2004-04-19 devnull r->type = TINT;
219 564ca709 2004-04-19 devnull r->store.fmt = 'D';
220 564ca709 2004-04-19 devnull r->store.u.ival = nproc(argv);
224 564ca709 2004-04-19 devnull startstop(Node *r, Node *args)
226 564ca709 2004-04-19 devnull Node res;
228 564ca709 2004-04-19 devnull USED(r);
229 564ca709 2004-04-19 devnull if(args == 0)
230 564ca709 2004-04-19 devnull error("startstop(pid): no pid");
231 564ca709 2004-04-19 devnull expr(args, &res);
232 564ca709 2004-04-19 devnull if(res.type != TINT)
233 564ca709 2004-04-19 devnull error("startstop(pid): arg type");
235 564ca709 2004-04-19 devnull msg(res.store.u.ival, "startstop");
236 564ca709 2004-04-19 devnull notes(res.store.u.ival);
237 564ca709 2004-04-19 devnull dostop(res.store.u.ival);
241 564ca709 2004-04-19 devnull waitstop(Node *r, Node *args)
243 564ca709 2004-04-19 devnull Node res;
245 564ca709 2004-04-19 devnull USED(r);
246 564ca709 2004-04-19 devnull if(args == 0)
247 564ca709 2004-04-19 devnull error("waitstop(pid): no pid");
248 564ca709 2004-04-19 devnull expr(args, &res);
249 564ca709 2004-04-19 devnull if(res.type != TINT)
250 564ca709 2004-04-19 devnull error("waitstop(pid): arg type");
252 564ca709 2004-04-19 devnull Bflush(bout);
253 564ca709 2004-04-19 devnull msg(res.store.u.ival, "waitstop");
254 564ca709 2004-04-19 devnull notes(res.store.u.ival);
255 564ca709 2004-04-19 devnull dostop(res.store.u.ival);
259 564ca709 2004-04-19 devnull sysstop(Node *r, Node *args)
261 564ca709 2004-04-19 devnull Node res;
263 564ca709 2004-04-19 devnull USED(r);
264 564ca709 2004-04-19 devnull if(args == 0)
265 564ca709 2004-04-19 devnull error("waitstop(pid): no pid");
266 564ca709 2004-04-19 devnull expr(args, &res);
267 564ca709 2004-04-19 devnull if(res.type != TINT)
268 564ca709 2004-04-19 devnull error("waitstop(pid): arg type");
270 564ca709 2004-04-19 devnull Bflush(bout);
271 564ca709 2004-04-19 devnull msg(res.store.u.ival, "sysstop");
272 564ca709 2004-04-19 devnull notes(res.store.u.ival);
273 564ca709 2004-04-19 devnull dostop(res.store.u.ival);
277 564ca709 2004-04-19 devnull start(Node *r, Node *args)
279 564ca709 2004-04-19 devnull Node res;
281 564ca709 2004-04-19 devnull USED(r);
282 564ca709 2004-04-19 devnull if(args == 0)
283 564ca709 2004-04-19 devnull error("start(pid): no pid");
284 564ca709 2004-04-19 devnull expr(args, &res);
285 564ca709 2004-04-19 devnull if(res.type != TINT)
286 564ca709 2004-04-19 devnull error("start(pid): arg type");
288 564ca709 2004-04-19 devnull msg(res.store.u.ival, "start");
292 564ca709 2004-04-19 devnull stop(Node *r, Node *args)
294 564ca709 2004-04-19 devnull Node res;
296 564ca709 2004-04-19 devnull USED(r);
297 564ca709 2004-04-19 devnull if(args == 0)
298 564ca709 2004-04-19 devnull error("stop(pid): no pid");
299 564ca709 2004-04-19 devnull expr(args, &res);
300 564ca709 2004-04-19 devnull if(res.type != TINT)
301 564ca709 2004-04-19 devnull error("stop(pid): arg type");
303 564ca709 2004-04-19 devnull Bflush(bout);
304 564ca709 2004-04-19 devnull msg(res.store.u.ival, "stop");
305 564ca709 2004-04-19 devnull notes(res.store.u.ival);
306 564ca709 2004-04-19 devnull dostop(res.store.u.ival);
310 564ca709 2004-04-19 devnull xkill(Node *r, Node *args)
312 564ca709 2004-04-19 devnull Node res;
314 564ca709 2004-04-19 devnull USED(r);
315 564ca709 2004-04-19 devnull if(args == 0)
316 564ca709 2004-04-19 devnull error("kill(pid): no pid");
317 564ca709 2004-04-19 devnull expr(args, &res);
318 564ca709 2004-04-19 devnull if(res.type != TINT)
319 564ca709 2004-04-19 devnull error("kill(pid): arg type");
321 564ca709 2004-04-19 devnull msg(res.store.u.ival, "kill");
322 564ca709 2004-04-19 devnull deinstall(res.store.u.ival);
326 4f2ac1b7 2005-01-23 devnull xregister(Node *r, Node *args)
328 281c90a5 2005-02-11 devnull int tid;
329 4f2ac1b7 2005-01-23 devnull Regdesc *rp;
330 281c90a5 2005-02-11 devnull Node res, resid;
331 281c90a5 2005-02-11 devnull Node *av[Maxarg];
334 281c90a5 2005-02-11 devnull flatten(av, args);
335 7b8a3f12 2005-02-11 devnull if(na != 1/* && na != 2 */)
336 7b8a3f12 2005-02-11 devnull error("register(name): arg count");
338 281c90a5 2005-02-11 devnull expr(av[0], &res);
339 281c90a5 2005-02-11 devnull if(res.type != TSTRING)
340 7b8a3f12 2005-02-11 devnull error("register(name): arg type: name should be string");
341 281c90a5 2005-02-11 devnull tid = 0;
342 281c90a5 2005-02-11 devnull if(na == 2){
343 281c90a5 2005-02-11 devnull expr(av[1], &resid);
344 281c90a5 2005-02-11 devnull if(resid.type != TINT)
345 281c90a5 2005-02-11 devnull error("register(name[, threadid]): arg type: threadid should be int");
346 281c90a5 2005-02-11 devnull tid = resid.store.u.ival;
348 4f2ac1b7 2005-01-23 devnull if((rp = regdesc(res.store.u.string->string)) == nil)
349 4f2ac1b7 2005-01-23 devnull error("no such register");
350 4f2ac1b7 2005-01-23 devnull r->op = OCONST;
351 4f2ac1b7 2005-01-23 devnull r->type = TREG;
352 4f2ac1b7 2005-01-23 devnull r->store.fmt = rp->format;
353 281c90a5 2005-02-11 devnull r->store.u.reg.name = rp->name;
354 281c90a5 2005-02-11 devnull r->store.u.reg.thread = tid;
358 4f2ac1b7 2005-01-23 devnull refconst(Node *r, Node *args)
360 4f2ac1b7 2005-01-23 devnull Node *n;
362 4f2ac1b7 2005-01-23 devnull if(args == 0)
363 4f2ac1b7 2005-01-23 devnull error("refconst(expr): arg count");
365 4f2ac1b7 2005-01-23 devnull n = an(OCONST, ZN, ZN);
366 4f2ac1b7 2005-01-23 devnull expr(args, n);
368 4f2ac1b7 2005-01-23 devnull r->op = OCONST;
369 4f2ac1b7 2005-01-23 devnull r->type = TCON;
370 4f2ac1b7 2005-01-23 devnull r->store.u.con = n;
374 4f2ac1b7 2005-01-23 devnull dolook(Node *r, Node *args)
376 4f2ac1b7 2005-01-23 devnull Node res;
377 4f2ac1b7 2005-01-23 devnull Lsym *l;
379 4f2ac1b7 2005-01-23 devnull if(args == 0)
380 4f2ac1b7 2005-01-23 devnull error("var(string): arg count");
381 4f2ac1b7 2005-01-23 devnull expr(args, &res);
382 4f2ac1b7 2005-01-23 devnull if(res.type != TSTRING)
383 4f2ac1b7 2005-01-23 devnull error("var(string): arg type");
385 4f2ac1b7 2005-01-23 devnull r->op = OCONST;
386 4f2ac1b7 2005-01-23 devnull if((l = look(res.store.u.string->string)) == nil || l->v->set == 0){
387 4f2ac1b7 2005-01-23 devnull r->type = TLIST;
388 4f2ac1b7 2005-01-23 devnull r->store.u.l = nil;
390 4f2ac1b7 2005-01-23 devnull r->type = l->v->type;
391 4f2ac1b7 2005-01-23 devnull r->store = l->v->store;
396 564ca709 2004-04-19 devnull status(Node *r, Node *args)
398 564ca709 2004-04-19 devnull Node res;
399 564ca709 2004-04-19 devnull char *p;
401 564ca709 2004-04-19 devnull USED(r);
402 564ca709 2004-04-19 devnull if(args == 0)
403 564ca709 2004-04-19 devnull error("status(pid): no pid");
404 564ca709 2004-04-19 devnull expr(args, &res);
405 564ca709 2004-04-19 devnull if(res.type != TINT)
406 564ca709 2004-04-19 devnull error("status(pid): arg type");
408 564ca709 2004-04-19 devnull p = getstatus(res.store.u.ival);
409 564ca709 2004-04-19 devnull r->store.u.string = strnode(p);
410 564ca709 2004-04-19 devnull r->op = OCONST;
411 564ca709 2004-04-19 devnull r->store.fmt = 's';
412 564ca709 2004-04-19 devnull r->type = TSTRING;
416 564ca709 2004-04-19 devnull reason(Node *r, Node *args)
418 564ca709 2004-04-19 devnull Node res;
420 564ca709 2004-04-19 devnull if(args == 0)
421 564ca709 2004-04-19 devnull error("reason(cause): no cause");
422 564ca709 2004-04-19 devnull expr(args, &res);
423 564ca709 2004-04-19 devnull if(res.type != TINT)
424 564ca709 2004-04-19 devnull error("reason(cause): arg type");
426 564ca709 2004-04-19 devnull r->op = OCONST;
427 564ca709 2004-04-19 devnull r->type = TSTRING;
428 564ca709 2004-04-19 devnull r->store.fmt = 's';
429 4f2ac1b7 2005-01-23 devnull r->store.u.string = strnode((*mach->exc)(cormap, acidregs));
433 564ca709 2004-04-19 devnull follow(Node *r, Node *args)
435 564ca709 2004-04-19 devnull int n, i;
436 564ca709 2004-04-19 devnull Node res;
437 564ca709 2004-04-19 devnull ulong f[10];
438 564ca709 2004-04-19 devnull List **tail, *l;
440 564ca709 2004-04-19 devnull if(args == 0)
441 564ca709 2004-04-19 devnull error("follow(addr): no addr");
442 564ca709 2004-04-19 devnull expr(args, &res);
443 564ca709 2004-04-19 devnull if(res.type != TINT)
444 564ca709 2004-04-19 devnull error("follow(addr): arg type");
446 4f2ac1b7 2005-01-23 devnull n = (*mach->foll)(cormap, acidregs, res.store.u.ival, f);
447 564ca709 2004-04-19 devnull if (n < 0)
448 564ca709 2004-04-19 devnull error("follow(addr): %r");
449 564ca709 2004-04-19 devnull tail = &r->store.u.l;
450 564ca709 2004-04-19 devnull for(i = 0; i < n; i++) {
451 564ca709 2004-04-19 devnull l = al(TINT);
452 564ca709 2004-04-19 devnull l->store.u.ival = f[i];
453 564ca709 2004-04-19 devnull l->store.fmt = 'X';
454 564ca709 2004-04-19 devnull *tail = l;
455 564ca709 2004-04-19 devnull tail = &l->next;
460 564ca709 2004-04-19 devnull funcbound(Node *r, Node *args)
463 564ca709 2004-04-19 devnull Node res;
464 564ca709 2004-04-19 devnull ulong bounds[2];
465 564ca709 2004-04-19 devnull List *l;
467 564ca709 2004-04-19 devnull if(args == 0)
468 564ca709 2004-04-19 devnull error("fnbound(addr): no addr");
469 564ca709 2004-04-19 devnull expr(args, &res);
470 564ca709 2004-04-19 devnull if(res.type != TINT)
471 564ca709 2004-04-19 devnull error("fnbound(addr): arg type");
473 564ca709 2004-04-19 devnull n = fnbound(res.store.u.ival, bounds);
474 564ca709 2004-04-19 devnull if (n != 0) {
475 564ca709 2004-04-19 devnull r->store.u.l = al(TINT);
476 564ca709 2004-04-19 devnull l = r->store.u.l;
477 564ca709 2004-04-19 devnull l->store.u.ival = bounds[0];
478 564ca709 2004-04-19 devnull l->store.fmt = 'X';
479 564ca709 2004-04-19 devnull l->next = al(TINT);
480 564ca709 2004-04-19 devnull l = l->next;
481 564ca709 2004-04-19 devnull l->store.u.ival = bounds[1];
482 564ca709 2004-04-19 devnull l->store.fmt = 'X';
487 564ca709 2004-04-19 devnull setproc(Node *r, Node *args)
489 564ca709 2004-04-19 devnull Node res;
491 564ca709 2004-04-19 devnull USED(r);
492 564ca709 2004-04-19 devnull if(args == 0)
493 564ca709 2004-04-19 devnull error("setproc(pid): no pid");
494 564ca709 2004-04-19 devnull expr(args, &res);
495 564ca709 2004-04-19 devnull if(res.type != TINT)
496 564ca709 2004-04-19 devnull error("setproc(pid): arg type");
498 564ca709 2004-04-19 devnull sproc(res.store.u.ival);
502 564ca709 2004-04-19 devnull filepc(Node *r, Node *args)
505 564ca709 2004-04-19 devnull Node res;
506 564ca709 2004-04-19 devnull char *p, c;
507 564ca709 2004-04-19 devnull ulong v;
509 564ca709 2004-04-19 devnull if(args == 0)
510 564ca709 2004-04-19 devnull error("filepc(filename:line): arg count");
511 564ca709 2004-04-19 devnull expr(args, &res);
512 564ca709 2004-04-19 devnull if(res.type != TSTRING)
513 564ca709 2004-04-19 devnull error("filepc(filename:line): arg type");
515 564ca709 2004-04-19 devnull p = strchr(res.store.u.string->string, ':');
516 564ca709 2004-04-19 devnull if(p == 0)
517 564ca709 2004-04-19 devnull error("filepc(filename:line): bad arg format");
520 564ca709 2004-04-19 devnull *p++ = '\0';
521 564ca709 2004-04-19 devnull i = file2pc(res.store.u.string->string, atoi(p), &v);
522 564ca709 2004-04-19 devnull p[-1] = c;
523 564ca709 2004-04-19 devnull if(i < 0)
524 564ca709 2004-04-19 devnull error("filepc(filename:line): can't find address");
526 564ca709 2004-04-19 devnull r->op = OCONST;
527 564ca709 2004-04-19 devnull r->type = TINT;
528 564ca709 2004-04-19 devnull r->store.fmt = 'D';
529 564ca709 2004-04-19 devnull r->store.u.ival = v;
533 564ca709 2004-04-19 devnull interpret(Node *r, Node *args)
535 564ca709 2004-04-19 devnull Node res;
536 564ca709 2004-04-19 devnull int isave;
538 564ca709 2004-04-19 devnull if(args == 0)
539 564ca709 2004-04-19 devnull error("interpret(string): arg count");
540 564ca709 2004-04-19 devnull expr(args, &res);
541 564ca709 2004-04-19 devnull if(res.type != TSTRING)
542 564ca709 2004-04-19 devnull error("interpret(string): arg type");
544 564ca709 2004-04-19 devnull pushstr(&res);
546 564ca709 2004-04-19 devnull isave = interactive;
547 564ca709 2004-04-19 devnull interactive = 0;
548 564ca709 2004-04-19 devnull r->store.u.ival = yyparse();
549 564ca709 2004-04-19 devnull interactive = isave;
550 564ca709 2004-04-19 devnull popio();
551 564ca709 2004-04-19 devnull r->op = OCONST;
552 564ca709 2004-04-19 devnull r->type = TINT;
553 564ca709 2004-04-19 devnull r->store.fmt = 'D';
557 564ca709 2004-04-19 devnull include(Node *r, Node *args)
559 a8c15b08 2004-04-21 devnull char *file, *libfile;
560 a8c15b08 2004-04-21 devnull static char buf[1024];
561 564ca709 2004-04-19 devnull Node res;
562 564ca709 2004-04-19 devnull int isave;
564 564ca709 2004-04-19 devnull if(args == 0)
565 564ca709 2004-04-19 devnull error("include(string): arg count");
566 564ca709 2004-04-19 devnull expr(args, &res);
567 564ca709 2004-04-19 devnull if(res.type != TSTRING)
568 564ca709 2004-04-19 devnull error("include(string): arg type");
570 564ca709 2004-04-19 devnull Bflush(bout);
572 a8c15b08 2004-04-21 devnull libfile = nil;
573 a8c15b08 2004-04-21 devnull file = res.store.u.string->string;
574 a8c15b08 2004-04-21 devnull if(access(file, AREAD) < 0 && file[0] != '/'){
575 a8c15b08 2004-04-21 devnull snprint(buf, sizeof buf, "#9/acid/%s", file);
576 a8c15b08 2004-04-21 devnull libfile = unsharp(buf);
577 a8c15b08 2004-04-21 devnull if(access(libfile, AREAD) >= 0){
578 a8c15b08 2004-04-21 devnull strecpy(buf, buf+sizeof buf, libfile);
579 a8c15b08 2004-04-21 devnull file = buf;
581 a8c15b08 2004-04-21 devnull free(libfile);
584 a9df759c 2004-04-21 devnull pushfile(file);
585 564ca709 2004-04-19 devnull isave = interactive;
586 564ca709 2004-04-19 devnull interactive = 0;
587 564ca709 2004-04-19 devnull r->store.u.ival = yyparse();
588 564ca709 2004-04-19 devnull interactive = isave;
589 564ca709 2004-04-19 devnull popio();
590 564ca709 2004-04-19 devnull r->op = OCONST;
591 564ca709 2004-04-19 devnull r->type = TINT;
592 564ca709 2004-04-19 devnull r->store.fmt = 'D';
596 564ca709 2004-04-19 devnull includepipe(Node *r, Node *args)
598 564ca709 2004-04-19 devnull Node res;
599 564ca709 2004-04-19 devnull int i, isave, pid, pip[2];
600 564ca709 2004-04-19 devnull char *argv[4];
601 564ca709 2004-04-19 devnull Waitmsg *w;
603 564ca709 2004-04-19 devnull USED(r);
604 564ca709 2004-04-19 devnull if(args == 0)
605 564ca709 2004-04-19 devnull error("includepipe(string): arg count");
606 564ca709 2004-04-19 devnull expr(args, &res);
607 564ca709 2004-04-19 devnull if(res.type != TSTRING)
608 564ca709 2004-04-19 devnull error("includepipe(string): arg type");
610 564ca709 2004-04-19 devnull Bflush(bout);
612 564ca709 2004-04-19 devnull argv[0] = "rc";
613 564ca709 2004-04-19 devnull argv[1] = "-c";
614 564ca709 2004-04-19 devnull argv[2] = res.store.u.string->string;
615 564ca709 2004-04-19 devnull argv[3] = 0;
617 564ca709 2004-04-19 devnull if(pipe(pip) < 0)
618 564ca709 2004-04-19 devnull error("pipe: %r");
620 564ca709 2004-04-19 devnull pid = fork();
621 564ca709 2004-04-19 devnull switch(pid) {
622 564ca709 2004-04-19 devnull case -1:
623 564ca709 2004-04-19 devnull close(pip[0]);
624 564ca709 2004-04-19 devnull close(pip[1]);
625 564ca709 2004-04-19 devnull error("fork: %r");
627 564ca709 2004-04-19 devnull close(pip[0]);
628 564ca709 2004-04-19 devnull close(0);
629 564ca709 2004-04-19 devnull open("/dev/null", OREAD);
630 564ca709 2004-04-19 devnull dup(pip[1], 1);
631 564ca709 2004-04-19 devnull if(pip[1] > 1)
632 564ca709 2004-04-19 devnull close(pip[1]);
633 564ca709 2004-04-19 devnull for(i=3; i<100; i++)
634 564ca709 2004-04-19 devnull close(i);
635 564ca709 2004-04-19 devnull exec("rc", argv);
636 564ca709 2004-04-19 devnull sysfatal("exec rc: %r");
639 564ca709 2004-04-19 devnull close(pip[1]);
640 564ca709 2004-04-19 devnull pushfd(pip[0]);
642 564ca709 2004-04-19 devnull isave = interactive;
643 564ca709 2004-04-19 devnull interactive = 0;
644 564ca709 2004-04-19 devnull r->store.u.ival = yyparse();
645 564ca709 2004-04-19 devnull interactive = isave;
646 564ca709 2004-04-19 devnull popio();
648 564ca709 2004-04-19 devnull r->op = OCONST;
649 564ca709 2004-04-19 devnull r->type = TINT;
650 564ca709 2004-04-19 devnull r->store.fmt = 'D';
652 564ca709 2004-04-19 devnull w = waitfor(pid);
653 564ca709 2004-04-19 devnull if(w->msg && w->msg[0])
654 564ca709 2004-04-19 devnull error("includepipe(\"%s\"): %s", argv[2], w->msg); /* leaks w */
655 564ca709 2004-04-19 devnull free(w);
659 564ca709 2004-04-19 devnull rc(Node *r, Node *args)
661 564ca709 2004-04-19 devnull Node res;
662 564ca709 2004-04-19 devnull int pid;
663 564ca709 2004-04-19 devnull char *p, *q, *argv[4];
664 564ca709 2004-04-19 devnull Waitmsg *w;
666 564ca709 2004-04-19 devnull USED(r);
667 564ca709 2004-04-19 devnull if(args == 0)
668 564ca709 2004-04-19 devnull error("rc(string): arg count");
669 564ca709 2004-04-19 devnull expr(args, &res);
670 564ca709 2004-04-19 devnull if(res.type != TSTRING)
671 564ca709 2004-04-19 devnull error("rc(string): arg type");
673 564ca709 2004-04-19 devnull argv[0] = "rc";
674 564ca709 2004-04-19 devnull argv[1] = "-c";
675 564ca709 2004-04-19 devnull argv[2] = res.store.u.string->string;
676 564ca709 2004-04-19 devnull argv[3] = 0;
678 564ca709 2004-04-19 devnull pid = fork();
679 564ca709 2004-04-19 devnull switch(pid) {
680 564ca709 2004-04-19 devnull case -1:
681 564ca709 2004-04-19 devnull error("fork %r");
683 564ca709 2004-04-19 devnull exec("rc", argv);
684 564ca709 2004-04-19 devnull exits(0);
685 564ca709 2004-04-19 devnull default:
686 564ca709 2004-04-19 devnull w = waitfor(pid);
689 564ca709 2004-04-19 devnull p = w->msg;
690 564ca709 2004-04-19 devnull q = strrchr(p, ':');
692 564ca709 2004-04-19 devnull p = q+1;
694 564ca709 2004-04-19 devnull r->op = OCONST;
695 564ca709 2004-04-19 devnull r->type = TSTRING;
696 564ca709 2004-04-19 devnull r->store.u.string = strnode(p);
697 564ca709 2004-04-19 devnull free(w);
698 564ca709 2004-04-19 devnull r->store.fmt = 's';
702 564ca709 2004-04-19 devnull doerror(Node *r, Node *args)
704 564ca709 2004-04-19 devnull Node res;
706 564ca709 2004-04-19 devnull USED(r);
707 564ca709 2004-04-19 devnull if(args == 0)
708 564ca709 2004-04-19 devnull error("error(string): arg count");
709 564ca709 2004-04-19 devnull expr(args, &res);
710 564ca709 2004-04-19 devnull if(res.type != TSTRING)
711 564ca709 2004-04-19 devnull error("error(string): arg type");
713 564ca709 2004-04-19 devnull error(res.store.u.string->string);
717 564ca709 2004-04-19 devnull doaccess(Node *r, Node *args)
719 564ca709 2004-04-19 devnull Node res;
721 564ca709 2004-04-19 devnull if(args == 0)
722 564ca709 2004-04-19 devnull error("access(filename): arg count");
723 564ca709 2004-04-19 devnull expr(args, &res);
724 564ca709 2004-04-19 devnull if(res.type != TSTRING)
725 564ca709 2004-04-19 devnull error("access(filename): arg type");
727 564ca709 2004-04-19 devnull r->op = OCONST;
728 564ca709 2004-04-19 devnull r->type = TINT;
729 6c885647 2004-04-20 devnull r->store.fmt = 'D';
730 564ca709 2004-04-19 devnull r->store.u.ival = 0;
731 564ca709 2004-04-19 devnull if(access(res.store.u.string->string, 4) == 0)
732 564ca709 2004-04-19 devnull r->store.u.ival = 1;
736 564ca709 2004-04-19 devnull readfile(Node *r, Node *args)
738 564ca709 2004-04-19 devnull Node res;
739 564ca709 2004-04-19 devnull int n, fd;
740 564ca709 2004-04-19 devnull char *buf;
741 564ca709 2004-04-19 devnull Dir *db;
743 564ca709 2004-04-19 devnull if(args == 0)
744 564ca709 2004-04-19 devnull error("readfile(filename): arg count");
745 564ca709 2004-04-19 devnull expr(args, &res);
746 564ca709 2004-04-19 devnull if(res.type != TSTRING)
747 564ca709 2004-04-19 devnull error("readfile(filename): arg type");
749 564ca709 2004-04-19 devnull fd = open(res.store.u.string->string, OREAD);
750 564ca709 2004-04-19 devnull if(fd < 0)
753 564ca709 2004-04-19 devnull db = dirfstat(fd);
754 564ca709 2004-04-19 devnull if(db == nil || db->length == 0)
755 564ca709 2004-04-19 devnull n = 8192;
757 564ca709 2004-04-19 devnull n = db->length;
758 564ca709 2004-04-19 devnull free(db);
760 564ca709 2004-04-19 devnull buf = malloc(n);
761 564ca709 2004-04-19 devnull n = read(fd, buf, n);
763 564ca709 2004-04-19 devnull if(n > 0) {
764 564ca709 2004-04-19 devnull r->op = OCONST;
765 564ca709 2004-04-19 devnull r->type = TSTRING;
766 564ca709 2004-04-19 devnull r->store.u.string = strnodlen(buf, n);
767 564ca709 2004-04-19 devnull r->store.fmt = 's';
769 564ca709 2004-04-19 devnull free(buf);
770 564ca709 2004-04-19 devnull close(fd);
774 564ca709 2004-04-19 devnull getfile(Node *r, Node *args)
777 564ca709 2004-04-19 devnull char *p;
778 564ca709 2004-04-19 devnull Node res;
779 564ca709 2004-04-19 devnull String *s;
780 564ca709 2004-04-19 devnull Biobuf *bp;
781 564ca709 2004-04-19 devnull List **l, *new;
783 564ca709 2004-04-19 devnull if(args == 0)
784 564ca709 2004-04-19 devnull error("file(filename): arg count");
785 564ca709 2004-04-19 devnull expr(args, &res);
786 564ca709 2004-04-19 devnull if(res.type != TSTRING)
787 564ca709 2004-04-19 devnull error("file(filename): arg type");
789 564ca709 2004-04-19 devnull r->op = OCONST;
790 564ca709 2004-04-19 devnull r->type = TLIST;
791 564ca709 2004-04-19 devnull r->store.u.l = 0;
793 564ca709 2004-04-19 devnull p = res.store.u.string->string;
794 564ca709 2004-04-19 devnull bp = Bopen(p, OREAD);
795 564ca709 2004-04-19 devnull if(bp == 0)
798 564ca709 2004-04-19 devnull l = &r->store.u.l;
799 564ca709 2004-04-19 devnull for(;;) {
800 564ca709 2004-04-19 devnull p = Brdline(bp, '\n');
801 564ca709 2004-04-19 devnull n = Blinelen(bp);
802 564ca709 2004-04-19 devnull if(p == 0) {
803 564ca709 2004-04-19 devnull if(n == 0)
805 564ca709 2004-04-19 devnull s = strnodlen(0, n);
806 564ca709 2004-04-19 devnull Bread(bp, s->string, n);
809 564ca709 2004-04-19 devnull s = strnodlen(p, n-1);
811 564ca709 2004-04-19 devnull new = al(TSTRING);
812 564ca709 2004-04-19 devnull new->store.u.string = s;
813 564ca709 2004-04-19 devnull new->store.fmt = 's';
814 564ca709 2004-04-19 devnull *l = new;
815 564ca709 2004-04-19 devnull l = &new->next;
817 564ca709 2004-04-19 devnull Bterm(bp);
821 564ca709 2004-04-19 devnull cvtatof(Node *r, Node *args)
823 564ca709 2004-04-19 devnull Node res;
825 564ca709 2004-04-19 devnull if(args == 0)
826 564ca709 2004-04-19 devnull error("atof(string): arg count");
827 564ca709 2004-04-19 devnull expr(args, &res);
828 564ca709 2004-04-19 devnull if(res.type != TSTRING)
829 564ca709 2004-04-19 devnull error("atof(string): arg type");
831 564ca709 2004-04-19 devnull r->op = OCONST;
832 564ca709 2004-04-19 devnull r->type = TFLOAT;
833 564ca709 2004-04-19 devnull r->store.u.fval = atof(res.store.u.string->string);
834 564ca709 2004-04-19 devnull r->store.fmt = 'f';
838 564ca709 2004-04-19 devnull cvtatoi(Node *r, Node *args)
840 564ca709 2004-04-19 devnull Node res;
842 564ca709 2004-04-19 devnull if(args == 0)
843 564ca709 2004-04-19 devnull error("atoi(string): arg count");
844 564ca709 2004-04-19 devnull expr(args, &res);
845 564ca709 2004-04-19 devnull if(res.type != TSTRING)
846 564ca709 2004-04-19 devnull error("atoi(string): arg type");
848 564ca709 2004-04-19 devnull r->op = OCONST;
849 564ca709 2004-04-19 devnull r->type = TINT;
850 564ca709 2004-04-19 devnull r->store.u.ival = strtoul(res.store.u.string->string, 0, 0);
851 564ca709 2004-04-19 devnull r->store.fmt = 'D';
855 564ca709 2004-04-19 devnull cvtitoa(Node *r, Node *args)
857 564ca709 2004-04-19 devnull Node res;
858 564ca709 2004-04-19 devnull Node *av[Maxarg];
859 564ca709 2004-04-19 devnull int ival;
860 564ca709 2004-04-19 devnull char buf[128], *fmt;
862 564ca709 2004-04-19 devnull if(args == 0)
864 564ca709 2004-04-19 devnull error("itoa(number [, printformat]): arg count");
866 564ca709 2004-04-19 devnull flatten(av, args);
867 564ca709 2004-04-19 devnull if(na == 0 || na > 2)
868 564ca709 2004-04-19 devnull goto err;
869 564ca709 2004-04-19 devnull expr(av[0], &res);
870 564ca709 2004-04-19 devnull if(res.type != TINT)
871 564ca709 2004-04-19 devnull error("itoa(integer): arg type");
872 564ca709 2004-04-19 devnull ival = (int)res.store.u.ival;
873 564ca709 2004-04-19 devnull fmt = "%d";
874 564ca709 2004-04-19 devnull if(na == 2){
875 564ca709 2004-04-19 devnull expr(av[1], &res);
876 564ca709 2004-04-19 devnull if(res.type != TSTRING)
877 564ca709 2004-04-19 devnull error("itoa(integer, string): arg type");
878 564ca709 2004-04-19 devnull fmt = res.store.u.string->string;
881 564ca709 2004-04-19 devnull sprint(buf, fmt, ival);
882 564ca709 2004-04-19 devnull r->op = OCONST;
883 564ca709 2004-04-19 devnull r->type = TSTRING;
884 564ca709 2004-04-19 devnull r->store.u.string = strnode(buf);
885 564ca709 2004-04-19 devnull r->store.fmt = 's';
889 564ca709 2004-04-19 devnull mapent(Map *m)
892 564ca709 2004-04-19 devnull List *l, *n, **t, *h;
896 564ca709 2004-04-19 devnull for(i = 0; i < m->nseg; i++) {
897 564ca709 2004-04-19 devnull l = al(TSTRING);
898 564ca709 2004-04-19 devnull n = al(TLIST);
899 564ca709 2004-04-19 devnull n->store.u.l = l;
901 564ca709 2004-04-19 devnull t = &n->next;
902 564ca709 2004-04-19 devnull l->store.u.string = strnode(m->seg[i].name);
903 564ca709 2004-04-19 devnull l->store.fmt = 's';
904 564ca709 2004-04-19 devnull l->next = al(TSTRING);
905 564ca709 2004-04-19 devnull l = l->next;
906 564ca709 2004-04-19 devnull l->store.u.string = strnode(m->seg[i].file ? m->seg[i].file : "");
907 564ca709 2004-04-19 devnull l->store.fmt = 's';
908 564ca709 2004-04-19 devnull l->next = al(TINT);
909 564ca709 2004-04-19 devnull l = l->next;
910 564ca709 2004-04-19 devnull l->store.u.ival = m->seg[i].base;
911 564ca709 2004-04-19 devnull l->store.fmt = 'X';
912 564ca709 2004-04-19 devnull l->next = al(TINT);
913 564ca709 2004-04-19 devnull l = l->next;
914 564ca709 2004-04-19 devnull l->store.u.ival = m->seg[i].base + m->seg[i].size;
915 564ca709 2004-04-19 devnull l->store.fmt = 'X';
916 564ca709 2004-04-19 devnull l->next = al(TINT);
917 564ca709 2004-04-19 devnull l = l->next;
918 564ca709 2004-04-19 devnull l->store.u.ival = m->seg[i].offset;
919 564ca709 2004-04-19 devnull l->store.fmt = 'X';
921 564ca709 2004-04-19 devnull return h;
925 564ca709 2004-04-19 devnull map(Node *r, Node *args)
929 564ca709 2004-04-19 devnull List *l;
930 564ca709 2004-04-19 devnull char *nam, *fil;
931 564ca709 2004-04-19 devnull Node *av[Maxarg], res;
934 564ca709 2004-04-19 devnull flatten(av, args);
936 564ca709 2004-04-19 devnull if(na != 0) {
937 564ca709 2004-04-19 devnull expr(av[0], &res);
938 564ca709 2004-04-19 devnull if(res.type != TLIST)
939 564ca709 2004-04-19 devnull error("map(list): map needs a list");
940 564ca709 2004-04-19 devnull if(listlen(res.store.u.l) != 5)
941 564ca709 2004-04-19 devnull error("map(list): list must have 5 entries");
943 564ca709 2004-04-19 devnull l = res.store.u.l;
944 564ca709 2004-04-19 devnull if(l->type != TSTRING)
945 564ca709 2004-04-19 devnull error("map name must be a string");
946 564ca709 2004-04-19 devnull nam = l->store.u.string->string;
947 564ca709 2004-04-19 devnull l = l->next;
948 564ca709 2004-04-19 devnull if(l->type != TSTRING)
949 564ca709 2004-04-19 devnull error("map file must be a string");
950 564ca709 2004-04-19 devnull fil = l->store.u.string->string;
951 564ca709 2004-04-19 devnull m = symmap;
952 564ca709 2004-04-19 devnull i = findseg(m, nam, fil);
953 564ca709 2004-04-19 devnull if(i < 0) {
954 564ca709 2004-04-19 devnull m = cormap;
955 564ca709 2004-04-19 devnull i = findseg(m, nam, fil);
957 564ca709 2004-04-19 devnull if(i < 0)
958 564ca709 2004-04-19 devnull error("%s %s is not a map entry", nam, fil);
959 564ca709 2004-04-19 devnull l = l->next;
960 564ca709 2004-04-19 devnull if(l->type != TINT)
961 564ca709 2004-04-19 devnull error("map entry not int");
962 564ca709 2004-04-19 devnull m->seg[i].base = l->store.u.ival;
964 564ca709 2004-04-19 devnull if (strcmp(ent, "text") == 0)
965 564ca709 2004-04-19 devnull textseg(l->store.u.ival, &fhdr);
967 564ca709 2004-04-19 devnull l = l->next;
968 564ca709 2004-04-19 devnull if(l->type != TINT)
969 564ca709 2004-04-19 devnull error("map entry not int");
970 564ca709 2004-04-19 devnull m->seg[i].size = l->store.u.ival - m->seg[i].base;
971 564ca709 2004-04-19 devnull l = l->next;
972 564ca709 2004-04-19 devnull if(l->type != TINT)
973 564ca709 2004-04-19 devnull error("map entry not int");
974 564ca709 2004-04-19 devnull m->seg[i].offset = l->store.u.ival;
977 564ca709 2004-04-19 devnull r->type = TLIST;
978 564ca709 2004-04-19 devnull r->store.u.l = 0;
979 564ca709 2004-04-19 devnull if(symmap)
980 564ca709 2004-04-19 devnull r->store.u.l = mapent(symmap);
981 564ca709 2004-04-19 devnull if(cormap) {
982 564ca709 2004-04-19 devnull if(r->store.u.l == 0)
983 564ca709 2004-04-19 devnull r->store.u.l = mapent(cormap);
985 564ca709 2004-04-19 devnull for(l = r->store.u.l; l->next; l = l->next)
987 564ca709 2004-04-19 devnull l->next = mapent(cormap);
993 564ca709 2004-04-19 devnull flatten(Node **av, Node *n)
995 564ca709 2004-04-19 devnull if(n == 0)
998 564ca709 2004-04-19 devnull switch(n->op) {
999 564ca709 2004-04-19 devnull case OLIST:
1000 564ca709 2004-04-19 devnull flatten(av, n->left);
1001 564ca709 2004-04-19 devnull flatten(av, n->right);
1003 564ca709 2004-04-19 devnull default:
1004 564ca709 2004-04-19 devnull av[na++] = n;
1005 564ca709 2004-04-19 devnull if(na >= Maxarg)
1006 564ca709 2004-04-19 devnull error("too many function arguments");
1011 564ca709 2004-04-19 devnull static struct
1013 564ca709 2004-04-19 devnull char *name;
1014 564ca709 2004-04-19 devnull ulong val;
1015 564ca709 2004-04-19 devnull } sregs[Maxarg/2];
1016 564ca709 2004-04-19 devnull static int nsregs;
1018 564ca709 2004-04-19 devnull static int
1019 564ca709 2004-04-19 devnull straceregrw(Regs *regs, char *name, ulong *val, int isr)
1023 564ca709 2004-04-19 devnull if(!isr){
1024 564ca709 2004-04-19 devnull werrstr("saved registers cannot be written");
1025 564ca709 2004-04-19 devnull return -1;
1027 564ca709 2004-04-19 devnull for(i=0; i<nsregs; i++)
1028 564ca709 2004-04-19 devnull if(strcmp(sregs[i].name, name) == 0){
1029 564ca709 2004-04-19 devnull *val = sregs[i].val;
1030 564ca709 2004-04-19 devnull return 0;
1032 4f2ac1b7 2005-01-23 devnull return rget(acidregs, name, val);
1036 564ca709 2004-04-19 devnull strace(Node *r, Node *args)
1038 564ca709 2004-04-19 devnull Node *av[Maxarg], res;
1039 564ca709 2004-04-19 devnull List *l;
1040 564ca709 2004-04-19 devnull Regs regs;
1042 564ca709 2004-04-19 devnull na = 0;
1043 564ca709 2004-04-19 devnull flatten(av, args);
1045 564ca709 2004-04-19 devnull if(na != 1)
1046 564ca709 2004-04-19 devnull error("strace(list): want one arg");
1048 564ca709 2004-04-19 devnull expr(av[0], &res);
1049 564ca709 2004-04-19 devnull if(res.type != TLIST)
1050 564ca709 2004-04-19 devnull error("strace(list): strace needs a list");
1051 564ca709 2004-04-19 devnull l = res.store.u.l;
1052 564ca709 2004-04-19 devnull if(listlen(l)%2)
1053 564ca709 2004-04-19 devnull error("strace(list): strace needs an even-length list");
1054 564ca709 2004-04-19 devnull for(nsregs=0; l; nsregs++){
1055 564ca709 2004-04-19 devnull if(l->type != TSTRING)
1056 564ca709 2004-04-19 devnull error("strace({r,v,r,v,...}): non-string name");
1057 564ca709 2004-04-19 devnull sregs[nsregs].name = l->store.u.string->string;
1058 564ca709 2004-04-19 devnull if(regdesc(sregs[nsregs].name) == nil)
1059 564ca709 2004-04-19 devnull error("strace: bad register '%s'", sregs[nsregs].name);
1060 564ca709 2004-04-19 devnull l = l->next;
1062 564ca709 2004-04-19 devnull if(l == nil)
1063 564ca709 2004-04-19 devnull error("cannot happen in strace");
1064 564ca709 2004-04-19 devnull if(l->type != TINT)
1065 564ca709 2004-04-19 devnull error("strace: non-int value for %s", sregs[nsregs].name);
1066 564ca709 2004-04-19 devnull sregs[nsregs].val = l->store.u.ival;
1067 564ca709 2004-04-19 devnull l = l->next;
1069 564ca709 2004-04-19 devnull regs.rw = straceregrw;
1071 564ca709 2004-04-19 devnull tracelist = 0;
1072 564ca709 2004-04-19 devnull if(stacktrace(cormap, ®s, trlist) <= 0)
1073 564ca709 2004-04-19 devnull error("no stack frame");
1074 564ca709 2004-04-19 devnull r->type = TLIST;
1075 564ca709 2004-04-19 devnull r->store.u.l = tracelist;
1079 564ca709 2004-04-19 devnull regerror(char *msg)
1081 564ca709 2004-04-19 devnull error(msg);
1085 564ca709 2004-04-19 devnull regexp(Node *r, Node *args)
1087 564ca709 2004-04-19 devnull Node res;
1088 564ca709 2004-04-19 devnull Reprog *rp;
1089 564ca709 2004-04-19 devnull Node *av[Maxarg];
1091 564ca709 2004-04-19 devnull na = 0;
1092 564ca709 2004-04-19 devnull flatten(av, args);
1093 564ca709 2004-04-19 devnull if(na != 2)
1094 564ca709 2004-04-19 devnull error("regexp(pattern, string): arg count");
1095 564ca709 2004-04-19 devnull expr(av[0], &res);
1096 564ca709 2004-04-19 devnull if(res.type != TSTRING)
1097 564ca709 2004-04-19 devnull error("regexp(pattern, string): pattern must be string");
1098 564ca709 2004-04-19 devnull rp = regcomp(res.store.u.string->string);
1099 564ca709 2004-04-19 devnull if(rp == 0)
1100 564ca709 2004-04-19 devnull return;
1102 564ca709 2004-04-19 devnull expr(av[1], &res);
1103 564ca709 2004-04-19 devnull if(res.type != TSTRING)
1104 564ca709 2004-04-19 devnull error("regexp(pattern, string): bad string");
1106 564ca709 2004-04-19 devnull r->store.fmt = 'D';
1107 564ca709 2004-04-19 devnull r->type = TINT;
1108 564ca709 2004-04-19 devnull r->store.u.ival = regexec(rp, res.store.u.string->string, 0, 0);
1109 564ca709 2004-04-19 devnull free(rp);
1112 564ca709 2004-04-19 devnull char vfmt[] = "aBbcCdDfFgGiIoOqQrRsSuUVxXYZ";
1115 564ca709 2004-04-19 devnull fmt(Node *r, Node *args)
1117 564ca709 2004-04-19 devnull Node res;
1118 564ca709 2004-04-19 devnull Node *av[Maxarg];
1120 564ca709 2004-04-19 devnull na = 0;
1121 564ca709 2004-04-19 devnull flatten(av, args);
1122 564ca709 2004-04-19 devnull if(na != 2)
1123 564ca709 2004-04-19 devnull error("fmt(obj, fmt): arg count");
1124 564ca709 2004-04-19 devnull expr(av[1], &res);
1125 564ca709 2004-04-19 devnull if(res.type != TINT || strchr(vfmt, res.store.u.ival) == 0)
1126 564ca709 2004-04-19 devnull error("fmt(obj, fmt): bad format '%c'", (char)res.store.u.ival);
1127 564ca709 2004-04-19 devnull expr(av[0], r);
1128 564ca709 2004-04-19 devnull r->store.fmt = res.store.u.ival;
1132 564ca709 2004-04-19 devnull patom(char type, Store *res)
1135 564ca709 2004-04-19 devnull char buf[512];
1136 564ca709 2004-04-19 devnull extern char *typenames[];
1137 4f2ac1b7 2005-01-23 devnull Node *n;
1139 4f2ac1b7 2005-01-23 devnull switch(type){
1140 4f2ac1b7 2005-01-23 devnull case TREG:
1141 281c90a5 2005-02-11 devnull if(res->u.reg.thread)
1142 7b8a3f12 2005-02-11 devnull Bprint(bout, "register(\"%s\", %#ux)", res->u.reg.name, res->u.reg.thread);
1144 281c90a5 2005-02-11 devnull Bprint(bout, "register(\"%s\")", res->u.reg.name);
1145 4f2ac1b7 2005-01-23 devnull return;
1146 4f2ac1b7 2005-01-23 devnull case TCON:
1147 4f2ac1b7 2005-01-23 devnull Bprint(bout, "refconst(");
1148 4f2ac1b7 2005-01-23 devnull n = res->u.con;
1149 4f2ac1b7 2005-01-23 devnull patom(n->type, &n->store);
1150 4f2ac1b7 2005-01-23 devnull Bprint(bout, ")");
1151 4f2ac1b7 2005-01-23 devnull return;
1154 4f2ac1b7 2005-01-23 devnull switch(res->fmt){
1155 4f2ac1b7 2005-01-23 devnull case 'c':
1156 4f2ac1b7 2005-01-23 devnull case 'C':
1157 4f2ac1b7 2005-01-23 devnull case 'r':
1158 4f2ac1b7 2005-01-23 devnull case 'B':
1159 4f2ac1b7 2005-01-23 devnull case 'b':
1160 4f2ac1b7 2005-01-23 devnull case 'X':
1161 4f2ac1b7 2005-01-23 devnull case 'x':
1162 4f2ac1b7 2005-01-23 devnull case 'W':
1163 4f2ac1b7 2005-01-23 devnull case 'D':
1164 4f2ac1b7 2005-01-23 devnull case 'd':
1165 4f2ac1b7 2005-01-23 devnull case 'u':
1166 4f2ac1b7 2005-01-23 devnull case 'U':
1167 4f2ac1b7 2005-01-23 devnull case 'Z':
1168 4f2ac1b7 2005-01-23 devnull case 'V':
1169 4f2ac1b7 2005-01-23 devnull case 'Y':
1170 4f2ac1b7 2005-01-23 devnull case 'o':
1171 4f2ac1b7 2005-01-23 devnull case 'O':
1172 4f2ac1b7 2005-01-23 devnull case 'q':
1173 4f2ac1b7 2005-01-23 devnull case 'Q':
1174 4f2ac1b7 2005-01-23 devnull case 'a':
1175 4f2ac1b7 2005-01-23 devnull case 'A':
1176 4f2ac1b7 2005-01-23 devnull case 'I':
1177 4f2ac1b7 2005-01-23 devnull case 'i':
1178 4f2ac1b7 2005-01-23 devnull if(type != TINT){
1179 4f2ac1b7 2005-01-23 devnull badtype:
1180 4f2ac1b7 2005-01-23 devnull Bprint(bout, "*%s\\%c*", typenames[(uchar)type], res->fmt);
1181 4f2ac1b7 2005-01-23 devnull return;
1185 4f2ac1b7 2005-01-23 devnull case 'f':
1186 4f2ac1b7 2005-01-23 devnull case 'F':
1187 4f2ac1b7 2005-01-23 devnull if(type != TFLOAT)
1188 4f2ac1b7 2005-01-23 devnull goto badtype;
1191 4f2ac1b7 2005-01-23 devnull case 's':
1192 4f2ac1b7 2005-01-23 devnull case 'g':
1193 4f2ac1b7 2005-01-23 devnull case 'G':
1194 4f2ac1b7 2005-01-23 devnull case 'R':
1195 4f2ac1b7 2005-01-23 devnull if(type != TSTRING)
1196 4f2ac1b7 2005-01-23 devnull goto badtype;
1200 564ca709 2004-04-19 devnull switch(res->fmt) {
1201 564ca709 2004-04-19 devnull case 'c':
1202 564ca709 2004-04-19 devnull Bprint(bout, "%c", (int)res->u.ival);
1204 564ca709 2004-04-19 devnull case 'C':
1205 564ca709 2004-04-19 devnull if(res->u.ival < ' ' || res->u.ival >= 0x7f)
1206 564ca709 2004-04-19 devnull Bprint(bout, "%3d", (int)res->u.ival&0xff);
1208 564ca709 2004-04-19 devnull Bprint(bout, "%3c", (int)res->u.ival);
1210 564ca709 2004-04-19 devnull case 'r':
1211 564ca709 2004-04-19 devnull Bprint(bout, "%C", (int)res->u.ival);
1213 564ca709 2004-04-19 devnull case 'B':
1214 564ca709 2004-04-19 devnull memset(buf, '0', 34);
1215 564ca709 2004-04-19 devnull buf[1] = 'b';
1216 564ca709 2004-04-19 devnull for(i = 0; i < 32; i++) {
1217 564ca709 2004-04-19 devnull if(res->u.ival & (1<<i))
1218 564ca709 2004-04-19 devnull buf[33-i] = '1';
1220 564ca709 2004-04-19 devnull buf[35] = '\0';
1221 564ca709 2004-04-19 devnull Bprint(bout, "%s", buf);
1223 564ca709 2004-04-19 devnull case 'b':
1224 7b8a3f12 2005-02-11 devnull Bprint(bout, "%#.2x", (int)res->u.ival&0xff);
1226 564ca709 2004-04-19 devnull case 'X':
1227 7b8a3f12 2005-02-11 devnull Bprint(bout, "%#.8lux", (ulong)res->u.ival);
1229 564ca709 2004-04-19 devnull case 'x':
1230 7b8a3f12 2005-02-11 devnull Bprint(bout, "%#.4lux", (ulong)res->u.ival&0xffff);
1232 564ca709 2004-04-19 devnull case 'W':
1233 7b8a3f12 2005-02-11 devnull Bprint(bout, "%#.16llux", res->u.ival);
1235 564ca709 2004-04-19 devnull case 'D':
1236 564ca709 2004-04-19 devnull Bprint(bout, "%d", (int)res->u.ival);
1238 564ca709 2004-04-19 devnull case 'd':
1239 564ca709 2004-04-19 devnull Bprint(bout, "%d", (ushort)res->u.ival);
1241 564ca709 2004-04-19 devnull case 'u':
1242 564ca709 2004-04-19 devnull Bprint(bout, "%d", (int)res->u.ival&0xffff);
1244 564ca709 2004-04-19 devnull case 'U':
1245 564ca709 2004-04-19 devnull Bprint(bout, "%lud", (ulong)res->u.ival);
1247 564ca709 2004-04-19 devnull case 'Z':
1248 564ca709 2004-04-19 devnull Bprint(bout, "%llud", res->u.ival);
1250 564ca709 2004-04-19 devnull case 'V':
1251 564ca709 2004-04-19 devnull Bprint(bout, "%lld", res->u.ival);
1253 564ca709 2004-04-19 devnull case 'Y':
1254 7b8a3f12 2005-02-11 devnull Bprint(bout, "%#.16llux", res->u.ival);
1256 564ca709 2004-04-19 devnull case 'o':
1257 7b8a3f12 2005-02-11 devnull Bprint(bout, "%#.11uo", (int)res->u.ival&0xffff);
1259 564ca709 2004-04-19 devnull case 'O':
1260 7b8a3f12 2005-02-11 devnull Bprint(bout, "%#.6uo", (int)res->u.ival);
1262 564ca709 2004-04-19 devnull case 'q':
1263 7b8a3f12 2005-02-11 devnull Bprint(bout, "%#.11o", (short)(res->u.ival&0xffff));
1265 564ca709 2004-04-19 devnull case 'Q':
1266 7b8a3f12 2005-02-11 devnull Bprint(bout, "%#.6o", (int)res->u.ival);
1268 564ca709 2004-04-19 devnull case 'f':
1269 564ca709 2004-04-19 devnull case 'F':
1270 4f2ac1b7 2005-01-23 devnull Bprint(bout, "%g", res->u.fval);
1272 564ca709 2004-04-19 devnull case 's':
1273 564ca709 2004-04-19 devnull case 'g':
1274 564ca709 2004-04-19 devnull case 'G':
1275 4f2ac1b7 2005-01-23 devnull Bwrite(bout, res->u.string->string, res->u.string->len);
1277 564ca709 2004-04-19 devnull case 'R':
1278 4f2ac1b7 2005-01-23 devnull Bprint(bout, "%S", (Rune*)res->u.string->string);
1280 564ca709 2004-04-19 devnull case 'a':
1281 564ca709 2004-04-19 devnull case 'A':
1282 564ca709 2004-04-19 devnull symoff(buf, sizeof(buf), res->u.ival, CANY);
1283 564ca709 2004-04-19 devnull Bprint(bout, "%s", buf);
1285 564ca709 2004-04-19 devnull case 'I':
1286 564ca709 2004-04-19 devnull case 'i':
1287 4f2ac1b7 2005-01-23 devnull if (symmap == nil || (*mach->das)(symmap, res->u.ival, res->fmt, buf, sizeof(buf)) < 0)
1288 4f2ac1b7 2005-01-23 devnull Bprint(bout, "no instruction");
1290 4f2ac1b7 2005-01-23 devnull Bprint(bout, "%s", buf);
1296 564ca709 2004-04-19 devnull blprint(List *l)
1298 564ca709 2004-04-19 devnull Store *res;
1300 564ca709 2004-04-19 devnull Bprint(bout, "{");
1301 564ca709 2004-04-19 devnull while(l) {
1302 564ca709 2004-04-19 devnull switch(l->type) {
1303 564ca709 2004-04-19 devnull case TINT:
1304 564ca709 2004-04-19 devnull res = &l->store;
1305 564ca709 2004-04-19 devnull if(res->fmt == 'c'){
1306 564ca709 2004-04-19 devnull Bprint(bout, "\'%c\'", (int)res->u.ival);
1308 564ca709 2004-04-19 devnull }else if(res->fmt == 'r'){
1309 564ca709 2004-04-19 devnull Bprint(bout, "\'%C\'", (int)res->u.ival);
1312 564ca709 2004-04-19 devnull /* fall through */
1313 564ca709 2004-04-19 devnull default:
1314 564ca709 2004-04-19 devnull patom(l->type, &l->store);
1316 564ca709 2004-04-19 devnull case TSTRING:
1317 564ca709 2004-04-19 devnull Bputc(bout, '"');
1318 564ca709 2004-04-19 devnull patom(l->type, &l->store);
1319 564ca709 2004-04-19 devnull Bputc(bout, '"');
1321 564ca709 2004-04-19 devnull case TLIST:
1322 564ca709 2004-04-19 devnull blprint(l->store.u.l);
1324 564ca709 2004-04-19 devnull case TCODE:
1325 564ca709 2004-04-19 devnull pcode(l->store.u.cc, 0);
1328 564ca709 2004-04-19 devnull l = l->next;
1330 564ca709 2004-04-19 devnull Bprint(bout, ", ");
1332 564ca709 2004-04-19 devnull Bprint(bout, "}");
1336 564ca709 2004-04-19 devnull comx(Node res)
1338 564ca709 2004-04-19 devnull Lsym *sl;
1339 564ca709 2004-04-19 devnull Node *n, xx;
1341 564ca709 2004-04-19 devnull if(res.store.fmt != 'a' && res.store.fmt != 'A')
1342 564ca709 2004-04-19 devnull return 0;
1344 564ca709 2004-04-19 devnull if(res.store.comt == 0 || res.store.comt->base == 0)
1345 564ca709 2004-04-19 devnull return 0;
1347 564ca709 2004-04-19 devnull sl = res.store.comt->base;
1348 564ca709 2004-04-19 devnull if(sl->proc) {
1349 564ca709 2004-04-19 devnull res.left = ZN;
1350 564ca709 2004-04-19 devnull res.right = ZN;
1351 564ca709 2004-04-19 devnull n = an(ONAME, ZN, ZN);
1352 564ca709 2004-04-19 devnull n->sym = sl;
1353 564ca709 2004-04-19 devnull n = an(OCALL, n, &res);
1354 564ca709 2004-04-19 devnull n->left->sym = sl;
1355 564ca709 2004-04-19 devnull expr(n, &xx);
1356 564ca709 2004-04-19 devnull return 1;
1358 564ca709 2004-04-19 devnull print("(%s)", sl->name);
1359 564ca709 2004-04-19 devnull return 0;
1363 564ca709 2004-04-19 devnull bprint(Node *r, Node *args)
1365 564ca709 2004-04-19 devnull int i, nas;
1366 564ca709 2004-04-19 devnull Node res, *av[Maxarg];
1368 564ca709 2004-04-19 devnull USED(r);
1369 564ca709 2004-04-19 devnull na = 0;
1370 564ca709 2004-04-19 devnull flatten(av, args);
1371 564ca709 2004-04-19 devnull nas = na;
1372 564ca709 2004-04-19 devnull for(i = 0; i < nas; i++) {
1373 564ca709 2004-04-19 devnull expr(av[i], &res);
1374 564ca709 2004-04-19 devnull switch(res.type) {
1375 564ca709 2004-04-19 devnull default:
1376 564ca709 2004-04-19 devnull if(comx(res))
1378 564ca709 2004-04-19 devnull patom(res.type, &res.store);
1380 564ca709 2004-04-19 devnull case TCODE:
1381 564ca709 2004-04-19 devnull pcode(res.store.u.cc, 0);
1383 564ca709 2004-04-19 devnull case TLIST:
1384 564ca709 2004-04-19 devnull blprint(res.store.u.l);
1388 564ca709 2004-04-19 devnull if(ret == 0)
1389 564ca709 2004-04-19 devnull Bputc(bout, '\n');
1393 564ca709 2004-04-19 devnull printto(Node *r, Node *args)
1395 564ca709 2004-04-19 devnull int fd;
1396 564ca709 2004-04-19 devnull Biobuf *b;
1397 564ca709 2004-04-19 devnull int i, nas;
1398 564ca709 2004-04-19 devnull Node res, *av[Maxarg];
1400 564ca709 2004-04-19 devnull USED(r);
1401 564ca709 2004-04-19 devnull na = 0;
1402 564ca709 2004-04-19 devnull flatten(av, args);
1403 564ca709 2004-04-19 devnull nas = na;
1405 564ca709 2004-04-19 devnull expr(av[0], &res);
1406 564ca709 2004-04-19 devnull if(res.type != TSTRING)
1407 564ca709 2004-04-19 devnull error("printto(string, ...): need string");
1409 564ca709 2004-04-19 devnull fd = create(res.store.u.string->string, OWRITE, 0666);
1410 564ca709 2004-04-19 devnull if(fd < 0)
1411 564ca709 2004-04-19 devnull fd = open(res.store.u.string->string, OWRITE);
1412 564ca709 2004-04-19 devnull if(fd < 0)
1413 564ca709 2004-04-19 devnull error("printto: open %s: %r", res.store.u.string->string);
1415 564ca709 2004-04-19 devnull b = gmalloc(sizeof(Biobuf));
1416 564ca709 2004-04-19 devnull Binit(b, fd, OWRITE);
1418 564ca709 2004-04-19 devnull Bflush(bout);
1419 564ca709 2004-04-19 devnull io[iop++] = bout;
1420 564ca709 2004-04-19 devnull bout = b;
1422 564ca709 2004-04-19 devnull for(i = 1; i < nas; i++) {
1423 564ca709 2004-04-19 devnull expr(av[i], &res);
1424 564ca709 2004-04-19 devnull switch(res.type) {
1425 564ca709 2004-04-19 devnull default:
1426 564ca709 2004-04-19 devnull if(comx(res))
1428 564ca709 2004-04-19 devnull patom(res.type, &res.store);
1430 564ca709 2004-04-19 devnull case TLIST:
1431 564ca709 2004-04-19 devnull blprint(res.store.u.l);
1435 564ca709 2004-04-19 devnull if(ret == 0)
1436 564ca709 2004-04-19 devnull Bputc(bout, '\n');
1438 564ca709 2004-04-19 devnull Bterm(b);
1439 564ca709 2004-04-19 devnull close(fd);
1440 564ca709 2004-04-19 devnull free(b);
1441 564ca709 2004-04-19 devnull bout = io[--iop];
1445 564ca709 2004-04-19 devnull pcfile(Node *r, Node *args)
1447 564ca709 2004-04-19 devnull Node res;
1448 564ca709 2004-04-19 devnull char *p, buf[128];
1450 564ca709 2004-04-19 devnull if(args == 0)
1451 564ca709 2004-04-19 devnull error("pcfile(addr): arg count");
1452 564ca709 2004-04-19 devnull expr(args, &res);
1453 564ca709 2004-04-19 devnull if(res.type != TINT)
1454 564ca709 2004-04-19 devnull error("pcfile(addr): arg type");
1456 564ca709 2004-04-19 devnull r->type = TSTRING;
1457 564ca709 2004-04-19 devnull r->store.fmt = 's';
1458 564ca709 2004-04-19 devnull if(fileline(res.store.u.ival, buf, sizeof(buf)) < 0) {
1459 564ca709 2004-04-19 devnull r->store.u.string = strnode("?file?");
1460 564ca709 2004-04-19 devnull return;
1462 564ca709 2004-04-19 devnull p = strrchr(buf, ':');
1463 564ca709 2004-04-19 devnull if(p == 0)
1464 564ca709 2004-04-19 devnull error("pcfile(addr): funny file %s", buf);
1465 564ca709 2004-04-19 devnull *p = '\0';
1466 564ca709 2004-04-19 devnull r->store.u.string = strnode(buf);
1470 564ca709 2004-04-19 devnull pcline(Node *r, Node *args)
1472 564ca709 2004-04-19 devnull Node res;
1473 564ca709 2004-04-19 devnull char *p, buf[128];
1475 564ca709 2004-04-19 devnull if(args == 0)
1476 564ca709 2004-04-19 devnull error("pcline(addr): arg count");
1477 564ca709 2004-04-19 devnull expr(args, &res);
1478 564ca709 2004-04-19 devnull if(res.type != TINT)
1479 564ca709 2004-04-19 devnull error("pcline(addr): arg type");
1481 564ca709 2004-04-19 devnull r->type = TINT;
1482 564ca709 2004-04-19 devnull r->store.fmt = 'D';
1483 564ca709 2004-04-19 devnull if(fileline(res.store.u.ival, buf, sizeof(buf)) < 0) {
1484 564ca709 2004-04-19 devnull r->store.u.ival = 0;
1485 564ca709 2004-04-19 devnull return;
1488 564ca709 2004-04-19 devnull p = strrchr(buf, ':');
1489 564ca709 2004-04-19 devnull if(p == 0)
1490 564ca709 2004-04-19 devnull error("pcline(addr): funny file %s", buf);
1491 564ca709 2004-04-19 devnull r->store.u.ival = atoi(p+1);
1495 564ca709 2004-04-19 devnull textfile(Node *r, Node *args)
1497 564ca709 2004-04-19 devnull char *file;
1498 564ca709 2004-04-19 devnull long base;
1499 564ca709 2004-04-19 devnull Fhdr *fp;
1500 564ca709 2004-04-19 devnull Node res, *av[Maxarg];
1501 564ca709 2004-04-19 devnull List *l, *l2, **tail, *list, *tl;
1503 564ca709 2004-04-19 devnull na = 0;
1504 564ca709 2004-04-19 devnull flatten(av, args);
1506 564ca709 2004-04-19 devnull if(na != 0) {
1507 564ca709 2004-04-19 devnull expr(av[0], &res);
1508 564ca709 2004-04-19 devnull if(res.type != TLIST)
1509 564ca709 2004-04-19 devnull error("textfile(list): textfile needs a list");
1510 564ca709 2004-04-19 devnull if(listlen(res.store.u.l) != 2)
1511 564ca709 2004-04-19 devnull error("textfile(list): list must have 2 entries");
1513 564ca709 2004-04-19 devnull l = res.store.u.l;
1514 564ca709 2004-04-19 devnull if(l->type != TSTRING)
1515 564ca709 2004-04-19 devnull error("textfile name must be a string");
1516 564ca709 2004-04-19 devnull file = l->store.u.string->string;
1518 564ca709 2004-04-19 devnull l = l->next;
1519 564ca709 2004-04-19 devnull if(l->type != TINT)
1520 564ca709 2004-04-19 devnull error("textfile base must be an int");
1521 564ca709 2004-04-19 devnull base = l->store.u.ival;
1523 564ca709 2004-04-19 devnull if((fp = crackhdr(file, OREAD)) == nil)
1524 564ca709 2004-04-19 devnull error("crackhdr %s: %r", file);
1525 564ca709 2004-04-19 devnull Bflush(bout);
1526 564ca709 2004-04-19 devnull fp->base = base;
1527 564ca709 2004-04-19 devnull fprint(2, "%s: %s %s %s\n", file, fp->aname, fp->mname, fp->fname);
1528 564ca709 2004-04-19 devnull if(mapfile(fp, base, symmap, nil) < 0)
1529 564ca709 2004-04-19 devnull fprint(2, "mapping %s: %r\n", file);
1530 564ca709 2004-04-19 devnull if(corhdr){
1531 564ca709 2004-04-19 devnull unmapfile(corhdr, cormap);
1532 564ca709 2004-04-19 devnull mapfile(fp, base, cormap, nil);
1533 564ca709 2004-04-19 devnull free(correg);
1534 4f2ac1b7 2005-01-23 devnull correg = nil;
1535 564ca709 2004-04-19 devnull mapfile(corhdr, 0, cormap, &correg);
1537 8b549a62 2005-01-07 devnull if(symopen(fp) < 0)
1538 8b549a62 2005-01-07 devnull fprint(2, "symopen %s: %r\n", file);
1540 564ca709 2004-04-19 devnull addvarsym(fp);
1541 564ca709 2004-04-19 devnull return;
1544 564ca709 2004-04-19 devnull l2 = nil;
1545 564ca709 2004-04-19 devnull tail = &l2;
1546 564ca709 2004-04-19 devnull for(fp=fhdrlist; fp; fp=fp->next){
1547 564ca709 2004-04-19 devnull if(fp->ftype == FCORE)
1548 564ca709 2004-04-19 devnull continue;
1549 564ca709 2004-04-19 devnull tl = al(TLIST);
1550 564ca709 2004-04-19 devnull *tail = tl;
1551 564ca709 2004-04-19 devnull tail = &tl->next;
1553 564ca709 2004-04-19 devnull list = al(TSTRING);
1554 564ca709 2004-04-19 devnull tl->store.u.l = list;
1555 564ca709 2004-04-19 devnull list->store.u.string = strnode(fp->filename);
1556 564ca709 2004-04-19 devnull list->store.fmt = 's';
1557 564ca709 2004-04-19 devnull list->next = al(TINT);
1558 564ca709 2004-04-19 devnull list = list->next;
1559 564ca709 2004-04-19 devnull list->store.fmt = 'X';
1560 564ca709 2004-04-19 devnull list->store.u.ival = fp->base;
1563 564ca709 2004-04-19 devnull r->type = TLIST;
1564 564ca709 2004-04-19 devnull r->store.u.l = l2;
1568 564ca709 2004-04-19 devnull deltextfile(Node *r, Node *args)
1570 564ca709 2004-04-19 devnull int did;
1571 564ca709 2004-04-19 devnull char *file;
1572 564ca709 2004-04-19 devnull Fhdr *fp, *fpnext;
1573 564ca709 2004-04-19 devnull Node res, *av[Maxarg];
1575 564ca709 2004-04-19 devnull na = 0;
1576 564ca709 2004-04-19 devnull flatten(av, args);
1578 564ca709 2004-04-19 devnull if(na != 1)
1579 564ca709 2004-04-19 devnull error("deltextfile(string): arg count");
1581 564ca709 2004-04-19 devnull expr(av[0], &res);
1582 564ca709 2004-04-19 devnull if(res.type != TSTRING)
1583 564ca709 2004-04-19 devnull error("deltextfile(string): arg type");
1584 564ca709 2004-04-19 devnull file = res.store.u.string->string;
1586 564ca709 2004-04-19 devnull did = 0;
1587 564ca709 2004-04-19 devnull for(fp=fhdrlist; fp; fp=fpnext){
1588 564ca709 2004-04-19 devnull fpnext = fp->next;
1589 564ca709 2004-04-19 devnull if(fp->ftype == FCORE)
1590 564ca709 2004-04-19 devnull continue;
1591 564ca709 2004-04-19 devnull if(strcmp(file, fp->filename) == 0){
1592 564ca709 2004-04-19 devnull did = 1;
1593 564ca709 2004-04-19 devnull if(fp == symhdr)
1594 564ca709 2004-04-19 devnull error("cannot remove symbols from main text file");
1595 564ca709 2004-04-19 devnull unmapfile(fp, symmap);
1596 564ca709 2004-04-19 devnull uncrackhdr(fp);
1600 564ca709 2004-04-19 devnull delvarsym(file);
1601 564ca709 2004-04-19 devnull if(!did)
1602 564ca709 2004-04-19 devnull error("symbol file %s not open", file);
1606 709efa01 2004-09-23 devnull stringn(Node *r, Node *args)
1608 709efa01 2004-09-23 devnull uint addr;
1609 709efa01 2004-09-23 devnull int i, n, ret;
1610 709efa01 2004-09-23 devnull Node res, *av[Maxarg];
1611 709efa01 2004-09-23 devnull char *buf;
1613 709efa01 2004-09-23 devnull na = 0;
1614 709efa01 2004-09-23 devnull flatten(av, args);
1615 709efa01 2004-09-23 devnull if(na != 2)
1616 709efa01 2004-09-23 devnull error("stringn(addr, n): arg count");
1618 709efa01 2004-09-23 devnull expr(av[0], &res);
1619 709efa01 2004-09-23 devnull if(res.type != TINT)
1620 709efa01 2004-09-23 devnull error("stringn(addr, n): arg type");
1621 709efa01 2004-09-23 devnull addr = res.store.u.ival;
1623 709efa01 2004-09-23 devnull expr(av[1], &res);
1624 709efa01 2004-09-23 devnull if(res.type != TINT)
1625 709efa01 2004-09-23 devnull error("stringn(addr,n): arg type");
1626 709efa01 2004-09-23 devnull n = res.store.u.ival;
1628 709efa01 2004-09-23 devnull buf = malloc(n+1);
1629 709efa01 2004-09-23 devnull if(buf == nil)
1630 709efa01 2004-09-23 devnull error("out of memory");
1632 709efa01 2004-09-23 devnull r->type = TSTRING;
1633 709efa01 2004-09-23 devnull for(i=0; i<n; i++){
1634 4f2ac1b7 2005-01-23 devnull ret = get1(cormap, addr, (uchar*)&buf[i], 1);
1635 709efa01 2004-09-23 devnull if(ret < 0){
1636 709efa01 2004-09-23 devnull free(buf);
1637 709efa01 2004-09-23 devnull error("indir: %r");
1639 709efa01 2004-09-23 devnull addr++;
1641 709efa01 2004-09-23 devnull buf[n] = 0;
1642 709efa01 2004-09-23 devnull r->store.u.string = strnode(buf);
1643 709efa01 2004-09-23 devnull free(buf);