|
|
1.1 ! root 1: /* ! 2: * @(#)kdb_opset.c 7.4 (Berkeley) 5/1/89 ! 3: */ ! 4: ! 5: #include "../kdb/defs.h" ! 6: ! 7: #include "frame.h" ! 8: ! 9: ADDR kdbcallpc; ! 10: ADDR kdblastframe; ! 11: ! 12: /* ! 13: * Instruction printing. ! 14: */ ! 15: REGLIST kdbreglist [] = { ! 16: "p1lr", &kdbpcb.pcb_p1lr, "p1br", (int *)&kdbpcb.pcb_p1br, ! 17: "p0lr", &kdbpcb.pcb_p0lr, "p0br", (int *)&kdbpcb.pcb_p0br, ! 18: "ksp", &kdbpcb.pcb_ksp, "esp", &kdbpcb.pcb_esp, ! 19: "ssp", &kdbpcb.pcb_ssp, "psl", &kdbpcb.pcb_psl, ! 20: "pc", &kdbpcb.pcb_pc, "usp", &kdbpcb.pcb_usp, ! 21: "fp", &kdbpcb.pcb_fp, "ap", &kdbpcb.pcb_ap, ! 22: "r11", &kdbpcb.pcb_r11, "r10", &kdbpcb.pcb_r10, ! 23: "r9", &kdbpcb.pcb_r9, "r8", &kdbpcb.pcb_r8, ! 24: "r7", &kdbpcb.pcb_r7, "r6", &kdbpcb.pcb_r6, ! 25: "r5", &kdbpcb.pcb_r5, "r4", &kdbpcb.pcb_r4, ! 26: "r3", &kdbpcb.pcb_r3, "r2", &kdbpcb.pcb_r2, ! 27: "r1", &kdbpcb.pcb_r1, "r0", &kdbpcb.pcb_r0, ! 28: 0 ! 29: }; ! 30: ! 31: /* ! 32: * Argument data types ! 33: * ! 34: * If you change these definitions, you must also change the tables ! 35: * in assizetab.c ! 36: */ ! 37: #define TYPB 000 /* byte integer */ ! 38: #define TYPW 001 /* word integer */ ! 39: #define TYPL 002 /* long integer */ ! 40: #define TYPQ 003 /* quad integer */ ! 41: #define TYPO 004 /* octa integer */ ! 42: #define TYPF 005 /* F float */ ! 43: #define TYPD 006 /* D float */ ! 44: #define TYPG 007 /* G float */ ! 45: #define TYPH 010 /* H float */ ! 46: #define TYPUNPACKED 011 /* when unpacked into mantissa & exponent */ ! 47: #define TYPNONE 012 /* when nothing */ ! 48: #define TYPLG 4 /* number of bits the above take up */ ! 49: ! 50: #define TYPMASK ((1<<TYPLG)-1) /* the mask (assumes 2's comp arith) */ ! 51: /* ! 52: * Constructors and extractors for argument access kinds and types ! 53: */ ! 54: #define A_CONS(access, type) ((access) | (type)) ! 55: #define A_ACCEXT(consed) ((consed) & (TYPMASK << TYPLG)) ! 56: #define A_TYPEXT(consed) ((consed) & TYPMASK) ! 57: ! 58: /* ! 59: * Argument access types used to test validity of operands to operators ! 60: */ ! 61: #define ACCR (1<<TYPLG) /* read */ ! 62: #define ACCW (2<<TYPLG) /* write */ ! 63: #define ACCB (4<<TYPLG) /* branch displacement */ ! 64: #define ACCA (8<<TYPLG) /* address only */ ! 65: #define ACCV (8<<TYPLG) /* address only */ ! 66: #define ACCM (ACCR | ACCW) /* modify */ ! 67: #define ACCI (ACCB | ACCR) /* XFC code */ ! 68: ! 69: #define ACCESSMASK (ACCA | ACCR | ACCW | ACCB) /* the mask */ ! 70: ! 71: /* ! 72: * Construction of TYPX and ACCX, to make the instrs table ! 73: * easy to use and read. ! 74: */ ! 75: /* ! 76: * For real memory address ! 77: */ ! 78: #define A_AB A_CONS(ACCA, TYPB) ! 79: #define A_AW A_CONS(ACCA, TYPW) ! 80: #define A_AL A_CONS(ACCA, TYPL) ! 81: #define A_AQ A_CONS(ACCA, TYPQ) ! 82: #define A_AO A_CONS(ACCA, TYPO) ! 83: #define A_AF A_CONS(ACCA, TYPF) ! 84: #define A_AD A_CONS(ACCA, TYPD) ! 85: #define A_AG A_CONS(ACCA, TYPG) ! 86: #define A_AH A_CONS(ACCA, TYPH) ! 87: /* ! 88: * For real memory addresses, or register addresses [sic] ! 89: * ! 90: * CHEAT! we just call these read access, since ! 91: * registers are allowed. All field instruction, except insv, ! 92: * are are read access fields. ! 93: */ ! 94: #define A_VB A_CONS(ACCR, TYPB) ! 95: #define A_VW A_CONS(ACCR, TYPW) ! 96: #define A_VL A_CONS(ACCR, TYPL) ! 97: #define A_VQ A_CONS(ACCR, TYPQ) ! 98: #define A_VO A_CONS(ACCR, TYPO) ! 99: #define A_VF A_CONS(ACCR, TYPF) ! 100: #define A_VD A_CONS(ACCR, TYPD) ! 101: #define A_VG A_CONS(ACCR, TYPG) ! 102: #define A_VH A_CONS(ACCR, TYPH) ! 103: /* ! 104: * For branch displacement ! 105: */ ! 106: #define A_BB A_CONS(ACCB, TYPB) ! 107: #define A_BW A_CONS(ACCB, TYPW) ! 108: /* ! 109: * For modification ! 110: */ ! 111: #define A_MB A_CONS(ACCM, TYPB) ! 112: #define A_MW A_CONS(ACCM, TYPW) ! 113: #define A_ML A_CONS(ACCM, TYPL) ! 114: #define A_MF A_CONS(ACCM, TYPF) ! 115: #define A_MD A_CONS(ACCM, TYPD) ! 116: #define A_MG A_CONS(ACCM, TYPG) ! 117: #define A_MH A_CONS(ACCM, TYPH) ! 118: /* ! 119: * For reading ! 120: */ ! 121: #define A_RB A_CONS(ACCR, TYPB) ! 122: #define A_RW A_CONS(ACCR, TYPW) ! 123: #define A_RL A_CONS(ACCR, TYPL) ! 124: #define A_RQ A_CONS(ACCR, TYPQ) ! 125: #define A_RO A_CONS(ACCR, TYPO) ! 126: #define A_RF A_CONS(ACCR, TYPF) ! 127: #define A_RD A_CONS(ACCR, TYPD) ! 128: #define A_RG A_CONS(ACCR, TYPG) ! 129: #define A_RH A_CONS(ACCR, TYPH) ! 130: /* ! 131: * For writing ! 132: */ ! 133: #define A_WB A_CONS(ACCW, TYPB) ! 134: #define A_WW A_CONS(ACCW, TYPW) ! 135: #define A_WL A_CONS(ACCW, TYPL) ! 136: #define A_WQ A_CONS(ACCW, TYPQ) ! 137: #define A_WO A_CONS(ACCW, TYPO) ! 138: #define A_WF A_CONS(ACCW, TYPF) ! 139: #define A_WD A_CONS(ACCW, TYPD) ! 140: #define A_WG A_CONS(ACCW, TYPG) ! 141: #define A_WH A_CONS(ACCW, TYPH) ! 142: ! 143: struct insttab { ! 144: char *iname; ! 145: u_char eopcode; ! 146: u_char popcode; ! 147: char nargs; ! 148: u_char argtype[6]; ! 149: }; ! 150: ! 151: #define OP(name,eopcode,popdcode,nargs,a1,a2,a3,a4,a5,a6) \ ! 152: {name,eopcode,popdcode,nargs,a1,a2,a3,a4,a5,a6} ! 153: /* ! 154: * Definitions for the escape bytes ! 155: */ ! 156: #define CORE 0 ! 157: #define NEW 1 ! 158: #define ESCD 0xfd ! 159: #define ESCF 0xff ! 160: #define mapescbyte(b) ((b) == ESCD ? 1 : (b) == ESCF ? 2 : 0) ! 161: ! 162: static struct insttab insttab[] = { ! 163: #include "../vax/kdb_instrs" ! 164: 0}; ! 165: ! 166: /* ! 167: * Convert TYP[BWLQOFDGH] into {1 if relocation not OK} ! 168: */ ! 169: int ty_NORELOC[] = { ! 170: 0, /* TYPB */ ! 171: 0, /* TYPW */ ! 172: 0, /* TYPL */ ! 173: 1, /* TYPQ */ ! 174: 1, /* TYPO */ ! 175: 1, /* TYPF */ ! 176: 1, /* TYPD */ ! 177: 1, /* TYPG */ ! 178: 1, /* TYPH */ ! 179: 1 /* TYPNONE */ ! 180: }; ! 181: ! 182: /* ! 183: * Convert TYP[BWLQOFDGH] into {1 ... 16} ! 184: */ ! 185: int ty_nbyte[] = { ! 186: 1, /* TYPB */ ! 187: 2, /* TYPW */ ! 188: 4, /* TYPL */ ! 189: 8, /* TYPQ */ ! 190: 16, /* TYPO */ ! 191: 4, /* TYPF */ ! 192: 8, /* TYPD */ ! 193: 8, /* TYPG */ ! 194: 16, /* TYPH */ ! 195: 0 /* TYPNONE */ ! 196: }; ! 197: ! 198: static char *regname[] = { ! 199: "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", ! 200: "r8", "r9", "r10","r11","ap", "fp", "sp", "pc" ! 201: }; ! 202: static char *fltimm[] = { ! 203: "0.5", "0.5625", "0.625", "0.6875", "0.75", "0.8125", "0.875", "0.9375", ! 204: "1.0", "1.125", "1.25", "1.375", "1.5", "1.625", "1.75", "1.875", ! 205: "2.0", "2.25", "2.5", "2.75", "3.0", "3.25", "3.5", "3.75", ! 206: "4.0", "4.5", "5.0", "5.5", "6.0", "6.5", "7.0", "7.5", ! 207: "8.0", "9.0", "10.0", "11.0", "12.0", "13.0", "14.0", "15.0", ! 208: "16.0", "18.0", "20.0", "22.0", "24.0", "26.0", "28.0", "30.0", ! 209: "32.0", "36.0", "40.0", "44.0", "48.0", "52.0", "56.0", "60.0", ! 210: "64.0", "72.0", "80.0", "88.0", "96.0", "104.0", "112.0", "120.0" ! 211: }; ! 212: ! 213: static int type, space, incp; ! 214: static long insoutvar[36]; ! 215: /* ! 216: * Definitions for registers and for operand classes ! 217: */ ! 218: static char *insregname(); /* how to print a register */ ! 219: ! 220: #define R_PC 0xF ! 221: ! 222: #define OC_IMM0 0x0 ! 223: #define OC_IMM1 0x1 ! 224: #define OC_IMM2 0x2 ! 225: #define OC_IMM3 0x3 ! 226: #define OC_INDEX 0x4 ! 227: #define OC_REG 0x5 ! 228: #define OC_DREG 0x6 ! 229: #define OC_ADREG 0x7 ! 230: #define OC_AIREG 0x8 ! 231: #define OC_DAIREG 0x9 ! 232: ! 233: #define OC_BDISP 0xA ! 234: #define OC_DBDISP 0xB ! 235: #define OC_WDISP 0xC ! 236: #define OC_DWDISP 0xD ! 237: #define OC_LDISP 0xE ! 238: #define OC_DLDISP 0xF ! 239: ! 240: #define OC_SHIFT 4 ! 241: #define OC_CONS(oc,reg) (((oc & 0xF) << OC_SHIFT) | (reg & 0xF)) ! 242: #define OC_AMEXT(x) (((x) >> OC_SHIFT) & 0xF) ! 243: #define OC_REGEXT(x) ((x) & 0xF) ! 244: ! 245: /* ! 246: * Definitions for large numbers ! 247: */ ! 248: #include "asnumber.h" ! 249: typedef struct as_number *numberp; ! 250: static numberp snarf(); ! 251: static numberp snarfreloc(); ! 252: /* ! 253: * Definitions for special instructions ! 254: */ ! 255: #define CASEB 0x8F ! 256: #define CASEW 0xAF ! 257: #define CASEL 0xCF ! 258: ! 259: /* two level 1-based index by opcode into insttab */ ! 260: static short ioptab[3][256]; ! 261: ! 262: kdbsetup() ! 263: { ! 264: register struct insttab *p; ! 265: int mapchar; ! 266: ! 267: for(p = insttab; p->iname; p++){ ! 268: mapchar = mapescbyte(p->eopcode); ! 269: if (ioptab[mapchar][p->popcode]) ! 270: continue; ! 271: ioptab[mapchar][p->popcode] = (p - insttab) + 1; ! 272: } ! 273: } ! 274: ! 275: static u_char snarfuchar(); ! 276: /* ! 277: * Global variables for communicating with the minions and printins ! 278: */ ! 279: static int idsp; ! 280: static short argno; /* which argument one is working on */ ! 281: static char insoutfmt[2]; /* how to format the relocated symbols */ ! 282: ! 283: static savevar(val) ! 284: long val; ! 285: { ! 286: kdbvar[argno] = val; ! 287: insoutvar[argno] = val; ! 288: } ! 289: ! 290: /* ARGSUSED */ ! 291: kdbprintins(Idsp, ins) ! 292: u_char ins; ! 293: int Idsp; ! 294: { ! 295: u_char mode; /* mode */ ! 296: u_char ins2; ! 297: char *indexreg; /* print of which register indexes */ ! 298: char *indexed; /* we indexed */ ! 299: char *operandout(); ! 300: register u_char *ap; ! 301: register struct insttab *ip; ! 302: u_char optype; ! 303: int mapchar; ! 304: ! 305: idsp = Idsp; ! 306: type = DSYM; ! 307: space = idsp; ! 308: insoutfmt[0] = 0; ! 309: ! 310: incp = 1; ! 311: if ((mapchar = mapescbyte(ins)) != 0){ ! 312: ins2 = snarfuchar(); ! 313: if (ioptab[mapchar][ins2] == 0){ ! 314: /* ! 315: * Oops; not a defined instruction; ! 316: * back over this escape byte. ! 317: */ ! 318: incp -= 1; ! 319: mapchar = 0; ! 320: } else { ! 321: ins = ins2; ! 322: } ! 323: } ! 324: if (ioptab[mapchar][ins] == 0){ ! 325: kdbprintf("<undefined operator byte>: %x", ins); ! 326: goto ret; ! 327: } ! 328: ip = &insttab[ioptab[mapchar][ins] - 1]; ! 329: kdbprintf("%s\t", ip->iname); ! 330: ! 331: for (ap = ip->argtype, argno = 0; argno < ip->nargs; argno++, ap++) { ! 332: savevar(0x80000000); /* an illegal symbol */ ! 333: optype = *ap; ! 334: if (argno != 0) ! 335: kdbprintc(','); ! 336: indexreg = 0; ! 337: indexed = 0; ! 338: do{ ! 339: if (A_ACCEXT(optype) & ACCB){ ! 340: switch(A_TYPEXT(optype)){ ! 341: case TYPB: ! 342: mode = OC_CONS(OC_BDISP, R_PC); ! 343: break; ! 344: case TYPW: ! 345: mode = OC_CONS(OC_WDISP, R_PC); ! 346: break; ! 347: } ! 348: } else { ! 349: mode = snarfuchar(); ! 350: } ! 351: indexreg = operandout(mode, optype); ! 352: if (indexed) ! 353: kdbprintf("[%s]", indexed); ! 354: indexed = indexreg; ! 355: } while(indexed); ! 356: } ! 357: if (mapchar == 0){ ! 358: switch(ins){ ! 359: case CASEB: ! 360: case CASEW: ! 361: case CASEL: ! 362: casebody(insoutvar[1], insoutvar[2]); ! 363: break; ! 364: default: ! 365: break; ! 366: } ! 367: } ! 368: ret: ; ! 369: ! 370: kdbdotinc = incp; ! 371: } ! 372: ! 373: casebody(base, limit) ! 374: long base; ! 375: long limit; ! 376: { ! 377: int i; ! 378: u_int baseincp; ! 379: u_int advincp; ! 380: struct as_number *valuep; ! 381: #define OSIZE (sizeof(short)) ! 382: argno = 0; ! 383: baseincp = incp; ! 384: for (i = 0; i <= limit; i++) { ! 385: kdbprintc(EOR); ! 386: kdbprintf(" %R: ", i + base); ! 387: valuep = snarfreloc(OSIZE, 0); ! 388: advincp = incp; ! 389: incp = baseincp; ! 390: dispaddress(valuep, OC_CONS(OC_WDISP, R_PC)); ! 391: incp = advincp; ! 392: } ! 393: } ! 394: ! 395: /* ! 396: * magic values to mung an offset to a register into ! 397: * something that psymoff can understand.. all magic ! 398: */ ! 399: /* 0 1 2 3 4 */ ! 400: static long magic_masks[5] = {0, 0x80, 0x8000, 0, 0}; ! 401: static long magic_compl[5] = {0, 0x100, 0x10000,0, 0}; ! 402: /* ! 403: * Snarf up some bytes, and put in the magic relocation flags ! 404: */ ! 405: static numberp snarfreloc(nbytes) ! 406: int nbytes; ! 407: { ! 408: numberp back; ! 409: back = snarf(nbytes); ! 410: if (back->num_ulong[0] & magic_masks[nbytes]) ! 411: back->num_ulong[0] -= magic_compl[nbytes]; ! 412: return(back); ! 413: } ! 414: /* ! 415: * The following code is NOT portable from the PDP 11 to the VAX ! 416: * because of the byte ordering problem. ! 417: */ ! 418: static numberp snarf(nbytes) ! 419: int nbytes; ! 420: { ! 421: register int i; ! 422: ! 423: static struct as_number backnumber; ! 424: static struct as_number znumber; /* init'ed to 0 */ ! 425: ! 426: backnumber = znumber; ! 427: for (i = 0; i < nbytes; i++) ! 428: backnumber.num_uchar[i] = snarfuchar(); ! 429: return(&backnumber); ! 430: } ! 431: ! 432: /* ! 433: * Read one single character, and advance the dot ! 434: */ ! 435: static u_char ! 436: snarfuchar() ! 437: { ! 438: u_char back; ! 439: /* ! 440: * assert: bchkget and inkdot don't have side effects ! 441: */ ! 442: back = (u_char)kdbbchkget(kdbinkdot(incp), idsp); ! 443: incp += 1; ! 444: return(back); ! 445: } ! 446: ! 447: /* ! 448: * normal operand; return non zero pointer to register ! 449: * name if this is an index instruction. ! 450: */ ! 451: char *operandout(mode, optype) ! 452: u_char mode; ! 453: u_char optype; ! 454: { ! 455: char *r; ! 456: int regnumber; ! 457: int nbytes; ! 458: ! 459: regnumber = OC_REGEXT(mode); ! 460: r = insregname(regnumber); ! 461: switch (OC_AMEXT(mode)){ ! 462: case OC_IMM0: ! 463: case OC_IMM1: ! 464: case OC_IMM2: ! 465: case OC_IMM3: ! 466: shortliteral(mode, optype); ! 467: return(0); ! 468: case OC_INDEX: ! 469: return(r); /* will be printed later */ ! 470: case OC_REG: ! 471: kdbprintf("%s", r); ! 472: return(0); ! 473: case OC_DREG: ! 474: kdbprintf("(%s)", r); ! 475: return(0); ! 476: case OC_ADREG: ! 477: kdbprintf("-(%s)", r); ! 478: return(0); ! 479: case OC_DAIREG: ! 480: kdbprintc('*'); ! 481: case OC_AIREG: ! 482: if (regnumber == R_PC){ ! 483: pcimmediate(mode, optype); ! 484: } else { ! 485: kdbprintf("(%s)+", r); ! 486: } ! 487: return(0); ! 488: case OC_DBDISP: ! 489: kdbprintc('*'); ! 490: case OC_BDISP: ! 491: nbytes = 1; ! 492: break; ! 493: case OC_DWDISP: ! 494: kdbprintc('*'); ! 495: case OC_WDISP: ! 496: nbytes = 2; ! 497: break; ! 498: case OC_DLDISP: ! 499: kdbprintc('*'); ! 500: case OC_LDISP: ! 501: nbytes = 4; ! 502: break; ! 503: } ! 504: dispaddress(snarfreloc(nbytes), mode); ! 505: return(0); ! 506: } ! 507: ! 508: dispaddress(valuep, mode) ! 509: numberp valuep; ! 510: u_char mode; ! 511: { ! 512: int regnumber = OC_REGEXT(mode); ! 513: ! 514: switch(OC_AMEXT(mode)){ ! 515: case OC_BDISP: ! 516: case OC_DBDISP: ! 517: case OC_WDISP: ! 518: case OC_DWDISP: ! 519: case OC_LDISP: ! 520: case OC_DLDISP: ! 521: if (regnumber == R_PC){ ! 522: /* PC offset addressing */ ! 523: valuep->num_ulong[0] += kdbinkdot(incp); ! 524: } ! 525: } ! 526: if (regnumber == R_PC) ! 527: kdbpsymoff(valuep->num_ulong[0], type, &insoutfmt[0]); ! 528: else { /* } */ ! 529: kdbprintf(LPRMODE, valuep->num_ulong[0]); ! 530: kdbprintf(insoutfmt); ! 531: kdbprintf("(%s)", insregname(regnumber)); ! 532: } ! 533: savevar((long)valuep->num_ulong[0]); ! 534: } ! 535: ! 536: /* ! 537: * get a register name ! 538: */ ! 539: static char * ! 540: insregname(regnumber) ! 541: int regnumber; ! 542: { ! 543: char *r; ! 544: r = regname[regnumber]; ! 545: return(r); ! 546: } ! 547: ! 548: /* ! 549: * print out a short literal ! 550: */ ! 551: shortliteral(mode, optype) ! 552: u_char mode; ! 553: u_char optype; ! 554: { ! 555: savevar((long)mode); ! 556: switch(A_TYPEXT(optype)){ ! 557: case TYPF: ! 558: case TYPD: ! 559: case TYPG: ! 560: case TYPH: ! 561: kdbprintf("$%s", fltimm[mode]); ! 562: break; ! 563: default: ! 564: kdbprintf("$%r", mode); ! 565: break; ! 566: } ! 567: } ! 568: ! 569: pcimmediate(mode, optype) ! 570: u_char mode; ! 571: u_char optype; ! 572: { ! 573: int nbytes; ! 574: ! 575: kdbprintc('$'); ! 576: if (mode == OC_CONS(OC_DAIREG, R_PC)){ /* PC absolute, always 4 bytes*/ ! 577: dispaddress(snarfreloc(4), mode); ! 578: return; ! 579: } ! 580: nbytes = ty_nbyte[A_TYPEXT(optype)]; ! 581: if (! ty_NORELOC[A_TYPEXT(optype)]){ ! 582: dispaddress(snarfreloc(nbytes), mode); ! 583: return; ! 584: } ! 585: bignumprint(nbytes, optype); ! 586: } ! 587: ! 588: bignumprint(nbytes, optype) ! 589: int nbytes; ! 590: u_char optype; ! 591: { ! 592: numberp valuep; ! 593: int leading_zero = 1; ! 594: register int bindex; ! 595: register int nindex; ! 596: register int ch; ! 597: ! 598: valuep = snarf(nbytes); ! 599: switch(A_TYPEXT(optype)){ ! 600: case TYPF: ! 601: kdbprintf("0f%f", valuep->num_num.numFf_float.Ff_value); ! 602: break; ! 603: case TYPD: ! 604: kdbprintf("0d%f", valuep->num_num.numFd_float.Fd_value); ! 605: break; ! 606: case TYPG: ! 607: kdbprintf("0g::"); goto qprint; ! 608: case TYPH: ! 609: kdbprintf("0h::"); goto qprint; ! 610: case TYPQ: ! 611: case TYPO: ! 612: qprint: ! 613: for (bindex = nbytes - 1; bindex >= 0; --bindex){ ! 614: for (nindex = 4; nindex >= 0; nindex -= 4){ ! 615: ch = (valuep->num_uchar[bindex] >> nindex); ! 616: ch &= 0x0F; ! 617: if ( ! (leading_zero &= (ch == 0) ) ){ ! 618: if (ch <= 0x09) ! 619: kdbprintc(ch + '0'); ! 620: else ! 621: kdbprintc(ch - 0x0A + 'a'); ! 622: } ! 623: } ! 624: } ! 625: break; ! 626: } ! 627: } ! 628: ! 629: kdbstacktrace(dolocals) ! 630: int dolocals; ! 631: { ! 632: register ADDR ap, fp; ! 633: register int i, narg, tramp; ! 634: struct frame fr; ! 635: ! 636: if (kdbadrflg) { ! 637: /* ! 638: * Can only find args if called via `calls' (not callg). ! 639: * The horrible expression below reads the second ! 640: * longword of the given frame address; this contains ! 641: * fr_s and fr_spa, plus the register save mask. The ! 642: * memory layout is ! 643: * fp+0x00: call frame structure ! 644: * fp+0x14: saved registers ! 645: * fp+0xMM: stack alignment bytes ! 646: * fp+0xNN: arguments ! 647: */ ! 648: fp = kdbadrval; ! 649: ((int *)&fr)[1] = kdbget((off_t)fp + 4, DSP); ! 650: if (fr.fr_s) { ! 651: ap = fp + sizeof(fr) + fr.fr_spa; ! 652: for (i = fr.fr_mask; i != 0; i >>= 1) ! 653: if (i & 1) ! 654: ap += 4; ! 655: } else ! 656: ap = 0; ! 657: kdbcallpc = getprevpc(fp); ! 658: } else { ! 659: fp = kdbpcb.pcb_fp; ! 660: ap = kdbpcb.pcb_ap; ! 661: kdbcallpc = kdbpcb.pcb_pc; ! 662: } ! 663: ! 664: kdblastframe = NOFRAME; ! 665: while (kdbcntval-- && fp != NOFRAME) { ! 666: char *name; ! 667: ! 668: kdbchkerr(); ! 669: /* check for pc in pcb (signal trampoline code) */ ! 670: if (issignalpc(kdbcallpc)) { ! 671: tramp = 1; ! 672: name = "sigtramp"; ! 673: } else { ! 674: tramp = 0; ! 675: (void) kdbfindsym((long)kdbcallpc, ISYM); ! 676: if (kdbcursym) ! 677: name = kdbcursym->n_un.n_name; ! 678: else ! 679: name = "?"; ! 680: } ! 681: kdbprintf("%s(", name); ! 682: if (ap) { ! 683: /* byte at ap tells how many arguments */ ! 684: narg = kdbget((off_t)ap, DSP) & 0xff; ! 685: for (i = narg > 10 ? 10 : narg; i;) { ! 686: ap += 4; ! 687: kdbprintf("%R", kdbget((off_t)ap, DSP)); ! 688: if (--i != 0) ! 689: kdbprintc(','); ! 690: } ! 691: } else ! 692: kdbprintc('?'); ! 693: kdbprintf(") at "); ! 694: kdbpsymoff((long)kdbcallpc, ISYM, "\n"); ! 695: ! 696: if (dolocals) { ! 697: register ADDR word; ! 698: ! 699: while (kdblocalsym((long)fp)) { ! 700: word = kdbget((off_t)kdblocalval, DSP); ! 701: kdbprintf("%8t%s:%10t", ! 702: kdbcursym->n_un.n_name); ! 703: if (kdberrflg) { ! 704: kdbprintf("?\n"); ! 705: kdberrflg = 0; ! 706: } else ! 707: kdbprintf("%R\n", word); ! 708: } ! 709: } ! 710: if (!tramp) { ! 711: kdbcallpc = getprevpc(fp); ! 712: kdblastframe = fp; ! 713: /* 8 below == offsetof(struct frame, fr_savap) */ ! 714: ap = kdbget((off_t)fp + 8, DSP); ! 715: fp = getprevframe(fp); ! 716: } else { ! 717: kdbcallpc = getsignalpc(kdblastframe); ! 718: /* ??? WHAT ABOUT ap AND fp ??? */ ! 719: } ! 720: if (!kdbadrflg && !INSTACK(fp)) ! 721: break; ! 722: } ! 723: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.