mirror of
https://github.com/capstone-engine/capstone.git
synced 2024-11-26 23:10:32 +00:00
Add test with ASAN enabled. (#2313)
* Add test with ASAN enabled.
* Fix leaks in cstool and cs.c
* Add work around so ASAN binaries don't DEADSIGNAL due to too many randomized address bits.
* Add ASAN build arguments to cstest
* Fix leaks in cstest
* Use cstest binary build by the main build.
* Add clonging step for cmocka when cstest is build
* Skip Python tests for ASAN
* Remove make build from CI
* Fix leaks in cstest.
- Rewrite split to remove leaks and improve runtime by 6%
- Add free()
* Fix cmocka external project to stable branch.
* Revert "Fix leaks in cstest."
This reverts commit bf8ee125b0c58f9c794eb081a69c80f8a71825cd.
* Fix memleaks in cstest
* Document adding of ASAN job to release guide
* Add CAPSTONE_BUILD_CSTEST to build docs
* Fix double free
* Add more detail tests to CI and fix them
* Initialize variables
* Fix typo
* Update cstest build docs
* Revert "Remove make build from CI"
This reverts commit 84f7360c6da6183cd41bec0fef3e1d0a2ee49ddf.
* Make cstest only run for cmake builds.
* Add cstest job for make build.
* Add CAPSTONE_DIET build test.
* Compile the compatibility header test with ASAN if enabled.
* Fix DIET build by excluding not used code.
* Missing "
* Build static library with ASAN and DIET if enabled.
* Revert "Add CAPSTONE_DIET build test."
This reverts commit 71e1469dee
.
This commit is contained in:
parent
03c41e1be4
commit
0a67596f70
53
.github/workflows/CITest.yml
vendored
53
.github/workflows/CITest.yml
vendored
@ -36,6 +36,7 @@ jobs:
|
||||
python-arch: x64,
|
||||
python-version: '3.6',
|
||||
build-system: 'cmake',
|
||||
enable-asan: 'OFF'
|
||||
}
|
||||
- {
|
||||
name: 'ubuntu-22.04 x64 python3.9 make',
|
||||
@ -44,7 +45,8 @@ jobs:
|
||||
python-arch: x64,
|
||||
python-version: '3.9',
|
||||
build-system: 'make',
|
||||
}
|
||||
enable-asan: 'OFF'
|
||||
}
|
||||
- {
|
||||
name: 'ubuntu-22.04 x64 python3.9 cmake',
|
||||
os: ubuntu-22.04,
|
||||
@ -52,6 +54,7 @@ jobs:
|
||||
python-arch: x64,
|
||||
python-version: '3.9',
|
||||
build-system: 'cmake',
|
||||
enable-asan: 'OFF'
|
||||
}
|
||||
- {
|
||||
name: 'ubuntu-22.04 x64 python3.11 cmake',
|
||||
@ -60,6 +63,16 @@ jobs:
|
||||
python-arch: x64,
|
||||
python-version: '3.11',
|
||||
build-system: 'cmake',
|
||||
enable-asan: 'OFF'
|
||||
}
|
||||
- {
|
||||
name: 'ubuntu-22.04 x64 python3.11 ASAN',
|
||||
os: ubuntu-latest,
|
||||
arch: x64,
|
||||
python-arch: x64,
|
||||
python-version: '3.11',
|
||||
build-system: 'cmake',
|
||||
enable-asan: 'ON'
|
||||
}
|
||||
|
||||
steps:
|
||||
@ -88,35 +101,61 @@ jobs:
|
||||
|
||||
- name: cmake
|
||||
if: startsWith(matrix.config.build-system, 'cmake')
|
||||
env:
|
||||
asan: ${{ matrix.config.enable-asan }}
|
||||
run: |
|
||||
mkdir build && cd build
|
||||
# build static library
|
||||
cmake -DCAPSTONE_INSTALL=1 -DCMAKE_INSTALL_PREFIX=/usr ..
|
||||
cmake -DCAPSTONE_INSTALL=1 -DCMAKE_INSTALL_PREFIX=/usr -DENABLE_ASAN=${asan} -DCAPSTONE_BUILD_DIET=${diet_build} ..
|
||||
cmake --build . --config Release
|
||||
# build shared library
|
||||
cmake -DCAPSTONE_INSTALL=1 -DBUILD_SHARED_LIBS=1 -DCMAKE_INSTALL_PREFIX=/usr ..
|
||||
cmake -DCAPSTONE_INSTALL=1 -DBUILD_SHARED_LIBS=1 -DCMAKE_INSTALL_PREFIX=/usr -DCAPSTONE_BUILD_CSTEST=ON -DENABLE_ASAN=${asan} ..
|
||||
sudo cmake --build . --config Release --target install
|
||||
cp libcapstone.* ../
|
||||
cp libcapstone.* ../tests/
|
||||
cp test_* ../tests/
|
||||
|
||||
- name: Lower number of KASL randomized address bits
|
||||
run: |
|
||||
# Work-around ASAN bug https://github.com/google/sanitizers/issues/1716
|
||||
sudo sysctl vm.mmap_rnd_bits=28
|
||||
|
||||
- name: "Compatibility header test build"
|
||||
if: matrix.config.diet-build == 'OFF'
|
||||
env:
|
||||
asan: ${{ matrix.config.enable-asan }}
|
||||
run: |
|
||||
cd "$(git rev-parse --show-toplevel)/suite/auto-sync/c_tests/"
|
||||
clang -lcapstone src/test_arm64_compatibility_header.c -o test_arm64_compatibility_header
|
||||
if [ "$asan" = "ON" ]; then
|
||||
clang -lcapstone -fsanitize=address src/test_arm64_compatibility_header.c -o test_arm64_compatibility_header
|
||||
else
|
||||
clang -lcapstone src/test_arm64_compatibility_header.c -o test_arm64_compatibility_header
|
||||
fi
|
||||
./test_arm64_compatibility_header
|
||||
cd "$(git rev-parse --show-toplevel)"
|
||||
|
||||
- name: cstool - reaches disassembler engine
|
||||
run: |
|
||||
sh suite/run_invalid_cstool.sh
|
||||
|
||||
- name: cstest
|
||||
- name: cstest (cmake)
|
||||
if: startsWith(matrix.config.build-system, 'cmake')
|
||||
run: |
|
||||
python suite/cstest/cstest_report.py -D -d suite/MC
|
||||
python suite/cstest/cstest_report.py -D -f suite/cstest/issues.cs
|
||||
python suite/cstest/cstest_report.py -D -f tests/cs_details/issue.cs
|
||||
|
||||
- name: cstest (make)
|
||||
if: startsWith(matrix.config.build-system, 'make')
|
||||
run: |
|
||||
cd suite/cstest && ./build_cstest.sh
|
||||
python cstest_report.py -D -t build/cstest -d ../MC
|
||||
python cstest_report.py -D -t build/cstest -f issues.cs; cd ..
|
||||
python cstest_report.py -D -t build/cstest -f issues.cs
|
||||
python cstest_report.py -D -t build/cstest -f ../../tests/cs_details/issue.cs
|
||||
cd ../../
|
||||
|
||||
- name: verify python binding
|
||||
if: matrix.config.enable-asan == 'OFF'
|
||||
run: |
|
||||
mkdir -p bindings/python/capstone/lib && cp libcapstone.so.5.* bindings/python/capstone/lib/libcapstone.so
|
||||
cd bindings/python
|
||||
@ -136,6 +175,7 @@ jobs:
|
||||
make check
|
||||
|
||||
- name: run python binding test
|
||||
if: matrix.config.enable-asan == 'OFF'
|
||||
run: |
|
||||
cp libcapstone.* bindings/python/prebuilt
|
||||
cd bindings/python
|
||||
@ -144,6 +184,7 @@ jobs:
|
||||
BUILD_TESTS=no make tests
|
||||
|
||||
- name: run cython binding test
|
||||
if: matrix.config.enable-asan == 'OFF'
|
||||
run: |
|
||||
pip install cython
|
||||
cd bindings/python
|
||||
|
@ -68,6 +68,13 @@ option(CAPSTONE_USE_ARCH_REGISTRATION "Use explicit architecture registration" O
|
||||
option(CAPSTONE_ARCHITECTURE_DEFAULT "Whether architectures are enabled by default" ON)
|
||||
option(CAPSTONE_DEBUG "Whether to enable extra debug assertions" OFF)
|
||||
option(CAPSTONE_INSTALL "Generate install target" ${PROJECT_IS_TOP_LEVEL})
|
||||
option(ENABLE_ASAN "Enable address sanitizer" OFF)
|
||||
|
||||
if (ENABLE_ASAN)
|
||||
add_definitions(-DASAN_ENABLED)
|
||||
add_compile_options(-fsanitize=address)
|
||||
add_link_options(-fsanitize=address)
|
||||
endif()
|
||||
|
||||
# If building for OSX it's best to allow CMake to handle building both architectures
|
||||
if(APPLE AND NOT CAPSTONE_BUILD_MACOS_THIN)
|
||||
@ -855,16 +862,28 @@ if(CAPSTONE_BUILD_CSTOOL)
|
||||
endif()
|
||||
|
||||
if(CAPSTONE_BUILD_CSTEST)
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(CMOCKA REQUIRED IMPORTED_TARGET cmocka)
|
||||
include(ExternalProject)
|
||||
ExternalProject_Add(cmocka_ext
|
||||
PREFIX extern
|
||||
GIT_REPOSITORY "https://git.cryptomilk.org/projects/cmocka.git"
|
||||
GIT_TAG "origin/stable-1.1"
|
||||
CONFIGURE_COMMAND cmake -DBUILD_SHARED_LIBS=OFF ../cmocka_ext/
|
||||
BUILD_COMMAND cmake --build . --config Release
|
||||
INSTALL_COMMAND ""
|
||||
)
|
||||
set(CMOCKA_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/extern/src/cmocka_ext/include)
|
||||
set(CMOCKA_LIB_DIR ${CMAKE_CURRENT_BINARY_DIR}/extern/src/cmocka_ext-build/src/)
|
||||
add_library(cmocka STATIC IMPORTED)
|
||||
set_target_properties(cmocka PROPERTIES IMPORTED_LOCATION ${CMOCKA_LIB_DIR}/libcmocka.a)
|
||||
|
||||
file(GLOB CSTEST_SRC suite/cstest/src/*.c)
|
||||
add_executable(cstest ${CSTEST_SRC})
|
||||
target_link_libraries(cstest PUBLIC capstone PkgConfig::CMOCKA)
|
||||
add_dependencies(cstest cmocka_ext)
|
||||
target_link_libraries(cstest PUBLIC capstone cmocka)
|
||||
target_include_directories(cstest PRIVATE
|
||||
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
|
||||
${PROJECT_SOURCE_DIR}/suite/cstest/include
|
||||
${CMOCKA_INCLUDE_DIRS}
|
||||
${CMOCKA_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
if(CAPSTONE_INSTALL)
|
||||
|
@ -56,6 +56,8 @@ Get CMake for free from http://www.cmake.org.
|
||||
- CAPSTONE_X86_REDUCE: change this to ON to make X86 binary smaller.
|
||||
- CAPSTONE_X86_ATT_DISABLE: change this to ON to disable AT&T syntax on x86.
|
||||
- CAPSTONE_DEBUG: change this to ON to enable extra debug assertions.
|
||||
- CAPSTONE_BUILD_CSTEST: Build `cstest` in `suite/cstest/`
|
||||
- ENABLE_ASAN: Compiles Capstone with the address sanitizer.
|
||||
|
||||
By default, Capstone use system dynamic memory management, and both DIET and X86_REDUCE
|
||||
modes are disabled. To use your own memory allocations, turn ON both DIET &
|
||||
|
12
Mapping.h
12
Mapping.h
@ -74,17 +74,27 @@ const cs_ac_type mapping_get_op_access(MCInst *MI, unsigned OpNum,
|
||||
/// Macro for easier access of operand types from the map.
|
||||
/// Assumes the istruction operands map is called "insn_operands"
|
||||
/// Only usable by `auto-sync` archs!
|
||||
#ifndef CAPSTONE_DIET
|
||||
#define map_get_op_type(MI, OpNum) \
|
||||
mapping_get_op_type(MI, OpNum, (const map_insn_ops *)insn_operands, \
|
||||
sizeof(insn_operands) / sizeof(insn_operands[0]))
|
||||
#else
|
||||
#define map_get_op_type(MI, OpNum) \
|
||||
CS_OP_INVALID
|
||||
#endif
|
||||
|
||||
/// Macro for easier access of operand access flags from the map.
|
||||
/// Assumes the istruction operands map is called "insn_operands"
|
||||
/// Only usable by `auto-sync` archs!
|
||||
#ifndef CAPSTONE_DIET
|
||||
#define map_get_op_access(MI, OpNum) \
|
||||
mapping_get_op_access(MI, OpNum, (const map_insn_ops *)insn_operands, \
|
||||
sizeof(insn_operands) / \
|
||||
sizeof(insn_operands[0]))
|
||||
#else
|
||||
#define map_get_op_access(MI, OpNum) \
|
||||
CS_AC_INVALID
|
||||
#endif
|
||||
|
||||
///< Map for ids to their string
|
||||
typedef struct name_map {
|
||||
@ -212,4 +222,4 @@ bool map_use_alias_details(const MCInst *MI);
|
||||
|
||||
void map_set_alias_id(MCInst *MI, const SStream *O, const name_map *alias_mnem_id_map, int map_size);
|
||||
|
||||
#endif // CS_MAPPING_H
|
||||
#endif // CS_MAPPING_H
|
||||
|
@ -762,11 +762,11 @@ void ARM_init_mri(MCRegisterInfo *MRI)
|
||||
ARR_SIZE(ARMSubRegIdxLists), 0);
|
||||
}
|
||||
|
||||
#ifndef CAPSTONE_DIET
|
||||
static const map_insn_ops insn_operands[] = {
|
||||
#include "ARMGenCSMappingInsnOp.inc"
|
||||
};
|
||||
|
||||
#ifndef CAPSTONE_DIET
|
||||
void ARM_reg_access(const cs_insn *insn, cs_regs regs_read,
|
||||
uint8_t *regs_read_count, cs_regs regs_write,
|
||||
uint8_t *regs_write_count)
|
||||
|
@ -760,6 +760,7 @@ static void add_groups(MCInst *MI)
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef CAPSTONE_DIET
|
||||
static void update_regs_access(MCInst *MI, unsigned int opcode)
|
||||
{
|
||||
if (opcode == HPPA_INS_INVALID)
|
||||
@ -803,6 +804,7 @@ static void update_regs_access(MCInst *MI, unsigned int opcode)
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void HPPA_printInst(MCInst *MI, SStream *O, void *Info)
|
||||
{
|
||||
|
@ -300,6 +300,7 @@ const char *HPPA_insn_name(csh handle, unsigned int id)
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef CAPSTONE_DIET
|
||||
/* Integer register names, indexed by the numbers which appear in the
|
||||
opcodes. */
|
||||
static const char *const reg_names[] = {
|
||||
@ -341,6 +342,7 @@ static const char *const sp_fp_reg[] = {
|
||||
"fr16R", "fr17R", "fr18R", "fr19R", "fr20R", "fr21R", "fr22R", "fr23R",
|
||||
"fr24R", "fr25R", "fr26R", "fr27R", "fr28R", "fr29R", "fr30R", "fr31R"
|
||||
};
|
||||
#endif
|
||||
|
||||
const char *HPPA_reg_name(csh handle, unsigned int reg)
|
||||
{
|
||||
@ -437,4 +439,4 @@ void HPPA_reg_access(const cs_insn *insn, cs_regs regs_read,
|
||||
sort_and_uniq(regs_write, write_count, regs_write_count);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -225,8 +225,10 @@ void PPC_printer(MCInst *MI, SStream *O, void * /* MCRegisterInfo* */ info)
|
||||
MI->fillDetailOps = detail_is_set(MI);
|
||||
MI->flat_insn->usesAliasDetails = map_use_alias_details(MI);
|
||||
PPC_LLVM_printInst(MI, MI->address, "", O);
|
||||
#ifndef CAPSTONE_DIET
|
||||
map_set_alias_id(MI, O, insn_alias_mnem_map,
|
||||
ARR_SIZE(insn_alias_mnem_map));
|
||||
#endif
|
||||
}
|
||||
|
||||
bool PPC_getInstruction(csh handle, const uint8_t *bytes, size_t bytes_len,
|
||||
@ -264,9 +266,11 @@ bool PPC_getFeatureBits(unsigned int mode, unsigned int feature)
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifndef CAPSTONE_DIET
|
||||
static const map_insn_ops insn_operands[] = {
|
||||
#include "PPCGenCSMappingInsnOp.inc"
|
||||
};
|
||||
#endif
|
||||
|
||||
/// @brief Handles memory operands.
|
||||
/// @param MI The MCInst.
|
||||
|
7
cs.c
7
cs.c
@ -697,7 +697,7 @@ CAPSTONE_EXPORT
|
||||
cs_err CAPSTONE_API cs_open(cs_arch arch, cs_mode mode, csh *handle)
|
||||
{
|
||||
cs_err err;
|
||||
struct cs_struct *ud;
|
||||
struct cs_struct *ud = NULL;
|
||||
if (!cs_mem_malloc || !cs_mem_calloc || !cs_mem_realloc || !cs_mem_free || !cs_vsnprintf)
|
||||
// Error: before cs_open(), dynamic memory management must be initialized
|
||||
// with cs_option(CS_OPT_MEM)
|
||||
@ -736,6 +736,7 @@ cs_err CAPSTONE_API cs_open(cs_arch arch, cs_mode mode, csh *handle)
|
||||
|
||||
return CS_ERR_OK;
|
||||
} else {
|
||||
cs_mem_free(ud);
|
||||
*handle = 0;
|
||||
return CS_ERR_ARCH;
|
||||
}
|
||||
@ -744,8 +745,8 @@ cs_err CAPSTONE_API cs_open(cs_arch arch, cs_mode mode, csh *handle)
|
||||
CAPSTONE_EXPORT
|
||||
cs_err CAPSTONE_API cs_close(csh *handle)
|
||||
{
|
||||
struct cs_struct *ud;
|
||||
struct insn_mnem *next, *tmp;
|
||||
struct cs_struct *ud = NULL;
|
||||
struct insn_mnem *next = NULL, *tmp = NULL;
|
||||
|
||||
if (*handle == 0)
|
||||
// invalid handle
|
||||
|
@ -678,13 +678,15 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
cs_free(insn, count);
|
||||
free(assembly);
|
||||
} else {
|
||||
printf("ERROR: invalid assembly code\n");
|
||||
cs_close(&handle);
|
||||
free(assembly);
|
||||
return(-4);
|
||||
}
|
||||
|
||||
cs_close(&handle);
|
||||
free(assembly);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -58,6 +58,8 @@ void print_insn_detail_arm(csh handle, cs_insn *ins)
|
||||
printf("\t\t\toperands[%u].mem.scale: %d\n", i, op->mem.scale);
|
||||
if (op->mem.disp != 0)
|
||||
printf("\t\t\toperands[%u].mem.disp: 0x%x\n", i, op->mem.disp);
|
||||
if (op->mem.align != 0)
|
||||
printf("\t\t\toperands[%u].mem.align: 0x%x\n", i, op->mem.align);
|
||||
if (op->mem.lshift != 0)
|
||||
printf("\t\t\toperands[%u].mem.lshift: 0x%x\n", i, op->mem.lshift);
|
||||
|
||||
|
@ -174,6 +174,7 @@ These features are only supported by `auto-sync`-enabled architectures.
|
||||
**More code quality checks**
|
||||
|
||||
- `clang-tidy` is now run on all files changed by a PR.
|
||||
- ASAN: All tests are now run with the address sanitizer enabled. This includes checking for leaks.
|
||||
|
||||
**Instruction formats for PPC**
|
||||
|
||||
|
@ -6,7 +6,7 @@ LIBRARY = -lcmocka -lcapstone -L../..
|
||||
all:
|
||||
rm -rf $(BUILD)
|
||||
mkdir $(BUILD)
|
||||
$(CC) $(SOURCE)/*.c $(INCLUDE:%=-I %) -g -o $(BUILD)/cstest $(LIBRARY)
|
||||
$(CC) $(SOURCE)/*.c $(INCLUDE:%=-I %) ${CMAKE_C_FLAGS} -g -o $(BUILD)/cstest $(LIBRARY)
|
||||
cstest:
|
||||
$(BUILD)/cstest -d ../MC
|
||||
clean:
|
||||
|
@ -13,23 +13,12 @@ brew install cmocka
|
||||
|
||||
- Build Cmocka
|
||||
|
||||
```
|
||||
cd cmocka_dir
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ..
|
||||
make
|
||||
sudo make install
|
||||
```
|
||||
|
||||
## Build
|
||||
|
||||
- Build `cstest`
|
||||
You can build `cstest` with `cmake` when building Capstone. Just pass the `CAPSTONE_BUILD_CSTEST` flag
|
||||
during configuration.
|
||||
|
||||
```
|
||||
cd suite/cstest
|
||||
make
|
||||
```
|
||||
Alternatively you can use the `build_cstest.sh` file in this directory.
|
||||
|
||||
## Usage
|
||||
|
||||
|
@ -1,9 +1,21 @@
|
||||
#!/bin/sh
|
||||
#!/bin/sh -x
|
||||
|
||||
cd cmocka
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
cd cmocka && mkdir build && cd build
|
||||
if [ "$(uname)" = Darwin ]; then
|
||||
cmake -DCMAKE_INSTALL_PREFIX=/usr/local .. && make -j2 && sudo make install
|
||||
cmake -DCMAKE_INSTALL_PREFIX=/usr/local .. && make -j2 && sudo make install
|
||||
elif [ "$asan" = "ON" ]; then
|
||||
CMAKE_C_FLAGS="-fsanitize=address" CMAKE_LINK_FLAGS="-fsanitize=address" cmake -DCMAKE_INSTALL_PREFIX=/usr/local .. && make -j2 && sudo make install
|
||||
else # Linux
|
||||
cmake -DCMAKE_INSTALL_PREFIX=/usr .. && make -j2 && sudo make install
|
||||
cmake -DCMAKE_INSTALL_PREFIX=/usr .. && make -j2 && sudo make install
|
||||
fi
|
||||
|
||||
cd ../..
|
||||
|
||||
if [ "$asan" = "ON" ]; then
|
||||
CMAKE_C_FLAGS="-fsanitize=address" make
|
||||
else
|
||||
make
|
||||
fi
|
||||
cd ../.. && make
|
||||
|
@ -15,7 +15,7 @@ def Usage(s):
|
||||
sys.exit(-1)
|
||||
|
||||
def get_report_file(toolpath, filepath, getDetails, cmt_out):
|
||||
cmd = [toolpath, '-f', filepath]
|
||||
cmd = [toolpath if toolpath else "cstest", '-f', filepath]
|
||||
process = Popen(cmd, stdout=PIPE, stderr=PIPE)
|
||||
stdout, stderr = process.communicate()
|
||||
if process.returncode != 0:
|
||||
|
@ -17,7 +17,7 @@
|
||||
#define X86_32 1
|
||||
#define X86_64 2
|
||||
|
||||
char **split(char *str, char *delim, int *size);
|
||||
char **split(const char *str, const char *delim, int *size);
|
||||
void print_strs(char **list_str, int size);
|
||||
void free_strs(char **list_str, int size);
|
||||
void add_str(char **src, const char *format, ...);
|
||||
|
@ -52,6 +52,8 @@ char *get_detail_arm(csh *handle, cs_mode mode, cs_insn *ins)
|
||||
add_str(&result, " ; operands[%u].mem.scale: %d", i, op->mem.scale);
|
||||
if (op->mem.disp != 0)
|
||||
add_str(&result, " ; operands[%u].mem.disp: 0x%x", i, op->mem.disp);
|
||||
if (op->mem.align != 0)
|
||||
add_str(&result, " ; operands[%u].mem.align: 0x%x", i, op->mem.align);
|
||||
if (op->mem.lshift != 0)
|
||||
add_str(&result, " ; operands[%u].mem.lshift: 0x%x", i, op->mem.lshift);
|
||||
|
||||
|
@ -85,6 +85,10 @@ void test_single_MC(csh *handle, int mc_mode, char *line)
|
||||
// and laeds to wrong results.
|
||||
cs_arch arch = ((struct cs_struct *)(uintptr_t)*handle)->arch;
|
||||
if (arch != CS_ARCH_ARM) {
|
||||
if (insn->detail) {
|
||||
free(insn->detail);
|
||||
}
|
||||
free(insn);
|
||||
cs_disasm(*handle, code, size_byte, offset, 0, &insn);
|
||||
|
||||
strcpy(tmp_noreg, insn[0].mnemonic);
|
||||
@ -232,6 +236,7 @@ void test_single_issue(csh *handle, cs_mode mode, char *line, int detail)
|
||||
offset = 0;
|
||||
list_byte = split(offset_opcode[0], ",", &size_byte);
|
||||
}
|
||||
free_strs(offset_opcode, size_offset_opcode);
|
||||
|
||||
code = (unsigned char *)malloc(sizeof(char) * size_byte);
|
||||
for (i = 0; i < size_byte; ++i) {
|
||||
@ -239,6 +244,8 @@ void test_single_issue(csh *handle, cs_mode mode, char *line, int detail)
|
||||
}
|
||||
|
||||
count = cs_disasm(*handle, code, size_byte, offset, 0, &insn);
|
||||
free_strs(list_byte, size_byte);
|
||||
free(code);
|
||||
for (i = 0; i < count; ++i) {
|
||||
tmp = (char *)malloc(strlen(insn[i].mnemonic) + strlen(insn[i].op_str) + 100);
|
||||
strcpy(tmp, insn[i].mnemonic);
|
||||
@ -280,10 +287,10 @@ void test_single_issue(csh *handle, cs_mode mode, char *line, int detail)
|
||||
fprintf(stderr, "[ ERROR ] --- %s --- \"%s\" not in \"%s\"\n", list_part[0], list_part_issue_result[i], cs_result);
|
||||
cs_free(insn, count);
|
||||
free_strs(list_part, size_part);
|
||||
free_strs(list_byte, size_byte);
|
||||
free(cs_result);
|
||||
// free_strs(list_part_cs_result, size_part_cs_result);
|
||||
free_strs(list_part_issue_result, size_part_issue_result);
|
||||
free(tmptmp);
|
||||
_fail(__FILE__, __LINE__);
|
||||
}
|
||||
free(tmptmp);
|
||||
@ -291,7 +298,6 @@ void test_single_issue(csh *handle, cs_mode mode, char *line, int detail)
|
||||
|
||||
cs_free(insn, count);
|
||||
free_strs(list_part, size_part);
|
||||
free_strs(list_byte, size_byte);
|
||||
free(cs_result);
|
||||
// free_strs(list_part_cs_result, size_part_cs_result);
|
||||
free_strs(list_part_issue_result, size_part_issue_result);
|
||||
|
@ -4,15 +4,12 @@
|
||||
|
||||
#include "helper.h"
|
||||
|
||||
char **split(char *str, char *delim, int *size)
|
||||
char **split(const char *str, const char *delim, int *size)
|
||||
{
|
||||
char **result;
|
||||
char *token, *src;
|
||||
int cnt;
|
||||
|
||||
cnt = 0;
|
||||
src = str;
|
||||
result = NULL;
|
||||
char **result = NULL;
|
||||
char *token = NULL;
|
||||
const char *src = str;
|
||||
int cnt = 0;
|
||||
|
||||
while ((token = strstr(src, delim)) != NULL) {
|
||||
result = (char **)realloc(result, sizeof(char *) * (cnt + 1));
|
||||
|
@ -431,6 +431,11 @@ static void test_file(const char *filename)
|
||||
printf("[!] Noted:\n[ ERROR ] --- \"<capstone result>\" != \"<user result>\"\n");
|
||||
printf("\n\n");
|
||||
free_strs(list_lines, size_lines);
|
||||
for (int k = 0; tests && k < number_of_tests; k++) {
|
||||
free((char *)tests[k].name);
|
||||
}
|
||||
free(tests);
|
||||
free(content);
|
||||
}
|
||||
|
||||
static void test_folder(const char *folder)
|
||||
|
@ -1,4 +1,4 @@
|
||||
#!/bin/sh
|
||||
#!/bin/sh -x
|
||||
|
||||
cstool -d x64 0x4 | grep "ERROR: invalid assembly code" &&
|
||||
cstool -d arm 0x1 | grep "ERROR: invalid assembly code" &&
|
||||
@ -27,3 +27,5 @@ cstool -d riscv64 0x1 | grep "ERROR: invalid assembly code" &&
|
||||
cstool -d sh 0x1 | grep "ERROR: invalid assembly code" &&
|
||||
cstool -d tc162 0x1 | grep "ERROR: invalid assembly code"
|
||||
|
||||
# One successful disassembly
|
||||
cstool -d x64 0xc5,0xca,0x58,0xd4
|
||||
|
@ -130,7 +130,7 @@
|
||||
|
||||
!# issue 0 ARM operand groups 0xa4,0xf9,0x6d,0x0e == vld3.16 {d0[], d2[], d4[]}, [r4]! ;
|
||||
!# CS_ARCH_ARM, CS_MODE_THUMB, CS_OPT_DETAIL
|
||||
0xa4,0xf9,0x6d,0x0e == vld3.16 {d0[], d2[], d4[]}, [r4]! ; op_count: 4 ; operands[0].type: REG = d0 ; operands[0].access: WRITE ; operands[1].type: REG = d2 ; operands[1].access: WRITE ; operands[2].type: REG = d4 ; operands[2].access: WRITE ; operands[3].type: MEM ; operands[3].mem.index: REG = r4 ; operands[3].access: READ ; Write-back: True ; Registers read: r4 ; Registers modified: r4 d0 d2 d4
|
||||
0xa4,0xf9,0x6d,0x0e == vld3.16 {d0[], d2[], d4[]}, [r4]! ; op_count: 4 ; operands[0].type: REG = d0 ; operands[0].access: WRITE ; operands[1].type: REG = d2 ; operands[1].access: WRITE ; operands[2].type: REG = d4 ; operands[2].access: WRITE ; operands[3].type: MEM ; operands[3].mem.base: REG = r4 ; operands[3].access: READ | WRITE ; Write-back: True ; Registers read: r4 ; Registers modified: r4 d0 d2 d4
|
||||
|
||||
!# issue 0 ARM operand groups 0x0d,0x50,0x66,0xe4 == strbt r5, [r6], #-13 ;
|
||||
!# CS_ARCH_ARM, CS_MODE_ARM, CS_OPT_DETAIL
|
||||
@ -166,7 +166,7 @@
|
||||
|
||||
!# issue 0 ARM operand groups 0xa4,0xf9,0xed,0x0b == vld4.32 {d0[1], d2[1], d4[1], d6[1]}, [r4:128]! ;
|
||||
!# CS_ARCH_ARM, CS_MODE_THUMB, CS_OPT_DETAIL
|
||||
0xa4,0xf9,0xed,0x0b == vld4.32 {d0[1], d2[1], d4[1], d6[1]}, [r4:0x80]! ; op_count: 5 ; operands[0].type: REG = d0 ; operands[0].neon_lane = 1 ; operands[0].access: READ | WRITE ; operands[1].type: REG = d2 ; operands[1].neon_lane = 1 ; operands[1].access: READ | WRITE ; operands[2].type: REG = d4 ; operands[2].neon_lane = 1 ; operands[2].access: READ | WRITE ; operands[3].type: REG = d6 ; operands[3].neon_lane = 1 ; operands[3].access: READ | WRITE ; operands[4].type: MEM ; operands[4].mem.index: REG = r4 ; operands[4].mem.disp: 0x80 ; operands[4].access: READ ; Write-back: True ; Registers read: d0 d2 d4 d6 r4 ; Registers modified: r4 d0 d2 d4 d6
|
||||
0xa4,0xf9,0xed,0x0b == vld4.32 {d0[1], d2[1], d4[1], d6[1]}, [r4:0x80]! ; op_count: 5 ; operands[0].type: REG = d0 ; operands[0].neon_lane = 1 ; operands[0].access: READ | WRITE ; operands[1].type: REG = d2 ; operands[1].neon_lane = 1 ; operands[1].access: READ | WRITE ; operands[2].type: REG = d4 ; operands[2].neon_lane = 1 ; operands[2].access: READ | WRITE ; operands[3].type: REG = d6 ; operands[3].neon_lane = 1 ; operands[3].access: READ | WRITE ; operands[4].type: MEM ; operands[4].mem.base: REG = r4 ; operands[4].mem.align: 0x80 ; operands[4].access: READ | WRITE ; Write-back: True ; Registers read: d0 d2 d4 d6 r4 ; Registers modified: r4 d0 d2 d4 d6
|
||||
|
||||
!# issue 0 ARM operand groups 0x42,0x03,0xb0,0xf3 == aesd.8 q0, q1 ;
|
||||
!# CS_ARCH_ARM, CS_MODE_ARM | CS_MODE_V8, CS_OPT_DETAIL
|
||||
@ -202,5 +202,5 @@
|
||||
|
||||
!# issue 0 ARM operand groups 0xef,0xf3,0x11,0x85 == ldrhi pc, [r1, #-0x3ef]
|
||||
!# CS_ARCH_ARM, CS_MODE_ARM, CS_OPT_DETAIL
|
||||
0xef,0xf3,0x11,0x85 == ldrhi pc, [r1, #-0x3ef] ; op_count: 2 ; operands[0].type: REG = r15 ; operands[0].access: WRITE ; operands[1].type: MEM ; operands[1].mem.base: REG = r1 ; operands[1].mem.disp: 0x3ef ; operands[1].access: READ ; Code condition: 8 ; Registers read: cpsr r1 ; Registers modified: r15 ; Groups: IsARM
|
||||
0xef,0xf3,0x11,0x85 == ldrhi pc, [r1, #-0x3ef] ; op_count: 2 ; operands[0].type: REG = r15 ; operands[0].access: WRITE ; operands[1].type: MEM ; operands[1].mem.base: REG = r1 ; operands[1].mem.disp: 0x3ef ; operands[1].access: READ ; Code condition: 8 ; Registers read: cpsr r1 ; Registers modified: r15 ; Groups: IsARM jump
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user