aboutsummaryrefslogtreecommitdiffstats
path: root/capstone/suite/synctools/disassemblertables2.c
diff options
context:
space:
mode:
Diffstat (limited to 'capstone/suite/synctools/disassemblertables2.c')
-rw-r--r--capstone/suite/synctools/disassemblertables2.c176
1 files changed, 176 insertions, 0 deletions
diff --git a/capstone/suite/synctools/disassemblertables2.c b/capstone/suite/synctools/disassemblertables2.c
new file mode 100644
index 000000000..f336da103
--- /dev/null
+++ b/capstone/suite/synctools/disassemblertables2.c
@@ -0,0 +1,176 @@
+/* Capstone Disassembly Engine */
+/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2019 */
+
+// this tool is to generate arch/X86/X86GenDisassemblerTables2.inc
+// NOTE: this requires updated X86GenDisassemblerTables2 & X86GenDisassemblerTables2
+// generatedy by ./disassemblertables.py & disassemblertables_reduce.py
+
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+
+// X86DisassemblerDecoderCommon.h is copied from Capstone src
+#include "../../arch/X86/X86DisassemblerDecoderCommon.h"
+
+#define ARR_SIZE(a) (sizeof(a) / sizeof(a[0]))
+
+/// Specifies whether a ModR/M byte is needed and (if so) which
+/// instruction each possible value of the ModR/M byte corresponds to. Once
+/// this information is known, we have narrowed down to a single instruction.
+struct ModRMDecision {
+ uint8_t modrm_type;
+ uint16_t instructionIDs;
+};
+
+/// Specifies which set of ModR/M->instruction tables to look at
+/// given a particular opcode.
+struct OpcodeDecision {
+ struct ModRMDecision modRMDecisions[256];
+};
+
+/// Specifies which opcode->instruction tables to look at given
+/// a particular context (set of attributes). Since there are many possible
+/// contexts, the decoder first uses CONTEXTS_SYM to determine which context
+/// applies given a specific set of attributes. Hence there are only IC_max
+/// entries in this table, rather than 2^(ATTR_max).
+struct ContextDecision {
+ struct OpcodeDecision opcodeDecisions[IC_max];
+};
+
+#ifdef CAPSTONE_X86_REDUCE
+#include "X86GenDisassemblerTables_reduce2.inc"
+#else
+#include "X86GenDisassemblerTables2.inc"
+#endif
+
+static void index_OpcodeDecision(const struct OpcodeDecision *decisions, size_t size,
+ const struct OpcodeDecision *emptyDecision, unsigned int *index_table,
+ const char *opcodeTable,
+ const char *index_opcodeTable)
+{
+ unsigned int i, count = 0;
+
+ for (i = 0; i < size; i++) {
+ if (memcmp((const void *)&decisions[i],
+ emptyDecision, sizeof(*emptyDecision)) != 0) {
+ // this is a non-zero entry
+ // index_table entry must be != 0
+ index_table[i] = count + 1;
+ count++;
+ } else
+ // empty entry
+ index_table[i] = 0;
+ }
+
+ printf("static const unsigned char %s[] = {\n", index_opcodeTable);
+
+ for (i = 0; i < size; i++) {
+ printf(" %u,\n", index_table[i]);
+ }
+
+ printf("};\n\n");
+
+ printf("static const struct OpcodeDecision %s[] = {\n", opcodeTable);
+ for (i = 0; i < size; i++) {
+ if (index_table[i]) {
+ unsigned int j;
+ const struct OpcodeDecision *decision;
+
+ // print out this non-zero entry
+ printf(" { {\n");
+ decision = &decisions[i];
+
+ for(j = 0; j < ARR_SIZE(emptyDecision->modRMDecisions); j++) {
+ const char *modrm;
+
+ switch(decision->modRMDecisions[j].modrm_type) {
+ default:
+ modrm = "MODRM_ONEENTRY";
+ break;
+ case 1:
+ modrm = "MODRM_SPLITRM";
+ break;
+ case 2:
+ modrm = "MODRM_SPLITMISC";
+ break;
+ case 3:
+ modrm = "MODRM_SPLITREG";
+ break;
+ case 4:
+ modrm = "MODRM_FULL";
+ break;
+ }
+ printf(" { %s, %u },\n",
+ modrm, decision->modRMDecisions[j].instructionIDs);
+ }
+ printf(" } },\n");
+ }
+ }
+
+ printf("};\n\n");
+}
+
+
+int main(int argc, char **argv)
+{
+ unsigned int index_table[ARR_SIZE(x86DisassemblerOneByteOpcodes.opcodeDecisions)];
+ const struct OpcodeDecision emptyDecision;
+
+ memset((void *)&emptyDecision, 0, sizeof(emptyDecision));
+
+ printf("/* Capstone Disassembly Engine, http://www.capstone-engine.org */\n");
+ printf("/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2019 */\n");
+ printf("\n");
+
+ index_OpcodeDecision(x86DisassemblerOneByteOpcodes.opcodeDecisions,
+ ARR_SIZE(x86DisassemblerOneByteOpcodes.opcodeDecisions),
+ &emptyDecision, index_table,
+ "x86DisassemblerOneByteOpcodes",
+ "index_x86DisassemblerOneByteOpcodes");
+
+ index_OpcodeDecision(x86DisassemblerTwoByteOpcodes.opcodeDecisions,
+ ARR_SIZE(x86DisassemblerTwoByteOpcodes.opcodeDecisions),
+ &emptyDecision, index_table,
+ "x86DisassemblerTwoByteOpcodes",
+ "index_x86DisassemblerTwoByteOpcodes");
+
+ index_OpcodeDecision(x86DisassemblerThreeByte38Opcodes.opcodeDecisions,
+ ARR_SIZE(x86DisassemblerThreeByte38Opcodes.opcodeDecisions),
+ &emptyDecision, index_table,
+ "x86DisassemblerThreeByte38Opcodes",
+ "index_x86DisassemblerThreeByte38Opcodes");
+
+ index_OpcodeDecision(x86DisassemblerThreeByte3AOpcodes.opcodeDecisions,
+ ARR_SIZE(x86DisassemblerThreeByte3AOpcodes.opcodeDecisions),
+ &emptyDecision, index_table,
+ "x86DisassemblerThreeByte3AOpcodes",
+ "index_x86DisassemblerThreeByte3AOpcodes");
+
+#ifndef CAPSTONE_X86_REDUCE
+ index_OpcodeDecision(x86DisassemblerXOP8Opcodes.opcodeDecisions,
+ ARR_SIZE(x86DisassemblerXOP8Opcodes.opcodeDecisions),
+ &emptyDecision, index_table,
+ "x86DisassemblerXOP8Opcodes",
+ "index_x86DisassemblerXOP8Opcodes");
+
+ index_OpcodeDecision(x86DisassemblerXOP9Opcodes.opcodeDecisions,
+ ARR_SIZE(x86DisassemblerXOP9Opcodes.opcodeDecisions),
+ &emptyDecision, index_table,
+ "x86DisassemblerXOP9Opcodes",
+ "index_x86DisassemblerXOP9Opcodes");
+
+ index_OpcodeDecision(x86DisassemblerXOPAOpcodes.opcodeDecisions,
+ ARR_SIZE(x86DisassemblerXOPAOpcodes.opcodeDecisions),
+ &emptyDecision, index_table,
+ "x86DisassemblerXOPAOpcodes",
+ "index_x86DisassemblerXOPAOpcodes");
+
+ index_OpcodeDecision(x86Disassembler3DNowOpcodes.opcodeDecisions,
+ ARR_SIZE(x86Disassembler3DNowOpcodes.opcodeDecisions),
+ &emptyDecision, index_table,
+ "x86Disassembler3DNowOpcodes",
+ "index_x86Disassembler3DNowOpcodes");
+#endif
+
+ return 0;
+}