📄 xmon.c
字号:
break; } if (!mread(sp + 16, &ip, sizeof(unsigned long)) || !mread(sp, &newsp, sizeof(unsigned long))) { printf("Couldn't read stack frame at %lx\n", sp); break; } /* * For the first stack frame, try to work out if * LR and/or the saved LR value in the bottommost * stack frame are valid. */ if ((pc | lr) != 0) { unsigned long fnstart, fnend; unsigned long nextip; int printip = 1; get_function_bounds(pc, &fnstart, &fnend); nextip = 0; if (newsp > sp) mread(newsp + 16, &nextip, sizeof(unsigned long)); if (lr == ip) { if (lr < PAGE_OFFSET || (fnstart <= lr && lr < fnend)) printip = 0; } else if (lr == nextip) { printip = 0; } else if (lr >= PAGE_OFFSET && !(fnstart <= lr && lr < fnend)) { printf("[link register ] "); xmon_print_symbol(lr, " ", "\n"); } if (printip) { printf("[%.16lx] ", sp); xmon_print_symbol(ip, " ", " (unreliable)\n"); } pc = lr = 0; } else { printf("[%.16lx] ", sp); xmon_print_symbol(ip, " ", "\n"); } /* Look for "regshere" marker to see if this is an exception frame. */ if (mread(sp + 0x60, &marker, sizeof(unsigned long)) && marker == 0x7265677368657265ul) { if (mread(sp + 0x70, ®s, sizeof(regs)) != sizeof(regs)) { printf("Couldn't read registers at %lx\n", sp + 0x70); 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); printf(" paca = 0x%lx\n", get_paca()); 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; 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 %.16lx\n", base); return; } catch_memory_errors = 0; fp = ®s; } if (FULL_REGS(fp)) { for (n = 0; n < 16; ++n) printf("R%.2ld = %.16lx R%.2ld = %.16lx\n", n, fp->gpr[n], n+16, fp->gpr[n+16]); } else { for (n = 0; n < 7; ++n) printf("R%.2ld = %.16lx R%.2ld = %.16lx\n", n, fp->gpr[n], n+7, fp->gpr[n+7]); } printf("pc = "); xmon_print_symbol(fp->nip, " ", "\n"); printf("lr = "); xmon_print_symbol(fp->link, " ", "\n"); printf("msr = %.16lx cr = %.8lx\n", fp->msr, fp->ccr); printf("ctr = %.16lx xer = %.16lx trap = %8lx\n", fp->ctr, fp->xer, fp->trap);}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 opd[3]; unsigned long ret = -1UL; instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6); instrs[1] = 0x4e800020; opd[0] = (unsigned long)instrs; opd[1] = 0; opd[2] = 0; store_inst(instrs); store_inst(instrs+1); code = (unsigned long (*)(void)) opd; 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); unsigned long opd[3]; instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6); instrs[1] = 0x4e800020; opd[0] = (unsigned long)instrs; opd[1] = 0; opd[2] = 0; store_inst(instrs); store_inst(instrs+1); code = (unsigned long (*)(unsigned long)) opd; 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;voidsuper_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 = %.16lx sprg0= %.16lx\n", get_msr(), get_sprg0()); printf("pvr = %.16lx sprg1= %.16lx\n", get_pvr(), get_sprg1()); printf("dec = %.16lx sprg2= %.16lx\n", get_dec(), get_sprg2()); printf("sp = %.16lx sprg3= %.16lx\n", sp, get_sprg3()); printf("toc = %.16lx dar = %.16lx\n", toc, get_dar()); printf("srr0 = %.16lx srr1 = %.16lx\n", get_srr0(), get_srr1());#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; case 'm': val = get_msr(); scanhex(&val); set_msrd(val); 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: *(short *)q = *(short *)p; break; case 4: *(int *)q = *(int *)p; break; case 8: *(long *)q = *(long *)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: *(short *)p = *(short *)q; break; case 4: *(int *)p = *(int *)q; break; case 8: *(long *)p = *(long *)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 char *fault_chars[] = { "--", "**", "##" };static inthandle_fault(struct pt_regs *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("%.16x%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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -