xref: /plan9/sys/src/cmd/db/format.c (revision c93608cc76758b2be624199c6208a0f90bad298d)
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*) &dot;
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*) &dot;
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*) &dot;
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