diff --git a/CMakeLists.txt b/CMakeLists.txt index e5cf27b8..36a37c73 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,8 +37,8 @@ option(CAPSTONE_ARCHITECTURE_DEFAULT "Whether architectures are enabled by defau option(CAPSTONE_DEBUG "Whether to enable extra debug assertions" OFF) option(CAPSTONE_INSTALL "Generate install target" ${PROJECT_IS_TOP_LEVEL}) -set(SUPPORTED_ARCHITECTURES ARM ARM64 M68K MIPS PPC SPARC SYSZ XCORE X86 TMS320C64X M680X EVM MOS65XX WASM BPF RISCV) -set(SUPPORTED_ARCHITECTURE_LABELS ARM ARM64 M68K MIPS PowerPC Sparc SystemZ XCore x86 TMS320C64x M680x EVM MOS65XX WASM BPF RISCV) +set(SUPPORTED_ARCHITECTURES ARM ARM64 M68K MIPS PPC SPARC SYSZ XCORE X86 TMS320C64X M680X EVM MOS65XX WASM BPF RISCV SH) +set(SUPPORTED_ARCHITECTURE_LABELS ARM ARM64 M68K MIPS PowerPC Sparc SystemZ XCore x86 TMS320C64x M680x EVM MOS65XX WASM BPF RISCV SH) list(LENGTH SUPPORTED_ARCHITECTURES count) math(EXPR count "${count}-1") @@ -509,6 +509,21 @@ if(CAPSTONE_RISCV_SUPPORT) set(TEST_SOURCES ${TEST_SOURCES} test_riscv.c) endif() +if(CAPSTONE_SH_SUPPORT) + add_definitions(-DCAPSTONE_HAS_SH) + set(SOURCES_SH + arch/SH/SHDisassembler.c + arch/SH/SHInstPrinter.c + arch/SH/SHModule.c + ) + set(HEADERS_SH + arch/SH/SHDisassembler.h + arch/SH/SHInstPrinter.h + arch/SH/SHModule.h + arch/SH/SHInsnTable.inc + ) +endif() + if(CAPSTONE_OSXKERNEL_SUPPORT) add_definitions(-DCAPSTONE_HAS_OSXKERNEL) endif() @@ -531,6 +546,7 @@ set(ALL_SOURCES ${SOURCES_MOS65XX} ${SOURCES_BPF} ${SOURCES_RISCV} + ${SOURCES_SH} ) set(ALL_HEADERS @@ -552,6 +568,7 @@ set(ALL_HEADERS ${HEADERS_MOS65XX} ${HEADERS_BPF} ${HEADERS_RISCV} + ${HEADERS_SH} ) ## properties @@ -612,6 +629,7 @@ source_group("Source\\WASM" FILES ${SOURCES_WASM}) source_group("Source\\MOS65XX" FILES ${SOURCES_MOS65XX}) source_group("Source\\BPF" FILES ${SOURCES_BPF}) source_group("Source\\RISCV" FILES ${SOURCES_RISCV}) +source_group("Source\\SH" FILES ${SOURCES_SH}) source_group("Include\\Common" FILES ${HEADERS_COMMON}) source_group("Include\\Engine" FILES ${HEADERS_ENGINE}) @@ -631,6 +649,7 @@ source_group("Include\\WASM" FILES ${HEADERS_WASM}) source_group("Include\\MOS65XX" FILES ${HEADERS_MOS65XX}) source_group("Include\\BPF" FILES ${HEADERS_BPF}) source_group("Include\\RISCV" FILES ${HEADERS_RISCV}) +source_group("Include\\SH" FILES ${HEADERS_SH}) ## installation if(CAPSTONE_INSTALL) diff --git a/cs.c b/cs.c index b30de609..73c70fd5 100644 --- a/cs.c +++ b/cs.c @@ -68,6 +68,7 @@ #include "arch/RISCV/RISCVModule.h" #include "arch/MOS65XX/MOS65XXModule.h" #include "arch/BPF/BPFModule.h" +#include "arch/SH/SHModule.h" static const struct { // constructor initialization @@ -231,6 +232,17 @@ static const struct { #else { NULL, NULL, 0 }, #endif +#ifdef CAPSTONE_HAS_SH + { + SH_global_init, + SH_option, + ~(CS_MODE_SH2 | CS_MODE_SH2A | CS_MODE_SH3 | + CS_MODE_SH4 | CS_MODE_SH4A | + CS_MODE_SHFPU | CS_MODE_SHDSP|CS_MODE_BIG_ENDIAN), + }, +#else + { NULL, NULL, 0 }, +#endif }; // bitmask of enabled architectures @@ -283,6 +295,9 @@ static const uint32_t all_arch = 0 #ifdef CAPSTONE_HAS_RISCV | (1 << CS_ARCH_RISCV) #endif +#ifdef CAPSTONE_HAS_SH + | (1 << CS_ARCH_SH) +#endif ; #if defined(CAPSTONE_USE_SYS_DYN_MEM) @@ -354,7 +369,8 @@ bool CAPSTONE_API cs_support(int query) (1 << CS_ARCH_M68K) | (1 << CS_ARCH_TMS320C64X) | (1 << CS_ARCH_M680X) | (1 << CS_ARCH_EVM) | (1 << CS_ARCH_RISCV) | (1 << CS_ARCH_MOS65XX) | - (1 << CS_ARCH_WASM) | (1 << CS_ARCH_BPF)); + (1 << CS_ARCH_WASM) | (1 << CS_ARCH_BPF)) | + (1 << CS_ARCH_SH); if ((unsigned int)query < CS_ARCH_MAX) return all_arch & (1 << query); @@ -656,6 +672,8 @@ static uint8_t skipdata_size(cs_struct *handle) if (handle->mode & CS_MODE_RISCVC) return 2; return 4; + case CS_ARCH_SH: + return 2; } } @@ -1554,6 +1572,14 @@ int CAPSTONE_API cs_op_index(csh ud, const cs_insn *insn, unsigned int op_type, return i; } break; + case CS_ARCH_SH: + for (i = 0; i < insn->detail->sh.op_count; i++) { + if (insn->detail->sh.operands[i].type == (sh_op_type)op_type) + count++; + if (count == post) + return i; + } + break; } return -1; diff --git a/cstool/cstool.c b/cstool/cstool.c index 2e6a5e01..1465dcff 100644 --- a/cstool/cstool.c +++ b/cstool/cstool.c @@ -87,6 +87,25 @@ static struct { { "65c02", CS_ARCH_MOS65XX, CS_MODE_MOS65XX_65C02 }, { "w65c02", CS_ARCH_MOS65XX, CS_MODE_MOS65XX_W65C02 }, { "65816", CS_ARCH_MOS65XX, CS_MODE_MOS65XX_65816_LONG_MX }, + { "sh", CS_ARCH_SH, CS_MODE_BIG_ENDIAN }, + { "sh2", CS_ARCH_SH, CS_MODE_SH2 | CS_MODE_BIG_ENDIAN}, + { "sh2e", CS_ARCH_SH, CS_MODE_SH2 | CS_MODE_SHFPU | CS_MODE_BIG_ENDIAN}, + { "sh-dsp", CS_ARCH_SH, CS_MODE_SH2 | CS_MODE_SHDSP | CS_MODE_BIG_ENDIAN}, + { "sh2a", CS_ARCH_SH, CS_MODE_SH2A | CS_MODE_BIG_ENDIAN}, + { "sh2a-fpu", CS_ARCH_SH, CS_MODE_SH2A | CS_MODE_SHFPU | CS_MODE_BIG_ENDIAN}, + { "sh3", CS_ARCH_SH, CS_MODE_LITTLE_ENDIAN | CS_MODE_SH3 }, + { "sh3be", CS_ARCH_SH, CS_MODE_BIG_ENDIAN | CS_MODE_SH3 }, + { "sh3e", CS_ARCH_SH, CS_MODE_LITTLE_ENDIAN | CS_MODE_SH3 | CS_MODE_SHFPU}, + { "sh3ebe", CS_ARCH_SH, CS_MODE_BIG_ENDIAN | CS_MODE_SH3 | CS_MODE_SHFPU}, + { "sh3-dsp", CS_ARCH_SH, CS_MODE_LITTLE_ENDIAN | CS_MODE_SH3 | CS_MODE_SHDSP }, + { "sh3-dspbe", CS_ARCH_SH, CS_MODE_BIG_ENDIAN | CS_MODE_SH3 | CS_MODE_SHDSP }, + { "sh4", CS_ARCH_SH, CS_MODE_LITTLE_ENDIAN | CS_MODE_SH4 | CS_MODE_SHFPU }, + { "sh4be", CS_ARCH_SH, CS_MODE_BIG_ENDIAN | CS_MODE_SH4 | CS_MODE_SHFPU }, + { "sh4a", CS_ARCH_SH, CS_MODE_LITTLE_ENDIAN | CS_MODE_SH4A | CS_MODE_SHFPU }, + { "sh4abe", CS_ARCH_SH, CS_MODE_BIG_ENDIAN | CS_MODE_SH4A | CS_MODE_SHFPU }, + { "sh4al-dsp", CS_ARCH_SH, CS_MODE_LITTLE_ENDIAN | CS_MODE_SH4A | CS_MODE_SHDSP | CS_MODE_SHFPU }, + { "sh4al-dspbe", CS_ARCH_SH, CS_MODE_BIG_ENDIAN | CS_MODE_SH4A | CS_MODE_SHDSP | CS_MODE_SHFPU}, + { NULL } }; @@ -106,6 +125,7 @@ void print_insn_detail_riscv(csh handle, cs_insn *ins); void print_insn_detail_wasm(csh handle, cs_insn *ins); void print_insn_detail_mos65xx(csh handle, cs_insn *ins); void print_insn_detail_bpf(csh handle, cs_insn *ins); +void print_insn_detail_sh(csh handle, cs_insn *ins); static void print_details(csh handle, cs_arch arch, cs_mode md, cs_insn *ins); @@ -278,6 +298,27 @@ static void usage(char *prog) printf(" riscv64 riscv64\n"); } + if (cs_support(CS_ARCH_SH)) { + printf(" sh superh SH1\n"); + printf(" sh2 superh SH2\n"); + printf(" sh2e superh SH2E\n"); + printf(" sh2dsp superh SH2-DSP\n"); + printf(" sh2a superh SH2A\n"); + printf(" sh2afpu superh SH2A-FPU\n"); + printf(" sh3 superh SH3\n"); + printf(" sh3be superh SH3 big endian\n"); + printf(" sh3e superh SH3E\n"); + printf(" sh3ebe superh SH3E big endian\n"); + printf(" sh3-dsp superh SH3-DSP\n"); + printf(" sh3-dspbe superh SH3-DSP big endian\n"); + printf(" sh4 superh SH4\n"); + printf(" sh4be superh SH4 big endian\n"); + printf(" sh4a superh SH4A\n"); + printf(" sh4abe superh SH4A big endian\n"); + printf(" sh4al-dsp superh SH4AL-DSP\n"); + printf(" sh4al-dspbe superh SH4AL-DSP big endian\n"); + } + printf("\nExtra options:\n"); printf(" -d show detailed information of the instructions\n"); printf(" -s decode in SKIPDATA mode\n"); @@ -338,6 +379,9 @@ static void print_details(csh handle, cs_arch arch, cs_mode md, cs_insn *ins) case CS_ARCH_RISCV: print_insn_detail_riscv(handle, ins); break; + case CS_ARCH_SH: + print_insn_detail_sh(handle, ins); + break; default: break; } @@ -450,6 +494,10 @@ int main(int argc, char **argv) printf("riscv=1 "); } + if (cs_support(CS_ARCH_SH)) { + printf("sh=1 "); + } + if (cs_support(CS_SUPPORT_DIET)) { printf("diet=1 "); } diff --git a/include/capstone/capstone.h b/include/capstone/capstone.h index c45ca187..0140c001 100644 --- a/include/capstone/capstone.h +++ b/include/capstone/capstone.h @@ -88,6 +88,7 @@ typedef enum cs_arch { CS_ARCH_WASM, ///< WebAssembly architecture CS_ARCH_BPF, ///< Berkeley Packet Filter architecture (including eBPF) CS_ARCH_RISCV, ///< RISCV architecture + CS_ARCH_SH, ///< SH architecture CS_ARCH_MAX, CS_ARCH_ALL = 0xFFFF, // All architectures - for cs_support() } cs_arch; @@ -153,6 +154,13 @@ typedef enum cs_mode { 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; typedef void* (CAPSTONE_API *cs_malloc_t)(size_t size); @@ -304,6 +312,7 @@ typedef struct cs_opt_skipdata { #include "wasm.h" #include "mos65xx.h" #include "bpf.h" +#include "sh.h" /// NOTE: All information in cs_detail is only available when CS_OPT_DETAIL = CS_OPT_ON /// Initialized as memset(., 0, offsetof(cs_detail, ARCH)+sizeof(cs_ARCH)) @@ -338,6 +347,7 @@ typedef struct cs_detail { cs_wasm wasm; ///< Web Assembly architecture cs_bpf bpf; ///< Berkeley Packet Filter architecture (including eBPF) cs_riscv riscv; ///< RISCV architecture + cs_sh sh; ///< SH architecture }; } cs_detail;