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