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 } 724