xref: /plan9-contrib/sys/src/cmd/db/format.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1 /*
2  *
3  *	debugger
4  *
5  */
6 
7 #include "defs.h"
8 #include "fns.h"
9 
10 extern	char	lastc, peekc;
11 
12 void
13 scanform(long icount, int prt, char *ifp, Map *map, int literal)
14 {
15 	char	*fp;
16 	char	c;
17 	int	fcount;
18 	ADDR	savdot;
19 	int firstpass;
20 
21 	firstpass = 1;
22 	while (icount) {
23 		fp=ifp;
24 		savdot=dot;
25 		/*now loop over format*/
26 		while (*fp) {
27 			if (!isdigit(*fp))
28 				fcount = 1;
29 			else {
30 				fcount = 0;
31 				while (isdigit(c = *fp++)) {
32 					fcount *= 10;
33 					fcount += c-'0';
34 				}
35 				fp--;
36 			}
37 			if (*fp==0)
38 				break;
39 			fp=exform(fcount,prt,fp,map,literal,firstpass);
40 			firstpass = 0;
41 		}
42 		dotinc=dot-savdot;
43 		dot=savdot;
44 		if (--icount)
45 			dot=inkdot(dotinc);
46 	}
47 }
48 
49 char *
50 exform(int fcount, int prt, char *ifp, Map *map, int literal, int firstpass)
51 {
52 	/* execute single format item `fcount' times
53 	 * sets `dotinc' and moves `dot'
54 	 * returns address of next format item
55 	 */
56 	int	w;
57 	ulong	savdot;
58 	char	*fp, *p;
59 	char	c, modifier;
60 	int	i;
61 	ushort sh, *sp;
62 	uchar ch, *cp;
63 	Symbol s;
64 	char buf[512];
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 (charpos()==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("%lux%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("%-8lux", 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("%-16lux", 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 'B':
162 		case 'b':
163 		case 'c':
164 		case 'C':
165 			if (literal)
166 				ch = (uchar) dot;
167 			else if (get1(map, dot, &ch, 1)  < 0)
168 				error("%r");
169 			if (modifier == 'C')
170 				printesc(ch);
171 			else if (modifier == 'B' || modifier == 'b')
172 				dprint("%-8lux", (long) ch);
173 			else
174 				printc(ch);
175 			dotinc = 1;
176 			break;
177 
178 		case 'r':
179 			if (literal)
180 				sh = (ushort) dot;
181 			else if (get2(map, dot, &sh) < 0)
182 				error("%r");
183 			dprint("%C", sh);
184 			dotinc = 2;
185 			break;
186 
187 		case 'R':
188 			if (literal) {
189 				sp = (ushort*) &dot;
190 				dprint("%C%C", sp[0], sp[1]);
191 				endline();
192 				dotinc = 4;
193 				break;
194 			}
195 			savdot=dot;
196 			while ((i = get2(map, dot, &sh) > 0) && sh) {
197 				dot=inkdot(2);
198 				dprint("%C", sh);
199 				endline();
200 			}
201 			if (i < 0)
202 				error("%r");
203 			dotinc = dot-savdot+2;
204 			dot=savdot;
205 			break;
206 
207 		case 's':
208 			if (literal) {
209 				cp = (uchar*) &dot;
210 				for (i = 0; i < 4; i++)
211 					buf[i] = cp[i];
212 				buf[i] = 0;
213 				dprint("%s", buf);
214 				endline();
215 				dotinc = 4;
216 				break;
217 			}
218 			savdot = dot;
219 			for(;;){
220 				i = 0;
221 				do{
222 					if (get1(map, dot, (uchar*)&buf[i], 1) < 0)
223 						error("%r");
224 					dot = inkdot(1);
225 					i++;
226 				}while(!fullrune(buf, i));
227 				if(buf[0] == 0)
228 					break;
229 				buf[i] = 0;
230 				dprint("%s", buf);
231 				endline();
232 			}
233 			dotinc = dot-savdot+1;
234 			dot = savdot;
235 			break;
236 
237 		case 'S':
238 			if (literal) {
239 				cp = (uchar*) &dot;
240 				for (i = 0; i < 4; i++)
241 					printesc(cp[i]);
242 				endline();
243 				dotinc = 4;
244 				break;
245 			}
246 			savdot=dot;
247 			while ((i = get1(map, dot, &ch, 1) > 0) && ch) {
248 				dot=inkdot(1);
249 				printesc(ch);
250 				endline();
251 			}
252 			if (i < 0)
253 				error("%r");
254 			dotinc = dot-savdot+1;
255 			dot=savdot;
256 			break;
257 
258 		case 'Y':
259 			if (literal)
260 				w = (long) dot;
261 			else if (get4(map, dot, &w) < 0)
262 				error("%r");
263 			p = ctime(w);
264 			p[strlen(p)-1] = 0;	/* stomp on newline */
265 			dprint("%-25s", p);
266 			dotinc = 4;
267 			break;
268 
269 		case 'I':
270 		case 'i':
271 			dotinc = machdata->das(map, dot, modifier, buf, sizeof(buf));
272 			if (dotinc < 0)
273 				error("%r");
274 			dprint("%s\n", buf);
275 			break;
276 
277 		case 'M':
278 			dotinc = machdata->hexinst(map, dot, buf, sizeof(buf));
279 			if (dotinc < 0)
280 				error("%r");
281 			dprint("%s", buf);
282 			if (*fp) {
283 				dotinc = 0;
284 				dprint("%48t");
285 			} else
286 				dprint("\n");
287 			break;
288 
289 		case 'f':
290 			if (get1(map, dot, (uchar*)buf, mach->szfloat) < 0)
291 				error("%r");
292 			machdata->sftos(buf, sizeof(buf), (void*) buf);
293 			dprint("%s\n", buf);
294 			dotinc = mach->szfloat;
295 			break;
296 
297 		case 'F':
298 			if (get1(map, dot, (uchar*)buf, mach->szdouble) < 0)
299 				error("%r");
300 			machdata->dftos(buf, sizeof(buf), (void*) buf);
301 			dprint("%s\n", buf);
302 			dotinc = mach->szdouble;
303 			break;
304 
305 		case 'n':
306 		case 'N':
307 			printc('\n');
308 			dotinc=0;
309 			break;
310 
311 		case '"':
312 			dotinc=0;
313 			while (*fp != '"' && *fp)
314 				printc(*fp++);
315 			if (*fp)
316 				fp++;
317 			break;
318 
319 		case '^':
320 			dot=inkdot(-dotinc*fcount);
321 			return(fp);
322 
323 		case '+':
324 			dot=inkdot((WORD)fcount);
325 			return(fp);
326 
327 		case '-':
328 			dot=inkdot(-(WORD)fcount);
329 			return(fp);
330 
331 		case 'z':
332 			if (findsym(dot, CTEXT, &s))
333 				dprint("%s() ", s.name);
334 			printsource(dot);
335 			printc(EOR);
336 			return fp;
337 
338 		default:
339 			error("bad modifier");
340 		}
341 		if (map->fd >= 0)
342 			dot=inkdot(dotinc);
343 		fcount--;
344 		endline();
345 	}
346 
347 	return(fp);
348 }
349 
350 void
351 printesc(int c)
352 {
353 	static char hex[] = "0123456789abcdef";
354 
355 	if (c < SPC || c >= 0177)
356 		dprint("\\x%c%c", hex[(c&0xF0)>>4], hex[c&0xF]);
357 	else
358 		printc(c);
359 }
360 
361 ADDR
362 inkdot(WORD incr)
363 {
364 	ADDR	newdot;
365 
366 	newdot=dot+incr;
367 	if ((incr >= 0 && newdot < dot)
368 	||  (incr < 0 && newdot > dot))
369 		error("address wraparound");
370 	return(newdot);
371 }
372