Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 30 Mar 2005 22:00:56 GMT
From:      Peter Wemm <peter@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 74127 for review
Message-ID:  <200503302200.j2UM0ubP070333@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
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 <sys/param.h>
 
 #include <ddb/ddb.h>
 #include <ddb/db_access.h>
 #include <ddb/db_sym.h>
+#else
+#include <sys/types.h>
+#include <stdio.h>
+#include <string.h>
+
+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("<bad instruction>");
@@ -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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200503302200.j2UM0ubP070333>