📄 machine.c
字号:
private int printdisp(addr, nbytes, reg, mode)Address addr;int nbytes;char *reg;int mode;{ char byte; short hword; int argval; Symbol f; switch (nbytes) { case 1: iread(&byte, addr, sizeof(byte)); argval = byte; break; case 2: iread(&hword, addr, sizeof(hword)); argval = hword; break; case 4: iread(&argval, addr, sizeof(argval)); break; } if (reg == regname[PROGCTR] && mode >= BYTEDISP) { argval += addr + nbytes; } if (reg == regname[PROGCTR]) { f = whatblock((Address) argval + 2); if (codeloc(f) == argval + 2) { printf("%s", symname(f)); } else { printf("%x", argval); } } else { if (varIsSet("$hexoffsets")) { if (argval < 0) { printf("-%x(%s)", -(argval), reg); } else { printf("%x(%s)", argval, reg); } } else { printf("%d(%s)", argval, reg); } } return argval;}/* * Print the contents of the addresses within the given range * according to the given format. */typedef struct { String name; String printfstring; int length;} Format;private Format fmt[] = { { "d", " %d", sizeof(short) }, { "D", " %ld", sizeof(long) }, { "o", " %o", sizeof(short) }, { "O", " %lo", sizeof(long) }, { "x", " %04x", sizeof(short) }, { "X", " %08x", sizeof(long) }, { "b", " \\%o", sizeof(char) }, { "c", " '%c'", sizeof(char) }, { "s", "%c", sizeof(char) }, { "f", " %f", sizeof(float) }, { "g", " %g", sizeof(double) }, { "v", " (%ld,%ld)", 2 * sizeof(long) }, { "vx", " (0x%X,0x%X)", 2 * sizeof(long) }, { "vf", " (%f,%f)", sizeof(Vquad) }, { nil, nil, 0 }};private Format *findformat(s)String s;{ register Format *f; f = &fmt[0]; while (f->name != nil and not streq(f->name, s)) { ++f; } if (f->name == nil) { error("bad print format \"%s\"", s); } return f;}public Address printdata(lowaddr, highaddr, format)Address lowaddr;Address highaddr;String format;{ register int n; register Address addr; register Format *f; int value; if (lowaddr > highaddr) { error("first address larger than second"); } f = findformat(format); n = 0; value = 0; for (addr = lowaddr; addr <= highaddr; addr += f->length) { if (n == 0) { printf("%08x: ", addr); } if(streq(format, "vf")) { Vquad value; dread(&value, addr, f->length); printf("("); prtreal(value.val[0]); printf(","); prtreal(value.val[1]); printf(")"); } else { dread(&value, addr, f->length); if(streq(format, "g") || streq(format, "f")) { prtreal(value); } else { printf(f->printfstring, value); } } ++n; if (n >= (16 div f->length)) { putchar('\n'); n = 0; } } if (n != 0) { putchar('\n'); } prtaddr = addr; return addr;}/* * The other approach is to print n items starting with a given address. */public printndata(count, startaddr, format)int count;Address startaddr;String format;{ register int i, n; register Address addr; register Format *f; register Boolean isstring; char c; union { char charv; short shortv; int intv; float floatv; double doublev; } value; if (count <= 0) { error("non-positive repetition count"); } f = findformat(format); isstring = (Boolean) streq(f->name, "s"); n = 0; addr = startaddr; value.intv = 0; for (i = 0; i < count; i++) { if (n == 0) { printf("%08x: ", addr); } if (isstring) { putchar('"'); dread(&c, addr, sizeof(char)); while (c != '\0') { printchar(c); ++addr; dread(&c, addr, sizeof(char)); } putchar('"'); putchar('\n'); n = 0; addr += sizeof(String); } else { if(streq(format, "vf")) { Vquad value; dread(&value, addr, f->length); printf(" ("); prtreal(value.val[0]); printf(","); prtreal(value.val[1]); printf(")"); } else { value.doublev = 0.0; dread(&value, addr, f->length); if(streq(format, "g") || streq(format, "f")) { printf(" "); prtreal(value); }else { printf(f->printfstring, value); } } ++n; if (n >= (16 div f->length)) { putchar('\n'); n = 0; } addr += f->length; } } if (n != 0) { putchar('\n'); } prtaddr = addr;}/* * Print out a value according to the given format. */public printvalue(v, format)long v;String format;{ Format *f; char *p, *q; f = findformat(format); if (streq(f->name, "s")) { putchar('"'); p = (char *) &v; q = p + sizeof(v); while (p < q) { printchar(*p); ++p; } putchar('"'); } else { printf(f->printfstring, v); } putchar('\n');}/* * Print out an execution time error. * Assumes the source position of the error has been calculated. * * Have to check if the -r option was specified; if so then * the object file information hasn't been read in yet. */public printerror(){ extern Integer sys_nsig; extern String sys_siglist[]; integer err; if (isfinished(process)) { err = exitcode(process); if (err == 0) { printf("\"%s\" terminated normally\n", objname); } else { printf("\"%s\" terminated abnormally (exit code %d)\n", objname, err ); } erecover(); } if (runfirst) { fprintf(stderr, "Entering debugger ...\n"); init(); } err = errnum(process); putchar('\n'); printsig(err); putchar(' '); printloc(); putchar('\n'); if (curline > 0) { printlines(curline, curline); } else { printinst(pc, pc); } erecover();}/* * Print out a signal. */private String illinames[] = { "reserved addressing fault", "privileged instruction fault", "reserved operand fault"};private String fpenames[] = { nil, "integer overflow trap", "integer divide by zero trap", "floating overflow trap", "floating/decimal divide by zero trap", "floating underflow trap", "decimal overflow trap", "subscript out of range trap", "floating overflow fault", "floating divide by zero fault", "floating underflow fault"};public printsig (signo)integer signo;{ integer code; if (signo < 0 or signo > sys_nsig) { printf("[signal %d]", signo); } else { printf("%s", sys_siglist[signo]); } code = errcode(process); if (signo == SIGILL) { if (code >= 0 and code < sizeof(illinames) / sizeof(illinames[0])) { printf(" (%s)", illinames[code]); } } else if (signo == SIGFPE) { if (code > 0 and code < sizeof(fpenames) / sizeof(fpenames[0])) { printf(" (%s)", fpenames[code]); } }}/* * Merge bit field into old value (on top of expression stack). */public void depositField(value, s)long value;Symbol s;{ unsigned n; unsigned long offset; unsigned long length; offset = s->symvalue.field.offset mod 8; length = s->symvalue.field.length; n = pop(long); n = (n & ((1 << length) - 1)); n = (n << offset) | (value & ~( ((1 << length) - 1) << offset )); push(long, n);}/* * Note the termination of the program. We do this so as to avoid * having the process exit, which would make the values of variables * inaccessible. We do want to flush all output buffers here, * otherwise it'll never get done. */public endprogram(){ Integer exitcode; stepto(nextaddr(pc, true)); printnews(); exitcode = argn(1, nil); if (exitcode != 0) { printf("\nexecution completed (exit code %d)\n", exitcode); } else { printf("\nexecution completed\n"); } getsrcpos(); erecover();}/* * Single step the machine a source line (or instruction if "inst_tracing" * is true). If "isnext" is true, skip over procedure calls. */private Address getcall();public Boolean dostep(isnext, isvector)Boolean isnext, isvector;{ register Address addr; register Lineno line; String filename; Boolean ret = false; addr = nextaddr(pc, isnext); if(!(isvector && found_a_vec_inst)) { if (not inst_tracing and nlhdr.nlines != 0) { line = linelookup(addr); while (line == 0) { addr = nextaddr(addr, isnext); line = linelookup(addr); } curline = line; } else { curline = 0; }/* jlr005 * No need to check for one-line loops: since nextaddr() steps if there's * a jump, if addr==starting addr, there must have been a jump, and we're * already done. */ stepto(addr); } else { ret = true; } filename = srcfilename(addr); setsource(filename); return(ret);}/* * Compute the next address that will be executed from the given one. * If "isnext" is true then consider a procedure call as straight line code. * * We must unfortunately do much of the same work that is necessary * to print instructions. In addition we have to deal with branches. * Unconditional branches we just follow, for conditional branches * we continue execution to the current location and then single step * the machine. We assume that the last argument in an instruction * that branches is the branch address (or relative offset). */private Address findnextaddr();public Address nextaddr(startaddr, isnext)Address startaddr;boolean isnext;{ Address addr; addr = usignal(process); if (addr == 0 or addr == 1) { addr = findnextaddr(startaddr, isnext); } return addr;}/* * Determine if it's ok to skip function f entered by instruction ins. * If so, we're going to compute the return address and step to it. * Therefore we cannot skip over a function entered by a jsb or bsb, * since the return address is not easily computed for them. */private boolean skipfunc (ins, f)VaxOpcode ins;Symbol f;{ boolean b; b = (boolean) ( ins != O_JSB and ins != O_BSBB and ins != O_BSBW and not inst_tracing and nlhdr.nlines != 0 and nosource(curfunc) and canskip(curfunc) ); return b;}private Address findnextaddr(startaddr, isnext)Address startaddr;Boolean isnext;{ register Address addr; Optab op; VaxOpcode ins, ins2; unsigned char mode;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -