Subversion Repositories planix.SVN

Rev

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

Rev Author Line No. Line
2 - 1
/*
2
 *
3
 *	debugger
4
 *
5
 */
6
#include "defs.h"
7
#include "fns.h"
8
 
9
extern	int	infile;
10
extern	int	outfile;
11
extern	int	maxpos;
12
 
13
/* general printing routines ($) */
14
 
15
char	*Ipath = INCDIR;
16
static	int	tracetype;
17
static void	printfp(Map*, int);
18
 
19
/*
20
 *	callback on stack trace
21
 */
22
static void
23
ptrace(Map *map, uvlong pc, uvlong sp, Symbol *sym)
24
{
25
	char buf[512];
26
 
27
	USED(map);
28
	dprint("%s(", sym->name);
29
	printparams(sym, sp);
30
	dprint(") ");
31
	printsource(sym->value);
32
	dprint(" called from ");
33
	symoff(buf, 512, pc, CTEXT);
34
	dprint("%s ", buf);
35
	printsource(pc);
36
	dprint("\n");
37
	if(tracetype == 'C')
38
		printlocals(sym, sp);
39
}
40
 
41
void
42
printtrace(int modif)
43
{
44
	int i;
45
	uvlong pc, sp, link;
46
	ulong w;
47
	BKPT *bk;
48
	Symbol s;
49
	int stack;
50
	char *fname;
51
	char buf[512];
52
 
53
	if (cntflg==0)
54
		cntval = -1;
55
	switch (modif) {
56
 
57
	case '<':
58
		if (cntval == 0) {
59
			while (readchar() != EOR)
60
				;
61
			reread();
62
			break;
63
		}
64
		if (rdc() == '<')
65
			stack = 1;
66
		else {
67
			stack = 0;
68
			reread();
69
		}
70
		fname = getfname();
71
		redirin(stack, fname);
72
		break;
73
 
74
	case '>':
75
		fname = getfname();
76
		redirout(fname);
77
		break;
78
 
79
	case 'a':
80
		attachprocess();
81
		break;
82
 
83
	case 'k':
84
		kmsys();
85
		break;
86
 
87
	case 'q':
88
	case 'Q':
89
		done();
90
 
91
	case 'w':
92
		maxpos=(adrflg?adrval:MAXPOS);
93
		break;
94
 
95
	case 'S':
96
		printsym();
97
		break;
98
 
99
	case 's':
100
		maxoff=(adrflg?adrval:MAXOFF);
101
		break;
102
 
103
	case 'm':
104
		printmap("? map", symmap);
105
		printmap("/ map", cormap);
106
		break;
107
 
108
	case 0:
109
	case '?':
110
		if (pid)
111
			dprint("pid = %d\n",pid);
112
		else
113
			prints("no process\n");
114
		flushbuf();
115
 
116
	case 'r':
117
	case 'R':
118
		printregs(modif);
119
		return;
120
 
121
	case 'f':
122
	case 'F':
123
		printfp(cormap, modif);
124
		return;
125
 
126
	case 'c':
127
	case 'C':
128
		tracetype = modif;
129
		if (machdata->ctrace) {
130
			if (adrflg) {
131
				/*
132
				 * trace from jmpbuf for multi-threaded code.
133
				 * assume sp and pc are in adjacent locations
134
				 * and mach->szaddr in size.
135
				 */
136
				if (geta(cormap, adrval, &sp) < 0 ||
137
					geta(cormap, adrval+mach->szaddr, &pc) < 0)
138
						error("%r");
139
			} else {
140
				sp = rget(cormap, mach->sp);
141
				pc = rget(cormap, mach->pc);
142
			}
143
			if(mach->link)
144
				link = rget(cormap, mach->link);
145
			else
146
				link = 0;
147
			if (machdata->ctrace(cormap, pc, sp, link, ptrace) <= 0)
148
				error("no stack frame");
149
		}
150
		break;
151
 
152
		/*print externals*/
153
	case 'e':
154
		for (i = 0; globalsym(&s, i); i++) {
155
			if (get4(cormap, s.value, &w) > 0)
156
				dprint("%s/%12t%#lux\n", s.name, w);
157
		}
158
		break;
159
 
160
		/*print breakpoints*/
161
	case 'b':
162
	case 'B':
163
		for (bk=bkpthead; bk; bk=bk->nxtbkpt)
164
			if (bk->flag) {
165
				symoff(buf, 512, (WORD)bk->loc, CTEXT);
166
				dprint(buf);
167
				if (bk->count != 1)
168
					dprint(",%d", bk->count);
169
				dprint(":%c %s", bk->flag == BKPTTMP ? 'B' : 'b', bk->comm);
170
			}
171
		break;
172
 
173
	case 'M':
174
		fname = getfname();
175
		if (machbyname(fname) == 0)
176
			dprint("unknown name\n");;
177
		break;
178
	default:
179
		error("bad `$' command");
180
	}
181
 
182
}
183
 
184
char *
185
getfname(void)
186
{
187
	static char fname[ARB];
188
	char *p;
189
 
190
	if (rdc() == EOR) {
191
		reread();
192
		return (0);
193
	}
194
	p = fname;
195
	do {
196
		*p++ = lastc;
197
		if (p >= &fname[ARB-1])
198
			error("filename too long");
199
	} while (rdc() != EOR);
200
	*p = 0;
201
	reread();
202
	return (fname);
203
}
204
 
