]> git.lizzy.rs Git - plan9front.git/blob - sys/lib/acid/port
dist/mkfile: run binds in subshell
[plan9front.git] / sys / lib / acid / port
1 // portable acid for all architectures
2
3 defn pfl(addr)
4 {
5         print(pcfile(addr), ":", pcline(addr), "\n");
6 }
7
8 defn
9 notestk(addr)
10 {
11         local pc, sp;
12         complex Ureg addr;
13
14         pc = addr.pc\X;
15         sp = addr.sp\X;
16
17         print("Note pc:", pc, " sp:", sp, " ", fmt(pc, 'a'), " ");
18         pfl(pc);
19         _stk(pc, sp, linkreg(addr), 1);
20 }
21
22 defn
23 notelstk(addr)
24 {
25         local pc, sp;
26         complex Ureg addr;
27
28         pc = addr.pc\X;
29         sp = addr.sp\X;
30
31         print("Note pc:", pc, " sp:", sp, " ", fmt(pc, 'a'), " ");
32         pfl(pc);
33         _stk(pc, sp, linkreg(addr), 1);
34 }
35
36 defn labstk(l)                          // trace from a label
37 {
38         _stk(*(l+4), *l, linkreg(0), 0);
39 }
40
41 defn params(param)
42 {
43         while param do {
44                 sym = head param;
45                 print(sym[0], "=", itoa(sym[1], "%ux"));
46                 param = tail param;
47                 if param then
48                         print (",");
49         }       
50 }
51
52 stkprefix = "";
53 stkignore = {};
54 stkend = 0;
55
56 defn locals(l)
57 {
58         local sym;
59
60         while l do {
61                 sym = head l;
62                 print(stkprefix, "\t", sym[0], "=", itoa(sym[1], "%ux"), "\n");
63                 l = tail l;
64         }       
65 }
66
67 defn _stkign(file)
68 {
69         s = stkignore;
70         while s do {
71                 if regexp(head s, file) then
72                         return 1;
73                 s = tail s;
74         }
75         return 0;
76 }
77
78 // print a stack trace
79 //
80 // in a run of leading frames in files matched by regexps in stkignore,
81 // only print the last one.
82 defn _stk(pc, sp, link, dolocals)
83 {
84         local stk, ign, last, lastpc;
85
86         stk = strace(pc, sp, link);
87         if stkignore then
88                 ign = 1;
89         else
90                 ign = 0;
91         last = stk;
92         lastpc = pc;
93         while stk do {
94                 if ign then {
95                         if !_stkign(pcfile(pc)) then {
96                                 ign = 0;
97                                 stk = last;
98                                 pc = lastpc;
99                         }
100                 }
101                 frame = head stk;
102                 if !ign then {
103                         print(stkprefix, fmt(frame[0], 'a'), "(");
104                         params(frame[2]);
105                         print(")+", itoa(pc-frame[0], "%ux"), " ");
106                         pfl(pc);
107                         if dolocals then
108                                 locals(frame[3]);
109                 }
110                 last = stk;
111                 lastpc = pc;
112                 stk = tail stk;
113                 pc = frame[1];
114         }
115         print(stkprefix, fmt(pc, 'a'), " ");
116         pfl(pc);
117 }
118
119 defn findsrc(file)
120 {
121         local lst, src;
122
123         if file[0] == '/' then {
124                 src = file(file);
125                 if src != {} then {
126                         srcfiles = append srcfiles, file;
127                         srctext = append srctext, src;
128                         return src;
129                 }
130                 return {};
131         }
132
133         lst = srcpath;
134         while head lst do {
135                 src = file(head lst+file);
136                 if src != {} then {
137                         srcfiles = append srcfiles, file;
138                         srctext = append srctext, src;
139                         return src;
140                 }
141                 lst = tail lst;
142         }
143 }
144
145 defn line(addr)
146 {
147         local src, file;
148
149         file = pcfile(addr);
150         src = match(file, srcfiles);
151
152         if src >= 0 then
153                 src = srctext[src];
154         else
155                 src = findsrc(file);
156
157         if src == {} then {
158                 print("no source for ", file, "\n");
159                 return {};
160         }
161         line = pcline(addr)-1;
162         print(file, ":", src[line], "\n");
163 }
164
165 defn addsrcdir(dir)
166 {
167         dir = dir+"/";
168
169         if match(dir, srcpath) >= 0 then {
170                 print("already in srcpath\n");
171                 return {};
172         }
173
174         srcpath = {dir}+srcpath;
175 }
176
177 defn source()
178 {
179         local l;
180
181         l = srcpath;
182         while l do {
183                 print(head l, "\n");
184                 l = tail l;
185         }
186         l = srcfiles;
187
188         while l do {
189                 print("\t", head l, "\n");
190                 l = tail l;
191         }
192 }
193
194 defn Bsrc(addr)
195 {
196         local lst;
197
198         lst = srcpath;
199         file = pcfile(addr);
200         if file[0] == '/' && access(file) then {
201                 rc("B "+file+":"+itoa(pcline(addr)));
202                 return {};
203         }
204         while head lst do {
205                 name = head lst+file;
206                 if access(name) then {
207                         rc("B "+name+":"+itoa(pcline(addr)));
208                         return {};
209                 }
210                 lst = tail lst;
211         }
212         print("no source for ", file, "\n");
213 }
214
215 defn srcline(addr)
216 {
217         local text, cline, line, file, src;
218         file = pcfile(addr);
219         src = match(file,srcfiles);
220         if (src>=0) then
221                 src = srctext[src];
222         else
223                 src = findsrc(file);
224         if (src=={}) then
225         {
226                 return "(no source)";
227         }
228         return src[pcline(addr)-1];
229 }
230
231 defn src(addr)
232 {
233         local src, file, line, cline, text;
234
235         file = pcfile(addr);
236         src = match(file, srcfiles);
237
238         if src >= 0 then
239                 src = srctext[src];
240         else
241                 src = findsrc(file);
242
243         if src == {} then {
244                 print("no source for ", file, "\n");
245                 return {};
246         }
247
248         cline = pcline(addr)-1;
249         print(file, ":", cline+1, "\n");
250         line = cline-5;
251         loop 0,10 do {
252                 if line >= 0 then {
253                         text = src[line];
254                         if text == {} then
255                                 return {};
256                         if line == cline then
257                                 print(">");
258                         else
259                                 print(" ");
260                         print(line+1, "\t", text, "\n");
261                 }
262                 line = line+1;
263         }       
264 }
265
266 defn step()                                     // single step the process
267 {
268         local lst, lpl, addr, bput;
269
270         bput = 0;
271         if match(*PC, bplist) >= 0 then {       // Sitting on a breakpoint
272                 bput = fmt(*PC, bpfmt);
273                 *bput = @bput;
274         }
275
276         lst = follow(*PC);
277
278         lpl = lst;
279         while lpl do {                          // place break points
280                 *(head lpl) = bpinst;
281                 lpl = tail lpl;
282         }
283
284         startstop(pid);                         // do the step
285
286         while lst do {                          // remove the breakpoints
287                 addr = fmt(head lst, bpfmt);
288                 *addr = @addr;
289                 lst = tail lst;
290         }
291         if bput != 0 then
292                 *bput = bpinst;
293 }
294
295 defn bpset(addr)                                // set a breakpoint
296 {
297         if status(pid) != "Stopped" then {
298                 print("Waiting...\n");
299                 stop(pid);
300         }
301         if match(addr, bplist) >= 0 then
302                 print("breakpoint already set at ", fmt(addr, 'a'), "\n");
303         else {
304                 *fmt(addr, bpfmt) = bpinst;
305                 bplist = append bplist, addr;
306         }
307 }
308
309 defn bptab()                                    // print a table of breakpoints
310 {
311         local lst, addr;
312
313         lst = bplist;
314         while lst do {
315                 addr = head lst;
316                 print("\t", fmt(addr, 'X'), " ", fmt(addr, 'a'), "  ", fmt(addr, 'i'), "\n");
317                 lst = tail lst;
318         }
319 }
320
321 defn bpdel(addr)                                // delete a breakpoint
322 {
323         local n, pc, nbplist;
324
325         n = match(addr, bplist);
326         if n < 0  then {
327                 print("no breakpoint at ", fmt(addr, 'a'), "\n");
328                 return {};
329         }
330
331         addr = fmt(addr, bpfmt);
332         *addr = @addr;
333
334         nbplist = {};                           // delete from list
335         while bplist do {
336                 pc = head bplist;
337                 if pc != addr then
338                         nbplist = append nbplist, pc;
339                 bplist = tail bplist;
340         }
341         bplist = nbplist;                       // delete from memory
342 }
343
344 defn cont()                                     // continue execution
345 {
346         local addr;
347
348         addr = fmt(*PC, bpfmt);
349         if match(addr, bplist) >= 0 then {      // Sitting on a breakpoint
350                 *addr = @addr;
351                 step();                         // Step over
352                 *addr = bpinst;
353         }
354         startstop(pid);                         // Run
355 }
356
357 defn stopped(pid)               // called from acid when a process changes state
358 {
359         pstop(pid);             // stub so this is easy to replace
360 }
361
362 defn procs()                    // print status of processes
363 {
364         local c, lst, cpid;
365
366         cpid = pid;
367         lst = proclist;
368         while lst do {
369                 np = head lst;
370                 setproc(np);
371                 if np == cpid then
372                         c = '>';
373                 else
374                         c = ' ';
375                 print(fmt(c, 'c'), np, ": ", status(np), " at ", fmt(*PC, 'a'), " setproc(", np, ")\n");
376                 lst = tail lst;
377         }
378         pid = cpid;
379         if pid != 0 then
380                 setproc(pid);
381 }
382
383 _asmlines = 30;
384
385 defn asm(addr)
386 {
387         local bound;
388
389         bound = fnbound(addr);
390
391         addr = fmt(addr, 'i');
392         loop 1,_asmlines do {
393                 print(fmt(addr, 'a'), " ", fmt(addr, 'X'));
394                 print("\t", @addr++, "\n");
395                 if bound != {} && addr > bound[1] then {
396                         lasmaddr = addr;
397                         return {};
398                 }
399         }
400         lasmaddr = addr;
401 }
402
403 defn casm()
404 {
405         asm(lasmaddr);
406 }
407
408 defn win()
409 {
410         local npid, estr;
411
412         bplist = {};
413         notes = {};
414
415         estr = "/sys/lib/acid/window '0 0 600 400' "+textfile;
416         if progargs != "" then
417                 estr = estr+" "+progargs;
418
419         npid = rc(estr);
420         npid = atoi(npid);
421         if npid == 0 then
422                 error("win failed to create process");
423
424         setproc(npid);
425         stopped(npid);
426 }
427
428 defn win2()
429 {
430         local npid, estr;
431
432         bplist = {};
433         notes = {};
434
435         estr = "/sys/lib/acid/transcript '0 0 600 400' '100 100 700 500' "+textfile;
436         if progargs != "" then
437                 estr = estr+" "+progargs;
438
439         npid = rc(estr);
440         npid = atoi(npid);
441         if npid == 0 then
442                 error("win failed to create process");
443
444         setproc(npid);
445         stopped(npid);
446 }
447
448 defn new()
449 {
450         bplist = {};
451         newproc(progargs);
452         // Dont miss the delay slot calls
453         bpset(follow(main)[0]);
454         cont();
455         bpdel(*PC);
456 }
457
458 defn stmnt()                    // step one statement
459 {
460         local line;
461
462         line = pcline(*PC);
463         while 1 do {
464                 step();
465                 if line != pcline(*PC) then {
466                         src(*PC);
467                         return {};
468                 }
469         }
470 }
471
472 defn func()                     // step until we leave the current function
473 {
474         local bound, end, start, pc;
475
476         bound = fnbound(*PC);
477         if bound == {} then {
478                 print("cannot locate text symbol\n");
479                 return {};
480         }
481
482         pc = *PC;
483         start = bound[0];
484         end = bound[1];
485         while pc >= start && pc < end do {
486                 step();
487                 pc = *PC;
488         }
489 }
490
491 defn next()
492 {
493         local sp, bound;
494
495         sp = *SP;
496         bound = fnbound(*PC);
497         stmnt();
498         pc = *PC;
499         if pc >= bound[0] && pc < bound[1] then
500                 return {};
501
502         while (pc < bound[0] || pc > bound[1]) && sp >= *SP do {
503                 step();
504                 pc = *PC;
505         }
506         src(*PC);
507 }
508
509 defn dump(addr, n, fmt)
510 {
511         // see definition of dump in acid manual: it does n+1 iterations
512         loop 0, n do {
513                 print(fmt(addr, 'X'), ": ");
514                 addr = mem(addr, fmt);
515         }
516 }
517
518 defn mem(addr, fmt)
519 {
520
521         local i, c, n;
522
523         i = 0;
524         while fmt[i] != 0 do {
525                 c = fmt[i];
526                 n = 0;
527                 while '0' <= fmt[i] && fmt[i] <= '9' do {
528                         n = 10*n + fmt[i]-'0';
529                         i = i+1;
530                 }
531                 if n <= 0 then n = 1;
532                 addr = fmt(addr, fmt[i]);
533                 while n > 0 do {
534                         print(*addr++, " ");
535                         n = n-1;
536                 }
537                 i = i+1;
538         }
539         print("\n");
540         return addr;
541 }
542
543 defn symbols(pattern)
544 {
545         local l, s;
546
547         l = symbols;
548         while l do {
549                 s = head l;
550                 if regexp(pattern, s[0]) then
551                         print(s[0], "\t", s[1], "\t", s[2], "\n");
552                 l = tail l;
553         }
554 }
555
556 defn spsrch(len)
557 {
558         local addr, a, s, e;
559
560         addr = *SP;
561         s = origin & 0x7fffffff;
562         e = etext & 0x7fffffff;
563         loop 1, len do {
564                 a = *addr++;
565                 c = a & 0x7fffffff;
566                 if c > s && c < e then {
567                         print("src(", a, ")\n");
568                         pfl(a);
569                 }                       
570         }
571 }
572
573 progargs="";
574 print("/sys/lib/acid/port");