From owner-p4-projects@FreeBSD.ORG Wed Mar 30 22:00:58 2005 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 7490316A4D1; Wed, 30 Mar 2005 22:00:58 +0000 (GMT) Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 2443616A4D0 for ; Wed, 30 Mar 2005 22:00:58 +0000 (GMT) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id CF5C943D5E for ; Wed, 30 Mar 2005 22:00:56 +0000 (GMT) (envelope-from peter@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.1/8.13.1) with ESMTP id j2UM0uh1070336 for ; Wed, 30 Mar 2005 22:00:56 GMT (envelope-from peter@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.1/8.13.1/Submit) id j2UM0ubP070333 for perforce@freebsd.org; Wed, 30 Mar 2005 22:00:56 GMT (envelope-from peter@freebsd.org) Date: Wed, 30 Mar 2005 22:00:56 GMT Message-Id: <200503302200.j2UM0ubP070333@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to peter@freebsd.org using -f From: Peter Wemm To: Perforce Change Reviews Subject: PERFORCE change 74127 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 30 Mar 2005 22:00:59 -0000 http://perforce.freebsd.org/chv.cgi?CH=74127 Change 74127 by peter@peter_daintree on 2005/03/30 22:00:39 snapshot at something that does a halfway reasonable attempt at disassembling itself. known bugs: movslq has the wrong source operand mode. it is coming out as %r instead of %e. might need a hack for this. gcc generates cmoveXX instructions with -O, there is no decoder for that. Affected files ... .. //depot/projects/hammer/sys/amd64/amd64/db_disasm.c#6 edit Differences ... ==== //depot/projects/hammer/sys/amd64/amd64/db_disasm.c#6 (text+ko) ==== @@ -30,11 +30,27 @@ /* * Instruction disassembler. */ +#ifdef _KERNEL #include #include #include #include +#else +#include +#include +#include + +typedef unsigned long db_addr_t; +#define db_printf printf +#define db_printsym(x, y) printf("%#lx", (long)(x)); +typedef int boolean_t; +typedef unsigned int db_expr_t; +#define FALSE 0 +#define TRUE 1 +void db_read_bytes(db_addr_t addr, int size, char *data) { memcpy(data, (void *)addr, size); } +db_expr_t db_get_value(db_addr_t addr, int size, boolean_t is_signed); +#endif /* * Size attributes @@ -50,6 +66,15 @@ #define NONE 8 /* + * REX prefix and bits + */ +#define REX_B 1 +#define REX_X 2 +#define REX_R 4 +#define REX_W 8 +#define REX 0x40 + +/* * Addressing modes */ #define E 1 /* general effective address */ @@ -585,23 +610,23 @@ /*3e*/ { "", FALSE, NONE, 0, 0 }, /*3f*/ { "aas", FALSE, NONE, 0, 0 }, -/*40*/ { "inc", FALSE, LONG, op1(Ri), 0 }, -/*41*/ { "inc", FALSE, LONG, op1(Ri), 0 }, -/*42*/ { "inc", FALSE, LONG, op1(Ri), 0 }, -/*43*/ { "inc", FALSE, LONG, op1(Ri), 0 }, -/*44*/ { "inc", FALSE, LONG, op1(Ri), 0 }, -/*45*/ { "inc", FALSE, LONG, op1(Ri), 0 }, -/*46*/ { "inc", FALSE, LONG, op1(Ri), 0 }, -/*47*/ { "inc", FALSE, LONG, op1(Ri), 0 }, +/*40*/ { "rex", FALSE, NONE, 0, 0 }, +/*41*/ { "rex.b", FALSE, NONE, 0, 0 }, +/*42*/ { "rex.x", FALSE, NONE, 0, 0 }, +/*43*/ { "rex.xb", FALSE, NONE, 0, 0 }, +/*44*/ { "rex.r", FALSE, NONE, 0, 0 }, +/*45*/ { "rex.rb", FALSE, NONE, 0, 0 }, +/*46*/ { "rex.rx", FALSE, NONE, 0, 0 }, +/*47*/ { "rex.rxb", FALSE, NONE, 0, 0 }, -/*48*/ { "dec", FALSE, LONG, op1(Ri), 0 }, -/*49*/ { "dec", FALSE, LONG, op1(Ri), 0 }, -/*4a*/ { "dec", FALSE, LONG, op1(Ri), 0 }, -/*4b*/ { "dec", FALSE, LONG, op1(Ri), 0 }, -/*4c*/ { "dec", FALSE, LONG, op1(Ri), 0 }, -/*4d*/ { "dec", FALSE, LONG, op1(Ri), 0 }, -/*4e*/ { "dec", FALSE, LONG, op1(Ri), 0 }, -/*4f*/ { "dec", FALSE, LONG, op1(Ri), 0 }, +/*48*/ { "rex.w", FALSE, NONE, 0, 0 }, +/*49*/ { "rex.wb", FALSE, NONE, 0, 0 }, +/*4a*/ { "rex.wx", FALSE, NONE, 0, 0 }, +/*4b*/ { "rex.wxb", FALSE, NONE, 0, 0 }, +/*4c*/ { "rex.wr", FALSE, NONE, 0, 0 }, +/*4d*/ { "rex.wrb", FALSE, NONE, 0, 0 }, +/*4e*/ { "rex.wrx", FALSE, NONE, 0, 0 }, +/*4f*/ { "rex.wrxb", FALSE, NONE, 0, 0 }, /*50*/ { "push", FALSE, LONG, op1(Ri), 0 }, /*51*/ { "push", FALSE, LONG, op1(Ri), 0 }, @@ -624,7 +649,7 @@ /*60*/ { "pusha", FALSE, LONG, 0, 0 }, /*61*/ { "popa", FALSE, LONG, 0, 0 }, /*62*/ { "bound", TRUE, LONG, op2(E, R), 0 }, -/*63*/ { "arpl", TRUE, NONE, op2(Rw,Ew), 0 }, +/*63*/ { "movslq", TRUE, NONE, op2(E,R), 0 }, /*64*/ { "", FALSE, NONE, 0, 0 }, /*65*/ { "", FALSE, NONE, 0, 0 }, @@ -807,13 +832,13 @@ { "???", FALSE, NONE, 0, 0 } ; -#define f_mod(byte) ((byte)>>6) -#define f_reg(byte) (((byte)>>3)&0x7) -#define f_rm(byte) ((byte)&0x7) +#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(byte) ((byte)>>6) -#define sib_index(byte) (((byte)>>3)&0x7) -#define sib_base(byte) ((byte)&0x7) +#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; /* if reg, reg number is in 'disp' */ @@ -834,10 +859,25 @@ "%bx" }; -static const char * const db_reg[3][8] = { - { "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh" }, - { "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di" }, - { "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi" } +static 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" }} }; static const char * const db_seg_reg[8] = { @@ -862,28 +902,29 @@ (loc) += (size); static db_addr_t - db_disasm_esc(db_addr_t loc, int inst, int short_addr, + db_disasm_esc(db_addr_t loc, int inst, int rex, int short_addr, int size, const char *seg); -static void db_print_address(const char *seg, int size, +static void db_print_address(const char *seg, int size, int rex, struct i_addr *addrp); static db_addr_t - db_read_address(db_addr_t loc, int short_addr, int regmodrm, + db_read_address(db_addr_t loc, int short_addr, int rex, int regmodrm, struct i_addr *addrp); /* * Read address at location and return updated location. */ static db_addr_t -db_read_address(loc, short_addr, regmodrm, addrp) +db_read_address(loc, short_addr, rex, regmodrm, addrp) db_addr_t loc; int short_addr; + int rex; int regmodrm; struct i_addr * addrp; /* out */ { int mod, rm, sib, index, disp; - mod = f_mod(regmodrm); - rm = f_rm(regmodrm); + mod = f_mod(rex, regmodrm); + rm = f_rm(rex, regmodrm); if (mod == 3) { addrp->is_reg = TRUE; @@ -892,6 +933,7 @@ } addrp->is_reg = FALSE; addrp->index = 0; +/* printf("[[short_addr %d, mod %d rm %d, rex %x]]", short_addr,mod, rm, rex); */ if (short_addr) { addrp->index = 0; @@ -924,13 +966,14 @@ else { if (mod != 3 && rm == 4) { get_value_inc(sib, loc, 1, FALSE); - rm = sib_base(sib); - index = sib_index(sib); + rm = sib_base(rex, sib); + index = sib_index(rex, sib); if (index != 4) - addrp->index = db_reg[LONG][index]; - addrp->ss = sib_ss(sib); + addrp->index = db_reg[1][QUAD][index]; + addrp->ss = sib_ss(rex, sib); } +/* printf("[mod %d]", mod); */ switch (mod) { case 0: if (rm == 5) { @@ -939,20 +982,20 @@ } else { addrp->disp = 0; - addrp->base = db_reg[LONG][rm]; + addrp->base = db_reg[1][QUAD][rm]; } break; case 1: get_value_inc(disp, loc, 1, TRUE); addrp->disp = disp; - addrp->base = db_reg[LONG][rm]; + addrp->base = db_reg[1][QUAD][rm]; break; case 2: get_value_inc(disp, loc, 4, FALSE); addrp->disp = disp; - addrp->base = db_reg[LONG][rm]; + addrp->base = db_reg[1][QUAD][rm]; break; } } @@ -960,13 +1003,15 @@ } static void -db_print_address(seg, size, addrp) +db_print_address(seg, size, rex, addrp) const char * seg; int size; + int rex; struct i_addr * addrp; { +/* printf("[rex:0x%x,size=%d]", rex, size); */ if (addrp->is_reg) { - db_printf("%s", db_reg[size][addrp->disp]); + db_printf("%s", db_reg[rex != 0 ? 1 : 0][(size == LONG && (rex & REX_W)) ? QUAD : size][addrp->disp]); return; } @@ -990,9 +1035,10 @@ * and return updated location. */ static db_addr_t -db_disasm_esc(loc, inst, short_addr, size, seg) +db_disasm_esc(loc, inst, rex, short_addr, size, seg) db_addr_t loc; int inst; + int rex; int short_addr; int size; const char * seg; @@ -1004,8 +1050,8 @@ const char * name; get_value_inc(regmodrm, loc, 1, FALSE); - fp = &db_Esc_inst[inst - 0xd8][f_reg(regmodrm)]; - mod = f_mod(regmodrm); + 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(""); @@ -1014,7 +1060,7 @@ /* * Normal address modes. */ - loc = db_read_address(loc, short_addr, regmodrm, &address); + loc = db_read_address(loc, short_addr, rex, regmodrm, &address); db_printf("%s", fp->f_name); switch(fp->f_size) { case SNGL: @@ -1039,7 +1085,7 @@ break; } db_printf("\t"); - db_print_address(seg, BYTE, &address); + db_print_address(seg, BYTE, rex, &address); } else { /* @@ -1048,24 +1094,24 @@ 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(regmodrm)); + 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(regmodrm)); + 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(regmodrm)); + db_printf("%s\t%%st(%d)",name, f_rm(rex, regmodrm)); break; case op1(X): - name = ((const char * const *)fp->f_rrname)[f_rm(regmodrm)]; + 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(regmodrm)]; + name = ((const char * const *)fp->f_rrname)[f_rm(rex, regmodrm)]; if (*name == '\0') goto bad; db_printf("%s\t%%ax", name); @@ -1098,6 +1144,7 @@ const char * i_name; int i_size; int i_mode; + int rex = 0; int regmodrm = 0; boolean_t first; int displ; @@ -1112,6 +1159,9 @@ size = LONG; seg = 0; +#ifndef _KERNEL +printf("0x%08x: "); +#endif /* * Get prefixes */ @@ -1155,13 +1205,17 @@ prefix = FALSE; break; } + if (inst >= 0x40 && inst < 0x50) { + rex = inst; + prefix = TRUE; + } 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); + loc = db_disasm_esc(loc, inst, rex, short_addr, size, seg); db_printf("\n"); return (loc); } @@ -1181,7 +1235,7 @@ if (ip->i_has_modrm) { get_value_inc(regmodrm, loc, 1, FALSE); - loc = db_read_address(loc, short_addr, regmodrm, &address); + loc = db_read_address(loc, short_addr, rex, regmodrm, &address); } i_name = ip->i_name; @@ -1191,17 +1245,17 @@ if (ip->i_extra == db_Grp1 || ip->i_extra == db_Grp2 || ip->i_extra == db_Grp6 || ip->i_extra == db_Grp7 || ip->i_extra == db_Grp8 || ip->i_extra == db_Grp9) { - i_name = ((const char * const *)ip->i_extra)[f_reg(regmodrm)]; + i_name = ((const char * const *)ip->i_extra)[f_reg(rex, regmodrm)]; } else if (ip->i_extra == db_Grp3) { ip = ip->i_extra; - ip = &ip[f_reg(regmodrm)]; + ip = &ip[f_reg(rex, regmodrm)]; i_name = ip->i_name; i_mode = ip->i_mode; } else if (ip->i_extra == db_Grp4 || ip->i_extra == db_Grp5) { ip = ip->i_extra; - ip = &ip[f_reg(regmodrm)]; + ip = &ip[f_reg(rex, regmodrm)]; i_name = ip->i_name; i_mode = ip->i_mode; i_size = ip->i_size; @@ -1215,6 +1269,11 @@ } else { db_printf("%s", i_name); + if ((strncmp(i_name, "push", 4) == 0) || + (strncmp(i_name, "pop", 3) == 0)) { + i_size = NONE; + db_printf("q"); + } if (i_size != NONE) { if (i_size == BYTE) { db_printf("b"); @@ -1226,8 +1285,12 @@ } else if (size == WORD) db_printf("w"); - else - db_printf("l"); + else { + if (rex & REX_W) + db_printf("q"); + else + db_printf("l"); + } } } db_printf("\t"); @@ -1238,138 +1301,203 @@ if (!first) db_printf(","); +#ifdef _KERNEL +#define M(s) do { } while (0) +#else +#if 0 +#define M(s) printf(s) +#else +#define M(s) do { } while (0) +#endif +#endif switch (i_mode & 0xFF) { case E: - db_print_address(seg, size, &address); + M("[E]"); + db_print_address(seg, size, rex, &address); break; case Eind: + M("[Eind]"); db_printf("*"); - db_print_address(seg, size, &address); + db_print_address(seg, size, rex, &address); break; case El: - db_print_address(seg, LONG, &address); + M("[El]"); + db_print_address(seg, (rex & REX_W) ? QUAD : LONG, rex, &address); break; case Ew: - db_print_address(seg, WORD, &address); + M("[Ew]"); + db_print_address(seg, WORD, rex, &address); break; case Eb: - db_print_address(seg, BYTE, &address); + M("[Eb]"); + db_print_address(seg, BYTE, rex, &address); break; case R: - db_printf("%s", db_reg[size][f_reg(regmodrm)]); + M("[R]"); + db_printf("%s", db_reg[rex != 0 ? 1 : 0][(size == LONG && (rex & REX_W)) ? QUAD : size][f_reg(rex, regmodrm)]); break; case Rw: - db_printf("%s", db_reg[WORD][f_reg(regmodrm)]); + M("[Rw]"); + db_printf("%s", db_reg[rex != 0 ? 1 : 0][WORD][f_reg(rex, regmodrm)]); break; case Ri: - db_printf("%s", db_reg[size][f_rm(inst)]); + M("[Ri]"); + db_printf("%s", db_reg[0][QUAD][f_rm(rex, inst)]); break; case Ril: - db_printf("%s", db_reg[LONG][f_rm(inst)]); + M("[Ril]"); + db_printf("%s", db_reg[rex != 0 ? 1 : 0][(rex & REX_R) ? QUAD : LONG][f_rm(rex, inst)]); break; case S: - db_printf("%s", db_seg_reg[f_reg(regmodrm)]); + M("[S]"); + db_printf("%s", db_seg_reg[f_reg(rex, regmodrm)]); break; case Si: - db_printf("%s", db_seg_reg[f_reg(inst)]); + M("[Si]"); + db_printf("%s", db_seg_reg[f_reg(rex, inst)]); break; case A: - db_printf("%s", db_reg[size][0]); /* acc */ + M("[A]"); + db_printf("%s", db_reg[rex != 0 ? 1 : 0][size][0]); /* acc */ break; case BX: + M("[BX]"); if (seg) db_printf("%s:", seg); db_printf("(%s)", short_addr ? "%bx" : "%ebx"); break; case CL: + M("[CL]"); db_printf("%%cl"); break; case DX: + M("[DX]"); db_printf("%%dx"); break; case SI: + M("[SI]"); if (seg) db_printf("%s:", seg); - db_printf("(%s)", short_addr ? "%si" : "%esi"); + db_printf("(%s)", short_addr ? "%si" : "%rsi"); break; case DI: - db_printf("%%es:(%s)", short_addr ? "%di" : "%edi"); + M("[DI]"); + db_printf("%%es:(%s)", short_addr ? "%di" : "%rdi"); break; case CR: - db_printf("%%cr%d", f_reg(regmodrm)); + M("[CR]"); + db_printf("%%cr%d", f_reg(rex, regmodrm)); break; case DR: - db_printf("%%dr%d", f_reg(regmodrm)); + M("[DR]"); + db_printf("%%dr%d", f_reg(rex, regmodrm)); break; case TR: - db_printf("%%tr%d", f_reg(regmodrm)); + M("[TR]"); + db_printf("%%tr%d", f_reg(rex, regmodrm)); break; case I: + M("[I]"); len = db_lengths[size]; get_value_inc(imm, loc, len, FALSE); +#ifdef _KERNEL db_printf("$%#r", imm); +#else + db_printf("$%#x", imm); +#endif break; case Is: - len = db_lengths[size]; + M("[Is]"); + len = db_lengths[(size == LONG && (rex & REX_W)) ? QUAD : size]; get_value_inc(imm, loc, len, FALSE); +#ifdef _KERNEL db_printf("$%+#r", imm); +#else + db_printf("$%#x", imm); +#endif break; case Ib: + M("[Ib]"); get_value_inc(imm, loc, 1, FALSE); +#ifdef _KERNEL db_printf("$%#r", imm); +#else + db_printf("$%#x", imm); +#endif break; case Iba: + M("[Iba]"); get_value_inc(imm, loc, 1, FALSE); if (imm != 0x0a) +#ifdef _KERNEL db_printf("$%#r", imm); +#else + db_printf("$%#x", imm); +#endif break; case Ibs: + M("[Ibs]"); get_value_inc(imm, loc, 1, TRUE); if (size == WORD) imm &= 0xFFFF; +#ifdef _KERNEL db_printf("$%+#r", imm); +#else + db_printf("$%#x", imm); +#endif break; case Iw: + M("[Iw]"); get_value_inc(imm, loc, 2, FALSE); +#ifdef _KERNEL db_printf("$%#r", imm); +#else + db_printf("$%#x", imm); +#endif break; case O: + M("[O]"); len = (short_addr ? 2 : 4); get_value_inc(displ, loc, len, FALSE); if (seg) +#ifdef _KERNEL db_printf("%s:%+#r",seg, displ); +#else + db_printf("%s:%#x",seg, displ); +#endif else db_printsym((db_addr_t)displ, DB_STGY_ANY); break; case Db: + M("[Db]"); get_value_inc(displ, loc, 1, TRUE); displ += loc; if (size == WORD) @@ -1378,7 +1506,8 @@ break; case Dl: - len = db_lengths[size]; + M("[Dl]"); + len = db_lengths[(size == LONG && (rex & REX_W)) ? QUAD : size]; get_value_inc(displ, loc, len, FALSE); displ += loc; if (size == WORD) @@ -1387,21 +1516,87 @@ break; case o1: + M("[o1]"); db_printf("$1"); break; case o3: + M("[o3]"); db_printf("$3"); break; case OS: + M("[OS]"); len = db_lengths[size]; get_value_inc(imm, loc, len, FALSE); /* offset */ get_value_inc(imm2, loc, 2, FALSE); /* segment */ +#ifdef _KERNEL db_printf("$%#r,%#r", imm2, imm); +#else + db_printf("$%#x,%#x", imm2, imm); +#endif break; } } db_printf("\n"); return (loc); +#undef M +} + +#ifndef _KERNEL +/* Just self-disassemble for a a few instructions */ +int +main(int ac, char *av[]) +{ + db_addr_t base = (db_addr_t)main; + int i; + for (i = 0; i < 60; i++) + base = db_disasm(base, 0); + return 0; } +void tasm(void) +{ + asm("push %si"); +} + +/* + * Access unaligned data items on aligned (longword) + * boundaries. + */ + +static unsigned db_extend[] = { /* table for sign-extending */ + 0, + 0xFFFFFF80U, + 0xFFFF8000U, + 0xFF800000U +}; + +db_expr_t +db_get_value(addr, size, is_signed) + db_addr_t addr; + register int size; + boolean_t is_signed; +{ + char data[sizeof(int)]; + register db_expr_t value; + register int i; + + db_read_bytes(addr, size, data); + + value = 0; +#if BYTE_MSF + for (i = 0; i < size; i++) +#else /* BYTE_LSF */ + for (i = size - 1; i >= 0; i--) +#endif + { + value = (value << 8) + (data[i] & 0xFF); + } + + if (size < 4) { + if (is_signed && (value & db_extend[size]) != 0) + value |= db_extend[size]; + } + return (value); +} +#endif