geode/loader/dobby/source/InstructionRelocation/x86/deprecated/Ia32Disassembler.cc
2022-07-30 19:24:03 +03:00

388 lines
No EOL
8.7 KiB
C++

#include <stdio.h>
#include <stdint.h>
#include "logging/logging.h"
enum SegmentPrefix {
kCs = 0x2e,
kSs = 0x36,
kDs = 0x3e,
kEs = 0x26,
kFs = 0x64,
kGs = 0x65,
};
bool supports_rex_ = false;
void DecodeInstruction(uint8_t *instr) {
bool have_prefixes = true;
uint8_t prefix[4] = {0, 0, 0, 0};
// decode legacy prefix
do {
switch (*instr) {
// Group 1 - lock and repeat prefixes:
case 0xF0:
case 0xF2:
case 0xF3:
prefix[0] = *instr;
break;
// Group 2 - segment override prefixes:
case kCs:
case kSs:
case kDs:
case kEs:
case kFs:
case kGs:
prefix[1] = *instr;
break;
// Group 3 - operand size override:
case 0x66:
prefix[2] = *instr;
break;
// Group 4 - address size override:
case 0x67:
prefix[3] = *instr;
break;
default:
have_prefixes = false;
break;
}
if (have_prefixes) {
instr++;
}
} while (have_prefixes);
// x64 rex
uint8_t rex = (supports_rex_ && (*instr >= 0x40) && (*instr <= 0x4F)) ? *instr : 0;
if (rex != 0) {
instr++;
}
bool has_modrm = false;
bool reg_is_opcode = false;
size_t immediate_bytes = 0;
#define OpEn_MR \
do { \
has_modrm = true; \
} while (0); \
break;
#define OpEn_RM \
do { \
has_modrm = true; \
} while (0); \
break;
#define OpEn_I(immediate_size) \
do { \
immediate_bytes = immediate_size; \
} while (0); \
break;
#define OpEn_RMI(immediate_size) \
do { \
immediate_bytes = immediate_size; \
} while (0); \
break;
#define OpEn_O \
do { \
reg_is_opcode = true; \
} while (0); \
break;
#define OpEn_D \
do { \
reg_is_opcode = true; \
} while (0); \
break;
#define OpEn_ZO \
do { \
reg_is_opcode = true; \
} while (0); \
break;
#define Op_Prefix \
do { \
reg_is_opcode = true; \
} while (0); \
break;
#define UnImplOpcode \
do { \
DLOG(0, "opcode unreachable"); \
} while (0); \
break;
typedef enum {
MR,
} OpEnTy;
// decode opcode
switch (*instr) {
case 0x00:
OpEn_MR;
case 0x01:
OpEn_MR;
case 0x02:
OpEn_RM;
case 0x03:
OpEn_RM;
case 0x04:
OpEn_I(8);
case 0x05:
OpEn_I(16 | 32);
case 0x06:
case 0x07:
UnImplOpcode;
case 0x08:
OpEn_MR;
case 0x09:
OpEn_MR;
case 0x0a:
OpEn_RM;
case 0x0b:
OpEn_RM;
case 0x0c:
OpEn_I(8);
case 0x0d:
OpEn_I(16 | 32);
case 0x0e:
case 0x0f:
UnImplOpcode;
case 0x10:
OpEn_MR;
case 0x11:
OpEn_MR;
case 0x12:
OpEn_RM;
case 0x13:
OpEn_RM;
case 0x14:
OpEn_I(8);
case 0x15:
OpEn_I(16 | 32);
case 0x16:
case 0x17:
UnImplOpcode;
case 0x18:
OpEn_MR;
case 0x19:
OpEn_MR;
case 0x1a:
OpEn_RM;
case 0x1b:
OpEn_RM;
case 0x1c:
OpEn_I(8);
case 0x1d:
OpEn_I(16 | 32);
case 0x1e:
case 0x1f:
UnImplOpcode;
case 0x20:
OpEn_MR;
case 0x21:
OpEn_MR;
case 0x22:
OpEn_RM;
case 0x23:
OpEn_RM;
case 0x24:
OpEn_I(8);
case 0x25:
OpEn_I(16 | 32);
case 0x26:
case 0x27:
UnImplOpcode;
case 0x28:
OpEn_MR;
case 0x29:
OpEn_MR;
case 0x2a:
OpEn_RM;
case 0x2b:
OpEn_RM;
case 0x2c:
OpEn_I(8);
case 0x2d:
OpEn_I(16 | 32);
case 0x2e:
case 0x2f:
UnImplOpcode;
case 0x30:
OpEn_MR;
case 0x31:
OpEn_MR;
case 0x32:
OpEn_RM;
case 0x33:
OpEn_RM;
case 0x34:
OpEn_I(8);
case 0x35:
OpEn_I(16 | 32);
case 0x36:
case 0x37:
UnImplOpcode;
case 0x38:
OpEn_MR;
case 0x39:
OpEn_MR;
case 0x3a:
OpEn_RM;
case 0x3b:
OpEn_RM;
case 0x3c:
OpEn_I(8);
case 0x3d:
OpEn_I(16 | 32);
case 0x40:
case 0x41:
case 0x42:
case 0x43:
case 0x44:
case 0x45:
case 0x46:
case 0x47:
case 0x48:
case 0x49:
case 0x4a:
case 0x4b:
case 0x4c:
case 0x4d:
case 0x4e:
case 0x4f:
UnImplOpcode;
case 0x50:
case 0x51:
case 0x52:
case 0x53:
case 0x54:
case 0x55:
case 0x56:
case 0x57:
case 0x58:
case 0x59:
case 0x5A:
case 0x5B:
case 0x5C:
case 0x5D:
case 0x5E:
case 0x5F:
OpEn_O;
case 0x60:
case 0x61:
case 0x62:
UnImplOpcode;
case 0x63:
if ((rex & REX_W) != 0) {
OpEn_RM;
};
break;
case 0x64:
case 0x65:
case 0x66:
case 0x67:
Op_Prefix;
case 0x68:
OpEn_I(16 | 32);
case 0x69:
OpEn_RMI(16 | 32);
case 0x6a:
OpEn_I(8);
case 0x6b:
OpEn_RMI(8);
case 0x70:
case 0x71:
case 0x72:
case 0x73:
case 0x74:
case 0x75:
case 0x76:
case 0x77:
case 0x78:
case 0x79:
case 0x7A:
case 0x7B:
case 0x7C:
case 0x7D:
case 0x7E:
case 0x7F:
OpEn_D;
case 0x80:
case 0x81:
case 0x82:
case 0x83:
case 0x84:
case 0x85:
UnImplOpcode;
case 0x86:
case 0x87:
OpEn_RM;
case 0x88:
case 0x89:
case 0x8a:
case 0x8b:
OpEn_RM;
case 0x8c:
case 0x8d:
case 0x8e:
case 0x8f:
case 0x90:
case 0x91:
case 0x92:
case 0x93:
case 0x94:
case 0x95:
case 0x96:
case 0x97:
case 0x98:
case 0x99:
case 0x9a:
case 0x9b:
case 0x9c:
UnImplOpcode;
case 0x9d:
OpEn_ZO;
case 0x0f:
DecodeExtendedOpcode
}
}
void DecodeExtendedOpcode(uint8_t *instr) {
}