📄 kadb.c
字号:
default: kdbprintf("\t%s,%s,%s", reg_name[i.RType.rd], reg_name[i.RType.rs], reg_name[i.RType.rt]); }; break; case OP_BCOND: kdbprintf("%s\t%s,", bcond_name[i.IType.rt], reg_name[i.IType.rs]); goto pr_displ; case OP_BLEZ: case OP_BGTZ: kdbprintf("%s\t%s,", op_name[i.IType.op], reg_name[i.IType.rs]); goto pr_displ; case OP_BEQ: if (i.IType.rs == 0 && i.IType.rt == 0) { kdbprintf("b\t"); goto pr_displ; } /* FALLTHROUGH */ case OP_BNE: kdbprintf("%s\t%s,%s,", op_name[i.IType.op], reg_name[i.IType.rs], reg_name[i.IType.rt]); pr_displ: kdbpsymoff(kdbdot + 4 + ((short)i.IType.imm << 2), ISYM, ""); break; case OP_COP0: switch (i.RType.rs) { case OP_BCx: case OP_BCy: kdbprintf("bc0%c\t", "ft"[i.RType.rt & COPz_BC_TF_MASK]); goto pr_displ; case OP_MT: kdbprintf("mtc0\t%s,%s", reg_name[i.RType.rt], c0_reg[i.RType.rd]); break; case OP_MF: kdbprintf("mfc0\t%s,%s", reg_name[i.RType.rt], c0_reg[i.RType.rd]); break; default: kdbprintf("%s", c0_opname[i.FRType.func]); }; break; case OP_COP1: switch (i.RType.rs) { case OP_BCx: case OP_BCy: kdbprintf("bc1%c\t", "ft"[i.RType.rt & COPz_BC_TF_MASK]); goto pr_displ; case OP_MT: kdbprintf("mtc1\t%s,f%d", reg_name[i.RType.rt], i.RType.rd); break; case OP_MF: kdbprintf("mfc1\t%s,f%d", reg_name[i.RType.rt], i.RType.rd); break; case OP_CT: kdbprintf("ctc1\t%s,f%d", reg_name[i.RType.rt], i.RType.rd); break; case OP_CF: kdbprintf("cfc1\t%s,f%d", reg_name[i.RType.rt], i.RType.rd); break; default: kdbprintf("%s.%s\tf%d,f%d,f%d", cop1_name[i.FRType.func], fmt_name[i.FRType.fmt], i.FRType.fd, i.FRType.fs, i.FRType.ft); }; break; case OP_J: case OP_JAL: kdbprintf("%s\t", op_name[i.JType.op]); kdbpsymoff((kdbdot & 0xF0000000) | (i.JType.target << 2), ISYM, ""); break; case OP_LWC1: case OP_SWC1: kdbprintf("%s\tf%d,", op_name[i.IType.op], i.IType.rt); goto loadstore; case OP_LB: case OP_LH: case OP_LW: case OP_LBU: case OP_LHU: case OP_SB: case OP_SH: case OP_SW: kdbprintf("%s\t%s,", op_name[i.IType.op], reg_name[i.IType.rt]); loadstore: kdbprintf("%d(%s)", (short)i.IType.imm, reg_name[i.IType.rs]); break; case OP_ORI: case OP_XORI: if (i.IType.rs == 0) { kdbprintf("li\t%s,0x%X", reg_name[i.IType.rt], i.IType.imm); break; } /* FALLTHROUGH */ case OP_ANDI: kdbprintf("%s\t%s,%s,0x%X", op_name[i.IType.op], reg_name[i.IType.rt], reg_name[i.IType.rs], i.IType.imm); break; case OP_LUI: kdbprintf("%s\t%s,0x%X", op_name[i.IType.op], reg_name[i.IType.rt], i.IType.imm); break; case OP_ADDI: case OP_ADDIU: if (i.IType.rs == 0) { kdbprintf("li\t%s,%D", reg_name[i.IType.rt], (short)i.IType.imm); break; } /* FALLTHROUGH */ default: kdbprintf("%s\t%s,%s,%D", op_name[i.IType.op], reg_name[i.IType.rt], reg_name[i.IType.rs], (short)i.IType.imm); } kdbdotinc = 4;}#define MIPS_JR_RA 0x03e00008 /* instruction code for jr ra *//* * Print a stack backtrace. */voidkdbstacktrace(printlocals) int printlocals;{ unsigned pc, sp, ra, va, subr; int a0, a1, a2, a3; unsigned instr, mask; InstFmt i; int more, stksize; extern MachKernGenException(); extern MachUserGenException(); extern MachKernIntr(); extern MachUserIntr(); extern setsoftclock(); /* get initial values from the exception frame */ sp = kdbpcb.pcb_regs[SP]; pc = kdbpcb.pcb_regs[PC]; ra = kdbpcb.pcb_regs[RA]; a0 = kdbpcb.pcb_regs[A0]; a1 = kdbpcb.pcb_regs[A1]; a2 = kdbpcb.pcb_regs[A2]; a3 = kdbpcb.pcb_regs[A3];loop: /* check for current PC in the kernel interrupt handler code */ if (pc >= (unsigned)MachKernIntr && pc < (unsigned)MachUserIntr) { /* NOTE: the offsets depend on the code in locore.s */ kdbprintf("interupt\n"); a0 = kdbchkget(sp + 36, DSP); a1 = kdbchkget(sp + 40, DSP); a2 = kdbchkget(sp + 44, DSP); a3 = kdbchkget(sp + 48, DSP); pc = kdbchkget(sp + 20, DSP); ra = kdbchkget(sp + 92, DSP); sp = kdbchkget(sp + 100, DSP); } /* check for current PC in the exception handler code */ if (pc >= 0x80000000 && pc < (unsigned)setsoftclock) { ra = 0; subr = 0; goto done; } /* * Find the beginning of the current subroutine by scanning backwards * from the current PC for the end of the previous subroutine. */ va = pc - sizeof(int); while ((instr = kdbchkget(va, ISP)) != MIPS_JR_RA) va -= sizeof(int); va += 2 * sizeof(int); /* skip back over branch & delay slot */ /* skip over nulls which might separate .o files */ while ((instr = kdbchkget(va, ISP)) == 0) va += sizeof(int); subr = va; /* scan forwards to find stack size and any saved registers */ stksize = 0; more = 3; mask = 0; for (; more; va += sizeof(int), more = (more == 3) ? 3 : more - 1) { /* stop if hit our current position */ if (va >= pc) break; instr = kdbchkget(va, ISP); i.word = instr; switch (i.JType.op) { case OP_SPECIAL: switch (i.RType.func) { case OP_JR: case OP_JALR: more = 2; /* stop after next instruction */ break; case OP_SYSCALL: case OP_BREAK: more = 1; /* stop now */ }; break; case OP_BCOND: case OP_J: case OP_JAL: case OP_BEQ: case OP_BNE: case OP_BLEZ: case OP_BGTZ: more = 2; /* stop after next instruction */ break; case OP_COP0: case OP_COP1: case OP_COP2: case OP_COP3: switch (i.RType.rs) { case OP_BCx: case OP_BCy: more = 2; /* stop after next instruction */ }; break; case OP_SW: /* look for saved registers on the stack */ if (i.IType.rs != 29) break; /* only restore the first one */ if (mask & (1 << i.IType.rt)) break; mask |= 1 << i.IType.rt; switch (i.IType.rt) { case 4: /* a0 */ a0 = kdbchkget(sp + (short)i.IType.imm, DSP); break; case 5: /* a1 */ a1 = kdbchkget(sp + (short)i.IType.imm, DSP); break; case 6: /* a2 */ a2 = kdbchkget(sp + (short)i.IType.imm, DSP); break; case 7: /* a3 */ a3 = kdbchkget(sp + (short)i.IType.imm, DSP); break; case 31: /* ra */ ra = kdbchkget(sp + (short)i.IType.imm, DSP); } break; case OP_ADDI: case OP_ADDIU: /* look for stack pointer adjustment */ if (i.IType.rs != 29 && i.IType.rt != 29) break; stksize = (short)i.IType.imm; } }done:#if 0 kdbpsymoff((long)pc, ISYM, "");#else kdbprintf("%X+%X ", subr, pc - subr); /* XXX */#endif kdbprintf("(%X,%X,%X,%X)\n", a0, a1, a2, a3); if (ra) { pc = ra; sp -= stksize; goto loop; }}/* * Very simple memory allocator for kdb. */char *kdbmalloc(size) int size;{ static char buffer[4096]; static char *bufp = buffer; char *p; /* round size up to sizeof(int) */ size = (size + sizeof(int) - 1) & ~(sizeof(int) - 1); p = bufp; bufp = p + size; return (p);}/* * Machine dependent printing '$'. * Return zero if modif character not recognized. */kdbprintmachdep(modif){ register int i, j; extern int tlbhi, tlblo; switch (modif) { case 'p': case 'P': /* print TLB entries */ if (kdbadrflg) { i = kdbadrval; if (i < 0 || i > VMMACH_NUM_TLB_ENTRIES) { extern char *kdbBADMOD; kdberror(kdbBADMOD); break; } if (kdbcntflg == 0) j = i + 1; else { j = i + kdbcntval; if (j > VMMACH_NUM_TLB_ENTRIES) j = VMMACH_NUM_TLB_ENTRIES; } } else { i = 0; j = VMMACH_NUM_TLB_ENTRIES; } for (; i < j; i++) { MachTLBRead(i); if (modif == 'p' && !(tlblo & PG_V)) continue; kdbprintf("TLB %2d: hi %8X low %8X\n", i, tlbhi, tlblo); } kdbprintf("TLB PID %x\n", MachTLBGetPID()); break; case 'f': /* find a TLB entry by virtaddr */ case 'F': /* find a TLB entry by physaddr */ j = kdbdot & PG_FRAME; for (i = 0; i < VMMACH_NUM_TLB_ENTRIES; i++) { MachTLBRead(i); if (modif == 'f') { if ((tlbhi & PG_FRAME) != j) continue; } else { if ((tlblo & PG_FRAME) != j) continue; } kdbprintf("TLB %2d: hi %8X low %8X\n", i, tlbhi, tlblo); } break; default: return (0); } return (1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -