1 /*
2 *
3 * debugger
4 *
5 */
6
7 #include "defs.h"
8 #include "fns.h"
9
10 void
scanform(long icount,int prt,char * ifp,Map * map,int literal)11 scanform(long icount, int prt, char *ifp, Map *map, int literal)
12 {
13 char *fp;
14 char c;
15 int fcount;
16 ADDR savdot;
17 int firstpass;
18
19 firstpass = 1;
20 while (icount) {
21 fp=ifp;
22 savdot=dot;
23 /*now loop over format*/
24 while (*fp) {
25 if (!isdigit(*fp))
26 fcount = 1;
27 else {
28 fcount = 0;
29 while (isdigit(c = *fp++)) {
30 fcount *= 10;
31 fcount += c-'0';
32 }
33 fp--;
34 }
35 if (*fp==0)
36 break;
37 fp=exform(fcount,prt,fp,map,literal,firstpass);
38 firstpass = 0;
39 }
40 dotinc=dot-savdot;
41 dot=savdot;
42 if (--icount)
43 dot=inkdot(dotinc);
44 }
45 }
46
47 char *
exform(int fcount,int prt,char * ifp,Map * map,int literal,int firstpass)48 exform(int fcount, int prt, char *ifp, Map *map, int literal, int firstpass)
49 {
50 /* execute single format item `fcount' times
51 * sets `dotinc' and moves `dot'
52 * returns address of next format item
53 */
54 uvlong v;
55 ulong w;
56 ADDR savdot;
57 char *fp;
58 char c, modifier;
59 int i;
60 ushort sh, *sp;
61 uchar ch, *cp;
62 Symbol s;
63 char buf[512];
64 extern int printcol;
65
66 fp = 0;
67 while (fcount > 0) {
68 fp = ifp;
69 c = *fp;
70 modifier = *fp++;
71 if (firstpass) {
72 firstpass = 0;
73 if (!literal && (c == 'i' || c == 'I' || c == 'M')
74 && (dot & (mach->pcquant-1))) {
75 dprint("warning: instruction not aligned");
76 printc('\n');
77 }
78 if (prt && modifier != 'a' && modifier != 'A') {
79 symoff(buf, 512, dot, CANY);
80 dprint("%s%c%16t", buf, map==symmap? '?':'/');
81 }
82 }
83 if (printcol==0 && modifier != 'a' && modifier != 'A')
84 dprint("\t\t");
85 switch(modifier) {
86
87 case SPC:
88 case TB:
89 dotinc = 0;
90 break;
91
92 case 't':
93 case 'T':
94 dprint("%*t", fcount);
95 dotinc = 0;
96 return(fp);
97
98 case 'a':
99 symoff(buf, sizeof(buf), dot, CANY);
100 dprint("%s%c%16t", buf, map==symmap? '?':'/');
101 dotinc = 0;
102 break;
103
104 case 'A':
105 dprint("%#llux%10t", dot);
106 dotinc = 0;
107 break;
108
109 case 'p':
110 if (get4(map, dot, &w) < 0)
111 error("%r");
112 symoff(buf, sizeof(buf), w, CANY);
113 dprint("%s%16t", buf);
114 dotinc = mach->szaddr;
115 break;
116
117 case 'u':
118 case 'd':
119 case 'x':
120 case 'o':
121 case 'q':
122 if (literal)
123 sh = (ushort) dot;
124 else if (get2(map, dot, &sh) < 0)
125 error("%r");
126 w = sh;
127 dotinc = 2;
128 if (c == 'u')
129 dprint("%-8lud", w);
130 else if (c == 'x')
131 dprint("%-8#lux", w);
132 else if (c == 'd')
133 dprint("%-8ld", w);
134 else if (c == 'o')
135 dprint("%-8#luo", w);
136 else if (c == 'q')
137 dprint("%-8#lo", w);
138 break;
139
140 case 'U':
141 case 'D':
142 case 'X':
143 case 'O':
144 case 'Q':
145 if (literal)
146 w = (long) dot;
147 else if (get4(map, dot, &w) < 0)
148 error("%r");
149 dotinc = 4;
150 if (c == 'U')
151 dprint("%-16lud", w);
152 else if (c == 'X')
153 dprint("%-16#lux", w);
154 else if (c == 'D')
155 dprint("%-16ld", w);
156 else if (c == 'O')
157 dprint("%-#16luo", w);
158 else if (c == 'Q')
159 dprint("%-#16lo", w);
160 break;
161 case 'Z':
162 case 'V':
163 case 'Y':
164 if (literal)
165 v = dot;
166 else if (get8(map, dot, &v) < 0)
167 error("%r");
168 dotinc = 8;
169 if (c == 'Y')
170 dprint("%-20#llux", v);
171 else if (c == 'V')
172 dprint("%-20lld", v);
173 else if (c == 'Z')
174 dprint("%-20llud", v);
175 break;
176 case 'B':
177 case 'b':
178 case 'c':
179 case 'C':
180 if (literal)
181 ch = (uchar) dot;
182 else if (get1(map, dot, &ch, 1) < 0)
183 error("%r");
184 if (modifier == 'C')
185 printesc(ch);
186 else if (modifier == 'B' || modifier == 'b')
187 dprint("%-8#lux", (long) ch);
188 else
189 printc(ch);
190 dotinc = 1;
191 break;
192
193 case 'r':
194 if (literal)
195 sh = (ushort) dot;
196 else if (get2(map, dot, &sh) < 0)
197 error("%r");
198 dprint("%C", sh);
199 dotinc = 2;
200 break;
201
202 case 'R':
203 if (literal) {
204 sp = (ushort*) ˙
205 dprint("%C%C", sp[0], sp[1]);
206 endline();
207 dotinc = 4;
208 break;
209 }
210 savdot=dot;
211 while ((i = get2(map, dot, &sh) > 0) && sh) {
212 dot=inkdot(2);
213 dprint("%C", sh);
214 endline();
215 }
216 if (i < 0)
217 error("%r");
218 dotinc = dot-savdot+2;
219 dot=savdot;
220 break;
221
222 case 's':
223 if (literal) {
224 cp = (uchar*) ˙
225 for (i = 0; i < 4; i++)
226 buf[i] = cp[i];
227 buf[i] = 0;
228 dprint("%s", buf);
229 endline();
230 dotinc = 4;
231 break;
232 }
233 savdot = dot;
234 for(;;){
235 i = 0;
236 do{
237 if (get1(map, dot, (uchar*)&buf[i], 1) < 0)
238 error("%r");
239 dot = inkdot(1);
240 i++;
241 }while(!fullrune(buf, i));
242 if(buf[0] == 0)
243 break;
244 buf[i] = 0;
245 dprint("%s", buf);
246 endline();
247 }
248 dotinc = dot-savdot+1;
249 dot = savdot;
250 break;
251
252 case 'S':
253 if (literal) {
254 cp = (uchar*) ˙
255 for (i = 0; i < 4; i++)
256 printesc(cp[i]);
257 endline();
258 dotinc = 4;
259 break;
260 }
261 savdot=dot;
262 while ((i = get1(map, dot, &ch, 1) > 0) && ch) {
263 dot=inkdot(1);
264 printesc(ch);
265 endline();
266 }
267 if (i < 0)
268 error("%r");
269 dotinc = dot-savdot+1;
270 dot=savdot;
271 break;
272
273
274 case 'I':
275 case 'i':
276 i = machdata->das(map, dot, modifier, buf, sizeof(buf));
277 if (i < 0)
278 error("%r");
279 dotinc = i;
280 dprint("%s\n", buf);
281 break;
282
283 case 'M':
284 i = machdata->hexinst(map, dot, buf, sizeof(buf));
285 if (i < 0)
286 error("%r");
287 dotinc = i;
288 dprint("%s", buf);
289 if (*fp) {
290 dotinc = 0;
291 dprint("%48t");
292 } else
293 dprint("\n");
294 break;
295
296 case 'f':
297 /* BUG: 'f' and 'F' assume szdouble is sizeof(vlong) in the literal case */
298 if (literal) {
299 v = machdata->swav(dot);
300 memmove(buf, &v, mach->szfloat);
301 }else if (get1(map, dot, (uchar*)buf, mach->szfloat) < 0)
302 error("%r");
303 machdata->sftos(buf, sizeof(buf), (void*) buf);
304 dprint("%s\n", buf);
305 dotinc = mach->szfloat;
306 break;
307
308 case 'F':
309 /* BUG: 'f' and 'F' assume szdouble is sizeof(vlong) in the literal case */
310 if (literal) {
311 v = machdata->swav(dot);
312 memmove(buf, &v, mach->szdouble);
313 }else if (get1(map, dot, (uchar*)buf, mach->szdouble) < 0)
314 error("%r");
315 machdata->dftos(buf, sizeof(buf), (void*) buf);
316 dprint("%s\n", buf);
317 dotinc = mach->szdouble;
318 break;
319
320 case 'n':
321 case 'N':
322 printc('\n');
323 dotinc=0;
324 break;
325
326 case '"':
327 dotinc=0;
328 while (*fp != '"' && *fp)
329 printc(*fp++);
330 if (*fp)
331 fp++;
332 break;
333
334 case '^':
335 dot=inkdot(-dotinc*fcount);
336 return(fp);
337
338 case '+':
339 dot=inkdot((WORD)fcount);
340 return(fp);
341
342 case '-':
343 dot=inkdot(-(WORD)fcount);
344 return(fp);
345
346 case 'z':
347 if (findsym(dot, CTEXT, &s))
348 dprint("%s() ", s.name);
349 printsource(dot);
350 printc(EOR);
351 return fp;
352
353 default:
354 error("bad modifier");
355 }
356 if (map->seg[0].fd >= 0)
357 dot=inkdot(dotinc);
358 fcount--;
359 endline();
360 }
361
362 return(fp);
363 }
364
365 void
printesc(int c)366 printesc(int c)
367 {
368 static char hex[] = "0123456789abcdef";
369
370 if (c < SPC || c >= 0177)
371 dprint("\\x%c%c", hex[(c&0xF0)>>4], hex[c&0xF]);
372 else
373 printc(c);
374 }
375
376 ADDR
inkdot(int incr)377 inkdot(int incr)
378 {
379 ADDR newdot;
380
381 newdot=dot+incr;
382 if ((incr >= 0 && newdot < dot)
383 || (incr < 0 && newdot > dot))
384 error("address wraparound");
385 return(newdot);
386 }
387