Squashed 'external/ircolib/' changes from ce3cd726c..de6e324bd

de6e324bd separate emu thread
10d3daf86 Roms List improvements
95d202f37 Let's make the rom list process on a separate thread so the emulator doesnt take ages to load.
fc306967f Wow the ROM Header was just completely busted. Game list view works now
bad1691ee fuck this shit
2b59e5f46 game list in progress
d26417b83 remappable inputs in progress
ac4af8106 input
e72abc240 update readme
430139dc9 Qt6 frontend
3080d4d45 Fix this small bug too
08cd13b85 Cop0 unused functions do not actually pose a threat (as per manual). They don't do anything, so shall we.
61bb4fb44 make idle loop detection a little more specific with where the load goes
b037de4c3 SAZDFsdff
12e81e73e need to figure out why n64-systemtest loops indefinitely at some address that appears to be valid (i think it's me not invalidating the cache properly)
204f0e13b idle skipping seems to work!
cb8bb634a sdkfjlasdf
58e5c89c1 Fix compilation issue on my machine (no idea)
24fb2898e attempting more serious idle skipping
214719577 Place rsp.Step inside cached interpreter. Gains about 3 more fps
bb97dcc23 mmmmm
920b77d38 wjkhasdfjhkasdf
430ccdab4 it's a start...
4f42a673a Cached interpreter plays Mario 64. Start looking into RSP as well
c9a030787 idle skipping works!
5fbda03ce new idea
366637aba Idle skipping... maybe?
609fa2fb0 Cache instructions implemented but broken lmao. Commented out for now
e140a6d12 - Stop using inheritance for CPU, instead use composition. - Introduce KAIZEN_JIT_ENABLED optional define instead of relying on __aarch64__ and the like. - More cache work
68e613057 prep cache impl
811b4d809 fix clang format
fda755f7d idk
d5024ebbf small MI refactor in preparation of (eventually) implementing the RDRAM interface properly
694b45341 Merge commit '206dcdedf195fb320913584180edb12c7731e396' as 'external/SDL'
206dcdedf Squashed 'external/SDL/' content from commit 4d17b99d0a
4d16e1cb4 need to update sdl
848b19920 Fix compilation error
db61b5299 Merge commit 'e94a94559f28e49678fbcf72199a5258137b0fe9' as 'external/imgui'
e94a94559 Squashed 'external/imgui/' content from commit 02e9b8cac
52edb3757 need to update imgui
c1a705e86 Emulate weird JALR behaviour
4b4c32f4b Fix exception for "unusable COP1" in 4 instructions i missed accidentally (again)
df5828142 Bug putting 0s in the log everywhere
f8b580048 Make isviewer a sink to file
8241e9735 Fix exception for "unusable COP1" in 4 instructions i missed accidentally
b29715f20 small changes
d9a620bc1 make use of my new small utility library
0d1aa938e Add 'external/ircolib/' from commit 'ce3cd726c8df8388d554abf8bb55d55020eb4450'
e64eb40b3 Fuck git

git-subtree-dir: external/ircolib
git-subtree-split: de6e324bde
This commit is contained in:
2026-06-15 11:56:38 +02:00
parent ce3cd726c8
commit 00cc9309cb
4479 changed files with 2943227 additions and 7 deletions
+94
View File
@@ -0,0 +1,94 @@
cmake_minimum_required(VERSION 3.15)
# Enable DOWNLOAD_EXTRACT_TIMESTAMP
if(POLICY CMP0135)
cmake_policy(SET CMP0135 NEW)
endif()
include(ExternalProject)
find_library(libyaml
NAMES libyaml yaml
REQUIRED)
set(CMOCKA_LIB_FILE "${CMAKE_CURRENT_BINARY_DIR}/extern/src/cmocka_ext-build/src/libcmocka.a")
ExternalProject_Add(cmocka_ext
PREFIX extern
URL "https://cmocka.org/files/1.1/cmocka-1.1.7.tar.xz"
URL_HASH SHA256=810570eb0b8d64804331f82b29ff47c790ce9cd6b163e98d47a4807047ecad82
CONFIGURE_COMMAND cmake -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} ../cmocka_ext/
BUILD_COMMAND cmake --build . --config Release
BUILD_BYPRODUCTS "${CMOCKA_LIB_FILE}"
INSTALL_COMMAND ""
)
if ("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
set(LIBCYAML_VARIANT "debug")
else()
set(LIBCYAML_VARIANT "release")
endif()
set(LIBCYAML_LIB_FILE "${CMAKE_CURRENT_BINARY_DIR}/extern/src/libcyaml_ext/build/${LIBCYAML_VARIANT}/libcyaml.a")
ExternalProject_Add(libcyaml_ext
PREFIX extern
URL "https://github.com/tlsa/libcyaml/archive/refs/tags/v1.4.2.tar.gz"
URL_HASH SHA256=3211b2a0589ebfe02c563c96adce9246c0787be2af30353becbbd362998d16dc
CONFIGURE_COMMAND ""
BUILD_COMMAND make VARIANT=${LIBCYAML_VARIANT} PKG_CONFIG=pkg-config
BUILD_BYPRODUCTS "${LIBCYAML_LIB_FILE}"
BUILD_IN_SOURCE true
INSTALL_COMMAND ""
)
set(CMOCKA_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/extern/src/cmocka_ext/include)
set(LIBCYAML_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/extern/src/libcyaml_ext/include)
add_library(cmocka STATIC IMPORTED)
add_library(libcyaml STATIC IMPORTED)
set_target_properties(cmocka PROPERTIES IMPORTED_LOCATION "${CMOCKA_LIB_FILE}")
set_target_properties(libcyaml PROPERTIES IMPORTED_LOCATION "${LIBCYAML_LIB_FILE}")
set(CSTEST_INCLUDE_DIR ${CSTEST_DIR}/include)
file(GLOB CSTEST_SRC ${CSTEST_DIR}/src/*.c)
add_executable(cstest ${CSTEST_SRC})
add_library(libcstest STATIC ${CSTEST_SRC})
add_dependencies(cstest cmocka_ext)
add_dependencies(cstest libcyaml_ext)
target_link_libraries(cstest PUBLIC capstone cmocka libcyaml ${libyaml})
target_link_libraries(libcstest PUBLIC capstone cmocka libcyaml ${libyaml})
target_include_directories(cstest PRIVATE
${PROJECT_SOURCE_DIR}/include>
${CSTEST_INCLUDE_DIR}
${CMOCKA_INCLUDE_DIR}
${LIBCYAML_INCLUDE_DIR}
)
target_include_directories(libcstest PRIVATE
${PROJECT_SOURCE_DIR}/include>
${CSTEST_INCLUDE_DIR}
${CMOCKA_INCLUDE_DIR}
${LIBCYAML_INCLUDE_DIR}
)
# Unit tests for cstest
set(CSTEST_TEST_DIR ${CSTEST_DIR}/test/)
add_subdirectory(${CSTEST_TEST_DIR})
# Test targets
add_test(MCTests
cstest ${PROJECT_SOURCE_DIR}/tests/MC
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
)
add_test(DetailTests
cstest ${PROJECT_SOURCE_DIR}/tests/details
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
)
add_test(IssueTests
cstest ${PROJECT_SOURCE_DIR}/tests/issues
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
)
add_test(FeaturesTests
cstest ${PROJECT_SOURCE_DIR}/tests/features
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
)
if(CAPSTONE_INSTALL)
install(TARGETS cstest EXPORT capstone-targets DESTINATION ${CMAKE_INSTALL_BINDIR})
endif()
+8
View File
@@ -0,0 +1,8 @@
<!--
Copyright © 2024 Rot127 <unisono@quyllur.org>
SPDX-License-Identifier: BSD-3
-->
## Testing cstest
Files to test `cstest` itself are located in `suite/cstest/test`.
+21
View File
@@ -0,0 +1,21 @@
/* Capstone testing regression */
/* By Do Minh Tuan <tuanit96@gmail.com>, 02-2019 */
#ifndef HELPER_H
#define HELPER_H
#include <stddef.h>
#define MAX_ASM_TXT_MEM 1024
#define X86_16 0
#define X86_32 1
#define X86_64 2
void trim_str(char *str);
void add_str(char **src, const char *format, ...);
void replace_hex(char *src, size_t src_len);
void replace_negative(char *src, size_t src_len, size_t arch_bits);
void norm_spaces(char *str);
void str_to_lower(char *str);
#endif /* HELPER_H */
+178
View File
@@ -0,0 +1,178 @@
// Copyright © 2024 Rot127 <unisono@quyllur.org>
// SPDX-License-Identifier: BSD-3
#ifndef TESTCASE_H
#define TESTCASE_H
#include "test_detail.h"
#include <cyaml/cyaml.h>
#include <capstone/capstone.h>
#include <stdbool.h>
#include <stdint.h>
/// Input data for a test case.
typedef struct {
char *name;
uint8_t *bytes; // mandatory
uint32_t bytes_count; // Filled by cyaml
char *arch; // mandatory
uint64_t address;
char **options; // mandatory
uint32_t options_count; // Filled by cyaml
} TestInput;
TestInput *test_input_new();
void test_input_free(TestInput *test_input);
TestInput *test_input_clone(TestInput *test_input);
char *test_input_stringify(const TestInput *test_input, const char *postfix);
cs_arch test_input_get_cs_arch(const TestInput *test_input);
cs_mode test_input_get_cs_mode(const TestInput *test_input);
void test_input_get_cs_option(const TestInput *test_input, cs_opt_type *otype,
cs_opt_value *oval);
/// A single byte
static const cyaml_schema_value_t byte_schema = {
CYAML_VALUE_UINT(CYAML_FLAG_DEFAULT, uint8_t),
};
/// A single option string
static const cyaml_schema_value_t option_schema = {
CYAML_VALUE_STRING(CYAML_FLAG_POINTER, char, 0, CYAML_UNLIMITED),
};
static const cyaml_schema_field_t test_input_mapping_schema[] = {
CYAML_FIELD_STRING_PTR("name", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL, TestInput, name,
0, CYAML_UNLIMITED),
CYAML_FIELD_SEQUENCE("bytes", CYAML_FLAG_POINTER, TestInput, bytes,
&byte_schema, 0, CYAML_UNLIMITED), // 0-MAX bytes
CYAML_FIELD_STRING_PTR("arch", CYAML_FLAG_POINTER, TestInput, arch, 0,
CYAML_UNLIMITED),
CYAML_FIELD_UINT("address",
CYAML_FLAG_SCALAR_PLAIN | CYAML_FLAG_OPTIONAL,
TestInput, address),
CYAML_FIELD_SEQUENCE("options", CYAML_FLAG_POINTER, TestInput, options,
&option_schema, 0,
CYAML_UNLIMITED), // 0-MAX options
CYAML_FIELD_END
};
/// Data compared to the produced cs_insn.
typedef struct {
char *id;
char *asm_text; // mandatory
char *op_str;
int32_t is_alias; ///< 0 == not given, >0 == true, <0 == false
int32_t illegal; ///< 0 == not given, >0 == true, <0 == false
char *alias_id;
char *mnemonic;
TestDetail *details;
} TestInsnData;
TestInsnData *test_insn_data_new();
void test_insn_data_free(TestInsnData *test_insn_data);
TestInsnData *test_insn_data_clone(TestInsnData *test_insn_data);
static const cyaml_schema_field_t test_insn_data_mapping_schema[] = {
CYAML_FIELD_STRING_PTR("id", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestInsnData, id, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("asm_text", CYAML_FLAG_POINTER, TestInsnData,
asm_text, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR(
"op_str", CYAML_FLAG_POINTER_NULL_STR | CYAML_FLAG_OPTIONAL,
TestInsnData, op_str, 0, CYAML_UNLIMITED),
CYAML_FIELD_INT("is_alias", CYAML_FLAG_OPTIONAL, TestInsnData,
is_alias),
CYAML_FIELD_INT("illegal", CYAML_FLAG_OPTIONAL, TestInsnData,
illegal),
CYAML_FIELD_STRING_PTR("alias_id",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestInsnData, alias_id, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR(
"mnemonic", CYAML_FLAG_POINTER_NULL_STR | CYAML_FLAG_OPTIONAL,
TestInsnData, mnemonic, 0, CYAML_UNLIMITED),
CYAML_FIELD_MAPPING_PTR(
"details", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestInsnData, details, test_detail_mapping_schema),
CYAML_FIELD_END
};
/// The expected data for a test. This can hold multiple instructions
/// if enough bytes were given.
typedef struct {
TestInsnData **insns; ///< Zero to N disassembled instructions.
uint32_t insns_count; ///< Filled by cyaml.
} TestExpected;
TestExpected *test_expected_new();
void test_expected_free(TestExpected *test_expected);
TestExpected *test_expected_clone(TestExpected *test_expected);
void test_expected_compare(csh *handle, TestExpected *expected, cs_insn *insns,
size_t insns_count, size_t arch_bits);
static const cyaml_schema_value_t insn_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER, TestInsnData,
test_insn_data_mapping_schema),
};
static const cyaml_schema_field_t test_expected_mapping_schema[] = {
CYAML_FIELD_SEQUENCE("insns", CYAML_FLAG_POINTER, TestExpected, insns,
&insn_schema, 0, CYAML_UNLIMITED), // 0-MAX options
CYAML_FIELD_END
};
/// A single test case.
typedef struct {
TestInput *input; ///< Input data for a test case
TestExpected *expected; ///< Expected data of the test case.
bool skip; ///< If set, the test is skipped
char *skip_reason; ///< Reason this test is skipped.
} TestCase;
TestCase *test_case_new();
void test_case_free(TestCase *test_case);
TestCase *test_case_clone(TestCase *test_case);
static const cyaml_schema_field_t test_case_mapping_schema[] = {
CYAML_FIELD_MAPPING_PTR("input", CYAML_FLAG_POINTER, TestCase, input,
test_input_mapping_schema),
CYAML_FIELD_MAPPING_PTR("expected", CYAML_FLAG_POINTER, TestCase,
expected, test_expected_mapping_schema),
CYAML_FIELD_BOOL("skip", CYAML_FLAG_OPTIONAL, TestCase, skip),
CYAML_FIELD_STRING_PTR("skip_reason",
CYAML_FLAG_POINTER_NULL_STR |
CYAML_FLAG_OPTIONAL,
TestCase, skip_reason, 0, CYAML_UNLIMITED),
CYAML_FIELD_END
};
static const cyaml_schema_value_t test_case_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER, TestCase,
test_case_mapping_schema),
};
typedef struct {
char *filename; ///< Filename. NOT filled by cyaml.
TestCase **test_cases;
uint32_t test_cases_count;
} TestFile;
TestFile *test_file_new();
void test_file_free(TestFile *test_file);
TestFile *test_file_clone(TestFile *test_file);
static const cyaml_schema_field_t test_file_mapping_schema[] = {
CYAML_FIELD_STRING_PTR(
"filename", CYAML_FLAG_OPTIONAL | CYAML_FLAG_POINTER_NULL_STR,
TestFile, filename, 0, 0),
CYAML_FIELD_SEQUENCE("test_cases", CYAML_FLAG_POINTER, TestFile,
test_cases, &test_case_schema, 1,
CYAML_UNLIMITED), // 1-MAX options
CYAML_FIELD_END
};
static const cyaml_schema_value_t test_file_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER, TestFile,
test_file_mapping_schema),
};
#endif // TESTCASE_H
+233
View File
@@ -0,0 +1,233 @@
// Copyright © 2024 Rot127 <unisono@quyllur.org>
// SPDX-License-Identifier: BSD-3
#ifndef TEST_COMPARE_H
#define TEST_COMPARE_H
#include <stdint.h>
#include "test_mapping.h"
#include "../../../utils.h"
/// An integer encoding a boolean value from the test files.
/// libcyaml saves 0 by default, if an optional value was not set.
/// Due to that, boolean values are represented as integer with the
/// interpretation:
///
/// = 0 => unset
/// < 0 => false
/// > 0 => true
typedef int32_t tbool;
#define CYAML_FIELD_TBOOL(name, flags, type, member) \
CYAML_FIELD_INT(name, flags, type, member)
/// Compares the @actual bool against the @expected tbool:
/// It returns with @ret_val, if expected is set but the values mismatch.
#define compare_tbool_ret(actual, expected, ret_val) \
if (expected != 0 && \
((actual && expected <= 0) || (!actual && expected >= 0))) { \
fprintf(stderr, \
#actual " is %s but expected is %" PRId32 \
" (=0 unset, >0 true, <0 false)\n", \
actual ? "true" : "false", expected); \
return ret_val; \
}
/// Compares two unsigned int values.
/// It returns with @ret_val if they mismatch.
#define compare_uint_ret(actual, expected, ret_val) \
if (((unsigned int)actual) != ((unsigned int)expected)) { \
fprintf(stderr, \
#actual " != " #expected ": 0x%" PRIx32 \
" != 0x%" PRIx32 "\n", \
actual, expected); \
return ret_val; \
}
/// Compares two uint8_t values.
/// It returns with @ret_val if they mismatch.
#define compare_uint8_ret(actual, expected, ret_val) \
if (((uint8_t)actual) != ((uint8_t)expected)) { \
fprintf(stderr, \
#actual " != " #expected ": %" PRId8 " != %" PRId8 \
"\n", \
actual, expected); \
return ret_val; \
}
/// Compares two uint16_t values.
/// It returns with @ret_val if they mismatch.
#define compare_uint16_ret(actual, expected, ret_val) \
if (((uint16_t)actual) != ((uint16_t)expected)) { \
fprintf(stderr, \
#actual " != " #expected ": 0x%" PRIx16 \
" != 0x%" PRIx16 "\n", \
actual, expected); \
return ret_val; \
}
/// Compares two uint32_t values.
/// It returns with @ret_val if they mismatch.
#define compare_uint32_ret(actual, expected, ret_val) \
if (((uint32_t)actual) != ((uint32_t)expected)) { \
fprintf(stderr, \
#actual " != " #expected ": 0x%" PRIx32 \
" != 0x%" PRIx32 "\n", \
actual, expected); \
return ret_val; \
}
/// Compares two uint64_t values.
/// It returns with @ret_val if they mismatch.
#define compare_uint64_ret(actual, expected, ret_val) \
if (((uint64_t)actual) != ((uint64_t)expected)) { \
fprintf(stderr, \
#actual " != " #expected ": 0x%" PRIx64 \
" != 0x%" PRIx64 "\n", \
actual, expected); \
return ret_val; \
}
/// Compares two int values.
/// It returns with @ret_val if they mismatch.
#define compare_int_ret(actual, expected, ret_val) \
if (((int)actual) != ((int)expected)) { \
fprintf(stderr, \
#actual " != " #expected ": 0x%" PRIx32 \
" != 0x%" PRIx32 "\n", \
actual, expected); \
return ret_val; \
}
/// Compares two int8_t values.
/// It returns with @ret_val if they mismatch.
#define compare_int8_ret(actual, expected, ret_val) \
if (((int8_t)actual) != ((int8_t)expected)) { \
fprintf(stderr, \
#actual " != " #expected ": 0x%" PRIx8 " != 0x%" PRIx8 \
"\n", \
actual, expected); \
return ret_val; \
}
/// Compares two int16_t values.
/// It returns with @ret_val if they mismatch.
#define compare_int16_ret(actual, expected, ret_val) \
if (((int16_t)actual) != ((int16_t)expected)) { \
fprintf(stderr, \
#actual " != " #expected ": 0x%" PRIx16 \
" != 0x%" PRIx16 "\n", \
actual, expected); \
return ret_val; \
}
/// Compares two int32_t values.
/// It returns with @ret_val if they mismatch.
#define compare_int32_ret(actual, expected, ret_val) \
if (((int32_t)actual) != ((int32_t)expected)) { \
fprintf(stderr, \
#actual " != " #expected ": 0x%" PRIx32 \
" != 0x%" PRIx32 "\n", \
actual, expected); \
return ret_val; \
}
/// Compares two int64_t values.
/// It returns with @ret_val if they mismatch.
#define compare_int64_ret(actual, expected, ret_val) \
if (((int64_t)actual) != ((int64_t)expected)) { \
fprintf(stderr, \
#actual " != " #expected ": 0x%" PRIx64 \
" != 0x%" PRIx64 "\n", \
actual, expected); \
return ret_val; \
}
/// Compares two floating point values.
/// It returns with @ret_val if they mismatch.
#define compare_fp_ret(actual, expected, ret_val) \
if (actual != expected) { \
fprintf(stderr, #actual " != " #expected ": %f != %f\n", \
actual, expected); \
return ret_val; \
}
/// Compares enum id.
/// Actual is the value, expected is the enum idetifer as string.
/// It returns with @ret_val if they mismatch.
#define compare_enum_ret(actual, expected, ret_val) \
if (expected) { \
bool found = false; \
uint32_t eval = enum_map_bin_search( \
cs_enum_map, ARR_SIZE(cs_enum_map), expected, &found); \
if (expected && (actual != eval || !found)) { \
fprintf(stderr, \
#actual " != " #expected ": %" PRId32 \
" != %s%s\n", \
actual, expected, \
found ? "" : " <== id not found. Consider adding it in test_mapping.h::cs_enum_map."); \
return ret_val; \
} \
}
/// Checks if all bit flags in @expected are set in @actual.
/// Actual is the value with all bits set.
/// @expected is a list the @len enum identifiers as string.
/// It returns with @ret_val if they mismatch.
#define compare_bit_flags_ret(actual, expected, len, ret_val) \
if (expected) { \
for (size_t cmp_i = 0; cmp_i < len; ++cmp_i) { \
bool found = false; \
uint32_t eval = enum_map_bin_search( \
cs_enum_map, ARR_SIZE(cs_enum_map), \
expected[cmp_i], &found); \
if (!(actual & eval) || !found) { \
fprintf(stderr, \
#actual " != " #expected ": %" PRId32 \
" != %s%s\n", \
actual, expected[cmp_i], \
found ? " <== Flag not set" : \
" <== id not found"); \
return ret_val; \
} \
} \
}
/// Checks if all bit flags in @expected are set in @actual.
/// Actual is the value with all bits set.
/// @expected is a list the @len enum identifiers as string.
/// It returns with @ret_val if they mismatch.
#define compare_bit_flags_64_ret(actual, expected, len, ret_val) \
if (expected) { \
for (size_t cmp_i = 0; cmp_i < len; ++cmp_i) { \
bool found = false; \
uint64_t eval = enum_map_bin_search( \
cs_enum_map, ARR_SIZE(cs_enum_map), \
expected[cmp_i], &found); \
if (!(actual & eval) || !found) { \
fprintf(stderr, \
#actual " != " #expected ": %" PRId64 \
" != %s%s\n", \
actual, expected[cmp_i], \
found ? " <== Flag not set" : \
" <== id not found"); \
return ret_val; \
} \
} \
}
/// Compares register names.
/// Actual is the register id, expected is name as string.
/// It returns with @ret_val if they mismatch.
#define compare_reg_ret(handle, actual, expected, ret_val) \
if (expected) { \
const char *reg_name = cs_reg_name(handle, actual); \
if (expected && !strings_match(reg_name, expected)) { \
fprintf(stderr, \
#actual " != " #expected ": '%s' != '%s'\n", \
reg_name, expected); \
return ret_val; \
} \
}
#endif // TEST_COMPARE_H
+184
View File
@@ -0,0 +1,184 @@
// Copyright © 2024 Rot127 <unisono@quyllur.org>
// SPDX-License-Identifier: BSD-3
/// @file Defines all detail structures to test against and their yaml schemas.
/// The structs currently need to be partially redefined, if they contain unions.
/// And they won't be supported until libcyaml v2:
/// https://github.com/tlsa/libcyaml/issues/186
#ifndef TEST_DETAIL_H
#define TEST_DETAIL_H
#include "test_detail_aarch64.h"
#include "test_detail_arm.h"
#include "test_detail_evm.h"
#include "test_detail_loongarch.h"
#include "test_detail_mos65xx.h"
#include "test_detail_ppc.h"
#include "test_detail_riscv.h"
#include "test_detail_tricore.h"
#include "test_detail_systemz.h"
#include "test_detail_sh.h"
#include "test_detail_sparc.h"
#include "test_detail_alpha.h"
#include "test_detail_bpf.h"
#include "test_detail_hppa.h"
#include "test_detail_xcore.h"
#include "test_detail_mips.h"
#include "test_detail_riscv.h"
#include "test_detail_m680x.h"
#include "test_detail_tms320c64x.h"
#include "test_detail_wasm.h"
#include "test_detail_x86.h"
#include "test_detail_m68k.h"
#include "test_detail_xtensa.h"
#include "test_detail_arc.h"
#include "test_compare.h"
#include <capstone/capstone.h>
#include <cyaml/cyaml.h>
/// The equivalent to cs_detail in capstone.h
/// but with pointers and no unions. Because cyaml does not support them.
typedef struct {
TestDetailAArch64 *aarch64;
TestDetailARM *arm;
TestDetailPPC *ppc;
TestDetailTriCore *tricore;
TestDetailAlpha *alpha;
TestDetailHPPA *hppa;
TestDetailBPF *bpf;
TestDetailSystemZ *systemz;
TestDetailSparc *sparc;
TestDetailXCore *xcore;
TestDetailSH *sh;
TestDetailMips *mips;
TestDetailRISCV *riscv;
TestDetailM680x *m680x;
TestDetailTMS320c64x *tms320c64x;
TestDetailMos65xx *mos65xx;
TestDetailEVM *evm;
TestDetailLoongArch *loongarch;
TestDetailWASM *wasm;
TestDetailX86 *x86;
TestDetailM68K *m68k;
TestDetailXtensa *xtensa;
TestDetailARC *arc;
char **regs_read;
uint8_t regs_read_count;
char **regs_write;
uint8_t regs_write_count;
// Implicit read/writes only
char **regs_impl_read;
uint8_t regs_impl_read_count;
char **regs_impl_write;
uint8_t regs_impl_write_count;
char **groups;
uint8_t groups_count;
tbool writeback;
} TestDetail;
static const cyaml_schema_value_t single_string_schema = {
CYAML_VALUE_STRING(CYAML_FLAG_POINTER, char, 0, CYAML_UNLIMITED),
};
static const cyaml_schema_field_t test_detail_mapping_schema[] = {
CYAML_FIELD_MAPPING_PTR(
"aarch64", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL, TestDetail,
aarch64, test_detail_aarch64_mapping_schema),
CYAML_FIELD_MAPPING_PTR("arm", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetail, arm,
test_detail_arm_mapping_schema),
CYAML_FIELD_MAPPING_PTR("ppc", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetail, ppc,
test_detail_ppc_mapping_schema),
CYAML_FIELD_MAPPING_PTR(
"tricore", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL, TestDetail,
tricore, test_detail_tricore_mapping_schema),
CYAML_FIELD_MAPPING_PTR(
"alpha", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL, TestDetail,
alpha, test_detail_alpha_mapping_schema),
CYAML_FIELD_MAPPING_PTR(
"hppa", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL, TestDetail,
hppa, test_detail_hppa_mapping_schema),
CYAML_FIELD_MAPPING_PTR("bpf", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetail, bpf,
test_detail_bpf_mapping_schema),
CYAML_FIELD_MAPPING_PTR(
"systemz", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL, TestDetail,
systemz, test_detail_systemz_mapping_schema),
CYAML_FIELD_MAPPING_PTR(
"sparc", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL, TestDetail,
sparc, test_detail_sparc_mapping_schema),
CYAML_FIELD_MAPPING_PTR(
"xcore", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL, TestDetail,
xcore, test_detail_xcore_mapping_schema),
CYAML_FIELD_MAPPING_PTR("sh", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetail, sh, test_detail_sh_mapping_schema),
CYAML_FIELD_MAPPING_PTR(
"mips", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL, TestDetail,
mips, test_detail_mips_mapping_schema),
CYAML_FIELD_MAPPING_PTR(
"riscv", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL, TestDetail,
riscv, test_detail_riscv_mapping_schema),
CYAML_FIELD_MAPPING_PTR(
"m680x", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL, TestDetail,
m680x, test_detail_m680x_mapping_schema),
CYAML_FIELD_MAPPING_PTR(
"tms320c64x", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetail, tms320c64x, test_detail_tms320c64x_mapping_schema),
CYAML_FIELD_MAPPING_PTR(
"mos65xx", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL, TestDetail,
mos65xx, test_detail_mos65xx_mapping_schema),
CYAML_FIELD_MAPPING_PTR("evm", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetail, evm,
test_detail_evm_mapping_schema),
CYAML_FIELD_MAPPING_PTR(
"loongarch", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetail, loongarch, test_detail_loongarch_mapping_schema),
CYAML_FIELD_MAPPING_PTR(
"wasm", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL, TestDetail,
wasm, test_detail_wasm_mapping_schema),
CYAML_FIELD_MAPPING_PTR("x86", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetail, x86,
test_detail_x86_mapping_schema),
CYAML_FIELD_MAPPING_PTR(
"m68k", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL, TestDetail,
m68k, test_detail_m68k_mapping_schema),
CYAML_FIELD_MAPPING_PTR(
"xtensa", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL, TestDetail,
xtensa, test_detail_xtensa_mapping_schema),
CYAML_FIELD_MAPPING_PTR(
"arc", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL, TestDetail,
arc, test_detail_arc_mapping_schema),
CYAML_FIELD_SEQUENCE("regs_read",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetail, regs_read, &single_string_schema, 0, 255),
CYAML_FIELD_SEQUENCE("regs_write",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetail, regs_write, &single_string_schema, 0, 255),
CYAML_FIELD_SEQUENCE(
"regs_impl_read", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetail, regs_impl_read, &single_string_schema, 0, 255),
CYAML_FIELD_SEQUENCE(
"regs_impl_write", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetail, regs_impl_write, &single_string_schema, 0, 255),
CYAML_FIELD_SEQUENCE("groups", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetail, groups, &single_string_schema, 0, 255),
CYAML_FIELD_INT("writeback", CYAML_FLAG_OPTIONAL, TestDetail,
writeback),
CYAML_FIELD_END
};
TestDetail *test_detail_new();
TestDetail *test_detail_clone(TestDetail *detail);
void test_detail_free(TestDetail *detail);
bool test_expected_detail(csh *handle, const cs_insn *insn,
TestDetail *expected);
#endif // TEST_DETAIL_H
@@ -0,0 +1,184 @@
// Copyright © 2024 Rot127 <unisono@quyllur.org>
// SPDX-License-Identifier: BSD-3
#ifndef TEST_DETAIL_AARCH64_H
#define TEST_DETAIL_AARCH64_H
#include "test_compare.h"
#include <cyaml/cyaml.h>
#include <capstone/capstone.h>
typedef struct {
char *type;
char *tile;
char *slice_reg;
int8_t slice_offset_imm;
int8_t slice_offset_ir_first;
int8_t slice_offset_ir_offset;
bool slice_offset_ir_set;
tbool has_range_offset;
tbool is_vertical;
} TestDetailAArch64SME;
static const cyaml_schema_field_t test_detail_aarch64_sme_mapping_schema[] = {
CYAML_FIELD_STRING_PTR("type", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailAArch64SME, type, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("tile", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailAArch64SME, tile, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR(
"slice_reg", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailAArch64SME, slice_reg, 0, CYAML_UNLIMITED),
CYAML_FIELD_INT("slice_offset_imm", CYAML_FLAG_OPTIONAL,
TestDetailAArch64SME, slice_offset_imm),
CYAML_FIELD_INT("slice_offset_ir_first", CYAML_FLAG_OPTIONAL,
TestDetailAArch64SME, slice_offset_ir_first),
CYAML_FIELD_INT("slice_offset_ir_offset", CYAML_FLAG_OPTIONAL,
TestDetailAArch64SME, slice_offset_ir_offset),
CYAML_FIELD_BOOL("slice_offset_ir_set", CYAML_FLAG_OPTIONAL,
TestDetailAArch64SME, slice_offset_ir_set),
CYAML_FIELD_INT("has_range_offset", CYAML_FLAG_OPTIONAL,
TestDetailAArch64SME, has_range_offset),
CYAML_FIELD_INT("is_vertical", CYAML_FLAG_OPTIONAL,
TestDetailAArch64SME, is_vertical),
CYAML_FIELD_END
};
typedef struct {
char *type;
char *sub_type;
char *access;
char *reg;
int64_t imm;
char *mem_base;
char *mem_index;
int32_t mem_disp;
int8_t imm_range_first;
int8_t imm_range_offset;
double fp;
bool fp_set; /// Only relevant for SysOps with EXACTFPIMM
int sys_raw_val;
TestDetailAArch64SME *sme;
char *pred_reg;
char *pred_vec_select;
int32_t pred_imm_index;
bool pred_imm_index_set;
char *shift_type;
uint32_t shift_value;
char *ext;
char *vas;
tbool is_vreg;
int vector_index;
bool vector_index_is_set;
tbool is_list_member;
} TestDetailAArch64Op;
static const cyaml_schema_field_t test_detail_aarch64_op_mapping_schema[] = {
CYAML_FIELD_STRING_PTR("type", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailAArch64Op, type, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR(
"sub_type", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailAArch64Op, sub_type, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("access",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailAArch64Op, access, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("reg", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailAArch64Op, reg, 0, CYAML_UNLIMITED),
CYAML_FIELD_INT("imm", CYAML_FLAG_OPTIONAL, TestDetailAArch64Op, imm),
CYAML_FIELD_STRING_PTR(
"mem_base", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailAArch64Op, mem_base, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR(
"mem_index", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailAArch64Op, mem_index, 0, CYAML_UNLIMITED),
CYAML_FIELD_INT("mem_disp", CYAML_FLAG_OPTIONAL, TestDetailAArch64Op,
mem_disp),
CYAML_FIELD_INT("imm_range_first", CYAML_FLAG_OPTIONAL,
TestDetailAArch64Op, imm_range_first),
CYAML_FIELD_INT("imm_range_offset", CYAML_FLAG_OPTIONAL,
TestDetailAArch64Op, imm_range_offset),
CYAML_FIELD_FLOAT("fp", CYAML_FLAG_OPTIONAL, TestDetailAArch64Op, fp),
CYAML_FIELD_BOOL("fp_set", CYAML_FLAG_OPTIONAL, TestDetailAArch64Op, fp_set),
CYAML_FIELD_UINT("sys_raw_val", CYAML_FLAG_OPTIONAL,
TestDetailAArch64Op, sys_raw_val),
CYAML_FIELD_MAPPING_PTR("sme", CYAML_FLAG_OPTIONAL, TestDetailAArch64Op,
sme, test_detail_aarch64_sme_mapping_schema),
CYAML_FIELD_STRING_PTR(
"pred_reg", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailAArch64Op, pred_reg, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR(
"pred_vec_select", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailAArch64Op, pred_vec_select, 0, CYAML_UNLIMITED),
CYAML_FIELD_INT("pred_imm_index", CYAML_FLAG_OPTIONAL,
TestDetailAArch64Op, pred_imm_index),
CYAML_FIELD_BOOL("pred_imm_index_set", CYAML_FLAG_OPTIONAL,
TestDetailAArch64Op, pred_imm_index_set),
CYAML_FIELD_STRING_PTR(
"shift_type", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailAArch64Op, shift_type, 0, CYAML_UNLIMITED),
CYAML_FIELD_UINT("shift_value", CYAML_FLAG_OPTIONAL,
TestDetailAArch64Op, shift_value),
CYAML_FIELD_STRING_PTR("ext", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailAArch64Op, ext, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("vas", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailAArch64Op, vas, 0, CYAML_UNLIMITED),
CYAML_FIELD_INT("is_vreg", CYAML_FLAG_OPTIONAL, TestDetailAArch64Op,
is_vreg),
CYAML_FIELD_INT("vector_index", CYAML_FLAG_OPTIONAL,
TestDetailAArch64Op, vector_index),
CYAML_FIELD_BOOL("vector_index_is_set", CYAML_FLAG_OPTIONAL,
TestDetailAArch64Op, vector_index_is_set),
CYAML_FIELD_INT("is_list_member", CYAML_FLAG_OPTIONAL,
TestDetailAArch64Op, is_list_member),
CYAML_FIELD_END
};
static const cyaml_schema_value_t test_detail_aarch64_op_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER, TestDetailAArch64Op,
test_detail_aarch64_op_mapping_schema),
};
typedef struct {
char *cc;
tbool update_flags;
tbool post_indexed;
TestDetailAArch64Op **operands;
uint32_t operands_count;
} TestDetailAArch64;
static const cyaml_schema_field_t test_detail_aarch64_mapping_schema[] = {
CYAML_FIELD_STRING_PTR("cc", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailAArch64, cc, 0, CYAML_UNLIMITED),
CYAML_FIELD_INT("update_flags", CYAML_FLAG_OPTIONAL, TestDetailAArch64,
update_flags),
CYAML_FIELD_INT("post_indexed", CYAML_FLAG_OPTIONAL, TestDetailAArch64,
post_indexed),
CYAML_FIELD_SEQUENCE(
"operands", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailAArch64, operands, &test_detail_aarch64_op_schema, 0,
CYAML_UNLIMITED), // 0-MAX options
CYAML_FIELD_END
};
TestDetailAArch64 *test_detail_aarch64_new();
TestDetailAArch64 *test_detail_aarch64_clone(TestDetailAArch64 *detail);
void test_detail_aarch64_free(TestDetailAArch64 *detail);
TestDetailAArch64Op *test_detail_aarch64_op_new();
TestDetailAArch64Op *test_detail_aarch64_op_clone(TestDetailAArch64Op *detail);
void test_detail_aarch64_op_free(TestDetailAArch64Op *detail);
TestDetailAArch64SME *test_detail_aarch64_op_sme_new();
TestDetailAArch64SME *test_detail_aarch64_op_sme_clone(TestDetailAArch64SME *sme);
void test_detail_aarch64_op_sme_free(TestDetailAArch64SME *sme);
bool test_expected_aarch64(csh *handle, cs_aarch64 *actual,
TestDetailAArch64 *expected);
#endif // TEST_DETAIL_AARCH64_H
@@ -0,0 +1,60 @@
// Copyright © 2024 Rot127 <unisono@quyllur.org>
// SPDX-License-Identifier: BSD-3
#ifndef TEST_DETAIL_ALPHA_H
#define TEST_DETAIL_ALPHA_H
#include "test_compare.h"
#include <cyaml/cyaml.h>
#include <capstone/capstone.h>
typedef struct {
char *type;
char *access;
char *reg;
int32_t imm;
} TestDetailAlphaOp;
static const cyaml_schema_field_t test_detail_alpha_op_mapping_schema[] = {
CYAML_FIELD_STRING_PTR("type", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailAlphaOp, type, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("access",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailAlphaOp, access, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("reg", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailAlphaOp, reg, 0, CYAML_UNLIMITED),
CYAML_FIELD_INT("imm", CYAML_FLAG_OPTIONAL, TestDetailAlphaOp, imm),
CYAML_FIELD_END
};
static const cyaml_schema_value_t test_detail_alpha_op_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER, TestDetailAlphaOp,
test_detail_alpha_op_mapping_schema),
};
typedef struct {
TestDetailAlphaOp **operands;
uint32_t operands_count;
} TestDetailAlpha;
static const cyaml_schema_field_t test_detail_alpha_mapping_schema[] = {
CYAML_FIELD_SEQUENCE(
"operands", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailAlpha, operands, &test_detail_alpha_op_schema, 0,
CYAML_UNLIMITED), // 0-MAX options
CYAML_FIELD_END
};
TestDetailAlpha *test_detail_alpha_new();
TestDetailAlpha *test_detail_alpha_clone(const TestDetailAlpha *detail);
void test_detail_alpha_free(TestDetailAlpha *detail);
TestDetailAlphaOp *test_detail_alpha_op_new();
TestDetailAlphaOp *test_detail_alpha_op_clone(const TestDetailAlphaOp *detail);
void test_detail_alpha_op_free(TestDetailAlphaOp *detail);
bool test_expected_alpha(csh *handle, const cs_alpha *actual,
const TestDetailAlpha *expected);
#endif // TEST_DETAIL_ALPHA_H
@@ -0,0 +1,60 @@
// Copyright © 2024 Sibirtsev Dmitry <sibirtsevdl@gmail.com>
// SPDX-License-Identifier: BSD-3
#ifndef TEST_DETAIL_ARC_H
#define TEST_DETAIL_ARC_H
#include "test_compare.h"
#include <cyaml/cyaml.h>
#include <capstone/capstone.h>
typedef struct {
char *type;
char *access;
char *reg;
int64_t imm;
} TestDetailARCOp;
static const cyaml_schema_field_t test_detail_arc_op_mapping_schema[] = {
CYAML_FIELD_STRING_PTR("type", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailARCOp, type, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("access",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailARCOp, access, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("reg", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailARCOp, reg, 0, CYAML_UNLIMITED),
CYAML_FIELD_INT("imm", CYAML_FLAG_OPTIONAL, TestDetailARCOp, imm),
CYAML_FIELD_END
};
static const cyaml_schema_value_t test_detail_arc_op_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER, TestDetailARCOp,
test_detail_arc_op_mapping_schema),
};
typedef struct {
TestDetailARCOp **operands;
uint32_t operands_count;
} TestDetailARC;
static const cyaml_schema_field_t test_detail_arc_mapping_schema[] = {
CYAML_FIELD_SEQUENCE(
"operands", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailARC, operands, &test_detail_arc_op_schema, 0,
CYAML_UNLIMITED), // 0-MAX options
CYAML_FIELD_END
};
TestDetailARC *test_detail_arc_new();
TestDetailARC *test_detail_arc_clone(const TestDetailARC *detail);
void test_detail_arc_free(TestDetailARC *detail);
TestDetailARCOp *test_detail_arc_op_new();
TestDetailARCOp *test_detail_arc_op_clone(const TestDetailARCOp *detail);
void test_detail_arc_op_free(TestDetailARCOp *detail);
bool test_expected_arc(csh *handle, const cs_arc *actual,
const TestDetailARC *expected);
#endif // TEST_DETAIL_ARC_H
+165
View File
@@ -0,0 +1,165 @@
// Copyright © 2024 Rot127 <unisono@quyllur.org>
// SPDX-License-Identifier: BSD-3
#ifndef TEST_DETAIL_ARM_H
#define TEST_DETAIL_ARM_H
#include "test_compare.h"
#include <cyaml/cyaml.h>
#include <capstone/capstone.h>
typedef struct {
char *type;
char *access;
char *reg;
int64_t imm;
char *setend;
int pred;
double fp;
char *mem_base;
char *mem_index;
int32_t mem_scale;
int32_t mem_disp;
uint32_t mem_align;
char *sys_reg;
char **sys_psr_bits;
uint32_t sys_psr_bits_count;
int sys_sysm;
int sys_msr_mask;
char *shift_type;
uint32_t shift_value;
int8_t neon_lane;
int vector_index;
bool vector_index_is_set;
tbool subtracted;
} TestDetailARMOp;
static const cyaml_schema_value_t test_detail_arm_op_sys_psr_schema = {
CYAML_VALUE_STRING(CYAML_FLAG_POINTER, char, 0, CYAML_UNLIMITED),
};
static const cyaml_schema_field_t test_detail_arm_op_mapping_schema[] = {
CYAML_FIELD_STRING_PTR("type", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailARMOp, type, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("access",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailARMOp, access, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("reg", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailARMOp, reg, 0, CYAML_UNLIMITED),
CYAML_FIELD_INT("imm", CYAML_FLAG_OPTIONAL, TestDetailARMOp, imm),
CYAML_FIELD_STRING_PTR("setend",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailARMOp, setend, 0, CYAML_UNLIMITED),
CYAML_FIELD_INT("pred", CYAML_FLAG_OPTIONAL, TestDetailARMOp, pred),
CYAML_FIELD_FLOAT("fp", CYAML_FLAG_OPTIONAL, TestDetailARMOp, fp),
CYAML_FIELD_STRING_PTR("mem_base",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailARMOp, mem_base, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("mem_index",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailARMOp, mem_index, 0, CYAML_UNLIMITED),
CYAML_FIELD_INT("mem_disp", CYAML_FLAG_OPTIONAL, TestDetailARMOp,
mem_disp),
CYAML_FIELD_INT("mem_scale", CYAML_FLAG_OPTIONAL, TestDetailARMOp,
mem_scale),
CYAML_FIELD_UINT("mem_align", CYAML_FLAG_OPTIONAL, TestDetailARMOp,
mem_align),
CYAML_FIELD_STRING_PTR("sys_reg",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailARMOp, sys_reg, 0, CYAML_UNLIMITED),
CYAML_FIELD_SEQUENCE(
"sys_psr_bits", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailARMOp, sys_psr_bits,
&test_detail_arm_op_sys_psr_schema, 0, CYAML_UNLIMITED),
CYAML_FIELD_INT("sys_sysm", CYAML_FLAG_OPTIONAL, TestDetailARMOp,
sys_sysm),
CYAML_FIELD_INT("sys_msr_mask", CYAML_FLAG_OPTIONAL, TestDetailARMOp,
sys_msr_mask),
CYAML_FIELD_STRING_PTR("shift_type",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailARMOp, shift_type, 0, CYAML_UNLIMITED),
CYAML_FIELD_UINT("shift_value", CYAML_FLAG_OPTIONAL, TestDetailARMOp,
shift_value),
CYAML_FIELD_INT("neon_lane", CYAML_FLAG_OPTIONAL, TestDetailARMOp,
neon_lane),
CYAML_FIELD_INT("vector_index", CYAML_FLAG_OPTIONAL, TestDetailARMOp,
vector_index),
CYAML_FIELD_BOOL("vector_index_is_set", CYAML_FLAG_OPTIONAL,
TestDetailARMOp, vector_index_is_set),
CYAML_FIELD_INT("subtracted", CYAML_FLAG_OPTIONAL, TestDetailARMOp,
subtracted),
CYAML_FIELD_END
};
static const cyaml_schema_value_t test_detail_arm_op_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER, TestDetailARMOp,
test_detail_arm_op_mapping_schema),
};
typedef struct {
int vector_size;
char *vector_data;
char *cps_mode;
char *cps_flag;
char *cc;
char *vcc;
char *mem_barrier;
uint8_t pred_mask;
tbool usermode;
tbool update_flags;
tbool post_indexed;
TestDetailARMOp **operands;
uint32_t operands_count;
} TestDetailARM;
static const cyaml_schema_field_t test_detail_arm_mapping_schema[] = {
CYAML_FIELD_INT("vector_size", CYAML_FLAG_OPTIONAL, TestDetailARM,
vector_size),
CYAML_FIELD_STRING_PTR("vector_data",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailARM, vector_data, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("cps_mode",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailARM, cps_mode, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("cps_flag",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailARM, cps_flag, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("cc", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailARM, cc, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("vcc", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailARM, vcc, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("mem_barrier",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailARM, mem_barrier, 0, CYAML_UNLIMITED),
CYAML_FIELD_UINT("pred_mask", CYAML_FLAG_OPTIONAL, TestDetailARM,
pred_mask),
CYAML_FIELD_INT("usermode", CYAML_FLAG_OPTIONAL, TestDetailARM,
usermode),
CYAML_FIELD_INT("update_flags", CYAML_FLAG_OPTIONAL, TestDetailARM,
update_flags),
CYAML_FIELD_INT("post_indexed", CYAML_FLAG_OPTIONAL, TestDetailARM,
post_indexed),
CYAML_FIELD_SEQUENCE(
"operands", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailARM, operands, &test_detail_arm_op_schema, 0,
CYAML_UNLIMITED), // 0-MAX options
CYAML_FIELD_END
};
TestDetailARM *test_detail_arm_new();
TestDetailARM *test_detail_arm_clone(TestDetailARM *detail);
void test_detail_arm_free(TestDetailARM *detail);
TestDetailARMOp *test_detail_arm_op_new();
TestDetailARMOp *test_detail_arm_op_clone(TestDetailARMOp *detail);
void test_detail_arm_op_free(TestDetailARMOp *detail);
bool test_expected_arm(csh *handle, cs_arm *actual, TestDetailARM *expected);
#endif // TEST_DETAIL_ARM_H
@@ -0,0 +1,82 @@
// Copyright © 2024 Rot127 <unisono@quyllur.org>
// SPDX-License-Identifier: BSD-3
#ifndef TEST_DETAIL_BPF_H
#define TEST_DETAIL_BPF_H
#include "test_compare.h"
#include <cyaml/cyaml.h>
#include <capstone/capstone.h>
typedef struct {
char *type;
char *access;
char *reg;
uint64_t imm;
uint32_t off;
uint32_t mmem;
uint32_t msh;
char *ext;
char *mem_base;
uint32_t mem_disp;
tbool is_pkt;
tbool is_signed;
} TestDetailBPFOp;
static const cyaml_schema_field_t test_detail_bpf_op_mapping_schema[] = {
CYAML_FIELD_STRING_PTR("type", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailBPFOp, type, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("access",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailBPFOp, access, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("reg", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailBPFOp, reg, 0, CYAML_UNLIMITED),
CYAML_FIELD_UINT("imm", CYAML_FLAG_OPTIONAL, TestDetailBPFOp, imm),
CYAML_FIELD_UINT("off", CYAML_FLAG_OPTIONAL, TestDetailBPFOp, off),
CYAML_FIELD_UINT("mmem", CYAML_FLAG_OPTIONAL, TestDetailBPFOp, mmem),
CYAML_FIELD_UINT("msh", CYAML_FLAG_OPTIONAL, TestDetailBPFOp, msh),
CYAML_FIELD_STRING_PTR("ext", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailBPFOp, ext, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("mem_base",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailBPFOp, mem_base, 0, CYAML_UNLIMITED),
CYAML_FIELD_UINT("mem_disp", CYAML_FLAG_OPTIONAL, TestDetailBPFOp,
mem_disp),
CYAML_FIELD_TBOOL("is_pkt", CYAML_FLAG_OPTIONAL, TestDetailBPFOp,
is_pkt),
CYAML_FIELD_TBOOL("is_signed", CYAML_FLAG_OPTIONAL, TestDetailBPFOp,
is_signed),
CYAML_FIELD_END
};
static const cyaml_schema_value_t test_detail_bpf_op_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER, TestDetailBPFOp,
test_detail_bpf_op_mapping_schema),
};
typedef struct {
TestDetailBPFOp **operands;
uint32_t operands_count;
} TestDetailBPF;
static const cyaml_schema_field_t test_detail_bpf_mapping_schema[] = {
CYAML_FIELD_SEQUENCE(
"operands", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailBPF, operands, &test_detail_bpf_op_schema, 0,
CYAML_UNLIMITED), // 0-MAX options
CYAML_FIELD_END
};
TestDetailBPF *test_detail_bpf_new();
TestDetailBPF *test_detail_bpf_clone(const TestDetailBPF *detail);
void test_detail_bpf_free(TestDetailBPF *detail);
TestDetailBPFOp *test_detail_bpf_op_new();
TestDetailBPFOp *test_detail_bpf_op_clone(const TestDetailBPFOp *detail);
void test_detail_bpf_op_free(TestDetailBPFOp *detail);
bool test_expected_bpf(csh *handle, const cs_bpf *actual,
const TestDetailBPF *expected);
#endif // TEST_DETAIL_BPF_H
@@ -0,0 +1,30 @@
// Copyright © 2024 Rot127 <unisono@quyllur.org>
// SPDX-License-Identifier: BSD-3
#ifndef TEST_DETAIL_EVM_H
#define TEST_DETAIL_EVM_H
#include <cyaml/cyaml.h>
#include <capstone/capstone.h>
typedef struct {
unsigned char pop;
unsigned char push;
unsigned int fee;
} TestDetailEVM;
static const cyaml_schema_field_t test_detail_evm_mapping_schema[] = {
CYAML_FIELD_UINT("pop", CYAML_FLAG_OPTIONAL, TestDetailEVM, pop),
CYAML_FIELD_UINT("push", CYAML_FLAG_OPTIONAL, TestDetailEVM, push),
CYAML_FIELD_UINT("fee", CYAML_FLAG_OPTIONAL, TestDetailEVM, fee),
CYAML_FIELD_END
};
TestDetailEVM *test_detail_evm_new();
TestDetailEVM *test_detail_evm_clone(const TestDetailEVM *detail);
void test_detail_evm_free(TestDetailEVM *detail);
bool test_expected_evm(csh *handle, const cs_evm *actual,
const TestDetailEVM *expected);
#endif // TEST_DETAIL_EVM_H
@@ -0,0 +1,72 @@
// Copyright © 2024 Rot127 <unisono@quyllur.org>
// SPDX-License-Identifier: BSD-3
#ifndef TEST_DETAIL_HPPA_H
#define TEST_DETAIL_HPPA_H
#include "test_compare.h"
#include <cyaml/cyaml.h>
#include <capstone/capstone.h>
typedef struct {
char *type;
char *access;
char *reg;
int64_t imm;
char *mem_base;
char *mem_space;
char *mem_base_access;
} TestDetailHPPAOp;
static const cyaml_schema_field_t test_detail_hppa_op_mapping_schema[] = {
CYAML_FIELD_STRING_PTR("type", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailHPPAOp, type, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("access",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailHPPAOp, access, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("reg", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailHPPAOp, reg, 0, CYAML_UNLIMITED),
CYAML_FIELD_INT("imm", CYAML_FLAG_OPTIONAL, TestDetailHPPAOp, imm),
CYAML_FIELD_STRING_PTR("mem_base",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailHPPAOp, mem_base, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("mem_space",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailHPPAOp, mem_space, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR(
"mem_base_access", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailHPPAOp, mem_base_access, 0, CYAML_UNLIMITED),
CYAML_FIELD_END
};
static const cyaml_schema_value_t test_detail_hppa_op_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER, TestDetailHPPAOp,
test_detail_hppa_op_mapping_schema),
};
typedef struct {
TestDetailHPPAOp **operands;
uint32_t operands_count;
} TestDetailHPPA;
static const cyaml_schema_field_t test_detail_hppa_mapping_schema[] = {
CYAML_FIELD_SEQUENCE(
"operands", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailHPPA, operands, &test_detail_hppa_op_schema, 0,
CYAML_UNLIMITED), // 0-MAX options
CYAML_FIELD_END
};
TestDetailHPPA *test_detail_hppa_new();
TestDetailHPPA *test_detail_hppa_clone(const TestDetailHPPA *detail);
void test_detail_hppa_free(TestDetailHPPA *detail);
TestDetailHPPAOp *test_detail_hppa_op_new();
TestDetailHPPAOp *test_detail_hppa_op_clone(const TestDetailHPPAOp *detail);
void test_detail_hppa_op_free(TestDetailHPPAOp *detail);
bool test_expected_hppa(csh *handle, const cs_hppa *actual,
const TestDetailHPPA *expected);
#endif // TEST_DETAIL_HPPA_H
@@ -0,0 +1,77 @@
// Copyright © 2024 Rot127 <unisono@quyllur.org>
// SPDX-License-Identifier: BSD-3
#ifndef TEST_DETAIL_LOONGARCH_H
#define TEST_DETAIL_LOONGARCH_H
#include <cyaml/cyaml.h>
#include <capstone/capstone.h>
typedef struct {
char *type;
char *access;
char *reg;
uint64_t imm;
char *mem_base;
char *mem_index;
int64_t mem_disp;
} TestDetailLoongArchOp;
static const cyaml_schema_field_t test_detail_loongarch_op_mapping_schema[] = {
CYAML_FIELD_STRING_PTR("type", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailLoongArchOp, type, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR(
"access", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailLoongArchOp, access, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("reg", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailLoongArchOp, reg, 0, CYAML_UNLIMITED),
CYAML_FIELD_INT("imm", CYAML_FLAG_OPTIONAL, TestDetailLoongArchOp, imm),
CYAML_FIELD_STRING_PTR(
"mem_base", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailLoongArchOp, mem_base, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR(
"mem_index", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailLoongArchOp, mem_index, 0, CYAML_UNLIMITED),
CYAML_FIELD_INT("mem_disp", CYAML_FLAG_OPTIONAL, TestDetailLoongArchOp,
mem_disp),
CYAML_FIELD_END
};
static const cyaml_schema_value_t test_detail_loongarch_op_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER, TestDetailLoongArchOp,
test_detail_loongarch_op_mapping_schema),
};
typedef struct {
char *format;
TestDetailLoongArchOp **operands;
uint32_t operands_count;
} TestDetailLoongArch;
static const cyaml_schema_field_t test_detail_loongarch_mapping_schema[] = {
CYAML_FIELD_STRING_PTR("format",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailLoongArch, format, 0, CYAML_UNLIMITED),
CYAML_FIELD_SEQUENCE("operands",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailLoongArch, operands,
&test_detail_loongarch_op_schema, 0,
CYAML_UNLIMITED), // 0-MAX options
CYAML_FIELD_END
};
TestDetailLoongArch *test_detail_loongarch_new();
TestDetailLoongArch *
test_detail_loongarch_clone(const TestDetailLoongArch *detail);
void test_detail_loongarch_free(TestDetailLoongArch *detail);
TestDetailLoongArchOp *test_detail_loongarch_op_new();
TestDetailLoongArchOp *
test_detail_loongarch_op_clone(const TestDetailLoongArchOp *detail);
void test_detail_loongarch_op_free(TestDetailLoongArchOp *detail);
bool test_expected_loongarch(csh *handle, const cs_loongarch *actual,
const TestDetailLoongArch *expected);
#endif // TEST_DETAIL_LOONGARCH_H
@@ -0,0 +1,133 @@
// Copyright © 2024 Rot127 <unisono@quyllur.org>
// SPDX-License-Identifier: BSD-3
#ifndef TEST_DETAIL_M680X_H
#define TEST_DETAIL_M680X_H
#include "test_compare.h"
#include <cyaml/cyaml.h>
#include <capstone/capstone.h>
typedef struct {
char *base_reg;
char *offset_reg;
int16_t offset;
uint16_t offset_addr;
uint8_t offset_bits;
int8_t inc_dec;
char **flags;
uint32_t flags_count;
} TestDetailM680xIdx;
static const cyaml_schema_value_t flag_schema = {
CYAML_VALUE_STRING(CYAML_FLAG_POINTER, char, 0, CYAML_UNLIMITED),
};
static const cyaml_schema_field_t test_detail_m680x_idx_mapping_schema[] = {
CYAML_FIELD_STRING_PTR(
"base_reg", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailM680xIdx, base_reg, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR(
"offset_reg", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailM680xIdx, offset_reg, 0, CYAML_UNLIMITED),
CYAML_FIELD_INT("offset", CYAML_FLAG_OPTIONAL, TestDetailM680xIdx,
offset),
CYAML_FIELD_UINT("offset_addr", CYAML_FLAG_OPTIONAL, TestDetailM680xIdx,
offset_addr),
CYAML_FIELD_UINT("offset_bits", CYAML_FLAG_OPTIONAL, TestDetailM680xIdx,
offset_bits),
CYAML_FIELD_INT("inc_dec", CYAML_FLAG_OPTIONAL, TestDetailM680xIdx,
inc_dec),
CYAML_FIELD_SEQUENCE("flags", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailM680xIdx, flags, &flag_schema, 0,
CYAML_UNLIMITED), // 0-MAX flags
CYAML_FIELD_END
};
typedef struct {
char *type;
char *access;
TestDetailM680xIdx *idx;
char *reg;
int32_t imm;
uint16_t rel_address;
uint16_t ext_address;
int16_t rel_offset;
tbool ext_indirect;
uint8_t direct_addr;
bool direct_addr_set;
uint8_t const_val;
uint8_t size;
} TestDetailM680xOp;
static const cyaml_schema_field_t test_detail_m680x_op_mapping_schema[] = {
CYAML_FIELD_STRING_PTR("type", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailM680xOp, type, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("access",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailM680xOp, access, 0, CYAML_UNLIMITED),
CYAML_FIELD_MAPPING_PTR("idx", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailM680xOp, idx,
test_detail_m680x_idx_mapping_schema),
CYAML_FIELD_STRING_PTR("reg", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailM680xOp, reg, 0, CYAML_UNLIMITED),
CYAML_FIELD_INT("imm", CYAML_FLAG_OPTIONAL, TestDetailM680xOp, imm),
CYAML_FIELD_UINT("rel_address", CYAML_FLAG_OPTIONAL, TestDetailM680xOp,
rel_address),
CYAML_FIELD_UINT("ext_address", CYAML_FLAG_OPTIONAL, TestDetailM680xOp,
ext_address),
CYAML_FIELD_INT("rel_offset", CYAML_FLAG_OPTIONAL, TestDetailM680xOp,
rel_offset),
CYAML_FIELD_INT("ext_indirect", CYAML_FLAG_OPTIONAL, TestDetailM680xOp,
ext_indirect),
CYAML_FIELD_UINT("direct_addr", CYAML_FLAG_OPTIONAL, TestDetailM680xOp,
direct_addr),
CYAML_FIELD_BOOL("direct_addr_set", CYAML_FLAG_OPTIONAL,
TestDetailM680xOp, direct_addr_set),
CYAML_FIELD_UINT("const_val", CYAML_FLAG_OPTIONAL, TestDetailM680xOp,
const_val),
CYAML_FIELD_UINT("size", CYAML_FLAG_OPTIONAL, TestDetailM680xOp, size),
CYAML_FIELD_END
};
static const cyaml_schema_value_t test_detail_m680x_op_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER, TestDetailM680xOp,
test_detail_m680x_op_mapping_schema),
};
typedef struct {
char **flags;
size_t flags_count;
TestDetailM680xOp **operands;
uint32_t operands_count;
} TestDetailM680x;
static const cyaml_schema_field_t test_detail_m680x_mapping_schema[] = {
CYAML_FIELD_SEQUENCE("flags", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailM680x, flags, &flag_schema, 0,
CYAML_UNLIMITED), // 0-MAX flags
CYAML_FIELD_SEQUENCE(
"operands", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailM680x, operands, &test_detail_m680x_op_schema, 0,
CYAML_UNLIMITED), // 0-MAX options
CYAML_FIELD_END
};
TestDetailM680x *test_detail_m680x_new();
TestDetailM680x *test_detail_m680x_clone(const TestDetailM680x *detail);
void test_detail_m680x_free(TestDetailM680x *detail);
TestDetailM680xOp *test_detail_m680x_op_new();
TestDetailM680xOp *test_detail_m680x_op_clone(const TestDetailM680xOp *detail);
void test_detail_m680x_op_free(TestDetailM680xOp *detail);
TestDetailM680xIdx *test_detail_m680x_idx_new();
TestDetailM680xIdx *
test_detail_m680x_idx_clone(const TestDetailM680xIdx *detail);
void test_detail_m680x_idx_free(TestDetailM680xIdx *detail);
bool test_expected_m680x(csh *handle, const cs_m680x *actual,
const TestDetailM680x *expected);
#endif // TEST_DETAIL_M680X_H
@@ -0,0 +1,151 @@
// Copyright © 2024 Rot127 <unisono@quyllur.org>
// SPDX-License-Identifier: BSD-3
#ifndef TEST_DETAIL_M68K_H
#define TEST_DETAIL_M68K_H
#include "test_compare.h"
#include <cyaml/cyaml.h>
#include <capstone/capstone.h>
typedef struct {
char *base_reg;
char *index_reg;
char *in_base_reg;
tbool index_size; // -1 == word, 1 == long
int16_t disp;
uint32_t in_disp;
uint32_t out_disp;
uint8_t scale;
uint8_t bitfield;
uint8_t width;
uint8_t offset;
} TestDetailM68KOpMem;
static const cyaml_schema_field_t test_detail_m68k_op_mem_mapping_schema[] = {
CYAML_FIELD_INT("disp", CYAML_FLAG_OPTIONAL, TestDetailM68KOpMem, disp),
CYAML_FIELD_STRING_PTR(
"base_reg", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailM68KOpMem, base_reg, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR(
"index_reg", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailM68KOpMem, index_reg, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR(
"in_base_reg", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailM68KOpMem, in_base_reg, 0, CYAML_UNLIMITED),
CYAML_FIELD_INT("index_size", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailM68KOpMem, index_size),
CYAML_FIELD_INT("disp", CYAML_FLAG_OPTIONAL, TestDetailM68KOpMem, disp),
CYAML_FIELD_UINT("in_disp", CYAML_FLAG_OPTIONAL, TestDetailM68KOpMem,
in_disp),
CYAML_FIELD_UINT("out_disp", CYAML_FLAG_OPTIONAL, TestDetailM68KOpMem,
out_disp),
CYAML_FIELD_UINT("scale", CYAML_FLAG_OPTIONAL, TestDetailM68KOpMem,
scale),
CYAML_FIELD_UINT("bitfield", CYAML_FLAG_OPTIONAL, TestDetailM68KOpMem,
bitfield),
CYAML_FIELD_UINT("width", CYAML_FLAG_OPTIONAL, TestDetailM68KOpMem,
width),
CYAML_FIELD_UINT("offset", CYAML_FLAG_OPTIONAL, TestDetailM68KOpMem,
offset),
CYAML_FIELD_END
};
typedef struct {
char *type;
char *address_mode;
char *reg;
char *reg_pair_0;
char *reg_pair_1;
uint64_t imm;
int32_t br_disp;
uint8_t br_disp_size;
uint32_t register_bits;
double dimm;
float simm;
TestDetailM68KOpMem *mem;
} TestDetailM68KOp;
static const cyaml_schema_value_t test_detail_m68k_op_sys_psr_schema = {
CYAML_VALUE_STRING(CYAML_FLAG_POINTER, char, 0, CYAML_UNLIMITED),
};
static const cyaml_schema_field_t test_detail_m68k_op_mapping_schema[] = {
CYAML_FIELD_STRING_PTR("type", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailM68KOp, type, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR(
"address_mode", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailM68KOp, address_mode, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("reg", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailM68KOp, reg, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR(
"reg_pair_0", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailM68KOp, reg_pair_0, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR(
"reg_pair_1", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailM68KOp, reg_pair_1, 0, CYAML_UNLIMITED),
CYAML_FIELD_INT("imm", CYAML_FLAG_OPTIONAL, TestDetailM68KOp, imm),
CYAML_FIELD_INT("br_disp", CYAML_FLAG_OPTIONAL, TestDetailM68KOp,
br_disp),
CYAML_FIELD_UINT("br_disp_size", CYAML_FLAG_OPTIONAL, TestDetailM68KOp,
br_disp_size),
CYAML_FIELD_UINT("register_bits", CYAML_FLAG_OPTIONAL, TestDetailM68KOp,
register_bits),
CYAML_FIELD_FLOAT("dimm", CYAML_FLAG_OPTIONAL, TestDetailM68KOp, dimm),
CYAML_FIELD_FLOAT("simm", CYAML_FLAG_OPTIONAL, TestDetailM68KOp, simm),
CYAML_FIELD_MAPPING_PTR("mem", CYAML_FLAG_OPTIONAL, TestDetailM68KOp,
mem, test_detail_m68k_op_mem_mapping_schema),
CYAML_FIELD_END
};
static const cyaml_schema_value_t test_detail_m68k_op_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER, TestDetailM68KOp,
test_detail_m68k_op_mapping_schema),
};
typedef struct {
char *op_size_type;
char *op_size_fpu;
char *op_size_cpu;
TestDetailM68KOp **operands;
uint32_t operands_count;
} TestDetailM68K;
static const cyaml_schema_field_t test_detail_m68k_mapping_schema[] = {
CYAML_FIELD_STRING_PTR(
"op_size_type", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailM68K, op_size_type, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("op_size_fpu",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailM68K, op_size_fpu, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("op_size_cpu",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailM68K, op_size_cpu, 0, CYAML_UNLIMITED),
CYAML_FIELD_SEQUENCE(
"operands", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailM68K, operands, &test_detail_m68k_op_schema, 0,
CYAML_UNLIMITED), // 0-MAX options
CYAML_FIELD_END
};
TestDetailM68K *test_detail_m68k_new();
TestDetailM68K *test_detail_m68k_clone(TestDetailM68K *detail);
void test_detail_m68k_free(TestDetailM68K *detail);
TestDetailM68KOp *test_detail_m68k_op_new();
TestDetailM68KOp *test_detail_m68k_op_clone(TestDetailM68KOp *detail);
void test_detail_m68k_op_free(TestDetailM68KOp *detail);
TestDetailM68KOpMem *test_detail_m68k_op_mem_new();
TestDetailM68KOpMem *test_detail_m68k_op_mem_clone(TestDetailM68KOpMem *detail);
void test_detail_m68k_op_mem_free(TestDetailM68KOpMem *detail);
bool test_expected_m68k(csh *handle, cs_m68k *actual, TestDetailM68K *expected);
#endif // TEST_DETAIL_M68K_H
@@ -0,0 +1,66 @@
// Copyright © 2024 Rot127 <unisono@quyllur.org>
// SPDX-License-Identifier: BSD-3
#ifndef TEST_DETAIL_MIPS_H
#define TEST_DETAIL_MIPS_H
#include "test_compare.h"
#include <cyaml/cyaml.h>
#include <capstone/capstone.h>
typedef struct {
char *type;
char *access;
char *reg;
uint64_t imm;
char *mem_base;
int64_t mem_disp;
} TestDetailMipsOp;
static const cyaml_schema_field_t test_detail_mips_op_mapping_schema[] = {
CYAML_FIELD_STRING_PTR("type", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailMipsOp, type, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR(
"access", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailMipsOp, access, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("reg", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailMipsOp, reg, 0, CYAML_UNLIMITED),
CYAML_FIELD_INT("imm", CYAML_FLAG_OPTIONAL, TestDetailMipsOp, imm),
CYAML_FIELD_STRING_PTR("mem_base",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailMipsOp, mem_base, 0, CYAML_UNLIMITED),
CYAML_FIELD_INT("mem_disp", CYAML_FLAG_OPTIONAL, TestDetailMipsOp,
mem_disp),
CYAML_FIELD_END
};
static const cyaml_schema_value_t test_detail_mips_op_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER, TestDetailMipsOp,
test_detail_mips_op_mapping_schema),
};
typedef struct {
TestDetailMipsOp **operands;
uint32_t operands_count;
} TestDetailMips;
static const cyaml_schema_field_t test_detail_mips_mapping_schema[] = {
CYAML_FIELD_SEQUENCE(
"operands", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailMips, operands, &test_detail_mips_op_schema, 0,
CYAML_UNLIMITED), // 0-MAX options
CYAML_FIELD_END
};
TestDetailMips *test_detail_mips_new();
TestDetailMips *test_detail_mips_clone(const TestDetailMips *detail);
void test_detail_mips_free(TestDetailMips *detail);
TestDetailMipsOp *test_detail_mips_op_new();
TestDetailMipsOp *test_detail_mips_op_clone(const TestDetailMipsOp *detail);
void test_detail_mips_op_free(TestDetailMipsOp *detail);
bool test_expected_mips(csh *handle, const cs_mips *actual,
const TestDetailMips *expected);
#endif // TEST_DETAIL_MIPS_H
@@ -0,0 +1,66 @@
// Copyright © 2024 Rot127 <unisono@quyllur.org>
// SPDX-License-Identifier: BSD-3
#ifndef TEST_DETAIL_MOS65XX_H
#define TEST_DETAIL_MOS65XX_H
#include "test_compare.h"
#include <cyaml/cyaml.h>
#include <capstone/capstone.h>
typedef struct {
char *type;
char *reg;
uint16_t imm;
uint32_t mem;
} TestDetailMos65xxOp;
static const cyaml_schema_field_t test_detail_mos65xx_op_mapping_schema[] = {
CYAML_FIELD_STRING_PTR("type", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailMos65xxOp, type, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("reg", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailMos65xxOp, reg, 0, CYAML_UNLIMITED),
CYAML_FIELD_UINT("imm", CYAML_FLAG_OPTIONAL, TestDetailMos65xxOp, imm),
CYAML_FIELD_UINT("mem", CYAML_FLAG_OPTIONAL, TestDetailMos65xxOp, mem),
CYAML_FIELD_END
};
static const cyaml_schema_value_t test_detail_mos65xx_op_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER, TestDetailMos65xxOp,
test_detail_mos65xx_op_mapping_schema),
};
typedef struct {
char *am;
tbool modifies_flags;
TestDetailMos65xxOp **operands;
uint32_t operands_count;
} TestDetailMos65xx;
static const cyaml_schema_field_t test_detail_mos65xx_mapping_schema[] = {
CYAML_FIELD_STRING_PTR("am", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailMos65xx, am, 0, CYAML_UNLIMITED),
CYAML_FIELD_INT("modifies_flags", CYAML_FLAG_OPTIONAL,
TestDetailMos65xx, modifies_flags),
CYAML_FIELD_SEQUENCE(
"operands", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailMos65xx, operands, &test_detail_mos65xx_op_schema, 0,
CYAML_UNLIMITED), // 0-MAX options
CYAML_FIELD_END
};
TestDetailMos65xx *test_detail_mos65xx_new();
TestDetailMos65xx *test_detail_mos65xx_clone(const TestDetailMos65xx *detail);
void test_detail_mos65xx_free(TestDetailMos65xx *detail);
TestDetailMos65xxOp *test_detail_mos65xx_op_new();
TestDetailMos65xxOp *
test_detail_mos65xx_op_clone(const TestDetailMos65xxOp *detail);
void test_detail_mos65xx_op_free(TestDetailMos65xxOp *detail);
bool test_expected_mos65xx(csh *handle, const cs_mos65xx *actual,
const TestDetailMos65xx *expected);
#endif // TEST_DETAIL_MOS65XX_H
+124
View File
@@ -0,0 +1,124 @@
// Copyright © 2024 Rot127 <unisono@quyllur.org>
// SPDX-License-Identifier: BSD-3
#ifndef TEST_DETAIL_PPC_H
#define TEST_DETAIL_PPC_H
#include "test_compare.h"
#include <cyaml/cyaml.h>
#include <capstone/capstone.h>
typedef struct {
char *type;
char *access;
char *reg;
int64_t imm;
char *mem_base;
char *mem_offset;
int32_t mem_disp;
} TestDetailPPCOp;
static const cyaml_schema_field_t test_detail_ppc_op_mapping_schema[] = {
CYAML_FIELD_STRING_PTR("type", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailPPCOp, type, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("access",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailPPCOp, access, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("reg", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailPPCOp, reg, 0, CYAML_UNLIMITED),
CYAML_FIELD_INT("imm", CYAML_FLAG_OPTIONAL, TestDetailPPCOp, imm),
CYAML_FIELD_STRING_PTR("mem_base",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailPPCOp, mem_base, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("mem_offset",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailPPCOp, mem_offset, 0, CYAML_UNLIMITED),
CYAML_FIELD_INT("mem_disp", CYAML_FLAG_OPTIONAL, TestDetailPPCOp,
mem_disp),
CYAML_FIELD_END
};
static const cyaml_schema_value_t test_detail_ppc_op_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER, TestDetailPPCOp,
test_detail_ppc_op_mapping_schema),
};
typedef struct {
uint8_t bo;
bool bo_set;
uint8_t bi;
bool bi_set;
char *crX_bit;
char *crX;
char *hint;
char *pred_cr;
char *pred_ctr;
char *bh;
} TestDetailPPCBC;
static const cyaml_schema_field_t test_detail_ppc_bc_mapping_schema[] = {
CYAML_FIELD_INT("bi", CYAML_FLAG_OPTIONAL, TestDetailPPCBC, bi),
CYAML_FIELD_BOOL("bi_set", CYAML_FLAG_OPTIONAL, TestDetailPPCBC,
bi_set),
CYAML_FIELD_INT("bo", CYAML_FLAG_OPTIONAL, TestDetailPPCBC, bo),
CYAML_FIELD_BOOL("bo_set", CYAML_FLAG_OPTIONAL, TestDetailPPCBC,
bo_set),
CYAML_FIELD_STRING_PTR("crX_bit",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailPPCBC, crX_bit, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("crX", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailPPCBC, crX, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("hint", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailPPCBC, hint, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("pred_cr",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailPPCBC, pred_cr, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("pred_ctr",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailPPCBC, pred_ctr, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("bh", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailPPCBC, bh, 0, CYAML_UNLIMITED),
CYAML_FIELD_END
};
typedef struct {
TestDetailPPCBC *bc;
tbool update_cr0;
char *format;
TestDetailPPCOp **operands;
uint32_t operands_count;
} TestDetailPPC;
static const cyaml_schema_field_t test_detail_ppc_mapping_schema[] = {
CYAML_FIELD_MAPPING_PTR("bc", CYAML_FLAG_OPTIONAL, TestDetailPPC, bc,
test_detail_ppc_bc_mapping_schema),
CYAML_FIELD_STRING_PTR("format",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailPPC, format, 0, CYAML_UNLIMITED),
CYAML_FIELD_INT("update_cr0", CYAML_FLAG_OPTIONAL, TestDetailPPC,
update_cr0),
CYAML_FIELD_SEQUENCE(
"operands", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailPPC, operands, &test_detail_ppc_op_schema, 0,
CYAML_UNLIMITED), // 0-MAX options
CYAML_FIELD_END
};
TestDetailPPC *test_detail_ppc_new();
TestDetailPPC *test_detail_ppc_clone(const TestDetailPPC *detail);
void test_detail_ppc_free(TestDetailPPC *detail);
TestDetailPPCOp *test_detail_ppc_op_new();
TestDetailPPCOp *test_detail_ppc_op_clone(const TestDetailPPCOp *detail);
void test_detail_ppc_op_free(TestDetailPPCOp *detail);
TestDetailPPCBC *test_detail_ppc_bc_new();
TestDetailPPCBC *test_detail_ppc_bc_clone(const TestDetailPPCBC *detail);
void test_detail_ppc_bc_free(TestDetailPPCBC *detail);
bool test_expected_ppc(csh *handle, const cs_ppc *actual,
const TestDetailPPC *expected);
#endif // TEST_DETAIL_PPC_H
@@ -0,0 +1,67 @@
// Copyright © 2024 Rot127 <unisono@quyllur.org>
// SPDX-License-Identifier: BSD-3
#ifndef TEST_DETAIL_RISCV_H
#define TEST_DETAIL_RISCV_H
#include "test_compare.h"
#include <cyaml/cyaml.h>
#include <capstone/capstone.h>
typedef struct {
char *type;
char *access;
char *reg;
uint64_t imm;
char *mem_base;
int64_t mem_disp;
} TestDetailRISCVOp;
static const cyaml_schema_field_t test_detail_riscv_op_mapping_schema[] = {
CYAML_FIELD_STRING_PTR("type", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailRISCVOp, type, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("access",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailRISCVOp, access, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("reg", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailRISCVOp, reg, 0, CYAML_UNLIMITED),
CYAML_FIELD_INT("imm", CYAML_FLAG_OPTIONAL, TestDetailRISCVOp, imm),
CYAML_FIELD_STRING_PTR("mem_base",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailRISCVOp, mem_base, 0, CYAML_UNLIMITED),
CYAML_FIELD_INT("mem_disp", CYAML_FLAG_OPTIONAL, TestDetailRISCVOp,
mem_disp),
CYAML_FIELD_END
};
static const cyaml_schema_value_t test_detail_riscv_op_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER, TestDetailRISCVOp,
test_detail_riscv_op_mapping_schema),
};
typedef struct {
TestDetailRISCVOp **operands;
uint32_t operands_count;
} TestDetailRISCV;
static const cyaml_schema_field_t test_detail_riscv_mapping_schema[] = {
CYAML_FIELD_SEQUENCE(
"operands", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailRISCV, operands, &test_detail_riscv_op_schema, 0,
CYAML_UNLIMITED), // 0-MAX options
CYAML_FIELD_END
};
TestDetailRISCV *test_detail_riscv_new();
TestDetailRISCV *test_detail_riscv_clone(const TestDetailRISCV *detail);
void test_detail_riscv_free(TestDetailRISCV *detail);
TestDetailRISCVOp *test_detail_riscv_op_new();
TestDetailRISCVOp *test_detail_riscv_op_clone(const TestDetailRISCVOp *detail);
void test_detail_riscv_op_free(TestDetailRISCVOp *detail);
bool test_expected_riscv(csh *handle, const cs_riscv *actual,
const TestDetailRISCV *expected);
#endif // TEST_DETAIL_RISCV_H
+67
View File
@@ -0,0 +1,67 @@
// Copyright © 2024 Rot127 <unisono@quyllur.org>
// SPDX-License-Identifier: BSD-3
#ifndef TEST_DETAIL_SH_H
#define TEST_DETAIL_SH_H
#include "test_compare.h"
#include <cyaml/cyaml.h>
#include <capstone/capstone.h>
typedef struct {
char *type;
char *reg;
uint64_t imm;
char *mem_reg;
char *mem_address;
int32_t mem_disp;
} TestDetailSHOp;
static const cyaml_schema_field_t test_detail_sh_op_mapping_schema[] = {
CYAML_FIELD_STRING_PTR("type", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailSHOp, type, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("reg", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailSHOp, reg, 0, CYAML_UNLIMITED),
CYAML_FIELD_INT("imm", CYAML_FLAG_OPTIONAL, TestDetailSHOp, imm),
CYAML_FIELD_STRING_PTR("mem_reg",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailSHOp, mem_reg, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("mem_address",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailSHOp, mem_address, 0, CYAML_UNLIMITED),
CYAML_FIELD_INT("mem_disp", CYAML_FLAG_OPTIONAL, TestDetailSHOp,
mem_disp),
CYAML_FIELD_END
};
static const cyaml_schema_value_t test_detail_sh_op_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER, TestDetailSHOp,
test_detail_sh_op_mapping_schema),
};
typedef struct {
TestDetailSHOp **operands;
uint32_t operands_count;
} TestDetailSH;
static const cyaml_schema_field_t test_detail_sh_mapping_schema[] = {
CYAML_FIELD_SEQUENCE(
"operands", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailSH, operands, &test_detail_sh_op_schema, 0,
CYAML_UNLIMITED), // 0-MAX options
CYAML_FIELD_END
};
TestDetailSH *test_detail_sh_new();
TestDetailSH *test_detail_sh_clone(const TestDetailSH *detail);
void test_detail_sh_free(TestDetailSH *detail);
TestDetailSHOp *test_detail_sh_op_new();
TestDetailSHOp *test_detail_sh_op_clone(const TestDetailSHOp *detail);
void test_detail_sh_op_free(TestDetailSHOp *detail);
bool test_expected_sh(csh *handle, const cs_sh *actual,
const TestDetailSH *expected);
#endif // TEST_DETAIL_SH_H
@@ -0,0 +1,87 @@
// Copyright © 2024 Rot127 <unisono@quyllur.org>
// SPDX-License-Identifier: BSD-3
#ifndef TEST_DETAIL_SPARC_H
#define TEST_DETAIL_SPARC_H
#include "test_compare.h"
#include <cyaml/cyaml.h>
#include <capstone/capstone.h>
typedef struct {
char *type;
char *access;
char *reg;
int64_t imm;
char *mem_base;
char *mem_index;
int32_t mem_disp;
char *asi;
char *membar_tag;
} TestDetailSparcOp;
static const cyaml_schema_field_t test_detail_sparc_op_mapping_schema[] = {
CYAML_FIELD_STRING_PTR("type", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailSparcOp, type, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("access", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailSparcOp, access, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("reg", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailSparcOp, reg, 0, CYAML_UNLIMITED),
CYAML_FIELD_INT("imm", CYAML_FLAG_OPTIONAL, TestDetailSparcOp, imm),
CYAML_FIELD_STRING_PTR("mem_base",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailSparcOp, mem_base, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR(
"mem_index", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailSparcOp, mem_index, 0, CYAML_UNLIMITED),
CYAML_FIELD_INT("mem_disp", CYAML_FLAG_OPTIONAL, TestDetailSparcOp,
mem_disp),
CYAML_FIELD_STRING_PTR("asi",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailSparcOp, asi, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("membar_tag",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailSparcOp, membar_tag, 0, CYAML_UNLIMITED),
CYAML_FIELD_END
};
static const cyaml_schema_value_t test_detail_sparc_op_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER, TestDetailSparcOp,
test_detail_sparc_op_mapping_schema),
};
typedef struct {
char *cc;
char *cc_field;
char *hint;
TestDetailSparcOp **operands;
uint32_t operands_count;
} TestDetailSparc;
static const cyaml_schema_field_t test_detail_sparc_mapping_schema[] = {
CYAML_FIELD_STRING_PTR("cc", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailSparc, cc, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("cc_field", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailSparc, cc_field, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("hint", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailSparc, hint, 0, CYAML_UNLIMITED),
CYAML_FIELD_SEQUENCE(
"operands", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailSparc, operands, &test_detail_sparc_op_schema, 0,
CYAML_UNLIMITED), // 0-MAX options
CYAML_FIELD_END
};
TestDetailSparc *test_detail_sparc_new();
TestDetailSparc *test_detail_sparc_clone(const TestDetailSparc *detail);
void test_detail_sparc_free(TestDetailSparc *detail);
TestDetailSparcOp *test_detail_sparc_op_new();
TestDetailSparcOp *test_detail_sparc_op_clone(const TestDetailSparcOp *detail);
void test_detail_sparc_op_free(TestDetailSparcOp *detail);
bool test_expected_sparc(csh *handle, const cs_sparc *actual,
const TestDetailSparc *expected);
#endif // TEST_DETAIL_SPARC_H
@@ -0,0 +1,85 @@
// Copyright © 2024 Rot127 <unisono@quyllur.org>
// SPDX-License-Identifier: BSD-3
#ifndef TEST_DETAIL_SYSTEMZ_H
#define TEST_DETAIL_SYSTEMZ_H
#include "test_compare.h"
#include <cyaml/cyaml.h>
#include <capstone/capstone.h>
typedef struct {
char *type;
char *access;
char *reg;
int64_t imm;
uint8_t imm_width;
char *mem_am;
char *mem_base;
char *mem_index;
int64_t mem_disp;
uint64_t mem_length;
} TestDetailSystemZOp;
static const cyaml_schema_field_t test_detail_systemz_op_mapping_schema[] = {
CYAML_FIELD_STRING_PTR("type", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailSystemZOp, type, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("access", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailSystemZOp, access, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("reg", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailSystemZOp, reg, 0, CYAML_UNLIMITED),
CYAML_FIELD_INT("imm", CYAML_FLAG_OPTIONAL, TestDetailSystemZOp, imm),
CYAML_FIELD_UINT("imm_width", CYAML_FLAG_OPTIONAL, TestDetailSystemZOp,
imm_width),
CYAML_FIELD_STRING_PTR(
"mem_am", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailSystemZOp, mem_am, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR(
"mem_base", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailSystemZOp, mem_base, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR(
"mem_index", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailSystemZOp, mem_index, 0, CYAML_UNLIMITED),
CYAML_FIELD_INT("mem_disp", CYAML_FLAG_OPTIONAL, TestDetailSystemZOp,
mem_disp),
CYAML_FIELD_INT("mem_length", CYAML_FLAG_OPTIONAL, TestDetailSystemZOp,
mem_length),
CYAML_FIELD_END
};
static const cyaml_schema_value_t test_detail_systemz_op_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER, TestDetailSystemZOp,
test_detail_systemz_op_mapping_schema),
};
typedef struct {
char *format;
TestDetailSystemZOp **operands;
uint32_t operands_count;
} TestDetailSystemZ;
static const cyaml_schema_field_t test_detail_systemz_mapping_schema[] = {
CYAML_FIELD_STRING_PTR(
"format", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailSystemZ, format, 0, CYAML_UNLIMITED),
CYAML_FIELD_SEQUENCE(
"operands", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailSystemZ, operands, &test_detail_systemz_op_schema, 0,
CYAML_UNLIMITED), // 0-MAX options
CYAML_FIELD_END
};
TestDetailSystemZ *test_detail_systemz_new();
TestDetailSystemZ *test_detail_systemz_clone(const TestDetailSystemZ *detail);
void test_detail_systemz_free(TestDetailSystemZ *detail);
TestDetailSystemZOp *test_detail_systemz_op_new();
TestDetailSystemZOp *
test_detail_systemz_op_clone(const TestDetailSystemZOp *detail);
void test_detail_systemz_op_free(TestDetailSystemZOp *detail);
bool test_expected_systemz(csh *handle, const cs_systemz *actual,
const TestDetailSystemZ *expected);
#endif // TEST_DETAIL_SYSTEMZ_H
@@ -0,0 +1,134 @@
// Copyright © 2024 Rot127 <unisono@quyllur.org>
// SPDX-License-Identifier: BSD-3
#ifndef TEST_DETAIL_TMS320C64X_H
#define TEST_DETAIL_TMS320C64X_H
#include "test_compare.h"
#include <cyaml/cyaml.h>
#include <capstone/capstone.h>
typedef struct {
char *type;
char *reg;
char *reg_pair_0;
char *reg_pair_1;
int32_t imm;
char *mem_base;
tbool mem_scaled;
char *mem_disptype;
char *mem_direction;
char *mem_modify;
char *mem_disp_reg;
unsigned int mem_disp_const;
unsigned int mem_unit;
} TestDetailTMS320c64xOp;
static const cyaml_schema_value_t test_detail_tms320c64x_op_sys_psr_schema = {
CYAML_VALUE_STRING(CYAML_FLAG_POINTER, char, 0, CYAML_UNLIMITED),
};
static const cyaml_schema_field_t test_detail_tms320c64x_op_mapping_schema[] = {
CYAML_FIELD_STRING_PTR("type", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailTMS320c64xOp, type, 0,
CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("reg", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailTMS320c64xOp, reg, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR(
"reg_pair_0", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailTMS320c64xOp, reg_pair_0, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR(
"reg_pair_1", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailTMS320c64xOp, reg_pair_1, 0, CYAML_UNLIMITED),
CYAML_FIELD_INT("imm", CYAML_FLAG_OPTIONAL, TestDetailTMS320c64xOp,
imm),
CYAML_FIELD_INT("mem_scaled", CYAML_FLAG_OPTIONAL,
TestDetailTMS320c64xOp, mem_scaled),
CYAML_FIELD_STRING_PTR(
"mem_base", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailTMS320c64xOp, mem_base, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR(
"mem_disptype", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailTMS320c64xOp, mem_disptype, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR(
"mem_direction", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailTMS320c64xOp, mem_direction, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR(
"mem_modify", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailTMS320c64xOp, mem_modify, 0, CYAML_UNLIMITED),
CYAML_FIELD_UINT("mem_disp_const", CYAML_FLAG_OPTIONAL,
TestDetailTMS320c64xOp, mem_disp_const),
CYAML_FIELD_STRING_PTR(
"mem_disp_reg", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailTMS320c64xOp, mem_disp_reg, 0, CYAML_UNLIMITED),
CYAML_FIELD_UINT("mem_unit", CYAML_FLAG_OPTIONAL,
TestDetailTMS320c64xOp, mem_unit),
CYAML_FIELD_END
};
static const cyaml_schema_value_t test_detail_tms320c64x_op_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER, TestDetailTMS320c64xOp,
test_detail_tms320c64x_op_mapping_schema),
};
typedef struct {
char *cond_reg;
tbool cond_zero;
char *funit_unit;
uint8_t funit_side;
bool funit_side_set;
uint8_t funit_crosspath;
bool funit_crosspath_set;
int8_t parallel;
bool parallel_set;
TestDetailTMS320c64xOp **operands;
uint32_t operands_count;
} TestDetailTMS320c64x;
static const cyaml_schema_field_t test_detail_tms320c64x_mapping_schema[] = {
CYAML_FIELD_STRING_PTR(
"cond_reg", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailTMS320c64x, cond_reg, 0, CYAML_UNLIMITED),
CYAML_FIELD_INT("cond_zero", CYAML_FLAG_OPTIONAL, TestDetailTMS320c64x,
cond_zero),
CYAML_FIELD_STRING_PTR(
"funit_unit", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailTMS320c64x, funit_unit, 0, CYAML_UNLIMITED),
CYAML_FIELD_UINT("funit_side", CYAML_FLAG_OPTIONAL,
TestDetailTMS320c64x, funit_side),
CYAML_FIELD_BOOL("funit_side_set", CYAML_FLAG_OPTIONAL,
TestDetailTMS320c64x, funit_side_set),
CYAML_FIELD_UINT("funit_crosspath", CYAML_FLAG_OPTIONAL,
TestDetailTMS320c64x, funit_crosspath),
CYAML_FIELD_BOOL("funit_crosspath_set", CYAML_FLAG_OPTIONAL,
TestDetailTMS320c64x, funit_crosspath_set),
CYAML_FIELD_INT("parallel", CYAML_FLAG_OPTIONAL, TestDetailTMS320c64x,
parallel),
CYAML_FIELD_BOOL("parallel_set", CYAML_FLAG_OPTIONAL,
TestDetailTMS320c64x, parallel_set),
CYAML_FIELD_SEQUENCE("operands",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailTMS320c64x, operands,
&test_detail_tms320c64x_op_schema, 0,
CYAML_UNLIMITED), // 0-MAX options
CYAML_FIELD_END
};
TestDetailTMS320c64x *test_detail_tms320c64x_new();
TestDetailTMS320c64x *
test_detail_tms320c64x_clone(TestDetailTMS320c64x *detail);
void test_detail_tms320c64x_free(TestDetailTMS320c64x *detail);
TestDetailTMS320c64xOp *test_detail_tms320c64x_op_new();
TestDetailTMS320c64xOp *
test_detail_tms320c64x_op_clone(TestDetailTMS320c64xOp *detail);
void test_detail_tms320c64x_op_free(TestDetailTMS320c64xOp *detail);
bool test_expected_tms320c64x(csh *handle, cs_tms320c64x *actual,
TestDetailTMS320c64x *expected);
#endif // TEST_DETAIL_TMS320C64X_H
@@ -0,0 +1,71 @@
// Copyright © 2024 Rot127 <unisono@quyllur.org>
// SPDX-License-Identifier: BSD-3
#ifndef TEST_DETAIL_TRICORE_H
#define TEST_DETAIL_TRICORE_H
#include "test_compare.h"
#include <cyaml/cyaml.h>
#include <capstone/capstone.h>
typedef struct {
char *type;
char *access;
char *reg;
int64_t imm;
char *mem_base;
int64_t mem_disp;
} TestDetailTriCoreOp;
static const cyaml_schema_field_t test_detail_tricore_op_mapping_schema[] = {
CYAML_FIELD_STRING_PTR("type", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailTriCoreOp, type, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("access",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailTriCoreOp, access, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("reg", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailTriCoreOp, reg, 0, CYAML_UNLIMITED),
CYAML_FIELD_INT("imm", CYAML_FLAG_OPTIONAL, TestDetailTriCoreOp, imm),
CYAML_FIELD_STRING_PTR(
"mem_base", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailTriCoreOp, mem_base, 0, CYAML_UNLIMITED),
CYAML_FIELD_INT("mem_disp", CYAML_FLAG_OPTIONAL, TestDetailTriCoreOp,
mem_disp),
CYAML_FIELD_END
};
static const cyaml_schema_value_t test_detail_tricore_op_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER, TestDetailTriCoreOp,
test_detail_tricore_op_mapping_schema),
};
typedef struct {
tbool update_flags;
TestDetailTriCoreOp **operands;
uint32_t operands_count;
} TestDetailTriCore;
static const cyaml_schema_field_t test_detail_tricore_mapping_schema[] = {
CYAML_FIELD_INT("update_flags", CYAML_FLAG_OPTIONAL, TestDetailTriCore,
update_flags),
CYAML_FIELD_SEQUENCE(
"operands", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailTriCore, operands, &test_detail_tricore_op_schema, 0,
CYAML_UNLIMITED), // 0-MAX options
CYAML_FIELD_END
};
TestDetailTriCore *test_detail_tricore_new();
TestDetailTriCore *test_detail_tricore_clone(const TestDetailTriCore *detail);
void test_detail_tricore_free(TestDetailTriCore *detail);
TestDetailTriCoreOp *test_detail_tricore_op_new();
TestDetailTriCoreOp *
test_detail_tricore_op_clone(const TestDetailTriCoreOp *detail);
void test_detail_tricore_op_free(TestDetailTriCoreOp *detail);
bool test_expected_tricore(csh *handle, const cs_tricore *actual,
const TestDetailTriCore *expected);
#endif // TEST_DETAIL_TRICORE_H
@@ -0,0 +1,82 @@
// Copyright © 2024 Rot127 <unisono@quyllur.org>
// SPDX-License-Identifier: BSD-3
#ifndef TEST_DETAIL_WASM_H
#define TEST_DETAIL_WASM_H
#include "test_compare.h"
#include <cyaml/cyaml.h>
#include <capstone/capstone.h>
typedef struct {
char *type;
uint32_t size;
int8_t int7;
uint32_t varuint32;
uint64_t varuint64;
uint32_t uint32;
uint64_t uint64;
uint32_t immediate_0;
uint32_t immediate_1;
uint32_t brt_length;
uint64_t brt_address;
uint32_t brt_default_target;
} TestDetailWASMOp;
static const cyaml_schema_field_t test_detail_wasm_op_mapping_schema[] = {
CYAML_FIELD_STRING_PTR("type", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailWASMOp, type, 0, CYAML_UNLIMITED),
CYAML_FIELD_UINT("size", CYAML_FLAG_OPTIONAL, TestDetailWASMOp, size),
CYAML_FIELD_INT("int7", CYAML_FLAG_OPTIONAL, TestDetailWASMOp, int7),
CYAML_FIELD_UINT("varuint32", CYAML_FLAG_OPTIONAL, TestDetailWASMOp,
varuint32),
CYAML_FIELD_UINT("varuint64", CYAML_FLAG_OPTIONAL, TestDetailWASMOp,
varuint64),
CYAML_FIELD_UINT("uint64", CYAML_FLAG_OPTIONAL, TestDetailWASMOp,
uint64),
CYAML_FIELD_UINT("uint32", CYAML_FLAG_OPTIONAL, TestDetailWASMOp,
uint32),
CYAML_FIELD_UINT("immediate_0", CYAML_FLAG_OPTIONAL, TestDetailWASMOp,
immediate_0),
CYAML_FIELD_UINT("immediate_1", CYAML_FLAG_OPTIONAL, TestDetailWASMOp,
immediate_1),
CYAML_FIELD_UINT("brt_length", CYAML_FLAG_OPTIONAL, TestDetailWASMOp,
brt_length),
CYAML_FIELD_UINT("brt_address", CYAML_FLAG_OPTIONAL, TestDetailWASMOp,
brt_address),
CYAML_FIELD_UINT("brt_default_target", CYAML_FLAG_OPTIONAL,
TestDetailWASMOp, brt_default_target),
CYAML_FIELD_END
};
static const cyaml_schema_value_t test_detail_wasm_op_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER, TestDetailWASMOp,
test_detail_wasm_op_mapping_schema),
};
typedef struct {
TestDetailWASMOp **operands;
uint32_t operands_count;
} TestDetailWASM;
static const cyaml_schema_field_t test_detail_wasm_mapping_schema[] = {
CYAML_FIELD_SEQUENCE(
"operands", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailWASM, operands, &test_detail_wasm_op_schema, 0,
CYAML_UNLIMITED), // 0-MAX options
CYAML_FIELD_END
};
TestDetailWASM *test_detail_wasm_new();
TestDetailWASM *test_detail_wasm_clone(const TestDetailWASM *detail);
void test_detail_wasm_free(TestDetailWASM *detail);
TestDetailWASMOp *test_detail_wasm_op_new();
TestDetailWASMOp *test_detail_wasm_op_clone(const TestDetailWASMOp *detail);
void test_detail_wasm_op_free(TestDetailWASMOp *detail);
bool test_expected_wasm(csh *handle, const cs_wasm *actual,
const TestDetailWASM *expected);
#endif // TEST_DETAIL_WASM_H
+178
View File
@@ -0,0 +1,178 @@
// Copyright © 2024 Rot127 <unisono@quyllur.org>
// SPDX-License-Identifier: BSD-3
#ifndef TEST_DETAIL_X86_H
#define TEST_DETAIL_X86_H
#include "test_compare.h"
#include <cyaml/cyaml.h>
#include <capstone/capstone.h>
#include <stdint.h>
typedef struct {
char *type;
char *access;
uint8_t size;
char *reg;
int64_t imm;
char *mem_segment;
char *mem_base;
char *mem_index;
int mem_scale;
int64_t mem_disp;
char *avx_bcast;
tbool avx_zero_opmask;
} TestDetailX86Op;
static const cyaml_schema_value_t test_detail_x86_op_sys_psr_schema = {
CYAML_VALUE_STRING(CYAML_FLAG_POINTER, char, 0, CYAML_UNLIMITED),
};
static const cyaml_schema_field_t test_detail_x86_op_mapping_schema[] = {
CYAML_FIELD_STRING_PTR("type", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailX86Op, type, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("access",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailX86Op, access, 0, CYAML_UNLIMITED),
CYAML_FIELD_UINT("size", CYAML_FLAG_OPTIONAL, TestDetailX86Op, size),
CYAML_FIELD_STRING_PTR("reg", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailX86Op, reg, 0, CYAML_UNLIMITED),
CYAML_FIELD_INT("imm", CYAML_FLAG_OPTIONAL, TestDetailX86Op, imm),
CYAML_FIELD_STRING_PTR(
"mem_segment", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailX86Op, mem_segment, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("mem_base",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailX86Op, mem_base, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("mem_index",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailX86Op, mem_index, 0, CYAML_UNLIMITED),
CYAML_FIELD_INT("mem_disp", CYAML_FLAG_OPTIONAL, TestDetailX86Op,
mem_disp),
CYAML_FIELD_INT("mem_scale", CYAML_FLAG_OPTIONAL, TestDetailX86Op,
mem_scale),
CYAML_FIELD_INT("avx_zero_opmask", CYAML_FLAG_OPTIONAL, TestDetailX86Op,
avx_zero_opmask),
CYAML_FIELD_STRING_PTR("avx_bcast",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailX86Op, avx_bcast, 0, CYAML_UNLIMITED),
CYAML_FIELD_END
};
static const cyaml_schema_value_t test_detail_x86_op_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER, TestDetailX86Op,
test_detail_x86_op_mapping_schema),
};
static const cyaml_schema_value_t test_detail_x86_opcode_schema = {
CYAML_VALUE_UINT(CYAML_FLAG_DEFAULT, uint8_t),
};
static const cyaml_schema_value_t test_detail_x86_string_schema = {
CYAML_VALUE_STRING(CYAML_FLAG_POINTER, char, 0, CYAML_UNLIMITED),
};
typedef struct {
char *sib_index;
char *sib_base;
char *xop_cc;
char *sse_cc;
char *avx_cc;
char *avx_rm;
char *prefix[4];
uint8_t opcode[4];
uint8_t rex;
uint8_t addr_size;
uint8_t modrm;
uint8_t sib;
int64_t disp;
int8_t sib_scale;
tbool avx_sae;
char **eflags;
size_t eflags_count;
char **fpu_flags;
size_t fpu_flags_count;
uint8_t enc_modrm_offset;
uint8_t enc_disp_offset;
uint8_t enc_disp_size;
uint8_t enc_imm_offset;
uint8_t enc_imm_size;
TestDetailX86Op **operands;
uint32_t operands_count;
} TestDetailX86;
static const cyaml_schema_field_t test_detail_x86_mapping_schema[] = {
CYAML_FIELD_STRING_PTR("sib_index",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailX86, sib_index, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("sib_base",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailX86, sib_base, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("xop_cc",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailX86, xop_cc, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("sse_cc",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailX86, sse_cc, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("avx_cc",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailX86, avx_cc, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("avx_rm",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailX86, avx_rm, 0, CYAML_UNLIMITED),
CYAML_FIELD_SEQUENCE_FIXED("prefix", CYAML_FLAG_OPTIONAL, TestDetailX86,
prefix, &test_detail_x86_string_schema, 4),
CYAML_FIELD_SEQUENCE_FIXED("opcode", CYAML_FLAG_OPTIONAL, TestDetailX86,
opcode, &test_detail_x86_opcode_schema, 4),
CYAML_FIELD_UINT("rex", CYAML_FLAG_OPTIONAL, TestDetailX86, rex),
CYAML_FIELD_UINT("addr_size", CYAML_FLAG_OPTIONAL, TestDetailX86,
addr_size),
CYAML_FIELD_UINT("modrm", CYAML_FLAG_OPTIONAL, TestDetailX86, modrm),
CYAML_FIELD_UINT("sib", CYAML_FLAG_OPTIONAL, TestDetailX86, sib),
CYAML_FIELD_INT("disp", CYAML_FLAG_OPTIONAL, TestDetailX86, disp),
CYAML_FIELD_INT("sib_scale", CYAML_FLAG_OPTIONAL, TestDetailX86,
sib_scale),
CYAML_FIELD_INT("avx_sae", CYAML_FLAG_OPTIONAL, TestDetailX86, avx_sae),
CYAML_FIELD_SEQUENCE("eflags", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailX86, eflags,
&test_detail_x86_string_schema, 0,
CYAML_UNLIMITED),
CYAML_FIELD_SEQUENCE(
"fpu_flags", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailX86, fpu_flags, &test_detail_x86_string_schema, 0,
CYAML_UNLIMITED),
CYAML_FIELD_UINT("enc_modrm_offset", CYAML_FLAG_OPTIONAL, TestDetailX86,
enc_modrm_offset),
CYAML_FIELD_UINT("enc_disp_offset", CYAML_FLAG_OPTIONAL, TestDetailX86,
enc_disp_offset),
CYAML_FIELD_UINT("enc_disp_size", CYAML_FLAG_OPTIONAL, TestDetailX86,
enc_disp_size),
CYAML_FIELD_UINT("enc_imm_offset", CYAML_FLAG_OPTIONAL, TestDetailX86,
enc_imm_offset),
CYAML_FIELD_UINT("enc_imm_size", CYAML_FLAG_OPTIONAL, TestDetailX86,
enc_imm_size),
CYAML_FIELD_SEQUENCE(
"operands", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailX86, operands, &test_detail_x86_op_schema, 0,
CYAML_UNLIMITED), // 0-MAX options
CYAML_FIELD_END
};
TestDetailX86 *test_detail_x86_new();
TestDetailX86 *test_detail_x86_clone(TestDetailX86 *detail);
void test_detail_x86_free(TestDetailX86 *detail);
TestDetailX86Op *test_detail_x86_op_new();
TestDetailX86Op *test_detail_x86_op_clone(TestDetailX86Op *detail);
void test_detail_x86_op_free(TestDetailX86Op *detail);
bool test_expected_x86(csh *handle, cs_x86 *actual, TestDetailX86 *expected);
#endif // TEST_DETAIL_X86_H
@@ -0,0 +1,70 @@
// Copyright © 2024 Rot127 <unisono@quyllur.org>
// SPDX-License-Identifier: BSD-3
#ifndef TEST_DETAIL_XCORE_H
#define TEST_DETAIL_XCORE_H
#include "test_compare.h"
#include <cyaml/cyaml.h>
#include <capstone/capstone.h>
typedef struct {
char *type;
char *reg;
int32_t imm;
char *mem_base;
char *mem_index;
int32_t mem_disp;
int32_t mem_direct;
} TestDetailXCoreOp;
static const cyaml_schema_field_t test_detail_xcore_op_mapping_schema[] = {
CYAML_FIELD_STRING_PTR("type", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailXCoreOp, type, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("reg", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailXCoreOp, reg, 0, CYAML_UNLIMITED),
CYAML_FIELD_INT("imm", CYAML_FLAG_OPTIONAL, TestDetailXCoreOp, imm),
CYAML_FIELD_STRING_PTR("mem_base",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailXCoreOp, mem_base, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR(
"mem_index", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailXCoreOp, mem_index, 0, CYAML_UNLIMITED),
CYAML_FIELD_INT("mem_disp", CYAML_FLAG_OPTIONAL, TestDetailXCoreOp,
mem_disp),
CYAML_FIELD_INT("mem_direct", CYAML_FLAG_OPTIONAL, TestDetailXCoreOp,
mem_direct),
CYAML_FIELD_END
};
static const cyaml_schema_value_t test_detail_xcore_op_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER, TestDetailXCoreOp,
test_detail_xcore_op_mapping_schema),
};
typedef struct {
TestDetailXCoreOp **operands;
uint32_t operands_count;
} TestDetailXCore;
static const cyaml_schema_field_t test_detail_xcore_mapping_schema[] = {
CYAML_FIELD_SEQUENCE(
"operands", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailXCore, operands, &test_detail_xcore_op_schema, 0,
CYAML_UNLIMITED), // 0-MAX options
CYAML_FIELD_END
};
TestDetailXCore *test_detail_xcore_new();
TestDetailXCore *test_detail_xcore_clone(const TestDetailXCore *detail);
void test_detail_xcore_free(TestDetailXCore *detail);
TestDetailXCoreOp *test_detail_xcore_op_new();
TestDetailXCoreOp *test_detail_xcore_op_clone(const TestDetailXCoreOp *detail);
void test_detail_xcore_op_free(TestDetailXCoreOp *detail);
bool test_expected_xcore(csh *handle, const cs_xcore *actual,
const TestDetailXCore *expected);
#endif // TEST_DETAIL_XCORE_H
@@ -0,0 +1,73 @@
// Copyright © 2024 Rot127 <unisono@quyllur.org>
// Copyright © 2024 Billow <billow.fun@gmail.com>
// SPDX-License-Identifier: BSD-3
#ifndef TEST_DETAIL_XTENSA_H
#define TEST_DETAIL_XTENSA_H
#include "test_compare.h"
#include <cyaml/cyaml.h>
#include <capstone/capstone.h>
typedef struct {
char *type;
char *access;
char *reg;
int32_t imm;
char *mem_base;
int32_t mem_disp;
} TestDetailXtensaOp;
static const cyaml_schema_field_t test_detail_xtensa_op_mapping_schema[] = {
CYAML_FIELD_STRING_PTR("type", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailXtensaOp, type, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("access",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailXtensaOp, access, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("reg", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailXtensaOp, reg, 0, CYAML_UNLIMITED),
CYAML_FIELD_INT("imm", CYAML_FLAG_OPTIONAL, TestDetailXtensaOp, imm),
CYAML_FIELD_STRING_PTR(
"mem_base", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailXtensaOp, mem_base, 0, CYAML_UNLIMITED),
CYAML_FIELD_INT("mem_disp", CYAML_FLAG_OPTIONAL, TestDetailXtensaOp,
mem_disp),
CYAML_FIELD_END
};
static const cyaml_schema_value_t test_detail_xtensa_op_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER, TestDetailXtensaOp,
test_detail_xtensa_op_mapping_schema),
};
typedef struct {
TestDetailXtensaOp **operands;
uint32_t operands_count;
char *format;
} TestDetailXtensa;
static const cyaml_schema_field_t test_detail_xtensa_mapping_schema[] = {
CYAML_FIELD_SEQUENCE(
"operands", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailXtensa, operands, &test_detail_xtensa_op_schema, 0,
CYAML_UNLIMITED), // 0-MAX options
CYAML_FIELD_STRING_PTR("format",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
TestDetailXtensa, format, 0, CYAML_UNLIMITED),
CYAML_FIELD_END
};
TestDetailXtensa *test_detail_xtensa_new();
TestDetailXtensa *test_detail_xtensa_clone(const TestDetailXtensa *detail);
void test_detail_xtensa_free(TestDetailXtensa *detail);
TestDetailXtensaOp *test_detail_xtensa_op_new();
TestDetailXtensaOp *
test_detail_xtensa_op_clone(const TestDetailXtensaOp *detail);
void test_detail_xtensa_op_free(TestDetailXtensaOp *detail);
bool test_expected_xtensa(csh *handle, const cs_xtensa *actual,
const TestDetailXtensa *expected);
#endif // TEST_DETAIL_XTENSA_H
File diff suppressed because it is too large Load Diff
+49
View File
@@ -0,0 +1,49 @@
// Copyright © 2024 Rot127 <unisono@quyllur.org>
// SPDX-License-Identifier: BSD-3
#ifndef TESTRUN_H
#define TESTRUN_H
#include "test_case.h"
#include <stdint.h>
typedef enum {
TEST_RUN_SUCCESS = 0, ///< All test cases succeeded.
TEST_RUN_FAILURE = 1, ///< At least one test case failed.
TEST_RUN_ERROR = 2, ///< Test run had errors.
} TestRunResult;
typedef struct {
uint32_t valid_test_files; ///< Total number of test files.
uint32_t invalid_files; ///< Number of invalid files.
uint32_t tc_total; ///< Total number of test cases.
uint32_t successful; ///< Number of successful test cases.
uint32_t failed; ///< Number of failed test cases.
uint32_t errors; ///< Number errors (parsing errors etc).
uint32_t skipped; ///< Number skipped test cases.
uint32_t decoded_insns; ///< Number of total decoded instructions.
} TestRunStats;
typedef struct {
uint32_t case_cnt;
TestCase *cases;
} TestRun;
/* CYAML configuration. */
static const cyaml_config_t cyaml_config = {
.log_fn = cyaml_log, /* Use the default logging function. */
.mem_fn = cyaml_mem, /* Use the default memory allocator. */
.log_level = CYAML_LOG_WARNING, /* Logging errors and warnings only. */
};
typedef struct {
size_t arch_bits; ///< Bits of the architecture.
TestCase *tcase; ///< The test case to check.
csh handle; ///< The Capstone instance for this test. Setup and teared down by the cmocka handlers.
uint32_t decoded_insns; ///< Counts the number of decoded instructions of this test case.
} UnitTestState;
TestRunResult cstest_run_tests(char **test_file_paths, uint32_t path_count,
TestRunStats *stats);
#endif // TESTRUN_H
+112
View File
@@ -0,0 +1,112 @@
// Copyright © 2024 Rot127 <unisono@quyllur.org>
// SPDX-License-Identifier: BSD-3
#define _XOPEN_SOURCE 500
#include "../../../utils.h"
#include "test_run.h"
#include <capstone/platform.h>
#include <ftw.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
// Pointer to the file list table
// Must be a thread local, because we cannot pass arguments to `nftw`.
// So the found test files can only be saved, very annoyingly,
// to a global/thread-local mutable variables.
char ***test_files = NULL;
uint32_t file_count = 0;
static void help(const char *self)
{
fprintf(stderr, "%s <test-file-dir>/<test-file.yml> ...\n", self);
}
static int handle_ftree_entry(const char *fpath, const struct stat *sb,
int typeflag, struct FTW *ftwbuf)
{
if (typeflag != FTW_F) {
return 0;
}
const char *suffix = strstr(fpath, ".yaml");
if (!suffix || suffix - fpath != strlen(fpath) - 5) {
// Misses the .yaml suffix.
return 0;
}
file_count++;
*test_files = cs_mem_realloc(*test_files, sizeof(char *) * file_count);
if (!*test_files) {
fprintf(stderr, "[!] realloc failed\n");
return -1;
}
test_files[0][file_count - 1] = cs_strdup(fpath);
return 0;
}
/// Parses the test file paths from the @argv array.
static void get_tfiles(int argc, const char **argv)
{
for (size_t i = 1; i < argc; ++i) {
if (nftw(argv[i], handle_ftree_entry, 20,
FTW_DEPTH | FTW_PHYS) == -1) {
fprintf(stderr, "[!] nftw failed.\n");
return;
}
}
}
void print_test_run_stats(const TestRunStats *stats)
{
printf("\n-----------------------------------------\n");
printf("Test run statistics\n\n");
printf("Valid files: %" PRId32 "\n", stats->valid_test_files);
printf("Invalid files: %" PRId32 "\n", stats->invalid_files);
printf("Errors: %" PRId32 "\n\n", stats->errors);
printf("Test cases:\n");
printf("\tTotal: %" PRId32 "\n", stats->tc_total);
printf("\tSuccessful: %" PRId32 "\n", stats->successful);
printf("\tSkipped: %" PRId32 "\n", stats->skipped);
printf("\tFailed: %" PRId32 "\n", stats->failed);
printf("\n\tDecoded instructions: %" PRId32 "\n", stats->decoded_insns);
printf("-----------------------------------------\n");
printf("\n");
}
int main(int argc, const char **argv)
{
if (argc < 2 || strcmp(argv[1], "-h") == 0 ||
strcmp(argv[1], "--help") == 0) {
help(argv[0]);
exit(EXIT_FAILURE);
}
test_files = malloc(sizeof(char **));
*test_files = NULL;
get_tfiles(argc, argv);
if (!*test_files || file_count == 0) {
fprintf(stderr, "Arguments are invalid. No files found.\n");
exit(EXIT_FAILURE);
}
printf("Test files found: %" PRId32 "\n", file_count);
TestRunStats stats = { 0 };
TestRunResult res = cstest_run_tests(*test_files, file_count, &stats);
print_test_run_stats(&stats);
if (res == TEST_RUN_ERROR) {
fprintf(stderr, "[!] An error occured.\n");
exit(EXIT_FAILURE);
} else if (res == TEST_RUN_SUCCESS) {
printf("[o] All tests succeeded.\n");
exit(EXIT_SUCCESS);
} else if (res == TEST_RUN_FAILURE) {
printf("\nNOTE: Asserts have the actual data on the left side: 'actual' != 'expected'\n\n");
fprintf(stderr, "[!] Some tests failed.\n");
exit(EXIT_FAILURE);
}
fprintf(stderr, "[!] Unhandled Test Run result\n");
exit(EXIT_FAILURE);
}
+200
View File
@@ -0,0 +1,200 @@
/* Capstone testing regression */
/* By Do Minh Tuan <tuanit96@gmail.com>, 02-2019 */
#include <assert.h>
#include <stdbool.h>
#include <stdarg.h>
#include <stdint.h>
#include <capstone/platform.h>
#include <stddef.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <setjmp.h>
#include "cmocka.h"
#include "helper.h"
void add_str(char **src, const char *format, ...)
{
char *tmp;
size_t len1, len2;
va_list args;
tmp = (char *)malloc(sizeof(char) * 1000);
va_start(args, format);
vsprintf(tmp, format, args);
va_end(args);
len1 = strlen(*src);
len2 = strlen(tmp);
*src = (char *)realloc(*src, sizeof(char) * (len1 + len2 + 10));
memcpy(*src + len1, tmp, len2 + 1);
free(tmp);
}
void replace_hex(char *src, size_t src_len)
{
char *tmp, *result, *found, *origin, *orig_found;
int valid;
unsigned long long int value;
char *tmp_tmp;
result = (char *)malloc(sizeof(char));
result[0] = '\0';
tmp = strdup(src);
origin = tmp;
while ((found = strstr(tmp, "0x")) != NULL) {
orig_found = found;
found += 2;
value = 0;
valid = 0;
tmp_tmp = strndup(tmp, orig_found - tmp);
while (*found != '\0' && isxdigit(*found)) {
valid = 1;
if (*found >= 'a' && *found <= 'f')
value = value * 0x10 + (*found - 'a' + 10);
else if (*found >= 'A' && *found <= 'F')
value = value * 0x10 + (*found - 'A' + 10);
else
value = value * 0x10 + (*found - '0');
found++;
}
if (valid == 1)
add_str(&result, "%s%llu", tmp_tmp, value);
else
add_str(&result, "%s0x", tmp_tmp);
tmp = found;
free(tmp_tmp);
}
add_str(&result, "%s", tmp);
if (strlen(result) >= src_len) {
free(result);
free(origin);
fprintf(stderr,
"[ Error ] --- Buffer Overflow in replace_hex()\n");
_fail(__FILE__, __LINE__);
}
strcpy(src, result);
free(result);
free(origin);
}
void replace_negative(char *src, size_t src_len, size_t arch_bits)
{
char *tmp, *result, *found, *origin, *orig_found;
int cnt, valid;
char *value, *tmp_tmp;
unsigned short int tmp_short;
unsigned int tmp_int;
unsigned long int tmp_long;
result = (char *)malloc(sizeof(char));
result[0] = '\0';
tmp = strdup(src);
origin = tmp;
while ((found = strstr(tmp, "-")) != NULL) {
orig_found = found;
found++;
valid = 0;
value = strdup("-");
cnt = 2;
while (*found != '\0' && isdigit(*found)) {
valid = 1;
value = (char *)realloc(value, cnt + 1);
value[cnt - 1] = *found;
value[cnt] = '\0';
cnt++;
found++;
}
tmp_tmp = strndup(tmp, orig_found - tmp);
if (valid == 1) {
*orig_found = '\0';
if (arch_bits == 16) {
sscanf(value, "%hu", &tmp_short);
add_str(&result, "%s%hu", tmp_tmp, tmp_short);
} else if (arch_bits == 32) {
sscanf(value, "%u", &tmp_int);
add_str(&result, "%s%u", tmp_tmp, tmp_int);
} else if (arch_bits == 64) {
sscanf(value, "%lu", &tmp_long);
add_str(&result, "%s%lu", tmp_tmp, tmp_long);
}
} else
add_str(&result, "%s-", tmp_tmp);
tmp = found;
free(value);
free(tmp_tmp);
}
add_str(&result, "%s", tmp);
if (strlen(result) >= src_len) {
fprintf(stderr,
"[ Error ] --- Buffer Overflow in replace_negative()\n");
free(result);
free(origin);
_fail(__FILE__, __LINE__);
}
strcpy(src, result);
free(result);
free(origin);
}
void trim_str(char *str)
{
char tmp[MAX_ASM_TXT_MEM];
int start, end, j, i;
start = 0;
end = strlen(str) - 1;
j = 0;
while (start < strlen(str) && isspace(str[start]))
start++;
while (end >= 0 && isspace(str[end]))
end--;
for (i = start; i <= end; ++i)
tmp[j++] = str[i];
tmp[j] = '\0';
strcpy(str, tmp);
return;
}
/// Normalizes the usage of spaces in the given string.
/// It does:
/// - Replaces '\t' with '\s'
/// - Replace '\s\s+' with a single space.
void norm_spaces(char *str)
{
assert(str);
char *space_ptr = NULL;
while ((space_ptr = strstr(str, "\t")) != NULL) {
*space_ptr = ' ';
}
while ((space_ptr = strstr(str, " ")) != NULL) {
memmove(space_ptr, space_ptr + 1, strlen(space_ptr));
}
return;
}
void str_to_lower(char *str)
{
assert(str);
for (size_t i = 0; i < strlen(str); ++i)
str[i] = tolower(str[i]);
}
+352
View File
@@ -0,0 +1,352 @@
// Copyright © 2024 Rot127 <unisono@quyllur.org>
// SPDX-License-Identifier: BSD-3
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include "cmocka.h"
#include "test_detail.h"
#include "test_case.h"
#include "test_compare.h"
#include "helper.h"
#include "../../../utils.h"
#include <stdio.h>
#include <string.h>
TestInput *test_input_new()
{
TestInput *p = cs_mem_calloc(sizeof(TestInput), 1);
assert(p);
return p;
}
void test_input_free(TestInput *test_input)
{
if (!test_input) {
return;
}
cs_mem_free(test_input->name);
cs_mem_free(test_input->bytes);
cs_mem_free(test_input->arch);
for (size_t i = 0; i < test_input->options_count; i++) {
cs_mem_free(test_input->options[i]);
}
cs_mem_free(test_input->options);
cs_mem_free(test_input);
}
TestInput *test_input_clone(TestInput *test_input)
{
assert(test_input);
TestInput *ti = test_input_new();
ti->address = test_input->address;
for (size_t i = 0; i < test_input->options_count; i++) {
ti->options = cs_mem_realloc(
ti->options, sizeof(char *) * (ti->options_count + 1));
ti->options[i] = cs_strdup(test_input->options[i]);
ti->options_count++;
}
ti->name = test_input->name ? cs_strdup(test_input->name) : NULL;
ti->arch = cs_strdup(test_input->arch);
ti->bytes = cs_mem_calloc(sizeof(uint8_t), test_input->bytes_count);
ti->bytes_count = test_input->bytes_count;
memcpy(ti->bytes, test_input->bytes, test_input->bytes_count);
return ti;
}
char *test_input_stringify(const TestInput *test_input, const char *postfix)
{
size_t msg_len = 2048;
char *msg = cs_mem_calloc(sizeof(char), msg_len);
char *byte_seq =
byte_seq_to_str(test_input->bytes, test_input->bytes_count);
if (!msg) {
cs_mem_free(byte_seq);
return NULL;
}
char opt_seq[128] = { 0 };
str_append_no_realloc(opt_seq, sizeof(opt_seq), "[");
for (size_t i = 0; i < test_input->options_count; ++i) {
str_append_no_realloc(opt_seq, sizeof(opt_seq), test_input->options[i]);
if (i < test_input->options_count - 1) {
str_append_no_realloc(opt_seq, sizeof(opt_seq), ", ");
}
}
str_append_no_realloc(opt_seq, sizeof(opt_seq), "]");
cs_snprintf(msg, msg_len,
"%sTestInput { arch: %s, options: %s, addr: 0x%" PRIx64
", bytes: %s }",
postfix, test_input->arch, opt_seq, test_input->address,
byte_seq);
cs_mem_free(byte_seq);
return msg;
}
TestInsnData *test_insn_data_new()
{
TestInsnData *p = cs_mem_calloc(sizeof(TestInsnData), 1);
assert(p);
return p;
}
void test_insn_data_free(TestInsnData *test_insn_data)
{
if (!test_insn_data) {
return;
}
cs_mem_free(test_insn_data->asm_text);
cs_mem_free(test_insn_data->op_str);
cs_mem_free(test_insn_data->mnemonic);
cs_mem_free(test_insn_data->id);
cs_mem_free(test_insn_data->alias_id);
test_detail_free(test_insn_data->details);
cs_mem_free(test_insn_data);
}
TestInsnData *test_insn_data_clone(TestInsnData *test_insn_data)
{
assert(test_insn_data);
TestInsnData *tid = test_insn_data_new();
tid->alias_id = test_insn_data->alias_id ?
cs_strdup(test_insn_data->alias_id) :
NULL;
tid->id = test_insn_data->id ?
cs_strdup(test_insn_data->id) :
NULL;
tid->is_alias = test_insn_data->is_alias;
tid->illegal = test_insn_data->illegal;
tid->mnemonic = test_insn_data->mnemonic ?
cs_strdup(test_insn_data->mnemonic) :
NULL;
tid->op_str = test_insn_data->op_str ?
cs_strdup(test_insn_data->op_str) :
NULL;
tid->asm_text = test_insn_data->asm_text ?
cs_strdup(test_insn_data->asm_text) :
NULL;
if (test_insn_data->details) {
tid->details = test_detail_clone(test_insn_data->details);
}
return tid;
}
TestExpected *test_expected_new()
{
TestExpected *p = cs_mem_calloc(sizeof(TestExpected), 1);
assert(p);
return p;
}
void test_expected_free(TestExpected *test_expected)
{
if (!test_expected) {
return;
}
for (size_t i = 0; i < test_expected->insns_count; i++) {
test_insn_data_free(test_expected->insns[i]);
}
cs_mem_free(test_expected->insns);
cs_mem_free(test_expected);
}
TestExpected *test_expected_clone(TestExpected *test_expected)
{
assert(test_expected);
TestExpected *te = test_expected_new();
te->insns = cs_mem_calloc(sizeof(TestInsnData *),
test_expected->insns_count);
for (size_t i = 0; i < test_expected->insns_count; i++) {
te->insns[i] = test_insn_data_clone(test_expected->insns[i]);
te->insns_count++;
}
return te;
}
/// Compares the given @asm_text to the @expected one.
/// Because Capstone sometimes deviates from the LLVM syntax
/// the strings don't need to be the same to be considered a valid match.
/// E.g. Capstone sometimes prints decimal numbers instead of hexadecimal
/// for readability.
static bool compare_asm_text(const char *asm_text, const char *expected,
size_t arch_bits)
{
if (!asm_text || !expected) {
fprintf(stderr, "[!] asm_text or expected was NULL\n");
return false;
}
if (strcmp(asm_text, expected) == 0) {
return true;
}
// Normalize both strings
char asm_copy[MAX_ASM_TXT_MEM] = { 0 };
strncpy(asm_copy, asm_text, MAX_ASM_TXT_MEM - 1);
trim_str(asm_copy);
replace_hex(asm_copy, sizeof(asm_copy));
replace_negative(asm_copy, sizeof(asm_copy), arch_bits);
norm_spaces(asm_copy);
str_to_lower(asm_copy);
char expected_copy[MAX_ASM_TXT_MEM] = { 0 };
strncpy(expected_copy, expected, MAX_ASM_TXT_MEM - 1);
trim_str(expected_copy);
replace_hex(expected_copy, sizeof(expected_copy));
replace_negative(expected_copy, sizeof(expected_copy), arch_bits);
norm_spaces(expected_copy);
str_to_lower(expected_copy);
if (strcmp(asm_copy, expected_copy) == 0) {
return true;
}
fprintf(stderr,
"Normalized asm-text doesn't match:\n"
"decoded: '%s'\n"
"expected: '%s'\n",
asm_copy, expected_copy);
return false;
}
static bool ids_match(uint32_t actual, const char *expected) {
compare_enum_ret(actual, expected, false);
return true;
}
/// Compares the decoded instructions @insns against the @expected values and returns the result.
void test_expected_compare(csh *handle, TestExpected *expected, cs_insn *insns,
size_t insns_count, size_t arch_bits)
{
assert_int_equal(insns_count, expected->insns_count);
for (size_t i = 0; i < insns_count; ++i) {
TestInsnData *expec_data = expected->insns[i];
// Test mandatory fields first
// The asm text is saved differently for different architectures.
// Either all in op_str or split in mnemonic and op_str
char asm_text[256] = { 0 };
if (insns[i].mnemonic[0] != '\0') {
str_append_no_realloc(asm_text, sizeof(asm_text),
insns[i].mnemonic);
str_append_no_realloc(asm_text, sizeof(asm_text), " ");
}
if (insns[i].op_str[0] != '\0') {
str_append_no_realloc(asm_text, sizeof(asm_text),
insns[i].op_str);
}
if (!compare_asm_text(asm_text, expec_data->asm_text,
arch_bits)) {
fail_msg("asm-text mismatch\n");
}
// Not mandatory fields. If not initialized they should still match.
if (expec_data->id) {
assert_true(ids_match((uint32_t)insns[i].id,
expec_data->id));
}
if (expec_data->is_alias != 0) {
if (expec_data->is_alias > 0) {
assert_true(insns[i].is_alias);
} else {
assert_false(insns[i].is_alias);
}
}
if (expec_data->illegal != 0) {
if (expec_data->illegal > 0) {
assert_true(insns[i].illegal);
} else {
assert_false(insns[i].illegal);
}
}
if (expec_data->alias_id) {
assert_true(ids_match((uint32_t)insns[i].alias_id,
expec_data->alias_id));
}
if (expec_data->mnemonic) {
assert_string_equal(insns[i].mnemonic,
expec_data->mnemonic);
}
if (expec_data->op_str) {
assert_string_equal(insns[i].op_str,
expec_data->op_str);
}
if (expec_data->details) {
if (!insns[i].detail) {
fprintf(stderr, "detail is NULL\n");
assert_non_null(insns[i].detail);
}
assert_true(test_expected_detail(handle, &insns[i],
expec_data->details));
}
}
}
TestCase *test_case_new()
{
TestCase *p = cs_mem_calloc(sizeof(TestCase), 1);
assert(p);
return p;
}
void test_case_free(TestCase *test_case)
{
if (!test_case) {
return;
}
test_input_free(test_case->input);
test_expected_free(test_case->expected);
cs_mem_free(test_case->skip_reason);
cs_mem_free(test_case);
}
TestCase *test_case_clone(TestCase *test_case)
{
assert(test_case);
TestCase *tc = test_case_new();
TestInput *ti = test_input_clone(test_case->input);
tc->input = ti;
TestExpected *te = test_expected_clone(test_case->expected);
tc->expected = te;
tc->skip = test_case->skip;
if (tc->skip) {
tc->skip_reason = strdup(test_case->skip_reason);
}
return tc;
}
TestFile *test_file_new()
{
TestFile *p = cs_mem_calloc(sizeof(TestFile), 1);
assert(p);
return p;
}
void test_file_free(TestFile *test_file)
{
if (!test_file) {
return;
}
for (size_t i = 0; i < test_file->test_cases_count; ++i) {
test_case_free(test_file->test_cases[i]);
}
cs_mem_free(test_file->test_cases);
cs_mem_free(test_file->filename);
test_file->filename = NULL;
cs_mem_free(test_file);
}
TestFile *test_file_clone(TestFile *test_file)
{
assert(test_file);
TestFile *tf = test_file_new();
tf->filename = test_file->filename ? strdup(test_file->filename) : NULL;
tf->test_cases =
cs_mem_calloc(sizeof(TestCase *), test_file->test_cases_count);
for (size_t i = 0; i < test_file->test_cases_count;
i++, tf->test_cases_count++) {
TestCase *tc = test_case_clone(test_file->test_cases[i]);
tf->test_cases[i] = tc;
}
return tf;
}
+428
View File
@@ -0,0 +1,428 @@
// Copyright © 2024 Rot127 <unisono@quyllur.org>
// SPDX-License-Identifier: BSD-3
#include "test_detail.h"
#include "test_compare.h"
#include <capstone/capstone.h>
TestDetail *test_detail_new()
{
return cs_mem_calloc(sizeof(TestDetail), 1);
}
TestDetail *test_detail_clone(TestDetail *detail)
{
assert(detail);
TestDetail *clone = test_detail_new();
clone->regs_read =
detail->regs_read_count > 0 ?
cs_mem_calloc(sizeof(char *), detail->regs_read_count) :
NULL;
clone->regs_read_count = detail->regs_read_count;
for (size_t i = 0; i < detail->regs_read_count; ++i) {
clone->regs_read[i] = strdup(detail->regs_read[i]);
}
clone->regs_write = detail->regs_write_count > 0 ?
cs_mem_calloc(sizeof(char *),
detail->regs_write_count) :
NULL;
clone->regs_write_count = detail->regs_write_count;
for (size_t i = 0; i < detail->regs_write_count; ++i) {
clone->regs_write[i] = strdup(detail->regs_write[i]);
}
clone->regs_impl_read =
detail->regs_impl_read_count > 0 ?
cs_mem_calloc(sizeof(char *),
detail->regs_impl_read_count) :
NULL;
clone->regs_impl_read_count = detail->regs_impl_read_count;
for (size_t i = 0; i < detail->regs_impl_read_count; ++i) {
clone->regs_impl_read[i] = strdup(detail->regs_impl_read[i]);
}
clone->regs_impl_write =
detail->regs_impl_write_count > 0 ?
cs_mem_calloc(sizeof(char *),
detail->regs_impl_write_count) :
NULL;
clone->regs_impl_write_count = detail->regs_impl_write_count;
for (size_t i = 0; i < detail->regs_impl_write_count; ++i) {
clone->regs_impl_write[i] = strdup(detail->regs_impl_write[i]);
}
clone->groups =
detail->groups_count > 0 ?
cs_mem_calloc(sizeof(char *), detail->groups_count) :
NULL;
clone->groups_count = detail->groups_count;
for (size_t i = 0; i < detail->groups_count; ++i) {
clone->groups[i] = strdup(detail->groups[i]);
}
if (detail->aarch64) {
clone->aarch64 = test_detail_aarch64_clone(detail->aarch64);
}
if (detail->arm) {
clone->arm = test_detail_arm_clone(detail->arm);
}
if (detail->ppc) {
clone->ppc = test_detail_ppc_clone(detail->ppc);
}
if (detail->tricore) {
clone->tricore = test_detail_tricore_clone(detail->tricore);
}
if (detail->alpha) {
clone->alpha = test_detail_alpha_clone(detail->alpha);
}
if (detail->bpf) {
clone->bpf = test_detail_bpf_clone(detail->bpf);
}
if (detail->hppa) {
clone->hppa = test_detail_hppa_clone(detail->hppa);
}
if (detail->xcore) {
clone->xcore = test_detail_xcore_clone(detail->xcore);
}
if (detail->systemz) {
clone->systemz = test_detail_systemz_clone(detail->systemz);
}
if (detail->sparc) {
clone->sparc = test_detail_sparc_clone(detail->sparc);
}
if (detail->sh) {
clone->sh = test_detail_sh_clone(detail->sh);
}
if (detail->mips) {
clone->mips = test_detail_mips_clone(detail->mips);
}
if (detail->riscv) {
clone->riscv = test_detail_riscv_clone(detail->riscv);
}
if (detail->m680x) {
clone->m680x = test_detail_m680x_clone(detail->m680x);
}
if (detail->tms320c64x) {
clone->tms320c64x =
test_detail_tms320c64x_clone(detail->tms320c64x);
}
if (detail->mos65xx) {
clone->mos65xx = test_detail_mos65xx_clone(detail->mos65xx);
}
if (detail->evm) {
clone->evm = test_detail_evm_clone(detail->evm);
}
if (detail->loongarch) {
clone->loongarch =
test_detail_loongarch_clone(detail->loongarch);
}
if (detail->wasm) {
clone->wasm = test_detail_wasm_clone(detail->wasm);
}
if (detail->x86) {
clone->x86 = test_detail_x86_clone(detail->x86);
}
if (detail->m68k) {
clone->m68k = test_detail_m68k_clone(detail->m68k);
}
if (detail->xtensa) {
clone->xtensa = test_detail_xtensa_clone(detail->xtensa);
}
if (detail->arc) {
clone->arc = test_detail_arc_clone(detail->arc);
}
return clone;
}
void test_detail_free(TestDetail *detail)
{
if (!detail) {
return;
}
for (size_t i = 0; i < detail->regs_read_count; ++i) {
cs_mem_free(detail->regs_read[i]);
}
cs_mem_free(detail->regs_read);
for (size_t i = 0; i < detail->regs_write_count; ++i) {
cs_mem_free(detail->regs_write[i]);
}
cs_mem_free(detail->regs_write);
for (size_t i = 0; i < detail->regs_impl_read_count; ++i) {
cs_mem_free(detail->regs_impl_read[i]);
}
cs_mem_free(detail->regs_impl_read);
for (size_t i = 0; i < detail->regs_impl_write_count; ++i) {
cs_mem_free(detail->regs_impl_write[i]);
}
cs_mem_free(detail->regs_impl_write);
for (size_t i = 0; i < detail->groups_count; ++i) {
cs_mem_free(detail->groups[i]);
}
cs_mem_free(detail->groups);
if (detail->aarch64) {
test_detail_aarch64_free(detail->aarch64);
}
if (detail->arm) {
test_detail_arm_free(detail->arm);
}
if (detail->ppc) {
test_detail_ppc_free(detail->ppc);
}
if (detail->tricore) {
test_detail_tricore_free(detail->tricore);
}
if (detail->alpha) {
test_detail_alpha_free(detail->alpha);
}
if (detail->hppa) {
test_detail_hppa_free(detail->hppa);
}
if (detail->bpf) {
test_detail_bpf_free(detail->bpf);
}
if (detail->xcore) {
test_detail_xcore_free(detail->xcore);
}
if (detail->systemz) {
test_detail_systemz_free(detail->systemz);
}
if (detail->sparc) {
test_detail_sparc_free(detail->sparc);
}
if (detail->sh) {
test_detail_sh_free(detail->sh);
}
if (detail->mips) {
test_detail_mips_free(detail->mips);
}
if (detail->riscv) {
test_detail_riscv_free(detail->riscv);
}
if (detail->m680x) {
test_detail_m680x_free(detail->m680x);
}
if (detail->tms320c64x) {
test_detail_tms320c64x_free(detail->tms320c64x);
}
if (detail->mos65xx) {
test_detail_mos65xx_free(detail->mos65xx);
}
if (detail->evm) {
test_detail_evm_free(detail->evm);
}
if (detail->loongarch) {
test_detail_loongarch_free(detail->loongarch);
}
if (detail->wasm) {
test_detail_wasm_free(detail->wasm);
}
if (detail->x86) {
test_detail_x86_free(detail->x86);
}
if (detail->m68k) {
test_detail_m68k_free(detail->m68k);
}
if (detail->xtensa) {
test_detail_xtensa_free(detail->xtensa);
}
if (detail->arc) {
test_detail_arc_free(detail->arc);
}
cs_mem_free(detail);
}
static bool test_reg_rw_access(csh *handle, const cs_insn *insn,
TestDetail *expected)
{
assert(handle && insn && expected);
if (expected->regs_read_count <= 0 && expected->regs_write_count <= 0) {
return true;
}
cs_regs regs_read, regs_write;
uint8_t regs_read_count, regs_write_count;
cs_err err = cs_regs_access(*handle, insn, regs_read, &regs_read_count,
regs_write, &regs_write_count);
if (err != CS_ERR_OK) {
fprintf(stderr, "cs_regs_access() failed with '%s'\n",
cs_strerror(err));
return false;
}
if (expected->regs_read_count > 0) {
compare_uint32_ret(regs_read_count, expected->regs_read_count,
false);
for (size_t i = 0; i < regs_read_count; ++i) {
compare_reg_ret(*handle, regs_read[i],
expected->regs_read[i], false);
}
}
if (expected->regs_write_count > 0) {
compare_uint32_ret(regs_write_count, expected->regs_write_count,
false);
for (size_t i = 0; i < regs_write_count; ++i) {
compare_reg_ret(*handle, regs_write[i],
expected->regs_write[i], false);
}
}
return true;
}
static bool test_impl_reg_rw_access(csh *handle, const cs_insn *insn,
TestDetail *expected)
{
assert(handle && insn && expected);
if (expected->regs_impl_read_count <= 0 &&
expected->regs_impl_write_count <= 0) {
return true;
}
cs_detail *actual = insn->detail;
// Test exclusively the implicitly read or written register.
if (expected->regs_impl_read_count > 0) {
compare_uint32_ret(actual->regs_read_count,
expected->regs_impl_read_count, false);
for (size_t i = 0; i < actual->regs_read_count; ++i) {
compare_reg_ret(*handle, actual->regs_read[i],
expected->regs_impl_read[i], false);
}
}
if (expected->regs_impl_write_count > 0) {
compare_uint32_ret(actual->regs_write_count,
expected->regs_impl_write_count, false);
for (size_t i = 0; i < actual->regs_write_count; ++i) {
compare_reg_ret(*handle, actual->regs_write[i],
expected->regs_impl_write[i], false);
}
}
return true;
}
bool test_expected_detail(csh *handle, const cs_insn *insn,
TestDetail *expected)
{
assert(handle && insn && insn->detail && expected);
cs_detail *actual = insn->detail;
if (!test_reg_rw_access(handle, insn, expected)) {
return false;
}
if (!test_impl_reg_rw_access(handle, insn, expected)) {
return false;
}
if (expected->groups_count > 0) {
compare_uint32_ret(actual->groups_count, expected->groups_count,
false);
for (size_t i = 0; i < actual->groups_count; ++i) {
if (strings_match(cs_group_name(*handle,
actual->groups[i]),
expected->groups[i])) {
continue;
}
compare_enum_ret(actual->groups[i], expected->groups[i],
false);
}
}
if (expected->aarch64) {
return test_expected_aarch64(handle, &actual->aarch64,
expected->aarch64);
}
if (expected->arm) {
return test_expected_arm(handle, &actual->arm, expected->arm);
}
if (expected->ppc) {
return test_expected_ppc(handle, &actual->ppc, expected->ppc);
}
if (expected->tricore) {
return test_expected_tricore(handle, &actual->tricore,
expected->tricore);
}
if (expected->alpha) {
return test_expected_alpha(handle, &actual->alpha,
expected->alpha);
}
if (expected->bpf) {
return test_expected_bpf(handle, &actual->bpf, expected->bpf);
}
if (expected->hppa) {
return test_expected_hppa(handle, &actual->hppa,
expected->hppa);
}
if (expected->xcore) {
return test_expected_xcore(handle, &actual->xcore,
expected->xcore);
}
if (expected->systemz) {
return test_expected_systemz(handle, &actual->systemz,
expected->systemz);
}
if (expected->sparc) {
return test_expected_sparc(handle, &actual->sparc,
expected->sparc);
}
if (expected->sh) {
return test_expected_sh(handle, &actual->sh, expected->sh);
}
if (expected->mips) {
return test_expected_mips(handle, &actual->mips,
expected->mips);
}
if (expected->riscv) {
return test_expected_riscv(handle, &actual->riscv,
expected->riscv);
}
if (expected->m680x) {
return test_expected_m680x(handle, &actual->m680x,
expected->m680x);
}
if (expected->tms320c64x) {
return test_expected_tms320c64x(handle, &actual->tms320c64x,
expected->tms320c64x);
}
if (expected->mos65xx) {
return test_expected_mos65xx(handle, &actual->mos65xx,
expected->mos65xx);
}
if (expected->evm) {
return test_expected_evm(handle, &actual->evm, expected->evm);
}
if (expected->loongarch) {
return test_expected_loongarch(handle, &actual->loongarch,
expected->loongarch);
}
if (expected->wasm) {
return test_expected_wasm(handle, &actual->wasm,
expected->wasm);
}
if (expected->x86) {
return test_expected_x86(handle, &actual->x86, expected->x86);
}
if (expected->m68k) {
return test_expected_m68k(handle, &actual->m68k,
expected->m68k);
}
if (expected->xtensa) {
return test_expected_xtensa(handle, &actual->xtensa,
expected->xtensa);
}
if (expected->arc) {
return test_expected_arc(handle, &actual->arc,
expected->arc);
}
return true;
}
+260
View File
@@ -0,0 +1,260 @@
// Copyright © 2024 Rot127 <unisono@quyllur.org>
// SPDX-License-Identifier: BSD-3
#include "test_compare.h"
#include "test_detail_aarch64.h"
#include <capstone/capstone.h>
#include <stdio.h>
#include <string.h>
TestDetailAArch64 *test_detail_aarch64_new()
{
return cs_mem_calloc(sizeof(TestDetailAArch64), 1);
}
void test_detail_aarch64_free(TestDetailAArch64 *detail)
{
if (!detail) {
return;
}
for (size_t i = 0; i < detail->operands_count; ++i) {
test_detail_aarch64_op_free(detail->operands[i]);
}
cs_mem_free(detail->operands);
cs_mem_free(detail->cc);
cs_mem_free(detail);
}
TestDetailAArch64 *test_detail_aarch64_clone(TestDetailAArch64 *detail)
{
TestDetailAArch64 *clone = test_detail_aarch64_new();
clone->cc = detail->cc ? strdup(detail->cc) : NULL;
clone->update_flags = detail->update_flags;
clone->post_indexed = detail->post_indexed;
clone->operands_count = detail->operands_count;
if (detail->operands_count > 0) {
clone->operands = cs_mem_calloc(sizeof(TestDetailAArch64Op *),
detail->operands_count);
}
for (size_t i = 0; i < detail->operands_count; ++i) {
clone->operands[i] =
test_detail_aarch64_op_clone(detail->operands[i]);
}
return clone;
}
TestDetailAArch64Op *test_detail_aarch64_op_new()
{
return cs_mem_calloc(sizeof(TestDetailAArch64Op), 1);
}
TestDetailAArch64Op *test_detail_aarch64_op_clone(TestDetailAArch64Op *op)
{
TestDetailAArch64Op *clone = test_detail_aarch64_op_new();
clone->type = op->type ? strdup(op->type) : NULL;
clone->sub_type = op->sub_type ? strdup(op->sub_type) : NULL;
clone->access = op->access ? strdup(op->access) : NULL;
clone->reg = op->reg ? strdup(op->reg) : NULL;
clone->mem_base = op->mem_base ? strdup(op->mem_base) : NULL;
clone->mem_index = op->mem_index ? strdup(op->mem_index) : NULL;
clone->shift_type = op->shift_type ? strdup(op->shift_type) : NULL;
clone->ext = op->ext ? strdup(op->ext) : NULL;
clone->vas = op->vas ? strdup(op->vas) : NULL;
clone->imm = op->imm;
clone->sme = op->sme ? test_detail_aarch64_op_sme_clone(op->sme) : NULL;
clone->pred_reg = op->pred_reg ? strdup(op->pred_reg) : NULL;
clone->pred_vec_select =
op->pred_vec_select ? strdup(op->pred_vec_select) : NULL;
clone->pred_imm_index = op->pred_imm_index;
clone->pred_imm_index_set = op->pred_imm_index_set;
clone->mem_disp = op->mem_disp;
clone->imm_range_first = op->imm_range_first;
clone->imm_range_offset = op->imm_range_offset;
clone->fp = op->fp;
clone->fp_set = op->fp_set;
clone->sys_raw_val = op->sys_raw_val;
clone->shift_value = op->shift_value;
clone->is_vreg = op->is_vreg;
clone->vector_index = op->vector_index;
clone->vector_index_is_set = op->vector_index_is_set;
clone->is_list_member = op->is_list_member;
return clone;
}
void test_detail_aarch64_op_free(TestDetailAArch64Op *op)
{
if (!op) {
return;
}
test_detail_aarch64_op_sme_free(op->sme);
cs_mem_free(op->type);
cs_mem_free(op->sub_type);
cs_mem_free(op->access);
cs_mem_free(op->reg);
cs_mem_free(op->mem_base);
cs_mem_free(op->mem_index);
cs_mem_free(op->shift_type);
cs_mem_free(op->ext);
cs_mem_free(op->vas);
cs_mem_free(op->pred_reg);
cs_mem_free(op->pred_vec_select);
cs_mem_free(op);
}
TestDetailAArch64SME *test_detail_aarch64_op_sme_new()
{
return cs_mem_calloc(sizeof(TestDetailAArch64SME), 1);
}
TestDetailAArch64SME *test_detail_aarch64_op_sme_clone(TestDetailAArch64SME *sme)
{
TestDetailAArch64SME *clone = test_detail_aarch64_op_sme_new();
clone->type = sme->type ? strdup(sme->type) : NULL;
clone->tile = sme->tile ? strdup(sme->tile) : NULL;
clone->slice_reg = sme->slice_reg ? strdup(sme->slice_reg) : NULL;
clone->slice_offset_imm = sme->slice_offset_imm;
clone->slice_offset_ir_first = sme->slice_offset_ir_first;
clone->slice_offset_ir_offset = sme->slice_offset_ir_offset;
clone->slice_offset_ir_set = sme->slice_offset_ir_set;
clone->has_range_offset = sme->has_range_offset;
clone->is_vertical = sme->is_vertical;
return clone;
}
void test_detail_aarch64_op_sme_free(TestDetailAArch64SME *sme)
{
if (!sme) {
return;
}
cs_mem_free(sme->type);
cs_mem_free(sme->tile);
cs_mem_free(sme->slice_reg);
cs_mem_free(sme);
}
bool test_expected_aarch64(csh *handle, cs_aarch64 *actual,
TestDetailAArch64 *expected)
{
assert(handle && actual && expected);
compare_enum_ret(actual->cc, expected->cc, false);
compare_tbool_ret(actual->update_flags, expected->update_flags, false);
compare_tbool_ret(actual->post_index, expected->post_indexed, false);
if (expected->operands_count == 0) {
return true;
}
compare_uint8_ret(actual->op_count, expected->operands_count, false);
for (size_t i = 0; i < actual->op_count; ++i) {
cs_aarch64_op *op = &actual->operands[i];
TestDetailAArch64Op *eop = expected->operands[i];
compare_enum_ret(op->type, eop->type, false);
compare_enum_ret(op->access, eop->access, false);
switch (op->type) {
default:
fprintf(stderr,
"AArch64 op type %" PRId32 " not handled.\n",
op->type);
return false;
case AARCH64_OP_REG:
compare_reg_ret(*handle, op->reg, eop->reg, false);
break;
case AARCH64_OP_IMM:
compare_int64_ret(op->imm, eop->imm, false);
break;
case AARCH64_OP_IMM_RANGE:
compare_int8_ret(op->imm_range.first,
eop->imm_range_first, false);
compare_int8_ret(op->imm_range.offset,
eop->imm_range_offset, false);
break;
case AARCH64_OP_FP:
compare_fp_ret(op->fp, eop->fp, false);
break;
case AARCH64_OP_SYSREG:
compare_enum_ret(op->sysop.sub_type, eop->sub_type,
false);
compare_int_ret(op->sysop.reg.raw_val,
eop->sys_raw_val, false);
break;
case AARCH64_OP_SYSIMM:
compare_enum_ret(op->sysop.sub_type, eop->sub_type,
false);
compare_int_ret(op->sysop.imm.raw_val,
eop->sys_raw_val, false);
if (eop->fp_set) {
compare_fp_ret(op->fp, eop->fp, false);
}
break;
case AARCH64_OP_SYSALIAS:
compare_enum_ret(op->sysop.sub_type, eop->sub_type,
false);
compare_int_ret(op->sysop.alias.raw_val,
eop->sys_raw_val, false);
break;
case AARCH64_OP_MEM:
compare_reg_ret(*handle, op->mem.base, eop->mem_base,
false);
compare_reg_ret(*handle, op->mem.index, eop->mem_index,
false);
compare_int32_ret(op->mem.disp, eop->mem_disp, false);
break;
case AARCH64_OP_PRED:
compare_reg_ret(*handle, op->pred.reg, eop->pred_reg,
false);
compare_reg_ret(*handle, op->pred.vec_select, eop->pred_vec_select,
false);
if (eop->pred_imm_index_set) {
compare_int32_ret(op->pred.imm_index, eop->pred_imm_index, false);
} else {
assert(eop->pred_imm_index == 0);
}
break;
case AARCH64_OP_SME:
compare_enum_ret(op->sme.type, eop->sme->type,
false);
compare_reg_ret(*handle, op->sme.tile, eop->sme->tile,
false);
compare_reg_ret(*handle, op->sme.slice_reg, eop->sme->slice_reg,
false);
compare_tbool_ret(op->sme.has_range_offset, eop->sme->has_range_offset,
false);
compare_tbool_ret(op->sme.is_vertical, eop->sme->is_vertical,
false);
if (eop->sme->slice_offset_imm) {
compare_int32_ret(op->sme.slice_offset.imm, eop->sme->slice_offset_imm, false);
}
if (eop->sme->slice_offset_ir_set) {
compare_int32_ret(op->sme.slice_offset.imm_range.first, eop->sme->slice_offset_ir_first, false);
compare_int32_ret(op->sme.slice_offset.imm_range.offset, eop->sme->slice_offset_ir_offset, false);
} else {
assert(eop->sme->slice_offset_ir_first == 0 && eop->sme->slice_offset_ir_offset == 0);
}
break;
}
compare_enum_ret(op->shift.type, eop->shift_type, false);
compare_uint32_ret(op->shift.value, eop->shift_value, false);
compare_enum_ret(op->ext, eop->ext, false);
compare_enum_ret(op->vas, eop->vas, false);
compare_tbool_ret(op->is_vreg, eop->is_vreg, false);
if (eop->vector_index_is_set) {
compare_int32_ret(op->vector_index, eop->vector_index,
false);
} else {
assert(eop->vector_index == 0);
}
compare_tbool_ret(op->is_list_member, eop->is_list_member,
false);
}
return true;
}
+99
View File
@@ -0,0 +1,99 @@
// Copyright © 2024 Rot127 <unisono@quyllur.org>
// SPDX-License-Identifier: BSD-3
#include "test_compare.h"
#include "test_detail_alpha.h"
#include <capstone/capstone.h>
#include <stdio.h>
#include <string.h>
TestDetailAlpha *test_detail_alpha_new()
{
return cs_mem_calloc(sizeof(TestDetailAlpha), 1);
}
void test_detail_alpha_free(TestDetailAlpha *detail)
{
if (!detail) {
return;
}
for (size_t i = 0; i < detail->operands_count; ++i) {
test_detail_alpha_op_free(detail->operands[i]);
}
cs_mem_free(detail->operands);
cs_mem_free(detail);
}
TestDetailAlpha *test_detail_alpha_clone(const TestDetailAlpha *detail)
{
TestDetailAlpha *clone = test_detail_alpha_new();
clone->operands_count = detail->operands_count;
if (detail->operands_count > 0) {
clone->operands = cs_mem_calloc(sizeof(TestDetailAlphaOp *),
detail->operands_count);
}
for (size_t i = 0; i < detail->operands_count; ++i) {
clone->operands[i] =
test_detail_alpha_op_clone(detail->operands[i]);
}
return clone;
}
TestDetailAlphaOp *test_detail_alpha_op_new()
{
return cs_mem_calloc(sizeof(TestDetailAlphaOp), 1);
}
TestDetailAlphaOp *test_detail_alpha_op_clone(const TestDetailAlphaOp *op)
{
TestDetailAlphaOp *clone = test_detail_alpha_op_new();
clone->type = op->type ? strdup(op->type) : NULL;
clone->access = op->access ? strdup(op->access) : NULL;
clone->reg = op->reg ? strdup(op->reg) : NULL;
clone->imm = op->imm;
return clone;
}
void test_detail_alpha_op_free(TestDetailAlphaOp *op)
{
if (!op) {
return;
}
cs_mem_free(op->type);
cs_mem_free(op->access);
cs_mem_free(op->reg);
cs_mem_free(op);
}
bool test_expected_alpha(csh *handle, const cs_alpha *actual,
const TestDetailAlpha *expected)
{
assert(handle && actual && expected);
compare_uint8_ret(actual->op_count, expected->operands_count, false);
for (size_t i = 0; i < actual->op_count; ++i) {
const cs_alpha_op *op = &actual->operands[i];
TestDetailAlphaOp *eop = expected->operands[i];
compare_enum_ret(op->type, eop->type, false);
compare_enum_ret(op->access, eop->access, false);
switch (op->type) {
default:
fprintf(stderr,
"alpha op type %" PRId32 " not handled.\n",
op->type);
return false;
case ALPHA_OP_REG:
compare_reg_ret(*handle, op->reg, eop->reg, false);
break;
case ALPHA_OP_IMM:
compare_int32_ret(op->imm, eop->imm, false);
break;
}
}
return true;
}
+99
View File
@@ -0,0 +1,99 @@
// Copyright © 2024 Sibirtsev Dmitry <sibirtsevdl@gmail.com>
// SPDX-License-Identifier: BSD-3
#include "test_compare.h"
#include "test_detail_arc.h"
#include <capstone/capstone.h>
#include <stdio.h>
#include <string.h>
TestDetailARC *test_detail_arc_new()
{
return cs_mem_calloc(sizeof(TestDetailARC), 1);
}
void test_detail_arc_free(TestDetailARC *detail)
{
if (!detail) {
return;
}
for (size_t i = 0; i < detail->operands_count; ++i) {
test_detail_arc_op_free(detail->operands[i]);
}
cs_mem_free(detail->operands);
cs_mem_free(detail);
}
TestDetailARC *test_detail_arc_clone(const TestDetailARC *detail)
{
TestDetailARC *clone = test_detail_arc_new();
clone->operands_count = detail->operands_count;
if (detail->operands_count > 0) {
clone->operands = cs_mem_calloc(sizeof(TestDetailARCOp *),
detail->operands_count);
}
for (size_t i = 0; i < detail->operands_count; ++i) {
clone->operands[i] =
test_detail_arc_op_clone(detail->operands[i]);
}
return clone;
}
TestDetailARCOp *test_detail_arc_op_new()
{
return cs_mem_calloc(sizeof(TestDetailARCOp), 1);
}
TestDetailARCOp *test_detail_arc_op_clone(const TestDetailARCOp *op)
{
TestDetailARCOp *clone = test_detail_arc_op_new();
clone->type = op->type ? strdup(op->type) : NULL;
clone->access = op->access ? strdup(op->access) : NULL;
clone->reg = op->reg ? strdup(op->reg) : NULL;
clone->imm = op->imm;
return clone;
}
void test_detail_arc_op_free(TestDetailARCOp *op)
{
if (!op) {
return;
}
cs_mem_free(op->type);
cs_mem_free(op->access);
cs_mem_free(op->reg);
cs_mem_free(op);
}
bool test_expected_arc(csh *handle, const cs_arc *actual,
const TestDetailARC *expected)
{
assert(handle && actual && expected);
compare_uint8_ret(actual->op_count, expected->operands_count, false);
for (size_t i = 0; i < actual->op_count; ++i) {
const cs_arc_op *op = &actual->operands[i];
TestDetailARCOp *eop = expected->operands[i];
compare_enum_ret(op->type, eop->type, false);
compare_enum_ret(op->access, eop->access, false);
switch (op->type) {
default:
fprintf(stderr,
"arc op type %" PRId32 " not handled.\n",
op->type);
return false;
case ARC_OP_REG:
compare_reg_ret(*handle, op->reg, eop->reg, false);
break;
case ARC_OP_IMM:
compare_int64_ret(op->imm, eop->imm, false);
break;
}
}
return true;
}
+256
View File
@@ -0,0 +1,256 @@
// Copyright © 2024 Rot127 <unisono@quyllur.org>
// SPDX-License-Identifier: BSD-3
#include "test_compare.h"
#include "test_detail_arm.h"
#include <capstone/capstone.h>
#include <stdio.h>
#include <string.h>
TestDetailARM *test_detail_arm_new()
{
return cs_mem_calloc(sizeof(TestDetailARM), 1);
}
void test_detail_arm_free(TestDetailARM *detail)
{
if (!detail) {
return;
}
for (size_t i = 0; i < detail->operands_count; ++i) {
test_detail_arm_op_free(detail->operands[i]);
}
cs_mem_free(detail->operands);
cs_mem_free(detail->vector_data);
cs_mem_free(detail->cps_mode);
cs_mem_free(detail->cps_flag);
cs_mem_free(detail->cc);
cs_mem_free(detail->vcc);
cs_mem_free(detail->mem_barrier);
cs_mem_free(detail);
}
TestDetailARM *test_detail_arm_clone(TestDetailARM *detail)
{
TestDetailARM *clone = test_detail_arm_new();
clone->update_flags = detail->update_flags;
clone->post_indexed = detail->post_indexed;
clone->vector_data = detail->vector_data ? strdup(detail->vector_data) : NULL;
clone->cps_mode = detail->cps_mode ? strdup(detail->cps_mode) : NULL;
clone->cps_flag = detail->cps_flag ? strdup(detail->cps_flag) : NULL;
clone->cc = detail->cc ? strdup(detail->cc) : NULL;
clone->vcc = detail->vcc ? strdup(detail->vcc) : NULL;
clone->mem_barrier = detail->mem_barrier ? strdup(detail->mem_barrier) : NULL;
clone->operands_count = detail->operands_count;
if (detail->operands_count > 0) {
clone->operands = cs_mem_calloc(sizeof(TestDetailARMOp *),
detail->operands_count);
}
for (size_t i = 0; i < detail->operands_count; ++i) {
clone->operands[i] =
test_detail_arm_op_clone(detail->operands[i]);
}
return clone;
}
TestDetailARMOp *test_detail_arm_op_new()
{
return cs_mem_calloc(sizeof(TestDetailARMOp), 1);
}
TestDetailARMOp *test_detail_arm_op_clone(TestDetailARMOp *op)
{
TestDetailARMOp *clone = test_detail_arm_op_new();
clone->type = op->type ? strdup(op->type) : NULL;
clone->access = op->access ? strdup(op->access) : NULL;
clone->reg = op->reg ? strdup(op->reg) : NULL;
clone->imm = op->imm;
clone->setend = op->setend ? strdup(op->setend) : NULL;
clone->pred = op->pred;
clone->fp = op->fp;
clone->mem_base = op->mem_base ? strdup(op->mem_base) : NULL;
clone->mem_index = op->mem_index ? strdup(op->mem_index) : NULL;
clone->mem_scale = op->mem_scale;
clone->mem_disp = op->mem_disp;
clone->mem_align = op->mem_align;
clone->sys_reg = op->sys_reg ? strdup(op->sys_reg) : NULL;
clone->sys_psr_bits_count = op->sys_psr_bits_count;
clone->sys_psr_bits =
op->sys_psr_bits_count == 0 ?
NULL :
cs_mem_calloc(sizeof(char *), op->sys_psr_bits_count);
for (size_t i = 0; i < op->sys_psr_bits_count; ++i) {
clone->sys_psr_bits[i] = strdup(op->sys_psr_bits[i]);
}
clone->sys_sysm = op->sys_sysm;
clone->sys_msr_mask = op->sys_msr_mask;
clone->shift_type = op->shift_type ? strdup(op->shift_type) : NULL;
clone->shift_value = op->shift_value;
clone->neon_lane = op->neon_lane;
clone->vector_index = op->vector_index;
clone->vector_index_is_set = op->vector_index_is_set;
clone->subtracted = op->subtracted;
return clone;
}
void test_detail_arm_op_free(TestDetailARMOp *op)
{
if (!op) {
return;
}
cs_mem_free(op->type);
cs_mem_free(op->access);
cs_mem_free(op->reg);
cs_mem_free(op->setend);
cs_mem_free(op->mem_base);
cs_mem_free(op->mem_index);
cs_mem_free(op->shift_type);
cs_mem_free(op->sys_reg);
if (op->sys_psr_bits_count != 0) {
for (size_t i = 0; i < op->sys_psr_bits_count; ++i) {
cs_mem_free(op->sys_psr_bits[i]);
}
cs_mem_free(op->sys_psr_bits);
}
cs_mem_free(op);
}
bool test_expected_arm(csh *handle, cs_arm *actual, TestDetailARM *expected)
{
assert(handle && actual && expected);
if (expected->vector_size) {
compare_int_ret(actual->vector_size, expected->vector_size,
false);
}
compare_enum_ret(actual->vector_data, expected->vector_data, false);
compare_enum_ret(actual->cps_flag, expected->cps_flag, false);
compare_enum_ret(actual->cps_mode, expected->cps_mode, false);
compare_enum_ret(actual->cc, expected->cc, false);
compare_enum_ret(actual->vcc, expected->vcc, false);
compare_enum_ret(actual->mem_barrier, expected->mem_barrier, false);
if (expected->pred_mask) {
compare_uint8_ret(actual->pred_mask, expected->pred_mask,
false);
}
compare_tbool_ret(actual->usermode, expected->usermode, false);
compare_tbool_ret(actual->update_flags, expected->update_flags, false);
compare_tbool_ret(actual->post_index, expected->post_indexed, false);
if (expected->operands_count == 0) {
return true;
}
compare_uint8_ret(actual->op_count, expected->operands_count, false);
for (size_t i = 0; i < actual->op_count; ++i) {
cs_arm_op *op = &actual->operands[i];
TestDetailARMOp *eop = expected->operands[i];
compare_enum_ret(op->type, eop->type, false);
compare_enum_ret(op->access, eop->access, false);
switch (op->type) {
default:
fprintf(stderr,
"arm op type %" PRId32 " not handled.\n",
op->type);
return false;
case ARM_OP_REG:
compare_reg_ret(*handle, op->reg, eop->reg, false);
break;
case ARM_OP_IMM:
case ARM_OP_PIMM:
case ARM_OP_CIMM:
compare_int64_ret(op->imm, eop->imm, false);
break;
case ARM_OP_PRED:
compare_int_ret(op->pred, eop->pred, false);
break;
case ARM_OP_SETEND:
compare_enum_ret(op->setend, eop->setend, false);
break;
case ARM_OP_FP:
compare_fp_ret(op->fp, eop->fp, false);
break;
case ARM_OP_SYSREG:
compare_enum_ret(op->sysop.reg.mclasssysreg,
eop->sys_reg, false);
if (eop->sys_sysm) {
compare_uint16_ret(op->sysop.sysm,
eop->sys_sysm, false);
}
if (eop->sys_msr_mask) {
compare_uint8_ret(op->sysop.msr_mask,
eop->sys_msr_mask, false);
}
break;
case ARM_OP_BANKEDREG:
compare_enum_ret(op->sysop.reg.bankedreg, eop->sys_reg,
false);
if (eop->sys_sysm) {
compare_uint16_ret(op->sysop.sysm,
eop->sys_sysm, false);
}
if (eop->sys_msr_mask) {
compare_uint8_ret(op->sysop.msr_mask,
eop->sys_msr_mask, false);
}
break;
case ARM_OP_SPSR:
case ARM_OP_CPSR:
compare_bit_flags_ret(op->sysop.psr_bits,
eop->sys_psr_bits,
eop->sys_psr_bits_count, false);
if (eop->sys_sysm) {
compare_uint16_ret(op->sysop.sysm,
eop->sys_sysm, false);
}
if (eop->sys_msr_mask) {
compare_uint8_ret(op->sysop.msr_mask,
eop->sys_msr_mask, false);
}
break;
case ARM_OP_SYSM:
if (eop->sys_sysm) {
compare_uint16_ret(op->sysop.sysm,
eop->sys_sysm, false);
}
if (eop->sys_msr_mask) {
compare_uint8_ret(op->sysop.msr_mask,
eop->sys_msr_mask, false);
}
break;
case ARM_OP_MEM:
compare_reg_ret(*handle, op->mem.base, eop->mem_base,
false);
compare_reg_ret(*handle, op->mem.index, eop->mem_index,
false);
compare_int_ret(op->mem.disp, eop->mem_disp, false);
compare_uint_ret(op->mem.align, eop->mem_align, false);
if (eop->mem_scale) {
compare_int_ret(op->mem.scale, eop->mem_scale, false);
}
break;
}
compare_enum_ret(op->shift.type, eop->shift_type, false);
if (eop->shift_value) {
compare_uint32_ret(op->shift.value, eop->shift_value,
false);
}
if (eop->neon_lane) {
compare_uint8_ret(op->neon_lane, eop->neon_lane, false);
}
if (eop->vector_index_is_set) {
compare_int32_ret(op->vector_index, eop->vector_index,
false);
} else {
assert(eop->vector_index == 0);
}
compare_tbool_ret(op->subtracted, eop->subtracted, false);
}
return true;
}
+129
View File
@@ -0,0 +1,129 @@
// Copyright © 2024 Rot127 <unisono@quyllur.org>
// SPDX-License-Identifier: BSD-3
#include "test_compare.h"
#include "test_detail_bpf.h"
#include <capstone/bpf.h>
#include <capstone/capstone.h>
#include <stdio.h>
#include <string.h>
TestDetailBPF *test_detail_bpf_new()
{
return cs_mem_calloc(sizeof(TestDetailBPF), 1);
}
void test_detail_bpf_free(TestDetailBPF *detail)
{
if (!detail) {
return;
}
for (size_t i = 0; i < detail->operands_count; ++i) {
test_detail_bpf_op_free(detail->operands[i]);
}
cs_mem_free(detail->operands);
cs_mem_free(detail);
}
TestDetailBPF *test_detail_bpf_clone(const TestDetailBPF *detail)
{
TestDetailBPF *clone = test_detail_bpf_new();
clone->operands_count = detail->operands_count;
if (detail->operands_count > 0) {
clone->operands = cs_mem_calloc(sizeof(TestDetailBPFOp *),
detail->operands_count);
}
for (size_t i = 0; i < detail->operands_count; ++i) {
clone->operands[i] =
test_detail_bpf_op_clone(detail->operands[i]);
}
return clone;
}
TestDetailBPFOp *test_detail_bpf_op_new()
{
return cs_mem_calloc(sizeof(TestDetailBPFOp), 1);
}
TestDetailBPFOp *test_detail_bpf_op_clone(const TestDetailBPFOp *op)
{
TestDetailBPFOp *clone = test_detail_bpf_op_new();
clone->type = op->type ? strdup(op->type) : NULL;
clone->access = op->access ? strdup(op->access) : NULL;
clone->reg = op->reg ? strdup(op->reg) : NULL;
clone->imm = op->imm;
clone->off = op->off;
clone->mmem = op->mmem;
clone->msh = op->msh;
clone->ext = op->ext ? strdup(op->ext) : NULL;
clone->mem_base = op->mem_base ? strdup(op->mem_base) : NULL;
clone->mem_disp = op->mem_disp;
clone->is_pkt = op->is_pkt;
clone->is_signed = op->is_signed;
return clone;
}
void test_detail_bpf_op_free(TestDetailBPFOp *op)
{
if (!op) {
return;
}
cs_mem_free(op->type);
cs_mem_free(op->access);
cs_mem_free(op->reg);
cs_mem_free(op->ext);
cs_mem_free(op->mem_base);
cs_mem_free(op);
}
bool test_expected_bpf(csh *handle, const cs_bpf *actual,
const TestDetailBPF *expected)
{
assert(handle && actual && expected);
compare_uint8_ret(actual->op_count, expected->operands_count, false);
for (size_t i = 0; i < actual->op_count; ++i) {
const cs_bpf_op *op = &actual->operands[i];
TestDetailBPFOp *eop = expected->operands[i];
compare_enum_ret(op->type, eop->type, false);
compare_enum_ret(op->access, eop->access, false);
compare_tbool_ret(op->is_pkt, eop->is_pkt, false);
compare_tbool_ret(op->is_signed, eop->is_signed, false);
switch (op->type) {
default:
fprintf(stderr,
"bpf op type %" PRId32 " not handled.\n",
op->type);
return false;
case BPF_OP_REG:
compare_reg_ret(*handle, op->reg, eop->reg, false);
break;
case BPF_OP_IMM:
compare_uint64_ret(op->imm, eop->imm, false);
break;
case BPF_OP_OFF:
compare_uint32_ret(op->off, eop->off, false);
break;
case BPF_OP_MMEM:
compare_uint32_ret(op->mmem, eop->mmem, false);
break;
case BPF_OP_MSH:
compare_uint32_ret(op->msh, eop->msh, false);
break;
case BPF_OP_EXT:
compare_enum_ret(op->ext, eop->ext, false);
break;
case BPF_OP_MEM:
compare_reg_ret(*handle, op->mem.base, eop->mem_base,
false);
compare_uint32_ret(op->mem.disp, eop->mem_disp, false);
break;
}
}
return true;
}
+40
View File
@@ -0,0 +1,40 @@
// Copyright © 2024 Rot127 <unisono@quyllur.org>
// SPDX-License-Identifier: BSD-3
#include "test_compare.h"
#include "test_detail_evm.h"
#include <capstone/capstone.h>
TestDetailEVM *test_detail_evm_new()
{
return cs_mem_calloc(sizeof(TestDetailEVM), 1);
}
void test_detail_evm_free(TestDetailEVM *detail)
{
if (!detail) {
return;
}
cs_mem_free(detail);
}
TestDetailEVM *test_detail_evm_clone(const TestDetailEVM *detail)
{
TestDetailEVM *clone = test_detail_evm_new();
clone->fee = detail->fee;
clone->pop = detail->pop;
clone->push = detail->push;
return clone;
}
bool test_expected_evm(csh *handle, const cs_evm *actual,
const TestDetailEVM *expected)
{
assert(handle && actual && expected);
compare_uint8_ret(actual->fee, expected->fee, false);
compare_uint8_ret(actual->pop, expected->pop, false);
compare_uint8_ret(actual->push, expected->push, false);
return true;
}
+118
View File
@@ -0,0 +1,118 @@
// Copyright © 2024 Rot127 <unisono@quyllur.org>
// SPDX-License-Identifier: BSD-3
#include "capstone/hppa.h"
#include "test_compare.h"
#include "test_detail_hppa.h"
#include <capstone/capstone.h>
#include <stdio.h>
#include <string.h>
TestDetailHPPA *test_detail_hppa_new()
{
return cs_mem_calloc(sizeof(TestDetailHPPA), 1);
}
void test_detail_hppa_free(TestDetailHPPA *detail)
{
if (!detail) {
return;
}
for (size_t i = 0; i < detail->operands_count; ++i) {
test_detail_hppa_op_free(detail->operands[i]);
}
cs_mem_free(detail->operands);
cs_mem_free(detail);
}
TestDetailHPPA *test_detail_hppa_clone(const TestDetailHPPA *detail)
{
TestDetailHPPA *clone = test_detail_hppa_new();
clone->operands_count = detail->operands_count;
if (detail->operands_count > 0) {
clone->operands = cs_mem_calloc(sizeof(TestDetailHPPAOp *),
detail->operands_count);
}
for (size_t i = 0; i < detail->operands_count; ++i) {
clone->operands[i] =
test_detail_hppa_op_clone(detail->operands[i]);
}
return clone;
}
TestDetailHPPAOp *test_detail_hppa_op_new()
{
return cs_mem_calloc(sizeof(TestDetailHPPAOp), 1);
}
TestDetailHPPAOp *test_detail_hppa_op_clone(const TestDetailHPPAOp *op)
{
TestDetailHPPAOp *clone = test_detail_hppa_op_new();
clone->type = op->type ? strdup(op->type) : NULL;
clone->access = op->access ? strdup(op->access) : NULL;
clone->reg = op->reg ? strdup(op->reg) : NULL;
clone->imm = op->imm;
clone->mem_base = op->mem_base ? strdup(op->mem_base) : NULL;
clone->mem_space = op->mem_space ? strdup(op->mem_space) : NULL;
clone->mem_base_access =
op->mem_base_access ? strdup(op->mem_base_access) : NULL;
return clone;
}
void test_detail_hppa_op_free(TestDetailHPPAOp *op)
{
if (!op) {
return;
}
cs_mem_free(op->type);
cs_mem_free(op->access);
cs_mem_free(op->reg);
cs_mem_free(op->mem_base);
cs_mem_free(op->mem_base_access);
cs_mem_free(op->mem_space);
cs_mem_free(op);
}
bool test_expected_hppa(csh *handle, const cs_hppa *actual,
const TestDetailHPPA *expected)
{
assert(handle && actual && expected);
compare_uint8_ret(actual->op_count, expected->operands_count, false);
for (size_t i = 0; i < actual->op_count; ++i) {
const cs_hppa_op *op = &actual->operands[i];
TestDetailHPPAOp *eop = expected->operands[i];
compare_enum_ret(op->type, eop->type, false);
compare_enum_ret(op->access, eop->access, false);
switch (op->type) {
default:
fprintf(stderr,
"hppa op type %" PRId32 " not handled.\n",
op->type);
return false;
case HPPA_OP_REG:
case HPPA_OP_IDX_REG:
compare_reg_ret(*handle, op->reg, eop->reg, false);
break;
case HPPA_OP_DISP:
case HPPA_OP_IMM:
case HPPA_OP_TARGET:
compare_int64_ret(op->imm, eop->imm, false);
break;
case HPPA_OP_MEM:
compare_reg_ret(*handle, op->mem.base, eop->mem_base,
false);
compare_reg_ret(*handle, op->mem.space, eop->mem_space,
false);
compare_enum_ret(op->mem.base_access,
eop->mem_base_access, false);
break;
}
}
return true;
}
@@ -0,0 +1,114 @@
// Copyright © 2024 Rot127 <unisono@quyllur.org>
// SPDX-License-Identifier: BSD-3
#include "test_compare.h"
#include "test_detail_loongarch.h"
#include <capstone/capstone.h>
#include <stdio.h>
#include <string.h>
TestDetailLoongArch *test_detail_loongarch_new()
{
return cs_mem_calloc(sizeof(TestDetailLoongArch), 1);
}
void test_detail_loongarch_free(TestDetailLoongArch *detail)
{
if (!detail) {
return;
}
for (size_t i = 0; i < detail->operands_count; ++i) {
test_detail_loongarch_op_free(detail->operands[i]);
}
cs_mem_free(detail->operands);
cs_mem_free(detail->format);
cs_mem_free(detail);
}
TestDetailLoongArch *
test_detail_loongarch_clone(const TestDetailLoongArch *detail)
{
TestDetailLoongArch *clone = test_detail_loongarch_new();
clone->format = detail->format ? strdup(detail->format) : NULL;
clone->operands_count = detail->operands_count;
if (detail->operands_count > 0) {
clone->operands = cs_mem_calloc(sizeof(TestDetailLoongArchOp *),
detail->operands_count);
}
for (size_t i = 0; i < detail->operands_count; ++i) {
clone->operands[i] =
test_detail_loongarch_op_clone(detail->operands[i]);
}
return clone;
}
TestDetailLoongArchOp *test_detail_loongarch_op_new()
{
return cs_mem_calloc(sizeof(TestDetailLoongArchOp), 1);
}
TestDetailLoongArchOp *
test_detail_loongarch_op_clone(const TestDetailLoongArchOp *op)
{
TestDetailLoongArchOp *clone = test_detail_loongarch_op_new();
clone->type = op->type ? strdup(op->type) : NULL;
clone->access = op->access ? strdup(op->access) : NULL;
clone->reg = op->reg ? strdup(op->reg) : NULL;
clone->imm = op->imm;
clone->mem_base = op->mem_base ? strdup(op->mem_base) : NULL;
clone->mem_disp = op->mem_disp;
return clone;
}
void test_detail_loongarch_op_free(TestDetailLoongArchOp *op)
{
if (!op) {
return;
}
cs_mem_free(op->type);
cs_mem_free(op->access);
cs_mem_free(op->reg);
cs_mem_free(op->mem_base);
cs_mem_free(op);
}
bool test_expected_loongarch(csh *handle, const cs_loongarch *actual,
const TestDetailLoongArch *expected)
{
assert(handle && actual && expected);
compare_uint8_ret(actual->op_count, expected->operands_count, false);
compare_enum_ret(actual->format, expected->format, false);
for (size_t i = 0; i < actual->op_count; ++i) {
const cs_loongarch_op *op = &actual->operands[i];
TestDetailLoongArchOp *eop = expected->operands[i];
compare_enum_ret(op->type, eop->type, false);
compare_enum_ret(op->access, eop->access, false);
switch (op->type) {
default:
fprintf(stderr,
"loongarch op type %" PRId32 " not handled.\n",
op->type);
return false;
case LOONGARCH_OP_REG:
compare_reg_ret(*handle, op->reg, eop->reg, false);
break;
case LOONGARCH_OP_IMM:
compare_uint64_ret(op->imm, eop->imm, false);
break;
case LOONGARCH_OP_MEM:
compare_reg_ret(*handle, op->mem.base, eop->mem_base,
false);
compare_reg_ret(*handle, op->mem.index, eop->mem_index,
false);
compare_int64_ret(op->mem.disp, eop->mem_disp, false);
break;
}
}
return true;
}
+215
View File
@@ -0,0 +1,215 @@
// Copyright © 2024 Rot127 <unisono@quyllur.org>
// SPDX-License-Identifier: BSD-3
#include "test_compare.h"
#include "test_detail_m680x.h"
#include <capstone/capstone.h>
#include <stdio.h>
#include <string.h>
TestDetailM680xIdx *test_detail_m680x_idx_new()
{
return cs_mem_calloc(sizeof(TestDetailM680xIdx), 1);
}
TestDetailM680xIdx *test_detail_m680x_idx_clone(const TestDetailM680xIdx *idx)
{
assert(idx);
TestDetailM680xIdx *clone = test_detail_m680x_idx_new();
clone->base_reg = idx->base_reg ? strdup(idx->base_reg) : NULL;
clone->offset_reg = idx->offset_reg ? strdup(idx->offset_reg) : NULL;
clone->flags = idx->flags_count > 0 ?
cs_mem_calloc(sizeof(char *), idx->flags_count) :
NULL;
clone->flags_count = idx->flags_count;
for (size_t i = 0; i < clone->flags_count; ++i) {
clone->flags[i] = idx->flags[i] ? strdup(idx->flags[i]) : NULL;
}
clone->offset = idx->offset;
clone->offset_addr = idx->offset_addr;
clone->offset_bits = idx->offset_bits;
clone->inc_dec = idx->inc_dec;
return clone;
}
void test_detail_m680x_idx_free(TestDetailM680xIdx *idx)
{
if (!idx) {
return;
}
cs_mem_free(idx->base_reg);
cs_mem_free(idx->offset_reg);
for (size_t i = 0; i < idx->flags_count; ++i) {
cs_mem_free(idx->flags[i]);
}
cs_mem_free(idx->flags);
cs_mem_free(idx);
}
TestDetailM680x *test_detail_m680x_new()
{
return cs_mem_calloc(sizeof(TestDetailM680x), 1);
}
void test_detail_m680x_free(TestDetailM680x *detail)
{
if (!detail) {
return;
}
for (size_t i = 0; i < detail->operands_count; ++i) {
test_detail_m680x_op_free(detail->operands[i]);
}
cs_mem_free(detail->operands);
for (size_t i = 0; i < detail->flags_count; ++i) {
cs_mem_free(detail->flags[i]);
}
cs_mem_free(detail->flags);
cs_mem_free(detail);
}
TestDetailM680x *test_detail_m680x_clone(const TestDetailM680x *detail)
{
TestDetailM680x *clone = test_detail_m680x_new();
clone->flags_count = detail->flags_count;
if (detail->flags_count > 0) {
clone->flags =
cs_mem_calloc(sizeof(char *), detail->flags_count);
}
for (size_t i = 0; i < detail->flags_count; ++i) {
clone->flags[i] = detail->flags[i] ? strdup(detail->flags[i]) :
NULL;
}
clone->operands_count = detail->operands_count;
if (detail->operands_count > 0) {
clone->operands = cs_mem_calloc(sizeof(TestDetailM680xOp *),
detail->operands_count);
}
for (size_t i = 0; i < detail->operands_count; ++i) {
clone->operands[i] =
test_detail_m680x_op_clone(detail->operands[i]);
}
return clone;
}
TestDetailM680xOp *test_detail_m680x_op_new()
{
return cs_mem_calloc(sizeof(TestDetailM680xOp), 1);
}
TestDetailM680xOp *test_detail_m680x_op_clone(const TestDetailM680xOp *op)
{
TestDetailM680xOp *clone = test_detail_m680x_op_new();
clone->type = op->type ? strdup(op->type) : NULL;
clone->access = op->access ? strdup(op->access) : NULL;
clone->reg = op->reg ? strdup(op->reg) : NULL;
clone->idx = op->idx ? test_detail_m680x_idx_clone(op->idx) : NULL;
clone->imm = op->imm;
clone->rel_address = op->rel_address;
clone->rel_offset = op->rel_offset;
clone->ext_address = op->ext_address;
clone->ext_indirect = op->ext_indirect;
clone->direct_addr = op->direct_addr;
clone->direct_addr_set = op->direct_addr_set;
clone->const_val = op->const_val;
clone->size = op->size;
return clone;
}
void test_detail_m680x_op_free(TestDetailM680xOp *op)
{
if (!op) {
return;
}
cs_mem_free(op->type);
cs_mem_free(op->access);
cs_mem_free(op->reg);
test_detail_m680x_idx_free(op->idx);
cs_mem_free(op);
}
bool test_expected_m680x(csh *handle, const cs_m680x *actual,
const TestDetailM680x *expected)
{
assert(handle && actual && expected);
compare_uint8_ret(actual->op_count, expected->operands_count, false);
for (size_t i = 0; i < actual->op_count; ++i) {
const cs_m680x_op *op = &actual->operands[i];
TestDetailM680xOp *eop = expected->operands[i];
compare_enum_ret(op->type, eop->type, false);
compare_enum_ret(op->access, eop->access, false);
if (eop->size > 0) {
compare_uint8_ret(op->size, eop->size, false);
}
switch (op->type) {
default:
fprintf(stderr,
"m680x op type %" PRId32 " not handled.\n",
op->type);
return false;
case M680X_OP_REGISTER:
compare_reg_ret(*handle, op->reg, eop->reg, false);
break;
case M680X_OP_IMMEDIATE:
compare_int32_ret(op->imm, eop->imm, false);
break;
case M680X_OP_EXTENDED:
compare_uint16_ret(op->ext.address, eop->ext_address,
false);
compare_tbool_ret(op->ext.indirect, eop->ext_indirect,
false);
break;
case M680X_OP_DIRECT:
if (eop->direct_addr_set) {
compare_uint8_ret(op->direct_addr,
eop->direct_addr, false);
} else {
assert(eop->direct_addr == 0);
}
break;
case M680X_OP_RELATIVE:
compare_uint16_ret(op->rel.address, eop->rel_address,
false);
compare_int16_ret(op->rel.offset, eop->rel_offset,
false);
break;
case M680X_OP_CONSTANT:
compare_uint8_ret(op->const_val, eop->const_val, false);
break;
case M680X_OP_INDEXED:
if (!eop->idx) {
break;
}
compare_reg_ret(*handle, op->idx.base_reg,
eop->idx->base_reg, false);
compare_reg_ret(*handle, op->idx.offset_reg,
eop->idx->offset_reg, false);
if (eop->idx->offset) {
compare_int16_ret(op->idx.offset,
eop->idx->offset, false);
}
if (eop->idx->offset_addr) {
compare_uint16_ret(op->idx.offset_addr,
eop->idx->offset_addr,
false);
}
if (eop->idx->offset_bits) {
compare_uint8_ret(op->idx.offset_bits,
eop->idx->offset_bits, false);
}
if (eop->idx->inc_dec) {
compare_int8_ret(op->idx.inc_dec,
eop->idx->inc_dec, false);
}
compare_bit_flags_ret(op->idx.flags, eop->idx->flags,
eop->idx->flags_count, false);
break;
}
}
return true;
}
+226
View File
@@ -0,0 +1,226 @@
// Copyright © 2024 Rot127 <unisono@quyllur.org>
// SPDX-License-Identifier: BSD-3
#include "capstone/m68k.h"
#include "test_compare.h"
#include "test_detail_m68k.h"
#include <capstone/capstone.h>
#include <stdio.h>
#include <string.h>
TestDetailM68KOpMem *test_detail_m68k_op_mem_new()
{
return cs_mem_calloc(sizeof(TestDetailM68KOpMem), 1);
}
TestDetailM68KOpMem *test_detail_m68k_op_mem_clone(TestDetailM68KOpMem *mem)
{
assert(mem);
TestDetailM68KOpMem *clone = test_detail_m68k_op_mem_new();
clone->base_reg = mem->base_reg ? strdup(mem->base_reg) : NULL;
clone->index_reg = mem->index_reg ? strdup(mem->index_reg) : NULL;
clone->in_base_reg = mem->in_base_reg ? strdup(mem->in_base_reg) : NULL;
clone->index_size = mem->index_size;
clone->disp = mem->disp;
clone->in_disp = mem->in_disp;
clone->out_disp = mem->out_disp;
clone->scale = mem->scale;
clone->bitfield = mem->bitfield;
clone->width = mem->width;
clone->offset = mem->offset;
return clone;
}
void test_detail_m68k_op_mem_free(TestDetailM68KOpMem *mem)
{
if (!mem) {
return;
}
cs_mem_free(mem->base_reg);
cs_mem_free(mem->index_reg);
cs_mem_free(mem->in_base_reg);
cs_mem_free(mem);
}
TestDetailM68K *test_detail_m68k_new()
{
return cs_mem_calloc(sizeof(TestDetailM68K), 1);
}
void test_detail_m68k_free(TestDetailM68K *detail)
{
if (!detail) {
return;
}
for (size_t i = 0; i < detail->operands_count; ++i) {
test_detail_m68k_op_free(detail->operands[i]);
}
cs_mem_free(detail->operands);
cs_mem_free(detail->op_size_type);
cs_mem_free(detail->op_size_fpu);
cs_mem_free(detail->op_size_cpu);
cs_mem_free(detail);
}
TestDetailM68K *test_detail_m68k_clone(TestDetailM68K *detail)
{
TestDetailM68K *clone = test_detail_m68k_new();
clone->op_size_type =
detail->op_size_type ? strdup(detail->op_size_type) : NULL;
clone->op_size_fpu = detail->op_size_fpu ? strdup(detail->op_size_fpu) :
NULL;
clone->op_size_cpu = detail->op_size_cpu ? strdup(detail->op_size_cpu) :
NULL;
clone->operands_count = detail->operands_count;
if (detail->operands_count > 0) {
clone->operands = cs_mem_calloc(sizeof(TestDetailM68KOp *),
detail->operands_count);
}
for (size_t i = 0; i < detail->operands_count; ++i) {
clone->operands[i] =
test_detail_m68k_op_clone(detail->operands[i]);
}
return clone;
}
TestDetailM68KOp *test_detail_m68k_op_new()
{
return cs_mem_calloc(sizeof(TestDetailM68KOp), 1);
}
TestDetailM68KOp *test_detail_m68k_op_clone(TestDetailM68KOp *op)
{
TestDetailM68KOp *clone = test_detail_m68k_op_new();
clone->type = op->type ? strdup(op->type) : NULL;
clone->reg = op->reg ? strdup(op->reg) : NULL;
clone->reg_pair_0 = op->reg_pair_0 ? strdup(op->reg_pair_0) : NULL;
clone->reg_pair_1 = op->reg_pair_1 ? strdup(op->reg_pair_1) : NULL;
clone->address_mode = op->address_mode ? strdup(op->address_mode) :
NULL;
clone->imm = op->imm;
clone->dimm = op->dimm;
clone->simm = op->simm;
clone->br_disp = op->br_disp;
clone->br_disp_size = op->br_disp_size;
clone->register_bits = op->register_bits;
clone->mem = op->mem ? test_detail_m68k_op_mem_clone(op->mem) : NULL;
return clone;
}
void test_detail_m68k_op_free(TestDetailM68KOp *op)
{
if (!op) {
return;
}
cs_mem_free(op->type);
cs_mem_free(op->reg);
cs_mem_free(op->reg_pair_0);
cs_mem_free(op->reg_pair_1);
cs_mem_free(op->address_mode);
test_detail_m68k_op_mem_free(op->mem);
cs_mem_free(op);
}
bool test_expected_m68k(csh *handle, cs_m68k *actual, TestDetailM68K *expected)
{
assert(handle && actual && expected);
compare_uint8_ret(actual->op_count, expected->operands_count, false);
compare_enum_ret(actual->op_size.type, expected->op_size_type, false);
compare_enum_ret(actual->op_size.fpu_size, expected->op_size_fpu,
false);
compare_enum_ret(actual->op_size.cpu_size, expected->op_size_cpu,
false);
for (size_t i = 0; i < actual->op_count; ++i) {
cs_m68k_op *op = &actual->operands[i];
TestDetailM68KOp *eop = expected->operands[i];
compare_enum_ret(op->type, eop->type, false);
compare_enum_ret(op->address_mode, eop->address_mode, false);
switch (op->type) {
default:
fprintf(stderr,
"M68K op type %" PRId32 " not handled.\n",
op->type);
return false;
case M68K_OP_REG:
compare_reg_ret(*handle, op->reg, eop->reg, false);
break;
case M68K_OP_REG_PAIR:
compare_reg_ret(*handle, op->reg_pair.reg_0,
eop->reg_pair_0, false);
compare_reg_ret(*handle, op->reg_pair.reg_1,
eop->reg_pair_1, false);
break;
case M68K_OP_IMM:
compare_uint64_ret(op->imm, eop->imm, false);
break;
case M68K_OP_FP_SINGLE:
compare_fp_ret(op->simm, eop->simm, false);
break;
case M68K_OP_FP_DOUBLE:
compare_fp_ret(op->dimm, eop->dimm, false);
break;
case M68K_OP_REG_BITS:
compare_uint32_ret(op->register_bits,
eop->register_bits, false);
break;
case M68K_OP_BR_DISP:
compare_int32_ret(op->br_disp.disp, eop->br_disp,
false);
compare_uint8_ret(op->br_disp.disp_size,
eop->br_disp_size, false);
break;
case M68K_OP_MEM:
if (!eop->mem) {
break;
}
compare_reg_ret(*handle, op->mem.base_reg,
eop->mem->base_reg, false);
compare_reg_ret(*handle, op->mem.index_reg,
eop->mem->index_reg, false);
compare_reg_ret(*handle, op->mem.in_base_reg,
eop->mem->in_base_reg, false);
compare_tbool_ret(op->mem.index_size,
eop->mem->index_size, false);
if (eop->mem->in_disp) {
compare_uint32_ret(op->mem.in_disp,
eop->mem->in_disp, false);
}
if (eop->mem->out_disp) {
compare_uint32_ret(op->mem.out_disp,
eop->mem->out_disp, false);
}
if (eop->mem->disp) {
compare_int16_ret(op->mem.disp, eop->mem->disp,
false);
}
if (eop->mem->scale) {
compare_uint8_ret(op->mem.scale,
eop->mem->scale, false);
}
if (eop->mem->bitfield) {
compare_uint8_ret(op->mem.bitfield,
eop->mem->bitfield, false);
}
if (eop->mem->width) {
compare_uint8_ret(op->mem.width,
eop->mem->width, false);
}
if (eop->mem->offset) {
compare_uint8_ret(op->mem.offset,
eop->mem->offset, false);
}
break;
}
}
return true;
}
+106
View File
@@ -0,0 +1,106 @@
// Copyright © 2024 Rot127 <unisono@quyllur.org>
// SPDX-License-Identifier: BSD-3
#include "test_compare.h"
#include "test_detail_mips.h"
#include <capstone/capstone.h>
#include <stdio.h>
#include <string.h>
TestDetailMips *test_detail_mips_new()
{
return cs_mem_calloc(sizeof(TestDetailMips), 1);
}
void test_detail_mips_free(TestDetailMips *detail)
{
if (!detail) {
return;
}
for (size_t i = 0; i < detail->operands_count; ++i) {
test_detail_mips_op_free(detail->operands[i]);
}
cs_mem_free(detail->operands);
cs_mem_free(detail);
}
TestDetailMips *test_detail_mips_clone(const TestDetailMips *detail)
{
TestDetailMips *clone = test_detail_mips_new();
clone->operands_count = detail->operands_count;
if (detail->operands_count > 0) {
clone->operands = cs_mem_calloc(sizeof(TestDetailMipsOp *),
detail->operands_count);
}
for (size_t i = 0; i < detail->operands_count; ++i) {
clone->operands[i] =
test_detail_mips_op_clone(detail->operands[i]);
}
return clone;
}
TestDetailMipsOp *test_detail_mips_op_new()
{
return cs_mem_calloc(sizeof(TestDetailMipsOp), 1);
}
TestDetailMipsOp *test_detail_mips_op_clone(const TestDetailMipsOp *op)
{
TestDetailMipsOp *clone = test_detail_mips_op_new();
clone->type = op->type ? strdup(op->type) : NULL;
clone->access = op->access ? strdup(op->access) : NULL;
clone->reg = op->reg ? strdup(op->reg) : NULL;
clone->imm = op->imm;
clone->mem_base = op->mem_base ? strdup(op->mem_base) : NULL;
clone->mem_disp = op->mem_disp;
return clone;
}
void test_detail_mips_op_free(TestDetailMipsOp *op)
{
if (!op) {
return;
}
cs_mem_free(op->type);
cs_mem_free(op->access);
cs_mem_free(op->reg);
cs_mem_free(op->mem_base);
cs_mem_free(op);
}
bool test_expected_mips(csh *handle, const cs_mips *actual,
const TestDetailMips *expected)
{
assert(handle && actual && expected);
compare_uint8_ret(actual->op_count, expected->operands_count, false);
for (size_t i = 0; i < actual->op_count; ++i) {
const cs_mips_op *op = &actual->operands[i];
TestDetailMipsOp *eop = expected->operands[i];
compare_enum_ret(op->type, eop->type, false);
compare_enum_ret(op->access, eop->access, false);
switch (op->type) {
default:
fprintf(stderr, "sh op type %" PRId32 " not handled.\n",
op->type);
return false;
case MIPS_OP_REG:
compare_reg_ret(*handle, op->reg, eop->reg, false);
break;
case MIPS_OP_IMM:
compare_uint64_ret(op->imm, eop->imm, false);
break;
case MIPS_OP_MEM:
compare_reg_ret(*handle, op->mem.base, eop->mem_base,
false);
compare_int64_ret(op->mem.disp, eop->mem_disp, false);
break;
}
}
return true;
}
+105
View File
@@ -0,0 +1,105 @@
// Copyright © 2024 Rot127 <unisono@quyllur.org>
// SPDX-License-Identifier: BSD-3
#include "test_compare.h"
#include "test_detail_mos65xx.h"
#include <capstone/capstone.h>
#include <stdio.h>
#include <string.h>
TestDetailMos65xx *test_detail_mos65xx_new()
{
return cs_mem_calloc(sizeof(TestDetailMos65xx), 1);
}
void test_detail_mos65xx_free(TestDetailMos65xx *detail)
{
if (!detail) {
return;
}
for (size_t i = 0; i < detail->operands_count; ++i) {
test_detail_mos65xx_op_free(detail->operands[i]);
}
cs_mem_free(detail->operands);
cs_mem_free(detail->am);
cs_mem_free(detail);
}
TestDetailMos65xx *test_detail_mos65xx_clone(const TestDetailMos65xx *detail)
{
TestDetailMos65xx *clone = test_detail_mos65xx_new();
clone->operands_count = detail->operands_count;
if (detail->operands_count > 0) {
clone->operands = cs_mem_calloc(sizeof(TestDetailMos65xxOp *),
detail->operands_count);
}
for (size_t i = 0; i < detail->operands_count; ++i) {
clone->operands[i] =
test_detail_mos65xx_op_clone(detail->operands[i]);
}
clone->am = detail->am ? strdup(detail->am) : NULL;
clone->modifies_flags = detail->modifies_flags;
return clone;
}
TestDetailMos65xxOp *test_detail_mos65xx_op_new()
{
return cs_mem_calloc(sizeof(TestDetailMos65xxOp), 1);
}
TestDetailMos65xxOp *test_detail_mos65xx_op_clone(const TestDetailMos65xxOp *op)
{
TestDetailMos65xxOp *clone = test_detail_mos65xx_op_new();
clone->type = op->type ? strdup(op->type) : NULL;
clone->reg = op->reg ? strdup(op->reg) : NULL;
clone->imm = op->imm;
clone->mem = op->mem;
return clone;
}
void test_detail_mos65xx_op_free(TestDetailMos65xxOp *op)
{
if (!op) {
return;
}
cs_mem_free(op->type);
cs_mem_free(op->reg);
cs_mem_free(op);
}
bool test_expected_mos65xx(csh *handle, const cs_mos65xx *actual,
const TestDetailMos65xx *expected)
{
assert(handle && actual && expected);
compare_uint8_ret(actual->op_count, expected->operands_count, false);
compare_enum_ret(actual->am, expected->am, false);
compare_tbool_ret(actual->modifies_flags, expected->modifies_flags,
false);
for (size_t i = 0; i < actual->op_count; ++i) {
const cs_mos65xx_op *op = &actual->operands[i];
TestDetailMos65xxOp *eop = expected->operands[i];
compare_enum_ret(op->type, eop->type, false);
switch (op->type) {
default:
fprintf(stderr, "sh op type %" PRId32 " not handled.\n",
op->type);
return false;
case MOS65XX_OP_REG:
compare_reg_ret(*handle, op->reg, eop->reg, false);
break;
case MOS65XX_OP_IMM:
compare_uint16_ret(op->imm, eop->imm, false);
break;
case MOS65XX_OP_MEM:
compare_uint16_ret(op->mem, eop->mem, false);
break;
}
}
return true;
}
+185
View File
@@ -0,0 +1,185 @@
// Copyright © 2024 Rot127 <unisono@quyllur.org>
// SPDX-License-Identifier: BSD-3
#include "test_compare.h"
#include "test_detail_ppc.h"
#include <capstone/capstone.h>
#include <stdio.h>
#include <string.h>
TestDetailPPCBC *test_detail_ppc_bc_new()
{
return cs_mem_calloc(sizeof(TestDetailPPCBC), 1);
}
TestDetailPPCBC *test_detail_ppc_bc_clone(const TestDetailPPCBC *bc)
{
assert(bc);
TestDetailPPCBC *clone = test_detail_ppc_bc_new();
clone->bh = bc->bh ? strdup(bc->bh) : NULL;
clone->crX = bc->crX ? strdup(bc->crX) : NULL;
clone->crX_bit = bc->crX_bit ? strdup(bc->crX_bit) : NULL;
clone->hint = bc->hint ? strdup(bc->hint) : NULL;
clone->pred_cr = bc->pred_cr ? strdup(bc->pred_cr) : NULL;
clone->pred_ctr = bc->pred_ctr ? strdup(bc->pred_ctr) : NULL;
clone->bi = bc->bi;
clone->bi_set = bc->bi_set;
clone->bo = bc->bo;
clone->bo_set = bc->bo_set;
return clone;
}
void test_detail_ppc_bc_free(TestDetailPPCBC *bc)
{
if (!bc) {
return;
}
cs_mem_free(bc->bh);
cs_mem_free(bc->crX);
cs_mem_free(bc->crX_bit);
cs_mem_free(bc->hint);
cs_mem_free(bc->pred_cr);
cs_mem_free(bc->pred_ctr);
cs_mem_free(bc);
}
TestDetailPPC *test_detail_ppc_new()
{
return cs_mem_calloc(sizeof(TestDetailPPC), 1);
}
void test_detail_ppc_free(TestDetailPPC *detail)
{
if (!detail) {
return;
}
test_detail_ppc_bc_free(detail->bc);
for (size_t i = 0; i < detail->operands_count; ++i) {
test_detail_ppc_op_free(detail->operands[i]);
}
cs_mem_free(detail->operands);
cs_mem_free(detail->format);
cs_mem_free(detail);
}
TestDetailPPC *test_detail_ppc_clone(const TestDetailPPC *detail)
{
TestDetailPPC *clone = test_detail_ppc_new();
clone->format = detail->format ? strdup(detail->format) : NULL;
clone->update_cr0 = detail->update_cr0;
clone->bc = detail->bc ? test_detail_ppc_bc_clone(detail->bc) : NULL;
clone->operands_count = detail->operands_count;
if (detail->operands_count > 0) {
clone->operands = cs_mem_calloc(sizeof(TestDetailPPCOp *),
detail->operands_count);
}
for (size_t i = 0; i < detail->operands_count; ++i) {
clone->operands[i] =
test_detail_ppc_op_clone(detail->operands[i]);
}
return clone;
}
TestDetailPPCOp *test_detail_ppc_op_new()
{
return cs_mem_calloc(sizeof(TestDetailPPCOp), 1);
}
TestDetailPPCOp *test_detail_ppc_op_clone(const TestDetailPPCOp *op)
{
TestDetailPPCOp *clone = test_detail_ppc_op_new();
clone->type = op->type ? strdup(op->type) : NULL;
clone->access = op->access ? strdup(op->access) : NULL;
clone->reg = op->reg ? strdup(op->reg) : NULL;
clone->imm = op->imm;
clone->mem_base = op->mem_base ? strdup(op->mem_base) : NULL;
clone->mem_offset = op->mem_offset ? strdup(op->mem_offset) : NULL;
clone->mem_disp = op->mem_disp;
return clone;
}
void test_detail_ppc_op_free(TestDetailPPCOp *op)
{
if (!op) {
return;
}
cs_mem_free(op->type);
cs_mem_free(op->access);
cs_mem_free(op->reg);
cs_mem_free(op->mem_base);
cs_mem_free(op->mem_offset);
cs_mem_free(op);
}
bool test_expected_ppc(csh *handle, const cs_ppc *actual,
const TestDetailPPC *expected)
{
assert(handle && actual && expected);
compare_enum_ret(actual->format, expected->format, false);
compare_tbool_ret(actual->update_cr0, expected->update_cr0, false);
if (expected->operands_count == 0) {
return true;
}
compare_uint8_ret(actual->op_count, expected->operands_count, false);
for (size_t i = 0; i < actual->op_count; ++i) {
const cs_ppc_op *op = &actual->operands[i];
TestDetailPPCOp *eop = expected->operands[i];
compare_enum_ret(op->type, eop->type, false);
compare_enum_ret(op->access, eop->access, false);
switch (op->type) {
default:
fprintf(stderr,
"arm op type %" PRId32 " not handled.\n",
op->type);
return false;
case PPC_OP_REG:
compare_reg_ret(*handle, op->reg, eop->reg, false);
break;
case PPC_OP_IMM:
compare_int64_ret(op->imm, eop->imm, false);
break;
case PPC_OP_MEM:
compare_reg_ret(*handle, op->mem.base, eop->mem_base,
false);
compare_reg_ret(*handle, op->mem.offset,
eop->mem_offset, false);
compare_int_ret(op->mem.disp, eop->mem_disp, false);
break;
}
if (expected->bc) {
if (expected->bc->bi_set) {
compare_uint8_ret(actual->bc.bi,
expected->bc->bi, false);
} else {
assert(expected->bc->bi == 0);
}
if (expected->bc->bo_set) {
compare_uint8_ret(actual->bc.bo,
expected->bc->bo, false);
} else {
assert(expected->bc->bo == 0);
}
compare_enum_ret(actual->bc.bh, expected->bc->bh,
false);
compare_reg_ret(*handle, actual->bc.crX,
expected->bc->crX, false);
compare_enum_ret(actual->bc.crX_bit,
expected->bc->crX_bit, false);
compare_enum_ret(actual->bc.hint, expected->bc->hint,
false);
compare_enum_ret(actual->bc.pred_cr,
expected->bc->pred_cr, false);
compare_enum_ret(actual->bc.pred_ctr,
expected->bc->pred_ctr, false);
}
}
return true;
}
+106
View File
@@ -0,0 +1,106 @@
// Copyright © 2024 Rot127 <unisono@quyllur.org>
// SPDX-License-Identifier: BSD-3
#include "test_compare.h"
#include "test_detail_riscv.h"
#include <capstone/capstone.h>
#include <stdio.h>
#include <string.h>
TestDetailRISCV *test_detail_riscv_new()
{
return cs_mem_calloc(sizeof(TestDetailRISCV), 1);
}
void test_detail_riscv_free(TestDetailRISCV *detail)
{
if (!detail) {
return;
}
for (size_t i = 0; i < detail->operands_count; ++i) {
test_detail_riscv_op_free(detail->operands[i]);
}
cs_mem_free(detail->operands);
cs_mem_free(detail);
}
TestDetailRISCV *test_detail_riscv_clone(const TestDetailRISCV *detail)
{
TestDetailRISCV *clone = test_detail_riscv_new();
clone->operands_count = detail->operands_count;
if (detail->operands_count > 0) {
clone->operands = cs_mem_calloc(sizeof(TestDetailRISCVOp *),
detail->operands_count);
}
for (size_t i = 0; i < detail->operands_count; ++i) {
clone->operands[i] =
test_detail_riscv_op_clone(detail->operands[i]);
}
return clone;
}
TestDetailRISCVOp *test_detail_riscv_op_new()
{
return cs_mem_calloc(sizeof(TestDetailRISCVOp), 1);
}
TestDetailRISCVOp *test_detail_riscv_op_clone(const TestDetailRISCVOp *op)
{
TestDetailRISCVOp *clone = test_detail_riscv_op_new();
clone->type = op->type ? strdup(op->type) : NULL;
clone->access = op->access ? strdup(op->access) : NULL;
clone->reg = op->reg ? strdup(op->reg) : NULL;
clone->imm = op->imm;
clone->mem_base = op->mem_base ? strdup(op->mem_base) : NULL;
clone->mem_disp = op->mem_disp;
return clone;
}
void test_detail_riscv_op_free(TestDetailRISCVOp *op)
{
if (!op) {
return;
}
cs_mem_free(op->type);
cs_mem_free(op->access);
cs_mem_free(op->reg);
cs_mem_free(op->mem_base);
cs_mem_free(op);
}
bool test_expected_riscv(csh *handle, const cs_riscv *actual,
const TestDetailRISCV *expected)
{
assert(handle && actual && expected);
compare_uint8_ret(actual->op_count, expected->operands_count, false);
for (size_t i = 0; i < actual->op_count; ++i) {
const cs_riscv_op *op = &actual->operands[i];
TestDetailRISCVOp *eop = expected->operands[i];
compare_enum_ret(op->type, eop->type, false);
compare_enum_ret(op->access, eop->access, false);
switch (op->type) {
default:
fprintf(stderr, "sh op type %" PRId32 " not handled.\n",
op->type);
return false;
case RISCV_OP_REG:
compare_reg_ret(*handle, op->reg, eop->reg, false);
break;
case RISCV_OP_IMM:
compare_uint64_ret(op->imm, eop->imm, false);
break;
case RISCV_OP_MEM:
compare_reg_ret(*handle, op->mem.base, eop->mem_base,
false);
compare_int64_ret(op->mem.disp, eop->mem_disp, false);
break;
}
}
return true;
}
+107
View File
@@ -0,0 +1,107 @@
// Copyright © 2024 Rot127 <unisono@quyllur.org>
// SPDX-License-Identifier: BSD-3
#include "test_compare.h"
#include "test_detail_sh.h"
#include <capstone/capstone.h>
#include <stdio.h>
#include <string.h>
TestDetailSH *test_detail_sh_new()
{
return cs_mem_calloc(sizeof(TestDetailSH), 1);
}
void test_detail_sh_free(TestDetailSH *detail)
{
if (!detail) {
return;
}
for (size_t i = 0; i < detail->operands_count; ++i) {
test_detail_sh_op_free(detail->operands[i]);
}
cs_mem_free(detail->operands);
cs_mem_free(detail);
}
TestDetailSH *test_detail_sh_clone(const TestDetailSH *detail)
{
TestDetailSH *clone = test_detail_sh_new();
clone->operands_count = detail->operands_count;
if (detail->operands_count > 0) {
clone->operands = cs_mem_calloc(sizeof(TestDetailSHOp *),
detail->operands_count);
}
for (size_t i = 0; i < detail->operands_count; ++i) {
clone->operands[i] =
test_detail_sh_op_clone(detail->operands[i]);
}
return clone;
}
TestDetailSHOp *test_detail_sh_op_new()
{
return cs_mem_calloc(sizeof(TestDetailSHOp), 1);
}
TestDetailSHOp *test_detail_sh_op_clone(const TestDetailSHOp *op)
{
TestDetailSHOp *clone = test_detail_sh_op_new();
clone->type = op->type ? strdup(op->type) : NULL;
clone->reg = op->reg ? strdup(op->reg) : NULL;
clone->imm = op->imm;
clone->mem_reg = op->mem_reg ? strdup(op->mem_reg) : NULL;
clone->mem_address = op->mem_address ? strdup(op->mem_address) : NULL;
clone->mem_disp = op->mem_disp;
return clone;
}
void test_detail_sh_op_free(TestDetailSHOp *op)
{
if (!op) {
return;
}
cs_mem_free(op->type);
cs_mem_free(op->reg);
cs_mem_free(op->mem_reg);
cs_mem_free(op->mem_address);
cs_mem_free(op);
}
bool test_expected_sh(csh *handle, const cs_sh *actual,
const TestDetailSH *expected)
{
assert(handle && actual && expected);
compare_uint8_ret(actual->op_count, expected->operands_count, false);
for (size_t i = 0; i < actual->op_count; ++i) {
const cs_sh_op *op = &actual->operands[i];
TestDetailSHOp *eop = expected->operands[i];
compare_enum_ret(op->type, eop->type, false);
switch (op->type) {
default:
fprintf(stderr, "sh op type %" PRId32 " not handled.\n",
op->type);
return false;
case SH_OP_REG:
compare_reg_ret(*handle, op->reg, eop->reg, false);
break;
case SH_OP_IMM:
compare_uint64_ret(op->imm, eop->imm, false);
break;
case SH_OP_MEM:
compare_reg_ret(*handle, op->mem.reg, eop->mem_reg,
false);
compare_reg_ret(*handle, op->mem.address,
eop->mem_address, false);
compare_int_ret(op->mem.disp, eop->mem_disp, false);
break;
}
}
return true;
}
+141
View File
@@ -0,0 +1,141 @@
// Copyright © 2024 Rot127 <unisono@quyllur.org>
// SPDX-License-Identifier: BSD-3
#include "test_compare.h"
#include "test_detail_sparc.h"
#include <capstone/capstone.h>
#include <stdio.h>
#include <string.h>
TestDetailSparc *test_detail_sparc_new()
{
return cs_mem_calloc(sizeof(TestDetailSparc), 1);
}
void test_detail_sparc_free(TestDetailSparc *detail)
{
if (!detail) {
return;
}
for (size_t i = 0; i < detail->operands_count; ++i) {
test_detail_sparc_op_free(detail->operands[i]);
}
cs_mem_free(detail->operands);
cs_mem_free(detail->cc);
cs_mem_free(detail->cc_field);
cs_mem_free(detail->hint);
cs_mem_free(detail);
}
TestDetailSparc *test_detail_sparc_clone(const TestDetailSparc *detail)
{
TestDetailSparc *clone = test_detail_sparc_new();
clone->operands_count = detail->operands_count;
clone->cc = detail->cc ? strdup(detail->cc) : NULL;
clone->cc_field = detail->cc_field ? strdup(detail->cc_field) : NULL;
clone->hint = detail->hint ? strdup(detail->hint) : NULL;
if (detail->operands_count > 0) {
clone->operands = cs_mem_calloc(sizeof(TestDetailSparcOp *),
detail->operands_count);
}
for (size_t i = 0; i < detail->operands_count; ++i) {
clone->operands[i] =
test_detail_sparc_op_clone(detail->operands[i]);
}
return clone;
}
TestDetailSparcOp *test_detail_sparc_op_new()
{
return cs_mem_calloc(sizeof(TestDetailSparcOp), 1);
}
TestDetailSparcOp *test_detail_sparc_op_clone(const TestDetailSparcOp *op)
{
TestDetailSparcOp *clone = test_detail_sparc_op_new();
clone->type = op->type ? strdup(op->type) : NULL;
clone->access = op->access ? strdup(op->access) : NULL;
clone->reg = op->reg ? strdup(op->reg) : NULL;
clone->imm = op->imm;
clone->mem_base = op->mem_base ? strdup(op->mem_base) : NULL;
clone->mem_index = op->mem_index ? strdup(op->mem_index) : NULL;
clone->mem_disp = op->mem_disp;
clone->asi = op->asi ? strdup(op->asi) : NULL;
clone->membar_tag = op->membar_tag ? strdup(op->membar_tag) : NULL;
return clone;
}
void test_detail_sparc_op_free(TestDetailSparcOp *op)
{
if (!op) {
return;
}
cs_mem_free(op->type);
cs_mem_free(op->access);
cs_mem_free(op->reg);
cs_mem_free(op->mem_base);
cs_mem_free(op->mem_index);
cs_mem_free(op->asi);
cs_mem_free(op->membar_tag);
cs_mem_free(op);
}
bool test_expected_sparc(csh *handle, const cs_sparc *actual,
const TestDetailSparc *expected)
{
assert(handle && actual && expected);
if (expected->cc) {
compare_enum_ret(actual->cc, expected->cc, false);
}
if (expected->cc_field) {
compare_enum_ret(actual->cc_field, expected->cc_field, false);
}
if (expected->hint) {
compare_enum_ret(actual->hint, expected->hint, false);
}
if (expected->operands_count == 0) {
return true;
}
compare_uint8_ret(actual->op_count, expected->operands_count, false);
for (size_t i = 0; i < expected->operands_count; ++i) {
const cs_sparc_op *op = &actual->operands[i];
TestDetailSparcOp *eop = expected->operands[i];
compare_enum_ret(op->type, eop->type, false);
compare_enum_ret(op->access, eop->access, false);
switch (op->type) {
default:
fprintf(stderr,
"arm op type %" PRId32 " not handled.\n",
op->type);
return false;
case SPARC_OP_REG:
compare_reg_ret(*handle, op->reg, eop->reg, false);
break;
case SPARC_OP_IMM:
compare_int64_ret(op->imm, eop->imm, false);
break;
case SPARC_OP_MEM:
compare_reg_ret(*handle, op->mem.base, eop->mem_base,
false);
compare_reg_ret(*handle, op->mem.index, eop->mem_index,
false);
compare_int32_ret(op->mem.disp, eop->mem_disp, false);
break;
case SPARC_OP_ASI:
compare_enum_ret(op->asi, eop->asi, false);
break;
case SPARC_OP_MEMBAR_TAG:
compare_enum_ret(op->membar_tag, eop->membar_tag, false);
break;
}
}
return true;
}
+148
View File
@@ -0,0 +1,148 @@
// Copyright © 2024 Rot127 <unisono@quyllur.org>
// SPDX-License-Identifier: BSD-3
#include "test_compare.h"
#include "test_detail_systemz.h"
#include <capstone/capstone.h>
#include <stdio.h>
#include <string.h>
TestDetailSystemZ *test_detail_systemz_new()
{
return cs_mem_calloc(sizeof(TestDetailSystemZ), 1);
}
void test_detail_systemz_free(TestDetailSystemZ *detail)
{
if (!detail) {
return;
}
cs_mem_free(detail->format);
for (size_t i = 0; i < detail->operands_count; ++i) {
test_detail_systemz_op_free(detail->operands[i]);
}
cs_mem_free(detail->operands);
cs_mem_free(detail);
}
TestDetailSystemZ *test_detail_systemz_clone(const TestDetailSystemZ *detail)
{
TestDetailSystemZ *clone = test_detail_systemz_new();
clone->format = detail->format ? strdup(detail->format) : NULL;
clone->operands_count = detail->operands_count;
if (detail->operands_count > 0) {
clone->operands = cs_mem_calloc(sizeof(TestDetailSystemZOp *),
detail->operands_count);
}
for (size_t i = 0; i < detail->operands_count; ++i) {
clone->operands[i] =
test_detail_systemz_op_clone(detail->operands[i]);
}
return clone;
}
TestDetailSystemZOp *test_detail_systemz_op_new()
{
return cs_mem_calloc(sizeof(TestDetailSystemZOp), 1);
}
TestDetailSystemZOp *test_detail_systemz_op_clone(const TestDetailSystemZOp *op)
{
TestDetailSystemZOp *clone = test_detail_systemz_op_new();
clone->type = op->type ? strdup(op->type) : NULL;
clone->access = op->access ? strdup(op->access) : NULL;
clone->reg = op->reg ? strdup(op->reg) : NULL;
clone->imm = op->imm;
clone->imm_width = op->imm_width;
clone->mem_am = op->mem_am ? strdup(op->mem_am) : NULL;
clone->mem_base = op->mem_base ? strdup(op->mem_base) : NULL;
clone->mem_index = op->mem_index ? strdup(op->mem_index) : NULL;
clone->mem_disp = op->mem_disp;
clone->mem_length = op->mem_length;
return clone;
}
void test_detail_systemz_op_free(TestDetailSystemZOp *op)
{
if (!op) {
return;
}
cs_mem_free(op->type);
cs_mem_free(op->access);
cs_mem_free(op->reg);
cs_mem_free(op->mem_am);
cs_mem_free(op->mem_base);
cs_mem_free(op->mem_index);
cs_mem_free(op);
}
bool test_expected_systemz(csh *handle, const cs_systemz *actual,
const TestDetailSystemZ *expected)
{
assert(handle && actual && expected);
compare_enum_ret(actual->format, expected->format, false);
compare_uint8_ret(actual->op_count, expected->operands_count, false);
for (size_t i = 0; i < actual->op_count; ++i) {
const cs_systemz_op *op = &actual->operands[i];
TestDetailSystemZOp *eop = expected->operands[i];
compare_enum_ret(op->type, eop->type, false);
compare_enum_ret(op->access, eop->access, false);
switch (op->type) {
default:
fprintf(stderr,
"arm op type %" PRId32 " not handled.\n",
op->type);
return false;
case SYSTEMZ_OP_REG:
compare_reg_ret(*handle, op->reg, eop->reg, false);
break;
case SYSTEMZ_OP_IMM:
compare_int64_ret(op->imm, eop->imm, false);
compare_uint8_ret(op->imm_width, eop->imm_width, false);
break;
case SYSTEMZ_OP_MEM:
compare_enum_ret(op->mem.am, eop->mem_am, false);
switch(op->mem.am) {
default:
assert(0 && "Address mode not handled\n");
break;
case SYSTEMZ_AM_BD:
compare_reg_ret(*handle, op->mem.base, eop->mem_base,
false);
compare_reg_ret(*handle, op->mem.index, eop->mem_index,
false);
break;
case SYSTEMZ_AM_BDX:
case SYSTEMZ_AM_BDV:
compare_reg_ret(*handle, op->mem.base, eop->mem_base,
false);
compare_int64_ret(op->mem.disp, eop->mem_disp, false);
compare_reg_ret(*handle, op->mem.index, eop->mem_index,
false);
break;
case SYSTEMZ_AM_BDL:
compare_reg_ret(*handle, op->mem.base, eop->mem_base,
false);
compare_int64_ret(op->mem.disp, eop->mem_disp, false);
compare_uint64_ret(op->mem.length, eop->mem_length,
false);
break;
case SYSTEMZ_AM_BDR:
compare_reg_ret(*handle, op->mem.base, eop->mem_base,
false);
compare_int64_ret(op->mem.disp, eop->mem_disp, false);
compare_uint64_ret(op->mem.length, eop->mem_length,
false);
break;
}
break;
}
}
return true;
}
@@ -0,0 +1,179 @@
// Copyright © 2024 Rot127 <unisono@quyllur.org>
// SPDX-License-Identifier: BSD-3
#include "capstone/tms320c64x.h"
#include "test_compare.h"
#include "test_detail_tms320c64x.h"
#include <capstone/capstone.h>
#include <stdio.h>
#include <string.h>
TestDetailTMS320c64x *test_detail_tms320c64x_new()
{
return cs_mem_calloc(sizeof(TestDetailTMS320c64x), 1);
}
void test_detail_tms320c64x_free(TestDetailTMS320c64x *detail)
{
if (!detail) {
return;
}
for (size_t i = 0; i < detail->operands_count; ++i) {
test_detail_tms320c64x_op_free(detail->operands[i]);
}
cs_mem_free(detail->operands);
cs_mem_free(detail->cond_reg);
cs_mem_free(detail->funit_unit);
cs_mem_free(detail);
}
TestDetailTMS320c64x *test_detail_tms320c64x_clone(TestDetailTMS320c64x *detail)
{
TestDetailTMS320c64x *clone = test_detail_tms320c64x_new();
clone->cond_reg = detail->cond_reg ? strdup(detail->cond_reg) : NULL;
clone->cond_zero = detail->cond_zero;
clone->funit_unit = detail->funit_unit ? strdup(detail->funit_unit) :
NULL;
clone->funit_side = detail->funit_side;
clone->funit_side_set = detail->funit_side_set;
clone->funit_crosspath = detail->funit_crosspath;
clone->funit_crosspath_set = detail->funit_crosspath_set;
clone->parallel = detail->parallel;
clone->parallel_set = detail->parallel_set;
clone->operands_count = detail->operands_count;
if (detail->operands_count > 0) {
clone->operands =
cs_mem_calloc(sizeof(TestDetailTMS320c64xOp *),
detail->operands_count);
}
for (size_t i = 0; i < detail->operands_count; ++i) {
clone->operands[i] =
test_detail_tms320c64x_op_clone(detail->operands[i]);
}
return clone;
}
TestDetailTMS320c64xOp *test_detail_tms320c64x_op_new()
{
return cs_mem_calloc(sizeof(TestDetailTMS320c64xOp), 1);
}
TestDetailTMS320c64xOp *
test_detail_tms320c64x_op_clone(TestDetailTMS320c64xOp *op)
{
TestDetailTMS320c64xOp *clone = test_detail_tms320c64x_op_new();
clone->type = op->type ? strdup(op->type) : NULL;
clone->reg = op->reg ? strdup(op->reg) : NULL;
clone->reg_pair_0 = op->reg_pair_0 ? strdup(op->reg_pair_0) : NULL;
clone->reg_pair_1 = op->reg_pair_1 ? strdup(op->reg_pair_1) : NULL;
clone->imm = op->imm;
clone->mem_base = op->mem_base ? strdup(op->mem_base) : NULL;
clone->mem_scaled = op->mem_scaled;
clone->mem_disptype = op->mem_disptype ? strdup(op->mem_disptype) :
NULL;
clone->mem_direction = op->mem_direction ? strdup(op->mem_direction) :
NULL;
clone->mem_modify = op->mem_modify ? strdup(op->mem_modify) : NULL;
clone->mem_disp_const = op->mem_disp_const;
clone->mem_disp_reg = op->mem_disp_reg ? strdup(op->mem_disp_reg) :
NULL;
clone->mem_unit = op->mem_unit;
return clone;
}
void test_detail_tms320c64x_op_free(TestDetailTMS320c64xOp *op)
{
if (!op) {
return;
}
cs_mem_free(op->type);
cs_mem_free(op->mem_base);
cs_mem_free(op->mem_disp_reg);
cs_mem_free(op->mem_disptype);
cs_mem_free(op->mem_direction);
cs_mem_free(op->mem_modify);
cs_mem_free(op->reg);
cs_mem_free(op->reg_pair_0);
cs_mem_free(op->reg_pair_1);
cs_mem_free(op);
}
bool test_expected_tms320c64x(csh *handle, cs_tms320c64x *actual,
TestDetailTMS320c64x *expected)
{
assert(handle && actual && expected);
compare_uint8_ret(actual->op_count, expected->operands_count, false);
compare_reg_ret(*handle, actual->condition.reg, expected->cond_reg,
false);
compare_tbool_ret(actual->condition.zero, expected->cond_zero, false);
compare_enum_ret(actual->funit.unit, expected->funit_unit, false);
if (expected->funit_side_set) {
compare_uint8_ret(actual->funit.side, expected->funit_side,
false);
} else {
assert(expected->funit_side == 0);
}
if (expected->funit_crosspath_set) {
compare_uint8_ret(actual->funit.crosspath,
expected->funit_crosspath, false);
} else {
assert(expected->funit_crosspath == 0);
}
if (expected->parallel_set) {
compare_uint8_ret(actual->parallel, expected->parallel, false);
} else {
assert(expected->parallel == 0);
}
for (size_t i = 0; i < actual->op_count; ++i) {
cs_tms320c64x_op *op = &actual->operands[i];
TestDetailTMS320c64xOp *eop = expected->operands[i];
compare_enum_ret(op->type, eop->type, false);
switch (op->type) {
default:
fprintf(stderr,
"tms320c64x op type %" PRId32 " not handled.\n",
op->type);
return false;
case TMS320C64X_OP_REG:
compare_reg_ret(*handle, op->reg, eop->reg, false);
break;
case TMS320C64X_OP_REGPAIR:
compare_reg_ret(*handle, op->reg + 1, eop->reg_pair_0,
false);
compare_reg_ret(*handle, op->reg, eop->reg_pair_1,
false);
break;
case TMS320C64X_OP_IMM:
compare_int32_ret(op->imm, eop->imm, false);
break;
case TMS320C64X_OP_MEM:
compare_reg_ret(*handle, op->mem.base, eop->mem_base,
false);
compare_enum_ret(op->mem.direction, eop->mem_direction,
false);
compare_tbool_ret(op->mem.scaled, eop->mem_scaled,
false);
compare_enum_ret(op->mem.disptype, eop->mem_disptype,
false);
if (op->mem.disptype == TMS320C64X_MEM_DISP_REGISTER) {
compare_reg_ret(*handle, op->mem.disp,
eop->mem_disp_reg, false);
} else {
compare_uint_ret(op->mem.disp,
eop->mem_disp_const, false);
}
compare_enum_ret(op->mem.modify, eop->mem_modify,
false);
compare_uint_ret(op->mem.unit, eop->mem_unit, false);
break;
}
}
return true;
}
+109
View File
@@ -0,0 +1,109 @@
// Copyright © 2024 Rot127 <unisono@quyllur.org>
// SPDX-License-Identifier: BSD-3
#include "test_compare.h"
#include "test_detail_tricore.h"
#include <capstone/capstone.h>
#include <stdio.h>
#include <string.h>
TestDetailTriCore *test_detail_tricore_new()
{
return cs_mem_calloc(sizeof(TestDetailTriCore), 1);
}
void test_detail_tricore_free(TestDetailTriCore *detail)
{
if (!detail) {
return;
}
for (size_t i = 0; i < detail->operands_count; ++i) {
test_detail_tricore_op_free(detail->operands[i]);
}
cs_mem_free(detail->operands);
cs_mem_free(detail);
}
TestDetailTriCore *test_detail_tricore_clone(const TestDetailTriCore *detail)
{
TestDetailTriCore *clone = test_detail_tricore_new();
clone->update_flags = detail->update_flags;
clone->operands_count = detail->operands_count;
if (detail->operands_count > 0) {
clone->operands = cs_mem_calloc(sizeof(TestDetailTriCoreOp *),
detail->operands_count);
}
for (size_t i = 0; i < detail->operands_count; ++i) {
clone->operands[i] =
test_detail_tricore_op_clone(detail->operands[i]);
}
return clone;
}
TestDetailTriCoreOp *test_detail_tricore_op_new()
{
return cs_mem_calloc(sizeof(TestDetailTriCoreOp), 1);
}
TestDetailTriCoreOp *test_detail_tricore_op_clone(const TestDetailTriCoreOp *op)
{
TestDetailTriCoreOp *clone = test_detail_tricore_op_new();
clone->type = op->type ? strdup(op->type) : NULL;
clone->access = op->access ? strdup(op->access) : NULL;
clone->reg = op->reg ? strdup(op->reg) : NULL;
clone->imm = op->imm;
clone->mem_base = op->mem_base ? strdup(op->mem_base) : NULL;
clone->mem_disp = op->mem_disp;
return clone;
}
void test_detail_tricore_op_free(TestDetailTriCoreOp *op)
{
if (!op) {
return;
}
cs_mem_free(op->type);
cs_mem_free(op->access);
cs_mem_free(op->reg);
cs_mem_free(op->mem_base);
cs_mem_free(op);
}
bool test_expected_tricore(csh *handle, const cs_tricore *actual,
const TestDetailTriCore *expected)
{
assert(handle && actual && expected);
compare_uint8_ret(actual->op_count, expected->operands_count, false);
compare_tbool_ret(actual->update_flags, expected->update_flags, false);
for (size_t i = 0; i < actual->op_count; ++i) {
const cs_tricore_op *op = &actual->operands[i];
TestDetailTriCoreOp *eop = expected->operands[i];
compare_enum_ret(op->type, eop->type, false);
compare_enum_ret(op->access, eop->access, false);
switch (op->type) {
default:
fprintf(stderr,
"tricore op type %" PRId32 " not handled.\n",
op->type);
return false;
case TRICORE_OP_REG:
compare_reg_ret(*handle, op->reg, eop->reg, false);
break;
case TRICORE_OP_IMM:
compare_int64_ret(op->imm, eop->imm, false);
break;
case TRICORE_OP_MEM:
compare_reg_ret(*handle, op->mem.base, eop->mem_base,
false);
compare_int64_ret(op->mem.disp, eop->mem_disp, false);
break;
}
}
return true;
}
+128
View File
@@ -0,0 +1,128 @@
// Copyright © 2024 Rot127 <unisono@quyllur.org>
// SPDX-License-Identifier: BSD-3
#include "test_compare.h"
#include "test_detail_wasm.h"
#include <capstone/capstone.h>
#include <stdio.h>
#include <string.h>
TestDetailWASM *test_detail_wasm_new()
{
return cs_mem_calloc(sizeof(TestDetailWASM), 1);
}
void test_detail_wasm_free(TestDetailWASM *detail)
{
if (!detail) {
return;
}
for (size_t i = 0; i < detail->operands_count; ++i) {
test_detail_wasm_op_free(detail->operands[i]);
}
cs_mem_free(detail->operands);
cs_mem_free(detail);
}
TestDetailWASM *test_detail_wasm_clone(const TestDetailWASM *detail)
{
TestDetailWASM *clone = test_detail_wasm_new();
clone->operands_count = detail->operands_count;
if (detail->operands_count > 0) {
clone->operands = cs_mem_calloc(sizeof(TestDetailWASMOp *),
detail->operands_count);
}
for (size_t i = 0; i < detail->operands_count; ++i) {
clone->operands[i] =
test_detail_wasm_op_clone(detail->operands[i]);
}
return clone;
}
TestDetailWASMOp *test_detail_wasm_op_new()
{
return cs_mem_calloc(sizeof(TestDetailWASMOp), 1);
}
TestDetailWASMOp *test_detail_wasm_op_clone(const TestDetailWASMOp *op)
{
TestDetailWASMOp *clone = test_detail_wasm_op_new();
clone->type = op->type ? strdup(op->type) : NULL;
clone->size = op->size;
clone->int7 = op->int7;
clone->varuint32 = op->varuint32;
clone->varuint64 = op->varuint64;
clone->uint32 = op->uint32;
clone->uint64 = op->uint64;
clone->immediate_0 = op->immediate_0;
clone->immediate_1 = op->immediate_1;
clone->brt_length = op->brt_length;
clone->brt_address = op->brt_address;
clone->brt_default_target = op->brt_default_target;
return clone;
}
void test_detail_wasm_op_free(TestDetailWASMOp *op)
{
if (!op) {
return;
}
cs_mem_free(op->type);
cs_mem_free(op);
}
bool test_expected_wasm(csh *handle, const cs_wasm *actual,
const TestDetailWASM *expected)
{
assert(handle && actual && expected);
compare_uint8_ret(actual->op_count, expected->operands_count, false);
for (size_t i = 0; i < actual->op_count; ++i) {
const cs_wasm_op *op = &actual->operands[i];
TestDetailWASMOp *eop = expected->operands[i];
compare_enum_ret(op->type, eop->type, false);
switch (op->type) {
default:
fprintf(stderr,
"WASM op type %" PRId32 " not handled.\n",
op->type);
return false;
case WASM_OP_INT7:
compare_int8_ret(op->int7, eop->int7, false);
break;
case WASM_OP_VARUINT32:
compare_uint32_ret(op->varuint32, eop->varuint32,
false);
break;
case WASM_OP_VARUINT64:
compare_uint64_ret(op->varuint64, eop->varuint64,
false);
break;
case WASM_OP_UINT32:
compare_uint32_ret(op->uint32, eop->uint32, false);
break;
case WASM_OP_UINT64:
compare_uint64_ret(op->uint64, eop->uint64, false);
break;
case WASM_OP_IMM:
compare_uint32_ret(op->immediate[0], eop->immediate_0,
false);
compare_uint32_ret(op->immediate[1], eop->immediate_1,
false);
break;
case WASM_OP_BRTABLE:
compare_uint32_ret(op->brtable.length, eop->brt_length,
false);
compare_uint32_ret(op->brtable.default_target,
eop->brt_default_target, false);
compare_uint64_ret(op->brtable.address,
eop->brt_address, false);
break;
}
}
return true;
}
+264
View File
@@ -0,0 +1,264 @@
// Copyright © 2024 Rot127 <unisono@quyllur.org>
// SPDX-License-Identifier: BSD-3
#include "test_compare.h"
#include "test_detail_x86.h"
#include <capstone/capstone.h>
#include <stdio.h>
#include <string.h>
TestDetailX86 *test_detail_x86_new()
{
return cs_mem_calloc(sizeof(TestDetailX86), 1);
}
void test_detail_x86_free(TestDetailX86 *detail)
{
if (!detail) {
return;
}
if (detail->prefix[0]) {
for (size_t i = 0; i < ARR_SIZE(detail->prefix); ++i) {
cs_mem_free(detail->prefix[i]);
}
}
for (size_t i = 0; i < detail->eflags_count; ++i) {
cs_mem_free(detail->eflags[i]);
}
cs_mem_free(detail->eflags);
for (size_t i = 0; i < detail->fpu_flags_count; ++i) {
cs_mem_free(detail->fpu_flags[i]);
}
cs_mem_free(detail->fpu_flags);
for (size_t i = 0; i < detail->operands_count; ++i) {
test_detail_x86_op_free(detail->operands[i]);
}
cs_mem_free(detail->operands);
cs_mem_free(detail->sib_index);
cs_mem_free(detail->sib_base);
cs_mem_free(detail->xop_cc);
cs_mem_free(detail->sse_cc);
cs_mem_free(detail->avx_cc);
cs_mem_free(detail->avx_rm);
cs_mem_free(detail);
}
TestDetailX86 *test_detail_x86_clone(TestDetailX86 *detail)
{
TestDetailX86 *clone = test_detail_x86_new();
clone->sib_index = detail->sib_index ? strdup(detail->sib_index) : NULL;
clone->sib_base = detail->sib_base ? strdup(detail->sib_base) : NULL;
clone->xop_cc = detail->xop_cc ? strdup(detail->xop_cc) : NULL;
clone->sse_cc = detail->sse_cc ? strdup(detail->sse_cc) : NULL;
clone->avx_cc = detail->avx_cc ? strdup(detail->avx_cc) : NULL;
clone->avx_rm = detail->avx_rm ? strdup(detail->avx_rm) : NULL;
if (detail->prefix[0]) {
for (size_t i = 0; i < ARR_SIZE(clone->prefix); ++i) {
clone->prefix[i] = strdup(detail->prefix[i]);
}
}
memcpy(clone->opcode, detail->opcode, sizeof(clone->opcode));
clone->rex = detail->rex;
clone->addr_size = detail->addr_size;
clone->modrm = detail->modrm;
clone->sib = detail->sib;
clone->disp = detail->disp;
clone->sib_scale = detail->sib_scale;
clone->avx_sae = detail->avx_sae;
clone->enc_modrm_offset = detail->enc_modrm_offset;
clone->enc_disp_offset = detail->enc_disp_offset;
clone->enc_disp_size = detail->enc_disp_size;
clone->enc_imm_offset = detail->enc_imm_offset;
clone->enc_imm_size = detail->enc_imm_size;
clone->eflags_count = detail->eflags_count;
clone->eflags = detail->eflags ? cs_mem_calloc(sizeof(char *),
detail->eflags_count) :
NULL;
for (size_t i = 0; clone->eflags && i < detail->eflags_count; ++i) {
clone->eflags[i] =
detail->eflags[i] ? strdup(detail->eflags[i]) : NULL;
}
clone->fpu_flags_count = detail->fpu_flags_count;
clone->fpu_flags =
detail->fpu_flags ?
cs_mem_calloc(sizeof(char *), detail->fpu_flags_count) :
NULL;
for (size_t i = 0; clone->fpu_flags && i < detail->fpu_flags_count; ++i) {
clone->fpu_flags[i] = detail->fpu_flags[i] ?
strdup(detail->fpu_flags[i]) :
NULL;
}
clone->operands_count = detail->operands_count;
clone->operands = detail->operands_count > 0 ?
cs_mem_calloc(sizeof(TestDetailX86Op *),
detail->operands_count) :
NULL;
for (size_t i = 0; i < detail->operands_count; ++i) {
clone->operands[i] =
test_detail_x86_op_clone(detail->operands[i]);
}
return clone;
}
TestDetailX86Op *test_detail_x86_op_new()
{
return cs_mem_calloc(sizeof(TestDetailX86Op), 1);
}
TestDetailX86Op *test_detail_x86_op_clone(TestDetailX86Op *op)
{
TestDetailX86Op *clone = test_detail_x86_op_new();
clone->size = op->size;
clone->type = op->type ? strdup(op->type) : NULL;
clone->access = op->access ? strdup(op->access) : NULL;
clone->reg = op->reg ? strdup(op->reg) : NULL;
clone->imm = op->imm;
clone->mem_segment = op->mem_segment ? strdup(op->mem_segment) : NULL;
clone->mem_base = op->mem_base ? strdup(op->mem_base) : NULL;
clone->mem_index = op->mem_index ? strdup(op->mem_index) : NULL;
clone->mem_scale = op->mem_scale;
clone->mem_disp = op->mem_disp;
clone->avx_bcast = op->avx_bcast ? strdup(op->avx_bcast) : NULL;
clone->avx_zero_opmask = op->avx_zero_opmask;
return clone;
}
void test_detail_x86_op_free(TestDetailX86Op *op)
{
if (!op) {
return;
}
cs_mem_free(op->type);
cs_mem_free(op->access);
cs_mem_free(op->reg);
cs_mem_free(op->mem_segment);
cs_mem_free(op->mem_base);
cs_mem_free(op->mem_index);
cs_mem_free(op->avx_bcast);
cs_mem_free(op);
}
bool test_expected_x86(csh *handle, cs_x86 *actual, TestDetailX86 *expected)
{
assert(handle && actual && expected);
compare_reg_ret(*handle, actual->sib_index, expected->sib_index, false);
compare_reg_ret(*handle, actual->sib_base, expected->sib_base, false);
compare_enum_ret(actual->xop_cc, expected->xop_cc, false);
compare_enum_ret(actual->sse_cc, expected->sse_cc, false);
compare_enum_ret(actual->avx_cc, expected->avx_cc, false);
compare_enum_ret(actual->avx_rm, expected->avx_rm, false);
if (expected->rex) {
compare_uint8_ret(actual->rex, expected->rex, false);
}
if (expected->addr_size) {
compare_uint8_ret(actual->addr_size, expected->addr_size, false);
}
if (expected->modrm) {
compare_uint8_ret(actual->modrm, expected->modrm, false);
}
if (expected->sib) {
compare_uint8_ret(actual->sib, expected->sib, false);
}
if (expected->disp) {
compare_int64_ret(actual->disp, expected->disp, false);
}
if (expected->sib_scale) {
compare_int8_ret(actual->sib_scale, expected->sib_scale, false);
}
compare_tbool_ret(actual->avx_sae, expected->avx_sae, false);
for (size_t i = 0; i < ARR_SIZE(actual->prefix); ++i) {
compare_enum_ret(actual->prefix[i], expected->prefix[i],
false);
}
for (size_t i = 0; i < ARR_SIZE(actual->opcode); ++i) {
if (expected->opcode[i] != 0) {
compare_uint8_ret(actual->opcode[i], expected->opcode[i],
false);
}
}
compare_bit_flags_64_ret(actual->eflags, expected->eflags,
expected->eflags_count, false);
compare_bit_flags_64_ret(actual->fpu_flags, expected->fpu_flags,
expected->fpu_flags_count, false);
if (expected->enc_modrm_offset) {
compare_uint8_ret(actual->encoding.modrm_offset,
expected->enc_modrm_offset, false);
}
if (expected->enc_disp_offset) {
compare_uint8_ret(actual->encoding.disp_offset,
expected->enc_disp_offset, false);
}
if (expected->enc_disp_size) {
compare_uint8_ret(actual->encoding.disp_size,
expected->enc_disp_size, false);
}
if (expected->enc_imm_offset) {
compare_uint8_ret(actual->encoding.imm_offset,
expected->enc_imm_offset, false);
}
if (expected->enc_imm_size) {
compare_uint8_ret(actual->encoding.imm_size,
expected->enc_imm_size, false);
}
if (expected->operands_count == 0) {
return true;
}
compare_uint8_ret(actual->op_count, expected->operands_count, false);
for (size_t i = 0; i < actual->op_count; ++i) {
cs_x86_op *op = &actual->operands[i];
TestDetailX86Op *eop = expected->operands[i];
compare_enum_ret(op->type, eop->type, false);
compare_enum_ret(op->access, eop->access, false);
compare_enum_ret(op->avx_bcast, eop->avx_bcast, false);
compare_tbool_ret(op->avx_zero_opmask, eop->avx_zero_opmask,
false);
switch (op->type) {
default:
fprintf(stderr,
"arm op type %" PRId32 " not handled.\n",
op->type);
return false;
case X86_OP_REG:
compare_reg_ret(*handle, op->reg, eop->reg, false);
break;
case X86_OP_IMM:
compare_int64_ret(op->imm, eop->imm, false);
break;
case X86_OP_MEM:
compare_reg_ret(*handle, op->mem.segment,
eop->mem_segment, false);
compare_reg_ret(*handle, op->mem.base, eop->mem_base,
false);
compare_reg_ret(*handle, op->mem.index, eop->mem_index,
false);
if (eop->mem_disp) {
compare_int64_ret(op->mem.disp, eop->mem_disp, false);
}
if (eop->mem_scale) {
compare_int_ret(op->mem.scale, eop->mem_scale,
false);
}
break;
}
}
return true;
}
+113
View File
@@ -0,0 +1,113 @@
// Copyright © 2024 Rot127 <unisono@quyllur.org>
// SPDX-License-Identifier: BSD-3
#include "test_compare.h"
#include "test_detail_xcore.h"
#include <capstone/capstone.h>
#include <stdio.h>
#include <string.h>
TestDetailXCore *test_detail_xcore_new()
{
return cs_mem_calloc(sizeof(TestDetailXCore), 1);
}
void test_detail_xcore_free(TestDetailXCore *detail)
{
if (!detail) {
return;
}
for (size_t i = 0; i < detail->operands_count; ++i) {
test_detail_xcore_op_free(detail->operands[i]);
}
cs_mem_free(detail->operands);
cs_mem_free(detail);
}
TestDetailXCore *test_detail_xcore_clone(const TestDetailXCore *detail)
{
TestDetailXCore *clone = test_detail_xcore_new();
clone->operands_count = detail->operands_count;
if (detail->operands_count > 0) {
clone->operands = cs_mem_calloc(sizeof(TestDetailXCoreOp *),
detail->operands_count);
}
for (size_t i = 0; i < detail->operands_count; ++i) {
clone->operands[i] =
test_detail_xcore_op_clone(detail->operands[i]);
}
return clone;
}
TestDetailXCoreOp *test_detail_xcore_op_new()
{
return cs_mem_calloc(sizeof(TestDetailXCoreOp), 1);
}
TestDetailXCoreOp *test_detail_xcore_op_clone(const TestDetailXCoreOp *op)
{
TestDetailXCoreOp *clone = test_detail_xcore_op_new();
clone->type = op->type ? strdup(op->type) : NULL;
clone->reg = op->reg ? strdup(op->reg) : NULL;
clone->imm = op->imm;
clone->mem_base = op->mem_base ? strdup(op->mem_base) : NULL;
clone->mem_index = op->mem_index ? strdup(op->mem_index) : NULL;
clone->mem_disp = op->mem_disp;
clone->mem_direct = op->mem_direct;
return clone;
}
void test_detail_xcore_op_free(TestDetailXCoreOp *op)
{
if (!op) {
return;
}
cs_mem_free(op->type);
cs_mem_free(op->reg);
cs_mem_free(op->mem_base);
cs_mem_free(op->mem_index);
cs_mem_free(op);
}
bool test_expected_xcore(csh *handle, const cs_xcore *actual,
const TestDetailXCore *expected)
{
assert(handle && actual && expected);
compare_uint8_ret(actual->op_count, expected->operands_count, false);
for (size_t i = 0; i < actual->op_count; ++i) {
const cs_xcore_op *op = &actual->operands[i];
TestDetailXCoreOp *eop = expected->operands[i];
compare_enum_ret(op->type, eop->type, false);
switch (op->type) {
default:
fprintf(stderr,
"arm op type %" PRId32 " not handled.\n",
op->type);
return false;
case XCORE_OP_REG:
compare_reg_ret(*handle, op->reg, eop->reg, false);
break;
case XCORE_OP_IMM:
compare_int32_ret(op->imm, eop->imm, false);
break;
case XCORE_OP_MEM:
compare_reg_ret(*handle, op->mem.base, eop->mem_base,
false);
compare_reg_ret(*handle, op->mem.index, eop->mem_index,
false);
compare_int_ret(op->mem.disp, eop->mem_disp, false);
if (eop->mem_direct) {
compare_int_ret(op->mem.direct, eop->mem_direct,
false);
}
break;
}
}
return true;
}
+111
View File
@@ -0,0 +1,111 @@
// Copyright © 2024 Rot127 <unisono@quyllur.org>
// Copyright © 2024 Billow <billow.fun@gmail.com>
// SPDX-License-Identifier: BSD-3
#include "test_compare.h"
#include <capstone/capstone.h>
#include <stdio.h>
#include <string.h>
#include <test_detail_xtensa.h>
TestDetailXtensa *test_detail_xtensa_new()
{
return cs_mem_calloc(sizeof(TestDetailXtensa), 1);
}
void test_detail_xtensa_free(TestDetailXtensa *detail)
{
if (!detail) {
return;
}
for (size_t i = 0; i < detail->operands_count; ++i) {
test_detail_xtensa_op_free(detail->operands[i]);
}
cs_mem_free(detail->operands);
cs_mem_free(detail->format);
cs_mem_free(detail);
}
TestDetailXtensa *test_detail_xtensa_clone(const TestDetailXtensa *detail)
{
TestDetailXtensa *clone = test_detail_xtensa_new();
clone->format = detail->format ? strdup(detail->format) : NULL;
clone->operands_count = detail->operands_count;
if (detail->operands_count > 0) {
clone->operands = cs_mem_calloc(sizeof(TestDetailXtensaOp *),
detail->operands_count);
}
for (size_t i = 0; i < detail->operands_count; ++i) {
clone->operands[i] =
test_detail_xtensa_op_clone(detail->operands[i]);
}
return clone;
}
TestDetailXtensaOp *test_detail_xtensa_op_new()
{
return cs_mem_calloc(sizeof(TestDetailXtensaOp), 1);
}
TestDetailXtensaOp *test_detail_xtensa_op_clone(const TestDetailXtensaOp *op)
{
TestDetailXtensaOp *clone = test_detail_xtensa_op_new();
clone->type = op->type ? strdup(op->type) : NULL;
clone->access = op->access ? strdup(op->access) : NULL;
clone->reg = op->reg ? strdup(op->reg) : NULL;
clone->imm = op->imm;
clone->mem_base = op->mem_base ? strdup(op->mem_base) : NULL;
clone->mem_disp = op->mem_disp;
return clone;
}
void test_detail_xtensa_op_free(TestDetailXtensaOp *op)
{
if (!op) {
return;
}
cs_mem_free(op->type);
cs_mem_free(op->access);
cs_mem_free(op->reg);
cs_mem_free(op->mem_base);
cs_mem_free(op);
}
bool test_expected_xtensa(csh *handle, const cs_xtensa *actual,
const TestDetailXtensa *expected)
{
assert(handle && actual && expected);
compare_enum_ret(actual->format, expected->format, false);
compare_uint8_ret(actual->op_count, expected->operands_count, false);
for (size_t i = 0; i < actual->op_count; ++i) {
const cs_xtensa_op *op = &actual->operands[i];
TestDetailXtensaOp *eop = expected->operands[i];
compare_enum_ret(op->type, eop->type, false);
compare_enum_ret(op->access, eop->access, false);
switch (op->type) {
default:
fprintf(stderr,
"xtensa op type %" PRId32 " not handled.\n",
op->type);
return false;
case XTENSA_OP_REG:
compare_reg_ret(*handle, op->reg, eop->reg, false);
break;
case XTENSA_OP_L32R:
case XTENSA_OP_IMM:
compare_int32_ret(op->imm, eop->imm, false);
break;
case XTENSA_OP_MEM:
compare_reg_ret(*handle, op->mem.base, eop->mem_base,
false);
compare_int32_ret(op->mem.disp, eop->mem_disp, false);
break;
}
}
return true;
}
+330
View File
@@ -0,0 +1,330 @@
// Copyright © 2024 Rot127 <unisono@quyllur.org>
// SPDX-License-Identifier: BSD-3
#include "test_run.h"
#include "test_case.h"
#include "test_mapping.h"
#include "../../../utils.h"
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include "cmocka.h"
#include <capstone/capstone.h>
#include <stdbool.h>
#include <stdio.h>
static TestRunResult get_test_run_result(TestRunStats *stats)
{
if (stats->tc_total !=
stats->successful + stats->failed + stats->skipped) {
fprintf(stderr,
"[!] Inconsistent statistics: total != successful + failed + skipped\n");
stats->errors++;
return TEST_RUN_ERROR;
}
if (stats->errors != 0) {
return TEST_RUN_ERROR;
} else if (stats->failed != 0) {
return TEST_RUN_FAILURE;
}
return TEST_RUN_SUCCESS;
}
/// Extract all test cases from the given test files.
static TestFile **parse_test_files(char **tf_paths, uint32_t path_count,
TestRunStats *stats)
{
TestFile **files = NULL;
stats->tc_total = 0;
for (size_t i = 0; i < path_count; ++i) {
TestFile *test_file_data = NULL;
cyaml_err_t err = cyaml_load_file(
tf_paths[i], &cyaml_config, &test_file_schema,
(cyaml_data_t **)&test_file_data, NULL);
if (err != CYAML_OK || !test_file_data) {
fprintf(stderr, "[!] Failed to parse test file '%s'\n",
tf_paths[i]);
fprintf(stderr, "[!] Error: '%s'\n",
!test_file_data && err == CYAML_OK ?
"Empty file" :
cyaml_strerror(err));
stats->invalid_files++;
stats->errors++;
continue;
}
size_t k = stats->valid_test_files++;
// Copy all test cases of a test file
files = cs_mem_realloc(files, sizeof(TestFile *) *
stats->valid_test_files);
files[k] = test_file_clone(test_file_data);
assert(files[k]);
stats->tc_total += files[k]->test_cases_count;
files[k]->filename = strrchr(tf_paths[i], '/') ?
strdup(strrchr(tf_paths[i], '/')) :
strdup(tf_paths[i]);
err = cyaml_free(&cyaml_config, &test_file_schema,
test_file_data, 0);
if (err != CYAML_OK) {
fprintf(stderr, "[!] Error: '%s'\n",
cyaml_strerror(err));
stats->errors++;
continue;
}
}
return files;
}
/// Parses the @input and saves the results in the other arguments.
static bool parse_input_options(const TestInput *input, cs_arch *arch,
cs_mode *mode, cs_opt *opt_arr,
size_t opt_arr_size, size_t *opt_set)
{
assert(input && arch && mode && opt_arr);
bool arch_found = false;
const char *opt_str = input->arch;
int val = enum_map_bin_search(test_arch_map, ARR_SIZE(test_arch_map),
opt_str, &arch_found);
if (arch_found) {
*arch = val;
} else {
fprintf(stderr,
"[!] '%s' is not mapped to a capstone architecture.\n",
input->arch);
return false;
}
*mode = 0;
size_t opt_idx = 0;
char **options = input->options;
for (size_t i = 0; i < input->options_count; ++i) {
bool opt_found = false;
opt_str = options[i];
val = enum_map_bin_search(test_mode_map,
ARR_SIZE(test_mode_map),
opt_str, &opt_found);
if (opt_found) {
*mode |= val;
continue;
}
// Might be an option descriptor
for (size_t k = 0; k < ARR_SIZE(test_option_map); k++) {
if (strings_match(opt_str, test_option_map[k].str)) {
if (opt_idx >= opt_arr_size) {
fprintf(stderr,
"Too many options given in: '%s'. Maximum is: %" PRId64
"\n",
opt_str,
(uint64_t)opt_arr_size);
return false;
}
opt_arr[opt_idx++] = test_option_map[k].opt;
opt_found = true;
break;
}
}
if (!opt_found) {
fprintf(stderr, "[!] Option: '%s' not used\n", opt_str);
}
}
*opt_set = opt_idx;
return true;
}
/// Parses the options for cs_open/cs_option and initializes the handle.
/// Returns true for success and false otherwise.
static bool open_cs_handle(UnitTestState *ustate)
{
cs_arch arch = 0;
cs_mode mode = 0;
cs_opt options[8] = { 0 };
size_t options_set = 0;
if (!parse_input_options(ustate->tcase->input, &arch, &mode, options, 8,
&options_set)) {
char *tc_str = test_input_stringify(ustate->tcase->input, "");
fprintf(stderr, "Could not parse options: %s\n", tc_str);
cs_mem_free(tc_str);
return false;
}
cs_err err = cs_open(arch, mode, &ustate->handle);
if (err != CS_ERR_OK) {
char *tc_str = test_input_stringify(ustate->tcase->input, "");
fprintf(stderr,
"[!] cs_open() failed with: '%s'. TestInput: %s\n",
cs_strerror(err), tc_str);
cs_mem_free(tc_str);
return false;
}
// The bit mode must be set, otherwise the numbers are
// not normalized correctly in the asm-test comparison step.
if (arch == CS_ARCH_AARCH64 || mode & CS_MODE_64) {
ustate->arch_bits = 64;
} else if (mode & CS_MODE_16) {
ustate->arch_bits = 16;
} else {
ustate->arch_bits = 32;
}
for (size_t i = 0; i < options_set; ++i) {
err = cs_option(ustate->handle, options[i].type,
options[i].val);
if (err != CS_ERR_OK) {
goto option_error;
}
}
return true;
option_error: {
char *tc_str = test_input_stringify(ustate->tcase->input, "");
fprintf(stderr, "[!] cs_option() failed with: '%s'. TestInput: %s\n",
cs_strerror(err), tc_str);
cs_mem_free(tc_str);
cs_close(&ustate->handle);
return false;
}
}
static int cstest_unit_test_setup(void **state)
{
assert(state);
UnitTestState *ustate = *state;
assert(ustate->tcase);
if (!open_cs_handle(ustate)) {
fail_msg("Failed to initialize Capstone with given options.");
return -1;
}
return 0;
}
static int cstest_unit_test_teardown(void **state)
{
if (!state) {
return 0;
}
UnitTestState *ustate = *state;
if (ustate->handle) {
cs_err err = cs_close(&ustate->handle);
if (err != CS_ERR_OK) {
fail_msg("cs_close() failed with: '%s'.",
cs_strerror(err));
return -1;
}
}
return 0;
}
static void cstest_unit_test(void **state)
{
assert(state);
UnitTestState *ustate = *state;
assert(ustate);
assert(ustate->handle);
assert(ustate->tcase);
csh handle = ustate->handle;
TestCase *tcase = ustate->tcase;
cs_insn *insns = NULL;
size_t insns_count = cs_disasm(handle, tcase->input->bytes,
tcase->input->bytes_count,
tcase->input->address, 0, &insns);
test_expected_compare(&ustate->handle, tcase->expected, insns,
insns_count, ustate->arch_bits);
ustate->decoded_insns += insns_count;
cs_free(insns, insns_count);
}
static void eval_test_cases(TestFile **test_files, TestRunStats *stats)
{
assert(test_files && stats);
// CMocka's API doesn't allow to init a CMUnitTest with a partially initialized state
// (which is later initialized in the test setup).
// So we do it manually here.
struct CMUnitTest *utest_table =
cs_mem_calloc(sizeof(struct CMUnitTest),
stats->tc_total); // Number of test cases.
char utest_id[128] = { 0 };
size_t tci = 0;
for (size_t i = 0; i < stats->valid_test_files; ++i) {
TestCase **test_cases = test_files[i]->test_cases;
const char *filename = test_files[i]->filename ?
test_files[i]->filename :
NULL;
for (size_t k = 0; k < test_files[i]->test_cases_count;
++k, ++tci) {
cs_snprintf(utest_id, sizeof(utest_id),
"%s - TC #%" PRIx32 ": ", filename, k);
if (test_cases[k]->skip) {
char *tc_name = test_input_stringify(
test_cases[k]->input, utest_id);
fprintf(stderr, "SKIP: %s\nReason: %s\n",
tc_name, test_cases[k]->skip_reason);
cs_mem_free(tc_name);
stats->skipped++;
continue;
}
UnitTestState *ut_state =
cs_mem_calloc(sizeof(UnitTestState), 1);
ut_state->tcase = test_cases[k];
utest_table[tci].name = test_input_stringify(
ut_state->tcase->input, utest_id);
utest_table[tci].initial_state = ut_state;
utest_table[tci].setup_func = cstest_unit_test_setup;
utest_table[tci].teardown_func =
cstest_unit_test_teardown;
utest_table[tci].test_func = cstest_unit_test;
}
}
assert(tci == stats->tc_total);
// Use private function here, because the API takes only constant tables.
int failed_tests = _cmocka_run_group_tests(
"All test cases", utest_table, stats->tc_total, NULL, NULL);
assert(failed_tests >= 0 && "Faulty return value");
for (size_t i = 0; i < stats->tc_total; ++i) {
UnitTestState *ustate = utest_table[i].initial_state;
if (!ustate) {
// Skipped test case
continue;
}
stats->decoded_insns += ustate->decoded_insns;
cs_mem_free((char *)utest_table[i].name);
cs_mem_free(utest_table[i].initial_state);
}
cs_mem_free(utest_table);
stats->failed += failed_tests;
stats->successful += stats->tc_total - failed_tests - stats->skipped;
}
/// Runs runs all valid tests in the given @test_files
/// and returns the result as well as statistics in @stats.
TestRunResult cstest_run_tests(char **test_file_paths, uint32_t path_count,
TestRunStats *stats)
{
TestFile **files = parse_test_files(test_file_paths, path_count, stats);
if (!files) {
return get_test_run_result(stats);
}
eval_test_cases(files, stats);
for (size_t i = 0; i < stats->valid_test_files; ++i) {
test_file_free(files[i]);
}
cs_mem_free(files);
return get_test_run_result(stats);
}
+23
View File
@@ -0,0 +1,23 @@
cmake_minimum_required(VERSION 3.15)
set(CSTEST_TEST_SRC_DIR ${CSTEST_TEST_DIR}/src)
set(CSTEST_TEST_INC_DIR ${CSTEST_TEST_DIR}/include)
include_directories(${CSTEST_TEST_INC_DIR}
${CSTEST_INCLUDE_DIR}
${PROJECT_SOURCE_DIR}
${PROJECT_SOURCE_DIR}/include)
file(GLOB CSTEST_TEST_SRC ${CSTEST_TEST_SRC_DIR}/*.c)
add_executable(unit_test ${CSTEST_TEST_SRC})
add_dependencies(unit_test libcstest)
target_link_libraries(unit_test PUBLIC libcstest)
add_test(NAME unit_cstest
COMMAND unit_test
WORKING_DIRECTORY ${CSTEST_TEST_DIR}
)
add_test(NAME integration_cstest
COMMAND python3 ${CSTEST_TEST_DIR}/integration_tests.py cstest
WORKING_DIRECTORY ${CSTEST_TEST_DIR}
)
+1
View File
@@ -0,0 +1 @@
Integration tests of cstest
+126
View File
@@ -0,0 +1,126 @@
#!/usr/bin/env python3
# Copyright © 2024 Rot127 <unisono@quyllur.org>
# SPDX-License-Identifier: BSD-3
# Typing for Python3.8
from __future__ import annotations
import sys
import subprocess as sp
from pathlib import Path
def check(cmd: list[str], expected_stdout: str, expected_stderr: str, fail_msg: str):
print(f"Run: {' '.join(cmd)}")
result = sp.run(cmd, capture_output=True)
stderr = result.stderr.decode("utf8")
stdout = result.stdout.decode("utf8")
if expected_stderr and expected_stderr not in stderr:
print(f"STDERR mismatch: '{expected_stderr}' not in stderr")
print("\n###################### STDERR ######################\n")
print(stderr)
print("####################################################\n")
print(fail_msg)
exit(1)
if expected_stdout and expected_stdout not in stdout:
print(f"STDOUT mismatch: '{expected_stdout}' not in stdout")
print("\n###################### STDOUT ######################\n")
print(stdout)
print("####################################################\n")
print(fail_msg)
exit(1)
def run_tests(cmd: str):
path = Path(__file__).parent.resolve()
cmd = cmd.split(" ")
check(
cmd + [f"{path.joinpath('empty_test_file.yaml')}"],
expected_stderr="Failed to parse test file ",
expected_stdout="",
fail_msg="Failed the empty file test",
)
check(
cmd + [f"{path.joinpath('missing_madatory_field.yaml')}"],
expected_stderr="Error: 'Missing required mapping field'",
expected_stdout="",
fail_msg="Failed the mandatory field test",
)
check(
cmd + [f"{path.joinpath('invalid_test_file.yaml')}"],
expected_stderr="Error: 'libyaml parser error'",
expected_stdout="",
fail_msg="Failed the invalid test file test",
)
check(
cmd + [f"{path.joinpath('min_valid_test_file.yaml')}"],
expected_stdout="All tests succeeded.",
expected_stderr="",
fail_msg="Failed the minimal valid parsing test",
)
check(
cmd + [f"{path.joinpath('invalid_cs_input.yaml')}"],
expected_stderr="'ar' is not mapped to a capstone architecture.",
expected_stdout="",
fail_msg="Test: Invalid CS option failed",
)
check(
cmd + [f"{path.joinpath('invalid_cs_input.yaml')}"],
expected_stderr="0 != 0x1",
expected_stdout="",
fail_msg="Test: Wrong number of instruction disassembled failed",
)
check(
cmd + [f"{path.joinpath('invalid_cs_input.yaml')}"],
expected_stderr="Option: 'thum' not used",
expected_stdout="",
fail_msg="Test: Invalid disassembly due to wrong option failed",
)
check(
cmd + [f"{path}"],
expected_stdout="Test files found: 6",
expected_stderr="",
fail_msg="Test: Detecting file in directory failed.",
)
if "cstest_py" in cmd:
check(
cmd
+ [
f"{path}",
"-e",
"invalid_cs_input.yaml",
"-i",
"invalid_cs_input.yaml",
"min_valid_test_file.yaml",
"-v",
"debug",
],
expected_stdout="Test files found: 2",
expected_stderr="",
fail_msg="Test: Detecting file in directory failed.",
)
def print_usage_exit():
print(f'{sys.argv[0]} "cstest_command"')
print('"cstest_command" examples:')
print('\t"python3 ../../bindings/python/cstest.py"')
print("\tcstest")
exit(1)
if __name__ == "__main__":
if len(sys.argv) != 2:
print_usage_exit()
run_tests(sys.argv[1])
print("All tests passed")
exit(0)
@@ -0,0 +1,29 @@
test_cases:
-
input:
bytes: [ 0x05, 0xb0, 0xa0, 0xe1 ]
arch: "ar" # Wrong arch
options: ["arm"]
expected:
insns:
-
asm_text: "mov r11, r5"
-
input:
bytes: [ 0x06 ] # Wrong number of bytes.
arch: "aarch64"
options: []
expected:
insns:
-
asm_text: "mov r1, r6"
-
input:
bytes: [ 0xc2, 0xf3, 0x00, 0x8f ]
arch: "arm"
options: ["thum"] # Wrong mode
expected:
insns:
-
asm_text: "bxj r2"
@@ -0,0 +1,11 @@
test_cases:
-
input:
bytes: [ 0x05, 0xb0, 0xa0, 0xe1 ]
arch: "arm"
options: ["arm"]
expected:
insns:
-
op_str: "mov r11, r5"
# Invisble tab
@@ -0,0 +1,31 @@
test_cases:
-
input:
bytes: [ 0x05, 0xb0, 0xa0, 0xe1 ]
arch: "arm"
options: ["arm"]
expected:
insns:
-
asm_text: "mov r11, r5"
-
input:
bytes: [ 0x06, 0x10, 0xa0, 0xe1 ]
arch: "arm"
options: ["arm"]
expected:
insns:
-
asm_text: "mov r1, r6"
-
input:
bytes: [ 0x06, 0x10, 0xa0, 0xe1, 0x05, 0xb0, 0xa0, 0xe1 ]
arch: "arm"
options: ["arm"]
expected:
insns:
-
asm_text: "mov r1, r6"
-
asm_text: "mov r11, r5"
@@ -0,0 +1,8 @@
test_cases:
-
input:
arch: "arm"
expected:
insns:
-
op_str: "mov r11, r5"
@@ -0,0 +1,31 @@
test_cases:
-
input:
bytes: [ 0x05, 0xb0, 0xa0, 0xe1 ]
arch: "arm"
options: ["arm"]
expected:
insns:
-
asm_text: "mov r11, r5"
-
input:
bytes: [ 0x06, 0x10, 0xa0, 0xe1 ]
arch: "arm"
options: ["arm"]
expected:
insns:
-
asm_text: "mov r1, r6"
-
input:
bytes: [ 0x06, 0x10, 0xa0, 0xe1, 0x05, 0xb0, 0xa0, 0xe1 ]
arch: "arm"
options: ["arm"]
expected:
insns:
-
asm_text: "mov r1, r6"
-
asm_text: "mov r11, r5"
+94
View File
@@ -0,0 +1,94 @@
// Copyright © 2024 Rot127 <unisono@quyllur.org>
// SPDX-License-Identifier: BSD-3
#include "../../../utils.h"
#include "../../../Mapping.h"
#include "test_mapping.h"
#include <stdint.h>
bool test_cs_enum_get_val()
{
bool found = false;
// Get first value
uint32_t val = enum_map_bin_search(cs_enum_map, ARR_SIZE(cs_enum_map),
"AAAAAAAAAAAAAAAAAAAAAAAAAA",
&found);
if (!found || val != 0xffffff) {
fprintf(stderr,
"enum_map_bin_search(cs_enum_map, ARR_SIZE(cs_enum_map), AAAAAAAAAAAAAAAAAAAAAAAAAA) failed is %d.\n",
val);
return false;
}
// Get second value
val = enum_map_bin_search(cs_enum_map, ARR_SIZE(cs_enum_map),
"AAAAAAAAAAAAAAAAAAAAAAAAAB",
&found);
if (!found || val != 0xffffff) {
fprintf(stderr,
"enum_map_bin_search(cs_enum_map, ARR_SIZE(cs_enum_map), AAAAAAAAAAAAAAAAAAAAAAAAAB) failed is %d.\n",
val);
return false;
}
// Get second to last value
val = enum_map_bin_search(cs_enum_map, ARR_SIZE(cs_enum_map),
"zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzx", &found);
if (!found || val != 0xffffff) {
fprintf(stderr,
"enum_map_bin_search(cs_enum_map, ARR_SIZE(cs_enum_map), zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzx) failed is %d.\n",
val);
return false;
}
// Get last value
val = enum_map_bin_search(cs_enum_map, ARR_SIZE(cs_enum_map),
"zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz", &found);
if (!found || val != 0xffffff) {
fprintf(stderr,
"enum_map_bin_search(cs_enum_map, ARR_SIZE(cs_enum_map), zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz) failed is %d.\n",
val);
return false;
}
// Some values
val = enum_map_bin_search(cs_enum_map, ARR_SIZE(cs_enum_map),
"AArch64CC_EQ", &found);
if (!found || val != AArch64CC_EQ) {
fprintf(stderr,
"enum_map_bin_search(cs_enum_map, ARR_SIZE(cs_enum_map), AArch64CC_EQ) failed is %d.\n",
val);
return false;
}
val = enum_map_bin_search(cs_enum_map, ARR_SIZE(cs_enum_map),
"AArch64CC_Invalid", &found);
if (!found || val != AArch64CC_Invalid) {
fprintf(stderr,
"enum_map_bin_search(cs_enum_map, ARR_SIZE(cs_enum_map), AArch64CC_In) failed is %d.\n",
val);
return false;
}
enum_map_bin_search(cs_enum_map, ARR_SIZE(cs_enum_map), "\0", &found);
if (found) {
fprintf(stderr, "Out of bounds failed.\n");
return false;
}
enum_map_bin_search(cs_enum_map, ARR_SIZE(cs_enum_map),
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
&found);
if (found) {
fprintf(stderr, "Out of bounds failed.\n");
return false;
}
return true;
}
int main()
{
bool success = true;
success &= test_cs_enum_get_val();
printf("test_cs_enum_get_val: %s\n", success ? "ok" : "fail");
return success ? 0 : 1;
}