From 000840199efd5d76a1992d25be7939214972c2f2 Mon Sep 17 00:00:00 2001 From: Peace-Maker Date: Thu, 13 Jul 2023 19:11:01 +0200 Subject: [PATCH 1/9] Add Python bindings for WASM --- bindings/python/capstone/__init__.py | 7 ++- bindings/python/capstone/wasm.py | 71 ++++++++++++++++++++++++ bindings/python/pyx/ccapstone.pyx | 5 +- bindings/python/setup_cython.py | 2 +- bindings/python/test_basic.py | 6 ++- bindings/python/test_wasm.py | 81 ++++++++++++++++++++++++++++ 6 files changed, 167 insertions(+), 5 deletions(-) create mode 100644 bindings/python/capstone/wasm.py create mode 100755 bindings/python/test_wasm.py diff --git a/bindings/python/capstone/__init__.py b/bindings/python/capstone/__init__.py index 4ec23458d1..5bd4bc8d8f 100755 --- a/bindings/python/capstone/__init__.py +++ b/bindings/python/capstone/__init__.py @@ -35,6 +35,7 @@ 'CS_ARCH_TMS320C64X', 'CS_ARCH_M680X', 'CS_ARCH_EVM', + 'CS_ARCH_WASM', 'CS_ARCH_BPF', 'CS_ARCH_RISCV', 'CS_ARCH_MOS65XX', @@ -387,7 +388,7 @@ def copy_ctypes_list(src): return [copy_ctypes(n) for n in src] # Weird import placement because these modules are needed by the below code but need the above functions -from . import arm, arm64, m68k, mips, ppc, sparc, systemz, x86, xcore, tms320c64x, m680x, evm, mos65xx, bpf, riscv, tricore +from . import arm, arm64, m68k, mips, ppc, sparc, systemz, x86, xcore, tms320c64x, m680x, evm, mos65xx, wasm, bpf, riscv, tricore class _cs_arch(ctypes.Union): _fields_ = ( @@ -404,6 +405,7 @@ class _cs_arch(ctypes.Union): ('m680x', m680x.CsM680x), ('evm', evm.CsEvm), ('mos65xx', mos65xx.CsMOS65xx), + ('wasm', wasm.CsWasm), ('bpf', bpf.CsBPF), ('riscv', riscv.CsRISCV), ('tricore', tricore.CsTriCore), @@ -727,6 +729,8 @@ def __gen_detail(self): (self.pop, self.push, self.fee) = evm.get_arch_info(self._raw.detail.contents.arch.evm) elif arch == CS_ARCH_MOS65XX: (self.am, self.modifies_flags, self.operands) = mos65xx.get_arch_info(self._raw.detail.contents.arch.mos65xx) + elif arch == CS_ARCH_WASM: + (self.operands) = wasm.get_arch_info(self._raw.detail.contents.arch.wasm) elif arch == CS_ARCH_BPF: (self.operands) = bpf.get_arch_info(self._raw.detail.contents.arch.bpf) elif arch == CS_ARCH_RISCV: @@ -1199,6 +1203,7 @@ def debug(): "sysz": CS_ARCH_SYSZ, 'xcore': CS_ARCH_XCORE, "tms320c64x": CS_ARCH_TMS320C64X, "m680x": CS_ARCH_M680X, 'evm': CS_ARCH_EVM, 'mos65xx': CS_ARCH_MOS65XX, 'bpf': CS_ARCH_BPF, 'riscv': CS_ARCH_RISCV, 'tricore': CS_ARCH_TRICORE, + 'wasm': CS_ARCH_WASM, } all_archs = "" diff --git a/bindings/python/capstone/wasm.py b/bindings/python/capstone/wasm.py new file mode 100644 index 0000000000..23d68ca8ae --- /dev/null +++ b/bindings/python/capstone/wasm.py @@ -0,0 +1,71 @@ +# Capstone Python bindings, by Peace-Maker + +import ctypes + +from . import copy_ctypes_list +from .wasm_const import * + + +# define the API +class WASMBrTable(ctypes.Structure): + _fields_ = ( + ('length', ctypes.c_uint32), + ('address', ctypes.c_uint64), + ('default_target', ctypes.c_uint32), + ) + +class WASMOpValue(ctypes.Union): + _fields_ = ( + ('int7', ctypes.c_int8), + ('varuint32', ctypes.c_uint32), + ('varuint64', ctypes.c_uint64), + ('uint32', ctypes.c_uint32), + ('uint64', ctypes.c_uint64), + ('immediate', ctypes.c_uint32 * 2), + ('brtable', WASMBrTable), + ) + +class WASMOp(ctypes.Structure): + _fields_ = ( + ('type', ctypes.c_uint), + ('size', ctypes.c_uint32), + ('value', WASMOpValue), + ) + + @property + def int7(self): + return self.value.int7 + + @property + def varuint32(self): + return self.value.varuint32 + + @property + def varuint64(self): + return self.value.varuint64 + + @property + def uint32(self): + return self.value.uint32 + + @property + def uint64(self): + return self.value.uint64 + + @property + def immediate(self): + return self.value.immediate + + @property + def brtable(self): + return self.value.brtable + +class CsWasm(ctypes.Structure): + _fields_ = ( + ('op_count', ctypes.c_uint8), + ('operands', WASMOp * 2), + ) + +def get_arch_info(a): + return (copy_ctypes_list(a.operands[:a.op_count])) + diff --git a/bindings/python/pyx/ccapstone.pyx b/bindings/python/pyx/ccapstone.pyx index dbc92f6e55..3bf5d76c41 100644 --- a/bindings/python/pyx/ccapstone.pyx +++ b/bindings/python/pyx/ccapstone.pyx @@ -2,7 +2,7 @@ cimport pyx.ccapstone as cc import capstone, ctypes -from . import arm, x86, mips, ppc, arm64, sparc, systemz, xcore, tms320c64x, m68k, m680x, evm, mos65xx, bpf, riscv, tricore, CsError +from . import arm, x86, mips, ppc, arm64, sparc, systemz, xcore, tms320c64x, m68k, m680x, evm, mos65xx, wasm, bpf, riscv, tricore, CsError _diet = cc.cs_support(capstone.CS_SUPPORT_DIET) @@ -57,6 +57,8 @@ class CsDetail(object): (self.pop, self.push, self.fee) = evm.get_arch_info(detail.arch.evm) elif arch == capstone.CS_ARCH_MOS65XX: (self.am, self.modifies_flags, self.operands) = mos65xx.get_arch_info(detail.arch.mos65xx) + elif arch == capstone.CS_ARCH_WASM: + (self.operands) = wasm.get_arch_info(detail.arch.wasm) elif arch == capstone.CS_ARCH_BPF: (self.operands) = bpf.get_arch_info(detail.arch.bpf) elif arch == capstone.CS_ARCH_RISCV: @@ -361,6 +363,7 @@ def debug(): "sysz": capstone.CS_ARCH_SYSZ, "xcore": capstone.CS_ARCH_XCORE, \ "tms320c64x": capstone.CS_ARCH_TMS320C64X, "m680x": capstone.CS_ARCH_M680X, \ "evm": capstone.CS_ARCH_EVM, "mos65xx": capstone.CS_ARCH_MOS65XX, \ + "wasm": capstone.CS_ARCH_WASM, \ "bpf": capstone.CS_ARCH_BPF, "riscv": capstone.CS_ARCH_RISCV, \ "tricore": capstone.CS_ARCH_TRICORE } diff --git a/bindings/python/setup_cython.py b/bindings/python/setup_cython.py index 953b09a6db..6dc8e0393e 100644 --- a/bindings/python/setup_cython.py +++ b/bindings/python/setup_cython.py @@ -41,7 +41,7 @@ compile_args = ['-O3', '-fomit-frame-pointer', '-I' + HEADERS_DIR] link_args = ['-L' + LIBS_DIR] -ext_module_names = ['arm', 'arm_const', 'arm64', 'arm64_const', 'm68k', 'm68k_const', 'm680x', 'm680x_const', 'mips', 'mips_const', 'ppc', 'ppc_const', 'x86', 'x86_const', 'sparc', 'sparc_const', 'systemz', 'sysz_const', 'xcore', 'xcore_const', 'tms320c64x', 'tms320c64x_const', 'evm', 'evm_const', 'mos65xx', 'mos65xx_const', 'bpf', 'bpf_const', 'riscv', 'riscv_const', 'tricore', 'tricore_const' ] +ext_module_names = ['arm', 'arm_const', 'arm64', 'arm64_const', 'm68k', 'm68k_const', 'm680x', 'm680x_const', 'mips', 'mips_const', 'ppc', 'ppc_const', 'x86', 'x86_const', 'sparc', 'sparc_const', 'systemz', 'sysz_const', 'xcore', 'xcore_const', 'tms320c64x', 'tms320c64x_const', 'evm', 'evm_const', 'mos65xx', 'mos65xx_const', 'wasm', 'wasm_const', 'bpf', 'bpf_const', 'riscv', 'riscv_const', 'tricore', 'tricore_const' ] ext_modules = [Extension("capstone.ccapstone", ["pyx/ccapstone.pyx"], diff --git a/bindings/python/test_basic.py b/bindings/python/test_basic.py index 1f4c721a9f..55d153bfc3 100755 --- a/bindings/python/test_basic.py +++ b/bindings/python/test_basic.py @@ -34,6 +34,7 @@ M68K_CODE = b"\xd4\x40\x87\x5a\x4e\x71\x02\xb4\xc0\xde\xc0\xde\x5c\x00\x1d\x80\x71\x12\x01\x23\xf2\x3c\x44\x22\x40\x49\x0e\x56\x54\xc5\xf2\x3c\x44\x00\x44\x7a\x00\x00\xf2\x00\x0a\x28\x4E\xB9\x00\x00\x00\x12\x4E\x75" TMS320C64X_CODE = b"\x01\xac\x88\x40\x81\xac\x88\x43\x00\x00\x00\x00\x02\x90\x32\x96\x02\x80\x46\x9e\x05\x3c\x83\xe6\x0b\x0c\x8b\x24" M680X_CODE = b"\x06\x10\x19\x1a\x55\x1e\x01\x23\xe9\x31\x06\x34\x55\xa6\x81\xa7\x89\x7f\xff\xa6\x9d\x10\x00\xa7\x91\xa6\x9f\x10\x00\x11\xac\x99\x10\x00\x39" +WASM_CODE = b"\x20\x00\x20\x01\x41\x20\x10\xc9\x01\x45\x0b" RISCV_CODE32 = b"\x37\x34\x00\x00\x97\x82\x00\x00\xef\x00\x80\x00\xef\xf0\x1f\xff\xe7\x00\x45\x00\xe7\x00\xc0\xff\x63\x05\x41\x00\xe3\x9d\x61\xfe\x63\xca\x93\x00\x63\x53\xb5\x00\x63\x65\xd6\x00\x63\x76\xf7\x00\x03\x88\x18\x00\x03\x99\x49\x00\x03\xaa\x6a\x00\x03\xcb\x2b\x01\x03\xdc\x8c\x01\x23\x86\xad\x03\x23\x9a\xce\x03\x23\x8f\xef\x01\x93\x00\xe0\x00\x13\xa1\x01\x01\x13\xb2\x02\x7d\x13\xc3\x03\xdd\x13\xe4\xc4\x12\x13\xf5\x85\x0c\x13\x96\xe6\x01\x13\xd7\x97\x01\x13\xd8\xf8\x40\x33\x89\x49\x01\xb3\x0a\x7b\x41\x33\xac\xac\x01\xb3\x3d\xde\x01\x33\xd2\x62\x40\xb3\x43\x94\x00\x33\xe5\xc5\x00\xb3\x76\xf7\x00\xb3\x54\x39\x01\xb3\x50\x31\x00\x33\x9f\x0f\x00" RISCV_CODE64 = b"\x13\x04\xa8\x7a" @@ -65,8 +66,9 @@ (CS_ARCH_M68K, CS_MODE_BIG_ENDIAN | CS_MODE_M68K_040, M68K_CODE, "M68K (68040)", None), (CS_ARCH_TMS320C64X, 0, TMS320C64X_CODE, "TMS320C64x", None), (CS_ARCH_M680X, CS_MODE_M680X_6809, M680X_CODE, "M680X_M6809", None), - (CS_ARCH_RISCV, CS_MODE_RISCV32, RISCV_CODE32, "riscv32", None), - (CS_ARCH_RISCV, CS_MODE_RISCV64, RISCV_CODE64, "riscv64", None), + (CS_ARCH_WASM, 0, WASM_CODE, "WASM", None), + (CS_ARCH_RISCV, CS_MODE_RISCV32, RISCV_CODE32, "RISCV32", None), + (CS_ARCH_RISCV, CS_MODE_RISCV64, RISCV_CODE64, "RISCV64", None), ) # ## Test cs_disasm_quick() diff --git a/bindings/python/test_wasm.py b/bindings/python/test_wasm.py new file mode 100755 index 0000000000..2645711320 --- /dev/null +++ b/bindings/python/test_wasm.py @@ -0,0 +1,81 @@ +#!/usr/bin/env python + +# Capstone Python bindings, by Peace-Maker + +from __future__ import print_function +from capstone import * +from capstone.wasm import * +from xprint import to_hex + +WASM_CODE = b"\x20\x00\x20\x01\x41\x20\x10\xc9\x01\x45\x0b" + +all_tests = ( + (CS_ARCH_WASM, 0, WASM_CODE, "WASM"), +) + + +def print_insn_detail(insn): + # print address, mnemonic and operands + print("0x%x:\t%s\t%s" % (insn.address, insn.mnemonic, insn.op_str)) + + # "data" instruction generated by SKIPDATA option has no detail + if insn.id == 0: + return + + if len(insn.groups) > 0: + print("\tGroups: ", end="") + for group in insn.groups: + print("%s " % insn.group_name(group), end="") + print() + + if len(insn.operands) > 0: + print("\tOperand count: %u" % len(insn.operands)) + c = 0 + for i in insn.operands: + if i.type == WASM_OP_INT7: + print("\t\tOperand[%u] type: int7" % c) + print("\t\tOperand[%u] value: %d" % (c, i.int7)) + elif i.type == WASM_OP_VARUINT32: + print("\t\tOperand[%u] type: varuint32" % c) + print("\t\tOperand[%u] value: %#x" % (c, i.varuint32)) + elif i.type == WASM_OP_VARUINT64: + print("\t\tOperand[%u] type: varuint64" % c) + print("\t\tOperand[%u] value: %#x" % (c, i.varuint64)) + elif i.type == WASM_OP_UINT32: + print("\t\tOperand[%u] type: uint32" % c) + print("\t\tOperand[%u] value: %#x" % (c, i.uint32)) + elif i.type == WASM_OP_UINT64: + print("\t\tOperand[%u] type: uint64" % c) + print("\t\tOperand[%u] value: %#x" % (c, i.uint64)) + elif i.type == WASM_OP_IMM: + print("\t\tOperand[%u] type: imm" % c) + print("\t\tOperand[%u] value: %#x %#x" % (c, i.immediate[0], i.immediate[1])) + elif i.type == WASM_OP_BRTABLE: + print("\t\tOperand[%u] type: brtable" % c) + print("\t\tOperand[%u] value: length=%#x, address=%#x, default_target=%#x" % (c, i.brtable.length, i.brtable.address, i.brtable.default_target)) + print("\t\tOperand[%u] size: %u" % (c, i.size)) + c += 1 + + + +# ## Test class Cs +def test_class(): + for (arch, mode, code, comment) in all_tests: + print("*" * 16) + print("Platform: %s" % comment) + print("Code: %s" % to_hex(code)) + print("Disasm:") + + try: + md = Cs(arch, mode) + md.detail = True + for insn in md.disasm(code, 0xffff): + print_insn_detail(insn) + print() + print("0x%x:\n" % (insn.address + insn.size)) + except CsError as e: + print("ERROR: %s" % e) + + +if __name__ == '__main__': + test_class() From 99848981f34f7299b51a9e7a016dacafe7d883a3 Mon Sep 17 00:00:00 2001 From: Peace-Maker Date: Thu, 13 Jul 2023 19:23:22 +0200 Subject: [PATCH 2/9] Update Python bindings for m68k --- bindings/python/capstone/m68k.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/bindings/python/capstone/m68k.py b/bindings/python/capstone/m68k.py index 9cc8936548..9356462808 100644 --- a/bindings/python/capstone/m68k.py +++ b/bindings/python/capstone/m68k.py @@ -66,6 +66,10 @@ def simm(self): @property def reg(self): return self.value.reg + + @property + def reg_pair(self): + return self.value.reg_pair @property def mem(self): From 29175cf4b05c0cf98458a6f3a47216c9b976a746 Mon Sep 17 00:00:00 2001 From: Peace-Maker Date: Thu, 13 Jul 2023 19:23:59 +0200 Subject: [PATCH 3/9] Update Python bindings for mos65xx --- bindings/python/capstone/mos65xx.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bindings/python/capstone/mos65xx.py b/bindings/python/capstone/mos65xx.py index 11b3462a58..87a5f87054 100644 --- a/bindings/python/capstone/mos65xx.py +++ b/bindings/python/capstone/mos65xx.py @@ -8,8 +8,8 @@ class MOS65xxOpValue(ctypes.Union): _fields_ = ( ('reg', ctypes.c_uint), - ('imm', ctypes.c_uint8), - ('mem', ctypes.c_uint16), + ('imm', ctypes.c_uint16), + ('mem', ctypes.c_uint32), ) class MOS65xxOp(ctypes.Structure): From d3d0ab01a074a5226c2612ecedfdad0e61bd0c9d Mon Sep 17 00:00:00 2001 From: Peace-Maker Date: Thu, 13 Jul 2023 19:22:56 +0200 Subject: [PATCH 4/9] Update Python bindings for x86 --- bindings/python/capstone/__init__.py | 2 +- bindings/python/capstone/x86.py | 17 +++++++++++++++-- bindings/python/pyx/ccapstone.pyx | 2 +- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/bindings/python/capstone/__init__.py b/bindings/python/capstone/__init__.py index 5bd4bc8d8f..27b5202e63 100755 --- a/bindings/python/capstone/__init__.py +++ b/bindings/python/capstone/__init__.py @@ -705,7 +705,7 @@ def __gen_detail(self): (self.prefix, self.opcode, self.rex, self.addr_size, \ self.modrm, self.sib, self.disp, \ self.sib_index, self.sib_scale, self.sib_base, self.xop_cc, self.sse_cc, \ - self.avx_cc, self.avx_sae, self.avx_rm, self.eflags, \ + self.avx_cc, self.avx_sae, self.avx_rm, self.eflags, self.fpu_flags, \ self.encoding, self.modrm_offset, self.disp_offset, self.disp_size, self.imm_offset, self.imm_size, \ self.operands) = x86.get_arch_info(self._raw.detail.contents.arch.x86) elif arch == CS_ARCH_M68K: diff --git a/bindings/python/capstone/x86.py b/bindings/python/capstone/x86.py index f8056f1a94..caa5e35ebd 100644 --- a/bindings/python/capstone/x86.py +++ b/bindings/python/capstone/x86.py @@ -43,6 +43,11 @@ def reg(self): def mem(self): return self.value.mem +class X86Flags(ctypes.Union): + _fields_ = ( + ('eflags', ctypes.c_uint64), + ('fpu_flags', ctypes.c_uint64), + ) class CsX86Encoding(ctypes.Structure): _fields_ = ( @@ -70,16 +75,24 @@ class CsX86(ctypes.Structure): ('avx_cc', ctypes.c_uint), ('avx_sae', ctypes.c_bool), ('avx_rm', ctypes.c_uint), - ('eflags', ctypes.c_uint64), + ('flags', X86Flags), ('op_count', ctypes.c_uint8), ('operands', X86Op * 8), ('encoding', CsX86Encoding), ) + @property + def eflags(self): + return self.flags.eflags + + @property + def fpu_flags(self): + return self.flags.fpu_flags + def get_arch_info(a): return (a.prefix[:], a.opcode[:], a.rex, a.addr_size, \ a.modrm, a.sib, a.disp, a.sib_index, a.sib_scale, \ - a.sib_base, a.xop_cc, a.sse_cc, a.avx_cc, a.avx_sae, a.avx_rm, a.eflags, \ + a.sib_base, a.xop_cc, a.sse_cc, a.avx_cc, a.avx_sae, a.avx_rm, a.eflags, a.fpu_flags, \ a.encoding, a.encoding.modrm_offset, a.encoding.disp_offset, a.encoding.disp_size, a.encoding.imm_offset, a.encoding.imm_size, \ copy_ctypes_list(a.operands[:a.op_count])) diff --git a/bindings/python/pyx/ccapstone.pyx b/bindings/python/pyx/ccapstone.pyx index 3bf5d76c41..8b556b415d 100644 --- a/bindings/python/pyx/ccapstone.pyx +++ b/bindings/python/pyx/ccapstone.pyx @@ -34,7 +34,7 @@ class CsDetail(object): self.modrm, self.sib, self.disp, \ self.sib_index, self.sib_scale, self.sib_base, \ self.xop_cc, self.sse_cc, self.avx_cc, self.avx_sae, self.avx_rm, \ - self.eflags, self.encoding, self.modrm_offset, self.disp_offset, \ + self.eflags, self.fpu_flags, self.encoding, self.modrm_offset, self.disp_offset, \ self.disp_size, self.imm_offset, self.imm_size, self.operands) = x86.get_arch_info(detail.arch.x86) elif arch == capstone.CS_ARCH_M68K: (self.operands, self.op_size) = m68k.get_arch_info(detail.arch.m68k) From 5b05bcb1e009903dfd3d9c7000c48f9bb07f7119 Mon Sep 17 00:00:00 2001 From: Peace-Maker Date: Thu, 13 Jul 2023 19:16:06 +0200 Subject: [PATCH 5/9] Add Python bindings for SH --- .gitignore | 1 + bindings/const_generator.py | 3 +- bindings/python/capstone/__init__.py | 26 +- bindings/python/capstone/sh.py | 66 +++++ bindings/python/capstone/sh_const.py | 367 +++++++++++++++++++++++++++ bindings/python/pyx/ccapstone.pyx | 6 +- bindings/python/setup_cython.py | 2 +- bindings/python/test_sh.py | 97 +++++++ tests/Makefile | 4 + 9 files changed, 564 insertions(+), 8 deletions(-) create mode 100644 bindings/python/capstone/sh.py create mode 100644 bindings/python/capstone/sh_const.py create mode 100755 bindings/python/test_sh.py diff --git a/.gitignore b/.gitignore index aa1c8b6457..aa8f2543e4 100644 --- a/.gitignore +++ b/.gitignore @@ -72,6 +72,7 @@ tests/test_evm tests/test_wasm tests/test_mos65xx tests/test_bpf +tests/test_sh tests/test_riscv # regress binaries diff --git a/bindings/const_generator.py b/bindings/const_generator.py index 74c5f1e66c..fbe1947409 100644 --- a/bindings/const_generator.py +++ b/bindings/const_generator.py @@ -5,7 +5,7 @@ INCL_DIR = '../include/capstone/' -include = [ 'arm.h', 'arm64.h', 'm68k.h', 'mips.h', 'x86.h', 'ppc.h', 'sparc.h', 'systemz.h', 'xcore.h', 'tms320c64x.h', 'm680x.h', 'evm.h', 'mos65xx.h', 'wasm.h', 'bpf.h' ,'riscv.h', 'tricore.h' ] +include = [ 'arm.h', 'arm64.h', 'm68k.h', 'mips.h', 'x86.h', 'ppc.h', 'sparc.h', 'systemz.h', 'xcore.h', 'tms320c64x.h', 'm680x.h', 'evm.h', 'mos65xx.h', 'wasm.h', 'bpf.h' ,'riscv.h', 'sh.h', 'tricore.h' ] template = { 'java': { @@ -53,6 +53,7 @@ 'mos65xx.h': 'mos65xx', 'bpf.h': 'bpf', 'riscv.h': 'riscv', + 'sh.h': 'sh', 'tricore.h': ['TRICORE', 'TriCore'], 'comment_open': '#', 'comment_close': '', diff --git a/bindings/python/capstone/__init__.py b/bindings/python/capstone/__init__.py index 27b5202e63..74899bb3a4 100755 --- a/bindings/python/capstone/__init__.py +++ b/bindings/python/capstone/__init__.py @@ -35,10 +35,11 @@ 'CS_ARCH_TMS320C64X', 'CS_ARCH_M680X', 'CS_ARCH_EVM', + 'CS_ARCH_MOS65XX', 'CS_ARCH_WASM', 'CS_ARCH_BPF', 'CS_ARCH_RISCV', - 'CS_ARCH_MOS65XX', + 'CS_ARCH_SH', 'CS_ARCH_TRICORE', 'CS_ARCH_ALL', @@ -90,6 +91,13 @@ 'CS_MODE_MOS65XX_65816_LONG_M', 'CS_MODE_MOS65XX_65816_LONG_X', 'CS_MODE_MOS65XX_65816_LONG_MX', + 'CS_MODE_SH2', + 'CS_MODE_SH2A', + 'CS_MODE_SH3', + 'CS_MODE_SH4', + 'CS_MODE_SH4A', + 'CS_MODE_SHFPU', + 'CS_MODE_SHDSP', 'CS_MODE_TRICORE_110', 'CS_MODE_TRICORE_120', 'CS_MODE_TRICORE_130', @@ -186,7 +194,7 @@ CS_ARCH_WASM = 13 CS_ARCH_BPF = 14 CS_ARCH_RISCV = 15 -# CS_ARCH_SH = 16 +CS_ARCH_SH = 16 CS_ARCH_TRICORE = 17 CS_ARCH_MAX = 18 CS_ARCH_ALL = 0xFFFF @@ -240,6 +248,13 @@ CS_MODE_MOS65XX_65816_LONG_M = (1 << 5) # MOS65XXX WDC 65816, 16-bit m, 8-bit x CS_MODE_MOS65XX_65816_LONG_X = (1 << 6) # MOS65XXX WDC 65816, 8-bit m, 16-bit x CS_MODE_MOS65XX_65816_LONG_MX = CS_MODE_MOS65XX_65816_LONG_M | CS_MODE_MOS65XX_65816_LONG_X +CS_MODE_SH2 = 1 << 1 # SH2 +CS_MODE_SH2A = 1 << 2 # SH2A +CS_MODE_SH3 = 1 << 3 # SH3 +CS_MODE_SH4 = 1 << 4 # SH4 +CS_MODE_SH4A = 1 << 5 # SH4A +CS_MODE_SHFPU = 1 << 6 # w/ FPU +CS_MODE_SHDSP = 1 << 7 # w/ DSP CS_MODE_TRICORE_110 = 1 << 1 # Tricore 1.1 CS_MODE_TRICORE_120 = 1 << 2 # Tricore 1.2 CS_MODE_TRICORE_130 = 1 << 3 # Tricore 1.3 @@ -388,7 +403,7 @@ def copy_ctypes_list(src): return [copy_ctypes(n) for n in src] # Weird import placement because these modules are needed by the below code but need the above functions -from . import arm, arm64, m68k, mips, ppc, sparc, systemz, x86, xcore, tms320c64x, m680x, evm, mos65xx, wasm, bpf, riscv, tricore +from . import arm, arm64, m68k, mips, ppc, sparc, systemz, x86, xcore, tms320c64x, m680x, evm, mos65xx, wasm, bpf, riscv, sh, tricore class _cs_arch(ctypes.Union): _fields_ = ( @@ -408,6 +423,7 @@ class _cs_arch(ctypes.Union): ('wasm', wasm.CsWasm), ('bpf', bpf.CsBPF), ('riscv', riscv.CsRISCV), + ('sh', sh.CsSH), ('tricore', tricore.CsTriCore), ) @@ -735,6 +751,8 @@ def __gen_detail(self): (self.operands) = bpf.get_arch_info(self._raw.detail.contents.arch.bpf) elif arch == CS_ARCH_RISCV: (self.need_effective_addr, self.operands) = riscv.get_arch_info(self._raw.detail.contents.arch.riscv) + elif arch == CS_ARCH_SH: + (self.sh_insn, self.sh_size, self.operands) = sh.get_arch_info(self._raw.detail.contents.arch.sh) elif arch == CS_ARCH_TRICORE: (self.update_flags, self.operands) = tricore.get_arch_info(self._raw.detail.contents.arch.tricore) @@ -1203,7 +1221,7 @@ def debug(): "sysz": CS_ARCH_SYSZ, 'xcore': CS_ARCH_XCORE, "tms320c64x": CS_ARCH_TMS320C64X, "m680x": CS_ARCH_M680X, 'evm': CS_ARCH_EVM, 'mos65xx': CS_ARCH_MOS65XX, 'bpf': CS_ARCH_BPF, 'riscv': CS_ARCH_RISCV, 'tricore': CS_ARCH_TRICORE, - 'wasm': CS_ARCH_WASM, + 'wasm': CS_ARCH_WASM, 'sh': CS_ARCH_SH, } all_archs = "" diff --git a/bindings/python/capstone/sh.py b/bindings/python/capstone/sh.py new file mode 100644 index 0000000000..a00f8c669c --- /dev/null +++ b/bindings/python/capstone/sh.py @@ -0,0 +1,66 @@ +# Capstone Python bindings, by Peace-Maker + +import ctypes +from . import copy_ctypes_list +from .sh_const import * + +# define the API +class SHOpMem(ctypes.Structure): + _fields_ = ( + ('address', ctypes.c_uint), + ('reg', ctypes.c_uint), + ('disp', ctypes.c_uint32), + ) + +class SHOpDsp(ctypes.Structure): + _fields_ = ( + ('insn', ctypes.c_uint), + ('operand', ctypes.c_uint * 2), + ('r', ctypes.c_uint * 6), + ('cc', ctypes.c_uint), + ('imm', ctypes.c_uint8), + ('size', ctypes.c_int), + ) + +class SHOpValue(ctypes.Union): + _fields_ = ( + ('imm', ctypes.c_int64), + ('reg', ctypes.c_uint), + ('mem', SHOpMem), + ('dsp', SHOpDsp), + ) + +class SHOp(ctypes.Structure): + _fields_ = ( + ('type', ctypes.c_uint), + ('value', SHOpValue), + ) + + @property + def imm(self): + return self.value.imm + + @property + def reg(self): + return self.value.reg + + @property + def mem(self): + return self.value.mem + + @property + def dsp(self): + return self.value.dsp + + +class CsSH(ctypes.Structure): + _fields_ = ( + ('insn', ctypes.c_uint), + ('size', ctypes.c_uint8), + ('op_count', ctypes.c_uint8), + ('operands', SHOp * 3), + ) + +def get_arch_info(a): + return (a.insn, a.size, copy_ctypes_list(a.operands[:a.op_count])) + diff --git a/bindings/python/capstone/sh_const.py b/bindings/python/capstone/sh_const.py new file mode 100644 index 0000000000..5c6cdd0cba --- /dev/null +++ b/bindings/python/capstone/sh_const.py @@ -0,0 +1,367 @@ +from . import CS_OP_INVALID, CS_OP_REG, CS_OP_IMM, CS_OP_MEM +# For Capstone Engine. AUTO-GENERATED FILE, DO NOT EDIT [sh_const.py] + +SH_REG_INVALID = 0 +SH_REG_R0 = 1 +SH_REG_R1 = 2 +SH_REG_R2 = 3 +SH_REG_R3 = 4 +SH_REG_R4 = 5 +SH_REG_R5 = 6 +SH_REG_R6 = 7 +SH_REG_R7 = 8 +SH_REG_R8 = 9 +SH_REG_R9 = 10 +SH_REG_R10 = 11 +SH_REG_R11 = 12 +SH_REG_R12 = 13 +SH_REG_R13 = 14 +SH_REG_R14 = 15 +SH_REG_R15 = 16 +SH_REG_R0_BANK = 17 +SH_REG_R1_BANK = 18 +SH_REG_R2_BANK = 19 +SH_REG_R3_BANK = 20 +SH_REG_R4_BANK = 21 +SH_REG_R5_BANK = 22 +SH_REG_R6_BANK = 23 +SH_REG_R7_BANK = 24 +SH_REG_FR0 = 25 +SH_REG_FR1 = 26 +SH_REG_FR2 = 27 +SH_REG_FR3 = 28 +SH_REG_FR4 = 29 +SH_REG_FR5 = 30 +SH_REG_FR6 = 31 +SH_REG_FR7 = 32 +SH_REG_FR8 = 33 +SH_REG_FR9 = 34 +SH_REG_FR10 = 35 +SH_REG_FR11 = 36 +SH_REG_FR12 = 37 +SH_REG_FR13 = 38 +SH_REG_FR14 = 39 +SH_REG_FR15 = 40 +SH_REG_DR0 = 41 +SH_REG_DR2 = 42 +SH_REG_DR4 = 43 +SH_REG_DR6 = 44 +SH_REG_DR8 = 45 +SH_REG_DR10 = 46 +SH_REG_DR12 = 47 +SH_REG_DR14 = 48 +SH_REG_XD0 = 49 +SH_REG_XD2 = 50 +SH_REG_XD4 = 51 +SH_REG_XD6 = 52 +SH_REG_XD8 = 53 +SH_REG_XD10 = 54 +SH_REG_XD12 = 55 +SH_REG_XD14 = 56 +SH_REG_XF0 = 57 +SH_REG_XF1 = 58 +SH_REG_XF2 = 59 +SH_REG_XF3 = 60 +SH_REG_XF4 = 61 +SH_REG_XF5 = 62 +SH_REG_XF6 = 63 +SH_REG_XF7 = 64 +SH_REG_XF8 = 65 +SH_REG_XF9 = 66 +SH_REG_XF10 = 67 +SH_REG_XF11 = 68 +SH_REG_XF12 = 69 +SH_REG_XF13 = 70 +SH_REG_XF14 = 71 +SH_REG_XF15 = 72 +SH_REG_FV0 = 73 +SH_REG_FV4 = 74 +SH_REG_FV8 = 75 +SH_REG_FV12 = 76 +SH_REG_XMATRX = 77 +SH_REG_PC = 78 +SH_REG_PR = 79 +SH_REG_MACH = 80 +SH_REG_MACL = 81 +SH_REG_SR = 82 +SH_REG_GBR = 83 +SH_REG_SSR = 84 +SH_REG_SPC = 85 +SH_REG_SGR = 86 +SH_REG_DBR = 87 +SH_REG_VBR = 88 +SH_REG_TBR = 89 +SH_REG_RS = 90 +SH_REG_RE = 91 +SH_REG_MOD = 92 +SH_REG_FPUL = 93 +SH_REG_FPSCR = 94 +SH_REG_DSP_X0 = 95 +SH_REG_DSP_X1 = 96 +SH_REG_DSP_Y0 = 97 +SH_REG_DSP_Y1 = 98 +SH_REG_DSP_A0 = 99 +SH_REG_DSP_A1 = 100 +SH_REG_DSP_A0G = 101 +SH_REG_DSP_A1G = 102 +SH_REG_DSP_M0 = 103 +SH_REG_DSP_M1 = 104 +SH_REG_DSP_DSR = 105 +SH_REG_DSP_RSV0 = 106 +SH_REG_DSP_RSV1 = 107 +SH_REG_DSP_RSV2 = 108 +SH_REG_DSP_RSV3 = 109 +SH_REG_DSP_RSV4 = 110 +SH_REG_DSP_RSV5 = 111 +SH_REG_DSP_RSV6 = 112 +SH_REG_DSP_RSV7 = 113 +SH_REG_DSP_RSV8 = 114 +SH_REG_DSP_RSV9 = 115 +SH_REG_DSP_RSVA = 116 +SH_REG_DSP_RSVB = 117 +SH_REG_DSP_RSVC = 118 +SH_REG_DSP_RSVD = 119 +SH_REG_DSP_RSVE = 120 +SH_REG_DSP_RSVF = 121 +SH_REG_ENDING = 122 + +SH_OP_INVALID = 0 +SH_OP_REG = 1 +SH_OP_IMM = 2 +SH_OP_MEM = 3 + +SH_OP_MEM_INVALID = 0 +SH_OP_MEM_REG_IND = 1 +SH_OP_MEM_REG_POST = 2 +SH_OP_MEM_REG_PRE = 3 +SH_OP_MEM_REG_DISP = 4 +SH_OP_MEM_REG_R0 = 5 +SH_OP_MEM_GBR_DISP = 6 +SH_OP_MEM_GBR_R0 = 7 +SH_OP_MEM_PCR = 8 +SH_OP_MEM_TBR_DISP = 9 +SH_INS_DSP_INVALID = 10 +SH_INS_DSP_DOUBLE = 11 +SH_INS_DSP_SINGLE = 12 +SH_INS_DSP_PARALLEL = 13 +SH_INS_DSP_NOP = 1 +SH_INS_DSP_MOV = 2 +SH_INS_DSP_PSHL = 3 +SH_INS_DSP_PSHA = 4 +SH_INS_DSP_PMULS = 5 +SH_INS_DSP_PCLR_PMULS = 6 +SH_INS_DSP_PSUB_PMULS = 7 +SH_INS_DSP_PADD_PMULS = 8 +SH_INS_DSP_PSUBC = 9 +SH_INS_DSP_PADDC = 10 +SH_INS_DSP_PCMP = 11 +SH_INS_DSP_PABS = 12 +SH_INS_DSP_PRND = 13 +SH_INS_DSP_PSUB = 14 +SH_INS_DSP_PSUBr = 15 +SH_INS_DSP_PADD = 16 +SH_INS_DSP_PAND = 17 +SH_INS_DSP_PXOR = 18 +SH_INS_DSP_POR = 19 +SH_INS_DSP_PDEC = 20 +SH_INS_DSP_PINC = 21 +SH_INS_DSP_PCLR = 22 +SH_INS_DSP_PDMSB = 23 +SH_INS_DSP_PNEG = 24 +SH_INS_DSP_PCOPY = 25 +SH_INS_DSP_PSTS = 26 +SH_INS_DSP_PLDS = 27 +SH_INS_DSP_PSWAP = 28 +SH_INS_DSP_PWAD = 29 +SH_INS_DSP_PWSB = 30 +SH_OP_DSP_INVALID = 31 +SH_OP_DSP_REG_PRE = 32 +SH_OP_DSP_REG_IND = 33 +SH_OP_DSP_REG_POST = 34 +SH_OP_DSP_REG_INDEX = 35 +SH_OP_DSP_REG = 36 +SH_OP_DSP_IMM = 37 +SH_DSP_CC_INVALID = 38 +SH_DSP_CC_NONE = 39 +SH_DSP_CC_DCT = 40 +SH_DSP_CC_DCF = 41 +SH_INS_INVALID = 42 +SH_INS_ADD_r = 43 +SH_INS_ADD = 44 +SH_INS_ADDC = 45 +SH_INS_ADDV = 46 +SH_INS_AND = 47 +SH_INS_BAND = 48 +SH_INS_BANDNOT = 49 +SH_INS_BCLR = 50 +SH_INS_BF = 51 +SH_INS_BF_S = 52 +SH_INS_BLD = 53 +SH_INS_BLDNOT = 54 +SH_INS_BOR = 55 +SH_INS_BORNOT = 56 +SH_INS_BRA = 57 +SH_INS_BRAF = 58 +SH_INS_BSET = 59 +SH_INS_BSR = 60 +SH_INS_BSRF = 61 +SH_INS_BST = 62 +SH_INS_BT = 63 +SH_INS_BT_S = 64 +SH_INS_BXOR = 65 +SH_INS_CLIPS = 66 +SH_INS_CLIPU = 67 +SH_INS_CLRDMXY = 68 +SH_INS_CLRMAC = 69 +SH_INS_CLRS = 70 +SH_INS_CLRT = 71 +SH_INS_CMP_EQ = 72 +SH_INS_CMP_GE = 73 +SH_INS_CMP_GT = 74 +SH_INS_CMP_HI = 75 +SH_INS_CMP_HS = 76 +SH_INS_CMP_PL = 77 +SH_INS_CMP_PZ = 78 +SH_INS_CMP_STR = 79 +SH_INS_DIV0S = 80 +SH_INS_DIV0U = 81 +SH_INS_DIV1 = 82 +SH_INS_DIVS = 83 +SH_INS_DIVU = 84 +SH_INS_DMULS_L = 85 +SH_INS_DMULU_L = 86 +SH_INS_DT = 87 +SH_INS_EXTS_B = 88 +SH_INS_EXTS_W = 89 +SH_INS_EXTU_B = 90 +SH_INS_EXTU_W = 91 +SH_INS_FABS = 92 +SH_INS_FADD = 93 +SH_INS_FCMP_EQ = 94 +SH_INS_FCMP_GT = 95 +SH_INS_FCNVDS = 96 +SH_INS_FCNVSD = 97 +SH_INS_FDIV = 98 +SH_INS_FIPR = 99 +SH_INS_FLDI0 = 100 +SH_INS_FLDI1 = 101 +SH_INS_FLDS = 102 +SH_INS_FLOAT = 103 +SH_INS_FMAC = 104 +SH_INS_FMOV = 105 +SH_INS_FMUL = 106 +SH_INS_FNEG = 107 +SH_INS_FPCHG = 108 +SH_INS_FRCHG = 109 +SH_INS_FSCA = 110 +SH_INS_FSCHG = 111 +SH_INS_FSQRT = 112 +SH_INS_FSRRA = 113 +SH_INS_FSTS = 114 +SH_INS_FSUB = 115 +SH_INS_FTRC = 116 +SH_INS_FTRV = 117 +SH_INS_ICBI = 118 +SH_INS_JMP = 119 +SH_INS_JSR = 120 +SH_INS_JSR_N = 121 +SH_INS_LDBANK = 122 +SH_INS_LDC = 123 +SH_INS_LDRC = 124 +SH_INS_LDRE = 125 +SH_INS_LDRS = 126 +SH_INS_LDS = 127 +SH_INS_LDTLB = 128 +SH_INS_MAC_L = 129 +SH_INS_MAC_W = 130 +SH_INS_MOV = 131 +SH_INS_MOVA = 132 +SH_INS_MOVCA = 133 +SH_INS_MOVCO = 134 +SH_INS_MOVI20 = 135 +SH_INS_MOVI20S = 136 +SH_INS_MOVLI = 137 +SH_INS_MOVML = 138 +SH_INS_MOVMU = 139 +SH_INS_MOVRT = 140 +SH_INS_MOVT = 141 +SH_INS_MOVU = 142 +SH_INS_MOVUA = 143 +SH_INS_MUL_L = 144 +SH_INS_MULR = 145 +SH_INS_MULS_W = 146 +SH_INS_MULU_W = 147 +SH_INS_NEG = 148 +SH_INS_NEGC = 149 +SH_INS_NOP = 150 +SH_INS_NOT = 151 +SH_INS_NOTT = 152 +SH_INS_OCBI = 153 +SH_INS_OCBP = 154 +SH_INS_OCBWB = 155 +SH_INS_OR = 156 +SH_INS_PREF = 157 +SH_INS_PREFI = 158 +SH_INS_RESBANK = 159 +SH_INS_ROTCL = 160 +SH_INS_ROTCR = 161 +SH_INS_ROTL = 162 +SH_INS_ROTR = 163 +SH_INS_RTE = 164 +SH_INS_RTS = 165 +SH_INS_RTS_N = 166 +SH_INS_RTV_N = 167 +SH_INS_SETDMX = 168 +SH_INS_SETDMY = 169 +SH_INS_SETRC = 170 +SH_INS_SETS = 171 +SH_INS_SETT = 172 +SH_INS_SHAD = 173 +SH_INS_SHAL = 174 +SH_INS_SHAR = 175 +SH_INS_SHLD = 176 +SH_INS_SHLL = 177 +SH_INS_SHLL16 = 178 +SH_INS_SHLL2 = 179 +SH_INS_SHLL8 = 180 +SH_INS_SHLR = 181 +SH_INS_SHLR16 = 182 +SH_INS_SHLR2 = 183 +SH_INS_SHLR8 = 184 +SH_INS_SLEEP = 185 +SH_INS_STBANK = 186 +SH_INS_STC = 187 +SH_INS_STS = 188 +SH_INS_SUB = 189 +SH_INS_SUBC = 190 +SH_INS_SUBV = 191 +SH_INS_SWAP_B = 192 +SH_INS_SWAP_W = 193 +SH_INS_SYNCO = 194 +SH_INS_TAS = 195 +SH_INS_TRAPA = 196 +SH_INS_TST = 197 +SH_INS_XOR = 198 +SH_INS_XTRCT = 199 +SH_INS_DSP = 200 +SH_INS_ENDING = 201 + +SH_GRP_INVALID = 0 +SH_GRP_JUMP = 1 +SH_GRP_CALL = 2 +SH_GRP_INT = 3 +SH_GRP_RET = 4 +SH_GRP_IRET = 5 +SH_GRP_PRIVILEGE = 6 +SH_GRP_BRANCH_RELATIVE = 7 +SH_GRP_SH1 = 8 +SH_GRP_SH2 = 9 +SH_GRP_SH2E = 10 +SH_GRP_SH2DSP = 11 +SH_GRP_SH2A = 12 +SH_GRP_SH2AFPU = 13 +SH_GRP_SH3 = 14 +SH_GRP_SH3DSP = 15 +SH_GRP_SH4 = 16 +SH_GRP_SH4A = 17 +SH_GRP_ENDING = 18 diff --git a/bindings/python/pyx/ccapstone.pyx b/bindings/python/pyx/ccapstone.pyx index 8b556b415d..932752c4de 100644 --- a/bindings/python/pyx/ccapstone.pyx +++ b/bindings/python/pyx/ccapstone.pyx @@ -2,7 +2,7 @@ cimport pyx.ccapstone as cc import capstone, ctypes -from . import arm, x86, mips, ppc, arm64, sparc, systemz, xcore, tms320c64x, m68k, m680x, evm, mos65xx, wasm, bpf, riscv, tricore, CsError +from . import arm, x86, mips, ppc, arm64, sparc, systemz, xcore, tms320c64x, m68k, m680x, evm, mos65xx, wasm, bpf, riscv, sh, tricore, CsError _diet = cc.cs_support(capstone.CS_SUPPORT_DIET) @@ -63,6 +63,8 @@ class CsDetail(object): (self.operands) = bpf.get_arch_info(detail.arch.bpf) elif arch == capstone.CS_ARCH_RISCV: (self.need_effective_addr, self.operands) = riscv.get_arch_info(detail.arch.riscv) + elif arch == capstone.CS_ARCH_SH: + (self.sh_insn, self.sh_size, self.operands) = sh.get_arch_info(detail.arch.sh) elif arch == capstone.CS_ARCH_TRICORE: (self.update_flags, self.operands) = tricore.get_arch_info(detail.arch.tricore) @@ -365,7 +367,7 @@ def debug(): "evm": capstone.CS_ARCH_EVM, "mos65xx": capstone.CS_ARCH_MOS65XX, \ "wasm": capstone.CS_ARCH_WASM, \ "bpf": capstone.CS_ARCH_BPF, "riscv": capstone.CS_ARCH_RISCV, \ - "tricore": capstone.CS_ARCH_TRICORE } + "sh": capstone.CS_ARCH_SH, "tricore": capstone.CS_ARCH_TRICORE } all_archs = "" keys = list(archs.keys()) diff --git a/bindings/python/setup_cython.py b/bindings/python/setup_cython.py index 6dc8e0393e..70fcc856c9 100644 --- a/bindings/python/setup_cython.py +++ b/bindings/python/setup_cython.py @@ -41,7 +41,7 @@ compile_args = ['-O3', '-fomit-frame-pointer', '-I' + HEADERS_DIR] link_args = ['-L' + LIBS_DIR] -ext_module_names = ['arm', 'arm_const', 'arm64', 'arm64_const', 'm68k', 'm68k_const', 'm680x', 'm680x_const', 'mips', 'mips_const', 'ppc', 'ppc_const', 'x86', 'x86_const', 'sparc', 'sparc_const', 'systemz', 'sysz_const', 'xcore', 'xcore_const', 'tms320c64x', 'tms320c64x_const', 'evm', 'evm_const', 'mos65xx', 'mos65xx_const', 'wasm', 'wasm_const', 'bpf', 'bpf_const', 'riscv', 'riscv_const', 'tricore', 'tricore_const' ] +ext_module_names = ['arm', 'arm_const', 'arm64', 'arm64_const', 'm68k', 'm68k_const', 'm680x', 'm680x_const', 'mips', 'mips_const', 'ppc', 'ppc_const', 'x86', 'x86_const', 'sparc', 'sparc_const', 'systemz', 'sysz_const', 'xcore', 'xcore_const', 'tms320c64x', 'tms320c64x_const', 'evm', 'evm_const', 'mos65xx', 'mos65xx_const', 'wasm', 'wasm_const', 'bpf', 'bpf_const', 'riscv', 'riscv_const', 'sh', 'sh_const', 'tricore', 'tricore_const' ] ext_modules = [Extension("capstone.ccapstone", ["pyx/ccapstone.pyx"], diff --git a/bindings/python/test_sh.py b/bindings/python/test_sh.py new file mode 100755 index 0000000000..1afe31c3eb --- /dev/null +++ b/bindings/python/test_sh.py @@ -0,0 +1,97 @@ +#!/usr/bin/env python + +# Capstone Python bindings, by Peace-Maker + +from __future__ import print_function +from capstone import * +from capstone.sh import * +from xprint import to_x, to_hex + +SH4A_CODE = b"\x0c\x31\x10\x20\x22\x21\x36\x64\x46\x25\x12\x12\x1c\x02\x08\xc1\x05\xc7\x0c\x71\x1f\x02\x22\xcf\x06\x89\x23\x00\x2b\x41\x0b\x00\x0e\x40\x32\x00\x0a\xf1\x09\x00" +SH2A_CODE = b"\x32\x11\x92\x00\x32\x49\x31\x00" +all_tests = ( + (CS_ARCH_SH, CS_MODE_SH4A | CS_MODE_SHFPU, SH4A_CODE, "SH_SH4A"), + (CS_ARCH_SH, CS_MODE_SH2A | CS_MODE_SHFPU | CS_MODE_BIG_ENDIAN, SH2A_CODE, "SH_SH2A"), +) + + +reg_address_msg = [ + "Register indirect", + "Register indirect with predecrement", + "Register indirect with postincrement", +] + +def print_read_write_regs(insn): + if len(insn.regs_read) > 0: + print("\tRegisters read: %s" % " ".join(insn.reg_name(m) for m in insn.regs_read)) + + if len(insn.regs_write) > 0: + print("\tRegisters modified: %s" % " ".join(insn.reg_name(m) for m in insn.regs_write)) + +def print_insn_detail(insn): + # print address, mnemonic and operands + print("0x%x:\t%s\t%s" % (insn.address, insn.mnemonic, insn.op_str)) + + # "data" instruction generated by SKIPDATA option has no detail + if insn.id == 0: + return + + if len(insn.operands) > 0: + print("\top_count: %u" % len(insn.operands)) + c = 0 + for i in insn.operands: + if i.type == SH_OP_REG: + print("\t\toperands[%u].type: REG = %s" % (c, insn.reg_name(i.reg))) + elif i.type == SH_OP_IMM: + print("\t\toperands[%u].type: IMM = 0x%s" % (c, to_x(i.imm))) + elif i.type == SH_OP_MEM: + print("\t\toperands[%u].type: MEM " % c) + if i.mem.address in [SH_OP_MEM_REG_IND, SH_OP_MEM_REG_POST, SH_OP_MEM_REG_PRE]: + print("%s REG %s" % (reg_address_msg[i.mem.address - SH_OP_MEM_REG_IND], insn.reg_name(i.mem.reg))) + elif i.mem.address == SH_OP_MEM_REG_DISP: + print("Register indirect with displacement REG %s, DISP %d" % (insn.reg_name(i.mem.reg), i.mem.disp)) + elif i.mem.address == SH_OP_MEM_REG_R0: + print("R0 indexed") + elif i.mem.address == SH_OP_MEM_GBR_DISP: + print("GBR base with displacement DISP %d" % i.mem.disp) + elif i.mem.address == SH_OP_MEM_GBR_R0: + print("GBR base with R0 indexed") + elif i.mem.address == SH_OP_MEM_PCR: + print("PC relative Address=0x%08x" % i.mem.disp) + elif i.mem.address == SH_OP_MEM_TBR_DISP: + print("TBR base with displacement DISP %d", i.mem.disp) + else: + print("Unknown addressing mode %x" % i.mem.address) + + if i.sh_size != 0: + print("\t\t\tsh_size: %u" % i.sh_size) + c += 1 + + print_read_write_regs(insn) + + if len(insn.groups) > 0: + print('\tgroups: ' + ' '.join(map(lambda g: insn.group_name(g), insn.groups))) + + +# ## Test class Cs +def test_class(): + + for (arch, mode, code, comment) in all_tests: + print("*" * 16) + print("Platform: %s" %comment) + print("Code: %s" % to_hex(code)) + print("Disasm:") + + try: + md = Cs(arch, mode) + md.detail = True + for insn in md.disasm(code, 0x80000000): + print_insn_detail(insn) + print() + print("0x%x:" % (insn.address + insn.size)) + except CsError as e: + print("ERROR: %s" %e) + + +if __name__ == '__main__': + test_class() diff --git a/tests/Makefile b/tests/Makefile index a66df22fcc..b9e90c6d01 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -132,6 +132,10 @@ endif ifneq (,$(findstring tricore,$(CAPSTONE_ARCHS))) SOURCES += test_tricore.c endif +ifneq (,$(findstring sh,$(CAPSTONE_ARCHS))) +CFLAGS += -DCAPSTONE_HAS_SH +SOURCES += test_sh.c +endif OBJS = $(addprefix $(OBJDIR)/,$(SOURCES:.c=.o)) BINARY = $(addprefix $(TESTDIR)/,$(SOURCES:.c=$(BIN_EXT))) From b8febfe0db0fb0f191101ea7712b510af1347dc0 Mon Sep 17 00:00:00 2001 From: Peace-Maker Date: Thu, 13 Jul 2023 19:20:37 +0200 Subject: [PATCH 6/9] Update CS_* constants in Python bindings --- bindings/python/capstone/__init__.py | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/bindings/python/capstone/__init__.py b/bindings/python/capstone/__init__.py index 74899bb3a4..ca0435ad01 100755 --- a/bindings/python/capstone/__init__.py +++ b/bindings/python/capstone/__init__.py @@ -119,7 +119,13 @@ 'CS_OPT_ON', 'CS_OPT_OFF', + 'CS_OPT_INVALID', 'CS_OPT_MEM', + 'CS_OPT_SKIPDATA', + 'CS_OPT_SKIPDATA_SETUP', + 'CS_OPT_MNEMONIC', + 'CS_OPT_UNSIGNED', + 'CS_OPT_NO_BRANCH_OFFSET', 'CS_ERR_OK', 'CS_ERR_MEM', @@ -135,6 +141,7 @@ 'CS_ERR_SKIPDATA', 'CS_ERR_X86_ATT', 'CS_ERR_X86_INTEL', + 'CS_ERR_X86_MASM', 'CS_SUPPORT_DIET', 'CS_SUPPORT_X86_REDUCE', @@ -143,8 +150,8 @@ 'CS_OP_INVALID', 'CS_OP_REG', 'CS_OP_IMM', - 'CS_OP_MEM', 'CS_OP_FP', + 'CS_OP_MEM', 'CS_GRP_INVALID', 'CS_GRP_JUMP', @@ -264,6 +271,7 @@ CS_MODE_TRICORE_162 = 1 << 7 # Tricore 1.6.2 # Capstone option type +CS_OPT_INVALID = 0 # No option specified CS_OPT_SYNTAX = 1 # Intel X86 asm syntax (CS_ARCH_X86 arch) CS_OPT_DETAIL = 2 # Break down instruction structure into details CS_OPT_MODE = 3 # Change engine's mode at run-time @@ -272,17 +280,18 @@ CS_OPT_SKIPDATA_SETUP = 6 # Setup user-defined function for SKIPDATA option CS_OPT_MNEMONIC = 7 # Customize instruction mnemonic CS_OPT_UNSIGNED = 8 # Print immediate in unsigned form +CS_OPT_NO_BRANCH_OFFSET = 9 # ARM, prints branch immediates without offset. # Capstone option value CS_OPT_OFF = 0 # Turn OFF an option - default option of CS_OPT_DETAIL CS_OPT_ON = 3 # Turn ON an option (CS_OPT_DETAIL) # Common instruction operand types - to be consistent across all architectures. -CS_OP_INVALID = 0 -CS_OP_REG = 1 -CS_OP_IMM = 2 -CS_OP_MEM = 3 -CS_OP_FP = 4 +CS_OP_INVALID = 0 # uninitialized/invalid operand. +CS_OP_REG = 1 # Register operand. +CS_OP_IMM = 2 # Immediate operand. +CS_OP_FP = 3 # Floating-Point operand. +CS_OP_MEM = 0x80 # Memory operand. Can be ORed with another operand type. # Common instruction groups - to be consistent across all architectures. CS_GRP_INVALID = 0 # uninitialized/invalid group. From d2a39a2ef15ce4878f1186f711e97bee68845339 Mon Sep 17 00:00:00 2001 From: Peace-Maker Date: Wed, 19 Jul 2023 17:52:54 +0200 Subject: [PATCH 7/9] Update constants from ARM auto-sync patch --- bindings/python/capstone/__init__.py | 42 +++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/bindings/python/capstone/__init__.py b/bindings/python/capstone/__init__.py index ca0435ad01..22b26727b1 100755 --- a/bindings/python/capstone/__init__.py +++ b/bindings/python/capstone/__init__.py @@ -113,6 +113,7 @@ 'CS_OPT_SYNTAX_NOREGNAME', 'CS_OPT_SYNTAX_MASM', 'CS_OPT_SYNTAX_MOTOROLA', + 'CS_OPT_SYNTAX_CS_REG_ALIAS', 'CS_OPT_DETAIL', 'CS_OPT_MODE', @@ -151,6 +152,19 @@ 'CS_OP_REG', 'CS_OP_IMM', 'CS_OP_FP', + 'CS_OP_PRED', + 'CS_OP_RESERVED_5', + 'CS_OP_RESERVED_6', + 'CS_OP_RESERVED_7', + 'CS_OP_RESERVED_8', + 'CS_OP_RESERVED_9', + 'CS_OP_RESERVED_10', + 'CS_OP_RESERVED_11', + 'CS_OP_RESERVED_12', + 'CS_OP_RESERVED_13', + 'CS_OP_RESERVED_14', + 'CS_OP_RESERVED_15', + 'CS_OP_SPECIAL', 'CS_OP_MEM', 'CS_GRP_INVALID', @@ -284,13 +298,26 @@ # Capstone option value CS_OPT_OFF = 0 # Turn OFF an option - default option of CS_OPT_DETAIL -CS_OPT_ON = 3 # Turn ON an option (CS_OPT_DETAIL) +CS_OPT_ON = 1 << 0 # Turn ON an option (CS_OPT_DETAIL) # Common instruction operand types - to be consistent across all architectures. CS_OP_INVALID = 0 # uninitialized/invalid operand. CS_OP_REG = 1 # Register operand. CS_OP_IMM = 2 # Immediate operand. CS_OP_FP = 3 # Floating-Point operand. +CS_OP_PRED = 4 # Predicate operand. +CS_OP_RESERVED_5 = 5 +CS_OP_RESERVED_6 = 6 +CS_OP_RESERVED_7 = 7 +CS_OP_RESERVED_8 = 8 +CS_OP_RESERVED_9 = 9 +CS_OP_RESERVED_10 = 10 +CS_OP_RESERVED_11 = 11 +CS_OP_RESERVED_12 = 12 +CS_OP_RESERVED_13 = 13 +CS_OP_RESERVED_14 = 14 +CS_OP_RESERVED_15 = 15 +CS_OP_SPECIAL = 0x10 # Special operands from archs CS_OP_MEM = 0x80 # Memory operand. Can be ORed with another operand type. # Common instruction groups - to be consistent across all architectures. @@ -309,12 +336,13 @@ CS_AC_WRITE = (1 << 1) # Operand that is written to. # Capstone syntax value -CS_OPT_SYNTAX_DEFAULT = 0 # Default assembly syntax of all platforms (CS_OPT_SYNTAX) -CS_OPT_SYNTAX_INTEL = 1 # Intel X86 asm syntax - default syntax on X86 (CS_OPT_SYNTAX, CS_ARCH_X86) -CS_OPT_SYNTAX_ATT = 2 # ATT asm syntax (CS_OPT_SYNTAX, CS_ARCH_X86) -CS_OPT_SYNTAX_NOREGNAME = 3 # Asm syntax prints register name with only number - (CS_OPT_SYNTAX, CS_ARCH_PPC, CS_ARCH_ARM) -CS_OPT_SYNTAX_MASM = 4 # MASM syntax (CS_OPT_SYNTAX, CS_ARCH_X86) -CS_OPT_SYNTAX_MOTOROLA = 5 # MOS65XX use $ as hex prefix +CS_OPT_SYNTAX_DEFAULT = 1 << 1 # Default assembly syntax of all platforms (CS_OPT_SYNTAX) +CS_OPT_SYNTAX_INTEL = 1 << 2 # Intel X86 asm syntax - default syntax on X86 (CS_OPT_SYNTAX, CS_ARCH_X86) +CS_OPT_SYNTAX_ATT = 1 << 3 # ATT asm syntax (CS_OPT_SYNTAX, CS_ARCH_X86) +CS_OPT_SYNTAX_NOREGNAME = 1 << 4 # Asm syntax prints register name with only number - (CS_OPT_SYNTAX, CS_ARCH_PPC, CS_ARCH_ARM) +CS_OPT_SYNTAX_MASM = 1 << 5 # MASM syntax (CS_OPT_SYNTAX, CS_ARCH_X86) +CS_OPT_SYNTAX_MOTOROLA = 1 << 6 # MOS65XX use $ as hex prefix +CS_OPT_SYNTAX_CS_REG_ALIAS = 1 << 7 # Prints common register alias which are not defined in LLVM (ARM: r9 = sb etc.) # Capstone error type CS_ERR_OK = 0 # No error: everything was fine From a3ad50eaad61817d8dd1f0c26753f23af8b5c3bf Mon Sep 17 00:00:00 2001 From: Bastian Koppelmann Date: Wed, 26 Jul 2023 06:47:05 +0000 Subject: [PATCH 8/9] Fixing TriCore disasm instructions (#2088) --- arch/TriCore/TriCoreDisassembler.c | 121 +++++++++++++++++++++++------ arch/TriCore/TriCoreInstPrinter.c | 16 ++++ suite/MC/TriCore/csfr.s.cs | 3 + suite/MC/TriCore/extr_u.s.cs | 3 + suite/MC/TriCore/ldst_br_circ.s.cs | 47 +++++++++++ suite/MC/TriCore/rr_insn.s.cs | 6 ++ 6 files changed, 174 insertions(+), 22 deletions(-) create mode 100644 suite/MC/TriCore/csfr.s.cs create mode 100644 suite/MC/TriCore/extr_u.s.cs create mode 100644 suite/MC/TriCore/ldst_br_circ.s.cs create mode 100644 suite/MC/TriCore/rr_insn.s.cs diff --git a/arch/TriCore/TriCoreDisassembler.c b/arch/TriCore/TriCoreDisassembler.c index 408f516c59..40aad5e684 100644 --- a/arch/TriCore/TriCoreDisassembler.c +++ b/arch/TriCore/TriCoreDisassembler.c @@ -425,6 +425,7 @@ static DecodeStatus DecodeBOInstruction(MCInst *Inst, unsigned Insn, unsigned off10_0 = fieldFromInstruction_4(Insn, 16, 6); unsigned off10_1 = fieldFromInstruction_4(Insn, 28, 4); unsigned off10 = (off10_0 << 0) | (off10_1 << 6); + bool is_store = false; unsigned s2 = fieldFromInstruction_4(Insn, 12, 4); unsigned s1_d = fieldFromInstruction_4(Insn, 8, 4); @@ -440,32 +441,83 @@ static DecodeStatus DecodeBOInstruction(MCInst *Inst, unsigned Insn, return DecodeRegisterClass(Inst, s2, &desc->OpInfo[0], Decoder); } - if (desc->NumOperands == 2) { - status = DecodeRegisterClass(Inst, s2, &desc->OpInfo[0], - Decoder); - if (status != MCDisassembler_Success) - return status; + switch (MCInst_getOpcode(Inst)) { + case TRICORE_ST_A_bo_r: + case TRICORE_ST_A_bo_c: + case TRICORE_ST_B_bo_r: + case TRICORE_ST_B_bo_c: + case TRICORE_ST_D_bo_r: + case TRICORE_ST_D_bo_c: + case TRICORE_ST_DA_bo_r: + case TRICORE_ST_DA_bo_c: + case TRICORE_ST_H_bo_r: + case TRICORE_ST_H_bo_c: + case TRICORE_ST_Q_bo_r: + case TRICORE_ST_Q_bo_c: + case TRICORE_ST_W_bo_r: + case TRICORE_ST_W_bo_c: + case TRICORE_SWAP_W_bo_r: + case TRICORE_SWAP_W_bo_c: + case TRICORE_SWAPMSK_W_bo_c: + case TRICORE_SWAPMSK_W_bo_r: { + is_store = true; + break; + } + } + if (desc->NumOperands == 2) { if (desc->OpInfo[1].OperandType == MCOI_OPERAND_REGISTER) { - return DecodeRegisterClass(Inst, s1_d, &desc->OpInfo[1], - Decoder); + // we have [reg+r] instruction + if (is_store) { + status = DecodeRegisterClass(Inst, s2, &desc->OpInfo[0], + Decoder); + if (status != MCDisassembler_Success) + return status; + return DecodeRegisterClass(Inst, s1_d, &desc->OpInfo[1], + Decoder); + } else { + status = DecodeRegisterClass(Inst, s1_d, &desc->OpInfo[0], + Decoder); + if (status != MCDisassembler_Success) + return status; + return DecodeRegisterClass(Inst, s2, &desc->OpInfo[1], + Decoder); + } } else { + // we have one of the CACHE instructions without destination reg + status = DecodeRegisterClass(Inst, s2, &desc->OpInfo[0], + Decoder); + if (status != MCDisassembler_Success) + return status; + MCOperand_CreateImm0(Inst, off10); } return MCDisassembler_Success; } if (desc->NumOperands > 2) { - status = DecodeRegisterClass(Inst, s1_d, &desc->OpInfo[0], - Decoder); - if (status != MCDisassembler_Success) - return status; + if (is_store) { + // we have [reg+c] instruction + status = DecodeRegisterClass(Inst, s2, &desc->OpInfo[0], + Decoder); + if (status != MCDisassembler_Success) + return status; - status = DecodeRegisterClass(Inst, s2, &desc->OpInfo[1], - Decoder); - if (status != MCDisassembler_Success) - return status; + status = DecodeRegisterClass(Inst, s1_d, &desc->OpInfo[1], + Decoder); + if (status != MCDisassembler_Success) + return status; + } else { + status = DecodeRegisterClass(Inst, s1_d, &desc->OpInfo[0], + Decoder); + if (status != MCDisassembler_Success) + return status; + status = DecodeRegisterClass(Inst, s2, &desc->OpInfo[1], + Decoder); + if (status != MCDisassembler_Success) + return status; + } MCOperand_CreateImm0(Inst, off10); } @@ -649,8 +701,13 @@ static DecodeStatus DecodeRLCInstruction(MCInst *Inst, unsigned Insn, MCOperand_CreateImm0(Inst, const16); } else { MCOperand_CreateImm0(Inst, const16); - status = - DecodeRegisterClass(Inst, d, &desc->OpInfo[1], Decoder); + if (MCInst_getOpcode(Inst) == TRICORE_MTCR_rlc) { + status = + DecodeRegisterClass(Inst, s1, &desc->OpInfo[1], Decoder); + } else { + status = + DecodeRegisterClass(Inst, d, &desc->OpInfo[1], Decoder); + } if (status != MCDisassembler_Success) return status; } @@ -699,10 +756,24 @@ static DecodeStatus DecodeRRInstruction(MCInst *Inst, unsigned Insn, } if (desc->NumOperands > 1) { - status = DecodeRegisterClass(Inst, s1, &desc->OpInfo[1], - Decoder); - if (status != MCDisassembler_Success) - return status; + if (desc->OpInfo[0].OperandType == MCOI_OPERAND_REGISTER) { + switch (MCInst_getOpcode(Inst)) { + case TRICORE_ABSS_rr: + case TRICORE_ABSS_H_rr: + case TRICORE_ABS_H_rr: + case TRICORE_ABS_B_rr: + case TRICORE_ABS_rr: { + status = DecodeRegisterClass(Inst, s2, &desc->OpInfo[1], + Decoder); + break; + default: + status = DecodeRegisterClass(Inst, s1, &desc->OpInfo[1], + Decoder); + } + if (status != MCDisassembler_Success) + return status; + } + } } if (desc->NumOperands > 2) { @@ -1259,7 +1330,13 @@ static DecodeStatus DecodeRRRRInstruction(MCInst *Inst, unsigned Insn, return status; if (desc->NumOperands == 3) { - return DecodeRegisterClass(Inst, s2, &desc->OpInfo[2], Decoder); + switch (MCInst_getOpcode(Inst)) { + case TRICORE_EXTR_rrrr: + case TRICORE_EXTR_U_rrrr: + return DecodeRegisterClass(Inst, s3, &desc->OpInfo[2], Decoder); + default: + return DecodeRegisterClass(Inst, s2, &desc->OpInfo[2], Decoder); + } } // Decode s2. diff --git a/arch/TriCore/TriCoreInstPrinter.c b/arch/TriCore/TriCoreInstPrinter.c index eadf2eef2c..aaee3b536b 100644 --- a/arch/TriCore/TriCoreInstPrinter.c +++ b/arch/TriCore/TriCoreInstPrinter.c @@ -224,6 +224,19 @@ static void off4_fixup(MCInst *MI, uint64_t *off4) } } +static void const8_fixup(MCInst *MI, uint64_t *const8) +{ + switch (MCInst_getOpcode(MI)) { + case TRICORE_LD_A_sc: + case TRICORE_ST_A_sc: + case TRICORE_ST_W_sc: + case TRICORE_LD_W_sc: { + *const8 *= 4; + break; + } + } +} + static void print_zero_ext(MCInst *MI, int OpNum, SStream *O, unsigned n) { MCOperand *MO = MCInst_getOperand(MI, OpNum); @@ -235,6 +248,9 @@ static void print_zero_ext(MCInst *MI, int OpNum, SStream *O, unsigned n) if (n == 4) { off4_fixup(MI, &imm); } + if (n == 8) { + const8_fixup(MI, &imm); + } printInt64Bang(O, imm); fill_imm(MI, imm); diff --git a/suite/MC/TriCore/csfr.s.cs b/suite/MC/TriCore/csfr.s.cs new file mode 100644 index 0000000000..fc0db30274 --- /dev/null +++ b/suite/MC/TriCore/csfr.s.cs @@ -0,0 +1,3 @@ +# CS_ARCH_TRICORE, CS_MODE_TRICORE_131, None +0xcd, 0x41, 0xe0, 0x0f = mtcr #-0x1fc, d1 +0x4d, 0x40, 0xe0, 0x2f = mfcr d2, #0xfe04 diff --git a/suite/MC/TriCore/extr_u.s.cs b/suite/MC/TriCore/extr_u.s.cs new file mode 100644 index 0000000000..907a5e4ed1 --- /dev/null +++ b/suite/MC/TriCore/extr_u.s.cs @@ -0,0 +1,3 @@ +# CS_ARCH_TRICORE, CS_MODE_TRICORE_131, None +0x17, 0x01, 0x40, 0x02 = extr d0, d1, e2 +0x17, 0x01, 0x60, 0x02 = extr.u d0, d1, e2 diff --git a/suite/MC/TriCore/ldst_br_circ.s.cs b/suite/MC/TriCore/ldst_br_circ.s.cs new file mode 100644 index 0000000000..0bc85fb8fa --- /dev/null +++ b/suite/MC/TriCore/ldst_br_circ.s.cs @@ -0,0 +1,47 @@ +# CS_ARCH_TRICORE, CS_MODE_TRICORE_162, None +0xa9, 0x00, 0x80, 0x03 = cachea.i [p0+r] +0xa9, 0x00, 0x8a, 0x07 = cachea.i [p0+c]#0xa +0xa9, 0x00, 0x00, 0x03 = cachea.w [p0+r] +0xa9, 0x00, 0x0a, 0x07 = cachea.w [p0+c]#0xa +0xa9, 0x00, 0x40, 0x03 = cachea.wi [p0+r] +0xa9, 0x00, 0x4a, 0x07 = cachea.wi [p0+c]#0xa +0x69, 0x02, 0xc0, 0x00 = cmpswap.w [p0+r], e2 +0x69, 0x02, 0xca, 0x04 = cmpswap.w [p0+c]#0xa, e2 +0x29, 0x02, 0x80, 0x01 = ld.a a2, [p0+r] +0x29, 0x02, 0x8a, 0x05 = ld.a a2, [p0+c]#0xa +0x29, 0x02, 0x00, 0x00 = ld.b d2, [p0+r] +0x29, 0x02, 0x0a, 0x04 = ld.b d2, [p0+c]#0xa +0x29, 0x02, 0x40, 0x00 = ld.bu d2, [p0+r] +0x29, 0x02, 0x4a, 0x04 = ld.bu d2, [p0+c]#0xa +0x29, 0x02, 0x40, 0x01 = ld.d e2, [p0+r] +0x29, 0x02, 0x4a, 0x05 = ld.d e2, [p0+c]#0xa +0x29, 0x02, 0xc0, 0x01 = ld.da p2, [p0+r] +0x29, 0x02, 0xca, 0x05 = ld.da p2, [p0+c]#0xa +0x29, 0x02, 0x80, 0x00 = ld.h d2, [p0+r] +0x29, 0x02, 0x8a, 0x04 = ld.h d2, [p0+c]#0xa +0x29, 0x02, 0xc0, 0x00 = ld.hu d2, [p0+r] +0x29, 0x02, 0xca, 0x04 = ld.hu d2, [p0+c]#0xa +0x29, 0x02, 0x00, 0x02 = ld.q d2, [p0+r] +0x29, 0x02, 0x0a, 0x06 = ld.q d2, [p0+c]#0xa +0x29, 0x02, 0x00, 0x01 = ld.w d2, [p0+r] +0x29, 0x02, 0x0a, 0x05 = ld.w d2, [p0+c]#0xa +0x69, 0x02, 0x40, 0x00 = ldmst [p0+r], e2 +0x69, 0x02, 0x4a, 0x04 = ldmst [p0+c]#0xa, e2 +0xa9, 0x02, 0x80, 0x01 = st.a [p0+r], a2 +0xa9, 0x02, 0x8a, 0x05 = st.a [p0+c]#0xa, a2 +0xa9, 0x02, 0x00, 0x00 = st.b [p0+r], d2 +0xa9, 0x02, 0x0a, 0x04 = st.b [p0+c]#0xa, d2 +0xa9, 0x02, 0x40, 0x01 = st.d [p0+r], e2 +0xa9, 0x02, 0x4a, 0x05 = st.d [p0+c]#0xa, e2 +0xa9, 0x02, 0xc0, 0x01 = st.da [p0+r], p2 +0xa9, 0x02, 0xca, 0x05 = st.da [p0+c]#0xa, p2 +0xa9, 0x02, 0x80, 0x00 = st.h [p0+r], d2 +0xa9, 0x02, 0x8a, 0x04 = st.h [p0+c]#0xa, d2 +0xa9, 0x02, 0x00, 0x02 = st.q [p0+r], d2 +0xa9, 0x02, 0x0a, 0x06 = st.q [p0+c]#0xa, d2 +0xa9, 0x02, 0x00, 0x01 = st.w [p0+r], d2 +0xa9, 0x02, 0x0a, 0x05 = st.w [p0+c]#0xa, d2 +0x69, 0x02, 0x00, 0x00 = swap.w [p0+r], d2 +0x69, 0x02, 0x0a, 0x04 = swap.w [p0+c]#0xa, d2 +0x69, 0x02, 0x80, 0x00 = swapmsk.w [p0+r], e2 +0x69, 0x02, 0x8a, 0x04 = swapmsk.w [p0+c]#0xa, e2 diff --git a/suite/MC/TriCore/rr_insn.s.cs b/suite/MC/TriCore/rr_insn.s.cs new file mode 100644 index 0000000000..734b42ba07 --- /dev/null +++ b/suite/MC/TriCore/rr_insn.s.cs @@ -0,0 +1,6 @@ +# CS_ARCH_TRICORE, CS_MODE_TRICORE_131, None +0x0b, 0x20, 0xc0, 0x01 = abs d0, d2 +0x0b, 0x60, 0xc0, 0x05 = abs.b d0, d6 +0x0b, 0x40, 0xc0, 0x27 = abs.h d2, d4 +0x0b, 0x10, 0xd0, 0x01 = abss d0, d1 +0x0b, 0x10, 0xd0, 0x07 = abss.h d0, d1 From c703d968d1dbf5e557901cee4eadd7731c1a4747 Mon Sep 17 00:00:00 2001 From: chayleaf Date: Wed, 9 Aug 2023 22:05:06 +0700 Subject: [PATCH 9/9] allow absolute CMAKE_INSTALL_*DIR (#2134) This patch fixes Capstone 5 build on NixOS. NixOS's build infrastructure sets CMAKE_INSTALL_{LIB,INCLUDE}DIR to absolute paths. If you append it to ${prefix}, you get the wrong path. NixOS automatically detects it and links this issue: https://github.com/NixOS/nixpkgs/issues/144170 --- capstone-config.cmake.in | 4 ++-- capstone.pc.in | 4 ++-- cmake_uninstall.cmake.in | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/capstone-config.cmake.in b/capstone-config.cmake.in index 93ac2814e5..445ecda0eb 100644 --- a/capstone-config.cmake.in +++ b/capstone-config.cmake.in @@ -1,6 +1,6 @@ @PACKAGE_INIT@ -set_and_check(capstone_INCLUDE_DIR "${PACKAGE_PREFIX_DIR}/@CMAKE_INSTALL_INCLUDEDIR@") -set_and_check(capstone_LIB_DIR "${PACKAGE_PREFIX_DIR}/@CMAKE_INSTALL_LIBDIR@") +set_and_check(capstone_INCLUDE_DIR "@CMAKE_INSTALL_FULL_INCLUDEDIR@") +set_and_check(capstone_LIB_DIR "@CMAKE_INSTALL_FULL_LIBDIR@") include("${CMAKE_CURRENT_LIST_DIR}/capstone-targets.cmake") diff --git a/capstone.pc.in b/capstone.pc.in index ce253feea0..8def0ef421 100644 --- a/capstone.pc.in +++ b/capstone.pc.in @@ -1,7 +1,7 @@ prefix=@CMAKE_INSTALL_PREFIX@ exec_prefix=${prefix} -libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@ -includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@ +libdir=@CMAKE_INSTALL_FULL_LIBDIR@ +includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@ Name: capstone Description: Capstone disassembly engine diff --git a/cmake_uninstall.cmake.in b/cmake_uninstall.cmake.in index 1722d13eaf..a1cecefdee 100644 --- a/cmake_uninstall.cmake.in +++ b/cmake_uninstall.cmake.in @@ -13,8 +13,8 @@ foreach(file ${files}) endif() endforeach() -message(STATUS "Uninstalling @CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_INCLUDEDIR@/capstone") -file(REMOVE_RECURSE @CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_INCLUDEDIR@/capstone) +message(STATUS "Uninstalling @CMAKE_INSTALL_FULL_INCLUDEDIR@/capstone") +file(REMOVE_RECURSE @CMAKE_INSTALL_FULL_INCLUDEDIR@/capstone) -message(STATUS "Uninstalling @CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_LIBDIR@/cmake/capstone") -file(REMOVE_RECURSE @CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_LIBDIR@/cmake/capstone) +message(STATUS "Uninstalling @CMAKE_INSTALL_FULL_LIBDIR@/cmake/capstone") +file(REMOVE_RECURSE @CMAKE_INSTALL_FULL_LIBDIR@/cmake/capstone)