📄 xmon.c
字号:
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; }}static int brev;static int mnoread;voidmemex(void){ int cmd, inc, i, nslash; unsigned n; unsigned char val[4]; last_cmd = "m\n"; scanhex(&adrs); while ((cmd = skipbl()) != '\n') { switch( cmd ){ case 'b': size = 1; break; case 'w': size = 2; break; case 'l': size = 4; break; case 'r': brev = !brev; break; case 'n': mnoread = 1; break; case '.': mnoread = 0; break; } } if( size <= 0 ) size = 1; else if( size > 4 ) size = 4; for(;;){ if (!mnoread) n = mread(adrs, val, size); printf("%.8x%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 '^': 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(&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; } } adrs += inc; }}intbsesc(void){ 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;}voiddump(void){ int c; c = inchar(); if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n') termch = c; scanhex(&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 adrs, int ndump){ register int n, m, c, r, nr; unsigned char temp[16]; for( n = ndump; n > 0; ){ printf("%.8x", adrs); putchar(' '); r = n < 16? n: 16; nr = mread(adrs, temp, r); adrs += nr; for( m = 0; m < r; ++m ){ putchar((m & 3) == 0 && m > 0? '.': ' '); 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 adr, int count){ int nr, dotted; unsigned first_adr; unsigned long inst, last_inst = 0; 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("%.8x %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("%.8x ", adr); printf("%.8x\t", inst); print_insn_big_powerpc(stdout, inst, adr); /* always returns 4 */ printf("\n"); } return adr - first_adr;}voidprint_address(unsigned addr){ printf("0x%x", addr);}/* * Memory operations - move, set, print differences */static unsigned mdest; /* destination address */static unsigned msrc; /* source address */static unsigned mval; /* byte value to set memory to */static unsigned mcount; /* # bytes to affect */static unsigned mdiffs; /* max # differences to print */voidmemops(int cmd){ scanhex(&mdest); if( termch != '\n' ) termch = 0; scanhex(cmd == 's'? &mval: &msrc); if( termch != '\n' ) termch = 0; scanhex(&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(&mdiffs); memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs); break; }}voidmemdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr){ unsigned n, prt; prt = 0; for( n = nb; n > 0; --n ) if( *p1++ != *p2++ ) if( ++prt <= maxpr ) printf("%.8x %.2x # %.8x %.2x\n", (unsigned)p1 - 1, p1[-1], (unsigned)p2 - 1, p2[-1]); if( prt > maxpr ) printf("Total of %d differences\n", prt);}static unsigned mend;static unsigned mask;voidmemlocate(void){ unsigned a, n; unsigned char val[4]; last_cmd = "ml"; scanhex(&mdest); if (termch != '\n') { termch = 0; scanhex(&mend); if (termch != '\n') { termch = 0; scanhex(&mval); mask = ~0; if (termch != '\n') termch = 0; scanhex(&mask); } } n = 0; for (a = mdest; a < mend; a += 4) { if (mread(a, val, 4) == 4 && ((GETWORD(val) ^ mval) & mask) == 0) { printf("%.8x: %.8x\n", a, GETWORD(val)); if (++n >= 10) break; } }}static unsigned mskip = 0x1000;static unsigned mlim = 0xffffffff;voidmemzcan(void){ unsigned char v; unsigned a; int ok, ook; scanhex(&mdest); if (termch != '\n') termch = 0; scanhex(&mskip); if (termch != '\n') termch = 0; scanhex(&mlim); ook = 0; for (a = mdest; a < mlim; a += mskip) { ok = mread(a, &v, 1); if (ok && !ook) { printf("%.8x .. ", a); fflush(stdout); } else if (!ok && ook) printf("%.8x\n", a - mskip); ook = ok; if (a + mskip < a) break; } if (ook) printf("%.8x\n", a - mskip);}void proccall(void){ unsigned int args[8]; unsigned int ret; int i; typedef unsigned int (*callfunc_t)(unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int); callfunc_t func; scanhex(&adrs); if (termch != '\n') termch = 0; for (i = 0; i < 8; ++i) args[i] = 0; for (i = 0; i < 8; ++i) { if (!scanhex(&args[i]) || termch == '\n') break; termch = 0; } func = (callfunc_t) adrs; ret = 0; if (setjmp(bus_error_jmp) == 0) { debugger_fault_handler = handle_fault; sync(); ret = func(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]); sync(); printf("return value is %x\n", ret); } else { printf("*** %x exception occurred\n", fault_except); } debugger_fault_handler = NULL;}/* Input scanning routines */intskipbl(void){ int c; if( termch != 0 ){ c = termch; termch = 0; } else c = inchar(); while( c == ' ' || c == '\t' ) c = inchar(); return c;}#define N_PTREGS 44static char *regnames[N_PTREGS] = { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", "pc", "msr", "or3", "ctr", "lr", "xer", "ccr", "mq", "trap", "dar", "dsisr", "res"};intscanhex(unsigned *vp){ int c, d; unsigned v; c = skipbl(); if (c == '%') { /* parse register name */ char regname[8]; int i; for (i = 0; i < sizeof(regname) - 1; ++i) { c = inchar(); if (!isalnum(c)) { termch = c; break; } regname[i] = c; } regname[i] = 0; for (i = 0; i < N_PTREGS; ++i) { if (strcmp(regnames[i], regname) == 0) { unsigned *rp = (unsigned *) xmon_regs[smp_processor_id()]; if (rp == NULL) { printf("regs not available\n"); return 0; } *vp = rp[i]; return 1; } } printf("invalid register name '%%%s'\n", regname); return 0; } else if (c == '$') { static char symname[128]; int i; for (i=0; i<63; i++) { c = inchar(); if (isspace(c)) { termch = c; break; } symname[i] = c; } symname[i++] = 0; *vp = 0; if (setjmp(bus_error_jmp) == 0) { debugger_fault_handler = handle_fault; sync(); *vp = kallsyms_lookup_name(symname); sync(); } debugger_fault_handler = NULL; if (!(*vp)) { printf("unknown symbol\n"); return 0; } return 1; } d = hexdigit(c); if( d == EOF ){ termch = c; return 0; } v = 0; do { v = (v << 4) + d; c = inchar(); d = hexdigit(c); } while( d != EOF ); termch = c; *vp = v; return 1;}voidscannl(void){ int c; c = termch; termch = 0; while( c != '\n' ) c = inchar();}int hexdigit(int c){ if( '0' <= c && c <= '9' ) return c - '0'; if( 'A' <= c && c <= 'F' ) return c - ('A' - 10); if( 'a' <= c && c <= 'f' ) return c - ('a' - 10); return EOF;}voidgetstring(char *s, int size){ int c; c = skipbl(); do { if( size > 1 ){ *s++ = c; --size; } c = inchar(); } while( c != ' ' && c != '\t' && c != '\n' ); termch = c; *s = 0;}static char line[256];static char *lineptr;voidflush_input(void){ lineptr = NULL;}intinchar(void){ if (lineptr == NULL || *lineptr == 0) { if (fgets(line, sizeof(line), stdin) == NULL) { lineptr = NULL; return EOF; } lineptr = line; } return *lineptr++;}voidtake_input(char *str){ lineptr = str;}static voidsymbol_lookup(void){ int type = inchar(); unsigned addr; static char tmp[128]; switch (type) { case 'a': if (scanhex(&addr)) xmon_print_symbol(addr, ": ", "\n"); termch = 0; break; case 's': getstring(tmp, 64); if (setjmp(bus_error_jmp) == 0) { debugger_fault_handler = handle_fault; sync(); addr = kallsyms_lookup_name(tmp); if (addr) printf("%s: %lx\n", tmp, addr); else printf("Symbol '%s' not found.\n", tmp); sync(); } debugger_fault_handler = NULL; termch = 0; break; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -