Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch Catch up FreeBSD and OpenBSD's changes. Not complet...



details:   https://anonhg.NetBSD.org/src/rev/fac8d7f145be
branches:  trunk
changeset: 808290:fac8d7f145be
user:      msaitoh <msaitoh%NetBSD.org@localhost>
date:      Tue May 12 19:24:57 2015 +0000

description:
Catch up FreeBSD and OpenBSD's changes. Not completed but it's better than
before:
- Add support rdrand, rdseed, fxrstor, ldmxcsr, stmxcsr, xsare, xrstor,
  xsaveopt, cflush and some others.
- Check REX bit correctly.
- Print correct register.
- Fix a lot of bugs.
- KNF.

diffstat:

 sys/arch/amd64/amd64/db_disasm.c |  301 ++++++++++++++++++++------------------
 sys/arch/i386/i386/db_disasm.c   |  214 +++++++++++++++++----------
 2 files changed, 288 insertions(+), 227 deletions(-)

diffs (truncated from 938 to 300 lines):

diff -r 4f8b4d292f2f -r fac8d7f145be sys/arch/amd64/amd64/db_disasm.c
--- a/sys/arch/amd64/amd64/db_disasm.c  Tue May 12 14:59:35 2015 +0000
+++ b/sys/arch/amd64/amd64/db_disasm.c  Tue May 12 19:24:57 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: db_disasm.c,v 1.20 2014/10/23 10:01:53 msaitoh Exp $   */
+/*     $NetBSD: db_disasm.c,v 1.21 2015/05/12 19:24:57 msaitoh Exp $   */
 
 /* 
  * Mach Operating System
@@ -33,7 +33,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: db_disasm.c,v 1.20 2014/10/23 10:01:53 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: db_disasm.c,v 1.21 2015/05/12 19:24:57 msaitoh Exp $");
 
 #ifndef _KERNEL
 #include <sys/types.h>
@@ -68,6 +68,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 */
@@ -106,6 +115,7 @@
 #define        XA      34                      /* for 'fstcw %ax' */
 #define        Ed      35                      /* address, double size */
 #define        Iq      36                      /* word immediate, maybe 64bits */
+#define        Rv      40                      /* register in 'r/m' field */
 
 struct inst {
        const char *i_name;             /* name */
@@ -171,6 +181,17 @@
        "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[] = {
 /*00*/ { "",      true,  NONE,  op1(Ew),     db_Grp6 },
 /*01*/ { "",      true,  NONE,  op1(Ew),     db_Grp7 },
@@ -191,6 +212,26 @@
 /*0f*/ { "",      false, NONE,  0,           0 },  /* 3DNow */
 };
 
+const struct inst db_inst_0f1x[] = {
+/*10*/ { "",      FALSE, NONE,  0,           0 },
+/*11*/ { "",      FALSE, NONE,  0,           0 },
+/*12*/ { "",      FALSE, NONE,  0,           0 },
+/*13*/ { "",      FALSE, NONE,  0,           0 },
+/*14*/ { "",      FALSE, NONE,  0,           0 },
+/*15*/ { "",      FALSE, NONE,  0,           0 },
+/*16*/ { "",      FALSE, NONE,  0,           0 },
+/*17*/ { "",      FALSE, NONE,  0,           0 },
+
+/*18*/ { "",      FALSE, NONE,  0,           0 },
+/*19*/ { "",      FALSE, NONE,  0,           0 },
+/*1a*/ { "",      FALSE, NONE,  0,           0 },
+/*1b*/ { "",      FALSE, NONE,  0,           0 },
+/*1c*/ { "",      FALSE, NONE,  0,           0 },
+/*1d*/ { "",      FALSE, NONE,  0,           0 },
+/*1e*/ { "",      FALSE, NONE,  0,           0 },
+/*1f*/ { "nopl",  TRUE,  SDEP,  0,           "nopw" },
+};
+
 const struct inst db_inst_0f2x[] = {
 /*20*/ { "mov",   true,  LONG,  op2(CR,E),   0 }, /* use E for reg */
 /*21*/ { "mov",   true,  LONG,  op2(DR,E),   0 }, /* since mod == 11 */
@@ -352,7 +393,7 @@
 
 const struct inst * const db_inst_0f[] = {
        db_inst_0f0x,
-       NULL,
+       db_inst_0f1x,
        db_inst_0f2x,
        db_inst_0f3x,
        db_inst_0f4x,
@@ -852,13 +893,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' */
@@ -882,18 +923,25 @@
 #define DB_REG_DFLT    0
 #define DB_REG_REX     1
 
-const char * const db_reg[2][4][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" },
-    { "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi" }
-}, {
-    { "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b" },
-    { "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w" },
-    { "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d" },
-    { "%r8",  "%r9",  "%r10",  "%r11",  "%r12",  "%r13",  "%r14",  "%r15" }
-}};
+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", "", ""
@@ -912,23 +960,6 @@
        10,     /* EXTR */
 };
 
-#define        REX             0x00
-#define        REX_b           0x01
-#define        REX_x           0x02
-#define        REX_xb          0x03
-#define        REX_r           0x04
-#define        REX_rb          0x05
-#define        REX_rx          0x06
-#define        REX_rxb         0x07
-#define        REX_w           0x08
-#define        REX_wb          0x09
-#define        REX_wx          0x0a
-#define        REX_wxb         0x0b
-#define        REX_wr          0x0c
-#define        REX_wrb         0x0d
-#define        REX_wrx         0x0e
-#define        REX_wrxb        0x0f
-
 const char * const rex_str[0x10] = {
        "rex      ",    /* 0x40 */
        "rex.b    ",    /* 0x41 */
@@ -955,7 +986,7 @@
        } while (0)
 
 
-db_addr_t db_read_address(db_addr_t, u_int, int, int, struct i_addr *);
+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 *);
 
@@ -963,14 +994,15 @@
  * Read address at location and return updated location.
  */
 db_addr_t
-db_read_address(db_addr_t loc, u_int rex, int short_addr, int regmodrm,
+db_read_address(db_addr_t loc, int short_addr, u_int rex, int regmodrm,
     struct i_addr *addrp)
        /* addrp:                out */
 {
-       int             mod, rm, sib, index, disp, ext;
+       int             mod, rm, sib, index, disp, size, have_sib;
 
-       mod = f_mod(regmodrm);
-       rm  = f_rm(regmodrm);
+       size = (short_addr ? LONG : QUAD);
+       mod = f_mod(rex, regmodrm);
+       rm  = f_rm(rex, regmodrm);
 
        if (mod == 3) {
                addrp->is_reg = true;
@@ -980,76 +1012,42 @@
        addrp->is_reg = false;
        addrp->index = 0;
 
-       if (short_addr) {
-               /* x86_64 32 bit address mode */
-               if (mod != 3 && rm == 4) {
-                       ext = ((rex & REX_x) != 0);
-                       get_value_inc(sib, loc, 1, false);
-                       rm = sib_base(sib);
-                       index = sib_index(sib);
-                       if (index != 4)
-                               addrp->index = db_reg[ext][LONG][index];
-                       addrp->ss = sib_ss(sib);
-               }
+       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;
 
-               ext = ((rex & REX_b) != 0);
-               switch (mod) {
-               case 0:
-                       if (rm == 5) {
-                               get_value_inc(addrp->disp, loc, 4, false);
+       switch (mod) {
+       case 0:
+               if (rm == 5) {
+                       get_value_inc(addrp->disp, loc, 4, false);
+                       if (have_sib)
                                addrp->base = 0;
-                       } else {
-                               addrp->disp = 0;
-                               addrp->base = db_reg[ext][LONG][rm];
-                       }
-                       break;
-               case 1:
-                       get_value_inc(disp, loc, 1, true);
-                       addrp->disp = disp;
-                       addrp->base = db_reg[ext][LONG][rm];
-                       break;
-               case 2:
-                       get_value_inc(disp, loc, 4, false);
-                       addrp->disp = disp;
-                       addrp->base = db_reg[ext][LONG][rm];
-                       break;
+                       else if (short_addr)
+                               addrp->base = "%eip";
+                       else
+                               addrp->base = "%rip";
+               } else {
+                       addrp->disp = 0;
+                       addrp->base = db_reg[1][size][rm];
                }
-       } else {
-               /* x86_64 64 bit address mode */
-
-               if (mod != 3 && rm == 4) {
-                       ext = ((rex & REX_x) != 0);
-                       get_value_inc(sib, loc, 1, false);
-                       rm = sib_base(sib);
-                       index = sib_index(sib);
-                       if (index != 4)
-                               addrp->index = db_reg[ext][QUAD][index];
-                       addrp->ss = sib_ss(sib);
-               }
-
-               ext = ((rex & REX_b) != 0);
-               switch (mod) {
-               case 0:
-                       if (rm == 5) {
-                               /* x86_64 RIP-relative addressing */
-                               get_value_inc(addrp->disp, loc, 4, false);
-                               addrp->base = "%rip";
-                       } else {
-                               addrp->disp = 0;
-                               addrp->base = db_reg[ext][QUAD][rm];
-                       }
-                       break;
-               case 1:
-                       get_value_inc(disp, loc, 1, true);
-                       addrp->disp = disp;
-                       addrp->base = db_reg[ext][QUAD][rm];
-                       break;
-               case 2:
-                       get_value_inc(disp, loc, 4, false);
-                       addrp->disp = disp;



Home | Main Index | Thread Index | Old Index