From f3c11e85cd5b47e616d1084fa11151a65786a19b Mon Sep 17 00:00:00 2001 From: billow Date: Fri, 24 Mar 2023 21:41:06 +0800 Subject: [PATCH] add `tricore` to `cstest` --- CMakeLists.txt | 18 ++++++++ suite/cstest/include/factory.h | 1 + suite/cstest/src/capstone_test.c | 3 ++ suite/cstest/src/main.c | 3 ++ suite/cstest/src/tricore_detail.c | 74 +++++++++++++++++++++++++++++++ 5 files changed, 99 insertions(+) create mode 100644 suite/cstest/src/tricore_detail.c diff --git a/CMakeLists.txt b/CMakeLists.txt index b1e563ae..9020a280 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,6 +39,7 @@ option(CAPSTONE_BUILD_STATIC_RUNTIME "Embed static runtime" ${BUILD_SHARED_LIBS} option(CAPSTONE_BUILD_DIET "Build diet library" OFF) option(CAPSTONE_BUILD_TESTS "Build tests" ${PROJECT_IS_TOP_LEVEL}) option(CAPSTONE_BUILD_CSTOOL "Build cstool" ${PROJECT_IS_TOP_LEVEL}) +option(CAPSTONE_BUILD_CSTEST "Build cstest" ${PROJECT_IS_TOP_LEVEL}) option(CAPSTONE_USE_DEFAULT_ALLOC "Use default memory allocation functions" ON) option(CAPSTONE_ARCHITECTURE_DEFAULT "Whether architectures are enabled by default" ON) option(CAPSTONE_DEBUG "Whether to enable extra debug assertions" OFF) @@ -752,3 +753,20 @@ if(CAPSTONE_BUILD_CSTOOL) install(TARGETS cstool EXPORT capstone-targets DESTINATION ${CMAKE_INSTALL_BINDIR}) endif() endif() + +if(CAPSTONE_BUILD_CSTEST) + find_package(CMOCKA) + + file(GLOB CSTEST_SRC suite/cstest/src/*.c) + add_executable(cstest ${CSTEST_SRC}) + target_link_libraries(cstest PUBLIC capstone ${CMOCKA_LIBRARIES}) + target_include_directories(cstest PRIVATE + $ + ${PROJECT_SOURCE_DIR}/suite/cstest/include + ${CMOCKA_INCLUDE_DIR} + ) + + if(CAPSTONE_INSTALL) + install(TARGETS cstest EXPORT capstone-targets DESTINATION ${CMAKE_INSTALL_BINDIR}) + endif() +endif() diff --git a/suite/cstest/include/factory.h b/suite/cstest/include/factory.h index 7df6c783..e2a1c4c6 100644 --- a/suite/cstest/include/factory.h +++ b/suite/cstest/include/factory.h @@ -23,5 +23,6 @@ char *get_detail_m68k(csh *handle, cs_mode mode, cs_insn *ins); char *get_detail_mos65xx(csh *handle, cs_mode mode, cs_insn *ins); char *get_detail_tms320c64x(csh *handle, cs_mode mode, cs_insn *ins); char *get_detail_bpf(csh *handle, cs_mode mode, cs_insn *ins); +char *get_detail_tricore(csh *handle, cs_mode mode, cs_insn *ins); #endif /* FACTORY_H */ diff --git a/suite/cstest/src/capstone_test.c b/suite/cstest/src/capstone_test.c index a534e49b..779ab251 100644 --- a/suite/cstest/src/capstone_test.c +++ b/suite/cstest/src/capstone_test.c @@ -181,6 +181,9 @@ int set_function(int arch) case CS_ARCH_RISCV: function = get_detail_riscv; break; + case CS_ARCH_TRICORE: + function = get_detail_tricore; + break; default: return -1; } diff --git a/suite/cstest/src/main.c b/suite/cstest/src/main.c index 88e1b328..0217c77f 100644 --- a/suite/cstest/src/main.c +++ b/suite/cstest/src/main.c @@ -20,6 +20,7 @@ static single_dict arches[] = { {"CS_ARCH_M68K", CS_ARCH_M68K}, {"CS_ARCH_BPF", CS_ARCH_BPF}, {"CS_ARCH_RISCV", CS_ARCH_RISCV}, + {"CS_ARCH_TRICORE", CS_ARCH_TRICORE}, }; static single_dict modes[] = { @@ -61,6 +62,7 @@ static single_dict arches[] = { {"CS_MODE_BPF_EXTENDED", CS_MODE_BPF_EXTENDED}, {"CS_MODE_RISCV32", CS_MODE_RISCV32}, {"CS_MODE_RISCV64", CS_MODE_RISCV64}, + {"CS_MODE_TRICORE", CS_MODE_TRICORE}, }; static double_dict options[] = { @@ -107,6 +109,7 @@ static single_dict arches[] = { {"CS_MODE_M680X_HCS08", CS_OPT_MODE, CS_MODE_M680X_HCS08}, {"CS_MODE_RISCV32", CS_OPT_MODE, CS_MODE_RISCV32}, {"CS_MODE_RISCV64", CS_OPT_MODE, CS_MODE_RISCV64}, + {"CS_MODE_TRICORE", CS_OPT_MODE, CS_MODE_TRICORE}, {"CS_OPT_UNSIGNED", CS_OPT_UNSIGNED, CS_OPT_ON}, }; diff --git a/suite/cstest/src/tricore_detail.c b/suite/cstest/src/tricore_detail.c new file mode 100644 index 00000000..4605c16e --- /dev/null +++ b/suite/cstest/src/tricore_detail.c @@ -0,0 +1,74 @@ +// +// Created by aya on 3/24/23. +// + +#include "factory.h" + +char *get_detail_tricore(csh *p_handle, cs_mode mode, cs_insn *ins) +{ + cs_tricore *tricore; + int i; + cs_regs regs_read, regs_write; + uint8_t regs_read_count, regs_write_count; + + char *result; + result = (char *)malloc(sizeof(char)); + result[0] = '\0'; + + if (ins->detail == NULL) + return result; + + csh handle = *p_handle; + + tricore = &(ins->detail->tricore); + + if (tricore->op_count) + add_str(&result, "\top_count: %u\n", tricore->op_count); + + for (i = 0; i < tricore->op_count; i++) { + cs_tricore_op *op = &(tricore->operands[i]); + switch ((int)op->type) { + default: + break; + case TRICORE_OP_REG: + add_str(&result, "\t\toperands[%u].type: REG = %s\n", i, + cs_reg_name(handle, op->reg)); + break; + case TRICORE_OP_IMM: + add_str(&result, "\t\toperands[%u].type: IMM = 0x%x\n", i, op->imm); + break; + case TRICORE_OP_MEM: + add_str(&result, "\t\toperands[%u].type: MEM\n", i); + if (op->mem.base != TriCore_REG_INVALID) + add_str(&result, "\t\t\toperands[%u].mem.base: REG = %s\n", i, + cs_reg_name(handle, op->mem.base)); + if (op->mem.disp != 0) + add_str(&result, "\t\t\toperands[%u].mem.disp: 0x%x\n", i, + op->mem.disp); + break; + } + + // Print out all registers accessed by this instruction (either implicit or + // explicit) + if (!cs_regs_access(handle, ins, regs_read, ®s_read_count, regs_write, + ®s_write_count)) { + if (regs_read_count) { + add_str(&result, "\tRegisters read:"); + for (i = 0; i < regs_read_count; i++) { + add_str(&result, " %s", cs_reg_name(handle, regs_read[i])); + } + add_str(&result, "\n"); + } + + if (regs_write_count) { + add_str(&result, "\tRegisters modified:"); + for (i = 0; i < regs_write_count; i++) { + add_str(&result, " %s", cs_reg_name(handle, regs_write[i])); + } + add_str(&result, "\n"); + } + } + } + + return result; +}