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