Commit | Line | Data |
---|---|---|
128eca8b | 1 | static char sccsid[] = "@(#)print.c 4.4 %G%"; |
81f0c5ba BJ |
2 | /* |
3 | * | |
4 | * UNIX debugger | |
5 | * | |
6 | */ | |
7 | #include "defs.h" | |
8 | ||
9 | MSG LONGFIL; | |
10 | MSG NOTOPEN; | |
11 | MSG A68BAD; | |
12 | MSG A68LNK; | |
13 | MSG BADMOD; | |
14 | ||
15 | MAP txtmap; | |
16 | MAP datmap; | |
17 | ||
18 | ADDR lastframe; | |
19 | ADDR callpc; | |
20 | ||
21 | INT infile; | |
22 | INT outfile; | |
23 | CHAR *lp; | |
24 | L_INT maxoff; | |
25 | L_INT maxpos; | |
26 | INT radix; | |
27 | ||
28 | /* symbol management */ | |
29 | L_INT localval; | |
30 | ||
31 | /* breakpoints */ | |
32 | BKPTR bkpthead; | |
33 | ||
34 | REGLIST reglist [] = { | |
6eadceb1 BJ |
35 | "p1lr", P1LR, &pcb.pcb_p1lr, |
36 | "p1br", P1BR, &pcb.pcb_p1br, | |
37 | "p0lr", P0LR, &pcb.pcb_p0lr, | |
38 | "p0br", P0BR, &pcb.pcb_p0br, | |
39 | "ksp", KSP, &pcb.pcb_ksp, | |
40 | "esp", ESP, &pcb.pcb_esp, | |
41 | "ssp", SSP, &pcb.pcb_ssp, | |
42 | "psl", PSL, &pcb.pcb_psl, | |
43 | "pc", PC, &pcb.pcb_pc, | |
44 | "usp", USP, &pcb.pcb_usp, | |
45 | "fp", FP, &pcb.pcb_fp, | |
46 | "ap", AP, &pcb.pcb_ap, | |
47 | "r11", R11, &pcb.pcb_r11, | |
48 | "r10", R10, &pcb.pcb_r10, | |
49 | "r9", R9, &pcb.pcb_r9, | |
50 | "r8", R8, &pcb.pcb_r8, | |
51 | "r7", R7, &pcb.pcb_r7, | |
52 | "r6", R6, &pcb.pcb_r6, | |
53 | "r5", R5, &pcb.pcb_r5, | |
54 | "r4", R4, &pcb.pcb_r4, | |
55 | "r3", R3, &pcb.pcb_r3, | |
56 | "r2", R2, &pcb.pcb_r2, | |
57 | "r1", R1, &pcb.pcb_r1, | |
58 | "r0", R0, &pcb.pcb_r0, | |
81f0c5ba BJ |
59 | }; |
60 | ||
61 | char lastc; | |
62 | ||
63 | INT fcor; | |
64 | STRING errflg; | |
65 | INT signo; | |
66 | INT sigcode; | |
67 | ||
68 | ||
69 | L_INT dot; | |
70 | L_INT var[]; | |
71 | STRING symfil; | |
72 | STRING corfil; | |
73 | INT pid; | |
74 | L_INT adrval; | |
75 | INT adrflg; | |
76 | L_INT cntval; | |
77 | INT cntflg; | |
78 | ||
79 | STRING signals[] = { | |
80 | "", | |
81 | "hangup", | |
82 | "interrupt", | |
83 | "quit", | |
84 | "illegal instruction", | |
85 | "trace/BPT", | |
86 | "IOT", | |
87 | "EMT", | |
88 | "floating exception", | |
89 | "killed", | |
90 | "bus error", | |
91 | "memory fault", | |
92 | "bad system call", | |
93 | "broken pipe", | |
94 | "alarm call", | |
95 | "terminated", | |
96 | "signal 16", | |
97 | "stop (signal)", | |
98 | "stop (tty)", | |
99 | "continue (signal)", | |
100 | "child termination", | |
101 | "stop (tty input)", | |
102 | "stop (tty output)", | |
103 | "input available (signal)", | |
104 | "cpu timelimit", | |
105 | "file sizelimit", | |
106 | "signal 26", | |
107 | "signal 27", | |
108 | "signal 28", | |
109 | "signal 29", | |
110 | "signal 30", | |
111 | "signal 31", | |
112 | }; | |
113 | ||
114 | /* general printing routines ($) */ | |
115 | ||
116 | printtrace(modif) | |
117 | { | |
118 | INT narg, i, stat, name, limit; | |
119 | POS dynam; | |
120 | REG BKPTR bkptr; | |
121 | CHAR hi, lo; | |
122 | ADDR word; | |
123 | STRING comptr; | |
124 | ADDR argp, frame, link; | |
125 | register struct nlist *sp; | |
126 | INT stack; | |
127 | INT ntramp; | |
128 | ||
129 | IF cntflg==0 THEN cntval = -1; FI | |
130 | ||
131 | switch (modif) { | |
132 | ||
133 | case '<': | |
134 | IF cntval == 0 | |
135 | THEN WHILE readchar() != EOR | |
136 | DO OD | |
137 | lp--; | |
138 | break; | |
139 | FI | |
140 | IF rdc() == '<' | |
141 | THEN stack = 1; | |
142 | ELSE stack = 0; lp--; | |
143 | FI | |
144 | /* fall through */ | |
145 | case '>': | |
146 | {CHAR file[64]; | |
147 | CHAR Ifile[128]; | |
148 | extern CHAR *Ipath; | |
149 | INT index; | |
150 | ||
151 | index=0; | |
152 | IF modif=='<' | |
153 | THEN iclose(stack, 0); | |
154 | ELSE oclose(); | |
155 | FI | |
156 | IF rdc()!=EOR | |
157 | THEN REP file[index++]=lastc; | |
158 | IF index>=63 THEN error(LONGFIL); FI | |
159 | PER readchar()!=EOR DONE | |
160 | file[index]=0; | |
161 | IF modif=='<' | |
162 | THEN IF Ipath THEN | |
163 | strcpy(Ifile, Ipath); | |
164 | strcat(Ifile, "/"); | |
165 | strcat(Ifile, file); | |
166 | FI | |
167 | infile=open(file,0); | |
168 | IF infile<0 && (infile=open(Ifile,0))<0 | |
169 | THEN infile=0; error(NOTOPEN); | |
170 | ELSE IF cntflg | |
171 | THEN var[9] = cntval; | |
172 | ELSE var[9] = 1; | |
173 | FI | |
174 | FI | |
175 | ELSE outfile=open(file,1); | |
176 | IF outfile<0 | |
177 | THEN outfile=creat(file,0644); | |
178 | #ifndef EDDT | |
179 | ELSE lseek(outfile,0L,2); | |
180 | #endif | |
181 | FI | |
182 | FI | |
183 | ||
184 | ELSE IF modif == '<' | |
185 | THEN iclose(-1, 0); | |
186 | FI | |
187 | FI | |
188 | lp--; | |
189 | } | |
190 | break; | |
191 | ||
128eca8b BJ |
192 | case 'p': |
193 | IF kernel == 0 THEN | |
194 | printf("not debugging kernel\n"); | |
195 | ELSE | |
196 | IF adrflg THEN | |
197 | int pte = access(RD, dot, DSP, 0); | |
198 | masterpcbb = (pte&PG_PFNUM)*512; | |
199 | FI | |
200 | getpcb(); | |
201 | FI | |
202 | break; | |
203 | ||
81f0c5ba BJ |
204 | case 'd': |
205 | if (adrflg) { | |
206 | if (adrval<2 || adrval>16) {printf("must have 2 <= radix <= 16"); break;} | |
207 | printf("radix=%d base ten",radix=adrval); | |
208 | } | |
209 | break; | |
210 | ||
211 | case 'q': case 'Q': case '%': | |
212 | done(); | |
213 | ||
214 | case 'w': case 'W': | |
215 | maxpos=(adrflg?adrval:MAXPOS); | |
216 | break; | |
217 | ||
218 | case 's': case 'S': | |
219 | maxoff=(adrflg?adrval:MAXOFF); | |
220 | break; | |
221 | ||
222 | case 'v': case 'V': | |
223 | prints("variables\n"); | |
224 | FOR i=0;i<=35;i++ | |
225 | DO IF var[i] | |
226 | THEN printc((i<=9 ? '0' : 'a'-10) + i); | |
227 | printf(" = %Q\n",var[i]); | |
228 | FI | |
229 | OD | |
230 | break; | |
231 | ||
232 | case 'm': case 'M': | |
233 | printmap("? map",&txtmap); | |
234 | printmap("/ map",&datmap); | |
235 | break; | |
236 | ||
237 | case 0: case '?': | |
238 | IF pid | |
239 | THEN printf("pcs id = %d\n",pid); | |
240 | ELSE prints("no process\n"); | |
241 | FI | |
242 | sigprint(); flushbuf(); | |
243 | ||
244 | case 'r': case 'R': | |
245 | printregs(); | |
246 | return; | |
247 | ||
248 | case 'c': case 'C': | |
249 | IF adrflg | |
250 | THEN frame=adrval; | |
251 | word=get(adrval+6,DSP)&0xFFFF; | |
252 | IF word&0x2000 | |
253 | THEN /* 'calls', can figure out argp */ | |
254 | argp=adrval+20+((word>>14)&3); word &= 0xFFF; | |
255 | WHILE word DO IF word&1 THEN argp+=4; FI word>>=1; OD | |
256 | ELSE /* 'callg', can't tell where argp is */ argp=frame; | |
257 | FI | |
258 | callpc=get(frame+16,DSP); | |
128eca8b BJ |
259 | ELIF kcore THEN |
260 | argp = pcb.pcb_ap; | |
261 | frame = pcb.pcb_fp; | |
262 | callpc = pcb.pcb_pc; | |
263 | ELSE argp= *(ADDR *)(((ADDR)&u)+AP); | |
81f0c5ba BJ |
264 | frame= *(ADDR *)(((ADDR)&u)+FP); |
265 | callpc= *(ADDR *)(((ADDR)&u)+PC); | |
266 | FI | |
267 | lastframe=0; | |
268 | ntramp = 0; | |
269 | WHILE cntval-- | |
270 | DO char *name; | |
271 | chkerr(); | |
272 | if (callpc > 0x80000000 - 0x200 * UPAGES) { | |
273 | name = "sigtramp"; | |
274 | ntramp++; | |
275 | } else { | |
276 | ntramp = 0; | |
277 | findsym(callpc,ISYM); | |
278 | if (cursym && | |
279 | !strcmp(cursym->n_un.n_name, "start")) | |
280 | break; | |
281 | if (cursym) | |
282 | name = cursym->n_un.n_name; | |
283 | else | |
284 | name = "?"; | |
285 | } | |
286 | printf("%s(", name); | |
287 | narg = get(argp,DSP); IF narg&~0xFF THEN narg=0; FI | |
288 | LOOP IF narg==0 THEN break; FI | |
289 | printf("%R", get(argp += 4, DSP)); | |
290 | IF --narg!=0 THEN printc(','); FI | |
291 | POOL | |
292 | printf(") from %X\n",callpc); /* jkf mod */ | |
293 | ||
294 | IF modif=='C' | |
295 | THEN WHILE localsym(frame,argp) | |
296 | DO word=get(localval,DSP); | |
297 | printf("%8t%s:%10t", cursym->n_un.n_name); | |
298 | IF errflg THEN prints("?\n"); errflg=0; ELSE printf("%R\n",word); FI | |
299 | OD | |
300 | FI | |
301 | ||
302 | if (ntramp == 1) | |
303 | callpc=get(frame+64, DSP); | |
304 | else | |
305 | callpc=get(frame+16, DSP); | |
306 | argp=get(frame+8, DSP); | |
307 | lastframe=frame; | |
308 | frame=get(frame+12, DSP)&EVEN; | |
309 | IF frame==0 ORF (!adrflg ANDF !INSTACK(frame)) | |
310 | THEN break; | |
311 | FI | |
312 | OD | |
313 | break; | |
314 | ||
315 | /*print externals*/ | |
316 | case 'e': case 'E': | |
317 | for (sp = symtab; sp < esymtab; sp++) { | |
318 | if (sp->n_type==(N_DATA|N_EXT) ORF sp->n_type==(N_BSS|N_EXT)) | |
319 | printf("%s:%12t%R\n", sp->n_un.n_name, get(sp->n_value,DSP)); | |
320 | } | |
321 | break; | |
322 | ||
323 | case 'a': case 'A': | |
324 | error("No algol 68 on VAX"); | |
325 | /*NOTREACHED*/ | |
326 | ||
327 | /*print breakpoints*/ | |
328 | case 'b': case 'B': | |
329 | printf("breakpoints\ncount%8tbkpt%24tcommand\n"); | |
330 | for (bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt) | |
331 | if (bkptr->flag) { | |
332 | printf("%-8.8d",bkptr->count); | |
333 | psymoff(leng(bkptr->loc),ISYM,"%24t"); | |
334 | comptr=bkptr->comm; | |
335 | WHILE *comptr DO printc(*comptr++); OD | |
336 | } | |
337 | break; | |
338 | ||
339 | default: error(BADMOD); | |
340 | } | |
341 | ||
342 | } | |
343 | ||
344 | printmap(s,amap) | |
345 | STRING s; MAP *amap; | |
346 | { | |
347 | int file; | |
348 | file=amap->ufd; | |
349 | printf("%s%12t`%s'\n",s,(file<0 ? "-" : (file==fcor ? corfil : symfil))); | |
350 | printf("b1 = %-16R",amap->b1); | |
351 | printf("e1 = %-16R",amap->e1); | |
352 | printf("f1 = %-16R",amap->f1); | |
353 | printf("\nb2 = %-16R",amap->b2); | |
354 | printf("e2 = %-16R",amap->e2); | |
355 | printf("f2 = %-16R",amap->f2); | |
356 | printc(EOR); | |
357 | } | |
358 | ||
359 | printregs() | |
360 | { | |
361 | REG REGPTR p; | |
362 | L_INT v; | |
363 | ||
364 | FOR p=reglist; p < ®list[24]; p++ | |
6eadceb1 BJ |
365 | DO v = kcore ? *p->rkern : *(ADDR *)(((ADDR)&u)+p->roffs); |
366 | printf("%s%6t%R %16t", p->rname, v); | |
81f0c5ba BJ |
367 | valpr(v,(p->roffs==PC?ISYM:DSYM)); |
368 | printc(EOR); | |
369 | OD | |
370 | printpc(); | |
371 | } | |
372 | ||
6eadceb1 | 373 | getreg(regnam) { |
81f0c5ba BJ |
374 | REG REGPTR p; |
375 | REG STRING regptr; | |
376 | CHAR *olp; | |
377 | CHAR regnxt; | |
378 | ||
379 | olp=lp; | |
380 | FOR p=reglist; p < ®list[24]; p++ | |
381 | DO regptr=p->rname; | |
382 | IF (regnam == *regptr++) | |
383 | THEN | |
384 | WHILE *regptr | |
385 | DO IF (regnxt=readchar()) != *regptr++ | |
386 | THEN --regptr; break; | |
387 | FI | |
388 | OD | |
389 | IF *regptr | |
390 | THEN lp=olp; | |
6d4468aa BJ |
391 | ELSE |
392 | int i = kcore ? (int)p->rkern : p->roffs; | |
393 | printf("returning %X\n", i); | |
394 | return (i); | |
81f0c5ba BJ |
395 | FI |
396 | FI | |
397 | OD | |
398 | lp=olp; | |
399 | return(0); | |
400 | } | |
401 | ||
402 | printpc() | |
403 | { | |
404 | dot= *(ADDR *)(((ADDR)&u)+PC); | |
405 | psymoff(dot,ISYM,":%16t"); printins(0,ISP,chkget(dot,ISP)); | |
406 | printc(EOR); | |
407 | } | |
408 | ||
409 | char *illinames[] = { | |
410 | "reserved addressing fault", | |
411 | "priviliged instruction fault", | |
412 | "reserved operand fault" | |
413 | }; | |
414 | char *fpenames[] = { | |
415 | 0, | |
416 | "integer overflow trap", | |
417 | "integer divide by zero trap", | |
418 | "floating overflow trap", | |
419 | "floating/decimal divide by zero trap", | |
420 | "floating underflow trap", | |
421 | "decimal overflow trap", | |
422 | "subscript out of range trap", | |
423 | "floating overflow fault", | |
424 | "floating divide by zero fault", | |
425 | "floating undeflow fault" | |
426 | }; | |
427 | ||
428 | sigprint() | |
429 | { | |
430 | IF (signo>=0) ANDF (signo<sizeof signals/sizeof signals[0]) | |
431 | THEN prints(signals[signo]); FI | |
432 | switch (signo) { | |
433 | ||
434 | case SIGFPE: | |
435 | IF (sigcode > 0 && | |
436 | sigcode < sizeof fpenames / sizeof fpenames[0]) THEN | |
437 | prints(" ("); prints(fpenames[sigcode]); prints(")"); | |
438 | FI | |
439 | break; | |
440 | ||
441 | case SIGILL: | |
442 | IF (sigcode >= 0 && | |
443 | sigcode < sizeof illinames / sizeof illinames[0]) THEN | |
444 | prints(" ("); prints(illinames[sigcode]); prints(")"); | |
445 | FI | |
446 | break; | |
447 | } | |
448 | } |