|
|
1.1 ! root 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, long *r, Rgetter rget) ! 21: { ! 22: Symbol s; ! 23: ulong fp; ! 24: ulong pc, sp, link; ! 25: ! 26: if (!lookup(fn, 0, &s)) { ! 27: werrstr("function not found"); ! 28: return -1; ! 29: } ! 30: pc = rget(map, mach->pc); ! 31: sp = rget(map, mach->sp); ! 32: if(mach->link) ! 33: link = rget(map, mach->link); ! 34: else ! 35: link = 0; ! 36: fp = machdata->findframe(map, s.value, pc, sp, link); ! 37: if (fp == 0) { ! 38: werrstr("stack frame not found"); ! 39: return -1; ! 40: } ! 41: ! 42: if (!var || !var[0]) { ! 43: *r = fp; ! 44: return 1; ! 45: } ! 46: ! 47: if (findlocal(&s, var, &s) == 0) { ! 48: werrstr("local variable not found"); ! 49: return -1; ! 50: } ! 51: ! 52: switch (s.class) { ! 53: case CAUTO: ! 54: *r = fp - s.value; ! 55: break; ! 56: case CPARAM: /* assume address size is stack width */ ! 57: *r = fp + s.value + mach->szaddr; ! 58: break; ! 59: default: ! 60: werrstr("local variable not found: %d", s.class); ! 61: return -1; ! 62: } ! 63: return 1; ! 64: } ! 65: ! 66: /* ! 67: * Print value v as name[+offset] and then the string s. ! 68: */ ! 69: int ! 70: symoff(char *buf, int n, long v, int space) ! 71: { ! 72: Symbol s; ! 73: int r; ! 74: long delta; ! 75: ! 76: r = delta = 0; /* to shut compiler up */ ! 77: if (v) { ! 78: r = findsym(v, space, &s); ! 79: if (r) ! 80: delta = v-s.value; ! 81: if (delta < 0) ! 82: delta = -delta; ! 83: } ! 84: if (v == 0 || r == 0) ! 85: return snprint(buf, n, "%lux", v); ! 86: if (s.type != 't' && s.type != 'T' && delta >= 4096) ! 87: return snprint(buf, n, "%lux", v); ! 88: else if (delta) ! 89: return snprint(buf, n, "%s+%lux", s.name, delta); ! 90: else ! 91: return snprint(buf, n, "%s", s.name); ! 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: long r; ! 108: ! 109: switch(rp->rformat) ! 110: { ! 111: case 'X': ! 112: if (get4(map, rp->raddr, &r) < 0) ! 113: return -1; ! 114: snprint(buf, n, "%lux", r+rp->rdelta); ! 115: break; ! 116: case 'F': /* first reg of double reg pair */ ! 117: if (modif == 'F') ! 118: if (((rp+1)->rflags&RFLT) && (rp+1)->rformat == 'f') { ! 119: if (get1(map, rp->raddr, (uchar *)reg, 8) < 0) ! 120: return -1; ! 121: machdata->dftos(buf, n, reg); ! 122: return 2; ! 123: } ! 124: /* treat it like 'f' */ ! 125: if (get1(map, rp->raddr, (uchar *)reg, 4) < 0) ! 126: return -1; ! 127: machdata->sftos(buf, n, reg); ! 128: break; ! 129: case 'f': /* 32 bit float */ ! 130: if (get1(map, rp->raddr, (uchar *)reg, 4) < 0) ! 131: return -1; ! 132: machdata->sftos(buf, n, reg); ! 133: break; ! 134: case '3': /* little endian ieee 80 with hole in bytes 8&9 */ ! 135: if (get1(map, rp->raddr, (uchar *)reg, 10) < 0) ! 136: return -1; ! 137: memmove(reg+10, reg+8, 2); /* open hole */ ! 138: memset(reg+8, 0, 2); /* fill it */ ! 139: leieee80ftos(buf, n, reg); ! 140: break; ! 141: case '8': /* big-endian ieee 80 */ ! 142: if (get1(map, rp->raddr, (uchar *)reg, 10) < 0) ! 143: return -1; ! 144: beieee80ftos(buf, n, reg); ! 145: break; ! 146: default: /* unknown */ ! 147: break; ! 148: } ! 149: return 1; ! 150: } ! 151: ! 152: char * ! 153: _hexify(char *buf, ulong p, int zeros) ! 154: { ! 155: ulong d; ! 156: ! 157: d = p/16; ! 158: if(d) ! 159: buf = _hexify(buf, d, zeros-1); ! 160: else ! 161: while(zeros--) ! 162: *buf++ = '0'; ! 163: *buf++ = "0123456789abcdef"[p&0x0f]; ! 164: return buf; ! 165: } ! 166: ! 167: /* ! 168: * These routines assume that if the number is representable ! 169: * in IEEE floating point, it will be representable in the native ! 170: * double format. Naive but workable, probably. ! 171: */ ! 172: int ! 173: ieeedftos(char *buf, int n, ulong h, ulong l) ! 174: { ! 175: double fr; ! 176: int exp; ! 177: ! 178: if (n <= 0) ! 179: return 0; ! 180: ! 181: ! 182: if(h & (1L<<31)){ ! 183: *buf++ = '-'; ! 184: h &= ~(1L<<31); ! 185: }else ! 186: *buf++ = ' '; ! 187: n--; ! 188: if(l == 0 && h == 0) ! 189: return snprint(buf, n, "0."); ! 190: exp = (h>>20) & ((1L<<11)-1L); ! 191: if(exp == 0) ! 192: return snprint(buf, n, "DeN(%.8lux%.8lux)", h, l); ! 193: if(exp == ((1L<<11)-1L)){ ! 194: if(l==0 && (h&((1L<<20)-1L)) == 0) ! 195: return snprint(buf, n, "Inf"); ! 196: else ! 197: return snprint(buf, n, "NaN(%.8lux%.8lux)", h&((1L<<20)-1L), l); ! 198: } ! 199: exp -= (1L<<10) - 2L; ! 200: fr = l & ((1L<<16)-1L); ! 201: fr /= 1L<<16; ! 202: fr += (l>>16) & ((1L<<16)-1L); ! 203: fr /= 1L<<16; ! 204: fr += (h & (1L<<20)-1L) | (1L<<20); ! 205: fr /= 1L<<21; ! 206: fr = ldexp(fr, exp); ! 207: return snprint(buf, n, "%.18g", fr); ! 208: } ! 209: ! 210: int ! 211: ieeesftos(char *buf, int n, ulong h) ! 212: { ! 213: double fr; ! 214: int exp; ! 215: ! 216: if (n <= 0) ! 217: return 0; ! 218: ! 219: if(h & (1L<<31)){ ! 220: *buf++ = '-'; ! 221: h &= ~(1L<<31); ! 222: }else ! 223: *buf++ = ' '; ! 224: n--; ! 225: if(h == 0) ! 226: return snprint(buf, n, "0."); ! 227: exp = (h>>23) & ((1L<<8)-1L); ! 228: if(exp == 0) ! 229: return snprint(buf, n, "DeN(%.8lux)", h); ! 230: if(exp == ((1L<<8)-1L)){ ! 231: if((h&((1L<<23)-1L)) == 0) ! 232: return snprint(buf, n, "Inf"); ! 233: else ! 234: return snprint(buf, n, "NaN(%.8lux)", h&((1L<<23)-1L)); ! 235: } ! 236: exp -= (1L<<7) - 2L; ! 237: fr = (h & ((1L<<23)-1L)) | (1L<<23); ! 238: fr /= 1L<<24; ! 239: fr = ldexp(fr, exp); ! 240: return snprint(buf, n, "%.9g", fr); ! 241: } ! 242: ! 243: int ! 244: beieeesftos(char *buf, int n, void *s) ! 245: { ! 246: return ieeesftos(buf, n, beswal(*(ulong*)s)); ! 247: } ! 248: ! 249: int ! 250: beieeedftos(char *buf, int n, void *s) ! 251: { ! 252: return ieeedftos(buf, n, beswal(*(ulong*)s), beswal(((ulong*)(s))[1])); ! 253: } ! 254: ! 255: int ! 256: leieeesftos(char *buf, int n, void *s) ! 257: { ! 258: return ieeesftos(buf, n, leswal(*(ulong*)s)); ! 259: } ! 260: ! 261: int ! 262: leieeedftos(char *buf, int n, void *s) ! 263: { ! 264: return ieeedftos(buf, n, leswal(((ulong*)(s))[1]), leswal(*(ulong*)s)); ! 265: } ! 266: ! 267: /* packed in 12 bytes, with s[2]==s[3]==0; mantissa starts at s[4]*/ ! 268: int ! 269: beieee80ftos(char *buf, int n, void *s) ! 270: { ! 271: uchar *reg = (uchar*)s; ! 272: int i; ! 273: ulong x; ! 274: uchar ieee[8+8]; /* room for slop */ ! 275: uchar *p, *q; ! 276: ! 277: memset(ieee, 0, sizeof(ieee)); ! 278: /* sign */ ! 279: if(reg[0] & 0x80) ! 280: ieee[0] |= 0x80; ! 281: ! 282: /* exponent */ ! 283: x = ((reg[0]&0x7F)<<8) | reg[1]; ! 284: if(x == 0) /* number is ±0 */ ! 285: goto done; ! 286: if(x == 0x7FFF){ ! 287: if(memcmp(reg+4, ieee+1, 8) == 0){ /* infinity */ ! 288: x = 2047; ! 289: }else{ /* NaN */ ! 290: x = 2047; ! 291: ieee[7] = 0x1; /* make sure */ ! 292: } ! 293: ieee[0] |= x>>4; ! 294: ieee[1] |= (x&0xF)<<4; ! 295: goto done; ! 296: } ! 297: x -= 0x3FFF; /* exponent bias */ ! 298: x += 1023; ! 299: if(x >= (1<<11) || ((reg[4]&0x80)==0 && x!=0)) ! 300: return snprint(buf, n, "not in range"); ! 301: ieee[0] |= x>>4; ! 302: ieee[1] |= (x&0xF)<<4; ! 303: ! 304: /* mantissa */ ! 305: p = reg+4; ! 306: q = ieee+1; ! 307: for(i=0; i<56; i+=8, p++, q++){ /* move one byte */ ! 308: x = (p[0]&0x7F) << 1; ! 309: if(p[1] & 0x80) ! 310: x |= 1; ! 311: q[0] |= x>>4; ! 312: q[1] |= (x&0xF)<<4; ! 313: } ! 314: done: ! 315: return beieeedftos(buf, n, (void*)ieee); ! 316: } ! 317: ! 318: ! 319: int ! 320: leieee80ftos(char *buf, int n, void *s) ! 321: { ! 322: int i; ! 323: char *cp; ! 324: char b[12]; ! 325: ! 326: cp = (char*) s; ! 327: for(i=0; i<12; i++) ! 328: b[11-i] = *cp++; ! 329: return beieee80ftos(buf, n, b); ! 330: } ! 331: ! 332: int ! 333: cisctrace(Map *map, ulong pc, ulong sp, ulong link, Tracer trace) ! 334: { ! 335: Symbol s; ! 336: int found; ! 337: ulong opc; ! 338: long moved, j; ! 339: ! 340: USED(link); ! 341: j = 0; ! 342: opc = 0; ! 343: while(pc && opc != pc) { ! 344: moved = pc2sp(pc); ! 345: if (moved == -1) ! 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 (get4(map, sp, (long *)&pc) < 0) ! 356: break; ! 357: (*trace)(map, pc, sp, &s); ! 358: sp += mach->szaddr; /*assumes address size = stack width*/ ! 359: if(++j > 40) ! 360: break; ! 361: } ! 362: return j; ! 363: } ! 364: ! 365: int ! 366: risctrace(Map *map, ulong pc, ulong sp, ulong link, Tracer trace) ! 367: { ! 368: int i; ! 369: Symbol s, f; ! 370: ulong 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 (get4(map, sp, (long *) &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: ulong ! 402: ciscframe(Map *map, ulong addr, ulong pc, ulong sp, ulong link) ! 403: { ! 404: Symbol s; ! 405: int moved; ! 406: ! 407: USED(link); ! 408: for(;;) { ! 409: moved = pc2sp(pc); ! 410: if (moved == -1) ! 411: break; ! 412: sp += moved; ! 413: findsym(pc, CTEXT, &s); ! 414: if (addr == s.value) ! 415: return sp; ! 416: if (get4(map, sp, (long *) &pc) < 0) ! 417: break; ! 418: sp += mach->szaddr; /*assumes sizeof(addr) = stack width*/ ! 419: } ! 420: return 0; ! 421: } ! 422: ! 423: ulong ! 424: riscframe(Map *map, ulong addr, ulong pc, ulong sp, ulong 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 (get4(map, sp-f.value, (long *)&pc) < 0) ! 446: break; ! 447: } ! 448: return 0; ! 449: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.