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