diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 27fe8104..5eb98ca5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -21,6 +21,10 @@ on: - "true" - "false" +permissions: + contents: read + actions: write + concurrency: group: ${{ github.ref }} cancel-in-progress: true @@ -86,6 +90,11 @@ jobs: - name: Enable Developer Command Prompt uses: ilammy/msvc-dev-cmd@v1.13.0 + - name: Install sccache + uses: mozilla-actions/sccache-action@v0.0.9 + with: + disable_annotations: true + - name: CMake Build run: cmake --preset=release && cmake --build --preset=release -t dump-apiset @@ -255,7 +264,28 @@ jobs: ndk-version: r26d add-to-path: false - - name: Setup Environment Variables + - name: Setup sccache environment + shell: bash + run: | + WORKSPACE_PATH="${{github.workspace}}" + WORKSPACE_PATH="${WORKSPACE_PATH//\\//}" + echo "SCCACHE_DIR=${WORKSPACE_PATH}/sccache" >> $GITHUB_ENV + echo "SCCACHE_CACHE_SIZE=200M" >> $GITHUB_ENV + + - name: Recover sccache + uses: actions/cache/restore@v3 + with: + path: ${{env.SCCACHE_DIR}} + key: sccache-${{github.job}}-${{matrix.platform}}-${{matrix.configuration}}-${{ github.head_ref || github.ref_name }}- + restore-keys: | + sccache-${{github.job}}-${{matrix.platform}}-${{matrix.configuration}}-${{ github.event.repository.default_branch }}- + + - name: Install sccache + uses: mozilla-actions/sccache-action@v0.0.9 + with: + disable_annotations: true + + - name: Setup Android Environment Variables shell: bash if: ${{ startsWith(matrix.platform, 'Android') }} run: | @@ -280,6 +310,15 @@ jobs: path: "build/${{matrix.preset}}/**/CTestTestfile.cmake" retention-days: 1 + - name: Print sccache stats + run: sccache -s && sccache --stop-server + + - name: Save sccache + uses: actions/cache/save@v3 + with: + path: ${{env.SCCACHE_DIR}} + key: sccache-${{github.job}}-${{matrix.platform}}-${{matrix.configuration}}-${{ github.head_ref || github.ref_name }}-${{github.run_id}}-${{github.run_attempt}} + test: name: Test runs-on: ${{ matrix.runner }} diff --git a/.gitmodules b/.gitmodules index ea708bb8..385ca7f2 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,17 +10,22 @@ [submodule "deps/googletest"] path = deps/googletest url = https://github.com/google/googletest.git + shallow = true [submodule "deps/zlib"] path = deps/zlib url = https://github.com/madler/zlib.git branch = develop ignore = dirty + shallow = true [submodule "deps/gtest-parallel"] path = deps/gtest-parallel url = https://github.com/google/gtest-parallel.git + shallow = true [submodule "deps/flatbuffers"] path = deps/flatbuffers url = https://github.com/google/flatbuffers.git + shallow = true [submodule "deps/base64"] path = deps/base64 url = https://github.com/tobiaslocker/base64.git + shallow = true diff --git a/CMakeLists.txt b/CMakeLists.txt index ec3e355d..3ddb0b99 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,6 +29,9 @@ endif() # It doesn't support it, even if it thinks it does... set(ENV{ARCHFLAGS} "nope") +########################################## + +include(cmake/sccache.cmake) ########################################## diff --git a/CMakePresets.json b/CMakePresets.json index d7a107f3..5e0e6de9 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -23,7 +23,7 @@ "build" ], "cacheVariables": { - "CMAKE_BUILD_TYPE": "Release" + "CMAKE_BUILD_TYPE": "RelWithDebInfo" } }, { diff --git a/cmake/compiler-env.cmake b/cmake/compiler-env.cmake index c49c832f..9ccd1711 100644 --- a/cmake/compiler-env.cmake +++ b/cmake/compiler-env.cmake @@ -160,10 +160,6 @@ if(MSVC) /INCREMENTAL:NO ) - momo_add_c_and_cxx_release_compile_options( - /Ob2 - ) - add_compile_definitions( _CRT_SECURE_NO_WARNINGS _CRT_NONSTDC_NO_WARNINGS @@ -214,24 +210,6 @@ endif() ########################################## -set(OPT_DEBUG "-O0 -g") -set(OPT_RELEASE "-O3 -g") - -if(MSVC) - set(OPT_DEBUG "/Od /Ob0 /Zi") - set(OPT_RELEASE "/O2 /Ob2 /Zi") - - add_link_options(/DEBUG) -endif() - -set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${OPT_DEBUG}") -set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${OPT_DEBUG}") - -set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${OPT_RELEASE}") -set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${OPT_RELEASE}") - -########################################## - if(CMAKE_GENERATOR MATCHES "Visual Studio") momo_add_c_and_cxx_compile_options(/MP) endif() diff --git a/cmake/sccache.cmake b/cmake/sccache.cmake new file mode 100644 index 00000000..732330d5 --- /dev/null +++ b/cmake/sccache.cmake @@ -0,0 +1,14 @@ +include_guard() + +find_program(SCCACHE sccache) + +if (SCCACHE) + file(TO_CMAKE_PATH "${SCCACHE}" SCCACHE) + set(CMAKE_C_COMPILER_LAUNCHER ${SCCACHE}) + set(CMAKE_CXX_COMPILER_LAUNCHER ${SCCACHE}) + set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT Embedded) + + if(POLICY CMP0141) + cmake_policy(SET CMP0141 NEW) + endif() +endif() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f6138c49..6c71b182 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,6 +3,7 @@ add_subdirectory(emulator) add_subdirectory(gdb-stub) add_subdirectory(windows-emulator) add_subdirectory(windows-gdb-stub) +add_subdirectory(backend-selection) momo_add_subdirectory_and_get_targets("backends" BACKEND_TARGETS) momo_targets_set_folder("backends" ${BACKEND_TARGETS}) diff --git a/src/analyzer/CMakeLists.txt b/src/analyzer/CMakeLists.txt index 036e614e..a0ed8607 100644 --- a/src/analyzer/CMakeLists.txt +++ b/src/analyzer/CMakeLists.txt @@ -19,6 +19,7 @@ target_link_libraries(analyzer PRIVATE debugger windows-emulator windows-gdb-stub + backend-selection ) set_property(GLOBAL PROPERTY VS_STARTUP_PROJECT analyzer) diff --git a/src/analyzer/main.cpp b/src/analyzer/main.cpp index 363fb450..a9690f93 100644 --- a/src/analyzer/main.cpp +++ b/src/analyzer/main.cpp @@ -1,6 +1,7 @@ #include "std_include.hpp" #include +#include #include #include "object_watching.hpp" @@ -217,7 +218,7 @@ namespace std::unique_ptr create_empty_emulator(const analysis_options& options) { const auto settings = create_emulator_settings(options); - return std::make_unique(settings); + return std::make_unique(create_x86_64_emulator(), settings); } std::unique_ptr create_application_emulator(const analysis_options& options, @@ -234,7 +235,7 @@ namespace }; const auto settings = create_emulator_settings(options); - return std::make_unique(std::move(app_settings), settings); + return std::make_unique(create_x86_64_emulator(), std::move(app_settings), settings); } std::unique_ptr setup_emulator(const analysis_options& options, diff --git a/src/backend-selection/CMakeLists.txt b/src/backend-selection/CMakeLists.txt new file mode 100644 index 00000000..3a2956d2 --- /dev/null +++ b/src/backend-selection/CMakeLists.txt @@ -0,0 +1,23 @@ +file(GLOB_RECURSE SRC_FILES CONFIGURE_DEPENDS + *.cpp + *.hpp + *.rc +) + +list(SORT SRC_FILES) + +add_library(backend-selection ${SRC_FILES}) + +momo_assign_source_group(${SRC_FILES}) + +target_include_directories(backend-selection INTERFACE "${CMAKE_CURRENT_LIST_DIR}") + +target_link_libraries(backend-selection PRIVATE + unicorn-emulator +) + +if (MOMO_ENABLE_RUST_CODE) + target_link_libraries(backend-selection PRIVATE + icicle-emulator + ) +endif() \ No newline at end of file diff --git a/src/backend-selection/backend_selection.cpp b/src/backend-selection/backend_selection.cpp new file mode 100644 index 00000000..77b252d7 --- /dev/null +++ b/src/backend-selection/backend_selection.cpp @@ -0,0 +1,23 @@ +#include "backend_selection.hpp" + +#include +#include + +#if MOMO_ENABLE_RUST_CODE +#include +#endif + +using namespace std::literals; + +std::unique_ptr create_x86_64_emulator() +{ +#if MOMO_ENABLE_RUST_CODE + const auto* env = getenv("EMULATOR_ICICLE"); + if (env && (env == "1"sv || env == "true"sv)) + { + return icicle::create_x86_64_emulator(); + } +#endif + + return unicorn::create_x86_64_emulator(); +} diff --git a/src/backend-selection/backend_selection.hpp b/src/backend-selection/backend_selection.hpp new file mode 100644 index 00000000..607e54a9 --- /dev/null +++ b/src/backend-selection/backend_selection.hpp @@ -0,0 +1,6 @@ +#pragma once + +#include +#include + +std::unique_ptr create_x86_64_emulator(); diff --git a/src/backends/icicle-emulator/icicle-bridge/CMakeLists.txt b/src/backends/icicle-emulator/icicle-bridge/CMakeLists.txt index d64c0d21..8399c7bc 100644 --- a/src/backends/icicle-emulator/icicle-bridge/CMakeLists.txt +++ b/src/backends/icicle-emulator/icicle-bridge/CMakeLists.txt @@ -35,13 +35,18 @@ endif() set(ICICLE_RUST_LIB ${ICICLE_ARTIFACT_DIR}/${ICICLE_RUST_LIBNAME}) +set(SCCACHE_ENV "MOMO_DUMMY_ENV=1") +if (SCCACHE) + set(SCCACHE_ENV "RUSTC_WRAPPER=${SCCACHE}") +endif() + ExternalProject_Add( icicle-rust-project PREFIX ${CMAKE_CURRENT_BINARY_DIR} SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR} BINARY_DIR ${CMAKE_CURRENT_LIST_DIR} CONFIGURE_COMMAND "" - BUILD_COMMAND ${CMAKE_COMMAND} -E env "CARGO_TARGET_DIR=${ICICLE_BUILD_DIR}" cargo build ${CARGO_OPTIONS} --lib --profile $,dev,release> + BUILD_COMMAND ${CMAKE_COMMAND} -E env "CARGO_TARGET_DIR=${ICICLE_BUILD_DIR}" "${SCCACHE_ENV}" -- cargo build ${CARGO_OPTIONS} --lib --profile $,dev,release> INSTALL_COMMAND "" USES_TERMINAL_CONFIGURE 1 USES_TERMINAL_BUILD 1 diff --git a/src/fuzzer/CMakeLists.txt b/src/fuzzer/CMakeLists.txt index 2ffc31a0..6fb50eff 100644 --- a/src/fuzzer/CMakeLists.txt +++ b/src/fuzzer/CMakeLists.txt @@ -19,4 +19,10 @@ target_link_libraries(fuzzer PRIVATE windows-emulator ) +if (MOMO_ENABLE_RUST_CODE) + target_link_libraries(fuzzer PRIVATE + icicle-emulator + ) +endif() + momo_strip_target(fuzzer) diff --git a/src/fuzzer/main.cpp b/src/fuzzer/main.cpp index 5f9c047a..2bb4cb5c 100644 --- a/src/fuzzer/main.cpp +++ b/src/fuzzer/main.cpp @@ -3,7 +3,11 @@ #include #include -#include "utils/finally.hpp" +#include + +#if MOMO_ENABLE_RUST_CODE +#include +#endif #ifdef _MSC_VER #pragma warning(disable : 4702) @@ -13,6 +17,15 @@ bool use_gdb = false; namespace { + std::unique_ptr create_emulator_backend() + { +#if MOMO_ENABLE_RUST_CODE + return icicle::create_x86_64_emulator(); +#else + throw std::runtime_error("Fuzzer requires rust code to be enabled"); +#endif + } + void run_emulation(windows_emulator& win_emu) { try @@ -47,7 +60,7 @@ namespace struct fuzzer_executer : fuzzer::executer { - windows_emulator emu{}; // TODO: Fix root directory + windows_emulator emu{create_emulator_backend()}; std::span emulator_data{}; std::unordered_set visited_blocks{}; const std::function* handler{nullptr}; @@ -148,7 +161,7 @@ namespace .application = application, }; - windows_emulator win_emu{std::move(settings)}; + windows_emulator win_emu{create_emulator_backend(), std::move(settings)}; forward_emulator(win_emu); run_fuzzer(win_emu); diff --git a/src/windows-emulator-test/CMakeLists.txt b/src/windows-emulator-test/CMakeLists.txt index 8bea4b26..e00f862f 100644 --- a/src/windows-emulator-test/CMakeLists.txt +++ b/src/windows-emulator-test/CMakeLists.txt @@ -14,6 +14,7 @@ target_link_libraries(windows-emulator-test PRIVATE gtest gtest_main windows-emulator + backend-selection ) if(WIN32 AND CMAKE_SIZEOF_VOID_P EQUAL 8) diff --git a/src/windows-emulator-test/emulation_test_utils.hpp b/src/windows-emulator-test/emulation_test_utils.hpp index d972de71..8aa201ab 100644 --- a/src/windows-emulator-test/emulation_test_utils.hpp +++ b/src/windows-emulator-test/emulation_test_utils.hpp @@ -3,6 +3,7 @@ #include #include #include +#include #include @@ -72,6 +73,7 @@ namespace test std::filesystem::temp_directory_path() / ("emulator-test-file-" + std::to_string(getpid()) + ".txt"); return windows_emulator{ + create_x86_64_emulator(), settings, std::move(callbacks), emulator_interfaces{ @@ -97,6 +99,7 @@ namespace test std::filesystem::temp_directory_path() / ("emulator-test-file-" + std::to_string(getpid()) + ".txt"); return windows_emulator{ + create_x86_64_emulator(), get_sample_app_settings(config), settings, std::move(callbacks), diff --git a/src/windows-emulator/CMakeLists.txt b/src/windows-emulator/CMakeLists.txt index 16167e84..93a25074 100644 --- a/src/windows-emulator/CMakeLists.txt +++ b/src/windows-emulator/CMakeLists.txt @@ -14,16 +14,6 @@ if(NOT MOMO_ENABLE_CLANG_TIDY) target_precompile_headers(windows-emulator PRIVATE std_include.hpp) endif() -target_link_libraries(windows-emulator PRIVATE - unicorn-emulator -) - -if (MOMO_ENABLE_RUST_CODE) -target_link_libraries(windows-emulator PRIVATE - icicle-emulator -) -endif() - target_link_libraries(windows-emulator PUBLIC emulator) target_include_directories(windows-emulator INTERFACE "${CMAKE_CURRENT_LIST_DIR}") diff --git a/src/windows-emulator/windows_emulator.cpp b/src/windows-emulator/windows_emulator.cpp index 76e6cc79..1b518afd 100644 --- a/src/windows-emulator/windows_emulator.cpp +++ b/src/windows-emulator/windows_emulator.cpp @@ -3,12 +3,6 @@ #include "cpu_context.hpp" -#include - -#if MOMO_ENABLE_RUST_CODE -#include -#endif - #include #include #include @@ -268,30 +262,17 @@ namespace } } -std::unique_ptr create_default_x86_64_emulator() -{ -#if MOMO_ENABLE_RUST_CODE - const auto* env = getenv("EMULATOR_ICICLE"); - if (env && (env == "1"sv || env == "true"sv)) - { - return icicle::create_x86_64_emulator(); - } -#endif - - return unicorn::create_x86_64_emulator(); -} - -windows_emulator::windows_emulator(application_settings app_settings, const emulator_settings& settings, - emulator_callbacks callbacks, emulator_interfaces interfaces, - std::unique_ptr emu) - : windows_emulator(settings, std::move(callbacks), std::move(interfaces), std::move(emu)) +windows_emulator::windows_emulator(std::unique_ptr emu, application_settings app_settings, + const emulator_settings& settings, emulator_callbacks callbacks, + emulator_interfaces interfaces) + : windows_emulator(std::move(emu), settings, std::move(callbacks), std::move(interfaces)) { fixup_application_settings(app_settings); this->setup_process(app_settings); } -windows_emulator::windows_emulator(const emulator_settings& settings, emulator_callbacks callbacks, - emulator_interfaces interfaces, std::unique_ptr emu) +windows_emulator::windows_emulator(std::unique_ptr emu, const emulator_settings& settings, + emulator_callbacks callbacks, emulator_interfaces interfaces) : emu_(std::move(emu)), clock_(get_clock(interfaces, this->executed_instructions_, settings.use_relative_time)), socket_factory_(get_socket_factory(interfaces)), diff --git a/src/windows-emulator/windows_emulator.hpp b/src/windows-emulator/windows_emulator.hpp index 520e1c80..ac0f20c6 100644 --- a/src/windows-emulator/windows_emulator.hpp +++ b/src/windows-emulator/windows_emulator.hpp @@ -13,8 +13,6 @@ #include "module/module_manager.hpp" #include "network/socket_factory.hpp" -std::unique_ptr create_default_x86_64_emulator(); - struct emulator_callbacks : module_manager::callbacks, process_context::callbacks { utils::optional_function emu = create_default_x86_64_emulator()); - windows_emulator(application_settings app_settings, const emulator_settings& settings = {}, - emulator_callbacks callbacks = {}, emulator_interfaces interfaces = {}, - std::unique_ptr emu = create_default_x86_64_emulator()); + windows_emulator(std::unique_ptr emu, const emulator_settings& settings = {}, + emulator_callbacks callbacks = {}, emulator_interfaces interfaces = {}); + windows_emulator(std::unique_ptr emu, application_settings app_settings, + const emulator_settings& settings = {}, emulator_callbacks callbacks = {}, + emulator_interfaces interfaces = {}); windows_emulator(windows_emulator&&) = delete; windows_emulator(const windows_emulator&) = delete;