📄 vax.c
字号:
printf("%g", *(float *)&argval); } addr += 4; break; case TYPD: /* XXX this bags the low order bits */ iread(&argval, addr, sizeof(argval)); if ((argval & 0xffff007f) == 0x8000) { printf("[reserved operand]"); } else { printf("%g", *(float *)&argval); } addr += 8; break; case TYPG: case TYPQ: iread(&argval, addr+4, sizeof(argval)); printf("%08x", argval); iread(&argval, addr, sizeof(argval)); printf("%08x", argval); addr += 8; break; case TYPH: case TYPO: iread(&argval, addr+12, sizeof(argval)); printf("%08x", argval); iread(&argval, addr+8, sizeof(argval)); printf("%08x", argval); iread(&argval, addr+4, sizeof(argval)); printf("%08x", argval); iread(&argval, addr, sizeof(argval)); printf("%08x", argval); addr += 16; break; } } break; case AUTOINCDEF: if (reg == regname[PROGCTR]) { printf("*$"); argval = printdisp(addr, 4, reg, amode); addr += 4; } else { printf("*(%s)+", reg); } break; case BYTEDISP: argval = printdisp(addr, 1, reg, amode); addr += 1; break; case BYTEDISPDEF: printf("*"); argval = printdisp(addr, 1, reg, amode); addr += 1; break; case WORDDISP: argval = printdisp(addr, 2, reg, amode); addr += 2; break; case WORDDISPDEF: printf("*"); argval = printdisp(addr, 2, reg, amode); addr += 2; break; case LONGDISP: argval = printdisp(addr, 4, reg, amode); addr += 4; break; case LONGDISPDEF: printf("*"); argval = printdisp(addr, 4, reg, amode); addr += 4; break; } } if (ins == O_CASEB || ins == O_CASEW || ins == O_CASEL) { for (argno = 0; argno <= argval; argno++) { iread(&offset, addr, sizeof(offset)); printf("\n\t\t%d", offset); addr += 2; } } printf("\n"); return addr;}/* * Print the displacement of an instruction that uses displacement * addressing. */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;}/* * 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; register Optab *op; VaxOpcode ins, ins2; unsigned char mode; int argtype, amode, argno, argval; String r; Boolean indexf; enum { KNOWN, SEQUENTIAL, BRANCH } addrstatus; argval = 0; indexf = false; addr = startaddr; iread(&ins, addr, sizeof(ins)); switch (ins) { /* * It used to be that unconditional jumps and branches were handled * by taking their destination address as the next address. While * saving the cost of starting up the process, this approach * doesn't work when jumping indirect (since the value in the * register might not yet have been set). * * So unconditional jumps and branches are now handled the same way * as conditional jumps and branches. * case O_BRB: case O_BRW: addrstatus = BRANCH; break; * */ case O_BSBB: case O_BSBW: case O_JSB: case O_CALLG: case O_CALLS: addrstatus = KNOWN; stepto(addr); pstep(process, DEFSIG); addr = reg(PROGCTR); pc = addr; setcurfunc(whatblock(pc)); if (not isbperr()) { printstatus(); /* NOTREACHED */ } bpact(); if (isnext or skipfunc(ins, curfunc)) { addrstatus = KNOWN; addr = return_addr(); stepto(addr); bpact(); } else { callnews(/* iscall = */ true); } break; case O_RSB: case O_RET: addrstatus = KNOWN; stepto(addr); callnews(/* iscall = */ false); pstep(process, DEFSIG); addr = reg(PROGCTR); pc = addr; if (not isbperr()) { printstatus(); } bpact(); break; case O_BRB: case O_BRW: case O_JMP: /* because it may be jmp (r1) */ case O_BNEQ: case O_BEQL: case O_BGTR: case O_BLEQ: case O_BGEQ: case O_BLSS: case O_BGTRU: case O_BLEQU: case O_BVC: case O_BVS: case O_BCC: case O_BCS: case O_CASEB: case O_CASEW: case O_CASEL: case O_BBS: case O_BBC: case O_BBSS: case O_BBCS: case O_BBSC: case O_BBCC: case O_BBSSI: case O_BBCCI: case O_BLBS: case O_BLBC: case O_ACBL: case O_AOBLSS: case O_AOBLEQ: case O_SOBGEQ: case O_SOBGTR: case O_ESCF: /* bugchecks */ branches: addrstatus = KNOWN; stepto(addr); pstep(process, DEFSIG); addr = reg(PROGCTR); pc = addr; if (not isbperr()) { printstatus(); } break; case O_ESCD: iread(&ins2, addr+1, sizeof(ins2)); if (ins2 == O_ACBF || ins2 == O_ACBD) /* actually ACBG and ACBH */ goto branches; /* fall through */ default: addrstatus = SEQUENTIAL; break; } if (addrstatus != KNOWN) { addr += 1; if (ins == O_ESCD) { ins = ins2; addr += 1; op = esctab[ins]; if (op == nil) { printf("[bad extended opcode %#x in findnextaddr]\n", ins); return addr; } } else { op = ioptab[ins]; if (op == nil) { printf("[bad opcode %#x in findnextaddr]\n", ins); return addr; } } for (argno = 0; argno < op->numargs; argno++) { if (indexf == true) { indexf = false; } argtype = op->argtype[argno]; if (is_branch_disp(argtype)) { mode = 0xAF + (typelen(argtype) << 5); } else { iread(&mode, addr, sizeof(mode)); addr += 1; } r = regname[regnm(mode)]; amode = addrmode(mode); switch (amode) { case LITSHORT: case LITUPTO31: case LITUPTO47: case LITUPTO63: argval = mode; break; case INDEX: indexf = true; --argno; break; case REG: case REGDEF: case AUTODEC: break; case AUTOINC: if (r == regname[PROGCTR]) { switch (typelen(argtype)) { case TYPB: argval = getdisp(addr, 1, r, amode); addr += 1; break; case TYPW: argval = getdisp(addr, 2, r, amode); addr += 2; break; case TYPL: argval = getdisp(addr, 4, r, amode); addr += 4; break; case TYPF: iread(&argval, addr, sizeof(argval)); addr += 4; break; case TYPQ: case TYPD: case TYPG: iread(&argval, addr+4, sizeof(argval)); addr += 8; break; case TYPO: case TYPH: iread(&argval, addr+12, sizeof(argval)); addr += 16; break; } } break; case AUTOINCDEF: if (r == regname[PROGCTR]) { argval = getdisp(addr, 4, r, amode); addr += 4; } break; case BYTEDISP: case BYTEDISPDEF: argval = getdisp(addr, 1, r, amode); addr += 1; break; case WORDDISP: case WORDDISPDEF: argval = getdisp(addr, 2, r, amode); addr += 2; break; case LONGDISP: case LONGDISPDEF: argval = getdisp(addr, 4, r, amode); addr += 4; break; } } if (ins == O_CALLS or ins == O_CALLG) { argval += 2; } if (addrstatus == BRANCH) { addr = argval; } } return addr;}/* * Get the displacement of an instruction that uses displacement addressing. */private int getdisp(addr, nbytes, reg, mode)Address addr;int nbytes;String reg;int mode;{ char byte; short hword; int argval; 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; } return argval;}/* * Enter a procedure by creating and executing a call instruction. */#define CALLSIZE 7 /* size of call instruction */public beginproc(p, argc)Symbol p;Integer argc;{ char save[CALLSIZE]; struct { VaxOpcode op; unsigned char numargs; unsigned char mode; char addr[sizeof(long)]; /* unaligned long */ } call; long dest; pc = 2; iread(save, pc, sizeof(save)); call.op = O_CALLS; call.numargs = argc; call.mode = 0xef; dest = codeloc(p) - 2 - (pc + 7); mov(&dest, call.addr, sizeof(call.addr)); iwrite(&call, pc, sizeof(call)); setreg(PROGCTR, pc); pstep(process, DEFSIG); iwrite(save, pc, sizeof(save)); pc = reg(PROGCTR); if (not isbperr()) { printstatus(); }}/* * Special variables for debugging the kernel. */public integer masterpcbb;public integer slr;public struct pte *sbr;private struct pcb pcb;public getpcb (){ integer i; fseek(corefile, masterpcbb & ~0x80000000, 0); get(corefile, pcb); pcb.pcb_p0lr &= ~AST_CLR; printf("p0br %lx p0lr %lx p1br %lx p1lr %lx\n", pcb.pcb_p0br, pcb.pcb_p0lr, pcb.pcb_p1br, pcb.pcb_p1lr ); setreg(0, pcb.pcb_r0); setreg(1, pcb.pcb_r1); setreg(2, pcb.pcb_r2); setreg(3, pcb.pcb_r3); setreg(4, pcb.pcb_r4); setreg(5, pcb.pcb_r5); setreg(6, pcb.pcb_r6); setreg(7, pcb.pcb_r7); setreg(8, pcb.pcb_r8); setreg(9, pcb.pcb_r9); setreg(10, pcb.pcb_r10); setreg(11, pcb.pcb_r11); setreg(ARGP, pcb.pcb_ap); setreg(FRP, pcb.pcb_fp); setreg(STKP, pcb.pcb_ksp); setreg(PROGCTR, pcb.pcb_pc);}public copyregs (savreg, reg)Word savreg[], reg[];{ reg[0] = savreg[R0]; reg[1] = savreg[R1]; reg[2] = savreg[R2]; reg[3] = savreg[R3]; reg[4] = savreg[R4]; reg[5] = savreg[R5]; reg[6] = savreg[R6]; reg[7] = savreg[R7]; reg[8] = savreg[R8]; reg[9] = savreg[R9]; reg[10] = savreg[R10]; reg[11] = savreg[R11]; reg[ARGP] = savreg[AP]; reg[FRP] = savreg[FP]; reg[STKP] = savreg[SP]; reg[PROGCTR] = savreg[PC];}/* * Map a virtual address to a physical address. */public Address vmap (addr)Address addr;{ Address r; integer v, n; struct pte pte; r = addr & ~0xc0000000; v = btop(r); switch (addr&0xc0000000) { case 0xc0000000: case 0x80000000: /* * In system space, so get system pte. * If it is valid or reclaimable then the physical address * is the combination of its page number and the page offset * of the original address. */ if (v >= slr) { error("address %x out of segment", addr); } r = ((long) (sbr + v)) & ~0x80000000; goto simple; case 0x40000000: /* * In p1 space, must not be in shadow region. */ if (v < pcb.pcb_p1lr) { error("address %x out of segment", addr); } r = (Address) (pcb.pcb_p1br + v); break; case 0x00000000: /* * In p0 space, must not be off end of region. */ if (v >= pcb.pcb_p0lr) { error("address %x out of segment", addr); } r = (Address) (pcb.pcb_p0br + v); break; default: /* do nothing */ break; } /* * For p0/p1 address, user-level page table should be in * kernel virtual memory. Do second-level indirect by recursing. */ if ((r & 0x80000000) == 0) { error("bad p0br or p1br in pcb"); } r = vmap(r);simple: /* * "r" is now the address of the pte of the page * we are interested in; get the pte and paste up the physical address. */ fseek(corefile, r, 0); n = fread(&pte, sizeof(pte), 1, corefile); if (n != 1) { error("page table botch (fread at %x returns %d)", r, n); } if (pte.pg_v == 0 and (pte.pg_fod != 0 or pte.pg_pfnum == 0)) { error("page no valid or reclamable"); } return (addr&PGOFSET) + ((Address) ptob(pte.pg_pfnum));}/* * Extract a bit field from an integer. */public integer extractField (s)Symbol s;{ integer n, nbytes, r; n = 0; nbytes = size(s); if (nbytes > sizeof(n)) { printf("[bad size in extractField -- word assumed]\n"); nbytes = sizeof(n); } popn(nbytes, &n); r = n >> (s->symvalue.field.offset mod BITSPERBYTE); r &= ((1 << s->symvalue.field.length) - 1); return r;}/* * Change the length of a value in memory according to a given difference * in the lengths of its new and old types. */public loophole (oldlen, newlen)integer oldlen, newlen;{ integer n, i; n = newlen - oldlen; if (n > 0) { for (i = 0; i < n; i++) { sp[i] = '\0'; } } sp += n;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -