/* * Disassemble instruction at 'loc'. 'altfmt' specifies an * (optional) alternate format. Return address of start of * next instruction. */ db_addr_t db_disasm(db_addr_t loc, boolean_t altfmt) { int inst; int size; int short_addr; char * seg; struct inst * ip; char * i_name; int i_size; int i_mode; int regmodrm = 0; boolean_t first; int displ; int prefix; int imm; int imm2; int len; struct i_addr address; char tmpfmt[24]; get_value_inc(inst, loc, 1, FALSE); short_addr = FALSE; size = LONG; seg = 0; /* * Get prefixes */ prefix = TRUE; do { switch (inst) { case 0x66: /* data16 */ size = WORD; break; case 0x67: short_addr = TRUE; break; case 0x26: seg = "%es"; break; case 0x36: seg = "%ss"; break; case 0x2e: seg = "%cs"; break; case 0x3e: seg = "%ds"; break; case 0x64: seg = "%fs"; break; case 0x65: seg = "%gs"; break; case 0xf0: db_printf("lock "); break; case 0xf2: db_printf("repne "); break; case 0xf3: db_printf("repe "); /* XXX repe VS rep */ break; default: prefix = FALSE; break; } if (prefix) get_value_inc(inst, loc, 1, FALSE); } while (prefix); if (inst >= 0xd8 && inst <= 0xdf) { loc = db_disasm_esc(loc, inst, short_addr, size, seg); db_printf("\n"); return (loc); } if (inst == 0x0f) { get_value_inc(inst, loc, 1, FALSE); ip = db_inst_0f[inst>>4]; if (ip == 0) ip = &db_bad_inst; else ip = &ip[inst&0xf]; } else {
/* * Disassemble instruction at 'loc'. 'altfmt' specifies an * (optional) alternate format. Return address of start of * next instruction. */ db_addr_t db_disasm(db_addr_t loc, boolean_t altfmt) { int inst; int size; int short_addr; char * seg; struct inst * ip; char * i_name; int i_size; int i_mode; int regmodrm = 0; boolean_t first; int displ; int prefix; long imm; int imm2; int len; int rex = 0; int segovr_grp; int repe, repne; struct i_addr address; db_addr_t loc_orig = loc; char tmpfmt[28]; get_value_inc(inst, loc, 1, FALSE); short_addr = FALSE; size = LONG; seg = 0; segovr_grp = 0; repe = 0; repne = 0; /* * Get prefixes */ prefix = TRUE; do { switch (inst) { case 0x66: /* data16 */ size = WORD; break; case 0x67: short_addr = TRUE; break; case 0x26: segovr_grp++; db_printf(" <segment override prefix ignored>"); break; case 0x36: db_printf(" <segment override prefix ignored>"); segovr_grp++; break; case 0x2e: db_printf(" <segment override prefix ignored>"); segovr_grp++; break; case 0x3e: db_printf(" <segment override prefix ignored>"); segovr_grp++; break; case 0x64: segovr_grp++; seg = "%fs"; break; case 0x65: segovr_grp++; seg = "%gs"; break; case 0xf0: db_printf("lock "); break; case 0xf2: repne++; break; case 0xf3: repe++; break; default: prefix = FALSE; break; } if (prefix) get_value_inc(inst, loc, 1, FALSE); } while (prefix); if (segovr_grp > 1) seg = "<bad segment override prefix combination> "; if (repe > 0 && repne > 0) db_printf("<bad repeat prefex combination> "); else if (repe > 0) db_printf("repe "); /* XXX "rep" if not CMPSx or SCASx */ else if (repne > 0) db_printf("repne "); if (inst >= 0x40 && inst <= 0x4f) { // rex page 14 rex = inst; if (REX_W(rex)) size = QUAD; get_value_inc(inst, loc, 1, FALSE); } if (inst >= 0xd8 && inst <= 0xdf) { loc = db_disasm_esc(loc, inst, short_addr, size, rex, seg); goto done; } if (inst == 0x0f) { get_value_inc(inst, loc, 1, FALSE); if (inst == 0x0f) { loc = db_disasm_3dnow(loc, short_addr, size, rex, seg); goto done; } ip = db_inst_0f[inst>>4]; if (ip == 0) ip = &db_bad_inst; else ip = &ip[inst&0xf]; } else {
/* * Disassemble instruction at 'loc'. 'altfmt' specifies an * (optional) alternate format. Return address of start of * next instruction. */ db_addr_t db_disasm( db_addr_t loc, bool altfmt) { int inst; int size; int short_addr; const char * seg; const struct inst * ip; const char * i_name; int i_size; int i_mode; int regmodrm = 0; bool first; int displ; int prefix; int imm; int imm2; int len; struct i_addr address; #ifdef _KERNEL pt_entry_t *pte, *pde; /* * Don't try to disassemble the location if the mapping is invalid. * If we do, we'll fault, and end up debugging the debugger! * in the case of largepages, "pte" is really the pde and "pde" is * really the entry for the pdp itself. */ if ((vaddr_t)loc >= VM_MIN_KERNEL_ADDRESS) pte = kvtopte((vaddr_t)loc); else pte = vtopte((vaddr_t)loc); pde = vtopte((vaddr_t)pte); if ((*pde & PG_V) == 0 || (*pte & PG_V) == 0) { db_printf("invalid address\n"); return (loc); } #endif get_value_inc(inst, loc, 1, false); short_addr = false; size = LONG; seg = 0; /* * Get prefixes */ prefix = true; do { switch (inst) { case 0x66: /* data16 */ size = WORD; break; case 0x67: short_addr = true; break; case 0x26: seg = "%es"; break; case 0x36: seg = "%ss"; break; case 0x2e: seg = "%cs"; break; case 0x3e: seg = "%ds"; break; case 0x64: seg = "%fs"; break; case 0x65: seg = "%gs"; break; case 0xf0: db_printf("lock "); break; case 0xf2: db_printf("repne "); break; case 0xf3: db_printf("repe "); /* XXX repe VS rep */ break; default: prefix = false; break; } if (prefix) get_value_inc(inst, loc, 1, false); } while (prefix); if (inst >= 0xd8 && inst <= 0xdf) { loc = db_disasm_esc(loc, inst, short_addr, size, seg); db_printf("\n"); return (loc); } if (inst == 0x0f) { get_value_inc(inst, loc, 1, false); ip = db_inst_0f[inst>>4]; if (ip == 0) ip = &db_bad_inst; else ip = &ip[inst&0xf]; } else {