#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: db_disasm.c,v 1.28 2021/05/23 08:59:08 riastradh Exp $");
#ifndef _KERNEL
#include <sys/types.h>
#include <sys/time.h>
#include <sys/ksyms.h>
#endif
#include <sys/param.h>
#include <sys/proc.h>
#include <machine/db_machdep.h>
#include <ddb/db_access.h>
#include <ddb/db_sym.h>
#include <ddb/db_output.h>
#include <ddb/db_interface.h>
#ifndef _KERNEL
#define db_printsym(a, x, fn) fn("%lx ", (a))
#endif
#define BYTE 0
#define WORD 1
#define LONG 2
#define QUAD 3
#define SNGL 4
#define DBLR 5
#define EXTR 6
#define SDEP 7
#define NONE 8
#define REX_B 1
#define REX_X 2
#define REX_R 4
#define REX_W 8
#define REX 0x40
#define E 1
#define Eind 2
#define Ew 3
#define Eb 4
#define R 5
#define Rw 6
#define Ri 7
#define S 8
#define Si 9
#define A 10
#define BX 11
#define CL 12
#define DX 13
#define SI 14
#define DI 15
#define CR 16
#define DR 17
#define TR 18
#define I 19
#define Is 20
#define Ib 21
#define Ibs 22
#define Iw 23
#define Il 24
#define O 25
#define Db 26
#define Dl 27
#define o1 28
#define o3 29
#define OS 30
#define ST 31
#define STI 32
#define X 33
#define XA 34
#define Ed 35
#define Iq 36
#define Rv 40
struct inst {
const char *i_name;
short i_has_modrm;
short i_size;
int i_mode;
const void *i_extra;
};
#define op1(x) (x)
#define op2(x,y) ((x)|((y)<<8))
#define op3(x,y,z) ((x)|((y)<<8)|((z)<<16))
struct finst {
const char *f_name;
int f_size;
int f_rrmode;
const void *f_rrname;
};
const char * const db_Grp6[] = {
"sldt",
"str",
"lldt",
"ltr",
"verr",
"verw",
"",
""
};
const char * const db_Grp7[] = {
"sgdt",
"sidt",
"lgdt",
"lidt",
"smsw",
"",
"lmsw",
"invlpg"
};
const char * const db_Grp8[] = {
"",
"",
"",
"",
"bt",
"bts",
"btr",
"btc"
};
const char * const db_Grp9[] = {
"",
"cmpxchg8b",
"",
"",
"",
"",
"vmptrld",
"vmptrst"
};
const struct inst db_Grp9b[] = {
{ "", true, NONE, 0, 0 },
{ "", true, NONE, 0, 0 },
{ "", true, NONE, 0, 0 },
{ "", true, NONE, 0, 0 },
{ "", true, NONE, 0, 0 },
{ "", true, NONE, 0, 0 },
{ "rdrand",true, LONG, op1(Rv), 0 },
{ "rdseed",true, LONG, op1(Rv), 0 }
};
const struct inst db_inst_0f0x[] = {
{ "", true, NONE, op1(Ew), db_Grp6 },
{ "", true, NONE, op1(Ew), db_Grp7 },
{ "lar", true, LONG, op2(E,R), 0 },
{ "lsl", true, LONG, op2(E,R), 0 },
{ "", false, NONE, 0, 0 },
{ "syscall",false,NONE, 0, 0 },
{ "clts", false, NONE, 0, 0 },
{ "sysret",false, NONE, 0, 0 },
{ "invd", false, NONE, 0, 0 },
{ "wbinvd",false, NONE, 0, 0 },
{ "", false, NONE, 0, 0 },
{ "ud2", false, NONE, 0, 0 },
{ "", false, NONE, 0, 0 },
{ "prefetch",true,NONE, op2(E,R), 0 },
{ "", false, NONE, 0, 0 },
{ "", false, NONE, 0, 0 },
};
const struct inst db_inst_0f1x[] = {
{ "", false, NONE, 0, 0 },
{ "", false, NONE, 0, 0 },
{ "", false, NONE, 0, 0 },
{ "", false, NONE, 0, 0 },
{ "", false, NONE, 0, 0 },
{ "", false, NONE, 0, 0 },
{ "", false, NONE, 0, 0 },
{ "", false, NONE, 0, 0 },
{ "", false, NONE, 0, 0 },
{ "", false, NONE, 0, 0 },
{ "", false, NONE, 0, 0 },
{ "", false, NONE, 0, 0 },
{ "", false, NONE, 0, 0 },
{ "", false, NONE, 0, 0 },
{ "", false, NONE, 0, 0 },
{ "nopl", true, SDEP, 0, "nopw" },
};
const struct inst db_inst_0f2x[] = {
{ "mov", true, LONG, op2(CR,E), 0 },
{ "mov", true, LONG, op2(DR,E), 0 },
{ "mov", true, LONG, op2(E,CR), 0 },
{ "mov", true, LONG, op2(E,DR), 0 },
{ "mov", true, LONG, op2(TR,E), 0 },
{ "", false, NONE, 0, 0 },
{ "mov", true, LONG, op2(E,TR), 0 },
{ "", false, NONE, 0, 0 },
{ "", false, NONE, 0, 0 },
{ "", false, NONE, 0, 0 },
{ "", false, NONE, 0, 0 },
{ "", false, NONE, 0, 0 },
{ "", false, NONE, 0, 0 },
{ "", false, NONE, 0, 0 },
{ "", false, NONE, 0, 0 },
{ "", false, NONE, 0, 0 },
};
const struct inst db_inst_0f3x[] = {
{ "wrmsr", false, NONE, 0, 0 },
{ "rdtsc", false, NONE, 0, 0 },
{ "rdmsr", false, NONE, 0, 0 },
{ "rdpmc", false, NONE, 0, 0 },
{ "sysenter",false,NONE, 0, 0 },
{ "sysexit",false, NONE, 0, 0 },
{ "", false, NONE, 0, 0 },
{ "getsec",false, NONE, 0, 0 },
{ "", false, NONE, 0, 0 },
{ "", false, NONE, 0, 0 },
{ "", false, NONE, 0, 0 },
{ "", false, NONE, 0, 0 },
{ "", false, NONE, 0, 0 },
{ "", false, NONE, 0, 0 },
{ "", false, NONE, 0, 0 },
{ "", false, NONE, 0, 0 },
};
const struct inst db_inst_0f4x[] = {
{ "cmovo", true, LONG, op2(E,R), 0 },
{ "cmovno", true, LONG, op2(E,R), 0 },
{ "cmovc", true, LONG, op2(E,R), 0 },
{ "cmovnc", true, LONG, op2(E,R), 0 },
{ "cmovz", true, LONG, op2(E,R), 0 },
{ "cmovnz", true, LONG, op2(E,R), 0 },
{ "cmovbe", true, LONG, op2(E,R), 0 },
{ "cmovmbe",true, LONG, op2(E,R), 0 },
{ "cmovs", true, LONG, op2(E,R), 0 },
{ "cmovns", true, LONG, op2(E,R), 0 },
{ "cmovp", true, LONG, op2(E,R), 0 },
{ "cmovnp", true, LONG, op2(E,R), 0 },
{ "cmovl", true, LONG, op2(E,R), 0 },
{ "cmovnl", true, LONG, op2(E,R), 0 },
{ "cmovle", true, LONG, op2(E,R), 0 },
{ "cmovnle",true, LONG, op2(E,R), 0 },
};
const struct inst db_inst_0f8x[] = {
{ "jo", false, NONE, op1(Dl), 0 },
{ "jno", false, NONE, op1(Dl), 0 },
{ "jb", false, NONE, op1(Dl), 0 },
{ "jnb", false, NONE, op1(Dl), 0 },
{ "jz", false, NONE, op1(Dl), 0 },
{ "jnz", false, NONE, op1(Dl), 0 },
{ "jbe", false, NONE, op1(Dl), 0 },
{ "jnbe", false, NONE, op1(Dl), 0 },
{ "js", false, NONE, op1(Dl), 0 },
{ "jns", false, NONE, op1(Dl), 0 },
{ "jp", false, NONE, op1(Dl), 0 },
{ "jnp", false, NONE, op1(Dl), 0 },
{ "jl", false, NONE, op1(Dl), 0 },
{ "jnl", false, NONE, op1(Dl), 0 },
{ "jle", false, NONE, op1(Dl), 0 },
{ "jnle", false, NONE, op1(Dl), 0 },
};
const struct inst db_inst_0f9x[] = {
{ "seto", true, NONE, op1(Eb), 0 },
{ "setno", true, NONE, op1(Eb), 0 },
{ "setb", true, NONE, op1(Eb), 0 },
{ "setnb", true, NONE, op1(Eb), 0 },
{ "setz", true, NONE, op1(Eb), 0 },
{ "setnz", true, NONE, op1(Eb), 0 },
{ "setbe", true, NONE, op1(Eb), 0 },
{ "setnbe",true, NONE, op1(Eb), 0 },
{ "sets", true, NONE, op1(Eb), 0 },
{ "setns", true, NONE, op1(Eb), 0 },
{ "setp", true, NONE, op1(Eb), 0 },
{ "setnp", true, NONE, op1(Eb), 0 },
{ "setl", true, NONE, op1(Eb), 0 },
{ "setnl", true, NONE, op1(Eb), 0 },
{ "setle", true, NONE, op1(Eb), 0 },
{ "setnle",true, NONE, op1(Eb), 0 },
};
const struct inst db_inst_0fax[] = {
{ "push", false, NONE, op1(Si), 0 },
{ "pop", false, NONE, op1(Si), 0 },
{ "cpuid", false, NONE, 0, 0 },
{ "bt", true, LONG, op2(R,E), 0 },
{ "shld", true, LONG, op3(Ib,R,E), 0 },
{ "shld", true, LONG, op3(CL,R,E), 0 },
{ "", false, NONE, 0, 0 },
{ "", false, NONE, 0, 0 },
{ "push", false, NONE, op1(Si), 0 },
{ "pop", false, NONE, op1(Si), 0 },
{ "rsm", false, NONE, 0, 0 },
{ "bts", true, LONG, op2(R,E), 0 },
{ "shrd", true, LONG, op3(Ib,R,E), 0 },
{ "shrd", true, LONG, op3(CL,R,E), 0 },
{ "fxsave",true, LONG, 0, 0 },
{ "imul", true, LONG, op2(E,R), 0 },
};
const struct inst db_inst_0fbx[] = {
{ "cmpxchg",true, BYTE, op2(R, E), 0 },
{ "cmpxchg",true, LONG, op2(R, E), 0 },
{ "lss", true, LONG, op2(E, R), 0 },
{ "btr", true, LONG, op2(R, E), 0 },
{ "lfs", true, LONG, op2(E, R), 0 },
{ "lgs", true, LONG, op2(E, R), 0 },
{ "movzb", true, LONG, op2(E, R), 0 },
{ "movzw", true, LONG, op2(E, R), 0 },
{ "", false, NONE, 0, 0 },
{ "", false, NONE, 0, 0 },
{ "", true, LONG, op2(Ib, E), db_Grp8 },
{ "btc", true, LONG, op2(R, E), 0 },
{ "bsf", true, LONG, op2(E, R), 0 },
{ "bsr", true, LONG, op2(E, R), 0 },
{ "movsb", true, LONG, op2(E, R), 0 },
{ "movsw", true, LONG, op2(E, R), 0 },
};
const struct inst db_inst_0fcx[] = {
{ "xadd", true, BYTE, op2(R, E), 0 },
{ "xadd", true, LONG, op2(R, E), 0 },
{ "", false, NONE, 0, 0 },
{ "", false, NONE, 0, 0 },
{ "", false, NONE, 0, 0 },
{ "", false, NONE, 0, 0 },
{ "", false, NONE, 0, 0 },
{ "", true, NONE, op1(E), db_Grp9 },
{ "bswap", false, LONG, op1(Ri), 0 },
{ "bswap", false, LONG, op1(Ri), 0 },
{ "bswap", false, LONG, op1(Ri), 0 },
{ "bswap", false, LONG, op1(Ri), 0 },
{ "bswap", false, LONG, op1(Ri), 0 },
{ "bswap", false, LONG, op1(Ri), 0 },
{ "bswap", false, LONG, op1(Ri), 0 },
{ "bswap", false, LONG, op1(Ri), 0 },
};
const struct inst * const db_inst_0f[] = {
db_inst_0f0x,
db_inst_0f1x,
db_inst_0f2x,
db_inst_0f3x,
db_inst_0f4x,
NULL,
NULL,
NULL,
db_inst_0f8x,
db_inst_0f9x,
db_inst_0fax,
db_inst_0fbx,
db_inst_0fcx,
NULL,
NULL,
NULL
};
const char * const db_Esc92[] = {
"fnop", "", "", "", "", "", "", ""
};
const char * const db_Esc93[] = {
"", "", "", "", "", "", "", ""
};
const char * const db_Esc94[] = {
"fchs", "fabs", "", "", "ftst", "fxam", "", ""
};
const char * const db_Esc95[] = {
"fld1", "fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz",""
};
const char * const db_Esc96[] = {
"f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp",
"fincstp"
};
const char * const db_Esc97[] = {
"fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos"
};
const char * const db_Esca4[] = {
"", "fucompp","", "", "", "", "", ""
};
const char * const db_Escb4[] = {
"", "", "fnclex","fninit","", "", "", ""
};
const char * const db_Esce3[] = {
"", "fcompp","", "", "", "", "", ""
};
const char * const db_Escf4[] = {
"fnstsw","", "", "", "", "", "", ""
};
const struct finst db_Esc8[] = {
{ "fadd", SNGL, op2(STI,ST), 0 },
{ "fmul", SNGL, op2(STI,ST), 0 },
{ "fcom", SNGL, op2(STI,ST), 0 },
{ "fcomp", SNGL, op2(STI,ST), 0 },
{ "fsub", SNGL, op2(STI,ST), 0 },
{ "fsubr", SNGL, op2(STI,ST), 0 },
{ "fdiv", SNGL, op2(STI,ST), 0 },
{ "fdivr", SNGL, op2(STI,ST), 0 },
};
const struct finst db_Esc9[] = {
{ "fld", SNGL, op1(STI), 0 },
{ "", NONE, op1(STI), "fxch" },
{ "fst", SNGL, op1(X), db_Esc92 },
{ "fstp", SNGL, op1(X), db_Esc93 },
{ "fldenv", NONE, op1(X), db_Esc94 },
{ "fldcw", NONE, op1(X), db_Esc95 },
{ "fnstenv",NONE, op1(X), db_Esc96 },
{ "fnstcw", NONE, op1(X), db_Esc97 },
};
const struct finst db_Esca[] = {
{ "fiadd", WORD, 0, 0 },
{ "fimul", WORD, 0, 0 },
{ "ficom", WORD, 0, 0 },
{ "ficomp", WORD, 0, 0 },
{ "fisub", WORD, op1(X), db_Esca4 },
{ "fisubr", WORD, 0, 0 },
{ "fidiv", WORD, 0, 0 },
{ "fidivr", WORD, 0, 0 }
};
const struct finst db_Escb[] = {
{ "fild", WORD, 0, 0 },
{ "", NONE, 0, 0 },
{ "fist", WORD, 0, 0 },
{ "fistp", WORD, 0, 0 },
{ "", WORD, op1(X), db_Escb4 },
{ "fld", EXTR, 0, 0 },
{ "", WORD, 0, 0 },
{ "fstp", EXTR, 0, 0 },
};
const struct finst db_Escc[] = {
{ "fadd", DBLR, op2(ST,STI), 0 },
{ "fmul", DBLR, op2(ST,STI), 0 },
{ "fcom", DBLR, op2(ST,STI), 0 },
{ "fcomp", DBLR, op2(ST,STI), 0 },
{ "fsub", DBLR, op2(ST,STI), "fsubr" },
{ "fsubr", DBLR, op2(ST,STI), "fsub" },
{ "fdiv", DBLR, op2(ST,STI), "fdivr" },
{ "fdivr", DBLR, op2(ST,STI), "fdiv" },
};
const struct finst db_Escd[] = {
{ "fld", DBLR, op1(STI), "ffree" },
{ "", NONE, 0, 0 },
{ "fst", DBLR, op1(STI), 0 },
{ "fstp", DBLR, op1(STI), 0 },
{ "frstor", NONE, op1(STI), "fucom" },
{ "", NONE, op1(STI), "fucomp" },
{ "fnsave", NONE, 0, 0 },
{ "fnstsw", NONE, 0, 0 },
};
const struct finst db_Esce[] = {
{ "fiadd", LONG, op2(ST,STI), "faddp" },
{ "fimul", LONG, op2(ST,STI), "fmulp" },
{ "ficom", LONG, 0, 0 },
{ "ficomp", LONG, op1(X), db_Esce3 },
{ "fisub", LONG, op2(ST,STI), "fsubrp" },
{ "fisubr", LONG, op2(ST,STI), "fsubp" },
{ "fidiv", LONG, op2(ST,STI), "fdivrp" },
{ "fidivr", LONG, op2(ST,STI), "fdivp" },
};
const struct finst db_Escf[] = {
{ "fild", LONG, 0, 0 },
{ "", LONG, 0, 0 },
{ "fist", LONG, 0, 0 },
{ "fistp", LONG, 0, 0 },
{ "fbld", NONE, op1(XA), db_Escf4 },
{ "fld", QUAD, 0, 0 },
{ "fbstp", NONE, 0, 0 },
{ "fstp", QUAD, 0, 0 },
};
const struct finst * const db_Esc_inst[] = {
db_Esc8, db_Esc9, db_Esca, db_Escb,
db_Escc, db_Escd, db_Esce, db_Escf
};
const char * const db_Grp1[] = {
"add",
"or",
"adc",
"sbb",
"and",
"sub",
"xor",
"cmp"
};
const char * const db_Grp2[] = {
"rol",
"ror",
"rcl",
"rcr",
"shl",
"shr",
"shl",
"sar"
};
const struct inst db_Grp3[] = {
{ "test", true, NONE, op2(I,E), 0 },
{ "test", true, NONE, op2(I,E), 0 },
{ "not", true, NONE, op1(E), 0 },
{ "neg", true, NONE, op1(E), 0 },
{ "mul", true, NONE, op2(E,A), 0 },
{ "imul", true, NONE, op2(E,A), 0 },
{ "div", true, NONE, op2(E,A), 0 },
{ "idiv", true, NONE, op2(E,A), 0 },
};
const struct inst db_Grp4[] = {
{ "inc", true, BYTE, op1(E), 0 },
{ "dec", true, BYTE, op1(E), 0 },
{ "", true, NONE, 0, 0 },
{ "", true, NONE, 0, 0 },
{ "", true, NONE, 0, 0 },
{ "", true, NONE, 0, 0 },
{ "", true, NONE, 0, 0 },
{ "", true, NONE, 0, 0 }
};
const struct inst db_Grp5[] = {
{ "inc", true, LONG, op1(E), 0 },
{ "dec", true, LONG, op1(E), 0 },
{ "call", true, NONE, op1(Eind),0 },
{ "lcall", true, NONE, op1(Eind),0 },
{ "jmp", true, NONE, op1(Eind),0 },
{ "ljmp", true, NONE, op1(Eind),0 },
{ "push", true, LONG, op1(E), 0 },
{ "", true, NONE, 0, 0 }
};
const struct inst db_inst_table[256] = {
{ "add", true, BYTE, op2(R, E), 0 },
{ "add", true, LONG, op2(R, E), 0 },
{ "add", true, BYTE, op2(E, R), 0 },
{ "add", true, LONG, op2(E, R), 0 },
{ "add", false, BYTE, op2(Is, A), 0 },
{ "add", false, LONG, op2(Is, A), 0 },
{ "push", false, NONE, op1(Si), 0 },
{ "pop", false, NONE, op1(Si), 0 },
{ "or", true, BYTE, op2(R, E), 0 },
{ "or", true, LONG, op2(R, E), 0 },
{ "or", true, BYTE, op2(E, R), 0 },
{ "or", true, LONG, op2(E, R), 0 },
{ "or", false, BYTE, op2(I, A), 0 },
{ "or", false, LONG, op2(I, A), 0 },
{ "push", false, NONE, op1(Si), 0 },
{ "", false, NONE, 0, 0 },
{ "adc", true, BYTE, op2(R, E), 0 },
{ "adc", true, LONG, op2(R, E), 0 },
{ "adc", true, BYTE, op2(E, R), 0 },
{ "adc", true, LONG, op2(E, R), 0 },
{ "adc", false, BYTE, op2(Is, A), 0 },
{ "adc", false, LONG, op2(Is, A), 0 },
{ "push", false, NONE, op1(Si), 0 },
{ "pop", false, NONE, op1(Si), 0 },
{ "sbb", true, BYTE, op2(R, E), 0 },
{ "sbb", true, LONG, op2(R, E), 0 },
{ "sbb", true, BYTE, op2(E, R), 0 },
{ "sbb", true, LONG, op2(E, R), 0 },
{ "sbb", false, BYTE, op2(Is, A), 0 },
{ "sbb", false, LONG, op2(Is, A), 0 },
{ "push", false, NONE, op1(Si), 0 },
{ "pop", false, NONE, op1(Si), 0 },
{ "and", true, BYTE, op2(R, E), 0 },
{ "and", true, LONG, op2(R, E), 0 },
{ "and", true, BYTE, op2(E, R), 0 },
{ "and", true, LONG, op2(E, R), 0 },
{ "and", false, BYTE, op2(I, A), 0 },
{ "and", false, LONG, op2(I, A), 0 },
{ "", false, NONE, 0, 0 },
{ "daa", false, NONE, 0, 0 },
{ "sub", true, BYTE, op2(R, E), 0 },
{ "sub", true, LONG, op2(R, E), 0 },
{ "sub", true, BYTE, op2(E, R), 0 },
{ "sub", true, LONG, op2(E, R), 0 },
{ "sub", false, BYTE, op2(Is, A), 0 },
{ "sub", false, LONG, op2(Is, A), 0 },
{ "", false, NONE, 0, 0 },
{ "das", false, NONE, 0, 0 },
{ "xor", true, BYTE, op2(R, E), 0 },
{ "xor", true, LONG, op2(R, E), 0 },
{ "xor", true, BYTE, op2(E, R), 0 },
{ "xor", true, LONG, op2(E, R), 0 },
{ "xor", false, BYTE, op2(I, A), 0 },
{ "xor", false, LONG, op2(I, A), 0 },
{ "", false, NONE, 0, 0 },
{ "aaa", false, NONE, 0, 0 },
{ "cmp", true, BYTE, op2(R, E), 0 },
{ "cmp", true, LONG, op2(R, E), 0 },
{ "cmp", true, BYTE, op2(E, R), 0 },
{ "cmp", true, LONG, op2(E, R), 0 },
{ "cmp", false, BYTE, op2(Is, A), 0 },
{ "cmp", false, LONG, op2(Is, A), 0 },
{ "", false, NONE, 0, 0 },
{ "aas", false, NONE, 0, 0 },
{ "inc", false, LONG, op1(Ri), 0 },
{ "inc", false, LONG, op1(Ri), 0 },
{ "inc", false, LONG, op1(Ri), 0 },
{ "inc", false, LONG, op1(Ri), 0 },
{ "inc", false, LONG, op1(Ri), 0 },
{ "inc", false, LONG, op1(Ri), 0 },
{ "inc", false, LONG, op1(Ri), 0 },
{ "inc", false, LONG, op1(Ri), 0 },
{ "dec", false, LONG, op1(Ri), 0 },
{ "dec", false, LONG, op1(Ri), 0 },
{ "dec", false, LONG, op1(Ri), 0 },
{ "dec", false, LONG, op1(Ri), 0 },
{ "dec", false, LONG, op1(Ri), 0 },
{ "dec", false, LONG, op1(Ri), 0 },
{ "dec", false, LONG, op1(Ri), 0 },
{ "dec", false, LONG, op1(Ri), 0 },
{ "push", false, QUAD, op1(Ri), 0 },
{ "push", false, QUAD, op1(Ri), 0 },
{ "push", false, QUAD, op1(Ri), 0 },
{ "push", false, QUAD, op1(Ri), 0 },
{ "push", false, QUAD, op1(Ri), 0 },
{ "push", false, QUAD, op1(Ri), 0 },
{ "push", false, QUAD, op1(Ri), 0 },
{ "push", false, QUAD, op1(Ri), 0 },
{ "pop", false, QUAD, op1(Ri), 0 },
{ "pop", false, QUAD, op1(Ri), 0 },
{ "pop", false, QUAD, op1(Ri), 0 },
{ "pop", false, QUAD, op1(Ri), 0 },
{ "pop", false, QUAD, op1(Ri), 0 },
{ "pop", false, QUAD, op1(Ri), 0 },
{ "pop", false, QUAD, op1(Ri), 0 },
{ "pop", false, QUAD, op1(Ri), 0 },
{ "pusha", false, LONG, 0, 0 },
{ "popa", false, LONG, 0, 0 },
{ "bound", true, LONG, op2(E, R), 0 },
#if 0
{ "arpl", true, NONE, op2(Ew,Rw), 0 },
#else
{ "movslq",true, NONE, op2(Ed, R), 0 },
#endif
{ "", false, NONE, 0, 0 },
{ "", false, NONE, 0, 0 },
{ "", false, NONE, 0, 0 },
{ "", false, NONE, 0, 0 },
{ "push", false, LONG, op1(I), 0 },
{ "imul", true, LONG, op3(I,E,R), 0 },
{ "push", false, LONG, op1(Ib), 0 },
{ "imul", true, LONG, op3(Ibs,E,R),0 },
{ "ins", false, BYTE, op2(DX, DI), 0 },
{ "ins", false, LONG, op2(DX, DI), 0 },
{ "outs", false, BYTE, op2(SI, DX), 0 },
{ "outs", false, LONG, op2(SI, DX), 0 },
{ "jo", false, NONE, op1(Db), 0 },
{ "jno", false, NONE, op1(Db), 0 },
{ "jb", false, NONE, op1(Db), 0 },
{ "jnb", false, NONE, op1(Db), 0 },
{ "jz", false, NONE, op1(Db), 0 },
{ "jnz", false, NONE, op1(Db), 0 },
{ "jbe", false, NONE, op1(Db), 0 },
{ "jnbe", false, NONE, op1(Db), 0 },
{ "js", false, NONE, op1(Db), 0 },
{ "jns", false, NONE, op1(Db), 0 },
{ "jp", false, NONE, op1(Db), 0 },
{ "jnp", false, NONE, op1(Db), 0 },
{ "jl", false, NONE, op1(Db), 0 },
{ "jnl", false, NONE, op1(Db), 0 },
{ "jle", false, NONE, op1(Db), 0 },
{ "jnle", false, NONE, op1(Db), 0 },
{ "", true, BYTE, op2(I, E), db_Grp1 },
{ "", true, LONG, op2(I, E), db_Grp1 },
{ "", true, BYTE, op2(Is,E), db_Grp1 },
{ "", true, LONG, op2(Ibs,E), db_Grp1 },
{ "test", true, BYTE, op2(R, E), 0 },
{ "test", true, LONG, op2(R, E), 0 },
{ "xchg", true, BYTE, op2(R, E), 0 },
{ "xchg", true, LONG, op2(R, E), 0 },
{ "mov", true, BYTE, op2(R, E), 0 },
{ "mov", true, LONG, op2(R, E), 0 },
{ "mov", true, BYTE, op2(E, R), 0 },
{ "mov", true, LONG, op2(E, R), 0 },
{ "mov", true, NONE, op2(S, Ew), 0 },
{ "lea", true, LONG, op2(E, R), 0 },
{ "mov", true, NONE, op2(Ew, S), 0 },
{ "pop", true, LONG, op1(E), 0 },
{ "nop", false, NONE, 0, 0 },
{ "xchg", false, LONG, op2(A, Ri), 0 },
{ "xchg", false, LONG, op2(A, Ri), 0 },
{ "xchg", false, LONG, op2(A, Ri), 0 },
{ "xchg", false, LONG, op2(A, Ri), 0 },
{ "xchg", false, LONG, op2(A, Ri), 0 },
{ "xchg", false, LONG, op2(A, Ri), 0 },
{ "xchg", false, LONG, op2(A, Ri), 0 },
{ "cbw", false, SDEP, 0, "cwde" },
{ "cwd", false, SDEP, 0, "cdq" },
{ "lcall", false, NONE, op1(OS), 0 },
{ "wait", false, NONE, 0, 0 },
{ "pushf", false, LONG, 0, 0 },
{ "popf", false, LONG, 0, 0 },
{ "sahf", false, NONE, 0, 0 },
{ "lahf", false, NONE, 0, 0 },
{ "mov", false, BYTE, op2(O, A), 0 },
{ "mov", false, LONG, op2(O, A), 0 },
{ "mov", false, BYTE, op2(A, O), 0 },
{ "mov", false, LONG, op2(A, O), 0 },
{ "movs", false, BYTE, op2(SI,DI), 0 },
{ "movs", false, LONG, op2(SI,DI), 0 },
{ "cmps", false, BYTE, op2(SI,DI), 0 },
{ "cmps", false, LONG, op2(SI,DI), 0 },
{ "test", false, BYTE, op2(I, A), 0 },
{ "test", false, LONG, op2(I, A), 0 },
{ "stos", false, BYTE, op1(DI), 0 },
{ "stos", false, LONG, op1(DI), 0 },
{ "lods", false, BYTE, op1(SI), 0 },
{ "lods", false, LONG, op1(SI), 0 },
{ "scas", false, BYTE, op1(SI), 0 },
{ "scas", false, LONG, op1(SI), 0 },
{ "mov", false, BYTE, op2(I, Ri), 0 },
{ "mov", false, BYTE, op2(I, Ri), 0 },
{ "mov", false, BYTE, op2(I, Ri), 0 },
{ "mov", false, BYTE, op2(I, Ri), 0 },
{ "mov", false, BYTE, op2(I, Ri), 0 },
{ "mov", false, BYTE, op2(I, Ri), 0 },
{ "mov", false, BYTE, op2(I, Ri), 0 },
{ "mov", false, BYTE, op2(I, Ri), 0 },
{ "mov", false, LONG, op2(Iq, Ri), 0 },
{ "mov", false, LONG, op2(Iq, Ri), 0 },
{ "mov", false, LONG, op2(Iq, Ri), 0 },
{ "mov", false, LONG, op2(Iq, Ri), 0 },
{ "mov", false, LONG, op2(Iq, Ri), 0 },
{ "mov", false, LONG, op2(Iq, Ri), 0 },
{ "mov", false, LONG, op2(Iq, Ri), 0 },
{ "mov", false, LONG, op2(Iq, Ri), 0 },
{ "", true, BYTE, op2(Ib, E), db_Grp2 },
{ "", true, LONG, op2(Ib, E), db_Grp2 },
{ "ret", false, NONE, op1(Iw), 0 },
{ "ret", false, NONE, 0, 0 },
{ "les", true, LONG, op2(E, R), 0 },
{ "lds", true, LONG, op2(E, R), 0 },
{ "mov", true, BYTE, op2(I, E), 0 },
{ "mov", true, LONG, op2(I, E), 0 },
{ "enter", false, NONE, op2(Ib, Iw), 0 },
{ "leave", false, NONE, 0, 0 },
{ "lret", false, NONE, op1(Iw), 0 },
{ "lret", false, NONE, 0, 0 },
{ "int", false, NONE, op1(o3), 0 },
{ "int", false, NONE, op1(Ib), 0 },
{ "into", false, NONE, 0, 0 },
{ "iret", false, NONE, 0, 0 },
{ "", true, BYTE, op2(o1, E), db_Grp2 },
{ "", true, LONG, op2(o1, E), db_Grp2 },
{ "", true, BYTE, op2(CL, E), db_Grp2 },
{ "", true, LONG, op2(CL, E), db_Grp2 },
{ "aam", true, NONE, 0, 0 },
{ "aad", true, NONE, 0, 0 },
{ "", false, NONE, 0, 0 },
{ "xlat", false, BYTE, op1(BX), 0 },
{ "", true, NONE, 0, db_Esc8 },
{ "", true, NONE, 0, db_Esc9 },
{ "", true, NONE, 0, db_Esca },
{ "", true, NONE, 0, db_Escb },
{ "", true, NONE, 0, db_Escc },
{ "", true, NONE, 0, db_Escd },
{ "", true, NONE, 0, db_Esce },
{ "", true, NONE, 0, db_Escf },
{ "loopne",false, NONE, op1(Db), 0 },
{ "loope", false, NONE, op1(Db), 0 },
{ "loop", false, NONE, op1(Db), 0 },
{ "jcxz", false, SDEP, op1(Db), "jecxz" },
{ "in", false, BYTE, op2(Ib, A), 0 },
{ "in", false, LONG, op2(Ib, A) , 0 },
{ "out", false, BYTE, op2(A, Ib), 0 },
{ "out", false, LONG, op2(A, Ib) , 0 },
{ "call", false, NONE, op1(Dl), 0 },
{ "jmp", false, NONE, op1(Dl), 0 },
{ "ljmp", false, NONE, op1(OS), 0 },
{ "jmp", false, NONE, op1(Db), 0 },
{ "in", false, BYTE, op2(DX, A), 0 },
{ "in", false, LONG, op2(DX, A) , 0 },
{ "out", false, BYTE, op2(A, DX), 0 },
{ "out", false, LONG, op2(A, DX) , 0 },
{ "", false, NONE, 0, 0 },
{ "", false, NONE, 0, 0 },
{ "", false, NONE, 0, 0 },
{ "", false, NONE, 0, 0 },
{ "hlt", false, NONE, 0, 0 },
{ "cmc", false, NONE, 0, 0 },
{ "", true, BYTE, 0, db_Grp3 },
{ "", true, LONG, 0, db_Grp3 },
{ "clc", false, NONE, 0, 0 },
{ "stc", false, NONE, 0, 0 },
{ "cli", false, NONE, 0, 0 },
{ "sti", false, NONE, 0, 0 },
{ "cld", false, NONE, 0, 0 },
{ "std", false, NONE, 0, 0 },
{ "", true, NONE, 0, db_Grp4 },
{ "", true, NONE, 0, db_Grp5 },
};
const struct inst db_bad_inst =
{ "???", false, NONE, 0, 0 }
;
#define f_mod(rex, byte) ((byte)>>6)
#define f_reg(rex, byte) ((((byte)>>3)&0x7) | (rex & REX_R ? 0x8 : 0x0))
#define f_rm(rex, byte) (((byte)&0x7) | (rex & REX_B ? 0x8 : 0x0))
#define sib_ss(rex, byte) ((byte)>>6)
#define sib_index(rex, byte) ((((byte)>>3)&0x7) | (rex & REX_X ? 0x8 : 0x0))
#define sib_base(rex, byte) (((byte)&0x7) | (rex & REX_B ? 0x8 : 0x0))
struct i_addr {
int is_reg;
int disp;
const char * base;
const char * index;
int ss;
};
const char * const db_index_reg_32[8] = {
"%ebx,%esi",
"%ebx,%edi",
"%ebp,%esi",
"%ebp,%edi",
"%esi",
"%edi",
"%ebp",
"%ebx"
};
#define DB_REG_DFLT 0
#define DB_REG_REX 1
const char * const db_reg[2][4][16] = {
{{"%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
"%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"},
{"%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
"%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"},
{"%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
"%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"},
{"%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
"%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15" }},
{{"%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
"%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"},
{"%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
"%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w" },
{"%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
"%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d" },
{"%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
"%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15" }}
};
const char * const db_seg_reg[8] = {
"%es", "%cs", "%ss", "%ds", "%fs", "%gs", "", ""
};
const int db_lengths[] = {
1,
2,
4,
4,
4,
8,
10,
};
const char * const rex_str[0x10] = {
"rex ",
"rex.b ",
"rex.x ",
"rex.xb ",
"rex.r ",
"rex.rb ",
"rex.rx ",
"rex.rxb ",
"rex.w ",
"rex.wb ",
"rex.wx ",
"rex.wxb ",
"rex.wr ",
"rex.wrb ",
"rex.wrx ",
"rex.wrxb ",
};
#define get_value_inc(result, loc, size, is_signed) \
do { \
result = db_get_value((loc), (size), (is_signed)); \
(loc) += (size); \
} while (0)
db_addr_t db_read_address(db_addr_t, int, u_int, int, struct i_addr *);
void db_print_address(const char *, u_int, int, struct i_addr *);
db_addr_t db_disasm_esc(db_addr_t, int, u_int, int, int, const char *);
db_addr_t
db_read_address(db_addr_t loc, int short_addr, u_int rex, int regmodrm,
struct i_addr *addrp)
{
int mod, rm, sib, index, disp, size, have_sib;
size = (short_addr ? LONG : QUAD);
mod = f_mod(rex, regmodrm);
rm = f_rm(rex, regmodrm);
if (mod == 3) {
addrp->is_reg = true;
addrp->disp = rm;
return (loc);
}
addrp->is_reg = false;
addrp->index = 0;
if ((rm & 0x7) == 4) {
get_value_inc(sib, loc, 1, false);
rm = sib_base(rex, sib);
index = sib_index(rex, sib);
if (index != 4)
addrp->index = db_reg[1][size][index];
addrp->ss = sib_ss(rex, sib);
have_sib = 1;
} else
have_sib = 0;
switch (mod) {
case 0:
if (rm == 5) {
get_value_inc(addrp->disp, loc, 4, false);
if (have_sib)
addrp->base = 0;
else if (short_addr)
addrp->base = "%eip";
else
addrp->base = "%rip";
} else {
addrp->disp = 0;
addrp->base = db_reg[1][size][rm];
}
break;
case 1:
get_value_inc(disp, loc, 1, true);
addrp->disp = disp;
addrp->base = db_reg[1][size][rm];
break;
case 2:
get_value_inc(disp, loc, 4, false);
addrp->disp = disp;
addrp->base = db_reg[1][size][rm];
break;
}
return (loc);
}
void
db_print_address(const char * seg, u_int rex, int size, struct i_addr *addrp)
{
if (addrp->is_reg) {
int ext = ((rex & REX_B) != 0);
db_printf("%s", db_reg[ext][size][addrp->disp]);
return;
}
if (seg)
db_printf("%s:", seg);
db_printsym((db_addr_t)addrp->disp, DB_STGY_ANY, db_printf);
if (addrp->base != 0 || addrp->index != 0) {
db_printf("(");
if (addrp->base)
db_printf("%s", addrp->base);
if (addrp->index)
db_printf(",%s,%d", addrp->index, 1<<addrp->ss);
db_printf(")");
}
}
db_addr_t
db_disasm_esc(db_addr_t loc, int inst, u_int rex, int short_addr, int size,
const char * seg)
{
int regmodrm;
const struct finst *fp;
int mod;
struct i_addr address;
const char * name;
get_value_inc(regmodrm, loc, 1, false);
fp = &db_Esc_inst[inst - 0xd8][f_reg(rex, regmodrm)];
mod = f_mod(rex, regmodrm);
if (mod != 3) {
if (*fp->f_name == '\0') {
db_printf("<bad instruction>");
return (loc);
}
loc = db_read_address(loc, short_addr, rex, regmodrm, &address);
db_printf("%s", fp->f_name);
switch (fp->f_size) {
case SNGL:
db_printf("s");
break;
case DBLR:
db_printf("l");
break;
case EXTR:
db_printf("t");
break;
case WORD:
db_printf("s");
break;
case LONG:
db_printf("l");
break;
case QUAD:
db_printf("q");
break;
default:
break;
}
db_printf("\t");
db_print_address(seg, rex, BYTE, &address);
} else {
switch (fp->f_rrmode) {
case op2(ST,STI):
name = (fp->f_rrname) ? fp->f_rrname : fp->f_name;
db_printf("%s\t%%st,%%st(%d)", name, f_rm(rex, regmodrm));
break;
case op2(STI,ST):
name = (fp->f_rrname) ? fp->f_rrname : fp->f_name;
db_printf("%s\t%%st(%d),%%st", name, f_rm(rex, regmodrm));
break;
case op1(STI):
name = (fp->f_rrname) ? fp->f_rrname : fp->f_name;
db_printf("%s\t%%st(%d)", name, f_rm(rex, regmodrm));
break;
case op1(X):
name = ((const char * const *)fp->f_rrname)[f_rm(rex, regmodrm)];
if (*name == '\0')
goto bad;
db_printf("%s", name);
break;
case op1(XA):
name = ((const char * const *)fp->f_rrname)[f_rm(rex, regmodrm)];
if (*name == '\0')
goto bad;
db_printf("%s\t%%ax", name);
break;
default:
bad:
db_printf("<bad instruction>");
break;
}
}
return (loc);
}
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;
uint64_t imm64;
int len;
struct i_addr address;
u_int rex = 0;
get_value_inc(inst, loc, 1, false);
short_addr = false;
size = LONG;
seg = 0;
prefix = true;
do {
switch (inst) {
case 0x66:
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 ");
break;
default:
prefix = false;
break;
}
if (inst >= 0x40 && inst <= 0x4f) {
rex = inst;
prefix = true;
}
if (prefix)
get_value_inc(inst, loc, 1, false);
} while (prefix);
if (rex != 0) {
if (rex & REX_W)
size = QUAD;
if (altfmt == true)
db_printf("%s", rex_str[rex & 0x0f]);
}
if (inst >= 0xd8 && inst <= 0xdf) {
loc = db_disasm_esc(loc, inst, rex, 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 {
ip = &db_inst_table[inst];
}
if (ip->i_has_modrm) {
get_value_inc(regmodrm, loc, 1, false);
loc = db_read_address(loc, short_addr, rex, regmodrm, &address);
}
i_name = ip->i_name;
i_size = ip->i_size;
i_mode = ip->i_mode;
if (ip->i_extra == db_Grp9 && f_mod(rex, regmodrm) == 3) {
ip = &db_Grp9b[f_reg(rex, regmodrm)];
i_name = ip->i_name;
i_size = ip->i_size;
i_mode = ip->i_mode;
} else if (ip->i_extra == (const char *)db_Grp1 ||
ip->i_extra == (const char *)db_Grp2 ||
ip->i_extra == (const char *)db_Grp6 ||
ip->i_extra == (const char *)db_Grp7 ||
ip->i_extra == (const char *)db_Grp8 ||
ip->i_extra == (const char *)db_Grp9) {
if (ip->i_extra == (const char *)db_Grp7 && regmodrm == 0xf8) {
i_name = "swapgs";
i_mode = 0;
} else if (ip->i_extra == (const char *)db_Grp7 && regmodrm == 0xcb) {
i_name = "stac";
i_mode = 0;
} else if (ip->i_extra == (const char *)db_Grp7 && regmodrm == 0xca) {
i_name = "clac";
i_mode = 0;
} else {
i_name = ((const char * const *)ip->i_extra)
[f_reg(rex, regmodrm)];
}
} else if (ip->i_extra == (const char *)db_Grp3) {
ip = (const struct inst *)ip->i_extra;
ip = &ip[f_reg(rex, regmodrm)];
i_name = ip->i_name;
i_mode = ip->i_mode;
} else if (ip->i_extra == (const char *)db_Grp4 ||
ip->i_extra == (const char *)db_Grp5) {
ip = (const struct inst *)ip->i_extra;
ip = &ip[f_reg(rex, regmodrm)];
i_name = ip->i_name;
i_mode = ip->i_mode;
i_size = ip->i_size;
}
if (i_size == SDEP) {
if (size == LONG)
db_printf("%s", i_name);
else
db_printf("%s", (const char *)ip->i_extra);
} else {
db_printf("%s", i_name);
if (i_size != NONE) {
if (i_size == BYTE) {
db_printf("b");
size = BYTE;
} else if (i_size == WORD) {
db_printf("w");
size = WORD;
} else if (size == WORD) {
db_printf("w");
} else if (i_size == QUAD) {
db_printf("q");
size = QUAD;
} else if (size == QUAD) {
db_printf("q");
} else {
db_printf("l");
}
}
}
db_printf("\t");
for (first = true; i_mode != 0; i_mode >>= 8, first = false) {
char tbuf[24];
if (!first)
db_printf(",");
switch (i_mode & 0xFF) {
case E:
case Eind:
case Ed:
case Ew:
case Eb:
if (!ip->i_has_modrm) {
db_printf("Bad address mode %#x without modrm",
i_mode);
break;
}
switch (i_mode & 0xFF) {
case E:
db_print_address(seg, rex, size, &address);
break;
case Eind:
db_printf("*");
db_print_address(seg, rex, size, &address);
break;
case Ed:
db_print_address(seg, rex, LONG, &address);
break;
case Ew:
db_print_address(seg, rex, WORD, &address);
break;
case Eb:
db_print_address(seg, rex, BYTE, &address);
break;
}
break;
case R: {
int ext = ((rex & REX_R) != 0);
db_printf("%s", db_reg[ext][size][f_reg(rex, regmodrm)]);
break;
}
case Rw: {
int ext = ((rex & REX_R) != 0);
db_printf("%s", db_reg[ext][WORD][f_reg(rex, regmodrm)]);
break;
}
case Ri: {
db_printf("%s", db_reg[0][size][f_rm(rex, inst)]);
break;
}
case S:
db_printf("%s", db_seg_reg[f_reg(rex, regmodrm)]);
break;
case Si:
db_printf("%s", db_seg_reg[f_reg(rex, inst)]);
break;
case A:
db_printf("%s", db_reg[0][size][0]);
break;
case BX:
if (seg)
db_printf("%s:", seg);
db_printf("(%s)", short_addr ? "%ebx" : "%rbx");
break;
case CL:
db_printf("%%cl");
break;
case DX:
db_printf("%%dx");
break;
case SI:
if (seg)
db_printf("%s:", seg);
db_printf("(%s)", short_addr ? "%esi" : "%rsi");
break;
case DI:
db_printf("%%es:(%s)", short_addr ? "%edi" : "%rdi");
break;
case CR:
db_printf("%%cr%d", f_reg(rex, regmodrm));
break;
case DR:
db_printf("%%dr%d", f_reg(rex, regmodrm));
break;
case TR:
db_printf("%%tr%d", f_reg(rex, regmodrm));
break;
case Iq:
if (size == QUAD) {
get_value_inc(imm64, loc, 8, false);
db_format_radix(tbuf, 24, imm64, true);
db_printf("$%s", tbuf);
break;
}
case I:
len = db_lengths[size];
get_value_inc(imm, loc, len, false);
db_format_radix(tbuf, 24, (unsigned int)imm, true);
db_printf("$%s", tbuf);
break;
case Is:
len = db_lengths[size];
get_value_inc(imm, loc, len, true);
db_format_radix(tbuf, 24, imm, true);
db_printf("$%s", tbuf);
break;
case Ib:
get_value_inc(imm, loc, 1, false);
db_format_radix(tbuf, 24, (unsigned int)imm, true);
db_printf("$%s", tbuf);
break;
case Ibs:
get_value_inc(imm, loc, 1, true);
db_format_radix(tbuf, 24, imm, true);
db_printf("$%s", tbuf);
break;
case Iw:
get_value_inc(imm, loc, 2, false);
db_format_radix(tbuf, 24, (unsigned int)imm, true);
db_printf("$%s", tbuf);
break;
case Il:
get_value_inc(imm, loc, 4, false);
db_format_radix(tbuf, 24, (unsigned int)imm, true);
db_printf("$%s", tbuf);
break;
case O:
if (short_addr)
get_value_inc(imm64, loc, 2, true);
else
get_value_inc(imm64, loc, 8, true);
if (seg) {
db_format_radix(tbuf, 24, imm64, true);
db_printf("%s:%s", seg, tbuf);
} else
db_printsym((db_addr_t)imm64, DB_STGY_ANY,
db_printf);
break;
case Db:
get_value_inc(displ, loc, 1, true);
db_printsym((db_addr_t)(displ + loc), DB_STGY_XTRN,
db_printf);
break;
case Dl:
get_value_inc(displ, loc, 4, true);
db_printsym((db_addr_t)(displ + loc), DB_STGY_XTRN,
db_printf);
break;
case o1:
db_printf("$1");
break;
case o3:
db_printf("$3");
break;
case OS:
get_value_inc(imm, loc, 4, false);
db_format_radix(tbuf, 24, (unsigned int)imm, true);
db_printf("$%s", tbuf);
get_value_inc(imm2, loc, 2, false);
db_format_radix(tbuf, 24, (unsigned int)imm2, true);
db_printf(",%s", tbuf);
break;
}
}
db_printf("\n");
return (loc);
}