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