📄 xmon.c
字号:
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(){ 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(){ 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; 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(addr)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(){ 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(){ 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);}/* Input scanning routines */intskipbl(){ 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(vp)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[64]; int i; for (i=0; i<63; i++) { c = inchar(); if (isspace(c)) { termch = c; break; } symname[i] = c; } symname[i++] = 0; *vp = xmon_symbol_to_addr(symname); 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(){ int c; c = termch; termch = 0; while( c != '\n' ) c = inchar();}inthexdigit(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(){ lineptr = NULL;}intinchar(){ if (lineptr == NULL || *lineptr == 0) { if (fgets(line, sizeof(line), stdin) == NULL) { lineptr = NULL; return EOF; } lineptr = line; } return *lineptr++;}voidtake_input(str)char *str;{ lineptr = str;}voidsysmap_lookup(void){ int type = inchar(); unsigned addr; static char tmp[64]; char* cur; extern char *sysmap; extern unsigned long sysmap_size; if ( !sysmap || !sysmap_size ) return; switch(type) { case 'a': if (scanhex(&addr)) { pretty_print_addr(addr); printf("\n"); } termch = 0; break; case 's': getstring(tmp, 64); if( setjmp(bus_error_jmp) == 0 ) { debugger_fault_handler = handle_fault; sync(); cur = sysmap; do { cur = strstr(cur, tmp); if (cur) { static char res[64]; char *p, *d; p = cur; while(p > sysmap && *p != 10) p--; if (*p == 10) p++; d = res; while(*p && p < (sysmap + sysmap_size) && *p != 10) *(d++) = *(p++); *(d++) = 0; printf("%s\n", res); cur++; } } while (cur); sync(); } debugger_fault_handler = 0; termch = 0; break; }}static intpretty_print_addr(unsigned long addr){ char *sym; unsigned long saddr; printf("%08x", addr); sym = xmon_find_symbol(addr, &saddr); if (sym) printf(" (%s+0x%x)", sym, addr-saddr); return (sym != 0);}char*xmon_find_symbol(unsigned long addr, unsigned long* saddr){ static char rbuffer[64]; char *p, *ep, *limit; unsigned long prev, next; char* psym; extern char *sysmap; extern unsigned long sysmap_size; if ( !sysmap || !sysmap_size ) return NULL; prev = 0; psym = NULL; p = sysmap; limit = p + sysmap_size; if( setjmp(bus_error_jmp) == 0 ) { debugger_fault_handler = handle_fault; sync(); do { next = simple_strtoul(p, &p, 16); if (next > addr && prev <= addr) { if (!psym) goto bail; ep = rbuffer; p = psym; while(*p && p < limit && *p == 32) p++; while(*p && p < limit && *p != 10 && (ep - rbuffer) < 63) *(ep++) = *(p++); *(ep++) = 0; if (saddr) *saddr = prev; debugger_fault_handler = 0; return rbuffer; } prev = next; psym = p; while(*p && p < limit && *p != 10) p++; if (*p) p++; } while(*p && p < limit && next);bail: sync(); } debugger_fault_handler = 0; return NULL;}unsigned longxmon_symbol_to_addr(char* symbol){ char *p, *cur; char *match; int goodness = 0; int result = 0; extern char *sysmap; extern unsigned long sysmap_size; if ( !sysmap || !sysmap_size ) return 0; if( setjmp(bus_error_jmp) == 0 ) { debugger_fault_handler = handle_fault; sync(); cur = sysmap; while(cur) { cur = strstr(cur, symbol); if (cur) { int gd = 1; /* best match if equal, better match if * begins with */ if (cur == sysmap || *(cur-1) == ' ') { gd++; if (cur[strlen(symbol)] == 10) gd++; } if (gd > goodness) { match = cur; goodness = gd; if (gd == 3) break; } cur++; } } if (goodness) { p = match; while(p > sysmap && *p != 10) p--; if (*p == 10) p++; result = simple_strtoul(p, &p, 16); } sync(); } debugger_fault_handler = 0; return result;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -