aboutsummaryrefslogtreecommitdiffstats
path: root/capstone/suite/synctools/disassemblertables-arch.py
diff options
context:
space:
mode:
authorAngelos Mouzakitis <a.mouzakitis@virtualopensystems.com>2023-10-10 14:33:42 +0000
committerAngelos Mouzakitis <a.mouzakitis@virtualopensystems.com>2023-10-10 14:33:42 +0000
commitaf1a266670d040d2f4083ff309d732d648afba2a (patch)
tree2fc46203448ddcc6f81546d379abfaeb323575e9 /capstone/suite/synctools/disassemblertables-arch.py
parente02cda008591317b1625707ff8e115a4841aa889 (diff)
Add submodule dependency filesHEADmaster
Change-Id: Iaf8d18082d3991dec7c0ebbea540f092188eb4ec
Diffstat (limited to 'capstone/suite/synctools/disassemblertables-arch.py')
-rwxr-xr-xcapstone/suite/synctools/disassemblertables-arch.py258
1 files changed, 258 insertions, 0 deletions
diff --git a/capstone/suite/synctools/disassemblertables-arch.py b/capstone/suite/synctools/disassemblertables-arch.py
new file mode 100755
index 000000000..55db77685
--- /dev/null
+++ b/capstone/suite/synctools/disassemblertables-arch.py
@@ -0,0 +1,258 @@
+#!/usr/bin/python
+# convert LLVM GenDisassemblerTables.inc for Capstone disassembler.
+# this just adds a header
+# by Nguyen Anh Quynh, 2019
+
+import sys
+
+if len(sys.argv) == 1:
+ print("Syntax: %s <GenDisassemblerTables.inc> <arch>" %sys.argv[0])
+ sys.exit(1)
+
+f = open(sys.argv[1])
+lines = f.readlines()
+f.close()
+
+print("/* Capstone Disassembly Engine, http://www.capstone-engine.org */")
+print("/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2019 */")
+print("/* Automatically generated file, do not edit! */\n")
+print('#include "../../MCInst.h"')
+print('#include "../../LEB128.h"')
+print("")
+
+print("""
+// Helper function for extracting fields from encoded instructions.
+
+//#if defined(_MSC_VER) && !defined(__clang__)
+//__declspec(noinline)
+//#endif
+
+#define FieldFromInstruction(fname, InsnType) \\
+static InsnType fname(InsnType insn, unsigned startBit, unsigned numBits) \\
+{ \\
+ InsnType fieldMask; \\
+ if (numBits == sizeof(InsnType) * 8) \\
+ fieldMask = (InsnType)(-1LL); \\
+ else \\
+ fieldMask = (((InsnType)1 << numBits) - 1) << startBit; \\
+ return (insn & fieldMask) >> startBit; \\
+}
+""")
+
+
+# extract text between <>
+# printSVERegOp<'q'>
+def extract_brackets(line):
+ return line[line.index('<')+1 : line.index('>')]
+
+# delete text between <>, including <>
+# printSVERegOp<'q'>
+def del_brackets(line):
+ return line[:line.index('<')] + line[line.index('>') + 1:]
+
+
+# skip printing some lines?
+skip_print = True
+# adding slash at the end of the line for C macro?
+adding_slash = False
+# skip LLVM_DEBUG
+llvm_debug = False
+
+def print_line(line):
+ if skip_print is True:
+ return
+ if adding_slash:
+ # skip blank line
+ if (len(line.strip()) == 0):
+ return
+ # // must be handled
+ if '//' in line:
+ line = line.replace('//', '/*')
+ line += ' */'
+ print(line + ' \\')
+ else:
+ print(line)
+
+
+for line in lines:
+ line2 = line.rstrip()
+
+ if '#include ' in line2:
+ continue
+
+ # skip until the first decoder table
+ elif skip_print and 'static const uint8_t DecoderTable' in line2:
+ skip_print = False
+
+ elif 'End llvm namespace' in line2:
+ # done
+ break
+
+ elif 'llvm_unreachable' in line2:
+ line2 = line2.replace('llvm_unreachable', '/* llvm_unreachable')
+ line2 += '*/ '
+ if '"Invalid index!"' in line2:
+ pass
+ #line2 += '\n return true;'
+
+ elif 'Bits[' in line2:
+ if sys.argv[2] == 'ARM':
+ line2 = line2.replace('Bits[', 'ARM_getFeatureBits(MI->csh->mode, ')
+ line2 = line2.replace(']', ')')
+ elif sys.argv[2] == 'AArch64':
+ line2 = line2.replace('Bits[', 'AArch64_getFeatureBits(')
+ line2 = line2.replace(']', ')')
+
+ elif 'static bool checkDecoderPredicate(unsigned Idx, const FeatureBitset& Bits) {' in line2:
+ line2 = 'static bool checkDecoderPredicate(unsigned Idx, MCInst *MI)\n{'
+
+ elif 'checkDecoderPredicate(PIdx, ' in line2:
+ line2 = line2.replace(', Bits)', ', MI)')
+
+ elif 'template<typename InsnType>' in line2:
+ continue
+
+ elif 'static DecodeStatus decodeToMCInst' in line2:
+ line2 = '#define DecodeToMCInst(fname, fieldname, InsnType) \\\n' + \
+ 'static DecodeStatus fname(DecodeStatus S, unsigned Idx, InsnType insn, MCInst *MI, \\\n' + \
+ '\t\tuint64_t Address, bool *Decoder) \\\n{'
+ adding_slash = True
+
+ elif 'fieldFromInstruction' in line2:
+ line2 = line2.replace('fieldFromInstruction', 'fieldname')
+ if 'InsnType FieldValue' in line2:
+ line2 = line2.replace('InsnType ', '')
+
+ elif 'DecodeComplete = true;' in line2:
+ # dead code
+ continue
+
+ elif 'bool &DecodeComplete) {' in line2:
+ continue
+
+ elif line2 == '}':
+ if adding_slash:
+ adding_slash = False
+
+ elif 'static DecodeStatus decodeInstruction' in line2:
+ line2 = '#define DecodeInstruction(fname, fieldname, decoder, InsnType) \\\n' + \
+ 'static DecodeStatus fname(const uint8_t DecodeTable[], MCInst *MI, \\\n' + \
+ '\t\tInsnType insn, uint64_t Address) \\\n{ \\\n' + \
+ ' unsigned Start, Len, NumToSkip, PIdx, Opc, DecodeIdx; \\\n' + \
+ ' InsnType Val, FieldValue, PositiveMask, NegativeMask; \\\n' + \
+ ' bool Pred, Fail, DecodeComplete = true; \\\n' + \
+ ' uint32_t ExpectedValue;'
+
+ adding_slash = True
+ print_line(line2)
+ # skip printing few lines
+ skip_print = True
+ elif 'const MCSubtargetInfo &STI' in line2:
+ skip_print = False
+ # skip this line
+ continue
+ elif 'Bits = STI.getFeatureBits()' in line2:
+ # skip this line
+ continue
+ elif 'errs() << ' in line2:
+ continue
+ elif 'unsigned Start =' in line2:
+ line2 = line2.replace('unsigned ', '')
+ elif 'unsigned Len =' in line2:
+ line2 = line2.replace('unsigned ', '')
+ elif 'unsigned Len;' in line2:
+ continue
+ elif 'MCInst TmpMI;' in line2:
+ continue
+ elif 'bool Pred;' in line2:
+ continue
+ elif 'bool DecodeComplete;' in line2:
+ continue
+ elif 'unsigned NumToSkip =' in line2:
+ line2 = line2.replace('unsigned ', '')
+ elif 'unsigned PIdx =' in line2:
+ line2 = line2.replace('unsigned ', '')
+ elif 'unsigned Opc =' in line2:
+ line2 = line2.replace('unsigned ', '')
+ elif 'unsigned DecodeIdx =' in line2:
+ line2 = line2.replace('unsigned ', '')
+ elif 'InsnType Val =' in line2:
+ line2 = line2.replace('InsnType ', '')
+ elif 'bool Fail' in line2:
+ line2 = line2.replace('bool ', '')
+ elif 'InsnType PositiveMask =' in line2:
+ line2 = line2.replace('InsnType ', '')
+ elif 'InsnType NegativeMask =' in line2:
+ line2 = line2.replace('InsnType ', '')
+ elif 'uint32_t ExpectedValue' in line2:
+ line2 = line2.replace('uint32_t ', '')
+ elif 'ptrdiff_t Loc = ' in line2:
+ continue
+ elif 'LLVM_DEBUG(' in line2:
+ # just this line?
+ if ');' in line2:
+ continue
+ skip_print = True
+ llvm_debug = True
+ continue
+ elif skip_print and llvm_debug and ');' in line2:
+ llvm_debug = False
+ skip_print = False
+ continue
+ elif 'decodeToMCInst(' in line2:
+ line2 = line2.replace('decodeToMCInst', 'decoder')
+ line2 = line2.replace('DecodeComplete);', '&DecodeComplete);')
+ line2 = line2.replace(', DisAsm', '')
+ line2 = line2.replace(', TmpMI', ', MI')
+ elif 'TmpMI.setOpcode(Opc);' in line2:
+ line2 = ' MCInst_setOpcode(MI, Opc);'
+ elif 'MI.setOpcode(Opc);' in line2:
+ line2 = ' MCInst_setOpcode(MI, Opc);'
+ elif 'MI.clear();' in line2:
+ line2 = ' MCInst_clear(MI);'
+ elif 'assert(' in line2:
+ line2 = line2.replace('assert(', '/* assert(')
+ line2 += ' */'
+ elif 'Check(S, ' in line2:
+ line2 = line2.replace('Check(S, ', 'Check(&S, ')
+ if 'DecodeImm8OptLsl<' in line2:
+ param = extract_brackets(line2)
+ line2 = del_brackets(line2)
+ line2 = line2.replace(', Decoder)', ', Decoder, %s)' %param)
+ elif 'DecodeSImm<' in line2:
+ param = extract_brackets(line2)
+ line2 = del_brackets(line2)
+ line2 = line2.replace(', Decoder)', ', Decoder, %s)' %param)
+ if 'DecodeComplete = false; ' in line2:
+ line2 = line2.replace('DecodeComplete = false; ', '')
+ elif 'decodeUImmOperand<' in line2 or 'decodeSImmOperand<' in line2 :
+ # decodeUImmOperand<5>(MI, tmp, Address, Decoder)
+ param = extract_brackets(line2)
+ line2 = del_brackets(line2)
+ line2 = line2.replace(', Decoder)', ', Decoder, %s)' %param)
+ elif 'MI.addOperand(MCOperand::createImm(tmp));' in line2:
+ line2 = ' MCOperand_CreateImm0(MI, tmp);'
+ elif 'MI = TmpMI;' in line2:
+ line2 = ''
+ #line2 = line2.replace('TmpMI', '&TmpMI')
+
+ line2 = line2.replace('::', '_')
+ print_line(line2)
+
+if sys.argv[2] == 'ARM':
+ print("""
+FieldFromInstruction(fieldFromInstruction_2, uint16_t)
+DecodeToMCInst(decodeToMCInst_2, fieldFromInstruction_2, uint16_t)
+DecodeInstruction(decodeInstruction_2, fieldFromInstruction_2, decodeToMCInst_2, uint16_t)
+
+FieldFromInstruction(fieldFromInstruction_4, uint32_t)
+DecodeToMCInst(decodeToMCInst_4, fieldFromInstruction_4, uint32_t)
+DecodeInstruction(decodeInstruction_4, fieldFromInstruction_4, decodeToMCInst_4, uint32_t)
+""")
+
+if sys.argv[2] in ('AArch64', 'PPC'):
+ print("""
+FieldFromInstruction(fieldFromInstruction_4, uint32_t)
+DecodeToMCInst(decodeToMCInst_4, fieldFromInstruction_4, uint32_t)
+DecodeInstruction(decodeInstruction_4, fieldFromInstruction_4, decodeToMCInst_4, uint32_t)
+""")