📄 8db.c
字号:
#include <u.h>#include <libc.h>#include <bio.h>#include <mach.h>/* * i386-specific debugger interface * also amd64 extensions */static char *i386excep(Map*, Rgetter);static int i386trace(Map*, uvlong, uvlong, uvlong, Tracer);static uvlong i386frame(Map*, uvlong, uvlong, uvlong, uvlong);static int i386foll(Map*, uvlong, Rgetter, uvlong*);static int i386inst(Map*, uvlong, char, char*, int);static int i386das(Map*, uvlong, char*, int);static int i386instlen(Map*, uvlong);static char STARTSYM[] = "_main";static char PROFSYM[] = "_mainp";static char FRAMENAME[] = ".frame";static char *excname[] ={[0] "divide error",[1] "debug exception",[4] "overflow",[5] "bounds check",[6] "invalid opcode",[7] "math coprocessor emulation",[8] "double fault",[9] "math coprocessor overrun",[10] "invalid TSS",[11] "segment not present",[12] "stack exception",[13] "general protection violation",[14] "page fault",[16] "math coprocessor error",[17] "alignment check",[18] "machine check",[19] "floating-point exception",[24] "clock",[25] "keyboard",[27] "modem status",[28] "serial line status",[30] "floppy disk",[36] "mouse",[37] "math coprocessor",[38] "hard disk",[64] "system call",};Machdata i386mach ={ {0xCC, 0, 0, 0}, /* break point: INT 3 */ 1, /* break point size */ leswab, /* convert short to local byte order */ leswal, /* convert long to local byte order */ leswav, /* convert vlong to local byte order */ i386trace, /* C traceback */ i386frame, /* frame finder */ i386excep, /* print exception */ 0, /* breakpoint fixup */ leieeesftos, /* single precision float printer */ leieeedftos, /* double precision float printer */ i386foll, /* following addresses */ i386inst, /* print instruction */ i386das, /* dissembler */ i386instlen, /* instruction size calculation */};static char*i386excep(Map *map, Rgetter rget){ ulong c; uvlong pc; static char buf[16]; c = (*rget)(map, "TRAP"); if(c > 64 || excname[c] == 0) { if (c == 3) { pc = (*rget)(map, "PC"); if (get1(map, pc, (uchar*)buf, machdata->bpsize) > 0) if (memcmp(buf, machdata->bpinst, machdata->bpsize) == 0) return "breakpoint"; } snprint(buf, sizeof(buf), "exception %ld", c); return buf; } else return excname[c];}static inti386trace(Map *map, uvlong pc, uvlong sp, uvlong link, Tracer trace){ int i; uvlong osp; Symbol s, f; USED(link); i = 0; osp = 0; while(findsym(pc, CTEXT, &s)) { if (osp == sp) break; osp = sp; if(strcmp(STARTSYM, s.name) == 0 || strcmp(PROFSYM, s.name) == 0) break; if(pc != s.value) { /* not at first instruction */ if(findlocal(&s, FRAMENAME, &f) == 0) break; sp += f.value-mach->szaddr; } if (geta(map, sp, &pc) < 0) break; if(pc == 0) break; (*trace)(map, pc, sp, &s); sp += mach->szaddr; if(++i > 1000) break; } return i;}static uvlongi386frame(Map *map, uvlong addr, uvlong pc, uvlong sp, uvlong link){ Symbol s, f; USED(link); while (findsym(pc, CTEXT, &s)) { if(strcmp(STARTSYM, s.name) == 0 || strcmp(PROFSYM, s.name) == 0) break; if(pc != s.value) { /* not first instruction */ if(findlocal(&s, FRAMENAME, &f) == 0) break; sp += f.value-mach->szaddr; } if (s.value == addr) return sp; if (geta(map, sp, &pc) < 0) break; sp += mach->szaddr; } return 0;} /* I386/486 - Disassembler and related functions *//* * an instruction */typedef struct Instr Instr;struct Instr{ uchar mem[1+1+1+1+2+1+1+4+4]; /* raw instruction */ uvlong addr; /* address of start of instruction */ int n; /* number of bytes in instruction */ char *prefix; /* instr prefix */ char *segment; /* segment override */ uchar jumptype; /* set to the operand type for jump/ret/call */ uchar amd64; uchar rex; /* REX prefix (or zero) */ char osize; /* 'W' or 'L' (or 'Q' on amd64) */ char asize; /* address size 'W' or 'L' (or 'Q' or amd64) */ uchar mod; /* bits 6-7 of mod r/m field */ uchar reg; /* bits 3-5 of mod r/m field */ char ss; /* bits 6-7 of SIB */ char index; /* bits 3-5 of SIB */ char base; /* bits 0-2 of SIB */ char rip; /* RIP-relative in amd64 mode */ uchar opre; /* f2/f3 could introduce media */ short seg; /* segment of far address */ ulong disp; /* displacement */ ulong imm; /* immediate */ ulong imm2; /* second immediate operand */ uvlong imm64; /* big immediate */ char *curr; /* fill level in output buffer */ char *end; /* end of output buffer */ char *err; /* error message */}; /* 386 register (ha!) set */enum{ AX=0, CX, DX, BX, SP, BP, SI, DI, /* amd64 */ R8, R9, R10, R11, R12, R13, R14, R15}; /* amd64 rex extension byte */enum{ REXW = 1<<3, /* =1, 64-bit operand size */ REXR = 1<<2, /* extend modrm reg */ REXX = 1<<1, /* extend sib index */ REXB = 1<<0 /* extend modrm r/m, sib base, or opcode reg */}; /* Operand Format codes *//*%A - address size register modifier (!asize -> 'E')%C - Control register CR0/CR1/CR2%D - Debug register DR0/DR1/DR2/DR3/DR6/DR7%I - second immediate operand%O - Operand size register modifier (!osize -> 'E')%T - Test register TR6/TR7%S - size code ('W' or 'L')%W - Weird opcode: OSIZE == 'W' => "CBW"; else => "CWDE"%d - displacement 16-32 bits%e - effective address - Mod R/M value%f - floating point register F0-F7 - from Mod R/M register%g - segment register%i - immediate operand 8-32 bits%p - PC-relative - signed displacement in immediate field%r - Reg from Mod R/M%w - Weird opcode: OSIZE == 'W' => "CWD"; else => "CDQ"*/typedef struct Optable Optable;struct Optable{ char operand[2]; void *proto; /* actually either (char*) or (Optable*) */}; /* Operand decoding codes */enum { Ib = 1, /* 8-bit immediate - (no sign extension)*/ Ibs, /* 8-bit immediate (sign extended) */ Jbs, /* 8-bit sign-extended immediate in jump or call */ Iw, /* 16-bit immediate -> imm */ Iw2, /* 16-bit immediate -> imm2 */ Iwd, /* Operand-sized immediate (no sign extension)*/ Iwdq, /* Operand-sized immediate, possibly 64 bits */ Awd, /* Address offset */ Iwds, /* Operand-sized immediate (sign extended) */ RM, /* Word or long R/M field with register (/r) */ RMB, /* Byte R/M field with register (/r) */ RMOP, /* Word or long R/M field with op code (/digit) */ RMOPB, /* Byte R/M field with op code (/digit) */ RMR, /* R/M register only (mod = 11) */ RMM, /* R/M memory only (mod = 0/1/2) */ R0, /* Base reg of Mod R/M is literal 0x00 */ R1, /* Base reg of Mod R/M is literal 0x01 */ FRMOP, /* Floating point R/M field with opcode */ FRMEX, /* Extended floating point R/M field with opcode */ JUMP, /* Jump or Call flag - no operand */ RET, /* Return flag - no operand */ OA, /* literal 0x0a byte */ PTR, /* Seg:Displacement addr (ptr16:16 or ptr16:32) */ AUX, /* Multi-byte op code - Auxiliary table */ AUXMM, /* multi-byte op code - auxiliary table chosen by prefix */ PRE, /* Instr Prefix */ OPRE, /* Instr Prefix or media op extension */ SEG, /* Segment Prefix */ OPOVER, /* Operand size override */ ADDOVER, /* Address size override */}; static Optable optab0F00[8]={[0x00] 0,0, "MOVW LDT,%e",[0x01] 0,0, "MOVW TR,%e",[0x02] 0,0, "MOVW %e,LDT",[0x03] 0,0, "MOVW %e,TR",[0x04] 0,0, "VERR %e",[0x05] 0,0, "VERW %e",};static Optable optab0F01[8]={[0x00] 0,0, "MOVL GDTR,%e",[0x01] 0,0, "MOVL IDTR,%e",[0x02] 0,0, "MOVL %e,GDTR",[0x03] 0,0, "MOVL %e,IDTR",[0x04] 0,0, "MOVW MSW,%e", /* word */[0x06] 0,0, "MOVW %e,MSW", /* word */[0x07] 0,0, "INVLPG %e", /* or SWAPGS */};static Optable optab0F01F8[1]={[0x00] 0,0, "SWAPGS",};/* 0F71 *//* 0F72 *//* 0F73 */static Optable optab0FAE[8]={[0x00] 0,0, "FXSAVE %e",[0x01] 0,0, "FXRSTOR %e",[0x02] 0,0, "LDMXCSR %e",[0x03] 0,0, "STMXCSR %e",[0x05] 0,0, "LFENCE",[0x06] 0,0, "MFENCE",[0x07] 0,0, "SFENCE",};/* 0F18 *//* 0F0D */static Optable optab0FBA[8]={[0x04] Ib,0, "BT%S %i,%e",[0x05] Ib,0, "BTS%S %i,%e",[0x06] Ib,0, "BTR%S %i,%e",[0x07] Ib,0, "BTC%S %i,%e",};static Optable optab0F0F[256]={[0x0c] 0,0, "PI2FW %m,%M",[0x0d] 0,0, "PI2L %m,%M",[0x1c] 0,0, "PF2IW %m,%M",[0x1d] 0,0, "PF2IL %m,%M",[0x8a] 0,0, "PFNACC %m,%M",[0x8e] 0,0, "PFPNACC %m,%M",[0x90] 0,0, "PFCMPGE %m,%M",[0x94] 0,0, "PFMIN %m,%M",[0x96] 0,0, "PFRCP %m,%M",[0x97] 0,0, "PFRSQRT %m,%M",[0x9a] 0,0, "PFSUB %m,%M",[0x9e] 0,0, "PFADD %m,%M",[0xa0] 0,0, "PFCMPGT %m,%M",[0xa4] 0,0, "PFMAX %m,%M",[0xa6] 0,0, "PFRCPIT1 %m,%M",[0xa7] 0,0, "PFRSQIT1 %m,%M",[0xaa] 0,0, "PFSUBR %m,%M",[0xae] 0,0, "PFACC %m,%M",[0xb0] 0,0, "PFCMPEQ %m,%M",[0xb4] 0,0, "PFMUL %m,%M",[0xb6] 0,0, "PFRCPI2T %m,%M",[0xb7] 0,0, "PMULHRW %m,%M",[0xbb] 0,0, "PSWAPL %m,%M",};static Optable optab0FC7[8]={[0x01] 0,0, "CMPXCHG8B %e",};static Optable optab660F71[8]={[0x02] Ib,0, "PSRLW %i,%X",[0x04] Ib,0, "PSRAW %i,%X",[0x06] Ib,0, "PSLLW %i,%X",};static Optable optab660F72[8]={[0x02] Ib,0, "PSRLL %i,%X",[0x04] Ib,0, "PSRAL %i,%X",[0x06] Ib,0, "PSLLL %i,%X",};static Optable optab660F73[8]={[0x02] Ib,0, "PSRLQ %i,%X",[0x03] Ib,0, "PSRLO %i,%X",[0x06] Ib,0, "PSLLQ %i,%X",[0x07] Ib,0, "PSLLO %i,%X",};static Optable optab660F[256]={[0x2B] RM,0, "MOVNTPD %x,%e",[0x2E] RM,0, "UCOMISD %x,%X",[0x2F] RM,0, "COMISD %x,%X",[0x5A] RM,0, "CVTPD2PS %x,%X",[0x5B] RM,0, "CVTPS2PL %x,%X",[0x6A] RM,0, "PUNPCKHLQ %x,%X",[0x6B] RM,0, "PACKSSLW %x,%X",[0x6C] RM,0, "PUNPCKLQDQ %x,%X",[0x6D] RM,0, "PUNPCKHQDQ %x,%X",[0x6E] RM,0, "MOV%S %e,%X",[0x6F] RM,0, "MOVO %x,%X", /* MOVDQA */[0x70] RM,Ib, "PSHUFL %i,%x,%X",[0x71] RMOP,0, optab660F71,[0x72] RMOP,0, optab660F72,[0x73] RMOP,0, optab660F73,[0x7E] RM,0, "MOV%S %X,%e",[0x7F] RM,0, "MOVO %X,%x",[0xC4] RM,Ib, "PINSRW %i,%e,%X",[0xC5] RMR,Ib, "PEXTRW %i,%X,%e",[0xD4] RM,0, "PADDQ %x,%X",[0xD5] RM,0, "PMULLW %x,%X",[0xD6] RM,0, "MOVQ %X,%x",[0xE6] RM,0, "CVTTPD2PL %x,%X",[0xE7] RM,0, "MOVNTO %X,%e",[0xF7] RM,0, "MASKMOVOU %x,%X",};static Optable optabF20F[256]={[0x10] RM,0, "MOVSD %x,%X",[0x11] RM,0, "MOVSD %X,%x",[0x2A] RM,0, "CVTS%S2SD %e,%X",[0x2C] RM,0, "CVTTSD2S%S %x,%r",[0x2D] RM,0, "CVTSD2S%S %x,%r",[0x5A] RM,0, "CVTSD2SS %x,%X",[0x6F] RM,0, "MOVOU %x,%X",[0x70] RM,Ib, "PSHUFLW %i,%x,%X",[0x7F] RM,0, "MOVOU %X,%x",[0xD6] RM,0, "MOVQOZX %M,%X",[0xE6] RM,0, "CVTPD2PL %x,%X",};static Optable optabF30F[256]={[0x10] RM,0, "MOVSS %x,%X",[0x11] RM,0, "MOVSS %X,%x",[0x2A] RM,0, "CVTS%S2SS %e,%X",[0x2C] RM,0, "CVTTSS2S%S %x,%r",[0x2D] RM,0, "CVTSS2S%S %x,%r",[0x5A] RM,0, "CVTSS2SD %x,%X",[0x5B] RM,0, "CVTTPS2PL %x,%X",[0x6F] RM,0, "MOVOU %x,%X",[0x70] RM,Ib, "PSHUFHW %i,%x,%X",[0x7E] RM,0, "MOVQOZX %x,%X",[0x7F] RM,0, "MOVOU %X,%x",[0xD6] RM,0, "MOVQOZX %m*,%X",[0xE6] RM,0, "CVTPL2PD %x,%X",};static Optable optab0F[256]={[0x00] RMOP,0, optab0F00,[0x01] RMOP,0, optab0F01,[0x02] RM,0, "LAR %e,%r",[0x03] RM,0, "LSL %e,%r",[0x05] 0,0, "SYSCALL",[0x06] 0,0, "CLTS",[0x07] 0,0, "SYSRET",[0x08] 0,0, "INVD",[0x09] 0,0, "WBINVD",[0x0B] 0,0, "UD2",[0x0F] RM,AUX, optab0F0F, /* 3DNow! */[0x10] RM,0, "MOVU%s %x,%X",[0x11] RM,0, "MOVU%s %X,%x",[0x12] RM,0, "MOV[H]L%s %x,%X", /* TO DO: H if source is XMM */[0x13] RM,0, "MOVL%s %X,%e",[0x14] RM,0, "UNPCKL%s %x,%X",[0x15] RM,0, "UNPCKH%s %x,%X",[0x16] RM,0, "MOV[L]H%s %x,%X", /* TO DO: L if source is XMM */[0x17] RM,0, "MOVH%s %X,%x",[0x20] RMR,0, "MOVL %C,%e",[0x21] RMR,0, "MOVL %D,%e",[0x22] RMR,0, "MOVL %e,%C",[0x23] RMR,0, "MOVL %e,%D",[0x24] RMR,0, "MOVL %T,%e",[0x26] RMR,0, "MOVL %e,%T",[0x28] RM,0, "MOVA%s %x,%X",[0x29] RM,0, "MOVA%s %X,%x",[0x2A] RM,0, "CVTPL2%s %m*,%X",[0x2B] RM,0, "MOVNT%s %X,%e",[0x2C] RM,0, "CVTT%s2PL %x,%M",[0x2D] RM,0, "CVT%s2PL %x,%M",[0x2E] RM,0, "UCOMISS %x,%X",[0x2F] RM,0, "COMISS %x,%X",[0x30] 0,0, "WRMSR",[0x31] 0,0, "RDTSC",[0x32] 0,0, "RDMSR",[0x33] 0,0, "RDPMC",[0x42] RM,0, "CMOVC %e,%r", /* CF */[0x43] RM,0, "CMOVNC %e,%r", /* ¬ CF */[0x44] RM,0, "CMOVZ %e,%r", /* ZF */[0x45] RM,0, "CMOVNZ %e,%r", /* ¬ ZF */[0x46] RM,0, "CMOVBE %e,%r", /* CF ∨ ZF */[0x47] RM,0, "CMOVA %e,%r", /* ¬CF ∧ ¬ZF */[0x48] RM,0, "CMOVS %e,%r", /* SF */[0x49] RM,0, "CMOVNS %e,%r", /* ¬ SF */[0x4A] RM,0, "CMOVP %e,%r", /* PF */[0x4B] RM,0, "CMOVNP %e,%r", /* ¬ PF */[0x4C] RM,0, "CMOVLT %e,%r", /* LT ≡ OF ≠ SF */[0x4D] RM,0, "CMOVGE %e,%r", /* GE ≡ ZF ∨ SF */[0x4E] RM,0, "CMOVLE %e,%r", /* LE ≡ ZF ∨ LT */[0x4F] RM,0, "CMOVGT %e,%r", /* GT ≡ ¬ZF ∧ GE */[0x50] RM,0, "MOVMSK%s %X,%r", /* TO DO: check */[0x51] RM,0, "SQRT%s %x,%X",[0x52] RM,0, "RSQRT%s %x,%X",[0x53] RM,0, "RCP%s %x,%X",[0x54] RM,0, "AND%s %x,%X",[0x55] RM,0, "ANDN%s %x,%X",[0x56] RM,0, "OR%s %x,%X", /* TO DO: S/D */[0x57] RM,0, "XOR%s %x,%X", /* S/D */[0x58] RM,0, "ADD%s %x,%X", /* S/P S/D */[0x59] RM,0, "MUL%s %x,%X",[0x5A] RM,0, "CVTPS2PD %x,%X",[0x5B] RM,0, "CVTPL2PS %x,%X",[0x5C] RM,0, "SUB%s %x,%X",[0x5D] RM,0, "MIN%s %x,%X",[0x5E] RM,0, "DIV%s %x,%X", /* TO DO: S/P S/D */[0x5F] RM,0, "MAX%s %x,%X",[0x60] RM,0, "PUNPCKLBW %m,%M",[0x61] RM,0, "PUNPCKLWL %m,%M",[0x62] RM,0, "PUNPCKLLQ %m,%M",[0x63] RM,0, "PACKSSWB %m,%M",[0x64] RM,0, "PCMPGTB %m,%M",[0x65] RM,0, "PCMPGTW %m,%M",[0x66] RM,0, "PCMPGTL %m,%M",[0x67] RM,0, "PACKUSWB %m,%M",[0x68] RM,0, "PUNPCKHBW %m,%M",[0x69] RM,0, "PUNPCKHWL %m,%M",[0x6A] RM,0, "PUNPCKHLQ %m,%M",[0x6B] RM,0, "PACKSSLW %m,%M",[0x6E] RM,0, "MOV%S %e,%M",[0x6F] RM,0, "MOVQ %m,%M",[0x70] RM,Ib, "PSHUFW %i,%m,%M",[0x74] RM,0, "PCMPEQB %m,%M",[0x75] RM,0, "PCMPEQW %m,%M",[0x76] RM,0, "PCMPEQL %m,%M",[0x7E] RM,0, "MOV%S %M,%e",[0x7F] RM,0, "MOVQ %M,%m",[0xAE] RMOP,0, optab0FAE,[0xAA] 0,0, "RSM",[0xB0] RM,0, "CMPXCHGB %r,%e",[0xB1] RM,0, "CMPXCHG%S %r,%e",[0xC0] RMB,0, "XADDB %r,%e",[0xC1] RM,0, "XADD%S %r,%e",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -