Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include <u.h>
2
#include <libc.h>
3
#include <bio.h>
4
#include <mach.h>
5
#include <ctype.h>
6
#include "arm.h"
7
 
8
char	buf[128], lastcmd[128];
9
char	fmt = 'X';
10
int	width = 60;
11
int	inc;
12
 
13
ulong	expr(char*);
14
ulong	expr1(char*);
15
char*	term(char*, ulong*);
16
 
17
char*
18
nextc(char *p)
19
{
20
	while(*p && (*p == ' ' || *p == '\t') && *p != '\n')
21
		p++;
22
 
23
	if(*p == '\n')
24
		*p = '\0';
25
 
26
	return p;
27
}
28
 
29
char*
30
numsym(char *addr, ulong *val)
31
{
32
	char tsym[128], *t;
33
	static char *delim = "`'<>/\\@*|-~+-/=?\n";
34
	Symbol s;
35
	char c;
36
 
37
	t = tsym;
38
	while(c = *addr) {
39
		if(strchr(delim, c))
40
			break;
41
		*t++ = c;
42
		addr++;
43
	}
44
	t[0] = '\0';
45
 
46
	if(strcmp(tsym, ".") == 0) {
47
		*val = dot;
48
		return addr;
49
	}
50
 
51
	if(lookup(0, tsym, &s))
52
		*val = s.value;
53
	else {
54
		if(tsym[0] == '#')
55
			*val = strtoul(tsym+1, 0, 16);
56
		else
57
			*val = strtoul(tsym, 0, 0);
58
	}
59
	return addr;
60
}
61
 
62
ulong
63
expr(char *addr)
64
{
65
	ulong t, t2;
66
	char op;
67
 
68
	if(*addr == '\0')
69
		return dot;
70
 
71
	addr = numsym(addr, &t);
72
 
73
	if(*addr == '\0')
74
		return t;
75
 
76
	addr = nextc(addr);
77
	op = *addr++;
78
	numsym(addr, &t2);
79
	switch(op) {
80
	default:
81
		Bprint(bioout, "expr syntax\n");
82
		return 0;
83
	case '+':
84
		t += t2;
85
		break;
86
	case '-':
87
		t -= t2;
88
		break;
89
	case '%':
90
		t /= t2;
91
		break;
92
	case '&':
93
		t &= t2;
94
		break;
95
	case '|':
96
		t |= t2;
97
		break;
98
	}
99
 
100
	return t;
101
}
102
 
103
int
104
buildargv(char *str, char **args, int max)
105
{
106
	int na = 0;
107
 
108
	while (na < max) {
109
		while((*str == ' ' || *str == '\t' || *str == '\n') && *str != '\0')
110
			str++;
111
 
112
		if(*str == '\0')
113
			return na;
114
 
115
		args[na++] = str;
116
		while(!(*str == ' ' || *str == '\t'|| *str == '\n') && *str != '\0')
117
			str++;
118
 
119
		if(*str == '\n')
120
			*str = '\0';
121
 
122
		if(*str == '\0')
123
			break;
124
 
125
		*str++ = '\0';
126
	}
127
	return na;
128
}
129
 
130
void
131
colon(char *addr, char *cp)
132
{
133
	int argc;
134
	char *argv[100];
135
	char tbuf[512];
136
 
137
	cp = nextc(cp);
138
	switch(*cp) {
139
	default:
140
		Bprint(bioout, "?\n");
141
		return;
142
	case 'b':
143
		breakpoint(addr, cp+1);
144
		return;
145
 
146
	case 'd':
147
		delbpt(addr);
148
		return;
149
 
150
	/* These fall through to print the stopped address */
151
	case 'r':
152
		reset();
153
		argc = buildargv(cp+1, argv, 100);
154
		initstk(argc, argv);
155
		count = 0;
156
		atbpt = 0;
157
		run();
158
		break;
159
	case 'c':
160
		count = 0;
161
		atbpt = 0;
162
		run();
163
		break;
164
	case 's':
165
		cp = nextc(cp+1);
166
		count = 0;
167
		if(*cp)
168
			count = strtoul(cp, 0, 0);
169
		if(count == 0)
170
			count = 1;
171
		atbpt = 0;
172
		run();
173
		break;
174
	}
175
 
176
	dot = reg.r[15];
177
	Bprint(bioout, "%s at #%lux ", atbpt? "breakpoint": "stopped", dot);
178
	symoff(tbuf, sizeof(tbuf), dot, CTEXT);
179
	Bprint(bioout, tbuf);
180
	if(fmt == 'z')
181
		printsource(dot);
182
 
183
	Bprint(bioout, "\n");
184
}
185
 
186
 
187
void
188
dollar(char *cp)
189
{
190
	cp = nextc(cp);
191
	switch(*cp) {
192
	default:
193
		Bprint(bioout, "?\n");
194
		break;
195
 
196
	case 'c':
197
		stktrace(*cp);
198
		break;
199
 
200
	case 'C':
201
		stktrace(*cp);
202
		break;
203
 
204
	case 'b':
205
		dobplist();
206
		break;
207
 
208
	case 'r':
209
		dumpreg();
210
		break;
211
 
212
	case 'R':
213
		dumpreg();
214
 
215
	case 'f':
216
		dumpfreg();
217
		break;
218
 
219
	case 'F':
220
		dumpdreg();
221
		break;
222
 
223
	case 'q':
224
		exits(0);
225
		break;
226
 
227
	case 'Q':
228
		isum();
229
		tlbsum();
230
		segsum();
231
		break;
232
 
233
	case 't':
234
		cp++;
235
		switch(*cp) {
236
		default:
237
			Bprint(bioout, ":t[0sic]\n");
238
			break;
239
		case '\0':
240
			trace = 1;
241
			break;
242
		case '0':
243
			trace = 0;
244
			sysdbg = 0;
245
			calltree = 0;
246
			break;
247
		case 's':
248
			sysdbg = 1;
249
			break;
250
		case 'i':
251
			trace = 1;
252
			break;
253
		case 'c':
254
			calltree = 1;
255
			break;
256
		}
257
		break;
258
 
259
	case 'i':
260
		cp++;
261
		switch(*cp) {
262
		default:
263
			Bprint(bioout, "$i[itsa]\n");
264
			break;
265
		case 'i':
266
			isum();
267
			break;
268
		case 't':
269
			tlbsum();
270
			break;
271
		case 's':
272
			segsum();
273
			break;
274
		case 'a':
275
			isum();
276
			tlbsum();
277
			segsum();
278
			iprofile();
279
			break;
280
		case 'p':
281
			iprofile();
282
			break;
283
		}
284
	}
285
}
286
 
287
int
288
pfmt(char fmt, int mem, ulong val)
289
{
290
	int c, i;
291
	Symbol s;
292
	char *p, ch, str[1024];
293
 
294
	c = 0;
295
	switch(fmt) {
296
	default:
297
		Bprint(bioout, "bad modifier\n");
298
		return 0;
299
	case 'o':
300
		c = Bprint(bioout, "%-4lo ", mem? (ushort)getmem_2(dot): val);
301
		inc = 2;
302
		break;
303
 
304
	case 'O':
305
		c = Bprint(bioout, "%-8lo ", mem? getmem_4(dot): val);
306
		inc = 4;
307
		break;
308
 
309
	case 'q':
310
		c = Bprint(bioout, "%-4lo ", mem? (short)getmem_2(dot): val);
311
		inc = 2;
312
		break;
313
 
314
	case 'Q':
315
		c = Bprint(bioout, "%-8lo ", mem? (long)getmem_4(dot): val);
316
		inc = 4;
317
		break;
318
 
319
	case 'd':
320
		c = Bprint(bioout, "%-5ld ", mem? (short)getmem_2(dot): val);
321
		inc = 2;
322
		break;
323
 
324
 
325
	case 'D':
326
		c = Bprint(bioout, "%-8ld ", mem? (long)getmem_4(dot): val);
327
		inc = 4;
328
		break;
329
 
330
	case 'x':
331
		c = Bprint(bioout, "#%-4lux ", mem? (long)getmem_2(dot): val);
332
		inc = 2;
333
		break;
334
 
335
	case 'X':
336
		c = Bprint(bioout, "#%-8lux ", mem? (long)getmem_4(dot): val);
337
		inc = 4;
338
		break;
339
 
340
	case 'u':
341
		c = Bprint(bioout, "%-5ld ", mem? (ushort)getmem_2(dot): val);
342
		inc = 2;
343
		break;
344
 
345
	case 'U':
346
		c = Bprint(bioout, "%-8ld ", mem? (ulong)getmem_4(dot): val);
347
		inc = 4;
348
		break;
349
 
350
	case 'b':
351
		c = Bprint(bioout, "%-3ld ", mem? getmem_b(dot): val);
352
		inc = 1;
353
		break;
354
 
355
	case 'c':
356
		c = Bprint(bioout, "%c ", (int)(mem? getmem_b(dot): val));
357
		inc = 1;
358
		break;
359
 
360
	case 'C':
361
		ch = mem? getmem_b(dot): val;
362
		if(isprint(ch))
363
			c = Bprint(bioout, "%c ", ch);
364
		else
365
			c = Bprint(bioout, "\\x%.2x ", ch);
366
		inc = 1;
367
		break;
368
 
369
	case 's':
370
		i = 0;
371
		while(ch = getmem_b(dot+i))
372
			str[i++] = ch;
373
		str[i] = '\0';
374
		dot += i;
375
		c = Bprint(bioout, "%s", str);
376
		inc = 0;
377
		break;
378
 
379
	case 'S':
380
		i = 0;
381
		while(ch = getmem_b(dot+i))
382
			str[i++] = ch;
383
		str[i] = '\0';
384
		dot += i;
385
		for(p = str; *p; p++)
386
			if(isprint(*p))
387
				c += Bprint(bioout, "%c", *p);
388
			else
389
				c += Bprint(bioout, "\\x%.2ux", *p);
390
		inc = 0;
391
		break;
392
 
393
	case 'Y':
394
		p = ctime(mem? getmem_b(dot): val);
395
		p[30] = '\0';
396
		c = Bprint(bioout, "%s", p);
397
		inc = 4;
398
		break;
399
 
400
	case 'a':
401
		symoff(str, sizeof(str), dot, CTEXT);
402
		c = Bprint(bioout, str);
403
		inc = 0;
404
		break;
405
 
406
	case 'e':
407
		for(i = 0; globalsym(&s, i); i++)
408
			Bprint(bioout, "%-15s #%lux\n", s.name,	getmem_4(s.value));
409
		inc = 0;
410
		break;
411
 
412
	case 'I':
413
	case 'i':
414
		inc = machdata->das(symmap, dot, fmt, str, sizeof(str));
415
		if(inc < 0) {
416
			Bprint(bioout, "5i: %r\n");
417
			return 0;
418
		}
419
		c = Bprint(bioout, "\t%s", str);
420
		break;
421
 
422
	case 'n':
423
		c = width+1;
424
		inc = 0;
425
		break;
426
 
427
	case '-':
428
		c = 0;
429
		inc = -1;
430
		break;
431
 
432
	case '+':
433
		c = 0;
434
		inc = 1;
435
		break;
436
 
437
	case '^':
438
		c = 0;
439
		if(inc > 0)
440
			inc = -inc;
441
		break;
442
 
443
	case 'z':
444
		if(findsym(dot, CTEXT, &s))
445
			Bprint(bioout, "  %s() ", s.name);
446
		printsource(dot);
447
		inc = 0;
448
		break;
449
	}
450
	return c;
451
}
452
 
453
void
454
eval(char *addr, char *p)
455
{
456
	ulong val;
457
 
458
	val = expr(addr);
459
	p = nextc(p);
460
	if(*p == '\0') {
461
		p[0] = fmt;
462
		p[1] = '\0';
463
	}
464
	pfmt(*p, 0, val);
465
	Bprint(bioout, "\n");
466
}
467
 
468
void
469
quesie(char *p)
470
{
471
	int c, count, i;
472
	char tbuf[512];
473
 
474
	c = 0;
475
	symoff(tbuf, sizeof(tbuf), dot, CTEXT);
476
	Bprint(bioout, "%s?\t", tbuf);
477
 
478
	while(*p) {
479
		p = nextc(p);
480
		if(*p == '"') {
481
			for(p++; *p && *p != '"'; p++) {
482
				Bputc(bioout, *p);
483
				c++;
484
			}
485
			if(*p)
486
				p++;
487
			continue;
488
		}
489
		count = 0;
490
		while(*p >= '0' && *p <= '9')
491
			count = count*10 + (*p++ - '0');
492
		if(count == 0)
493
			count = 1;
494
		p = nextc(p);
495
		if(*p == '\0') {
496
			p[0] = fmt;
497
			p[1] = '\0';
498
		}
499
		for(i = 0; i < count; i++) {
500
			c += pfmt(*p, 1, 0);
501
			dot += inc;
502
			if(c > width) {
503
				Bprint(bioout, "\n");
504
				symoff(tbuf, sizeof(tbuf), dot, CTEXT);
505
				Bprint(bioout, "%s?\t", tbuf);
506
				c = 0;
507
			}
508
		}
509
		fmt = *p++;
510
		p = nextc(p);
511
	}
512
	Bprint(bioout, "\n");
513
}
514
 
515
void
516
catcher(void *a, char *msg)
517
{
518
	static int hit = 0;
519
 
520
	hit++;
521
	if(hit > 5)
522
		exits(0);
523
	USED(a);
524
	if(strcmp(msg, "interrupt") != 0)
525
		noted(NDFLT);
526
 
527
	count = 1;
528
	print("5i\n");
529
	noted(NCONT);
530
}
531
 
532
void
533
setreg(char *addr, char *cp)
534
{
535
	int rn;
536
 
537
	dot = expr(addr);
538
	cp = nextc(cp);
539
	if(strcmp(cp, "pc") == 0) {
540
		reg.r[15] = dot;
541
		return;
542
	}
543
	if(strcmp(cp, "sp") == 0) {
544
		reg.r[13] = dot;
545
		return;
546
	}
547
	if(*cp++ == 'r') {
548
		rn = strtoul(cp, 0, 10);
549
		if(rn > 0 && rn < 16) {
550
			reg.r[rn] = dot;
551
			return;
552
		}
553
	}
554
	Bprint(bioout, "bad register\n");
555
}
556
 
557
void
558
cmd(void)
559
{
560
	char *p, *a, *cp, *gotint;
561
	char addr[128];
562
	static char *cmdlet = ":$?/=>";
563
	int n, i;
564
 
565
	notify(catcher);
566
 
567
	dot = reg.r[15];
568
	setjmp(errjmp);
569
 
570
	for(;;) {
571
		Bflush(bioout);
572
		p = buf;
573
		n = 0;
574
		for(;;) {
575
			i = Bgetc(bin);
576
			if(i < 0)
577
				exits(0);
578
			*p++ = i;
579
			n++;
580
			if(i == '\n')
581
				break;
582
		}
583
 
584
		if(buf[0] == '\n')
585
			strcpy(buf, lastcmd);
586
		else {
587
			buf[n-1] = '\0';
588
			strcpy(lastcmd, buf);
589
		}
590
		p = buf;
591
		a = addr;
592
 
593
		for(;;) {
594
			p = nextc(p);
595
			if(*p == 0 || strchr(cmdlet, *p))
596
				break;
597
			*a++ = *p++;
598
		}
599
 
600
		*a = '\0';
601
		cmdcount = 1;
602
		cp = strchr(addr, ',');
603
		if(cp != 0) {
604
			if(cp[1] == '#')
605
				cmdcount = strtoul(cp+2, &gotint, 16);
606
			else
607
				cmdcount = strtoul(cp+1, &gotint, 0);
608
			*cp = '\0';
609
		}
610
 
611
		switch(*p) {
612
		case '$':
613
			dollar(p+1);
614
			break;
615
		case ':':
616
			colon(addr, p+1);
617
			break;
618
		case '/':
619
		case '?':
620
			dot = expr(addr);
621
			for(i = 0; i < cmdcount; i++)
622
				quesie(p+1);
623
			break;
624
		case '=':
625
			eval(addr, p+1);
626
			break;
627
		case '>':
628
			setreg(addr, p+1);
629
			break;
630
		default:
631
			Bprint(bioout, "?\n");
632
			break;
633
		}
634
	}
635
}