SH: Add superh support for common part.

Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
This commit is contained in:
Yoshinori Sato 2022-09-12 21:26:04 +09:00
parent 51e8079a8c
commit 5b6846c2c8
4 changed files with 106 additions and 3 deletions

View File

@ -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)

28
cs.c
View File

@ -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;

View File

@ -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 ");
}

View File

@ -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;