|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1983 Regents of the University of California. ! 3: * All rights reserved. The Berkeley software License Agreement ! 4: * specifies the terms and conditions for redistribution. ! 5: */ ! 6: ! 7: #ifndef lint ! 8: static char sccsid[] = "@(#)iris.c 5.1 (Berkeley) 1/12/88"; ! 9: #endif not lint ! 10: ! 11: static char rcsid[] = "$Header: machine.c,v 1.2 87/03/26 14:54:55 donn Exp $"; ! 12: ! 13: /* ! 14: * Target machine dependent stuff. ! 15: */ ! 16: ! 17: #include "defs.h" ! 18: #include "machine.h" ! 19: #include "process.h" ! 20: #include "runtime.h" ! 21: #include "events.h" ! 22: #include "main.h" ! 23: #include "symbols.h" ! 24: #include "source.h" ! 25: #include "mappings.h" ! 26: #include "object.h" ! 27: #include "tree.h" ! 28: #include "eval.h" ! 29: #include "keywords.h" ! 30: #include "ops.h" ! 31: ! 32: #ifndef public ! 33: typedef unsigned int Address; ! 34: typedef unsigned char Byte; ! 35: typedef unsigned int Word; ! 36: ! 37: /* ! 38: * On the 68000, the pc isn't in a register, but we make believe ! 39: * so there's one more register. ! 40: * ! 41: * Note that there's also no argument pointer, this means code ! 42: * involving "ARGP" should always be #ifdef'd. ! 43: * ! 44: * The address corresponding to the beginning of a function is recorded ! 45: * as the address + FUNCOFFSET (skip the link instruction so that ! 46: * local information is available). ! 47: */ ! 48: ! 49: #define NREG 17 ! 50: ! 51: #define FRP 14 ! 52: #define STKP 15 ! 53: #define PROGCTR 16 ! 54: ! 55: #define CALL_RETADDR 0x800c /* Return address for 'call' command */ ! 56: #define FUNCOFFSET 4 ! 57: ! 58: #ifdef sun ! 59: # define CODESTART 0x8000 ! 60: #else /* IRIS */ ! 61: # define CODESTART 0x1000 ! 62: #endif ! 63: ! 64: #define optab_init() ! 65: ! 66: #define BITSPERBYTE 8 ! 67: #define BITSPERWORD (BITSPERBYTE * sizeof(Word)) ! 68: ! 69: /* ! 70: * This magic macro enables us to look at the process' registers ! 71: * in its user structure. ! 72: */ ! 73: ! 74: #define regloc(reg) (ctob(UPAGES) + (sizeof(Word) * ((reg) - PC)) - 10) ! 75: ! 76: #include "source.h" ! 77: #include "symbols.h" ! 78: #include <signal.h> ! 79: #include <sys/param.h> ! 80: #include <sys/dir.h> ! 81: #include <machine/psl.h> ! 82: #include <machine/pte.h> ! 83: #include <sys/user.h> ! 84: #undef DELETE /* XXX */ ! 85: #include <sys/vm.h> ! 86: #include <machine/reg.h> ! 87: ! 88: Address pc; ! 89: Address prtaddr; ! 90: ! 91: #endif ! 92: ! 93: /* ! 94: * Indices into u. for use in collecting registers values. ! 95: */ ! 96: public int rloc[] ={ ! 97: #ifdef sun ! 98: R0, R1, R2, R3, R4, R5, R6, R7, AR0, AR1, AR2, AR3, AR4, AR5, AR6, AR7, PC ! 99: #else /* IRIS */ ! 100: R0, R1, R2, R3, R4, R5, R6, R7, AR0, AR1, AR2, AR3, AR4, AR5, AR6, AR7, 16 ! 101: #endif ! 102: }; ! 103: ! 104: private Address printop(); ! 105: ! 106: /* ! 107: * Decode and print the instructions within the given address range. ! 108: */ ! 109: ! 110: public printinst(lowaddr, highaddr) ! 111: Address lowaddr; ! 112: Address highaddr; ! 113: { ! 114: register Address addr; ! 115: ! 116: for (addr = lowaddr; addr <= highaddr; ) { ! 117: addr = printop(addr); ! 118: } ! 119: prtaddr = addr; ! 120: } ! 121: ! 122: /* ! 123: * Another approach: print n instructions starting at the given address. ! 124: */ ! 125: ! 126: public printninst(count, addr) ! 127: int count; ! 128: Address addr; ! 129: { ! 130: register Integer i; ! 131: register Address newaddr; ! 132: ! 133: if (count <= 0) { ! 134: error("non-positive repetition count"); ! 135: } else { ! 136: newaddr = addr; ! 137: for (i = 0; i < count; i++) { ! 138: newaddr = printop(newaddr); ! 139: } ! 140: prtaddr = newaddr; ! 141: } ! 142: } ! 143: ! 144: /* ! 145: * Print the contents of the addresses within the given range ! 146: * according to the given format. ! 147: */ ! 148: ! 149: typedef struct { ! 150: String name; ! 151: String printfstring; ! 152: int length; ! 153: } Format; ! 154: ! 155: private Format fmt[] = { ! 156: { "d", " %d", sizeof(short) }, ! 157: { "D", " %ld", sizeof(long) }, ! 158: { "o", " %o", sizeof(short) }, ! 159: { "O", " %lo", sizeof(long) }, ! 160: { "x", " %04x", sizeof(short) }, ! 161: { "X", " %08x", sizeof(long) }, ! 162: { "b", " \\%o", sizeof(char) }, ! 163: { "c", " '%c'", sizeof(char) }, ! 164: { "s", "%c", sizeof(char) }, ! 165: { "f", " %f", sizeof(float) }, ! 166: { "g", " %g", sizeof(double) }, ! 167: { nil, nil, 0 } ! 168: }; ! 169: ! 170: private Format *findformat(s) ! 171: String s; ! 172: { ! 173: register Format *f; ! 174: ! 175: f = &fmt[0]; ! 176: while (f->name != nil and not streq(f->name, s)) { ! 177: ++f; ! 178: } ! 179: if (f->name == nil) { ! 180: error("bad print format \"%s\"", s); ! 181: } ! 182: return f; ! 183: } ! 184: ! 185: /* ! 186: * Retrieve and print out the appropriate data in the given format. ! 187: * Floats have to be handled specially to allow the compiler to ! 188: * convert them to doubles when passing to printf. ! 189: */ ! 190: ! 191: private printformat (f, addr) ! 192: Format *f; ! 193: Address addr; ! 194: { ! 195: union { ! 196: char charv; ! 197: short shortv; ! 198: int intv; ! 199: float floatv; ! 200: double doublev; ! 201: } value; ! 202: ! 203: value.intv = 0; ! 204: dread(&value, addr, f->length); ! 205: if (streq(f->name, "f")) { ! 206: printf(f->printfstring, value.floatv); ! 207: } else { ! 208: printf(f->printfstring, value); ! 209: } ! 210: } ! 211: ! 212: public Address printdata(lowaddr, highaddr, format) ! 213: Address lowaddr; ! 214: Address highaddr; ! 215: String format; ! 216: { ! 217: int n; ! 218: register Address addr; ! 219: Format *f; ! 220: ! 221: if (lowaddr > highaddr) { ! 222: error("first address larger than second"); ! 223: } ! 224: f = findformat(format); ! 225: n = 0; ! 226: for (addr = lowaddr; addr <= highaddr; addr += f->length) { ! 227: if (n == 0) { ! 228: printf("%08x: ", addr); ! 229: } ! 230: printformat(f, addr); ! 231: ++n; ! 232: if (n >= (16 div f->length)) { ! 233: printf("\n"); ! 234: n = 0; ! 235: } ! 236: } ! 237: if (n != 0) { ! 238: printf("\n"); ! 239: } ! 240: prtaddr = addr; ! 241: return addr; ! 242: } ! 243: ! 244: /* ! 245: * The other approach is to print n items starting with a given address. ! 246: */ ! 247: ! 248: public printndata(count, startaddr, format) ! 249: int count; ! 250: Address startaddr; ! 251: String format; ! 252: { ! 253: int i, n; ! 254: Address addr; ! 255: Format *f; ! 256: Boolean isstring; ! 257: char c; ! 258: ! 259: if (count <= 0) { ! 260: error("non-positive repetition count"); ! 261: } ! 262: f = findformat(format); ! 263: isstring = (Boolean) streq(f->name, "s"); ! 264: n = 0; ! 265: addr = startaddr; ! 266: for (i = 0; i < count; i++) { ! 267: if (n == 0) { ! 268: printf("%08x: ", addr); ! 269: } ! 270: if (isstring) { ! 271: printf("\""); ! 272: dread(&c, addr, sizeof(char)); ! 273: while (c != '\0') { ! 274: printchar(c); ! 275: ++addr; ! 276: dread(&c, addr, sizeof(char)); ! 277: } ! 278: printf("\"\n"); ! 279: n = 0; ! 280: addr += sizeof(String); ! 281: } else { ! 282: printformat(f, addr); ! 283: ++n; ! 284: if (n >= (16 div f->length)) { ! 285: printf("\n"); ! 286: n = 0; ! 287: } ! 288: addr += f->length; ! 289: } ! 290: } ! 291: if (n != 0) { ! 292: printf("\n"); ! 293: } ! 294: prtaddr = addr; ! 295: } ! 296: ! 297: /* ! 298: * Print out a value according to the given format. ! 299: */ ! 300: ! 301: public printvalue(v, format) ! 302: long v; ! 303: String format; ! 304: { ! 305: Format *f; ! 306: char *p, *q; ! 307: ! 308: f = findformat(format); ! 309: if (streq(f->name, "s")) { ! 310: putchar('"'); ! 311: p = (char *) &v; ! 312: q = p + sizeof(v); ! 313: while (p < q) { ! 314: printchar(*p); ! 315: ++p; ! 316: } ! 317: putchar('"'); ! 318: } else { ! 319: printf(f->printfstring, v); ! 320: } ! 321: putchar('\n'); ! 322: } ! 323: ! 324: /* ! 325: * Print out an execution time error. ! 326: * Assumes the source position of the error has been calculated. ! 327: * ! 328: * Have to check if the -r option was specified; if so then ! 329: * the object file information hasn't been read in yet. ! 330: */ ! 331: ! 332: public printerror() ! 333: { ! 334: extern Integer sys_nsig; ! 335: extern String sys_siglist[]; ! 336: integer err; ! 337: ! 338: if (isfinished(process)) { ! 339: err = exitcode(process); ! 340: if (err == 0) { ! 341: printf("\"%s\" terminated normally\n", objname); ! 342: } else { ! 343: printf("\"%s\" terminated abnormally (exit code %d)\n", ! 344: objname, err ! 345: ); ! 346: } ! 347: erecover(); ! 348: } ! 349: err = errnum(process); ! 350: putchar('\n'); ! 351: printsig(err); ! 352: putchar(' '); ! 353: printloc(); ! 354: putchar('\n'); ! 355: if (curline > 0) { ! 356: printlines(curline, curline); ! 357: } else { ! 358: printinst(pc, pc); ! 359: } ! 360: erecover(); ! 361: } ! 362: ! 363: /* ! 364: * Print out a signal. ! 365: */ ! 366: ! 367: private String illinames[] = { ! 368: "reserved addressing fault", ! 369: "privileged instruction fault", ! 370: "reserved operand fault" ! 371: }; ! 372: ! 373: private String fpenames[] = { ! 374: nil, ! 375: "integer overflow trap", ! 376: "integer divide by zero trap", ! 377: "floating overflow trap", ! 378: "floating/decimal divide by zero trap", ! 379: "floating underflow trap", ! 380: "decimal overflow trap", ! 381: "subscript out of range trap", ! 382: "floating overflow fault", ! 383: "floating divide by zero fault", ! 384: "floating underflow fault" ! 385: }; ! 386: ! 387: public printsig (signo) ! 388: integer signo; ! 389: { ! 390: integer code; ! 391: ! 392: if (signo < 0 or signo > sys_nsig) { ! 393: printf("[signal %d]", signo); ! 394: } else { ! 395: printf("%s", sys_siglist[signo]); ! 396: } ! 397: code = errcode(process); ! 398: if (signo == SIGILL) { ! 399: if (code >= 0 and code < sizeof(illinames) / sizeof(illinames[0])) { ! 400: printf(" (%s)", illinames[code]); ! 401: } ! 402: } else if (signo == SIGFPE) { ! 403: if (code > 0 and code < sizeof(fpenames) / sizeof(fpenames[0])) { ! 404: printf(" (%s)", fpenames[code]); ! 405: } ! 406: } ! 407: } ! 408: ! 409: /* ! 410: * Note the termination of the program. We do this so as to avoid ! 411: * having the process exit, which would make the values of variables ! 412: * inaccessible. We do want to flush all output buffers here, ! 413: * otherwise it'll never get done. ! 414: */ ! 415: ! 416: public endprogram() ! 417: { ! 418: Integer exitcode; ! 419: ! 420: stepto(nextaddr(pc, true)); ! 421: printnews(); ! 422: exitcode = argn(1, nil); ! 423: if (exitcode != 0) { ! 424: printf("\nexecution completed (exit code %d)\n", exitcode); ! 425: } else { ! 426: printf("\nexecution completed\n"); ! 427: } ! 428: getsrcpos(); ! 429: erecover(); ! 430: } ! 431: ! 432: /* ! 433: * Single step the machine a source line (or instruction if "inst_tracing" ! 434: * is true). If "isnext" is true, skip over procedure calls. ! 435: */ ! 436: ! 437: private Address getcall(); ! 438: ! 439: public dostep(isnext) ! 440: Boolean isnext; ! 441: { ! 442: register Address addr; ! 443: register Lineno line; ! 444: String filename; ! 445: Address startaddr; ! 446: ! 447: startaddr = pc; ! 448: addr = nextaddr(pc, isnext); ! 449: if (not inst_tracing and nlhdr.nlines != 0) { ! 450: line = linelookup(addr); ! 451: while (line == 0) { ! 452: addr = nextaddr(addr, isnext); ! 453: line = linelookup(addr); ! 454: } ! 455: curline = line; ! 456: } else { ! 457: curline = 0; ! 458: } ! 459: stepto(addr); ! 460: filename = srcfilename(addr); ! 461: setsource(filename); ! 462: } ! 463: ! 464: typedef short Bpinst; ! 465: ! 466: extern Bpinst BP_OP; ! 467: #ifdef sun ! 468: asm("_BP_OP: trap #15"); ! 469: #else /* IRIS */ ! 470: asm("_BP_OP: trap #1"); ! 471: #endif ! 472: ! 473: #define BP_ERRNO SIGTRAP /* signal received at a breakpoint */ ! 474: ! 475: /* ! 476: * Setting a breakpoint at a location consists of saving ! 477: * the word at the location and poking a BP_OP there. ! 478: * ! 479: * We save the locations and words on a list for use in unsetting. ! 480: */ ! 481: ! 482: typedef struct Savelist *Savelist; ! 483: ! 484: struct Savelist { ! 485: Address location; ! 486: Bpinst save; ! 487: short refcount; ! 488: Savelist link; ! 489: }; ! 490: ! 491: private Savelist savelist; ! 492: ! 493: /* ! 494: * Set a breakpoint at the given address. Only save the word there ! 495: * if it's not already a breakpoint. ! 496: */ ! 497: ! 498: public setbp(addr) ! 499: Address addr; ! 500: { ! 501: Bpinst w, save; ! 502: register Savelist newsave, s; ! 503: ! 504: for (s = savelist; s != nil; s = s->link) { ! 505: if (s->location == addr) { ! 506: s->refcount++; ! 507: return; ! 508: } ! 509: } ! 510: iread(&save, addr, sizeof(save)); ! 511: newsave = new(Savelist); ! 512: newsave->location = addr; ! 513: newsave->save = save; ! 514: newsave->refcount = 1; ! 515: newsave->link = savelist; ! 516: savelist = newsave; ! 517: w = BP_OP; ! 518: iwrite(&w, addr, sizeof(w)); ! 519: } ! 520: ! 521: /* ! 522: * Unset a breakpoint; unfortunately we have to search the SAVELIST ! 523: * to find the saved value. The assumption is that the SAVELIST will ! 524: * usually be quite small. ! 525: */ ! 526: ! 527: public unsetbp(addr) ! 528: Address addr; ! 529: { ! 530: register Savelist s, prev; ! 531: ! 532: prev = nil; ! 533: for (s = savelist; s != nil; s = s->link) { ! 534: if (s->location == addr) { ! 535: iwrite(&s->save, addr, sizeof(s->save)); ! 536: s->refcount--; ! 537: if (s->refcount == 0) { ! 538: if (prev == nil) { ! 539: savelist = s->link; ! 540: } else { ! 541: prev->link = s->link; ! 542: } ! 543: dispose(s); ! 544: } ! 545: return; ! 546: } ! 547: prev = s; ! 548: } ! 549: panic("unsetbp: couldn't find address %d", addr); ! 550: } ! 551: ! 552: /* ! 553: * Instruction decoding routines for 68000, derived from adb. ! 554: * ! 555: * The shared boolean variable "printing" is true if the decoded ! 556: * instruction is to be printed, false if not. In either case, ! 557: * the address of the next instruction after the given one is returned. ! 558: */ ! 559: ! 560: private Boolean printing; ! 561: private Boolean following; ! 562: private Boolean followcalls; ! 563: private Address instaddr; ! 564: ! 565: #define instread(var) \ ! 566: { \ ! 567: iread(&var, instaddr, sizeof(var)); \ ! 568: instaddr += sizeof(var); \ ! 569: } ! 570: ! 571: private Optab *decode(inst, addr) ! 572: Word inst; ! 573: Address addr; ! 574: { ! 575: register Optab *o; ! 576: ! 577: o = &optab[0]; ! 578: while (o->mask != 0 and (inst&o->mask) != o->match) { ! 579: ++o; ! 580: } ! 581: return o; ! 582: } ! 583: ! 584: private Address printop(addr) ! 585: Address addr; ! 586: { ! 587: Optab *o; ! 588: short inst; ! 589: ! 590: printf("%08x ", addr); ! 591: iread(&inst, addr, sizeof(inst)); ! 592: o = decode(inst, addr); ! 593: if (o->mask == 0) { ! 594: printf("\tbadop"); ! 595: instaddr = addr + sizeof(inst); ! 596: } else { ! 597: printing = true; ! 598: following = false; ! 599: instaddr = addr + sizeof(inst); ! 600: (*o->opfun)(inst, o->farg); ! 601: printing = false; ! 602: } ! 603: printf("\n"); ! 604: return instaddr; ! 605: } ! 606: ! 607: /* ! 608: * Quickly find the return address of the current procedure or function ! 609: * while single stepping. Just get the word pointed at by sp. ! 610: */ ! 611: ! 612: private Address currtnaddr () ! 613: { ! 614: Address retaddr; ! 615: ! 616: dread(&retaddr, reg(STKP), sizeof(retaddr)); ! 617: return retaddr; ! 618: } ! 619: ! 620: /* ! 621: * Print out the effective address for the given parameters. ! 622: */ ! 623: ! 624: private printea(mode, reg, size) ! 625: long mode, reg; ! 626: int size; ! 627: { ! 628: long index, disp; ! 629: static char *aregs[] = { "a0", "a1", "a2", "a3", "a4", "a5", "a6", "sp" }; ! 630: Byte b; ! 631: short w; ! 632: long l; ! 633: ! 634: switch ((int)(mode)) { ! 635: case 0: ! 636: if (printing) { ! 637: printf("d%D", reg); ! 638: } ! 639: break; ! 640: ! 641: case 1: ! 642: if (printing) { ! 643: printf("%s", aregs[reg]); ! 644: } ! 645: break; ! 646: ! 647: case 2: ! 648: if (printing) { ! 649: printf("%s@", aregs[reg]); ! 650: } ! 651: break; ! 652: ! 653: case 3: ! 654: if (printing) { ! 655: printf("%s@+", aregs[reg]); ! 656: } ! 657: break; ! 658: ! 659: case 4: ! 660: if (printing) { ! 661: printf("%s@-", aregs[reg]); ! 662: } ! 663: break; ! 664: ! 665: case 5: ! 666: instread(w); ! 667: if (printing) { ! 668: printf("%s@(%D)", aregs[reg], w); ! 669: } ! 670: break; ! 671: ! 672: case 6: ! 673: instread(w); ! 674: if (printing) { ! 675: index = w; ! 676: disp = (char)(index&0377); ! 677: printf("%s@(%d,%c%D:%c)", aregs[reg], disp, ! 678: (index&0100000)?'a':'d',(index>>12)&07, ! 679: (index&04000)?'l':'w'); ! 680: } ! 681: break; ! 682: ! 683: case 7: ! 684: switch ((int)(reg)) { ! 685: case 0: ! 686: instread(w); ! 687: if (printing) { ! 688: index = w; ! 689: psymoff(index); ! 690: } ! 691: break; ! 692: ! 693: case 1: ! 694: instread(l); ! 695: if (printing) { ! 696: index = l; ! 697: psymoff(index); ! 698: } ! 699: break; ! 700: ! 701: case 2: ! 702: instread(w); ! 703: if (printing) { ! 704: disp = w; ! 705: psymoff(disp + instaddr); ! 706: } ! 707: break; ! 708: ! 709: case 3: ! 710: instread(w); ! 711: if (printing) { ! 712: index = w; ! 713: disp = (char)(index&0377); ! 714: printf("pc@(%D,%c%D:%c)", disp, ! 715: (index&0100000)?'a':'d',(index>>12)&07, ! 716: (index&04000)?'l':'w'); ! 717: } ! 718: break; ! 719: ! 720: case 4: ! 721: switch (size) { ! 722: case sizeof(b): ! 723: instread(w); ! 724: index = (w&0xff); ! 725: break; ! 726: ! 727: case sizeof(w): ! 728: instread(w); ! 729: index = w; ! 730: break; ! 731: ! 732: case sizeof(l): ! 733: instread(l); ! 734: index = l; ! 735: break; ! 736: ! 737: default: ! 738: if (printing) { ! 739: printf("unexpected size %d in printea\n", size); ! 740: } ! 741: instread(l); ! 742: index = l; ! 743: break; ! 744: } ! 745: if (printing) { ! 746: printf(IMDF, index); ! 747: } ! 748: break; ! 749: ! 750: default: ! 751: if (printing) { ! 752: printf("???"); ! 753: } ! 754: break; ! 755: } ! 756: break; ! 757: ! 758: default: ! 759: if (printing) { ! 760: printf("???"); ! 761: } ! 762: break; ! 763: } ! 764: } ! 765: ! 766: private printEA(ea, size) ! 767: long ea; ! 768: int size; ! 769: { ! 770: printea((ea>>3)&07, ea&07, size); ! 771: } ! 772: ! 773: private mapsize(inst) ! 774: register long inst; ! 775: { ! 776: int m; ! 777: ! 778: inst >>= 6; ! 779: inst &= 03; ! 780: switch (inst) { ! 781: case 0: ! 782: m = 1; ! 783: break; ! 784: ! 785: case 1: ! 786: m = 2; ! 787: break; ! 788: ! 789: case 2: ! 790: m = 4; ! 791: break; ! 792: ! 793: default: ! 794: m = -1; ! 795: break; ! 796: } ! 797: return m; ! 798: } ! 799: ! 800: private char suffix(size) ! 801: int size; ! 802: { ! 803: char c; ! 804: ! 805: switch (size) { ! 806: case 1: ! 807: c = 'b'; ! 808: break; ! 809: ! 810: case 2: ! 811: c = 'w'; ! 812: break; ! 813: ! 814: case 4: ! 815: c = 'l'; ! 816: break; ! 817: ! 818: default: ! 819: panic("bad size %d in suffix", size); ! 820: } ! 821: return c; ! 822: } ! 823: ! 824: /* ! 825: * Print an address offset. Eventually this should attempt to be symbolic, ! 826: * but for now its just printed in hex. ! 827: */ ! 828: ! 829: private psymoff (off) ! 830: Word off; ! 831: { ! 832: Symbol f; ! 833: ! 834: f = whatblock((Address) (off + FUNCOFFSET)); ! 835: if (codeloc(f) == off + FUNCOFFSET) { ! 836: printf("%s", symname(f)); ! 837: } else { ! 838: printf("0x%x", off); ! 839: } ! 840: } ! 841: ! 842: /* ! 843: * Instruction class specific routines. ! 844: */ ! 845: ! 846: public omove(inst, s) ! 847: long inst; ! 848: String s; ! 849: { ! 850: register int c; ! 851: int size; ! 852: ! 853: c = s[0]; ! 854: if (printing) { ! 855: printf("\tmov%c\t", c); ! 856: } ! 857: size = ((c == 'b') ? 1 : (c == 'w') ? 2 : 4); ! 858: printea((inst>>3)&07, inst&07, size); ! 859: if (printing) { ! 860: printf(","); ! 861: } ! 862: printea((inst>>6)&07, (inst>>9)&07, size); ! 863: } ! 864: ! 865: /* ! 866: * Two types: bsr (4 bytes) and bsrs (2 bytes) ! 867: */ ! 868: ! 869: public obranch(inst, dummy) ! 870: long inst; ! 871: { ! 872: long disp; ! 873: String s; ! 874: short w; ! 875: Address startingaddr; /* address of branch instruction */ ! 876: int branchtype; /* type of branch (0 = unconditional) */ ! 877: Address dest; ! 878: Address retaddr; /* for bsr instruction */ ! 879: ! 880: startingaddr = instaddr - 2; ! 881: disp = inst&0377; ! 882: s = "s "; ! 883: if (disp == 0) { ! 884: retaddr = startingaddr + 4; ! 885: } else { ! 886: retaddr = startingaddr + 2; ! 887: } ! 888: if (disp > 127) { ! 889: disp |= ~0377; ! 890: } else if (disp == 0){ ! 891: s = " "; ! 892: instread(w); ! 893: disp = w; ! 894: } ! 895: branchtype = (int)((inst>>8)&017); ! 896: dest = startingaddr + 2 + disp; ! 897: if (printing) { ! 898: printf("\tb%s%s\t", bname[branchtype], s); ! 899: psymoff(dest); ! 900: } ! 901: if (following) { ! 902: /* ! 903: * If we're to follow the dynamic flow of instructions, ! 904: * we must see where the branch leads. A branchtype of 0 ! 905: * indicates an unconditional branch which we simply take ! 906: * as the new instruction address. For a conditional branch, ! 907: * we continue execution up to the current address, single step, ! 908: * and keep going. ! 909: */ ! 910: if (branchtype == 0) { ! 911: instaddr = dest; ! 912: } else if (branchtype == 01) { /* bsr */ ! 913: if (followcalls) { ! 914: steppast(startingaddr); ! 915: curfunc = whatblock(pc, true); ! 916: if (not isbperr()) { ! 917: printstatus(); ! 918: /* NOTREACHED */ ! 919: } ! 920: bpact(); ! 921: if (nosource(curfunc) and canskip(curfunc) and ! 922: nlhdr.nlines != 0) { ! 923: stepto(retaddr); ! 924: instaddr = pc; ! 925: bpact(); ! 926: } else { ! 927: callnews(/* iscall = */ true); ! 928: } ! 929: } ! 930: } else { ! 931: steppast(startingaddr); ! 932: } ! 933: } ! 934: } ! 935: ! 936: public odbcc(inst, form) ! 937: long inst; ! 938: String form; ! 939: { ! 940: long disp; ! 941: short w; ! 942: ! 943: instread(w); ! 944: if (printing) { ! 945: printf(form, dbname[(int)((inst>>8)&017)], inst&07); ! 946: psymoff(w + sizeof(w)); ! 947: } ! 948: } ! 949: ! 950: public oscc(inst, dummy) ! 951: long inst; ! 952: long dummy; ! 953: { ! 954: if (printing) { ! 955: printf("\ts%s\t", cname[(int)((inst>>8)&017)]); ! 956: } ! 957: printea((inst>>3)&07, inst&07, 1); ! 958: } ! 959: ! 960: public biti(inst, dummy) ! 961: long inst; ! 962: long dummy; ! 963: { ! 964: short w; ! 965: ! 966: if (printing) { ! 967: printf("\t%s\t", bit[(int)((inst>>6)&03)]); ! 968: } ! 969: if (inst&0x0100) { ! 970: if (printing) { ! 971: printf("d%D,", inst>>9); ! 972: } ! 973: } else { ! 974: instread(w); ! 975: if (printing) { ! 976: printf(IMDF, w); ! 977: printf(","); ! 978: } ! 979: } ! 980: printEA(inst); ! 981: } ! 982: ! 983: public opmode(inst, opcode) ! 984: long inst; ! 985: long opcode; ! 986: { ! 987: register int opmode; ! 988: register int reg; ! 989: int size; ! 990: ! 991: opmode = (int)((inst>>6) & 07); ! 992: reg = (int)((inst>>9) & 07); ! 993: if (opmode == 0 or opmode == 4) { ! 994: size = 1; ! 995: } else if (opmode == 1 or opmode == 3 or opmode == 5) { ! 996: size = 2; ! 997: } else { ! 998: size = 4; ! 999: } ! 1000: if (printing) { ! 1001: printf("\t%s%c\t", opcode, suffix(size)); ! 1002: } ! 1003: if (opmode >= 4 and opmode <= 6) { ! 1004: if (printing) { ! 1005: printf("d%d,", reg); ! 1006: } ! 1007: printea((inst>>3)&07, inst&07, size); ! 1008: } else { ! 1009: printea((inst>>3)&07, inst&07, size); ! 1010: if (printing) { ! 1011: printf(",%c%d",(opmode<=2) ? 'd' : 'a', reg); ! 1012: } ! 1013: } ! 1014: } ! 1015: ! 1016: public shroi(inst, ds) ! 1017: long inst; ! 1018: String ds; ! 1019: { ! 1020: int rx, ry; ! 1021: String opcode; ! 1022: ! 1023: if ((inst & 0xC0) == 0xC0) { ! 1024: opcode = shro[(int)((inst>>9)&03)]; ! 1025: if (printing) { ! 1026: printf("\t%s%s\t", opcode, ds); ! 1027: } ! 1028: printEA(inst); ! 1029: } else { ! 1030: if (printing) { ! 1031: opcode = shro[(int)((inst>>3)&03)]; ! 1032: printf("\t%s%s%c\t", opcode, ds, suffix(mapsize(inst))); ! 1033: rx = (int)((inst>>9)&07); ry = (int)(inst&07); ! 1034: if ((inst>>5)&01) { ! 1035: printf("d%d,d%d", rx, ry); ! 1036: } else { ! 1037: printf(IMDF, (rx ? rx : 8)); ! 1038: printf(",d%d", ry); ! 1039: } ! 1040: } ! 1041: } ! 1042: } ! 1043: ! 1044: public oimmed(inst, opcode) ! 1045: long inst; ! 1046: register String opcode; ! 1047: { ! 1048: register int size; ! 1049: long const; ! 1050: short w; ! 1051: ! 1052: size = mapsize(inst); ! 1053: if (size > 0) { ! 1054: if (size == 4) { ! 1055: instread(const); ! 1056: } else { ! 1057: instread(w); ! 1058: const = w; ! 1059: } ! 1060: if (printing) { ! 1061: printf("\t%s%c\t", opcode, suffix(size)); ! 1062: printf(IMDF, const); ! 1063: printf(","); ! 1064: } ! 1065: printEA(inst, size); ! 1066: } else { ! 1067: if (printing) { ! 1068: printf("\tbadop"); ! 1069: } ! 1070: } ! 1071: } ! 1072: ! 1073: public oreg(inst, opcode) ! 1074: long inst; ! 1075: register String opcode; ! 1076: { ! 1077: if (printing) { ! 1078: printf(opcode, (inst & 07)); ! 1079: } ! 1080: } ! 1081: ! 1082: public extend(inst, opcode) ! 1083: long inst; ! 1084: String opcode; ! 1085: { ! 1086: register int size; ! 1087: int ry, rx; ! 1088: char c; ! 1089: ! 1090: if (printing) { ! 1091: size = mapsize(inst); ! 1092: ry = (inst&07); ! 1093: rx = ((inst>>9)&07); ! 1094: c = ((inst & 0x1000) ? suffix(size) : ' '); ! 1095: printf("\t%s%c\t", opcode, c); ! 1096: if (opcode[0] == 'e') { ! 1097: if (inst & 0x0080) { ! 1098: printf("d%D,a%D", rx, ry); ! 1099: } else if (inst & 0x0008) { ! 1100: printf("a%D,a%D", rx, ry); ! 1101: } else { ! 1102: printf("d%D,d%D", rx, ry); ! 1103: } ! 1104: } else if ((inst & 0xF000) == 0xB000) { ! 1105: printf("a%D@+,a%D@+", ry, rx); ! 1106: } else if (inst & 0x8) { ! 1107: printf("a%D@-,a%D@-", ry, rx); ! 1108: } else { ! 1109: printf("d%D,d%D", ry, rx); ! 1110: } ! 1111: } ! 1112: } ! 1113: ! 1114: public olink(inst, dummy) ! 1115: long inst; ! 1116: long dummy; ! 1117: { ! 1118: short w; ! 1119: ! 1120: instread(w); ! 1121: if (printing) { ! 1122: printf("\tlink\ta%D,", inst&07); ! 1123: printf(IMDF, w); ! 1124: } ! 1125: } ! 1126: ! 1127: public otrap(inst, dummy) ! 1128: long inst; ! 1129: { ! 1130: if (printing) { ! 1131: printf("\ttrap\t"); ! 1132: printf(IMDF, inst&017); ! 1133: } ! 1134: } ! 1135: ! 1136: public oneop(inst, opcode) ! 1137: long inst; ! 1138: register String opcode; ! 1139: { ! 1140: if (printing) { ! 1141: printf("\t%s",opcode); ! 1142: } ! 1143: printEA(inst); ! 1144: } ! 1145: ! 1146: public jsrop(inst, opcode) ! 1147: long inst; ! 1148: register String opcode; ! 1149: { ! 1150: Address startingaddr; /* beginning of jsr instruction */ ! 1151: Address retaddr; /* can't call return_addr (frame not set up yet) */ ! 1152: ! 1153: startingaddr = instaddr - 2; ! 1154: switch ((inst >> 3) & 07) { ! 1155: case 2: ! 1156: retaddr = instaddr; /* two byte instruction */ ! 1157: break; ! 1158: case 5: ! 1159: case 6: ! 1160: retaddr = instaddr + 2; /* four byte instruction */ ! 1161: break; ! 1162: case 7: ! 1163: default: ! 1164: switch (inst & 07) { ! 1165: case 0: ! 1166: case 2: ! 1167: case 3: ! 1168: retaddr = instaddr + 2; ! 1169: break; ! 1170: case 1: ! 1171: default: ! 1172: retaddr = instaddr + 4; /* six byte instruction */ ! 1173: break; ! 1174: } ! 1175: break; ! 1176: } ! 1177: if (printing) { ! 1178: printf("\t%s",opcode); ! 1179: } ! 1180: printEA(inst); ! 1181: if (following and followcalls) { ! 1182: steppast(startingaddr); ! 1183: curfunc = whatblock(pc, true); ! 1184: if (not isbperr()) { ! 1185: printstatus(); ! 1186: /* NOTREACHED */ ! 1187: } ! 1188: bpact(); ! 1189: if (nosource(curfunc) and canskip(curfunc) and nlhdr.nlines != 0) { ! 1190: stepto(retaddr); ! 1191: instaddr = pc; ! 1192: bpact(); ! 1193: } else { ! 1194: callnews(/* iscall = */ true); ! 1195: } ! 1196: } ! 1197: } ! 1198: ! 1199: public jmpop(inst, opcode) ! 1200: long inst; ! 1201: register String opcode; ! 1202: { ! 1203: Address startingaddr; /* beginning of jump instruction */ ! 1204: ! 1205: startingaddr = instaddr - 2; ! 1206: if (printing) { ! 1207: printf("\t%s",opcode); ! 1208: } ! 1209: printEA(inst); ! 1210: if (following) { ! 1211: steppast(startingaddr); ! 1212: } ! 1213: } ! 1214: ! 1215: public pregmask(mask) ! 1216: register int mask; ! 1217: { ! 1218: register int i; ! 1219: register int flag = 0; ! 1220: ! 1221: if (printing) { ! 1222: printf("#<"); ! 1223: for (i=0; i<16; i++) { ! 1224: if (mask&1) { ! 1225: if (flag) { ! 1226: printf(","); ! 1227: } else { ! 1228: ++flag; ! 1229: } ! 1230: printf("%c%d",(i<8) ? 'd' : 'a', i&07); ! 1231: } ! 1232: mask >>= 1; ! 1233: } ! 1234: printf(">"); ! 1235: } ! 1236: } ! 1237: ! 1238: public omovem(inst, dummy) ! 1239: long inst; ! 1240: long dummy; ! 1241: { ! 1242: register int i, list, mask; ! 1243: register int reglist; ! 1244: short w; ! 1245: ! 1246: i = 0; ! 1247: list = 0; ! 1248: mask = 0100000; ! 1249: instread(w); ! 1250: reglist = w; ! 1251: if ((inst & 070) == 040) { /* predecrement */ ! 1252: for (i = 15; i > 0; i -= 2) { ! 1253: list |= ((mask & reglist) >> i); ! 1254: mask >>= 1; ! 1255: } ! 1256: for (i = 1; i < 16; i += 2) { ! 1257: list |= ((mask & reglist) << i); ! 1258: mask >>= 1; ! 1259: } ! 1260: reglist = list; ! 1261: } ! 1262: if (printing) { ! 1263: printf("\tmovem%c\t",(inst&100)?'l':'w'); ! 1264: } ! 1265: if (inst&02000) { ! 1266: printEA(inst); ! 1267: if (printing) { ! 1268: printf(","); ! 1269: } ! 1270: pregmask(reglist); ! 1271: } else { ! 1272: pregmask(reglist); ! 1273: if (printing) { ! 1274: printf(","); ! 1275: } ! 1276: printEA(inst); ! 1277: } ! 1278: } ! 1279: ! 1280: public ochk(inst, opcode) ! 1281: long inst; ! 1282: register String opcode; ! 1283: { ! 1284: if (printing) { ! 1285: printf("\t%s\t", opcode); ! 1286: } ! 1287: printEA(inst, sizeof(Byte)); ! 1288: if (printing) { ! 1289: printf(",%c%D", (opcode[0] == 'l') ? 'a' : 'd', (inst>>9)&07); ! 1290: } ! 1291: } ! 1292: ! 1293: public soneop(inst, opcode) ! 1294: long inst; ! 1295: register String opcode; ! 1296: { ! 1297: register int size; ! 1298: ! 1299: size = mapsize(inst); ! 1300: if (size > 0) { ! 1301: if (printing) { ! 1302: printf("\t%s%c\t", opcode, suffix(size)); ! 1303: } ! 1304: printEA(inst); ! 1305: } else { ! 1306: if (printing) { ! 1307: printf("\tbadop"); ! 1308: } ! 1309: } ! 1310: } ! 1311: ! 1312: public oquick(inst, opcode) ! 1313: long inst; ! 1314: register String opcode; ! 1315: { ! 1316: register int size; ! 1317: register int data; ! 1318: ! 1319: size = mapsize(inst); ! 1320: data = (int)((inst>>9) & 07); ! 1321: if (data == 0) { ! 1322: data = 8; ! 1323: } ! 1324: if (size > 0) { ! 1325: if (printing) { ! 1326: printf("\t%s%c\t", opcode, suffix(size)); ! 1327: printf(IMDF, data); ! 1328: printf(","); ! 1329: } ! 1330: printEA(inst); ! 1331: } else { ! 1332: if (printing) { ! 1333: printf("\tbadop"); ! 1334: } ! 1335: } ! 1336: } ! 1337: ! 1338: public omoveq(inst, dummy) ! 1339: long inst; ! 1340: long dummy; ! 1341: { ! 1342: register int data; ! 1343: ! 1344: if (printing) { ! 1345: data = (int)(inst & 0377); ! 1346: if (data > 127) { ! 1347: data |= ~0377; ! 1348: } ! 1349: printf("\tmoveq\t"); ! 1350: printf(IMDF, data); ! 1351: printf(",d%D", (inst>>9)&07); ! 1352: } ! 1353: } ! 1354: ! 1355: public oprint(inst, opcode) ! 1356: long inst; ! 1357: register String opcode; ! 1358: { ! 1359: if (printing) { ! 1360: printf("\t%s",opcode); ! 1361: } ! 1362: } ! 1363: ! 1364: public ostop(inst, opcode) ! 1365: long inst; ! 1366: register String opcode; ! 1367: { ! 1368: short w; ! 1369: ! 1370: instread(w); ! 1371: if (printing) { ! 1372: printf(opcode, w); ! 1373: } ! 1374: } ! 1375: ! 1376: public orts(inst, opcode) ! 1377: long inst; ! 1378: register String opcode; ! 1379: { ! 1380: Address addr; ! 1381: ! 1382: if (following) { ! 1383: callnews(/* iscall = */ false); ! 1384: if (inst_tracing) { ! 1385: addr = currtnaddr(); ! 1386: } else { ! 1387: addr = return_addr(); ! 1388: if (addr == 0) { ! 1389: stepto(instaddr - 2); ! 1390: addr = currtnaddr(); ! 1391: } ! 1392: } ! 1393: stepto(addr); ! 1394: instaddr = pc; ! 1395: } ! 1396: if (printing) { ! 1397: printf("\t%s",opcode); ! 1398: } ! 1399: } ! 1400: ! 1401: /* ! 1402: * Not used by C compiler; does an rts but before doing so, pops ! 1403: * arg bytes from the stack. ! 1404: */ ! 1405: ! 1406: public ortspop(inst, opcode) ! 1407: long inst; ! 1408: register String opcode; ! 1409: { ! 1410: Address addr; ! 1411: short w; ! 1412: ! 1413: instread(w); ! 1414: if (following) { ! 1415: callnews(/* iscall = */ false); ! 1416: if (inst_tracing) { ! 1417: addr = currtnaddr(); ! 1418: } else { ! 1419: addr = return_addr(); ! 1420: } ! 1421: stepto(addr); ! 1422: instaddr = pc; ! 1423: } ! 1424: if (printing) { ! 1425: printf(opcode, w); ! 1426: } ! 1427: } ! 1428: ! 1429: public omovs(inst, opcode) ! 1430: long inst; ! 1431: String opcode; ! 1432: { ! 1433: register int size; ! 1434: register unsigned int controlword; ! 1435: short w; ! 1436: ! 1437: size = mapsize(inst); ! 1438: instread(w); ! 1439: controlword = w >> 11; ! 1440: if (printing) { ! 1441: printf("\t%s%c\t", opcode, suffix(size)); ! 1442: } ! 1443: if (controlword & 1){ ! 1444: controlword >>= 1; ! 1445: if (printing) { ! 1446: printf((controlword&0x8) ? "a%D," : "d%D,", controlword&7 ); ! 1447: } ! 1448: printEA(inst&0xff, size); ! 1449: } else { ! 1450: controlword >>= 1; ! 1451: printEA(inst&0xff, size); ! 1452: if (printing) { ! 1453: printf((controlword&0x8) ? ",a%D" : ",d%D", controlword&7); ! 1454: } ! 1455: } ! 1456: } ! 1457: ! 1458: public omovc(inst, opcode) ! 1459: long inst; ! 1460: String opcode; ! 1461: { ! 1462: register unsigned int controlword; ! 1463: String creg; ! 1464: short w; ! 1465: ! 1466: instread(w); ! 1467: if (printing) { ! 1468: controlword = w; ! 1469: switch (controlword & 0xfff) { ! 1470: case 0: ! 1471: creg = "sfc"; ! 1472: break; ! 1473: ! 1474: case 1: ! 1475: creg = "dfc"; ! 1476: break; ! 1477: ! 1478: case 0x800: ! 1479: creg = "usp"; ! 1480: break; ! 1481: ! 1482: case 0x801: ! 1483: creg = "vbr"; ! 1484: break; ! 1485: ! 1486: default: ! 1487: creg = "???"; ! 1488: break; ! 1489: } ! 1490: controlword >>= 12; ! 1491: if (inst & 1){ ! 1492: printf((controlword&0x8) ? "%sa%D,%s" : "%sd%D,%s", ! 1493: opcode, controlword&7, creg ); ! 1494: } else { ! 1495: printf((controlword&0x8) ? "%s%s,a%D" : "%s%s,d%D", ! 1496: opcode, creg, controlword&7 ); ! 1497: } ! 1498: } ! 1499: } ! 1500: ! 1501: /* ! 1502: * Compute the next address that will be executed from the given one. ! 1503: * If "isnext" is true then consider a procedure call as straight line code. ! 1504: * ! 1505: * Unconditional branches we just follow, for conditional branches ! 1506: * we continue execution to the current location and then single step ! 1507: * the machine. ! 1508: */ ! 1509: ! 1510: public Address nextaddr(startaddr, isnext) ! 1511: Address startaddr; ! 1512: Boolean isnext; ! 1513: { ! 1514: Optab *o; ! 1515: short inst; ! 1516: ! 1517: instaddr = usignal(process); ! 1518: if (instaddr == 0 or instaddr == 1) { ! 1519: following = true; ! 1520: followcalls = (Boolean) (not isnext); ! 1521: printing = false; ! 1522: iread(&inst, startaddr, sizeof(inst)); ! 1523: instaddr = startaddr + sizeof(inst); ! 1524: o = decode(inst, startaddr); ! 1525: if (o->mask == 0) { ! 1526: fprintf(stderr, ! 1527: "[internal error: undecodable op at 0x%x]\n", startaddr); ! 1528: fflush(stderr); ! 1529: } else { ! 1530: (*o->opfun)(inst, o->farg); ! 1531: } ! 1532: following = false; ! 1533: } ! 1534: return instaddr; ! 1535: } ! 1536: ! 1537: /* ! 1538: * Step to the given address and then execute one instruction past it. ! 1539: * Set instaddr to the new instruction address. ! 1540: */ ! 1541: ! 1542: private steppast(addr) ! 1543: Address addr; ! 1544: { ! 1545: stepto(addr); ! 1546: pstep(process, DEFSIG); ! 1547: pc = reg(PROGCTR); ! 1548: instaddr = pc; ! 1549: } ! 1550: ! 1551: /* ! 1552: * Enter a procedure by creating and executing a call instruction. ! 1553: */ ! 1554: ! 1555: #define CALLSIZE 6 /* size of call instruction */ ! 1556: ! 1557: public beginproc(p) ! 1558: Symbol p; ! 1559: { ! 1560: char save[CALLSIZE]; ! 1561: struct { ! 1562: short op; ! 1563: char addr[sizeof(long)]; /* unaligned long */ ! 1564: } call; ! 1565: long dest; ! 1566: ! 1567: pc = CODESTART + 6; ! 1568: iread(save, pc, sizeof(save)); ! 1569: call.op = 0x4eb9; /* jsr */ ! 1570: dest = codeloc(p) - FUNCOFFSET; ! 1571: mov(&dest, call.addr, sizeof(call.addr)); ! 1572: iwrite(&call, pc, sizeof(call)); ! 1573: setreg(PROGCTR, pc); ! 1574: pstep(process, DEFSIG); ! 1575: iwrite(save, pc, sizeof(save)); ! 1576: pc = reg(PROGCTR); ! 1577: if (not isbperr()) { ! 1578: printstatus(); ! 1579: } ! 1580: /* ! 1581: * Execute link instruction so the return addr is visible. ! 1582: */ ! 1583: pstep(process, DEFSIG); ! 1584: pc = reg(PROGCTR); ! 1585: if (not isbperr()) { ! 1586: printstatus(); ! 1587: } ! 1588: } ! 1589: ! 1590: /* ! 1591: * Special variables for debugging the kernel. ! 1592: */ ! 1593: ! 1594: public integer masterpcbb; ! 1595: public integer slr; ! 1596: public struct pte *sbr; ! 1597: private struct pcb pcb; ! 1598: ! 1599: public getpcb () ! 1600: { ! 1601: integer i; ! 1602: ! 1603: fseek(corefile, masterpcbb & ~0x80000000, 0); ! 1604: get(corefile, pcb); ! 1605: pcb.pcb_p0lr &= ~AST_CLR; ! 1606: printf("p0br %lx p0lr %lx p1br %lx p1lr %lx\n", ! 1607: pcb.pcb_p0br, pcb.pcb_p0lr, pcb.pcb_p1br, pcb.pcb_p1lr ! 1608: ); ! 1609: # ifdef sun ! 1610: for (i = 0; i < 14; i++) { ! 1611: setreg(i, pcb.pcb_regs.val[i]); ! 1612: } ! 1613: # else /* IRIS */ ! 1614: for (i = 0; i < 14; i++) { ! 1615: setreg(i, pcb.pcb_regs[i]); ! 1616: } ! 1617: # endif ! 1618: } ! 1619: ! 1620: public copyregs (savreg, reg) ! 1621: Word savreg[], reg[]; ! 1622: { ! 1623: reg[0] = savreg[R0]; ! 1624: reg[1] = savreg[R1]; ! 1625: reg[2] = savreg[R2]; ! 1626: reg[3] = savreg[R3]; ! 1627: reg[4] = savreg[R4]; ! 1628: reg[5] = savreg[R5]; ! 1629: reg[6] = savreg[R6]; ! 1630: reg[7] = savreg[R7]; ! 1631: reg[8] = savreg[AR0]; ! 1632: reg[9] = savreg[AR1]; ! 1633: reg[10] = savreg[AR2]; ! 1634: reg[11] = savreg[AR3]; ! 1635: reg[12] = savreg[AR4]; ! 1636: reg[13] = savreg[AR5]; ! 1637: reg[14] = savreg[AR6]; ! 1638: reg[15] = savreg[AR7]; ! 1639: reg[PROGCTR] = savreg[PC]; ! 1640: } ! 1641: ! 1642: /* ! 1643: * Map a virtual address to a physical address. ! 1644: * XXX THIS CAN'T BE RIGHT... XXX ! 1645: */ ! 1646: ! 1647: public Address vmap (addr) ! 1648: Address addr; ! 1649: { ! 1650: Address r; ! 1651: integer v, n; ! 1652: struct pte pte; ! 1653: ! 1654: r = addr & ~0xc0000000; ! 1655: v = btop(r); ! 1656: switch (addr&0xc0000000) { ! 1657: case 0xc0000000: ! 1658: case 0x80000000: ! 1659: /* ! 1660: * In system space, so get system pte. ! 1661: * If it is valid or reclaimable then the physical address ! 1662: * is the combination of its page number and the page offset ! 1663: * of the original address. ! 1664: */ ! 1665: if (v >= slr) { ! 1666: error("address %x out of segment", addr); ! 1667: } ! 1668: r = ((long) (sbr + v)) & ~0x80000000; ! 1669: goto simple; ! 1670: ! 1671: case 0x40000000: ! 1672: /* ! 1673: * In p1 space, must not be in shadow region. ! 1674: */ ! 1675: if (v < pcb.pcb_p1lr) { ! 1676: error("address %x out of segment", addr); ! 1677: } ! 1678: r = (Address) (pcb.pcb_p1br + v); ! 1679: break; ! 1680: ! 1681: case 0x00000000: ! 1682: /* ! 1683: * In p0 space, must not be off end of region. ! 1684: */ ! 1685: if (v >= pcb.pcb_p0lr) { ! 1686: error("address %x out of segment", addr); ! 1687: } ! 1688: r = (Address) (pcb.pcb_p0br + v); ! 1689: break; ! 1690: ! 1691: default: ! 1692: /* do nothing */ ! 1693: break; ! 1694: } ! 1695: /* ! 1696: * For p0/p1 address, user-level page table should be in ! 1697: * kernel virtual memory. Do second-level indirect by recursing. ! 1698: */ ! 1699: if ((r & 0x80000000) == 0) { ! 1700: error("bad p0br or p1br in pcb"); ! 1701: } ! 1702: r = vmap(r); ! 1703: simple: ! 1704: /* ! 1705: * "r" is now the address of the pte of the page ! 1706: * we are interested in; get the pte and paste up the physical address. ! 1707: */ ! 1708: fseek(corefile, r, 0); ! 1709: n = fread(&pte, sizeof(pte), 1, corefile); ! 1710: if (n != 1) { ! 1711: error("page table botch (fread at %x returns %d)", r, n); ! 1712: } ! 1713: if (pte.pg_v == 0 and (pte.pg_fod != 0 or pte.pg_pfnum == 0)) { ! 1714: error("page no valid or reclamable"); ! 1715: } ! 1716: return (addr&PGOFSET) + ((Address) ptob(pte.pg_pfnum)); ! 1717: } ! 1718: ! 1719: /* ! 1720: * Extract a bit field from an integer. ! 1721: */ ! 1722: ! 1723: public integer extractField (s) ! 1724: Symbol s; ! 1725: { ! 1726: integer nbytes, nbits, n, r, off, len; ! 1727: ! 1728: off = s->symvalue.field.offset; ! 1729: len = s->symvalue.field.length; ! 1730: nbytes = size(s); ! 1731: n = 0; ! 1732: if (nbytes > sizeof(n)) { ! 1733: printf("[bad size in extractField -- word assumed]\n"); ! 1734: nbytes = sizeof(n); ! 1735: } ! 1736: popn(nbytes, ((char *) &n) + (sizeof(Word) - nbytes)); ! 1737: nbits = nbytes * BITSPERBYTE; ! 1738: r = n >> (nbits - ((off mod nbits) + len)); ! 1739: r &= ((1 << len) - 1); ! 1740: return r; ! 1741: } ! 1742: ! 1743: /* ! 1744: * Change the length of a value in memory according to a given difference ! 1745: * in the lengths of its new and old types. ! 1746: */ ! 1747: ! 1748: public loophole (oldlen, newlen) ! 1749: integer oldlen, newlen; ! 1750: { ! 1751: integer i, n; ! 1752: Stack *oldsp; ! 1753: ! 1754: n = newlen - oldlen; ! 1755: oldsp = sp - oldlen; ! 1756: if (n > 0) { ! 1757: for (i = oldlen - 1; i >= 0; i--) { ! 1758: oldsp[n + i] = oldsp[i]; ! 1759: } ! 1760: for (i = 0; i < n; i++) { ! 1761: oldsp[i] = '\0'; ! 1762: } ! 1763: } else { ! 1764: for (i = 0; i < newlen; i++) { ! 1765: oldsp[i] = oldsp[i - n]; ! 1766: } ! 1767: } ! 1768: sp += n; ! 1769: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.