Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/feature_posix/sys/src/libmach/machdata.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/*
2
 * Debugger utilities shared by at least two architectures
3
 */
4
 
5
#include <u.h>
6
#include <libc.h>
7
#include <bio.h>
8
#include <mach.h>
9
 
10
#define STARTSYM	"_main"
11
#define PROFSYM		"_mainp"
12
#define	FRAMENAME	".frame"
13
 
14
extern	Machdata	mipsmach;
15
 
16
int	asstype = AMIPS;		/* disassembler type */
17
Machdata *machdata;		/* machine-dependent functions */
18
 
19
int
20
localaddr(Map *map, char *fn, char *var, uvlong *r, Rgetter rget)
21
{
22
	Symbol s;
23
	uvlong fp, pc, sp, link;
24
 
25
	if (!lookup(fn, 0, &s)) {
26
		werrstr("function not found");
27
		return -1;
28
	}
29
	pc = rget(map, mach->pc);
30
	sp = rget(map, mach->sp);
31
	if(mach->link)
32
		link = rget(map, mach->link);
33
	else
34
		link = 0;
35
	fp = machdata->findframe(map, s.value, pc, sp, link);
36
	if (fp == 0) {
37
		werrstr("stack frame not found");
38
		return -1;
39
	}
40
 
41
	if (!var || !var[0]) {
42
		*r = fp;
43
		return 1;
44
	}
45
 
46
	if (findlocal(&s, var, &s) == 0) {
47
		werrstr("local variable not found");
48
		return -1;
49
	}
50
 
51
	switch (s.class) {
52
	case CAUTO:
53
		*r = fp - s.value;
54
		break;
55
	case CPARAM:		/* assume address size is stack width */
56
		*r = fp + s.value + mach->szaddr;
57
		break;
58
	default:
59
		werrstr("local variable not found: %d", s.class);
60
		return -1;
61
	}
62
	return 1;
63
}
64
 
65
/*
66
 * Print value v as s.name[+offset] if possible, or just v.
67
 */
68
int
69
symoff(char *buf, int n, uvlong v, int space)
70
{
71
	Symbol s;
72
	int r;
73
	long delta;
74
 
75
	r = delta = 0;		/* to shut compiler up */
76
	if (v) {
77
		r = findsym(v, space, &s);
78
		if (r)
79
			delta = v-s.value;
80
		if (delta < 0)
81
			delta = -delta;
82
	}
83
	if (v == 0 || r == 0)
84
		return snprint(buf, n, "%llux", v);
85
	if (s.type != 't' && s.type != 'T' && delta >= 4096)
86
		return snprint(buf, n, "%llux", v);
87
	else if (delta)
88
		return snprint(buf, n, "%s+%lux", s.name, delta);
89
	else
90
		return snprint(buf, n, "%s", s.name);
91
}
92
 
93
/*
94
 *	Format floating point registers
95
 *
96
 *	Register codes in format field:
97
 *	'X' - print as 32-bit hexadecimal value
98
 *	'F' - 64-bit double register when modif == 'F'; else 32-bit single reg
99
 *	'f' - 32-bit ieee float
100
 *	'8' - big endian 80-bit ieee extended float
101
 *	'3' - little endian 80-bit ieee extended float with hole in bytes 8&9
102
 */
103
int
104
fpformat(Map *map, Reglist *rp, char *buf, int n, int modif)
105
{
106
	char reg[12];
107
	ulong r;
108
 
109
	switch(rp->rformat)
110
	{
111
	case 'X':
112
		if (get4(map, rp->roffs, &r) < 0)
113
			return -1;
114
		snprint(buf, n, "%lux", r);
115
		break;
116
	case 'F':	/* first reg of double reg pair */
117
		if (modif == 'F')
118
		if ((rp->rformat=='F') || (((rp+1)->rflags&RFLT) && (rp+1)->rformat == 'f')) {
119
			if (get1(map, rp->roffs, (uchar *)reg, 8) < 0)
120
				return -1;
121
			machdata->dftos(buf, n, reg);
122
			if (rp->rformat == 'F')
123
				return 1;
124
			return 2;
125
		}	
126
			/* treat it like 'f' */
127
		if (get1(map, rp->roffs, (uchar *)reg, 4) < 0)
128
			return -1;
129
		machdata->sftos(buf, n, reg);
130
		break;
131
	case 'f':	/* 32 bit float */
132
		if (get1(map, rp->roffs, (uchar *)reg, 4) < 0)
133
			return -1;
134
		machdata->sftos(buf, n, reg);
135
		break;
136
	case '3':	/* little endian ieee 80 with hole in bytes 8&9 */
137
		if (get1(map, rp->roffs, (uchar *)reg, 10) < 0)
138
			return -1;
139
		memmove(reg+10, reg+8, 2);	/* open hole */
140
		memset(reg+8, 0, 2);		/* fill it */
141
		leieee80ftos(buf, n, reg);
142
		break;
143
	case '8':	/* big-endian ieee 80 */
144
		if (get1(map, rp->roffs, (uchar *)reg, 10) < 0)
145
			return -1;
146
		beieee80ftos(buf, n, reg);
147
		break;
148
	default:	/* unknown */
149
		break;
150
	}
151
	return 1;
152
}
153
 
154
char *
155
_hexify(char *buf, ulong p, int zeros)
156
{
157
	ulong d;
158
 
159
	d = p/16;
160
	if(d)
161
		buf = _hexify(buf, d, zeros-1);
162
	else
163
		while(zeros--)
164
			*buf++ = '0';
165
	*buf++ = "0123456789abcdef"[p&0x0f];
166
	return buf;
167
}
168
 
169
/*
170
 * These routines assume that if the number is representable
171
 * in IEEE floating point, it will be representable in the native
172
 * double format.  Naive but workable, probably.
173
 */
174
int
175
ieeedftos(char *buf, int n, ulong h, ulong l)
176
{
177
	double fr;
178
	int exp;
179
 
180
	if (n <= 0)
181
		return 0;
182
 
183
 
184
	if(h & (1L<<31)){
185
		*buf++ = '-';
186
		h &= ~(1L<<31);
187
	}else
188
		*buf++ = ' ';
189
	n--;
190
	if(l == 0 && h == 0)
191
		return snprint(buf, n, "0.");
192
	exp = (h>>20) & ((1L<<11)-1L);
193
	if(exp == 0)
194
		return snprint(buf, n, "DeN(%.8lux%.8lux)", h, l);
195
	if(exp == ((1L<<11)-1L)){
196
		if(l==0 && (h&((1L<<20)-1L)) == 0)
197
			return snprint(buf, n, "Inf");
198
		else
199
			return snprint(buf, n, "NaN(%.8lux%.8lux)", h&((1L<<20)-1L), l);
200
	}
201
	exp -= (1L<<10) - 2L;
202
	fr = l & ((1L<<16)-1L);
203
	fr /= 1L<<16;
204
	fr += (l>>16) & ((1L<<16)-1L);
205
	fr /= 1L<<16;
206
	fr += (h & (1L<<20)-1L) | (1L<<20);
207
	fr /= 1L<<21;
208
	fr = ldexp(fr, exp);
209
	return snprint(buf, n, "%.18g", fr);
210
}
211
 
212
int
213
ieeesftos(char *buf, int n, ulong h)
214
{
215
	double fr;
216
	int exp;
217
 
218
	if (n <= 0)
219
		return 0;
220
 
221
	if(h & (1L<<31)){
222
		*buf++ = '-';
223
		h &= ~(1L<<31);
224
	}else
225
		*buf++ = ' ';
226
	n--;
227
	if(h == 0)
228
		return snprint(buf, n, "0.");
229
	exp = (h>>23) & ((1L<<8)-1L);
230
	if(exp == 0)
231
		return snprint(buf, n, "DeN(%.8lux)", h);
232
	if(exp == ((1L<<8)-1L)){
233
		if((h&((1L<<23)-1L)) == 0)
234
			return snprint(buf, n, "Inf");
235
		else
236
			return snprint(buf, n, "NaN(%.8lux)", h&((1L<<23)-1L));
237
	}
238
	exp -= (1L<<7) - 2L;
239
	fr = (h & ((1L<<23)-1L)) | (1L<<23);
240
	fr /= 1L<<24;
241
	fr = ldexp(fr, exp);
242
	return snprint(buf, n, "%.9g", fr);
243
}
244
 
245
int
246
beieeesftos(char *buf, int n, void *s)
247
{
248
	return ieeesftos(buf, n, beswal(*(ulong*)s));
249
}
250
 
251
int
252
beieeedftos(char *buf, int n, void *s)
253
{
254
	return ieeedftos(buf, n, beswal(*(ulong*)s), beswal(((ulong*)(s))[1]));
255
}
256
 
257
int
258
leieeesftos(char *buf, int n, void *s)
259
{
260
	return ieeesftos(buf, n, leswal(*(ulong*)s));
261
}
262
 
263
int
264
leieeedftos(char *buf, int n, void *s)
265
{
266
	return ieeedftos(buf, n, leswal(((ulong*)(s))[1]), leswal(*(ulong*)s));
267
}
268
 
269
/* packed in 12 bytes, with s[2]==s[3]==0; mantissa starts at s[4]*/
270
int
271
beieee80ftos(char *buf, int n, void *s)
272
{
273
	uchar *reg = (uchar*)s;
274
	int i;
275
	ulong x;
276
	uchar ieee[8+8];	/* room for slop */
277
	uchar *p, *q;
278
 
279
	memset(ieee, 0, sizeof(ieee));
280
	/* sign */
281
	if(reg[0] & 0x80)
282
		ieee[0] |= 0x80;
283
 
284
	/* exponent */
285
	x = ((reg[0]&0x7F)<<8) | reg[1];
286
	if(x == 0)		/* number is ±0 */
287
		goto done;
288
	if(x == 0x7FFF){
289
		if(memcmp(reg+4, ieee+1, 8) == 0){ /* infinity */
290
			x = 2047;
291
		}else{				/* NaN */
292
			x = 2047;
293
			ieee[7] = 0x1;		/* make sure */
294
		}
295
		ieee[0] |= x>>4;
296
		ieee[1] |= (x&0xF)<<4;
297
		goto done;
298
	}
299
	x -= 0x3FFF;		/* exponent bias */
300
	x += 1023;
301
	if(x >= (1<<11) || ((reg[4]&0x80)==0 && x!=0))
302
		return snprint(buf, n, "not in range");
303
	ieee[0] |= x>>4;
304
	ieee[1] |= (x&0xF)<<4;
305
 
306
	/* mantissa */
307
	p = reg+4;
308
	q = ieee+1;
309
	for(i=0; i<56; i+=8, p++, q++){	/* move one byte */
310
		x = (p[0]&0x7F) << 1;
311
		if(p[1] & 0x80)
312
			x |= 1;
313
		q[0] |= x>>4;
314
		q[1] |= (x&0xF)<<4;
315
	}
316
    done:
317
	return beieeedftos(buf, n, (void*)ieee);
318
}
319
 
320
int
321
leieee80ftos(char *buf, int n, void *s)
322
{
323
	int i;
324
	char *cp;
325
	char b[12];
326
 
327
	cp = (char*) s;
328
	for(i=0; i<12; i++)
329
		b[11-i] = *cp++;
330
	return beieee80ftos(buf, n, b);
331
}
332
 
333
int
334
cisctrace(Map *map, uvlong pc, uvlong sp, uvlong link, Tracer trace)
335
{
336
	Symbol s;
337
	int found, i;
338
	uvlong opc, moved;
339
 
340
	USED(link);
341
	i = 0;
342
	opc = 0;
343
	while(pc && opc != pc) {
344
		moved = pc2sp(pc);
345
		if (moved == ~0)
346
			break;
347
		found = findsym(pc, CTEXT, &s);
348
		if (!found)
349
			break;
350
		if(strcmp(STARTSYM, s.name) == 0 || strcmp(PROFSYM, s.name) == 0)
351
			break;
352
 
353
		sp += moved;
354
		opc = pc;
355
		if (geta(map, sp, &pc) < 0)
356
			break;
357
		(*trace)(map, pc, sp, &s);
358
		sp += mach->szaddr;	/*assumes address size = stack width*/
359
		if(++i > 40)
360
			break;
361
	}
362
	return i;
363
}
364
 
365
int
366
risctrace(Map *map, uvlong pc, uvlong sp, uvlong link, Tracer trace)
367
{
368
	int i;
369
	Symbol s, f;
370
	uvlong oldpc;
371
 
372
	i = 0;
373
	while(findsym(pc, CTEXT, &s)) {
374
		if(strcmp(STARTSYM, s.name) == 0 || strcmp(PROFSYM, s.name) == 0)
375
			break;
376
 
377
		if(pc == s.value)	/* at first instruction */
378
			f.value = 0;
379
		else if(findlocal(&s, FRAMENAME, &f) == 0)
380
			break;
381
 
382
		oldpc = pc;
383
		if(s.type == 'L' || s.type == 'l' || pc <= s.value+mach->pcquant)
384
			pc = link;
385
		else
386
			if (geta(map, sp, &pc) < 0)
387
				break;
388
 
389
		if(pc == 0 || (pc == oldpc && f.value == 0))
390
			break;
391
 
392
		sp += f.value;
393
		(*trace)(map, pc-8, sp, &s);
394
 
395
		if(++i > 40)
396
			break;
397
	}
398
	return i;
399
}
400
 
401
uvlong
402
ciscframe(Map *map, uvlong addr, uvlong pc, uvlong sp, uvlong link)
403
{
404
	Symbol s;
405
	uvlong moved;
406
 
407
	USED(link);
408
	for(;;) {
409
		moved = pc2sp(pc);
410
		if (moved  == ~0)
411
			break;
412
		sp += moved;
413
		findsym(pc, CTEXT, &s);
414
		if (addr == s.value)
415
			return sp;
416
		if (geta(map, sp, &pc) < 0)
417
			break;
418
		sp += mach->szaddr;	/*assumes sizeof(addr) = stack width*/
419
	}
420
	return 0;
421
}
422
 
423
uvlong
424
riscframe(Map *map, uvlong addr, uvlong pc, uvlong sp, uvlong link)
425
{
426
	Symbol s, f;
427
 
428
	while (findsym(pc, CTEXT, &s)) {
429
		if(strcmp(STARTSYM, s.name) == 0 || strcmp(PROFSYM, s.name) == 0)
430
			break;
431
 
432
		if(pc == s.value)	/* at first instruction */
433
			f.value = 0;
434
		else
435
		if(findlocal(&s, FRAMENAME, &f) == 0)
436
			break;
437
 
438
		sp += f.value;
439
		if (s.value == addr)
440
			return sp;
441
 
442
		if (s.type == 'L' || s.type == 'l' || pc-s.value <= mach->szaddr*2)
443
			pc = link;
444
		else
445
		if (geta(map, sp-f.value, &pc) < 0)
446
			break;
447
	}
448
	return 0;
449
}