205
static void
206
printfp(Map *map, int modif)
207
{
208
	Reglist *rp;
209
	int i;
210
	int ret;
211
	char buf[512];
212
 
213
	for (i = 0, rp = mach->reglist; rp->rname; rp += ret) {
214
		ret = 1;
215
		if (!(rp->rflags&RFLT))
216
			continue;
217
		ret = fpformat(map, rp, buf, sizeof(buf), modif);
218
		if (ret < 0) {
219
			werrstr("Register %s: %r", rp->rname);
220
			error("%r");
221
		}
222
			/* double column print */
223
		if (i&0x01)
224
			dprint("%40t%-8s%-12s\n", rp->rname, buf);
225
		else
226
			dprint("\t%-8s%-12s", rp->rname, buf);
227
		i++;
228
	}
229
}
230
 
231
void
232
redirin(int stack, char *file)
233
{
234
	char *pfile;
235
 
236
	if (file == 0) {
237
		iclose(-1, 0);
238
		return;
239
	}
240
	iclose(stack, 0);
241
	if ((infile = open(file, 0)) < 0) {
242
		pfile = smprint("%s/%s", Ipath, file);
243
		infile = open(pfile, 0);
244
		free(pfile);
245
		if(infile < 0) {
246
			infile = STDIN;
247
			error("cannot open");
248
		}
249
	}
250
}
251
 
252
void
253
printmap(char *s, Map *map)
254
{
255
	int i;
256
 
257
	if (!map)
258
		return;
259
	if (map == symmap)
260
		dprint("%s%12t`%s'\n", s, fsym < 0 ? "-" : symfil);
261
	else if (map == cormap)
262
		dprint("%s%12t`%s'\n", s, fcor < 0 ? "-" : corfil);
263
	else
264
		dprint("%s\n", s);
265
	for (i = 0; i < map->nsegs; i++) {
266
		if (map->seg[i].inuse)
267
			dprint("%s%8t%-16#llux %-16#llux %-16#llux\n",
268
				map->seg[i].name, map->seg[i].b,
269
				map->seg[i].e, map->seg[i].f);
270
	}
271
}
272
 
273
/*
274
 *	dump the raw symbol table
275
 */
276
void
277
printsym(void)
278
{
279
	int i;
280
	Sym *sp;
281
 
282
	for (i = 0; sp = getsym(i); i++) {
283
		switch(sp->type) {
284
		case 't':
285
		case 'l':
286
			dprint("%16#llux t %s\n", sp->value, sp->name);
287
			break;
288
		case 'T':
289
		case 'L':
290
			dprint("%16#llux T %s\n", sp->value, sp->name);
291
			break;
292
		case 'D':
293
		case 'd':
294
		case 'B':
295
		case 'b':
296
		case 'a':
297
		case 'p':
298
		case 'm':
299
			dprint("%16#llux %c %s\n", sp->value, sp->type, sp->name);
300
			break;
301
		default:
302
			break;
303
		}
304
	}
305
}
306
 
307
#define	STRINGSZ	128
308
 
309
/*
310
 *	print the value of dot as file:line
311
 */
312
void
313
printsource(ADDR dot)
314
{
315
	char str[STRINGSZ];
316
 
317
	if (fileline(str, STRINGSZ, dot))
318
		dprint("%s", str);
319
}
320
 
321
void
322
printpc(void)
323
{
324
	char buf[512];
325
 
326
	dot = rget(cormap, mach->pc);
327
	if(dot){
328
		printsource((long)dot);
329
		printc(' ');
330
		symoff(buf, sizeof(buf), (long)dot, CTEXT);
331
		dprint("%s/", buf);
332
		if (machdata->das(cormap, dot, 'i', buf, sizeof(buf)) < 0)
333
			error("%r");
334
		dprint("%16t%s\n", buf);
335
	}
336
}
337
 
338
void
339
printlocals(Symbol *fn, ADDR fp)
340
{
341
	int i;
342
	ulong w;
343
	Symbol s;
344
 
345
	s = *fn;
346
	for (i = 0; localsym(&s, i); i++) {
347
		if (s.class != CAUTO)
348
			continue;
349
		if (get4(cormap, fp-s.value, &w) > 0)
350
			dprint("%8t%s.%s/%10t%#lux\n", fn->name, s.name, w);
351
		else
352
			dprint("%8t%s.%s/%10t?\n", fn->name, s.name);
353
	}
354
}
355
 
356
void
357
printparams(Symbol *fn, ADDR fp)
358
{
359
	int i;
360
	Symbol s;
361
	ulong w;
362
	int first = 0;
363
 
364
	fp += mach->szaddr;			/* skip saved pc */
365
	s = *fn;
366
	for (i = 0; localsym(&s, i); i++) {
367
		if (s.class != CPARAM)
368
			continue;
369
		if (first++)
370
			dprint(", ");
371
		if (get4(cormap, fp+s.value, &w) > 0)
372
			dprint("%s=%#lux", s.name, w);
373
	}
374
}