From 9df6ac17886cd8923ea775636b93d6f02d5c59f4 Mon Sep 17 00:00:00 2001 From: Alexis Engelke Date: Sun, 8 Nov 2020 11:20:03 +0100 Subject: [PATCH] decode: Replace T8+T72 with T16+T8E for R/M value --- decode.c | 15 +++++++-------- parseinstrs.py | 30 ++++++++++++++++++++---------- 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/decode.c b/decode.c index 66f17db..d4dab48 100644 --- a/decode.c +++ b/decode.c @@ -30,8 +30,8 @@ typedef enum DecodeMode DecodeMode; #define ENTRY_NONE 0 #define ENTRY_INSTR 1 #define ENTRY_TABLE256 2 -#define ENTRY_TABLE8 3 -#define ENTRY_TABLE72 4 +#define ENTRY_TABLE16 3 +#define ENTRY_TABLE8E 4 #define ENTRY_TABLE_PREFIX 5 #define ENTRY_TABLE_VEX 6 #define ENTRY_TABLE_ROOT 8 @@ -409,13 +409,12 @@ fd_decode(const uint8_t* buffer, size_t len_sz, int mode_int, uintptr_t address, } // Then, walk through ModR/M-encoded opcode extensions. - if ((kind == ENTRY_TABLE8 || kind == ENTRY_TABLE72) && LIKELY(off < len)) - { - if (kind == ENTRY_TABLE72 && (buffer[off] & 0xc0) == 0xc0) - ENTRY_UNPACK(table, kind, table[buffer[off++] - 0xb8]); - else - ENTRY_UNPACK(table, kind, table[(buffer[off] >> 3) & 7]); + if (kind == ENTRY_TABLE16 && LIKELY(off < len)) { + unsigned isreg = (buffer[off] & 0xc0) == 0xc0 ? 8 : 0; + ENTRY_UNPACK(table, kind, table[((buffer[off] >> 3) & 7) | isreg]); } + if (kind == ENTRY_TABLE8E && LIKELY(off < len)) + ENTRY_UNPACK(table, kind, table[buffer[off++] & 7]); // For VEX prefix, we have to distinguish between VEX.W and VEX.L which may // be part of the opcode. diff --git a/parseinstrs.py b/parseinstrs.py index 3239407..c70e16e 100644 --- a/parseinstrs.py +++ b/parseinstrs.py @@ -202,8 +202,8 @@ class EntryKind(Enum): NONE = 0 INSTR = 1 TABLE256 = 2 - TABLE8 = 3 - TABLE72 = 4 + TABLE16 = 3 + TABLE8E = 4 TABLE_PREFIX = 5 TABLE_VEX = 6 TABLE_ROOT = -1 @@ -215,8 +215,8 @@ class TrieEntry(NamedTuple): TABLE_LENGTH = { EntryKind.TABLE256: 256, - EntryKind.TABLE8: 8, - EntryKind.TABLE72: 72, + EntryKind.TABLE16: 16, + EntryKind.TABLE8E: 8, EntryKind.TABLE_PREFIX: 4, EntryKind.TABLE_VEX: 4, EntryKind.TABLE_ROOT: 8, @@ -296,10 +296,18 @@ class Opcode(NamedTuple): prefix_val = ["NP", "66", "F3", "F2"].index(self.prefix) opcode.append((EntryKind.TABLE_PREFIX, [prefix_val])) if self.opcext: - opcext_kind = [EntryKind.TABLE8, EntryKind.TABLE72][self.opcext[0]] - opcext_val = self.opcext[1] - (0 if self.opcext[1] < 8 else 0xb8) - opcode.append((opcext_kind, [opcext_val])) - if self.extended: + opcext_val = self.opcext[1] + if not self.opcext[0]: + opcode.append((EntryKind.TABLE16, [opcext_val, opcext_val | 8])) + elif opcext_val < 8: + opcode.append((EntryKind.TABLE16, [opcext_val])) + else: + opcode.append((EntryKind.TABLE16, [((opcext_val - 0xc0) >> 3) | 8])) + if not self.extended: + opcode.append((EntryKind.TABLE8E, [opcext_val & 7])) + else: + opcode.append((EntryKind.TABLE8E, list(range(8)))) + if self.extended and not self.opcext: last_type, last_indices = opcode[-1] opcode[-1] = last_type, [last_indices[0] + i for i in range(8)] if self.vexl in ("0", "1") or self.rexw in ("0", "1"): @@ -320,8 +328,10 @@ def format_opcode(opcode): prefix += ["", "VEX."][byte >> 2] elif kind == EntryKind.TABLE256: opcode_string += "{:02x}".format(byte) - elif kind in (EntryKind.TABLE8, EntryKind.TABLE72): - opcode_string += "/{:x}".format(byte) + elif kind == EntryKind.TABLE16: + opcode_string += "/{:x}{}".format(byte & 7, "mr"[byte >> 3]) + elif kind == EntryKind.TABLE8E: + opcode_string += "+rm={:x}".format(byte) elif kind == EntryKind.TABLE_PREFIX: if byte & 4: prefix += "VEX."