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/6f056d63fc98
branches: trunk
changeset: 338148:6f056d63fc98
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 78bd83c0dc07 -r 6f056d63fc98 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