📄 xmon.c
字号:
xmon_print_symbol(ip, " ", "\n"); } /* Look for "regshere" marker to see if this is an exception frame. */ if (mread(sp + MARKER_OFFSET, &marker, sizeof(unsigned long)) && marker == REG_FRAME_MARKER) { if (mread(sp + REGS_OFFSET, ®s, sizeof(regs)) != sizeof(regs)) { printf("Couldn't read registers at %lx\n", sp + REGS_OFFSET); break; } printf("--- Exception: %lx %s at ", regs.trap, getvecname(TRAP(®s))); pc = regs.nip; lr = regs.link; xmon_print_symbol(pc, " ", "\n"); } if (newsp == 0) break; sp = newsp; } while (count++ < xmon_depth_to_print);}static void backtrace(struct pt_regs *excp){ unsigned long sp; if (scanhex(&sp)) xmon_show_stack(sp, 0, 0); else xmon_show_stack(excp->gpr[1], excp->link, excp->nip); scannl();}static void print_bug_trap(struct pt_regs *regs){ struct bug_entry *bug; unsigned long addr; if (regs->msr & MSR_PR) return; /* not in kernel */ addr = regs->nip; /* address of trap instruction */ if (addr < PAGE_OFFSET) return; bug = find_bug(regs->nip); if (bug == NULL) return; if (bug->line & BUG_WARNING_TRAP) return; printf("kernel BUG in %s at %s:%d!\n", bug->function, bug->file, (unsigned int)bug->line);}void excprint(struct pt_regs *fp){ unsigned long trap;#ifdef CONFIG_SMP printf("cpu 0x%x: ", smp_processor_id());#endif /* CONFIG_SMP */ trap = TRAP(fp); printf("Vector: %lx %s at [%lx]\n", fp->trap, getvecname(trap), fp); printf(" pc: "); xmon_print_symbol(fp->nip, ": ", "\n"); printf(" lr: ", fp->link); xmon_print_symbol(fp->link, ": ", "\n"); printf(" sp: %lx\n", fp->gpr[1]); printf(" msr: %lx\n", fp->msr); if (trap == 0x300 || trap == 0x380 || trap == 0x600) { printf(" dar: %lx\n", fp->dar); if (trap != 0x380) printf(" dsisr: %lx\n", fp->dsisr); } printf(" current = 0x%lx\n", current);#ifdef CONFIG_PPC64 printf(" paca = 0x%lx\n", get_paca());#endif if (current) { printf(" pid = %ld, comm = %s\n", current->pid, current->comm); } if (trap == 0x700) print_bug_trap(fp);}void prregs(struct pt_regs *fp){ int n, trap; unsigned long base; struct pt_regs regs; if (scanhex(&base)) { if (setjmp(bus_error_jmp) == 0) { catch_memory_errors = 1; sync(); regs = *(struct pt_regs *)base; sync(); __delay(200); } else { catch_memory_errors = 0; printf("*** Error reading registers from "REG"\n", base); return; } catch_memory_errors = 0; fp = ®s; }#ifdef CONFIG_PPC64 if (FULL_REGS(fp)) { for (n = 0; n < 16; ++n) printf("R%.2ld = "REG" R%.2ld = "REG"\n", n, fp->gpr[n], n+16, fp->gpr[n+16]); } else { for (n = 0; n < 7; ++n) printf("R%.2ld = "REG" R%.2ld = "REG"\n", n, fp->gpr[n], n+7, fp->gpr[n+7]); }#else for (n = 0; n < 32; ++n) { printf("R%.2d = %.8x%s", n, fp->gpr[n], (n & 3) == 3? "\n": " "); if (n == 12 && !FULL_REGS(fp)) { printf("\n"); break; } }#endif printf("pc = "); xmon_print_symbol(fp->nip, " ", "\n"); printf("lr = "); xmon_print_symbol(fp->link, " ", "\n"); printf("msr = "REG" cr = %.8lx\n", fp->msr, fp->ccr); printf("ctr = "REG" xer = "REG" trap = %4lx\n", fp->ctr, fp->xer, fp->trap); trap = TRAP(fp); if (trap == 0x300 || trap == 0x380 || trap == 0x600) printf("dar = "REG" dsisr = %.8lx\n", fp->dar, fp->dsisr);}void cacheflush(void){ int cmd; unsigned long nflush; cmd = inchar(); if (cmd != 'i') termch = cmd; scanhex((void *)&adrs); if (termch != '\n') termch = 0; nflush = 1; scanhex(&nflush); nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES; if (setjmp(bus_error_jmp) == 0) { catch_memory_errors = 1; sync(); if (cmd != 'i') { for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES) cflush((void *) adrs); } else { for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES) cinval((void *) adrs); } sync(); /* wait a little while to see if we get a machine check */ __delay(200); } catch_memory_errors = 0;}unsigned longread_spr(int n){ unsigned int instrs[2]; unsigned long (*code)(void); unsigned long ret = -1UL;#ifdef CONFIG_PPC64 unsigned long opd[3]; opd[0] = (unsigned long)instrs; opd[1] = 0; opd[2] = 0; code = (unsigned long (*)(void)) opd;#else code = (unsigned long (*)(void)) instrs;#endif /* mfspr r3,n; blr */ instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6); instrs[1] = 0x4e800020; store_inst(instrs); store_inst(instrs+1); if (setjmp(bus_error_jmp) == 0) { catch_memory_errors = 1; sync(); ret = code(); sync(); /* wait a little while to see if we get a machine check */ __delay(200); n = size; } return ret;}voidwrite_spr(int n, unsigned long val){ unsigned int instrs[2]; unsigned long (*code)(unsigned long);#ifdef CONFIG_PPC64 unsigned long opd[3]; opd[0] = (unsigned long)instrs; opd[1] = 0; opd[2] = 0; code = (unsigned long (*)(unsigned long)) opd;#else code = (unsigned long (*)(unsigned long)) instrs;#endif instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6); instrs[1] = 0x4e800020; store_inst(instrs); store_inst(instrs+1); if (setjmp(bus_error_jmp) == 0) { catch_memory_errors = 1; sync(); code(val); sync(); /* wait a little while to see if we get a machine check */ __delay(200); n = size; }}static unsigned long regno;extern char exc_prolog;extern char dec_exc;void super_regs(void){ int cmd; unsigned long val;#ifdef CONFIG_PPC_ISERIES struct paca_struct *ptrPaca = NULL; struct lppaca *ptrLpPaca = NULL; struct ItLpRegSave *ptrLpRegSave = NULL;#endif cmd = skipbl(); if (cmd == '\n') { unsigned long sp, toc; asm("mr %0,1" : "=r" (sp) :); asm("mr %0,2" : "=r" (toc) :); printf("msr = "REG" sprg0= "REG"\n", mfmsr(), mfspr(SPRN_SPRG0)); printf("pvr = "REG" sprg1= "REG"\n", mfspr(SPRN_PVR), mfspr(SPRN_SPRG1)); printf("dec = "REG" sprg2= "REG"\n", mfspr(SPRN_DEC), mfspr(SPRN_SPRG2)); printf("sp = "REG" sprg3= "REG"\n", sp, mfspr(SPRN_SPRG3)); printf("toc = "REG" dar = "REG"\n", toc, mfspr(SPRN_DAR));#ifdef CONFIG_PPC_ISERIES // Dump out relevant Paca data areas. printf("Paca: \n"); ptrPaca = get_paca(); printf(" Local Processor Control Area (LpPaca): \n"); ptrLpPaca = ptrPaca->lppaca_ptr; printf(" Saved Srr0=%.16lx Saved Srr1=%.16lx \n", ptrLpPaca->saved_srr0, ptrLpPaca->saved_srr1); printf(" Saved Gpr3=%.16lx Saved Gpr4=%.16lx \n", ptrLpPaca->saved_gpr3, ptrLpPaca->saved_gpr4); printf(" Saved Gpr5=%.16lx \n", ptrLpPaca->saved_gpr5); printf(" Local Processor Register Save Area (LpRegSave): \n"); ptrLpRegSave = ptrPaca->reg_save_ptr; printf(" Saved Sprg0=%.16lx Saved Sprg1=%.16lx \n", ptrLpRegSave->xSPRG0, ptrLpRegSave->xSPRG0); printf(" Saved Sprg2=%.16lx Saved Sprg3=%.16lx \n", ptrLpRegSave->xSPRG2, ptrLpRegSave->xSPRG3); printf(" Saved Msr =%.16lx Saved Nia =%.16lx \n", ptrLpRegSave->xMSR, ptrLpRegSave->xNIA);#endif return; } scanhex(®no); switch (cmd) { case 'w': val = read_spr(regno); scanhex(&val); write_spr(regno, val); /* fall through */ case 'r': printf("spr %lx = %lx\n", regno, read_spr(regno)); break; } scannl();}/* * Stuff for reading and writing memory safely */intmread(unsigned long adrs, void *buf, int size){ volatile int n; char *p, *q; n = 0; if (setjmp(bus_error_jmp) == 0) { catch_memory_errors = 1; sync(); p = (char *)adrs; q = (char *)buf; switch (size) { case 2: *(u16 *)q = *(u16 *)p; break; case 4: *(u32 *)q = *(u32 *)p; break; case 8: *(u64 *)q = *(u64 *)p; break; default: for( ; n < size; ++n) { *q++ = *p++; sync(); } } sync(); /* wait a little while to see if we get a machine check */ __delay(200); n = size; } catch_memory_errors = 0; return n;}intmwrite(unsigned long adrs, void *buf, int size){ volatile int n; char *p, *q; n = 0; if (setjmp(bus_error_jmp) == 0) { catch_memory_errors = 1; sync(); p = (char *) adrs; q = (char *) buf; switch (size) { case 2: *(u16 *)p = *(u16 *)q; break; case 4: *(u32 *)p = *(u32 *)q; break; case 8: *(u64 *)p = *(u64 *)q; break; default: for ( ; n < size; ++n) { *p++ = *q++; sync(); } } sync(); /* wait a little while to see if we get a machine check */ __delay(200); n = size; } else { printf("*** Error writing address %x\n", adrs + n); } catch_memory_errors = 0; return n;}static int fault_type;static int fault_except;static char *fault_chars[] = { "--", "**", "##" };static int handle_fault(struct pt_regs *regs){ fault_except = TRAP(regs); switch (TRAP(regs)) { case 0x200: fault_type = 0; break; case 0x300: case 0x380: fault_type = 1; break; default: fault_type = 2; } longjmp(bus_error_jmp, 1); return 0;}#define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))voidbyterev(unsigned char *val, int size){ int t; switch (size) { case 2: SWAP(val[0], val[1], t); break; case 4: SWAP(val[0], val[3], t); SWAP(val[1], val[2], t); break; case 8: /* is there really any use for this? */ SWAP(val[0], val[7], t); SWAP(val[1], val[6], t); SWAP(val[2], val[5], t); SWAP(val[3], val[4], t); break; }}static int brev;static int mnoread;static char *memex_help_string = "Memory examine command usage:\n" "m [addr] [flags] examine/change memory\n" " addr is optional. will start where left off.\n" " flags may include chars from this set:\n" " b modify by bytes (default)\n" " w modify by words (2 byte)\n" " l modify by longs (4 byte)\n" " d modify by doubleword (8 byte)\n" " r toggle reverse byte order mode\n" " n do not read memory (for i/o spaces)\n" " . ok to read (default)\n" "NOTE: flags are saved as defaults\n" "";static char *memex_subcmd_help_string = "Memory examine subcommands:\n" " hexval write this val to current location\n" " 'string' write chars from string to this location\n" " ' increment address\n" " ^ decrement address\n" " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n" " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n" " ` clear no-read flag\n" " ; stay at this addr\n" " v change to byte mode\n" " w change to word (2 byte) mode\n" " l change to long (4 byte) mode\n" " u change to doubleword (8 byte) mode\n" " m addr change current addr\n" " n toggle no-read flag\n" " r toggle byte reverse flag\n" " < count back up count bytes\n" " > count skip forward count bytes\n" " x exit this mode\n" "";voidmemex(void){ int cmd, inc, i, nslash; unsigned long n; unsigned char val[16]; scanhex((void *)&adrs); cmd = skipbl(); if (cmd == '?') { printf(memex_help_string); return; } else { termch = cmd; } last_cmd = "m\n"; while ((cmd = skipbl()) != '\n') { switch( cmd ){ case 'b': size = 1; break; case 'w': size = 2; break; case 'l': size = 4; break; case 'd': size = 8; break; case 'r': brev = !brev; break; case 'n': mnoread = 1; break; case '.': mnoread = 0; break; } } if( size <= 0 ) size = 1; else if( size > 8 ) size = 8; for(;;){ if (!mnoread) n = mread(adrs, val, size); printf(REG"%c", adrs, brev? 'r': ' '); if (!mnoread) { if (brev) byterev(val, size); putchar(' '); for (i = 0; i < n; ++i) printf("%.2x", val[i]); for (; i < size; ++i) printf("%s", fault_chars[fault_type]); } putchar(' '); inc = size; nslash = 0; for(;;){ if( scanhex(&n) ){ for (i = 0; i < size; ++i) val[i] = n >> (i * 8); if (!brev) byterev(val, size); mwrite(adrs, val, size); inc = size; } cmd = skipbl(); if (cmd == '\n') break; inc = 0; switch (cmd) { case '\'': for(;;){ n = inchar(); if( n == '\\' ) n = bsesc(); else if( n == '\'' ) break; for (i = 0; i < size; ++i) val[i] = n >> (i * 8); if (!brev) byterev(val, size); mwrite(adrs, val, size); adrs += size; } adrs -= size; inc = size; break; case ',': adrs += size; break; case '.': mnoread = 0; break; case ';': break; case 'x': case EOF: scannl(); return; case 'b': case 'v': size = 1; break; case 'w': size = 2; break; case 'l': size = 4; break; case 'u': size = 8; break; case '^': adrs -= size; break; break; case '/': if (nslash > 0) adrs -= 1 << nslash; else nslash = 0; nslash += 4; adrs += 1 << nslash; break; case '\\': if (nslash < 0) adrs += 1 << -nslash; else nslash = 0; nslash -= 4; adrs -= 1 << -nslash; break; case 'm': scanhex((void *)&adrs); break; case 'n': mnoread = 1; break; case 'r': brev = !brev; break; case '<': n = size; scanhex(&n); adrs -= n; break; case '>': n = size; scanhex(&n); adrs += n; break; case '?': printf(memex_subcmd_help_string); break; } } adrs += inc; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -