Commit | Line | Data |
---|---|---|
81f0c5ba BJ |
1 | static char sccsid[] = "@(#)print.c 4.1 %G%"; |
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 [] = { | |
35 | "p1lr", P1LR, | |
36 | "p1br",P1BR, | |
37 | "p0lr", P0LR, | |
38 | "p0br",P0BR, | |
39 | "ksp",KSP, | |
40 | "esp",ESP, | |
41 | "ssp",SSP, | |
42 | "psl", PSL, | |
43 | "pc", PC, | |
44 | "usp",USP, | |
45 | "fp", FP, | |
46 | "ap", AP, | |
47 | "r11", R11, | |
48 | "r10", R10, | |
49 | "r9", R9, | |
50 | "r8", R8, | |
51 | "r7", R7, | |
52 | "r6", R6, | |
53 | "r5", R5, | |
54 | "r4", R4, | |
55 | "r3", R3, | |
56 | "r2", R2, | |
57 | "r1", R1, | |
58 | "r0", R0, | |
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 | ||
192 | case 'd': | |
193 | if (adrflg) { | |
194 | if (adrval<2 || adrval>16) {printf("must have 2 <= radix <= 16"); break;} | |
195 | printf("radix=%d base ten",radix=adrval); | |
196 | } | |
197 | break; | |
198 | ||
199 | case 'q': case 'Q': case '%': | |
200 | done(); | |
201 | ||
202 | case 'w': case 'W': | |
203 | maxpos=(adrflg?adrval:MAXPOS); | |
204 | break; | |
205 | ||
206 | case 's': case 'S': | |
207 | maxoff=(adrflg?adrval:MAXOFF); | |
208 | break; | |
209 | ||
210 | case 'v': case 'V': | |
211 | prints("variables\n"); | |
212 | FOR i=0;i<=35;i++ | |
213 | DO IF var[i] | |
214 | THEN printc((i<=9 ? '0' : 'a'-10) + i); | |
215 | printf(" = %Q\n",var[i]); | |
216 | FI | |
217 | OD | |
218 | break; | |
219 | ||
220 | case 'm': case 'M': | |
221 | printmap("? map",&txtmap); | |
222 | printmap("/ map",&datmap); | |
223 | break; | |
224 | ||
225 | case 0: case '?': | |
226 | IF pid | |
227 | THEN printf("pcs id = %d\n",pid); | |
228 | ELSE prints("no process\n"); | |
229 | FI | |
230 | sigprint(); flushbuf(); | |
231 | ||
232 | case 'r': case 'R': | |
233 | printregs(); | |
234 | return; | |
235 | ||
236 | case 'c': case 'C': | |
237 | IF adrflg | |
238 | THEN frame=adrval; | |
239 | word=get(adrval+6,DSP)&0xFFFF; | |
240 | IF word&0x2000 | |
241 | THEN /* 'calls', can figure out argp */ | |
242 | argp=adrval+20+((word>>14)&3); word &= 0xFFF; | |
243 | WHILE word DO IF word&1 THEN argp+=4; FI word>>=1; OD | |
244 | ELSE /* 'callg', can't tell where argp is */ argp=frame; | |
245 | FI | |
246 | callpc=get(frame+16,DSP); | |
247 | ELSE argp= *(ADDR *)(((ADDR)&u)+AP); | |
248 | frame= *(ADDR *)(((ADDR)&u)+FP); | |
249 | callpc= *(ADDR *)(((ADDR)&u)+PC); | |
250 | FI | |
251 | lastframe=0; | |
252 | ntramp = 0; | |
253 | WHILE cntval-- | |
254 | DO char *name; | |
255 | chkerr(); | |
256 | if (callpc > 0x80000000 - 0x200 * UPAGES) { | |
257 | name = "sigtramp"; | |
258 | ntramp++; | |
259 | } else { | |
260 | ntramp = 0; | |
261 | findsym(callpc,ISYM); | |
262 | if (cursym && | |
263 | !strcmp(cursym->n_un.n_name, "start")) | |
264 | break; | |
265 | if (cursym) | |
266 | name = cursym->n_un.n_name; | |
267 | else | |
268 | name = "?"; | |
269 | } | |
270 | printf("%s(", name); | |
271 | narg = get(argp,DSP); IF narg&~0xFF THEN narg=0; FI | |
272 | LOOP IF narg==0 THEN break; FI | |
273 | printf("%R", get(argp += 4, DSP)); | |
274 | IF --narg!=0 THEN printc(','); FI | |
275 | POOL | |
276 | printf(") from %X\n",callpc); /* jkf mod */ | |
277 | ||
278 | IF modif=='C' | |
279 | THEN WHILE localsym(frame,argp) | |
280 | DO word=get(localval,DSP); | |
281 | printf("%8t%s:%10t", cursym->n_un.n_name); | |
282 | IF errflg THEN prints("?\n"); errflg=0; ELSE printf("%R\n",word); FI | |
283 | OD | |
284 | FI | |
285 | ||
286 | if (ntramp == 1) | |
287 | callpc=get(frame+64, DSP); | |
288 | else | |
289 | callpc=get(frame+16, DSP); | |
290 | argp=get(frame+8, DSP); | |
291 | lastframe=frame; | |
292 | frame=get(frame+12, DSP)&EVEN; | |
293 | IF frame==0 ORF (!adrflg ANDF !INSTACK(frame)) | |
294 | THEN break; | |
295 | FI | |
296 | OD | |
297 | break; | |
298 | ||
299 | /*print externals*/ | |
300 | case 'e': case 'E': | |
301 | for (sp = symtab; sp < esymtab; sp++) { | |
302 | if (sp->n_type==(N_DATA|N_EXT) ORF sp->n_type==(N_BSS|N_EXT)) | |
303 | printf("%s:%12t%R\n", sp->n_un.n_name, get(sp->n_value,DSP)); | |
304 | } | |
305 | break; | |
306 | ||
307 | case 'a': case 'A': | |
308 | error("No algol 68 on VAX"); | |
309 | /*NOTREACHED*/ | |
310 | ||
311 | /*print breakpoints*/ | |
312 | case 'b': case 'B': | |
313 | printf("breakpoints\ncount%8tbkpt%24tcommand\n"); | |
314 | for (bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt) | |
315 | if (bkptr->flag) { | |
316 | printf("%-8.8d",bkptr->count); | |
317 | psymoff(leng(bkptr->loc),ISYM,"%24t"); | |
318 | comptr=bkptr->comm; | |
319 | WHILE *comptr DO printc(*comptr++); OD | |
320 | } | |
321 | break; | |
322 | ||
323 | default: error(BADMOD); | |
324 | } | |
325 | ||
326 | } | |
327 | ||
328 | printmap(s,amap) | |
329 | STRING s; MAP *amap; | |
330 | { | |
331 | int file; | |
332 | file=amap->ufd; | |
333 | printf("%s%12t`%s'\n",s,(file<0 ? "-" : (file==fcor ? corfil : symfil))); | |
334 | printf("b1 = %-16R",amap->b1); | |
335 | printf("e1 = %-16R",amap->e1); | |
336 | printf("f1 = %-16R",amap->f1); | |
337 | printf("\nb2 = %-16R",amap->b2); | |
338 | printf("e2 = %-16R",amap->e2); | |
339 | printf("f2 = %-16R",amap->f2); | |
340 | printc(EOR); | |
341 | } | |
342 | ||
343 | printregs() | |
344 | { | |
345 | REG REGPTR p; | |
346 | L_INT v; | |
347 | ||
348 | FOR p=reglist; p < ®list[24]; p++ | |
349 | DO printf("%s%6t%R %16t", p->rname, v= *(ADDR *)(((ADDR)&u)+p->roffs)); | |
350 | valpr(v,(p->roffs==PC?ISYM:DSYM)); | |
351 | printc(EOR); | |
352 | OD | |
353 | printpc(); | |
354 | } | |
355 | ||
356 | getreg(regnam) | |
357 | { | |
358 | REG REGPTR p; | |
359 | REG STRING regptr; | |
360 | CHAR *olp; | |
361 | CHAR regnxt; | |
362 | ||
363 | olp=lp; | |
364 | FOR p=reglist; p < ®list[24]; p++ | |
365 | DO regptr=p->rname; | |
366 | IF (regnam == *regptr++) | |
367 | THEN | |
368 | WHILE *regptr | |
369 | DO IF (regnxt=readchar()) != *regptr++ | |
370 | THEN --regptr; break; | |
371 | FI | |
372 | OD | |
373 | IF *regptr | |
374 | THEN lp=olp; | |
375 | ELSE return(p->roffs); | |
376 | FI | |
377 | FI | |
378 | OD | |
379 | lp=olp; | |
380 | return(0); | |
381 | } | |
382 | ||
383 | printpc() | |
384 | { | |
385 | dot= *(ADDR *)(((ADDR)&u)+PC); | |
386 | psymoff(dot,ISYM,":%16t"); printins(0,ISP,chkget(dot,ISP)); | |
387 | printc(EOR); | |
388 | } | |
389 | ||
390 | char *illinames[] = { | |
391 | "reserved addressing fault", | |
392 | "priviliged instruction fault", | |
393 | "reserved operand fault" | |
394 | }; | |
395 | char *fpenames[] = { | |
396 | 0, | |
397 | "integer overflow trap", | |
398 | "integer divide by zero trap", | |
399 | "floating overflow trap", | |
400 | "floating/decimal divide by zero trap", | |
401 | "floating underflow trap", | |
402 | "decimal overflow trap", | |
403 | "subscript out of range trap", | |
404 | "floating overflow fault", | |
405 | "floating divide by zero fault", | |
406 | "floating undeflow fault" | |
407 | }; | |
408 | ||
409 | sigprint() | |
410 | { | |
411 | IF (signo>=0) ANDF (signo<sizeof signals/sizeof signals[0]) | |
412 | THEN prints(signals[signo]); FI | |
413 | switch (signo) { | |
414 | ||
415 | case SIGFPE: | |
416 | IF (sigcode > 0 && | |
417 | sigcode < sizeof fpenames / sizeof fpenames[0]) THEN | |
418 | prints(" ("); prints(fpenames[sigcode]); prints(")"); | |
419 | FI | |
420 | break; | |
421 | ||
422 | case SIGILL: | |
423 | IF (sigcode >= 0 && | |
424 | sigcode < sizeof illinames / sizeof illinames[0]) THEN | |
425 | prints(" ("); prints(illinames[sigcode]); prints(")"); | |
426 | FI | |
427 | break; | |
428 | } | |
429 | } |