📄 sun.c
字号:
} break; } if (printing) { printf("\t%s",opcode); } printEA(inst); if (following and followcalls) { steppast(startingaddr); curfunc = whatblock(pc, true); if (not isbperr()) { printstatus(); /* NOTREACHED */ } bpact(); if (nosource(curfunc) and canskip(curfunc) and nlhdr.nlines != 0) { stepto(retaddr); instaddr = pc; bpact(); } else { callnews(/* iscall = */ true); } }}public jmpop(inst, opcode)long inst;register String opcode;{ Address startingaddr; /* beginning of jump instruction */ startingaddr = instaddr - 2; if (printing) { printf("\t%s",opcode); } printEA(inst); if (following) { steppast(startingaddr); }}public pregmask(mask)register int mask;{ register int i; register int flag = 0; if (printing) { printf("#<"); for (i=0; i<16; i++) { if (mask&1) { if (flag) { printf(","); } else { ++flag; } printf("%c%d",(i<8) ? 'd' : 'a', i&07); } mask >>= 1; } printf(">"); }}public omovem(inst, dummy)long inst;long dummy;{ register int i, list, mask; register int reglist; short w; i = 0; list = 0; mask = 0100000; instread(w); reglist = w; if ((inst & 070) == 040) { /* predecrement */ for (i = 15; i > 0; i -= 2) { list |= ((mask & reglist) >> i); mask >>= 1; } for (i = 1; i < 16; i += 2) { list |= ((mask & reglist) << i); mask >>= 1; } reglist = list; } if (printing) { printf("\tmovem%c\t",(inst&100)?'l':'w'); } if (inst&02000) { printEA(inst); if (printing) { printf(","); } pregmask(reglist); } else { pregmask(reglist); if (printing) { printf(","); } printEA(inst); }}public ochk(inst, opcode)long inst;register String opcode;{ if (printing) { printf("\t%s\t", opcode); } printEA(inst, sizeof(Byte)); if (printing) { printf(",%c%D", (opcode[0] == 'l') ? 'a' : 'd', (inst>>9)&07); }}public soneop(inst, opcode)long inst;register String opcode;{ register int size; size = mapsize(inst); if (size > 0) { if (printing) { printf("\t%s%c\t", opcode, suffix(size)); } printEA(inst); } else { if (printing) { printf("\tbadop"); } }}public oquick(inst, opcode)long inst;register String opcode;{ register int size; register int data; size = mapsize(inst); data = (int)((inst>>9) & 07); if (data == 0) { data = 8; } if (size > 0) { if (printing) { printf("\t%s%c\t", opcode, suffix(size)); printf(IMDF, data); printf(","); } printEA(inst); } else { if (printing) { printf("\tbadop"); } }}public omoveq(inst, dummy)long inst;long dummy;{ register int data; if (printing) { data = (int)(inst & 0377); if (data > 127) { data |= ~0377; } printf("\tmoveq\t"); printf(IMDF, data); printf(",d%D", (inst>>9)&07); }}public oprint(inst, opcode)long inst;register String opcode;{ if (printing) { printf("\t%s",opcode); }}public ostop(inst, opcode)long inst;register String opcode;{ short w; instread(w); if (printing) { printf(opcode, w); }}public orts(inst, opcode)long inst;register String opcode;{ Address addr; if (following) { callnews(/* iscall = */ false); if (inst_tracing) { addr = currtnaddr(); } else { addr = return_addr(); if (addr == 0) { stepto(instaddr - 2); addr = currtnaddr(); } } stepto(addr); instaddr = pc; } if (printing) { printf("\t%s",opcode); }}/* * Not used by C compiler; does an rts but before doing so, pops * arg bytes from the stack. */public ortspop(inst, opcode)long inst;register String opcode;{ Address addr; short w; instread(w); if (following) { callnews(/* iscall = */ false); if (inst_tracing) { addr = currtnaddr(); } else { addr = return_addr(); } stepto(addr); instaddr = pc; } if (printing) { printf(opcode, w); }}public omovs(inst, opcode)long inst;String opcode;{ register int size; register unsigned int controlword; short w; size = mapsize(inst); instread(w); controlword = w >> 11; if (printing) { printf("\t%s%c\t", opcode, suffix(size)); } if (controlword & 1){ controlword >>= 1; if (printing) { printf((controlword&0x8) ? "a%D," : "d%D,", controlword&7 ); } printEA(inst&0xff, size); } else { controlword >>= 1; printEA(inst&0xff, size); if (printing) { printf((controlword&0x8) ? ",a%D" : ",d%D", controlword&7); } }}public omovc(inst, opcode)long inst;String opcode;{ register unsigned int controlword; String creg; short w; instread(w); if (printing) { controlword = w; switch (controlword & 0xfff) { case 0: creg = "sfc"; break; case 1: creg = "dfc"; break; case 0x800: creg = "usp"; break; case 0x801: creg = "vbr"; break; default: creg = "???"; break; } controlword >>= 12; if (inst & 1){ printf((controlword&0x8) ? "%sa%D,%s" : "%sd%D,%s", opcode, controlword&7, creg ); } else { printf((controlword&0x8) ? "%s%s,a%D" : "%s%s,d%D", opcode, creg, controlword&7 ); } }}/* * 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. * * Unconditional branches we just follow, for conditional branches * we continue execution to the current location and then single step * the machine. */public Address nextaddr(startaddr, isnext)Address startaddr;Boolean isnext;{ Optab *o; short inst; instaddr = usignal(process); if (instaddr == 0 or instaddr == 1) { following = true; followcalls = (Boolean) (not isnext); printing = false; iread(&inst, startaddr, sizeof(inst)); instaddr = startaddr + sizeof(inst); o = decode(inst, startaddr); if (o->mask == 0) { fprintf(stderr, "[internal error: undecodable op at 0x%x]\n", startaddr); fflush(stderr); } else { (*o->opfun)(inst, o->farg); } following = false; } return instaddr;}/* * Step to the given address and then execute one instruction past it. * Set instaddr to the new instruction address. */private steppast(addr)Address addr;{ stepto(addr); pstep(process, DEFSIG); pc = reg(PROGCTR); instaddr = pc;}/* * Enter a procedure by creating and executing a call instruction. */#define CALLSIZE 6 /* size of call instruction */public beginproc(p)Symbol p;{ char save[CALLSIZE]; struct { short op; char addr[sizeof(long)]; /* unaligned long */ } call; long dest; pc = CODESTART + 6; iread(save, pc, sizeof(save)); call.op = 0x4eb9; /* jsr */ dest = codeloc(p) - FUNCOFFSET; 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(); } /* * Execute link instruction so the return addr is visible. */ pstep(process, DEFSIG); 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 );# ifdef sun for (i = 0; i < 14; i++) { setreg(i, pcb.pcb_regs.val[i]); }# else /* IRIS */ for (i = 0; i < 14; i++) { setreg(i, pcb.pcb_regs[i]); }# endif}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[AR0]; reg[9] = savreg[AR1]; reg[10] = savreg[AR2]; reg[11] = savreg[AR3]; reg[12] = savreg[AR4]; reg[13] = savreg[AR5]; reg[14] = savreg[AR6]; reg[15] = savreg[AR7]; reg[PROGCTR] = savreg[PC];}/* * Map a virtual address to a physical address. * XXX THIS CAN'T BE RIGHT... XXX */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 nbytes, nbits, n, r, off, len; off = s->symvalue.field.offset; len = s->symvalue.field.length; nbytes = size(s); n = 0; if (nbytes > sizeof(n)) { printf("[bad size in extractField -- word assumed]\n"); nbytes = sizeof(n); } popn(nbytes, ((char *) &n) + (sizeof(Word) - nbytes)); nbits = nbytes * BITSPERBYTE; r = n >> (nbits - ((off mod nbits) + len)); r &= ((1 << len) - 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 i, n; Stack *oldsp; n = newlen - oldlen; oldsp = sp - oldlen; if (n > 0) { for (i = oldlen - 1; i >= 0; i--) { oldsp[n + i] = oldsp[i]; } for (i = 0; i < n; i++) { oldsp[i] = '\0'; } } else { for (i = 0; i < newlen; i++) { oldsp[i] = oldsp[i - n]; } } sp += n;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -