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