📄 xmon.c
字号:
scanhex(&val); set_sr(regno, val); break; case 'm': val = get_msr(); scanhex(&val); set_msrd(val); break; } scannl();}#ifndef CONFIG_PPC64BRIDGEstatic voiddump_hash_table_seg(unsigned seg, unsigned start, unsigned end){ extern void *Hash; extern unsigned long Hash_size; unsigned *htab = Hash; unsigned hsize = Hash_size; unsigned v, hmask, va, last_va; int found, last_found, i; unsigned *hg, w1, last_w2, last_va0; last_found = 0; hmask = hsize / 64 - 1; va = start; start = (start >> 12) & 0xffff; end = (end >> 12) & 0xffff; for (v = start; v < end; ++v) { found = 0; hg = htab + (((v ^ seg) & hmask) * 16); w1 = 0x80000000 | (seg << 7) | (v >> 10); for (i = 0; i < 8; ++i, hg += 2) { if (*hg == w1) { found = 1; break; } } if (!found) { w1 ^= 0x40; hg = htab + ((~(v ^ seg) & hmask) * 16); for (i = 0; i < 8; ++i, hg += 2) { if (*hg == w1) { found = 1; break; } } } if (!(last_found && found && (hg[1] & ~0x180) == last_w2 + 4096)) { if (last_found) { if (last_va != last_va0) printf(" ... %x", last_va); printf("\n"); } if (found) { printf("%x to %x", va, hg[1]); last_va0 = va; } last_found = found; } if (found) { last_w2 = hg[1] & ~0x180; last_va = va; } va += 4096; } if (last_found) printf(" ... %x\n", last_va);}#else /* CONFIG_PPC64BRIDGE */static voiddump_hash_table_seg(unsigned seg, unsigned start, unsigned end){ extern void *Hash; extern unsigned long Hash_size; unsigned *htab = Hash; unsigned hsize = Hash_size; unsigned v, hmask, va, last_va; int found, last_found, i; unsigned *hg, w1, last_w2, last_va0; last_found = 0; hmask = hsize / 128 - 1; va = start; start = (start >> 12) & 0xffff; end = (end >> 12) & 0xffff; for (v = start; v < end; ++v) { found = 0; hg = htab + (((v ^ seg) & hmask) * 32); w1 = 1 | (seg << 12) | ((v & 0xf800) >> 4); for (i = 0; i < 8; ++i, hg += 4) { if (hg[1] == w1) { found = 1; break; } } if (!found) { w1 ^= 2; hg = htab + ((~(v ^ seg) & hmask) * 32); for (i = 0; i < 8; ++i, hg += 4) { if (hg[1] == w1) { found = 1; break; } } } if (!(last_found && found && (hg[3] & ~0x180) == last_w2 + 4096)) { if (last_found) { if (last_va != last_va0) printf(" ... %x", last_va); printf("\n"); } if (found) { printf("%x to %x", va, hg[3]); last_va0 = va; } last_found = found; } if (found) { last_w2 = hg[3] & ~0x180; last_va = va; } va += 4096; } if (last_found) printf(" ... %x\n", last_va);}#endif /* CONFIG_PPC64BRIDGE */static unsigned long hash_ctx;static unsigned long hash_start;static unsigned long hash_end;static voiddump_hash_table(){ int seg; unsigned seg_start, seg_end; hash_ctx = 0; hash_start = 0; hash_end = 0xfffff000; scanhex(&hash_ctx); scanhex(&hash_start); scanhex(&hash_end); printf("Mappings for context %x\n", hash_ctx); seg_start = hash_start; for (seg = hash_start >> 28; seg <= hash_end >> 28; ++seg) { seg_end = (seg << 28) | 0x0ffff000; if (seg_end > hash_end) seg_end = hash_end; dump_hash_table_seg((hash_ctx << 4) + seg, seg_start, seg_end); seg_start = seg_end + 0x1000; }}intmread(unsigned long adrs, void *buf, int size){ volatile int n; char *p, *q; n = 0; if( setjmp(bus_error_jmp) == 0 ){ debugger_fault_handler = handle_fault; sync(); p = (char *) adrs; q = (char *) buf; switch (size) { case 2: *(short *)q = *(short *)p; break; case 4: *(int *)q = *(int *)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; } debugger_fault_handler = 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 ){ debugger_fault_handler = handle_fault; sync(); p = (char *) adrs; q = (char *) buf; switch (size) { case 2: *(short *)p = *(short *)q; break; case 4: *(int *)p = *(int *)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); } debugger_fault_handler = 0; return n;}static int fault_type;static char *fault_chars[] = { "--", "**", "##" };static voidhandle_fault(struct pt_regs *regs){ switch (regs->trap) { case 0x200: fault_type = 0; break; case 0x300: case 0x380: fault_type = 1; break; default: fault_type = 2; } longjmp(bus_error_jmp, 1);}#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(){ 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; 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; }}intbsesc(){ int c; c = inchar(); switch( c ){ case 'n': c = '\n'; break; case 'r': c = '\r'; break; case 'b': c = '\b'; break; case 't': c = '\t'; break; } return c;}#define isxdigit(c) (('0' <= (c) && (c) <= '9') \ || ('a' <= (c) && (c) <= 'f') \ || ('A' <= (c) && (c) <= 'F'))voiddump(){ int c; c = inchar(); if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n') termch = c; scanhex((void *)&adrs); if( termch != '\n') termch = 0; if( c == 'i' ){ scanhex(&nidump); if( nidump == 0 ) nidump = 16; adrs += ppc_inst_dump(adrs, nidump); last_cmd = "di\n"; } else { scanhex(&ndump); if( ndump == 0 ) ndump = 64; prdump(adrs, ndump); adrs += ndump; last_cmd = "d\n"; }}voidprdump(unsigned long adrs, long ndump){ long n, m, c, r, nr; unsigned char temp[16]; for( n = ndump; n > 0; ){ printf("%.16lx", adrs); putchar(' '); r = n < 16? n: 16; nr = mread(adrs, temp, r); adrs += nr; for( m = 0; m < r; ++m ){ if ((m & 7) == 0 && m > 0) putchar(' '); if( m < nr ) printf("%.2x", temp[m]); else printf("%s", fault_chars[fault_type]); } for(; m < 16; ++m ) printf(" "); printf(" |"); for( m = 0; m < r; ++m ){ if( m < nr ){ c = temp[m]; putchar(' ' <= c && c <= '~'? c: '.'); } else putchar(' '); } n -= r; for(; m < 16; ++m ) putchar(' '); printf("|\n"); if( nr < r ) break; }}intppc_inst_dump(unsigned long adr, long count){ int nr, dotted; unsigned long first_adr; unsigned long inst, last_inst; unsigned char val[4]; dotted = 0; for (first_adr = adr; count > 0; --count, adr += 4){ nr = mread(adr, val, 4); if( nr == 0 ){ const char *x = fault_chars[fault_type]; printf("%.16lx %s%s%s%s\n", adr, x, x, x, x); break; } inst = GETWORD(val); if (adr > first_adr && inst == last_inst) { if (!dotted) { printf(" ...\n"); dotted = 1; } continue; } dotted = 0; last_inst = inst; printf("%.16lx ", adr); printf("%.8x\t", inst); print_insn_big_powerpc(stdout, inst, adr); /* always returns 4 */ printf("\n"); } return adr - first_adr;}voidprint_address(unsigned long addr){ printf("0x%lx", addr);}/* * Memory operations - move, set, print differences */static unsigned long mdest; /* destination address */static unsigned long msrc; /* source address */static unsigned long mval; /* byte value to set memory to */static unsigned long mcount; /* # bytes to affect */static unsigned long mdiffs; /* max # differences to print */voidmemops(int cmd){ scanhex((void *)&mdest); if( termch != '\n' ) termch = 0; scanhex((void *)(cmd == 's'? &mval: &msrc)); if( termch != '\n' ) termch = 0; scanhex((void *)&mcount); switch( cmd ){ case 'm': memmove((void *)mdest, (void *)msrc, mcount); break; case 's': memset((void *)mdest, mval, mcount); break; case 'd': if( termch != '\n' ) termch = 0; scanhex((void *)&mdiffs); memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs); break; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -