Commit | Line | Data |
---|---|---|
54ee7326 BJ |
1 | # |
2 | /* | |
3 | * | |
4 | * UNIX debugger | |
5 | * | |
6 | */ | |
7 | ||
8 | #include "defs.h" | |
9 | SCCSID(@(#)print.c 2.9); | |
10 | #include "a.out.h" | |
11 | struct user u; | |
12 | ||
13 | ||
14 | MSG LONGFIL; | |
15 | MSG NOTOPEN; | |
16 | MSG A68BAD; | |
17 | MSG A68LNK; | |
18 | MSG BADMOD; | |
19 | ||
20 | MAP txtmap; | |
21 | MAP datmap; | |
22 | ||
23 | SYMTAB symbol; | |
24 | ADDR lastframe; | |
25 | ADDR callpc; | |
26 | ||
27 | INT infile; | |
28 | INT outfile; | |
29 | CHAR *lp; | |
30 | L_INT maxoff; | |
31 | L_INT maxpos; | |
32 | INT radix; | |
33 | ||
34 | /* symbol management */ | |
35 | L_INT localval; | |
36 | ||
37 | /* breakpoints */ | |
38 | BKPTR bkpthead; | |
39 | ||
40 | REGLIST reglist [] = { | |
41 | "p1lr", P1LR, | |
42 | "p1br",P1BR, | |
43 | "p0lr", P0LR, | |
44 | "p0br",P0BR, | |
45 | "ksp",KSP, | |
46 | "esp",ESP, | |
47 | "ssp",SSP, | |
48 | "psl", PSL, | |
49 | "pc", PC, | |
50 | "usp",USP, | |
51 | "fp", FP, | |
52 | "ap", AP, | |
53 | "r11", R11, | |
54 | "r10", R10, | |
55 | "r9", R9, | |
56 | "r8", R8, | |
57 | "r7", R7, | |
58 | "r6", R6, | |
59 | "r5", R5, | |
60 | "r4", R4, | |
61 | "r3", R3, | |
62 | "r2", R2, | |
63 | "r1", R1, | |
64 | "r0", R0, | |
65 | }; | |
66 | ||
67 | char lastc; | |
68 | ||
69 | INT fcor; | |
70 | STRING errflg; | |
71 | INT signo; | |
72 | ||
73 | ||
74 | L_INT dot; | |
75 | L_INT var[]; | |
76 | STRING symfil; | |
77 | STRING corfil; | |
78 | INT pid; | |
79 | L_INT adrval; | |
80 | INT adrflg; | |
81 | L_INT cntval; | |
82 | INT cntflg; | |
83 | ||
84 | STRING signals[] = { | |
85 | "", | |
86 | "hangup", | |
87 | "interrupt", | |
88 | "quit", | |
89 | "illegal instruction", | |
90 | "trace/BPT", | |
91 | "IOT", | |
92 | "EMT", | |
93 | "floating exception", | |
94 | "killed", | |
95 | "bus error", | |
96 | "memory fault", | |
97 | "bad system call", | |
98 | "broken pipe", | |
99 | "alarm call", | |
100 | "terminated", | |
101 | }; | |
102 | #define MAXSIG 15 | |
103 | ||
104 | ||
105 | ||
106 | ||
107 | /* general printing routines ($) */ | |
108 | ||
109 | printtrace(modif) | |
110 | { | |
111 | INT narg, i, stat, name, limit; | |
112 | POS dynam; | |
113 | REG BKPTR bkptr; | |
114 | CHAR hi, lo; | |
115 | ADDR word; | |
116 | STRING comptr; | |
117 | ADDR argp, frame, link; | |
118 | SYMPTR symp; | |
119 | ||
120 | IF cntflg==0 THEN cntval = -1; FI | |
121 | ||
122 | switch (modif) { | |
123 | ||
124 | case '<': | |
125 | case '>': | |
126 | {CHAR file[64]; | |
127 | INT index; | |
128 | ||
129 | index=0; | |
130 | IF modif=='<' | |
131 | THEN iclose(); | |
132 | ELSE oclose(); | |
133 | FI | |
134 | IF rdc()!=EOR | |
135 | THEN REP file[index++]=lastc; | |
136 | IF index>=63 THEN error(LONGFIL); FI | |
137 | PER readchar()!=EOR DONE | |
138 | file[index]=0; | |
139 | IF modif=='<' | |
140 | THEN infile=open(file,0); | |
141 | IF infile<0 | |
142 | THEN infile=0; error(NOTOPEN); | |
143 | FI | |
144 | ELSE outfile=open(file,1); | |
145 | IF outfile<0 | |
146 | THEN outfile=creat(file,0644); | |
147 | #ifndef EDDT | |
148 | ELSE lseek(outfile,0L,2); | |
149 | #endif | |
150 | FI | |
151 | FI | |
152 | ||
153 | FI | |
154 | lp--; | |
155 | } | |
156 | break; | |
157 | ||
158 | case 'd': | |
159 | if (adrflg) { | |
160 | if (adrval<2 || adrval>16) {printf("must have 2 <= radix <= 16"); break;} | |
161 | printf("radix=%d base ten",radix=adrval); | |
162 | } | |
163 | break; | |
164 | ||
165 | case 'q': case 'Q': case '%': | |
166 | done(); | |
167 | ||
168 | case 'w': case 'W': | |
169 | maxpos=(adrflg?adrval:MAXPOS); | |
170 | break; | |
171 | ||
172 | case 's': case 'S': | |
173 | maxoff=(adrflg?adrval:MAXOFF); | |
174 | break; | |
175 | ||
176 | case 'v': case 'V': | |
177 | prints("variables\n"); | |
178 | FOR i=0;i<=35;i++ | |
179 | DO IF var[i] | |
180 | THEN printc((i<=9 ? '0' : 'a'-10) + i); | |
181 | printf(" = %Q\n",var[i]); | |
182 | FI | |
183 | OD | |
184 | break; | |
185 | ||
186 | case 'm': case 'M': | |
187 | printmap("? map",&txtmap); | |
188 | printmap("/ map",&datmap); | |
189 | break; | |
190 | ||
191 | case 0: case '?': | |
192 | IF pid | |
193 | THEN printf("pcs id = %d\n",pid); | |
194 | ELSE prints("no process\n"); | |
195 | FI | |
196 | sigprint(); flushbuf(); | |
197 | ||
198 | case 'r': case 'R': | |
199 | printregs(); | |
200 | return; | |
201 | ||
202 | case 'c': case 'C': | |
203 | IF adrflg | |
204 | THEN frame=adrval; | |
205 | word=get(adrval+6,DSP)&0xFFFF; | |
206 | IF word&0x2000 | |
207 | THEN /* 'calls', can figure out argp */ | |
208 | argp=adrval+20+((word>>14)&3); word &= 0xFFF; | |
209 | WHILE word DO IF word&1 THEN argp+=4; FI word>>=1; OD | |
210 | ELSE /* 'callg', can't tell where argp is */ argp=frame; | |
211 | FI | |
212 | callpc=get(frame+16,DSP); | |
213 | ELSE argp= *(ADDR *)(((ADDR)&u)+AP); | |
214 | frame= *(ADDR *)(((ADDR)&u)+FP); | |
215 | callpc= *(ADDR *)(((ADDR)&u)+PC); | |
216 | FI | |
217 | lastframe=0; | |
218 | WHILE cntval-- | |
219 | DO chkerr(); | |
220 | printf("%.8s(", findsym(callpc,ISYM)==-1 ? "?":symbol.symc); | |
221 | narg = get(argp,DSP); IF narg&~0xFF THEN narg=0; FI | |
222 | LOOP IF narg==0 THEN break; FI | |
223 | printf("%R", get(argp += 4, DSP)); | |
224 | IF --narg!=0 THEN printc(','); FI | |
225 | POOL | |
226 | prints(")\n"); | |
227 | ||
228 | IF modif=='C' | |
229 | THEN WHILE localsym(frame,argp) | |
230 | DO word=get(localval,DSP); | |
231 | printf("%8t%.8s:%10t", symbol.symc); | |
232 | IF errflg THEN prints("?\n"); errflg=0; ELSE printf("%R\n",word); FI | |
233 | OD | |
234 | FI | |
235 | ||
236 | callpc=get(frame+16, DSP); | |
237 | argp=get(frame+8, DSP); | |
238 | lastframe=frame; | |
239 | frame=get(frame+12, DSP)&EVEN; | |
240 | IF frame==0 ORF (!adrflg ANDF (frame&0xF0000000)!=0x70000000) | |
241 | THEN break; | |
242 | FI | |
243 | OD | |
244 | break; | |
245 | ||
246 | #ifndef EDDT | |
247 | /*print externals*/ | |
248 | case 'e': case 'E': | |
249 | symset(); | |
250 | WHILE symp=symget() | |
251 | DO chkerr(); | |
252 | IF symp->symf==(N_DATA|N_EXT) ORF symp->symf==(N_BSS|N_EXT) | |
253 | THEN printf("%.8s:%12t%R\n", symp->symc, get(symp->symv,DSP)); | |
254 | FI | |
255 | OD | |
256 | break; | |
257 | ||
258 | case 'a': case 'A': | |
259 | frame=(adrflg ? adrval : *(ADDR *)(((ADDR)&u)+FP)); | |
260 | ||
261 | WHILE cntval-- | |
262 | DO chkerr(); | |
263 | stat=get(frame,DSP); dynam=get(frame+2,DSP); link=get(frame+4,DSP); | |
264 | IF modif=='A' | |
265 | THEN printf("%8O:%8t%-8o,%-8o,%-8o",frame,stat,dynam,link); | |
266 | FI | |
267 | IF stat==1 THEN break; FI | |
268 | IF errflg THEN error(A68BAD); FI | |
269 | ||
270 | IF get(link-4,ISP)!=04767 | |
271 | THEN IF get(link-2,ISP)!=04775 | |
272 | THEN error(A68LNK); | |
273 | ELSE /*compute entry point of routine*/ | |
274 | prints(" ? "); | |
275 | FI | |
276 | ELSE printf("%8t"); | |
277 | valpr(name=shorten(link)+get(link-2,ISP),ISYM); | |
278 | name=get(leng(name-2),ISP); | |
279 | printf("%8t\""); limit=8; | |
280 | REP word=get(leng(name),DSP); name += 2; | |
281 | lo=word&LOBYTE; hi=(word>>8)&LOBYTE; | |
282 | printc(lo); printc(hi); | |
283 | PER lo ANDF hi ANDF limit-- DONE | |
284 | printc('"'); | |
285 | FI | |
286 | limit=4; i=6; printf("%24targs:%8t"); | |
287 | WHILE limit-- | |
288 | DO printf("%8t%o",get(frame+i,DSP)); i += 2; OD | |
289 | printc(EOR); | |
290 | ||
291 | frame=dynam; | |
292 | OD | |
293 | errflg=0; | |
294 | flushbuf(); | |
295 | break; | |
296 | #endif | |
297 | ||
298 | /*set default c frame*/ | |
299 | /*print breakpoints*/ | |
300 | case 'b': case 'B': | |
301 | printf("breakpoints\ncount%8tbkpt%24tcommand\n"); | |
302 | FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt | |
303 | DO IF bkptr->flag | |
304 | THEN printf("%-8.8d",bkptr->count); | |
305 | psymoff(leng(bkptr->loc),ISYM,"%24t"); | |
306 | comptr=bkptr->comm; | |
307 | WHILE *comptr DO printc(*comptr++); OD | |
308 | FI | |
309 | OD | |
310 | break; | |
311 | ||
312 | default: error(BADMOD); | |
313 | } | |
314 | ||
315 | } | |
316 | ||
317 | printmap(s,amap) | |
318 | STRING s; MAP *amap; | |
319 | { | |
320 | int file; | |
321 | file=amap->ufd; | |
322 | printf("%s%12t`%s'\n",s,(file<0 ? "-" : (file==fcor ? corfil : symfil))); | |
323 | printf("b1 = %-16R",amap->b1); | |
324 | printf("e1 = %-16R",amap->e1); | |
325 | printf("f1 = %-16R",amap->f1); | |
326 | printf("\nb2 = %-16R",amap->b2); | |
327 | printf("e2 = %-16R",amap->e2); | |
328 | printf("f2 = %-16R",amap->f2); | |
329 | printc(EOR); | |
330 | } | |
331 | ||
332 | printregs() | |
333 | { | |
334 | REG REGPTR p; | |
335 | L_INT v; | |
336 | ||
337 | FOR p=reglist; p < ®list[24]; p++ | |
338 | DO printf("%s%6t%R %16t", p->rname, v= *(ADDR *)(((ADDR)&u)+p->roffs)); | |
339 | valpr(v,(p->roffs==PC?ISYM:DSYM)); | |
340 | printc(EOR); | |
341 | OD | |
342 | printpc(); | |
343 | } | |
344 | ||
345 | getreg(regnam) | |
346 | { | |
347 | REG REGPTR p; | |
348 | REG STRING regptr; | |
349 | CHAR *olp; | |
350 | CHAR regnxt; | |
351 | ||
352 | olp=lp; | |
353 | FOR p=reglist; p < ®list[24]; p++ | |
354 | DO regptr=p->rname; | |
355 | IF (regnam == *regptr++) | |
356 | THEN | |
357 | WHILE *regptr | |
358 | DO IF (regnxt=readchar()) != *regptr++ | |
359 | THEN --regptr; break; | |
360 | FI | |
361 | OD | |
362 | IF *regptr | |
363 | THEN lp=olp; | |
364 | ELSE return(p->roffs); | |
365 | FI | |
366 | FI | |
367 | OD | |
368 | lp=olp; | |
369 | return(0); | |
370 | } | |
371 | ||
372 | printpc() | |
373 | { | |
374 | dot= *(ADDR *)(((ADDR)&u)+PC); | |
375 | psymoff(dot,ISYM,":%16t"); printins(0,ISP,chkget(dot,ISP)); | |
376 | printc(EOR); | |
377 | } | |
378 | ||
379 | sigprint() | |
380 | { | |
381 | IF (signo>=0) ANDF (signo<=MAXSIG) THEN prints(signals[signo]); FI | |
382 | } | |
383 |