diff --git a/.github/workflows/CITest.yml b/.github/workflows/CITest.yml index 9fd30c66..95f95bc5 100644 --- a/.github/workflows/CITest.yml +++ b/.github/workflows/CITest.yml @@ -1,19 +1,62 @@ name: Run Test -on: [push, pull_request] +on: + push: + paths-ignore: + - ".gitignore" + - "docs/**" + - "ChangeLog" + - "CREDITS.TXT" + - "COMPILE.TXT" + - "COMPILE_MSVC.TXT" + - "COMPILE_CMAKE.TXT" + - "HACK.TXT" + - "LICENSE.TXT" + - "LICENSE_LLVM.TXT" + - "README.md" + - "RELEASE_NOTES" + - "SPONSORS.TXT" + - "TODO" + pull_request: + env: CI: true + jobs: - tests: - runs-on: ${{ matrix.os }} - name: Python ${{ matrix.python-version }} on ${{ matrix.os }} + Linux: + runs-on: ${{ matrix.config.os }} + name: ${{ matrix.config.name }} strategy: fail-fast: false matrix: - os: [ubuntu-18.04, ubuntu-20.04] - python-version: [2.7, 3.6, 3.9] - exclude: - - os: ubuntu-18.04 - python-version: 3.9 + config: + - { + name: 'ubuntu-18.04 x64 cmake', + os: ubuntu-18.04, + arch: x64, + python-arch: x64, + python-version: '2.7', + } + - { + name: 'ubuntu-18.04 x64 cmake', + os: ubuntu-18.04, + arch: x64, + python-arch: x64, + python-version: '3.6', + } + - { + name: 'ubuntu-20.04 x64 cmake', + os: ubuntu-20.04, + arch: x64, + python-arch: x64, + python-version: '2.7', + } + - { + name: 'ubuntu-20.04 x64 cmake', + os: ubuntu-20.04, + arch: x64, + python-arch: x64, + python-version: '3.9', + } steps: - uses: actions/checkout@v2 @@ -21,7 +64,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v2 with: - python-version: ${{ matrix.python-version }} + python-version: ${{ matrix.config.python-version }} - name: prepare shell: 'script -q -e -c "bash {0}"' @@ -51,4 +94,36 @@ jobs: 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 ..; - \ No newline at end of file + + # Windows: + # runs-on: ${{ matrix.config.os }} + # name: ${{ matrix.config.name }} + # strategy: + # fail-fast: false + # matrix: + # config: + # - { + # name: 'windows x64 MSVC 64bit', + # os: windows-latest, + # arch: x64, + # python-arch: x64, + # python-version: '3.9', + # } + + # steps: + # - uses: actions/checkout@v2 + + # - name: '🛠️ Win MSVC 64 setup' + # if: contains(matrix.config.name, 'MSVC 64') + # uses: microsoft/setup-msbuild@v1 + + # - name: '🚧 Win MSVC 64 build' + # if: contains(matrix.config.name, 'MSVC 64') + # shell: bash + # run: | + # # choco install cmake + # cmake --version + # mkdir build + # cd build + # cmake .. + # cmake --build . --config Release --target install diff --git a/.gitignore b/.gitignore index 9a72f29e..2bb522bc 100644 --- a/.gitignore +++ b/.gitignore @@ -129,3 +129,6 @@ cstool/cstool # android android-ndk-* + +# benchmark/ +benchmark/cs-benchmark* \ No newline at end of file diff --git a/benchmark/Makefile b/benchmark/Makefile new file mode 100644 index 00000000..1c514d58 --- /dev/null +++ b/benchmark/Makefile @@ -0,0 +1,7 @@ +# Modified from https://github.com/athre0z/disas-bench + +all: + cc main.c -O3 -o cs-benchmark -I../include ../build/libcapstone.a + +clean: + rm -f cs-benchmark* *.o \ No newline at end of file diff --git a/benchmark/load_bin.inc b/benchmark/load_bin.inc new file mode 100644 index 00000000..5421bd5c --- /dev/null +++ b/benchmark/load_bin.inc @@ -0,0 +1,60 @@ +// From https://github.com/athre0z/disas-bench + +#include +#include +#include +#include + + +int read_file_data(uint8_t** buf, const char* filename, size_t file_offset, size_t bin_len) +{ + FILE* f = fopen(filename, "rb"); + if (!f) return 0; + + // Seek to code section + if (fseek(f, (long)file_offset, SEEK_SET)) + { + fclose(f); + return 0; + } + + uint8_t* code = malloc(bin_len); + if (!code) + { + fclose(f); + return 0; + } + + if (fread(code, 1, bin_len, f) != bin_len) + { + fclose(f); + free(code); + return 0; + } + + *buf = code; + + return 1; +} + +int read_file(int argc, char *argv[], uint8_t **buf, size_t *bin_len, size_t *loop_count) +{ + if (argc != 5) + { + fputs("Expected args: \n", stderr); + return 0; + } + + *loop_count = (size_t)strtoull(argv[1], NULL, 0); + size_t file_offset = (size_t)strtoull(argv[2], NULL, 0); + *bin_len = (size_t)strtoull(argv[3], NULL, 0); + const char *filename = argv[4]; + + if (!read_file_data(buf, filename, file_offset, *bin_len)) + { + fprintf(stderr, "Couldn't read `%s`\n", filename); + return 0; + } + + return 1; +} \ No newline at end of file diff --git a/benchmark/main.c b/benchmark/main.c new file mode 100644 index 00000000..3ffe01e6 --- /dev/null +++ b/benchmark/main.c @@ -0,0 +1,82 @@ +// Modified from https://github.com/athre0z/disas-bench + +#include "./load_bin.inc" +#include + + +int main(int argc, char* argv[]) +{ + csh handle = 0; + cs_insn *insn = NULL; + int ret = 0; + const uint8_t *code_iter = NULL; + size_t code_len_iter = 0; + uint64_t ip = 0; + size_t num_valid_insns = 0; + size_t num_bad_insn = 0; + size_t round; + + if (cs_open(CS_ARCH_X86, CS_MODE_64, &handle) != CS_ERR_OK) + { + fputs("Unable to create Capstone handle\n", stderr); + ret = 1; + goto leave; + } + + uint8_t *code = NULL; + size_t code_len = 0, loop_count = 0; + if (!read_file(argc, argv, &code, &code_len, &loop_count)) + { + ret = 1; + goto leave; + } + + insn = cs_malloc(handle); + if (!insn) + { + fputs("Failed to allocate memory\n", stderr); + ret = 1; + goto leave; + } + + clock_t start_time = clock(); + for (round = 0; round < loop_count; ++round) + { + code_iter = code; + code_len_iter = code_len; + while (code_len_iter > 0) + { + if (!cs_disasm_iter( + handle, + &code_iter, + &code_len_iter, + &ip, + insn + )) + { + ++code_iter; + --code_len_iter; + ++num_bad_insn; + } + else + { + ++num_valid_insns; + } + } + } + clock_t end_time = clock(); + + printf( + "Disassembled %zu instructions (%zu valid, %zu bad), %.2f ms\n", + num_valid_insns + num_bad_insn, + num_valid_insns, + num_bad_insn, + (double)(end_time - start_time) * 1000.0 / CLOCKS_PER_SEC + ); + +leave: + if (insn) cs_free(insn, 1); + if (handle) cs_close(&handle); + if (code) free(code); + return ret; +} \ No newline at end of file