12f00b088Sdonn /*
2be26f981Sbostic * Copyright (c) 1983 The Regents of the University of California.
3be26f981Sbostic * All rights reserved.
4be26f981Sbostic *
5*1808f06cSbostic * %sccs.include.redist.c%
62f00b088Sdonn */
72f00b088Sdonn
82f00b088Sdonn #ifndef lint
9*1808f06cSbostic static char sccsid[] = "@(#)iris.c 5.3 (Berkeley) 06/01/90";
10be26f981Sbostic #endif /* not lint */
112f00b088Sdonn
122f00b088Sdonn /*
132f00b088Sdonn * Target machine dependent stuff.
142f00b088Sdonn */
152f00b088Sdonn
162f00b088Sdonn #include "defs.h"
172f00b088Sdonn #include "machine.h"
182f00b088Sdonn #include "process.h"
192f00b088Sdonn #include "runtime.h"
202f00b088Sdonn #include "events.h"
212f00b088Sdonn #include "main.h"
222f00b088Sdonn #include "symbols.h"
232f00b088Sdonn #include "source.h"
242f00b088Sdonn #include "mappings.h"
252f00b088Sdonn #include "object.h"
262f00b088Sdonn #include "tree.h"
272f00b088Sdonn #include "eval.h"
282f00b088Sdonn #include "keywords.h"
292f00b088Sdonn #include "ops.h"
302f00b088Sdonn
312f00b088Sdonn #ifndef public
322f00b088Sdonn typedef unsigned int Address;
332f00b088Sdonn typedef unsigned char Byte;
342f00b088Sdonn typedef unsigned int Word;
352f00b088Sdonn
362f00b088Sdonn /*
372f00b088Sdonn * On the 68000, the pc isn't in a register, but we make believe
382f00b088Sdonn * so there's one more register.
392f00b088Sdonn *
402f00b088Sdonn * Note that there's also no argument pointer, this means code
412f00b088Sdonn * involving "ARGP" should always be #ifdef'd.
422f00b088Sdonn *
432f00b088Sdonn * The address corresponding to the beginning of a function is recorded
442f00b088Sdonn * as the address + FUNCOFFSET (skip the link instruction so that
452f00b088Sdonn * local information is available).
462f00b088Sdonn */
472f00b088Sdonn
482f00b088Sdonn #define NREG 17
492f00b088Sdonn
502f00b088Sdonn #define FRP 14
512f00b088Sdonn #define STKP 15
522f00b088Sdonn #define PROGCTR 16
532f00b088Sdonn
542f00b088Sdonn #define CALL_RETADDR 0x800c /* Return address for 'call' command */
552f00b088Sdonn #define FUNCOFFSET 4
562f00b088Sdonn
572f00b088Sdonn #ifdef sun
582f00b088Sdonn # define CODESTART 0x8000
592f00b088Sdonn #else /* IRIS */
602f00b088Sdonn # define CODESTART 0x1000
612f00b088Sdonn #endif
622f00b088Sdonn
632f00b088Sdonn #define optab_init()
642f00b088Sdonn
652f00b088Sdonn #define BITSPERBYTE 8
662f00b088Sdonn #define BITSPERWORD (BITSPERBYTE * sizeof(Word))
672f00b088Sdonn
682f00b088Sdonn /*
692f00b088Sdonn * This magic macro enables us to look at the process' registers
702f00b088Sdonn * in its user structure.
712f00b088Sdonn */
722f00b088Sdonn
732f00b088Sdonn #define regloc(reg) (ctob(UPAGES) + (sizeof(Word) * ((reg) - PC)) - 10)
742f00b088Sdonn
752f00b088Sdonn #include "source.h"
762f00b088Sdonn #include "symbols.h"
772f00b088Sdonn #include <signal.h>
782f00b088Sdonn #include <sys/param.h>
792f00b088Sdonn #include <sys/dir.h>
802f00b088Sdonn #include <machine/psl.h>
812f00b088Sdonn #include <machine/pte.h>
822f00b088Sdonn #include <sys/user.h>
832f00b088Sdonn #undef DELETE /* XXX */
842f00b088Sdonn #include <sys/vm.h>
852f00b088Sdonn #include <machine/reg.h>
862f00b088Sdonn
872f00b088Sdonn Address pc;
882f00b088Sdonn Address prtaddr;
892f00b088Sdonn
902f00b088Sdonn #endif
912f00b088Sdonn
922f00b088Sdonn /*
932f00b088Sdonn * Indices into u. for use in collecting registers values.
942f00b088Sdonn */
952f00b088Sdonn public int rloc[] ={
962f00b088Sdonn #ifdef sun
972f00b088Sdonn R0, R1, R2, R3, R4, R5, R6, R7, AR0, AR1, AR2, AR3, AR4, AR5, AR6, AR7, PC
982f00b088Sdonn #else /* IRIS */
992f00b088Sdonn R0, R1, R2, R3, R4, R5, R6, R7, AR0, AR1, AR2, AR3, AR4, AR5, AR6, AR7, 16
1002f00b088Sdonn #endif
1012f00b088Sdonn };
1022f00b088Sdonn
1032f00b088Sdonn private Address printop();
1042f00b088Sdonn
1052f00b088Sdonn /*
1062f00b088Sdonn * Decode and print the instructions within the given address range.
1072f00b088Sdonn */
1082f00b088Sdonn
printinst(lowaddr,highaddr)1092f00b088Sdonn public printinst(lowaddr, highaddr)
1102f00b088Sdonn Address lowaddr;
1112f00b088Sdonn Address highaddr;
1122f00b088Sdonn {
1132f00b088Sdonn register Address addr;
1142f00b088Sdonn
1152f00b088Sdonn for (addr = lowaddr; addr <= highaddr; ) {
1162f00b088Sdonn addr = printop(addr);
1172f00b088Sdonn }
1182f00b088Sdonn prtaddr = addr;
1192f00b088Sdonn }
1202f00b088Sdonn
1212f00b088Sdonn /*
1222f00b088Sdonn * Another approach: print n instructions starting at the given address.
1232f00b088Sdonn */
1242f00b088Sdonn
printninst(count,addr)1252f00b088Sdonn public printninst(count, addr)
1262f00b088Sdonn int count;
1272f00b088Sdonn Address addr;
1282f00b088Sdonn {
1292f00b088Sdonn register Integer i;
1302f00b088Sdonn register Address newaddr;
1312f00b088Sdonn
1322f00b088Sdonn if (count <= 0) {
1332f00b088Sdonn error("non-positive repetition count");
1342f00b088Sdonn } else {
1352f00b088Sdonn newaddr = addr;
1362f00b088Sdonn for (i = 0; i < count; i++) {
1372f00b088Sdonn newaddr = printop(newaddr);
1382f00b088Sdonn }
1392f00b088Sdonn prtaddr = newaddr;
1402f00b088Sdonn }
1412f00b088Sdonn }
1422f00b088Sdonn
1432f00b088Sdonn /*
1442f00b088Sdonn * Print the contents of the addresses within the given range
1452f00b088Sdonn * according to the given format.
1462f00b088Sdonn */
1472f00b088Sdonn
1482f00b088Sdonn typedef struct {
1492f00b088Sdonn String name;
1502f00b088Sdonn String printfstring;
1512f00b088Sdonn int length;
1522f00b088Sdonn } Format;
1532f00b088Sdonn
1542f00b088Sdonn private Format fmt[] = {
1552f00b088Sdonn { "d", " %d", sizeof(short) },
1562f00b088Sdonn { "D", " %ld", sizeof(long) },
1572f00b088Sdonn { "o", " %o", sizeof(short) },
1582f00b088Sdonn { "O", " %lo", sizeof(long) },
1592f00b088Sdonn { "x", " %04x", sizeof(short) },
1602f00b088Sdonn { "X", " %08x", sizeof(long) },
1612f00b088Sdonn { "b", " \\%o", sizeof(char) },
1622f00b088Sdonn { "c", " '%c'", sizeof(char) },
1632f00b088Sdonn { "s", "%c", sizeof(char) },
1642f00b088Sdonn { "f", " %f", sizeof(float) },
1652f00b088Sdonn { "g", " %g", sizeof(double) },
1662f00b088Sdonn { nil, nil, 0 }
1672f00b088Sdonn };
1682f00b088Sdonn
findformat(s)1692f00b088Sdonn private Format *findformat(s)
1702f00b088Sdonn String s;
1712f00b088Sdonn {
1722f00b088Sdonn register Format *f;
1732f00b088Sdonn
1742f00b088Sdonn f = &fmt[0];
1752f00b088Sdonn while (f->name != nil and not streq(f->name, s)) {
1762f00b088Sdonn ++f;
1772f00b088Sdonn }
1782f00b088Sdonn if (f->name == nil) {
1792f00b088Sdonn error("bad print format \"%s\"", s);
1802f00b088Sdonn }
1812f00b088Sdonn return f;
1822f00b088Sdonn }
1832f00b088Sdonn
1842f00b088Sdonn /*
1852f00b088Sdonn * Retrieve and print out the appropriate data in the given format.
1862f00b088Sdonn * Floats have to be handled specially to allow the compiler to
1872f00b088Sdonn * convert them to doubles when passing to printf.
1882f00b088Sdonn */
1892f00b088Sdonn
printformat(f,addr)1902f00b088Sdonn private printformat (f, addr)
1912f00b088Sdonn Format *f;
1922f00b088Sdonn Address addr;
1932f00b088Sdonn {
1942f00b088Sdonn union {
1952f00b088Sdonn char charv;
1962f00b088Sdonn short shortv;
1972f00b088Sdonn int intv;
1982f00b088Sdonn float floatv;
1992f00b088Sdonn double doublev;
2002f00b088Sdonn } value;
2012f00b088Sdonn
2022f00b088Sdonn value.intv = 0;
2032f00b088Sdonn dread(&value, addr, f->length);
2042f00b088Sdonn if (streq(f->name, "f")) {
2052f00b088Sdonn printf(f->printfstring, value.floatv);
2062f00b088Sdonn } else {
2072f00b088Sdonn printf(f->printfstring, value);
2082f00b088Sdonn }
2092f00b088Sdonn }
2102f00b088Sdonn
printdata(lowaddr,highaddr,format)2112f00b088Sdonn public Address printdata(lowaddr, highaddr, format)
2122f00b088Sdonn Address lowaddr;
2132f00b088Sdonn Address highaddr;
2142f00b088Sdonn String format;
2152f00b088Sdonn {
2162f00b088Sdonn int n;
2172f00b088Sdonn register Address addr;
2182f00b088Sdonn Format *f;
2192f00b088Sdonn
2202f00b088Sdonn if (lowaddr > highaddr) {
2212f00b088Sdonn error("first address larger than second");
2222f00b088Sdonn }
2232f00b088Sdonn f = findformat(format);
2242f00b088Sdonn n = 0;
2252f00b088Sdonn for (addr = lowaddr; addr <= highaddr; addr += f->length) {
2262f00b088Sdonn if (n == 0) {
2272f00b088Sdonn printf("%08x: ", addr);
2282f00b088Sdonn }
2292f00b088Sdonn printformat(f, addr);
2302f00b088Sdonn ++n;
2312f00b088Sdonn if (n >= (16 div f->length)) {
2322f00b088Sdonn printf("\n");
2332f00b088Sdonn n = 0;
2342f00b088Sdonn }
2352f00b088Sdonn }
2362f00b088Sdonn if (n != 0) {
2372f00b088Sdonn printf("\n");
2382f00b088Sdonn }
2392f00b088Sdonn prtaddr = addr;
2402f00b088Sdonn return addr;
2412f00b088Sdonn }
2422f00b088Sdonn
2432f00b088Sdonn /*
2442f00b088Sdonn * The other approach is to print n items starting with a given address.
2452f00b088Sdonn */
2462f00b088Sdonn
printndata(count,startaddr,format)2472f00b088Sdonn public printndata(count, startaddr, format)
2482f00b088Sdonn int count;
2492f00b088Sdonn Address startaddr;
2502f00b088Sdonn String format;
2512f00b088Sdonn {
2522f00b088Sdonn int i, n;
2532f00b088Sdonn Address addr;
2542f00b088Sdonn Format *f;
2552f00b088Sdonn Boolean isstring;
2562f00b088Sdonn char c;
2572f00b088Sdonn
2582f00b088Sdonn if (count <= 0) {
2592f00b088Sdonn error("non-positive repetition count");
2602f00b088Sdonn }
2612f00b088Sdonn f = findformat(format);
2622f00b088Sdonn isstring = (Boolean) streq(f->name, "s");
2632f00b088Sdonn n = 0;
2642f00b088Sdonn addr = startaddr;
2652f00b088Sdonn for (i = 0; i < count; i++) {
2662f00b088Sdonn if (n == 0) {
2672f00b088Sdonn printf("%08x: ", addr);
2682f00b088Sdonn }
2692f00b088Sdonn if (isstring) {
2702f00b088Sdonn printf("\"");
2712f00b088Sdonn dread(&c, addr, sizeof(char));
2722f00b088Sdonn while (c != '\0') {
2732f00b088Sdonn printchar(c);
2742f00b088Sdonn ++addr;
2752f00b088Sdonn dread(&c, addr, sizeof(char));
2762f00b088Sdonn }
2772f00b088Sdonn printf("\"\n");
2782f00b088Sdonn n = 0;
2792f00b088Sdonn addr += sizeof(String);
2802f00b088Sdonn } else {
2812f00b088Sdonn printformat(f, addr);
2822f00b088Sdonn ++n;
2832f00b088Sdonn if (n >= (16 div f->length)) {
2842f00b088Sdonn printf("\n");
2852f00b088Sdonn n = 0;
2862f00b088Sdonn }
2872f00b088Sdonn addr += f->length;
2882f00b088Sdonn }
2892f00b088Sdonn }
2902f00b088Sdonn if (n != 0) {
2912f00b088Sdonn printf("\n");
2922f00b088Sdonn }
2932f00b088Sdonn prtaddr = addr;
2942f00b088Sdonn }
2952f00b088Sdonn
2962f00b088Sdonn /*
2972f00b088Sdonn * Print out a value according to the given format.
2982f00b088Sdonn */
2992f00b088Sdonn
printvalue(v,format)3002f00b088Sdonn public printvalue(v, format)
3012f00b088Sdonn long v;
3022f00b088Sdonn String format;
3032f00b088Sdonn {
3042f00b088Sdonn Format *f;
3052f00b088Sdonn char *p, *q;
3062f00b088Sdonn
3072f00b088Sdonn f = findformat(format);
3082f00b088Sdonn if (streq(f->name, "s")) {
3092f00b088Sdonn putchar('"');
3102f00b088Sdonn p = (char *) &v;
3112f00b088Sdonn q = p + sizeof(v);
3122f00b088Sdonn while (p < q) {
3132f00b088Sdonn printchar(*p);
3142f00b088Sdonn ++p;
3152f00b088Sdonn }
3162f00b088Sdonn putchar('"');
3172f00b088Sdonn } else {
3182f00b088Sdonn printf(f->printfstring, v);
3192f00b088Sdonn }
3202f00b088Sdonn putchar('\n');
3212f00b088Sdonn }
3222f00b088Sdonn
3232f00b088Sdonn /*
3242f00b088Sdonn * Print out an execution time error.
3252f00b088Sdonn * Assumes the source position of the error has been calculated.
3262f00b088Sdonn *
3272f00b088Sdonn * Have to check if the -r option was specified; if so then
3282f00b088Sdonn * the object file information hasn't been read in yet.
3292f00b088Sdonn */
3302f00b088Sdonn
printerror()3312f00b088Sdonn public printerror()
3322f00b088Sdonn {
3332f00b088Sdonn extern Integer sys_nsig;
3342f00b088Sdonn extern String sys_siglist[];
3352f00b088Sdonn integer err;
3362f00b088Sdonn
3372f00b088Sdonn if (isfinished(process)) {
3382f00b088Sdonn err = exitcode(process);
3392f00b088Sdonn if (err == 0) {
3402f00b088Sdonn printf("\"%s\" terminated normally\n", objname);
3412f00b088Sdonn } else {
3422f00b088Sdonn printf("\"%s\" terminated abnormally (exit code %d)\n",
3432f00b088Sdonn objname, err
3442f00b088Sdonn );
3452f00b088Sdonn }
3462f00b088Sdonn erecover();
3472f00b088Sdonn }
3482f00b088Sdonn err = errnum(process);
3492f00b088Sdonn putchar('\n');
3502f00b088Sdonn printsig(err);
3512f00b088Sdonn putchar(' ');
3522f00b088Sdonn printloc();
3532f00b088Sdonn putchar('\n');
3542f00b088Sdonn if (curline > 0) {
3552f00b088Sdonn printlines(curline, curline);
3562f00b088Sdonn } else {
3572f00b088Sdonn printinst(pc, pc);
3582f00b088Sdonn }
3592f00b088Sdonn erecover();
3602f00b088Sdonn }
3612f00b088Sdonn
3622f00b088Sdonn /*
3632f00b088Sdonn * Print out a signal.
3642f00b088Sdonn */
3652f00b088Sdonn
3662f00b088Sdonn private String illinames[] = {
3672f00b088Sdonn "reserved addressing fault",
3682f00b088Sdonn "privileged instruction fault",
3692f00b088Sdonn "reserved operand fault"
3702f00b088Sdonn };
3712f00b088Sdonn
3722f00b088Sdonn private String fpenames[] = {
3732f00b088Sdonn nil,
3742f00b088Sdonn "integer overflow trap",
3752f00b088Sdonn "integer divide by zero trap",
3762f00b088Sdonn "floating overflow trap",
3772f00b088Sdonn "floating/decimal divide by zero trap",
3782f00b088Sdonn "floating underflow trap",
3792f00b088Sdonn "decimal overflow trap",
3802f00b088Sdonn "subscript out of range trap",
3812f00b088Sdonn "floating overflow fault",
3822f00b088Sdonn "floating divide by zero fault",
3832f00b088Sdonn "floating underflow fault"
3842f00b088Sdonn };
3852f00b088Sdonn
printsig(signo)3862f00b088Sdonn public printsig (signo)
3872f00b088Sdonn integer signo;
3882f00b088Sdonn {
3892f00b088Sdonn integer code;
3902f00b088Sdonn
3912f00b088Sdonn if (signo < 0 or signo > sys_nsig) {
3922f00b088Sdonn printf("[signal %d]", signo);
3932f00b088Sdonn } else {
3942f00b088Sdonn printf("%s", sys_siglist[signo]);
3952f00b088Sdonn }
3962f00b088Sdonn code = errcode(process);
3972f00b088Sdonn if (signo == SIGILL) {
3982f00b088Sdonn if (code >= 0 and code < sizeof(illinames) / sizeof(illinames[0])) {
3992f00b088Sdonn printf(" (%s)", illinames[code]);
4002f00b088Sdonn }
4012f00b088Sdonn } else if (signo == SIGFPE) {
4022f00b088Sdonn if (code > 0 and code < sizeof(fpenames) / sizeof(fpenames[0])) {
4032f00b088Sdonn printf(" (%s)", fpenames[code]);
4042f00b088Sdonn }
4052f00b088Sdonn }
4062f00b088Sdonn }
4072f00b088Sdonn
4082f00b088Sdonn /*
4092f00b088Sdonn * Note the termination of the program. We do this so as to avoid
4102f00b088Sdonn * having the process exit, which would make the values of variables
4112f00b088Sdonn * inaccessible. We do want to flush all output buffers here,
4122f00b088Sdonn * otherwise it'll never get done.
4132f00b088Sdonn */
4142f00b088Sdonn
endprogram()4152f00b088Sdonn public endprogram()
4162f00b088Sdonn {
4172f00b088Sdonn Integer exitcode;
4182f00b088Sdonn
4192f00b088Sdonn stepto(nextaddr(pc, true));
4202f00b088Sdonn printnews();
4212f00b088Sdonn exitcode = argn(1, nil);
4222f00b088Sdonn if (exitcode != 0) {
4232f00b088Sdonn printf("\nexecution completed (exit code %d)\n", exitcode);
4242f00b088Sdonn } else {
4252f00b088Sdonn printf("\nexecution completed\n");
4262f00b088Sdonn }
4272f00b088Sdonn getsrcpos();
4282f00b088Sdonn erecover();
4292f00b088Sdonn }
4302f00b088Sdonn
4312f00b088Sdonn /*
4322f00b088Sdonn * Single step the machine a source line (or instruction if "inst_tracing"
4332f00b088Sdonn * is true). If "isnext" is true, skip over procedure calls.
4342f00b088Sdonn */
4352f00b088Sdonn
4362f00b088Sdonn private Address getcall();
4372f00b088Sdonn
dostep(isnext)4382f00b088Sdonn public dostep(isnext)
4392f00b088Sdonn Boolean isnext;
4402f00b088Sdonn {
4412f00b088Sdonn register Address addr;
4422f00b088Sdonn register Lineno line;
4432f00b088Sdonn String filename;
4442f00b088Sdonn Address startaddr;
4452f00b088Sdonn
4462f00b088Sdonn startaddr = pc;
4472f00b088Sdonn addr = nextaddr(pc, isnext);
4482f00b088Sdonn if (not inst_tracing and nlhdr.nlines != 0) {
4492f00b088Sdonn line = linelookup(addr);
4502f00b088Sdonn while (line == 0) {
4512f00b088Sdonn addr = nextaddr(addr, isnext);
4522f00b088Sdonn line = linelookup(addr);
4532f00b088Sdonn }
4542f00b088Sdonn curline = line;
4552f00b088Sdonn } else {
4562f00b088Sdonn curline = 0;
4572f00b088Sdonn }
4582f00b088Sdonn stepto(addr);
4592f00b088Sdonn filename = srcfilename(addr);
4602f00b088Sdonn setsource(filename);
4612f00b088Sdonn }
4622f00b088Sdonn
4632f00b088Sdonn typedef short Bpinst;
4642f00b088Sdonn
4652f00b088Sdonn extern Bpinst BP_OP;
4662f00b088Sdonn #ifdef sun
4672f00b088Sdonn asm("_BP_OP: trap #15");
4682f00b088Sdonn #else /* IRIS */
4692f00b088Sdonn asm("_BP_OP: trap #1");
4702f00b088Sdonn #endif
4712f00b088Sdonn
4722f00b088Sdonn #define BP_ERRNO SIGTRAP /* signal received at a breakpoint */
4732f00b088Sdonn
4742f00b088Sdonn /*
4752f00b088Sdonn * Setting a breakpoint at a location consists of saving
4762f00b088Sdonn * the word at the location and poking a BP_OP there.
4772f00b088Sdonn *
4782f00b088Sdonn * We save the locations and words on a list for use in unsetting.
4792f00b088Sdonn */
4802f00b088Sdonn
4812f00b088Sdonn typedef struct Savelist *Savelist;
4822f00b088Sdonn
4832f00b088Sdonn struct Savelist {
4842f00b088Sdonn Address location;
4852f00b088Sdonn Bpinst save;
4862f00b088Sdonn short refcount;
4872f00b088Sdonn Savelist link;
4882f00b088Sdonn };
4892f00b088Sdonn
4902f00b088Sdonn private Savelist savelist;
4912f00b088Sdonn
4922f00b088Sdonn /*
4932f00b088Sdonn * Set a breakpoint at the given address. Only save the word there
4942f00b088Sdonn * if it's not already a breakpoint.
4952f00b088Sdonn */
4962f00b088Sdonn
setbp(addr)4972f00b088Sdonn public setbp(addr)
4982f00b088Sdonn Address addr;
4992f00b088Sdonn {
5002f00b088Sdonn Bpinst w, save;
5012f00b088Sdonn register Savelist newsave, s;
5022f00b088Sdonn
5032f00b088Sdonn for (s = savelist; s != nil; s = s->link) {
5042f00b088Sdonn if (s->location == addr) {
5052f00b088Sdonn s->refcount++;
5062f00b088Sdonn return;
5072f00b088Sdonn }
5082f00b088Sdonn }
5092f00b088Sdonn iread(&save, addr, sizeof(save));
5102f00b088Sdonn newsave = new(Savelist);
5112f00b088Sdonn newsave->location = addr;
5122f00b088Sdonn newsave->save = save;
5132f00b088Sdonn newsave->refcount = 1;
5142f00b088Sdonn newsave->link = savelist;
5152f00b088Sdonn savelist = newsave;
5162f00b088Sdonn w = BP_OP;
5172f00b088Sdonn iwrite(&w, addr, sizeof(w));
5182f00b088Sdonn }
5192f00b088Sdonn
5202f00b088Sdonn /*
5212f00b088Sdonn * Unset a breakpoint; unfortunately we have to search the SAVELIST
5222f00b088Sdonn * to find the saved value. The assumption is that the SAVELIST will
5232f00b088Sdonn * usually be quite small.
5242f00b088Sdonn */
5252f00b088Sdonn
unsetbp(addr)5262f00b088Sdonn public unsetbp(addr)
5272f00b088Sdonn Address addr;
5282f00b088Sdonn {
5292f00b088Sdonn register Savelist s, prev;
5302f00b088Sdonn
5312f00b088Sdonn prev = nil;
5322f00b088Sdonn for (s = savelist; s != nil; s = s->link) {
5332f00b088Sdonn if (s->location == addr) {
5342f00b088Sdonn iwrite(&s->save, addr, sizeof(s->save));
5352f00b088Sdonn s->refcount--;
5362f00b088Sdonn if (s->refcount == 0) {
5372f00b088Sdonn if (prev == nil) {
5382f00b088Sdonn savelist = s->link;
5392f00b088Sdonn } else {
5402f00b088Sdonn prev->link = s->link;
5412f00b088Sdonn }
5422f00b088Sdonn dispose(s);
5432f00b088Sdonn }
5442f00b088Sdonn return;
5452f00b088Sdonn }
5462f00b088Sdonn prev = s;
5472f00b088Sdonn }
5482f00b088Sdonn panic("unsetbp: couldn't find address %d", addr);
5492f00b088Sdonn }
5502f00b088Sdonn
5512f00b088Sdonn /*
5522f00b088Sdonn * Instruction decoding routines for 68000, derived from adb.
5532f00b088Sdonn *
5542f00b088Sdonn * The shared boolean variable "printing" is true if the decoded
5552f00b088Sdonn * instruction is to be printed, false if not. In either case,
5562f00b088Sdonn * the address of the next instruction after the given one is returned.
5572f00b088Sdonn */
5582f00b088Sdonn
5592f00b088Sdonn private Boolean printing;
5602f00b088Sdonn private Boolean following;
5612f00b088Sdonn private Boolean followcalls;
5622f00b088Sdonn private Address instaddr;
5632f00b088Sdonn
5642f00b088Sdonn #define instread(var) \
5652f00b088Sdonn { \
5662f00b088Sdonn iread(&var, instaddr, sizeof(var)); \
5672f00b088Sdonn instaddr += sizeof(var); \
5682f00b088Sdonn }
5692f00b088Sdonn
decode(inst,addr)5702f00b088Sdonn private Optab *decode(inst, addr)
5712f00b088Sdonn Word inst;
5722f00b088Sdonn Address addr;
5732f00b088Sdonn {
5742f00b088Sdonn register Optab *o;
5752f00b088Sdonn
5762f00b088Sdonn o = &optab[0];
5772f00b088Sdonn while (o->mask != 0 and (inst&o->mask) != o->match) {
5782f00b088Sdonn ++o;
5792f00b088Sdonn }
5802f00b088Sdonn return o;
5812f00b088Sdonn }
5822f00b088Sdonn
printop(addr)5832f00b088Sdonn private Address printop(addr)
5842f00b088Sdonn Address addr;
5852f00b088Sdonn {
5862f00b088Sdonn Optab *o;
5872f00b088Sdonn short inst;
5882f00b088Sdonn
5892f00b088Sdonn printf("%08x ", addr);
5902f00b088Sdonn iread(&inst, addr, sizeof(inst));
5912f00b088Sdonn o = decode(inst, addr);
5922f00b088Sdonn if (o->mask == 0) {
5932f00b088Sdonn printf("\tbadop");
5942f00b088Sdonn instaddr = addr + sizeof(inst);
5952f00b088Sdonn } else {
5962f00b088Sdonn printing = true;
5972f00b088Sdonn following = false;
5982f00b088Sdonn instaddr = addr + sizeof(inst);
5992f00b088Sdonn (*o->opfun)(inst, o->farg);
6002f00b088Sdonn printing = false;
6012f00b088Sdonn }
6022f00b088Sdonn printf("\n");
6032f00b088Sdonn return instaddr;
6042f00b088Sdonn }
6052f00b088Sdonn
6062f00b088Sdonn /*
6072f00b088Sdonn * Quickly find the return address of the current procedure or function
6082f00b088Sdonn * while single stepping. Just get the word pointed at by sp.
6092f00b088Sdonn */
6102f00b088Sdonn
currtnaddr()6112f00b088Sdonn private Address currtnaddr ()
6122f00b088Sdonn {
6132f00b088Sdonn Address retaddr;
6142f00b088Sdonn
6152f00b088Sdonn dread(&retaddr, reg(STKP), sizeof(retaddr));
6162f00b088Sdonn return retaddr;
6172f00b088Sdonn }
6182f00b088Sdonn
6192f00b088Sdonn /*
6202f00b088Sdonn * Print out the effective address for the given parameters.
6212f00b088Sdonn */
6222f00b088Sdonn
printea(mode,reg,size)6232f00b088Sdonn private printea(mode, reg, size)
6242f00b088Sdonn long mode, reg;
6252f00b088Sdonn int size;
6262f00b088Sdonn {
6272f00b088Sdonn long index, disp;
6282f00b088Sdonn static char *aregs[] = { "a0", "a1", "a2", "a3", "a4", "a5", "a6", "sp" };
6292f00b088Sdonn Byte b;
6302f00b088Sdonn short w;
6312f00b088Sdonn long l;
6322f00b088Sdonn
6332f00b088Sdonn switch ((int)(mode)) {
6342f00b088Sdonn case 0:
6352f00b088Sdonn if (printing) {
6362f00b088Sdonn printf("d%D", reg);
6372f00b088Sdonn }
6382f00b088Sdonn break;
6392f00b088Sdonn
6402f00b088Sdonn case 1:
6412f00b088Sdonn if (printing) {
6422f00b088Sdonn printf("%s", aregs[reg]);
6432f00b088Sdonn }
6442f00b088Sdonn break;
6452f00b088Sdonn
6462f00b088Sdonn case 2:
6472f00b088Sdonn if (printing) {
6482f00b088Sdonn printf("%s@", aregs[reg]);
6492f00b088Sdonn }
6502f00b088Sdonn break;
6512f00b088Sdonn
6522f00b088Sdonn case 3:
6532f00b088Sdonn if (printing) {
6542f00b088Sdonn printf("%s@+", aregs[reg]);
6552f00b088Sdonn }
6562f00b088Sdonn break;
6572f00b088Sdonn
6582f00b088Sdonn case 4:
6592f00b088Sdonn if (printing) {
6602f00b088Sdonn printf("%s@-", aregs[reg]);
6612f00b088Sdonn }
6622f00b088Sdonn break;
6632f00b088Sdonn
6642f00b088Sdonn case 5:
6652f00b088Sdonn instread(w);
6662f00b088Sdonn if (printing) {
6672f00b088Sdonn printf("%s@(%D)", aregs[reg], w);
6682f00b088Sdonn }
6692f00b088Sdonn break;
6702f00b088Sdonn
6712f00b088Sdonn case 6:
6722f00b088Sdonn instread(w);
6732f00b088Sdonn if (printing) {
6742f00b088Sdonn index = w;
6752f00b088Sdonn disp = (char)(index&0377);
6762f00b088Sdonn printf("%s@(%d,%c%D:%c)", aregs[reg], disp,
6772f00b088Sdonn (index&0100000)?'a':'d',(index>>12)&07,
6782f00b088Sdonn (index&04000)?'l':'w');
6792f00b088Sdonn }
6802f00b088Sdonn break;
6812f00b088Sdonn
6822f00b088Sdonn case 7:
6832f00b088Sdonn switch ((int)(reg)) {
6842f00b088Sdonn case 0:
6852f00b088Sdonn instread(w);
6862f00b088Sdonn if (printing) {
6872f00b088Sdonn index = w;
6882f00b088Sdonn psymoff(index);
6892f00b088Sdonn }
6902f00b088Sdonn break;
6912f00b088Sdonn
6922f00b088Sdonn case 1:
6932f00b088Sdonn instread(l);
6942f00b088Sdonn if (printing) {
6952f00b088Sdonn index = l;
6962f00b088Sdonn psymoff(index);
6972f00b088Sdonn }
6982f00b088Sdonn break;
6992f00b088Sdonn
7002f00b088Sdonn case 2:
7012f00b088Sdonn instread(w);
7022f00b088Sdonn if (printing) {
7032f00b088Sdonn disp = w;
7042f00b088Sdonn psymoff(disp + instaddr);
7052f00b088Sdonn }
7062f00b088Sdonn break;
7072f00b088Sdonn
7082f00b088Sdonn case 3:
7092f00b088Sdonn instread(w);
7102f00b088Sdonn if (printing) {
7112f00b088Sdonn index = w;
7122f00b088Sdonn disp = (char)(index&0377);
7132f00b088Sdonn printf("pc@(%D,%c%D:%c)", disp,
7142f00b088Sdonn (index&0100000)?'a':'d',(index>>12)&07,
7152f00b088Sdonn (index&04000)?'l':'w');
7162f00b088Sdonn }
7172f00b088Sdonn break;
7182f00b088Sdonn
7192f00b088Sdonn case 4:
7202f00b088Sdonn switch (size) {
7212f00b088Sdonn case sizeof(b):
7222f00b088Sdonn instread(w);
7232f00b088Sdonn index = (w&0xff);
7242f00b088Sdonn break;
7252f00b088Sdonn
7262f00b088Sdonn case sizeof(w):
7272f00b088Sdonn instread(w);
7282f00b088Sdonn index = w;
7292f00b088Sdonn break;
7302f00b088Sdonn
7312f00b088Sdonn case sizeof(l):
7322f00b088Sdonn instread(l);
7332f00b088Sdonn index = l;
7342f00b088Sdonn break;
7352f00b088Sdonn
7362f00b088Sdonn default:
7372f00b088Sdonn if (printing) {
7382f00b088Sdonn printf("unexpected size %d in printea\n", size);
7392f00b088Sdonn }
7402f00b088Sdonn instread(l);
7412f00b088Sdonn index = l;
7422f00b088Sdonn break;
7432f00b088Sdonn }
7442f00b088Sdonn if (printing) {
7452f00b088Sdonn printf(IMDF, index);
7462f00b088Sdonn }
7472f00b088Sdonn break;
7482f00b088Sdonn
7492f00b088Sdonn default:
7502f00b088Sdonn if (printing) {
7512f00b088Sdonn printf("???");
7522f00b088Sdonn }
7532f00b088Sdonn break;
7542f00b088Sdonn }
7552f00b088Sdonn break;
7562f00b088Sdonn
7572f00b088Sdonn default:
7582f00b088Sdonn if (printing) {
7592f00b088Sdonn printf("???");
7602f00b088Sdonn }
7612f00b088Sdonn break;
7622f00b088Sdonn }
7632f00b088Sdonn }
7642f00b088Sdonn
printEA(ea,size)7652f00b088Sdonn private printEA(ea, size)
7662f00b088Sdonn long ea;
7672f00b088Sdonn int size;
7682f00b088Sdonn {
7692f00b088Sdonn printea((ea>>3)&07, ea&07, size);
7702f00b088Sdonn }
7712f00b088Sdonn
mapsize(inst)7722f00b088Sdonn private mapsize(inst)
7732f00b088Sdonn register long inst;
7742f00b088Sdonn {
7752f00b088Sdonn int m;
7762f00b088Sdonn
7772f00b088Sdonn inst >>= 6;
7782f00b088Sdonn inst &= 03;
7792f00b088Sdonn switch (inst) {
7802f00b088Sdonn case 0:
7812f00b088Sdonn m = 1;
7822f00b088Sdonn break;
7832f00b088Sdonn
7842f00b088Sdonn case 1:
7852f00b088Sdonn m = 2;
7862f00b088Sdonn break;
7872f00b088Sdonn
7882f00b088Sdonn case 2:
7892f00b088Sdonn m = 4;
7902f00b088Sdonn break;
7912f00b088Sdonn
7922f00b088Sdonn default:
7932f00b088Sdonn m = -1;
7942f00b088Sdonn break;
7952f00b088Sdonn }
7962f00b088Sdonn return m;
7972f00b088Sdonn }
7982f00b088Sdonn
suffix(size)7992f00b088Sdonn private char suffix(size)
8002f00b088Sdonn int size;
8012f00b088Sdonn {
8022f00b088Sdonn char c;
8032f00b088Sdonn
8042f00b088Sdonn switch (size) {
8052f00b088Sdonn case 1:
8062f00b088Sdonn c = 'b';
8072f00b088Sdonn break;
8082f00b088Sdonn
8092f00b088Sdonn case 2:
8102f00b088Sdonn c = 'w';
8112f00b088Sdonn break;
8122f00b088Sdonn
8132f00b088Sdonn case 4:
8142f00b088Sdonn c = 'l';
8152f00b088Sdonn break;
8162f00b088Sdonn
8172f00b088Sdonn default:
8182f00b088Sdonn panic("bad size %d in suffix", size);
8192f00b088Sdonn }
8202f00b088Sdonn return c;
8212f00b088Sdonn }
8222f00b088Sdonn
8232f00b088Sdonn /*
8242f00b088Sdonn * Print an address offset. Eventually this should attempt to be symbolic,
8252f00b088Sdonn * but for now its just printed in hex.
8262f00b088Sdonn */
8272f00b088Sdonn
psymoff(off)8282f00b088Sdonn private psymoff (off)
8292f00b088Sdonn Word off;
8302f00b088Sdonn {
8312f00b088Sdonn Symbol f;
8322f00b088Sdonn
8332f00b088Sdonn f = whatblock((Address) (off + FUNCOFFSET));
8342f00b088Sdonn if (codeloc(f) == off + FUNCOFFSET) {
8352f00b088Sdonn printf("%s", symname(f));
8362f00b088Sdonn } else {
8372f00b088Sdonn printf("0x%x", off);
8382f00b088Sdonn }
8392f00b088Sdonn }
8402f00b088Sdonn
8412f00b088Sdonn /*
8422f00b088Sdonn * Instruction class specific routines.
8432f00b088Sdonn */
8442f00b088Sdonn
omove(inst,s)8452f00b088Sdonn public omove(inst, s)
8462f00b088Sdonn long inst;
8472f00b088Sdonn String s;
8482f00b088Sdonn {
8492f00b088Sdonn register int c;
8502f00b088Sdonn int size;
8512f00b088Sdonn
8522f00b088Sdonn c = s[0];
8532f00b088Sdonn if (printing) {
8542f00b088Sdonn printf("\tmov%c\t", c);
8552f00b088Sdonn }
8562f00b088Sdonn size = ((c == 'b') ? 1 : (c == 'w') ? 2 : 4);
8572f00b088Sdonn printea((inst>>3)&07, inst&07, size);
8582f00b088Sdonn if (printing) {
8592f00b088Sdonn printf(",");
8602f00b088Sdonn }
8612f00b088Sdonn printea((inst>>6)&07, (inst>>9)&07, size);
8622f00b088Sdonn }
8632f00b088Sdonn
8642f00b088Sdonn /*
8652f00b088Sdonn * Two types: bsr (4 bytes) and bsrs (2 bytes)
8662f00b088Sdonn */
8672f00b088Sdonn
obranch(inst,dummy)8682f00b088Sdonn public obranch(inst, dummy)
8692f00b088Sdonn long inst;
8702f00b088Sdonn {
8712f00b088Sdonn long disp;
8722f00b088Sdonn String s;
8732f00b088Sdonn short w;
8742f00b088Sdonn Address startingaddr; /* address of branch instruction */
8752f00b088Sdonn int branchtype; /* type of branch (0 = unconditional) */
8762f00b088Sdonn Address dest;
8772f00b088Sdonn Address retaddr; /* for bsr instruction */
8782f00b088Sdonn
8792f00b088Sdonn startingaddr = instaddr - 2;
8802f00b088Sdonn disp = inst&0377;
8812f00b088Sdonn s = "s ";
8822f00b088Sdonn if (disp == 0) {
8832f00b088Sdonn retaddr = startingaddr + 4;
8842f00b088Sdonn } else {
8852f00b088Sdonn retaddr = startingaddr + 2;
8862f00b088Sdonn }
8872f00b088Sdonn if (disp > 127) {
8882f00b088Sdonn disp |= ~0377;
8892f00b088Sdonn } else if (disp == 0){
8902f00b088Sdonn s = " ";
8912f00b088Sdonn instread(w);
8922f00b088Sdonn disp = w;
8932f00b088Sdonn }
8942f00b088Sdonn branchtype = (int)((inst>>8)&017);
8952f00b088Sdonn dest = startingaddr + 2 + disp;
8962f00b088Sdonn if (printing) {
8972f00b088Sdonn printf("\tb%s%s\t", bname[branchtype], s);
8982f00b088Sdonn psymoff(dest);
8992f00b088Sdonn }
9002f00b088Sdonn if (following) {
9012f00b088Sdonn /*
9022f00b088Sdonn * If we're to follow the dynamic flow of instructions,
9032f00b088Sdonn * we must see where the branch leads. A branchtype of 0
9042f00b088Sdonn * indicates an unconditional branch which we simply take
9052f00b088Sdonn * as the new instruction address. For a conditional branch,
9062f00b088Sdonn * we continue execution up to the current address, single step,
9072f00b088Sdonn * and keep going.
9082f00b088Sdonn */
9092f00b088Sdonn if (branchtype == 0) {
9102f00b088Sdonn instaddr = dest;
9112f00b088Sdonn } else if (branchtype == 01) { /* bsr */
9122f00b088Sdonn if (followcalls) {
9132f00b088Sdonn steppast(startingaddr);
9142f00b088Sdonn curfunc = whatblock(pc, true);
9152f00b088Sdonn if (not isbperr()) {
9162f00b088Sdonn printstatus();
9172f00b088Sdonn /* NOTREACHED */
9182f00b088Sdonn }
9192f00b088Sdonn bpact();
9202f00b088Sdonn if (nosource(curfunc) and canskip(curfunc) and
9212f00b088Sdonn nlhdr.nlines != 0) {
9222f00b088Sdonn stepto(retaddr);
9232f00b088Sdonn instaddr = pc;
9242f00b088Sdonn bpact();
9252f00b088Sdonn } else {
9262f00b088Sdonn callnews(/* iscall = */ true);
9272f00b088Sdonn }
9282f00b088Sdonn }
9292f00b088Sdonn } else {
9302f00b088Sdonn steppast(startingaddr);
9312f00b088Sdonn }
9322f00b088Sdonn }
9332f00b088Sdonn }
9342f00b088Sdonn
odbcc(inst,form)9352f00b088Sdonn public odbcc(inst, form)
9362f00b088Sdonn long inst;
9372f00b088Sdonn String form;
9382f00b088Sdonn {
9392f00b088Sdonn long disp;
9402f00b088Sdonn short w;
9412f00b088Sdonn
9422f00b088Sdonn instread(w);
9432f00b088Sdonn if (printing) {
9442f00b088Sdonn printf(form, dbname[(int)((inst>>8)&017)], inst&07);
9452f00b088Sdonn psymoff(w + sizeof(w));
9462f00b088Sdonn }
9472f00b088Sdonn }
9482f00b088Sdonn
oscc(inst,dummy)9492f00b088Sdonn public oscc(inst, dummy)
9502f00b088Sdonn long inst;
9512f00b088Sdonn long dummy;
9522f00b088Sdonn {
9532f00b088Sdonn if (printing) {
9542f00b088Sdonn printf("\ts%s\t", cname[(int)((inst>>8)&017)]);
9552f00b088Sdonn }
9562f00b088Sdonn printea((inst>>3)&07, inst&07, 1);
9572f00b088Sdonn }
9582f00b088Sdonn
biti(inst,dummy)9592f00b088Sdonn public biti(inst, dummy)
9602f00b088Sdonn long inst;
9612f00b088Sdonn long dummy;
9622f00b088Sdonn {
9632f00b088Sdonn short w;
9642f00b088Sdonn
9652f00b088Sdonn if (printing) {
9662f00b088Sdonn printf("\t%s\t", bit[(int)((inst>>6)&03)]);
9672f00b088Sdonn }
9682f00b088Sdonn if (inst&0x0100) {
9692f00b088Sdonn if (printing) {
9702f00b088Sdonn printf("d%D,", inst>>9);
9712f00b088Sdonn }
9722f00b088Sdonn } else {
9732f00b088Sdonn instread(w);
9742f00b088Sdonn if (printing) {
9752f00b088Sdonn printf(IMDF, w);
9762f00b088Sdonn printf(",");
9772f00b088Sdonn }
9782f00b088Sdonn }
9792f00b088Sdonn printEA(inst);
9802f00b088Sdonn }
9812f00b088Sdonn
opmode(inst,opcode)9822f00b088Sdonn public opmode(inst, opcode)
9832f00b088Sdonn long inst;
9842f00b088Sdonn long opcode;
9852f00b088Sdonn {
9862f00b088Sdonn register int opmode;
9872f00b088Sdonn register int reg;
9882f00b088Sdonn int size;
9892f00b088Sdonn
9902f00b088Sdonn opmode = (int)((inst>>6) & 07);
9912f00b088Sdonn reg = (int)((inst>>9) & 07);
9922f00b088Sdonn if (opmode == 0 or opmode == 4) {
9932f00b088Sdonn size = 1;
9942f00b088Sdonn } else if (opmode == 1 or opmode == 3 or opmode == 5) {
9952f00b088Sdonn size = 2;
9962f00b088Sdonn } else {
9972f00b088Sdonn size = 4;
9982f00b088Sdonn }
9992f00b088Sdonn if (printing) {
10002f00b088Sdonn printf("\t%s%c\t", opcode, suffix(size));
10012f00b088Sdonn }
10022f00b088Sdonn if (opmode >= 4 and opmode <= 6) {
10032f00b088Sdonn if (printing) {
10042f00b088Sdonn printf("d%d,", reg);
10052f00b088Sdonn }
10062f00b088Sdonn printea((inst>>3)&07, inst&07, size);
10072f00b088Sdonn } else {
10082f00b088Sdonn printea((inst>>3)&07, inst&07, size);
10092f00b088Sdonn if (printing) {
10102f00b088Sdonn printf(",%c%d",(opmode<=2) ? 'd' : 'a', reg);
10112f00b088Sdonn }
10122f00b088Sdonn }
10132f00b088Sdonn }
10142f00b088Sdonn
shroi(inst,ds)10152f00b088Sdonn public shroi(inst, ds)
10162f00b088Sdonn long inst;
10172f00b088Sdonn String ds;
10182f00b088Sdonn {
10192f00b088Sdonn int rx, ry;
10202f00b088Sdonn String opcode;
10212f00b088Sdonn
10222f00b088Sdonn if ((inst & 0xC0) == 0xC0) {
10232f00b088Sdonn opcode = shro[(int)((inst>>9)&03)];
10242f00b088Sdonn if (printing) {
10252f00b088Sdonn printf("\t%s%s\t", opcode, ds);
10262f00b088Sdonn }
10272f00b088Sdonn printEA(inst);
10282f00b088Sdonn } else {
10292f00b088Sdonn if (printing) {
10302f00b088Sdonn opcode = shro[(int)((inst>>3)&03)];
10312f00b088Sdonn printf("\t%s%s%c\t", opcode, ds, suffix(mapsize(inst)));
10322f00b088Sdonn rx = (int)((inst>>9)&07); ry = (int)(inst&07);
10332f00b088Sdonn if ((inst>>5)&01) {
10342f00b088Sdonn printf("d%d,d%d", rx, ry);
10352f00b088Sdonn } else {
10362f00b088Sdonn printf(IMDF, (rx ? rx : 8));
10372f00b088Sdonn printf(",d%d", ry);
10382f00b088Sdonn }
10392f00b088Sdonn }
10402f00b088Sdonn }
10412f00b088Sdonn }
10422f00b088Sdonn
oimmed(inst,opcode)10432f00b088Sdonn public oimmed(inst, opcode)
10442f00b088Sdonn long inst;
10452f00b088Sdonn register String opcode;
10462f00b088Sdonn {
10472f00b088Sdonn register int size;
10482f00b088Sdonn long const;
10492f00b088Sdonn short w;
10502f00b088Sdonn
10512f00b088Sdonn size = mapsize(inst);
10522f00b088Sdonn if (size > 0) {
10532f00b088Sdonn if (size == 4) {
10542f00b088Sdonn instread(const);
10552f00b088Sdonn } else {
10562f00b088Sdonn instread(w);
10572f00b088Sdonn const = w;
10582f00b088Sdonn }
10592f00b088Sdonn if (printing) {
10602f00b088Sdonn printf("\t%s%c\t", opcode, suffix(size));
10612f00b088Sdonn printf(IMDF, const);
10622f00b088Sdonn printf(",");
10632f00b088Sdonn }
10642f00b088Sdonn printEA(inst, size);
10652f00b088Sdonn } else {
10662f00b088Sdonn if (printing) {
10672f00b088Sdonn printf("\tbadop");
10682f00b088Sdonn }
10692f00b088Sdonn }
10702f00b088Sdonn }
10712f00b088Sdonn
oreg(inst,opcode)10722f00b088Sdonn public oreg(inst, opcode)
10732f00b088Sdonn long inst;
10742f00b088Sdonn register String opcode;
10752f00b088Sdonn {
10762f00b088Sdonn if (printing) {
10772f00b088Sdonn printf(opcode, (inst & 07));
10782f00b088Sdonn }
10792f00b088Sdonn }
10802f00b088Sdonn
extend(inst,opcode)10812f00b088Sdonn public extend(inst, opcode)
10822f00b088Sdonn long inst;
10832f00b088Sdonn String opcode;
10842f00b088Sdonn {
10852f00b088Sdonn register int size;
10862f00b088Sdonn int ry, rx;
10872f00b088Sdonn char c;
10882f00b088Sdonn
10892f00b088Sdonn if (printing) {
10902f00b088Sdonn size = mapsize(inst);
10912f00b088Sdonn ry = (inst&07);
10922f00b088Sdonn rx = ((inst>>9)&07);
10932f00b088Sdonn c = ((inst & 0x1000) ? suffix(size) : ' ');
10942f00b088Sdonn printf("\t%s%c\t", opcode, c);
10952f00b088Sdonn if (opcode[0] == 'e') {
10962f00b088Sdonn if (inst & 0x0080) {
10972f00b088Sdonn printf("d%D,a%D", rx, ry);
10982f00b088Sdonn } else if (inst & 0x0008) {
10992f00b088Sdonn printf("a%D,a%D", rx, ry);
11002f00b088Sdonn } else {
11012f00b088Sdonn printf("d%D,d%D", rx, ry);
11022f00b088Sdonn }
11032f00b088Sdonn } else if ((inst & 0xF000) == 0xB000) {
11042f00b088Sdonn printf("a%D@+,a%D@+", ry, rx);
11052f00b088Sdonn } else if (inst & 0x8) {
11062f00b088Sdonn printf("a%D@-,a%D@-", ry, rx);
11072f00b088Sdonn } else {
11082f00b088Sdonn printf("d%D,d%D", ry, rx);
11092f00b088Sdonn }
11102f00b088Sdonn }
11112f00b088Sdonn }
11122f00b088Sdonn
olink(inst,dummy)11132f00b088Sdonn public olink(inst, dummy)
11142f00b088Sdonn long inst;
11152f00b088Sdonn long dummy;
11162f00b088Sdonn {
11172f00b088Sdonn short w;
11182f00b088Sdonn
11192f00b088Sdonn instread(w);
11202f00b088Sdonn if (printing) {
11212f00b088Sdonn printf("\tlink\ta%D,", inst&07);
11222f00b088Sdonn printf(IMDF, w);
11232f00b088Sdonn }
11242f00b088Sdonn }
11252f00b088Sdonn
otrap(inst,dummy)11262f00b088Sdonn public otrap(inst, dummy)
11272f00b088Sdonn long inst;
11282f00b088Sdonn {
11292f00b088Sdonn if (printing) {
11302f00b088Sdonn printf("\ttrap\t");
11312f00b088Sdonn printf(IMDF, inst&017);
11322f00b088Sdonn }
11332f00b088Sdonn }
11342f00b088Sdonn
oneop(inst,opcode)11352f00b088Sdonn public oneop(inst, opcode)
11362f00b088Sdonn long inst;
11372f00b088Sdonn register String opcode;
11382f00b088Sdonn {
11392f00b088Sdonn if (printing) {
11402f00b088Sdonn printf("\t%s",opcode);
11412f00b088Sdonn }
11422f00b088Sdonn printEA(inst);
11432f00b088Sdonn }
11442f00b088Sdonn
jsrop(inst,opcode)11452f00b088Sdonn public jsrop(inst, opcode)
11462f00b088Sdonn long inst;
11472f00b088Sdonn register String opcode;
11482f00b088Sdonn {
11492f00b088Sdonn Address startingaddr; /* beginning of jsr instruction */
11502f00b088Sdonn Address retaddr; /* can't call return_addr (frame not set up yet) */
11512f00b088Sdonn
11522f00b088Sdonn startingaddr = instaddr - 2;
11532f00b088Sdonn switch ((inst >> 3) & 07) {
11542f00b088Sdonn case 2:
11552f00b088Sdonn retaddr = instaddr; /* two byte instruction */
11562f00b088Sdonn break;
11572f00b088Sdonn case 5:
11582f00b088Sdonn case 6:
11592f00b088Sdonn retaddr = instaddr + 2; /* four byte instruction */
11602f00b088Sdonn break;
11612f00b088Sdonn case 7:
11622f00b088Sdonn default:
11632f00b088Sdonn switch (inst & 07) {
11642f00b088Sdonn case 0:
11652f00b088Sdonn case 2:
11662f00b088Sdonn case 3:
11672f00b088Sdonn retaddr = instaddr + 2;
11682f00b088Sdonn break;
11692f00b088Sdonn case 1:
11702f00b088Sdonn default:
11712f00b088Sdonn retaddr = instaddr + 4; /* six byte instruction */
11722f00b088Sdonn break;
11732f00b088Sdonn }
11742f00b088Sdonn break;
11752f00b088Sdonn }
11762f00b088Sdonn if (printing) {
11772f00b088Sdonn printf("\t%s",opcode);
11782f00b088Sdonn }
11792f00b088Sdonn printEA(inst);
11802f00b088Sdonn if (following and followcalls) {
11812f00b088Sdonn steppast(startingaddr);
11822f00b088Sdonn curfunc = whatblock(pc, true);
11832f00b088Sdonn if (not isbperr()) {
11842f00b088Sdonn printstatus();
11852f00b088Sdonn /* NOTREACHED */
11862f00b088Sdonn }
11872f00b088Sdonn bpact();
11882f00b088Sdonn if (nosource(curfunc) and canskip(curfunc) and nlhdr.nlines != 0) {
11892f00b088Sdonn stepto(retaddr);
11902f00b088Sdonn instaddr = pc;
11912f00b088Sdonn bpact();
11922f00b088Sdonn } else {
11932f00b088Sdonn callnews(/* iscall = */ true);
11942f00b088Sdonn }
11952f00b088Sdonn }
11962f00b088Sdonn }
11972f00b088Sdonn
jmpop(inst,opcode)11982f00b088Sdonn public jmpop(inst, opcode)
11992f00b088Sdonn long inst;
12002f00b088Sdonn register String opcode;
12012f00b088Sdonn {
12022f00b088Sdonn Address startingaddr; /* beginning of jump instruction */
12032f00b088Sdonn
12042f00b088Sdonn startingaddr = instaddr - 2;
12052f00b088Sdonn if (printing) {
12062f00b088Sdonn printf("\t%s",opcode);
12072f00b088Sdonn }
12082f00b088Sdonn printEA(inst);
12092f00b088Sdonn if (following) {
12102f00b088Sdonn steppast(startingaddr);
12112f00b088Sdonn }
12122f00b088Sdonn }
12132f00b088Sdonn
pregmask(mask)12142f00b088Sdonn public pregmask(mask)
12152f00b088Sdonn register int mask;
12162f00b088Sdonn {
12172f00b088Sdonn register int i;
12182f00b088Sdonn register int flag = 0;
12192f00b088Sdonn
12202f00b088Sdonn if (printing) {
12212f00b088Sdonn printf("#<");
12222f00b088Sdonn for (i=0; i<16; i++) {
12232f00b088Sdonn if (mask&1) {
12242f00b088Sdonn if (flag) {
12252f00b088Sdonn printf(",");
12262f00b088Sdonn } else {
12272f00b088Sdonn ++flag;
12282f00b088Sdonn }
12292f00b088Sdonn printf("%c%d",(i<8) ? 'd' : 'a', i&07);
12302f00b088Sdonn }
12312f00b088Sdonn mask >>= 1;
12322f00b088Sdonn }
12332f00b088Sdonn printf(">");
12342f00b088Sdonn }
12352f00b088Sdonn }
12362f00b088Sdonn
omovem(inst,dummy)12372f00b088Sdonn public omovem(inst, dummy)
12382f00b088Sdonn long inst;
12392f00b088Sdonn long dummy;
12402f00b088Sdonn {
12412f00b088Sdonn register int i, list, mask;
12422f00b088Sdonn register int reglist;
12432f00b088Sdonn short w;
12442f00b088Sdonn
12452f00b088Sdonn i = 0;
12462f00b088Sdonn list = 0;
12472f00b088Sdonn mask = 0100000;
12482f00b088Sdonn instread(w);
12492f00b088Sdonn reglist = w;
12502f00b088Sdonn if ((inst & 070) == 040) { /* predecrement */
12512f00b088Sdonn for (i = 15; i > 0; i -= 2) {
12522f00b088Sdonn list |= ((mask & reglist) >> i);
12532f00b088Sdonn mask >>= 1;
12542f00b088Sdonn }
12552f00b088Sdonn for (i = 1; i < 16; i += 2) {
12562f00b088Sdonn list |= ((mask & reglist) << i);
12572f00b088Sdonn mask >>= 1;
12582f00b088Sdonn }
12592f00b088Sdonn reglist = list;
12602f00b088Sdonn }
12612f00b088Sdonn if (printing) {
12622f00b088Sdonn printf("\tmovem%c\t",(inst&100)?'l':'w');
12632f00b088Sdonn }
12642f00b088Sdonn if (inst&02000) {
12652f00b088Sdonn printEA(inst);
12662f00b088Sdonn if (printing) {
12672f00b088Sdonn printf(",");
12682f00b088Sdonn }
12692f00b088Sdonn pregmask(reglist);
12702f00b088Sdonn } else {
12712f00b088Sdonn pregmask(reglist);
12722f00b088Sdonn if (printing) {
12732f00b088Sdonn printf(",");
12742f00b088Sdonn }
12752f00b088Sdonn printEA(inst);
12762f00b088Sdonn }
12772f00b088Sdonn }
12782f00b088Sdonn
ochk(inst,opcode)12792f00b088Sdonn public ochk(inst, opcode)
12802f00b088Sdonn long inst;
12812f00b088Sdonn register String opcode;
12822f00b088Sdonn {
12832f00b088Sdonn if (printing) {
12842f00b088Sdonn printf("\t%s\t", opcode);
12852f00b088Sdonn }
12862f00b088Sdonn printEA(inst, sizeof(Byte));
12872f00b088Sdonn if (printing) {
12882f00b088Sdonn printf(",%c%D", (opcode[0] == 'l') ? 'a' : 'd', (inst>>9)&07);
12892f00b088Sdonn }
12902f00b088Sdonn }
12912f00b088Sdonn
soneop(inst,opcode)12922f00b088Sdonn public soneop(inst, opcode)
12932f00b088Sdonn long inst;
12942f00b088Sdonn register String opcode;
12952f00b088Sdonn {
12962f00b088Sdonn register int size;
12972f00b088Sdonn
12982f00b088Sdonn size = mapsize(inst);
12992f00b088Sdonn if (size > 0) {
13002f00b088Sdonn if (printing) {
13012f00b088Sdonn printf("\t%s%c\t", opcode, suffix(size));
13022f00b088Sdonn }
13032f00b088Sdonn printEA(inst);
13042f00b088Sdonn } else {
13052f00b088Sdonn if (printing) {
13062f00b088Sdonn printf("\tbadop");
13072f00b088Sdonn }
13082f00b088Sdonn }
13092f00b088Sdonn }
13102f00b088Sdonn
oquick(inst,opcode)13112f00b088Sdonn public oquick(inst, opcode)
13122f00b088Sdonn long inst;
13132f00b088Sdonn register String opcode;
13142f00b088Sdonn {
13152f00b088Sdonn register int size;
13162f00b088Sdonn register int data;
13172f00b088Sdonn
13182f00b088Sdonn size = mapsize(inst);
13192f00b088Sdonn data = (int)((inst>>9) & 07);
13202f00b088Sdonn if (data == 0) {
13212f00b088Sdonn data = 8;
13222f00b088Sdonn }
13232f00b088Sdonn if (size > 0) {
13242f00b088Sdonn if (printing) {
13252f00b088Sdonn printf("\t%s%c\t", opcode, suffix(size));
13262f00b088Sdonn printf(IMDF, data);
13272f00b088Sdonn printf(",");
13282f00b088Sdonn }
13292f00b088Sdonn printEA(inst);
13302f00b088Sdonn } else {
13312f00b088Sdonn if (printing) {
13322f00b088Sdonn printf("\tbadop");
13332f00b088Sdonn }
13342f00b088Sdonn }
13352f00b088Sdonn }
13362f00b088Sdonn
omoveq(inst,dummy)13372f00b088Sdonn public omoveq(inst, dummy)
13382f00b088Sdonn long inst;
13392f00b088Sdonn long dummy;
13402f00b088Sdonn {
13412f00b088Sdonn register int data;
13422f00b088Sdonn
13432f00b088Sdonn if (printing) {
13442f00b088Sdonn data = (int)(inst & 0377);
13452f00b088Sdonn if (data > 127) {
13462f00b088Sdonn data |= ~0377;
13472f00b088Sdonn }
13482f00b088Sdonn printf("\tmoveq\t");
13492f00b088Sdonn printf(IMDF, data);
13502f00b088Sdonn printf(",d%D", (inst>>9)&07);
13512f00b088Sdonn }
13522f00b088Sdonn }
13532f00b088Sdonn
oprint(inst,opcode)13542f00b088Sdonn public oprint(inst, opcode)
13552f00b088Sdonn long inst;
13562f00b088Sdonn register String opcode;
13572f00b088Sdonn {
13582f00b088Sdonn if (printing) {
13592f00b088Sdonn printf("\t%s",opcode);
13602f00b088Sdonn }
13612f00b088Sdonn }
13622f00b088Sdonn
ostop(inst,opcode)13632f00b088Sdonn public ostop(inst, opcode)
13642f00b088Sdonn long inst;
13652f00b088Sdonn register String opcode;
13662f00b088Sdonn {
13672f00b088Sdonn short w;
13682f00b088Sdonn
13692f00b088Sdonn instread(w);
13702f00b088Sdonn if (printing) {
13712f00b088Sdonn printf(opcode, w);
13722f00b088Sdonn }
13732f00b088Sdonn }
13742f00b088Sdonn
orts(inst,opcode)13752f00b088Sdonn public orts(inst, opcode)
13762f00b088Sdonn long inst;
13772f00b088Sdonn register String opcode;
13782f00b088Sdonn {
13792f00b088Sdonn Address addr;
13802f00b088Sdonn
13812f00b088Sdonn if (following) {
13822f00b088Sdonn callnews(/* iscall = */ false);
13832f00b088Sdonn if (inst_tracing) {
13842f00b088Sdonn addr = currtnaddr();
13852f00b088Sdonn } else {
13862f00b088Sdonn addr = return_addr();
13872f00b088Sdonn if (addr == 0) {
13882f00b088Sdonn stepto(instaddr - 2);
13892f00b088Sdonn addr = currtnaddr();
13902f00b088Sdonn }
13912f00b088Sdonn }
13922f00b088Sdonn stepto(addr);
13932f00b088Sdonn instaddr = pc;
13942f00b088Sdonn }
13952f00b088Sdonn if (printing) {
13962f00b088Sdonn printf("\t%s",opcode);
13972f00b088Sdonn }
13982f00b088Sdonn }
13992f00b088Sdonn
14002f00b088Sdonn /*
14012f00b088Sdonn * Not used by C compiler; does an rts but before doing so, pops
14022f00b088Sdonn * arg bytes from the stack.
14032f00b088Sdonn */
14042f00b088Sdonn
ortspop(inst,opcode)14052f00b088Sdonn public ortspop(inst, opcode)
14062f00b088Sdonn long inst;
14072f00b088Sdonn register String opcode;
14082f00b088Sdonn {
14092f00b088Sdonn Address addr;
14102f00b088Sdonn short w;
14112f00b088Sdonn
14122f00b088Sdonn instread(w);
14132f00b088Sdonn if (following) {
14142f00b088Sdonn callnews(/* iscall = */ false);
14152f00b088Sdonn if (inst_tracing) {
14162f00b088Sdonn addr = currtnaddr();
14172f00b088Sdonn } else {
14182f00b088Sdonn addr = return_addr();
14192f00b088Sdonn }
14202f00b088Sdonn stepto(addr);
14212f00b088Sdonn instaddr = pc;
14222f00b088Sdonn }
14232f00b088Sdonn if (printing) {
14242f00b088Sdonn printf(opcode, w);
14252f00b088Sdonn }
14262f00b088Sdonn }
14272f00b088Sdonn
omovs(inst,opcode)14282f00b088Sdonn public omovs(inst, opcode)
14292f00b088Sdonn long inst;
14302f00b088Sdonn String opcode;
14312f00b088Sdonn {
14322f00b088Sdonn register int size;
14332f00b088Sdonn register unsigned int controlword;
14342f00b088Sdonn short w;
14352f00b088Sdonn
14362f00b088Sdonn size = mapsize(inst);
14372f00b088Sdonn instread(w);
14382f00b088Sdonn controlword = w >> 11;
14392f00b088Sdonn if (printing) {
14402f00b088Sdonn printf("\t%s%c\t", opcode, suffix(size));
14412f00b088Sdonn }
14422f00b088Sdonn if (controlword & 1){
14432f00b088Sdonn controlword >>= 1;
14442f00b088Sdonn if (printing) {
14452f00b088Sdonn printf((controlword&0x8) ? "a%D," : "d%D,", controlword&7 );
14462f00b088Sdonn }
14472f00b088Sdonn printEA(inst&0xff, size);
14482f00b088Sdonn } else {
14492f00b088Sdonn controlword >>= 1;
14502f00b088Sdonn printEA(inst&0xff, size);
14512f00b088Sdonn if (printing) {
14522f00b088Sdonn printf((controlword&0x8) ? ",a%D" : ",d%D", controlword&7);
14532f00b088Sdonn }
14542f00b088Sdonn }
14552f00b088Sdonn }
14562f00b088Sdonn
omovc(inst,opcode)14572f00b088Sdonn public omovc(inst, opcode)
14582f00b088Sdonn long inst;
14592f00b088Sdonn String opcode;
14602f00b088Sdonn {
14612f00b088Sdonn register unsigned int controlword;
14622f00b088Sdonn String creg;
14632f00b088Sdonn short w;
14642f00b088Sdonn
14652f00b088Sdonn instread(w);
14662f00b088Sdonn if (printing) {
14672f00b088Sdonn controlword = w;
14682f00b088Sdonn switch (controlword & 0xfff) {
14692f00b088Sdonn case 0:
14702f00b088Sdonn creg = "sfc";
14712f00b088Sdonn break;
14722f00b088Sdonn
14732f00b088Sdonn case 1:
14742f00b088Sdonn creg = "dfc";
14752f00b088Sdonn break;
14762f00b088Sdonn
14772f00b088Sdonn case 0x800:
14782f00b088Sdonn creg = "usp";
14792f00b088Sdonn break;
14802f00b088Sdonn
14812f00b088Sdonn case 0x801:
14822f00b088Sdonn creg = "vbr";
14832f00b088Sdonn break;
14842f00b088Sdonn
14852f00b088Sdonn default:
14862f00b088Sdonn creg = "???";
14872f00b088Sdonn break;
14882f00b088Sdonn }
14892f00b088Sdonn controlword >>= 12;
14902f00b088Sdonn if (inst & 1){
14912f00b088Sdonn printf((controlword&0x8) ? "%sa%D,%s" : "%sd%D,%s",
14922f00b088Sdonn opcode, controlword&7, creg );
14932f00b088Sdonn } else {
14942f00b088Sdonn printf((controlword&0x8) ? "%s%s,a%D" : "%s%s,d%D",
14952f00b088Sdonn opcode, creg, controlword&7 );
14962f00b088Sdonn }
14972f00b088Sdonn }
14982f00b088Sdonn }
14992f00b088Sdonn
15002f00b088Sdonn /*
15012f00b088Sdonn * Compute the next address that will be executed from the given one.
15022f00b088Sdonn * If "isnext" is true then consider a procedure call as straight line code.
15032f00b088Sdonn *
15042f00b088Sdonn * Unconditional branches we just follow, for conditional branches
15052f00b088Sdonn * we continue execution to the current location and then single step
15062f00b088Sdonn * the machine.
15072f00b088Sdonn */
15082f00b088Sdonn
nextaddr(startaddr,isnext)15092f00b088Sdonn public Address nextaddr(startaddr, isnext)
15102f00b088Sdonn Address startaddr;
15112f00b088Sdonn Boolean isnext;
15122f00b088Sdonn {
15132f00b088Sdonn Optab *o;
15142f00b088Sdonn short inst;
15152f00b088Sdonn
15162f00b088Sdonn instaddr = usignal(process);
15172f00b088Sdonn if (instaddr == 0 or instaddr == 1) {
15182f00b088Sdonn following = true;
15192f00b088Sdonn followcalls = (Boolean) (not isnext);
15202f00b088Sdonn printing = false;
15212f00b088Sdonn iread(&inst, startaddr, sizeof(inst));
15222f00b088Sdonn instaddr = startaddr + sizeof(inst);
15232f00b088Sdonn o = decode(inst, startaddr);
15242f00b088Sdonn if (o->mask == 0) {
15252f00b088Sdonn fprintf(stderr,
15262f00b088Sdonn "[internal error: undecodable op at 0x%x]\n", startaddr);
15272f00b088Sdonn fflush(stderr);
15282f00b088Sdonn } else {
15292f00b088Sdonn (*o->opfun)(inst, o->farg);
15302f00b088Sdonn }
15312f00b088Sdonn following = false;
15322f00b088Sdonn }
15332f00b088Sdonn return instaddr;
15342f00b088Sdonn }
15352f00b088Sdonn
15362f00b088Sdonn /*
15372f00b088Sdonn * Step to the given address and then execute one instruction past it.
15382f00b088Sdonn * Set instaddr to the new instruction address.
15392f00b088Sdonn */
15402f00b088Sdonn
steppast(addr)15412f00b088Sdonn private steppast(addr)
15422f00b088Sdonn Address addr;
15432f00b088Sdonn {
15442f00b088Sdonn stepto(addr);
15452f00b088Sdonn pstep(process, DEFSIG);
15462f00b088Sdonn pc = reg(PROGCTR);
15472f00b088Sdonn instaddr = pc;
15482f00b088Sdonn }
15492f00b088Sdonn
15502f00b088Sdonn /*
15512f00b088Sdonn * Enter a procedure by creating and executing a call instruction.
15522f00b088Sdonn */
15532f00b088Sdonn
15542f00b088Sdonn #define CALLSIZE 6 /* size of call instruction */
15552f00b088Sdonn
beginproc(p)15562f00b088Sdonn public beginproc(p)
15572f00b088Sdonn Symbol p;
15582f00b088Sdonn {
15592f00b088Sdonn char save[CALLSIZE];
15602f00b088Sdonn struct {
15612f00b088Sdonn short op;
15622f00b088Sdonn char addr[sizeof(long)]; /* unaligned long */
15632f00b088Sdonn } call;
15642f00b088Sdonn long dest;
15652f00b088Sdonn
15662f00b088Sdonn pc = CODESTART + 6;
15672f00b088Sdonn iread(save, pc, sizeof(save));
15682f00b088Sdonn call.op = 0x4eb9; /* jsr */
15692f00b088Sdonn dest = codeloc(p) - FUNCOFFSET;
15702f00b088Sdonn mov(&dest, call.addr, sizeof(call.addr));
15712f00b088Sdonn iwrite(&call, pc, sizeof(call));
15722f00b088Sdonn setreg(PROGCTR, pc);
15732f00b088Sdonn pstep(process, DEFSIG);
15742f00b088Sdonn iwrite(save, pc, sizeof(save));
15752f00b088Sdonn pc = reg(PROGCTR);
15762f00b088Sdonn if (not isbperr()) {
15772f00b088Sdonn printstatus();
15782f00b088Sdonn }
15792f00b088Sdonn /*
15802f00b088Sdonn * Execute link instruction so the return addr is visible.
15812f00b088Sdonn */
15822f00b088Sdonn pstep(process, DEFSIG);
15832f00b088Sdonn pc = reg(PROGCTR);
15842f00b088Sdonn if (not isbperr()) {
15852f00b088Sdonn printstatus();
15862f00b088Sdonn }
15872f00b088Sdonn }
15882f00b088Sdonn
15892f00b088Sdonn /*
15902f00b088Sdonn * Special variables for debugging the kernel.
15912f00b088Sdonn */
15922f00b088Sdonn
15932f00b088Sdonn public integer masterpcbb;
15942f00b088Sdonn public integer slr;
15952f00b088Sdonn public struct pte *sbr;
15962f00b088Sdonn private struct pcb pcb;
15972f00b088Sdonn
getpcb()15982f00b088Sdonn public getpcb ()
15992f00b088Sdonn {
16002f00b088Sdonn integer i;
16012f00b088Sdonn
16022f00b088Sdonn fseek(corefile, masterpcbb & ~0x80000000, 0);
16032f00b088Sdonn get(corefile, pcb);
16042f00b088Sdonn pcb.pcb_p0lr &= ~AST_CLR;
16052f00b088Sdonn printf("p0br %lx p0lr %lx p1br %lx p1lr %lx\n",
16062f00b088Sdonn pcb.pcb_p0br, pcb.pcb_p0lr, pcb.pcb_p1br, pcb.pcb_p1lr
16072f00b088Sdonn );
16082f00b088Sdonn # ifdef sun
16092f00b088Sdonn for (i = 0; i < 14; i++) {
16102f00b088Sdonn setreg(i, pcb.pcb_regs.val[i]);
16112f00b088Sdonn }
16122f00b088Sdonn # else /* IRIS */
16132f00b088Sdonn for (i = 0; i < 14; i++) {
16142f00b088Sdonn setreg(i, pcb.pcb_regs[i]);
16152f00b088Sdonn }
16162f00b088Sdonn # endif
16172f00b088Sdonn }
16182f00b088Sdonn
copyregs(savreg,reg)16192f00b088Sdonn public copyregs (savreg, reg)
16202f00b088Sdonn Word savreg[], reg[];
16212f00b088Sdonn {
16222f00b088Sdonn reg[0] = savreg[R0];
16232f00b088Sdonn reg[1] = savreg[R1];
16242f00b088Sdonn reg[2] = savreg[R2];
16252f00b088Sdonn reg[3] = savreg[R3];
16262f00b088Sdonn reg[4] = savreg[R4];
16272f00b088Sdonn reg[5] = savreg[R5];
16282f00b088Sdonn reg[6] = savreg[R6];
16292f00b088Sdonn reg[7] = savreg[R7];
16302f00b088Sdonn reg[8] = savreg[AR0];
16312f00b088Sdonn reg[9] = savreg[AR1];
16322f00b088Sdonn reg[10] = savreg[AR2];
16332f00b088Sdonn reg[11] = savreg[AR3];
16342f00b088Sdonn reg[12] = savreg[AR4];
16352f00b088Sdonn reg[13] = savreg[AR5];
16362f00b088Sdonn reg[14] = savreg[AR6];
16372f00b088Sdonn reg[15] = savreg[AR7];
16382f00b088Sdonn reg[PROGCTR] = savreg[PC];
16392f00b088Sdonn }
16402f00b088Sdonn
16412f00b088Sdonn /*
16422f00b088Sdonn * Map a virtual address to a physical address.
16432f00b088Sdonn * XXX THIS CAN'T BE RIGHT... XXX
16442f00b088Sdonn */
16452f00b088Sdonn
vmap(addr)16462f00b088Sdonn public Address vmap (addr)
16472f00b088Sdonn Address addr;
16482f00b088Sdonn {
16492f00b088Sdonn Address r;
16502f00b088Sdonn integer v, n;
16512f00b088Sdonn struct pte pte;
16522f00b088Sdonn
16532f00b088Sdonn r = addr & ~0xc0000000;
16542f00b088Sdonn v = btop(r);
16552f00b088Sdonn switch (addr&0xc0000000) {
16562f00b088Sdonn case 0xc0000000:
16572f00b088Sdonn case 0x80000000:
16582f00b088Sdonn /*
16592f00b088Sdonn * In system space, so get system pte.
16602f00b088Sdonn * If it is valid or reclaimable then the physical address
16612f00b088Sdonn * is the combination of its page number and the page offset
16622f00b088Sdonn * of the original address.
16632f00b088Sdonn */
16642f00b088Sdonn if (v >= slr) {
16652f00b088Sdonn error("address %x out of segment", addr);
16662f00b088Sdonn }
16672f00b088Sdonn r = ((long) (sbr + v)) & ~0x80000000;
16682f00b088Sdonn goto simple;
16692f00b088Sdonn
16702f00b088Sdonn case 0x40000000:
16712f00b088Sdonn /*
16722f00b088Sdonn * In p1 space, must not be in shadow region.
16732f00b088Sdonn */
16742f00b088Sdonn if (v < pcb.pcb_p1lr) {
16752f00b088Sdonn error("address %x out of segment", addr);
16762f00b088Sdonn }
16772f00b088Sdonn r = (Address) (pcb.pcb_p1br + v);
16782f00b088Sdonn break;
16792f00b088Sdonn
16802f00b088Sdonn case 0x00000000:
16812f00b088Sdonn /*
16822f00b088Sdonn * In p0 space, must not be off end of region.
16832f00b088Sdonn */
16842f00b088Sdonn if (v >= pcb.pcb_p0lr) {
16852f00b088Sdonn error("address %x out of segment", addr);
16862f00b088Sdonn }
16872f00b088Sdonn r = (Address) (pcb.pcb_p0br + v);
16882f00b088Sdonn break;
16892f00b088Sdonn
16902f00b088Sdonn default:
16912f00b088Sdonn /* do nothing */
16922f00b088Sdonn break;
16932f00b088Sdonn }
16942f00b088Sdonn /*
16952f00b088Sdonn * For p0/p1 address, user-level page table should be in
16962f00b088Sdonn * kernel virtual memory. Do second-level indirect by recursing.
16972f00b088Sdonn */
16982f00b088Sdonn if ((r & 0x80000000) == 0) {
16992f00b088Sdonn error("bad p0br or p1br in pcb");
17002f00b088Sdonn }
17012f00b088Sdonn r = vmap(r);
17022f00b088Sdonn simple:
17032f00b088Sdonn /*
17042f00b088Sdonn * "r" is now the address of the pte of the page
17052f00b088Sdonn * we are interested in; get the pte and paste up the physical address.
17062f00b088Sdonn */
17072f00b088Sdonn fseek(corefile, r, 0);
17082f00b088Sdonn n = fread(&pte, sizeof(pte), 1, corefile);
17092f00b088Sdonn if (n != 1) {
17102f00b088Sdonn error("page table botch (fread at %x returns %d)", r, n);
17112f00b088Sdonn }
17122f00b088Sdonn if (pte.pg_v == 0 and (pte.pg_fod != 0 or pte.pg_pfnum == 0)) {
17132f00b088Sdonn error("page no valid or reclamable");
17142f00b088Sdonn }
17152f00b088Sdonn return (addr&PGOFSET) + ((Address) ptob(pte.pg_pfnum));
17162f00b088Sdonn }
17172f00b088Sdonn
17182f00b088Sdonn /*
17192f00b088Sdonn * Extract a bit field from an integer.
17202f00b088Sdonn */
17212f00b088Sdonn
extractField(s)17222f00b088Sdonn public integer extractField (s)
17232f00b088Sdonn Symbol s;
17242f00b088Sdonn {
17252f00b088Sdonn integer nbytes, nbits, n, r, off, len;
17262f00b088Sdonn
17272f00b088Sdonn off = s->symvalue.field.offset;
17282f00b088Sdonn len = s->symvalue.field.length;
17292f00b088Sdonn nbytes = size(s);
17302f00b088Sdonn n = 0;
17312f00b088Sdonn if (nbytes > sizeof(n)) {
17322f00b088Sdonn printf("[bad size in extractField -- word assumed]\n");
17332f00b088Sdonn nbytes = sizeof(n);
17342f00b088Sdonn }
17352f00b088Sdonn popn(nbytes, ((char *) &n) + (sizeof(Word) - nbytes));
17362f00b088Sdonn nbits = nbytes * BITSPERBYTE;
17372f00b088Sdonn r = n >> (nbits - ((off mod nbits) + len));
17382f00b088Sdonn r &= ((1 << len) - 1);
17392f00b088Sdonn return r;
17402f00b088Sdonn }
17412f00b088Sdonn
17422f00b088Sdonn /*
17432f00b088Sdonn * Change the length of a value in memory according to a given difference
17442f00b088Sdonn * in the lengths of its new and old types.
17452f00b088Sdonn */
17462f00b088Sdonn
loophole(oldlen,newlen)17472f00b088Sdonn public loophole (oldlen, newlen)
17482f00b088Sdonn integer oldlen, newlen;
17492f00b088Sdonn {
17502f00b088Sdonn integer i, n;
17512f00b088Sdonn Stack *oldsp;
17522f00b088Sdonn
17532f00b088Sdonn n = newlen - oldlen;
17542f00b088Sdonn oldsp = sp - oldlen;
17552f00b088Sdonn if (n > 0) {
17562f00b088Sdonn for (i = oldlen - 1; i >= 0; i--) {
17572f00b088Sdonn oldsp[n + i] = oldsp[i];
17582f00b088Sdonn }
17592f00b088Sdonn for (i = 0; i < n; i++) {
17602f00b088Sdonn oldsp[i] = '\0';
17612f00b088Sdonn }
17622f00b088Sdonn } else {
17632f00b088Sdonn for (i = 0; i < newlen; i++) {
17642f00b088Sdonn oldsp[i] = oldsp[i - n];
17652f00b088Sdonn }
17662f00b088Sdonn }
17672f00b088Sdonn sp += n;
17682f00b088Sdonn }
1769