From 2345d1a56e591241d7f06dfcbd33272e7cf98691 Mon Sep 17 00:00:00 2001 From: elbiazo Date: Mon, 16 Jan 2023 19:59:42 -0800 Subject: [PATCH 1/3] working on initial build --- Cargo.toml | 2 + build.bat | 4 -- build.rs | 110 +++++++++++++++++++++++++++++++++-------------------- 3 files changed, 70 insertions(+), 46 deletions(-) delete mode 100644 build.bat diff --git a/Cargo.toml b/Cargo.toml index 221afc8..2a61daf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,3 +15,5 @@ cxx = { version = "1.0", default-features = false, features = ["alloc"] } [build-dependencies] cmake = "0.1" +git2 = "0.16.0" +which = "4.3.0" diff --git a/build.bat b/build.bat deleted file mode 100644 index 798d0e8..0000000 --- a/build.bat +++ /dev/null @@ -1,4 +0,0 @@ -git clone git@github.com:elbiazo/TinyInst.git -pushd TinyInst -git submodule update --init --recursive -popd diff --git a/build.rs b/build.rs index e94b1c8..2f37d4b 100644 --- a/build.rs +++ b/build.rs @@ -1,10 +1,21 @@ use std::{ env, + path::Path, process::{exit, Command}, }; use cmake::Config; +use git2::Repository; +use which::which; +// TODO: make a way to use official tinyinst +const TINYINST_URL: &str = "https://github.com/elbiazo/TinyInst.git"; + +fn build_dep_check(tools: &[&str]) { + for tool in tools { + which(tool).unwrap_or_else(|_| panic!("Build tool {tool} not found")); + } +} fn main() { // First we generate .cc and .h files from ffi.rs if !cfg!(windows) { @@ -12,89 +23,104 @@ fn main() { exit(0); } - let cwd = env::current_dir().unwrap().to_string_lossy().to_string(); - let tinyinst = format!("{}/TinyInst", &cwd); + build_dep_check(&["git", "python", "cxxbridge"]); + + let out_dir = env::var_os("OUT_DIR").unwrap(); + let out_dir_path = Path::new(&out_dir); + let tinyinst_path = out_dir_path.join("Tinyinst"); + // Clone println!("cargo:warning=Pulling TinyInst from github"); + let tinyinst_repo = match Repository::clone(TINYINST_URL, &tinyinst_path) { + Ok(repo) => repo, + _ => Repository::open(&tinyinst_path).expect("Failed to open repository"), + }; + let mut submodules = tinyinst_repo.submodules().unwrap(); + + // do git submodule --init --recursive on Tinyinst + for submodule in &mut submodules { + submodule.update(true, None).unwrap(); + } println!("cargo:warning=Generating Bridge files."); - // Get tinyinst from git - Command::new("cmd") - .arg("/C") - .arg(format!("{cwd}/build.bat")) - .status() - .unwrap(); + copy_tinyinst_files(&tinyinst_path); + let dst = Config::new(&tinyinst_path) + .generator("Visual Studio 17 2022") // make this configurable from env variable + .build_target("tinyinst") + .profile("Release") // without this, it goes into RelWithDbInfo folder?? + .build(); + + println!("cargo:warning={}", dst.display()); + println!("cargo:rustc-link-search={}\\build\\Release", dst.display()); // debug build? + println!( + "cargo:rustc-link-search={}\\build\\third_party\\obj\\wkit\\lib", + dst.display() + ); //xed + + println!("cargo:rustc-link-lib=static=tinyinst"); + println!("cargo:rustc-link-lib=static=xed"); + println!("cargo:rustc-link-lib=dylib=dbghelp"); + + println!("cargo:rerun-if-changed=src/"); + println!("cargo:rerun-if-changed=src/tinyinst.rs"); + println!("cargo:rerun-if-changed=build.rs"); + println!("cargo:rerun-if-changed=Tinyinst/litecov.cpp"); +} + +fn copy_tinyinst_files(tinyinst_path: &Path) { // source Command::new("cxxbridge") .args(["src/tinyinst.rs", "-o"]) - .arg(format!("{tinyinst}/bridge.cc")) + .arg(format!("{}/bridge.cc", tinyinst_path.to_string_lossy())) .status() .unwrap(); // header Command::new("cxxbridge") .args(["src/tinyinst.rs", "--header", "-o"]) - .arg(format!("{tinyinst}/bridge.h")) + .arg(format!("{}/bridge.h", tinyinst_path.to_string_lossy())) .status() .unwrap(); // cxx Command::new("cxxbridge") .args(["--header", "-o"]) - .arg(format!("{tinyinst}/cxx.h")) + .arg(format!("{}/cxx.h", tinyinst_path.to_string_lossy())) .status() .unwrap(); // shim - std::fs::copy("./src/shim.cc", "./Tinyinst/shim.cc").unwrap(); - std::fs::copy("./src/shim.h", "./Tinyinst/shim.h").unwrap(); + std::fs::copy("./src/shim.cc", tinyinst_path.join("shim.cc")).unwrap(); + std::fs::copy("./src/shim.h", tinyinst_path.join("shim.h")).unwrap(); // runresult - std::fs::copy("./src/runresult.h", "./Tinyinst/runresult.h").unwrap(); + std::fs::copy("./src/runresult.h", tinyinst_path.join("runresult.h")).unwrap(); // instrumentation std::fs::copy( "./src/instrumentation.cpp", - "./Tinyinst/instrumentation.cpp", + tinyinst_path.join("instrumentation.cpp"), + ) + .unwrap(); + std::fs::copy( + "./src/instrumentation.h", + tinyinst_path.join("instrumentation.h"), ) .unwrap(); - std::fs::copy("./src/instrumentation.h", "./Tinyinst/instrumentation.h").unwrap(); // tinyinstinstrumentation std::fs::copy( "./src/tinyinstinstrumentation.cpp", - "./Tinyinst/tinyinstinstrumentation.cpp", + tinyinst_path.join("tinyinstinstrumentation.cpp"), ) .unwrap(); std::fs::copy( "./src/tinyinstinstrumentation.h", - "./Tinyinst/tinyinstinstrumentation.h", + tinyinst_path.join("tinyinstinstrumentation.h"), ) .unwrap(); // aflcov - std::fs::copy("./src/aflcov.cpp", "./Tinyinst/aflcov.cpp").unwrap(); - std::fs::copy("./src/aflcov.h", "./Tinyinst/aflcov.h").unwrap(); - - let dst = Config::new("TinyInst") - .generator("Visual Studio 17 2022") // make this configurable from env variable - .build_target("tinyinst") - .profile("Release") // without this, it goes into RelWithDbInfo folder?? - .build(); - - println!("cargo:warning={}", dst.display()); - println!("cargo:rustc-link-search={}\\build\\Release", dst.display()); // debug build? - println!( - "cargo:rustc-link-search={}\\build\\third_party\\obj\\wkit\\lib", - dst.display() - ); //xed - - println!("cargo:rustc-link-lib=static=tinyinst"); - println!("cargo:rustc-link-lib=static=xed"); - println!("cargo:rustc-link-lib=dylib=dbghelp"); - - println!("cargo:rerun-if-changed=src/"); - println!("cargo:rerun-if-changed=src/tinyinst.rs"); - println!("cargo:rerun-if-changed=build.rs"); - println!("cargo:rerun-if-changed=Tinyinst/litecov.cpp"); + std::fs::copy("./src/aflcov.cpp", tinyinst_path.join("aflcov.cpp")).unwrap(); + std::fs::copy("./src/aflcov.h", tinyinst_path.join("aflcov.h")).unwrap(); } From e9d57ac4358d3ef697a61932d884c42f285440a3 Mon Sep 17 00:00:00 2001 From: elbiazo Date: Mon, 16 Jan 2023 20:33:43 -0800 Subject: [PATCH 2/3] removing junk --- build_test.bat | 9 -- debug.bat | 4 - run.bat | 1 - test/tinyinst-coverage.cpp | 212 ------------------------------------- 4 files changed, 226 deletions(-) delete mode 100644 build_test.bat delete mode 100644 debug.bat delete mode 100644 run.bat delete mode 100644 test/tinyinst-coverage.cpp diff --git a/build_test.bat b/build_test.bat deleted file mode 100644 index bff6020..0000000 --- a/build_test.bat +++ /dev/null @@ -1,9 +0,0 @@ -opy src\* .\TinyInst\ - -:: this will give you new litecov.exe to test on with Vector Coverage instead of list coverage -copy test\tinyinst-coverage.cpp TinyInst\tinyinst-coverage.cpp - -cxxbridge ./src/tinyinst.rs -o ./TinyInst/bridge.cc -cxxbridge ./src/tinyinst.rs --header -o ./TinyInst/bridge.h -cxxbridge --header -o ./TinyInst/cxx.h -cmake --build build \ No newline at end of file diff --git a/debug.bat b/debug.bat deleted file mode 100644 index f4689a1..0000000 --- a/debug.bat +++ /dev/null @@ -1,4 +0,0 @@ -cp -r .\src\*.c* .\TinyInst\ -cp -r .\src\*.h .\TinyInst\ -rm .\TinyInst\shim.* -cmake --build build \ No newline at end of file diff --git a/run.bat b/run.bat deleted file mode 100644 index 318ca16..0000000 --- a/run.bat +++ /dev/null @@ -1 +0,0 @@ -.\build\Debug\litecov.exe -instrument_module test.exe -instrument_module a.exe -- .\test\test.exe .\test\ok_input.txt \ No newline at end of file diff --git a/test/tinyinst-coverage.cpp b/test/tinyinst-coverage.cpp deleted file mode 100644 index fefed8e..0000000 --- a/test/tinyinst-coverage.cpp +++ /dev/null @@ -1,212 +0,0 @@ -/* -Copyright 2020 Google LLC. Modified by biazo - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -https ://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#define _CRT_SECURE_NO_WARNINGS - -#include -#include -#include - -#include "common.h" -// #include "litecov.h" -#include "aflcov.h" -#include -#include "cxx.h" - -uint8_t *trace_bits; - -AFLCov *instrumentation; -bool persist; -int num_iterations; -int cur_iteration; - -// run a single iteration over the target process -// whether it's the whole process or target method -// and regardless if the target is persistent or not -// (should know what to do in pretty much all cases) -void RunTarget(int argc, char **argv, unsigned int pid, uint32_t timeout) -{ - DebuggerStatus status; - - if (instrumentation->IsTargetFunctionDefined()) - { - if (cur_iteration == num_iterations) - { - instrumentation->Kill(); - cur_iteration = 0; - } - } - - // else clear only when the target function is reached - if (!instrumentation->IsTargetFunctionDefined()) - { - instrumentation->ClearCoverage(); - } - - if (instrumentation->IsTargetAlive() && persist) - { - status = instrumentation->Continue(timeout); - } - else - { - instrumentation->Kill(); - cur_iteration = 0; - if (argc) - { - status = instrumentation->Run(argc, argv, timeout); - } - else - { - status = instrumentation->Attach(pid, timeout); - } - } - - // if target function is defined, - // we should wait until it is hit - if (instrumentation->IsTargetFunctionDefined()) - { - if ((status != DEBUGGER_TARGET_START) && argc) - { - // try again with a clean process - WARN("Target function not reached, retrying with a clean process\n"); - instrumentation->Kill(); - cur_iteration = 0; - status = instrumentation->Run(argc, argv, timeout); - } - - if (status != DEBUGGER_TARGET_START) - { - switch (status) - { - case DEBUGGER_CRASHED: - FATAL("Process crashed before reaching the target method\n"); - break; - case DEBUGGER_HANGED: - FATAL("Process hanged before reaching the target method\n"); - break; - case DEBUGGER_PROCESS_EXIT: - FATAL("Process exited before reaching the target method\n"); - break; - default: - FATAL("An unknown problem occured before reaching the target method\n"); - break; - } - } - - instrumentation->ClearCoverage(); - - status = instrumentation->Continue(timeout); - } - - switch (status) - { - case DEBUGGER_CRASHED: - printf("Process crashed\n"); - instrumentation->Kill(); - break; - case DEBUGGER_HANGED: - printf("Process hanged\n"); - instrumentation->Kill(); - break; - case DEBUGGER_PROCESS_EXIT: - if (instrumentation->IsTargetFunctionDefined()) - { - printf("Process exit during target function\n"); - } - else - { - printf("Process finished normally\n"); - } - break; - case DEBUGGER_TARGET_END: - if (instrumentation->IsTargetFunctionDefined()) - { - printf("Target function returned normally\n"); - cur_iteration++; - } - else - { - FATAL("Unexpected status received from the debugger\n"); - } - break; - default: - FATAL("Unexpected status received from the debugger\n"); - break; - } -} - -int main(int argc, char **argv) -{ - printf("AFLCov TinyInst Coverage Tool v2.0\n"); - instrumentation = new AFLCov(); - instrumentation->Init(argc, argv); - - int target_opt_ind = 0; - for (int i = 1; i < argc; i++) - { - if (strcmp(argv[i], "--") == 0) - { - target_opt_ind = i + 1; - break; - } - } - - int target_argc = (target_opt_ind) ? argc - target_opt_ind : 0; - char **target_argv = (target_opt_ind) ? argv + target_opt_ind : NULL; - - unsigned int pid = GetIntOption("-pid", argc, argv, 0); - persist = GetBinaryOption("-persist", argc, argv, false); - num_iterations = GetIntOption("-iterations", argc, argv, 1); - char *outfile = GetOption("-coverage_file", argc, argv); - - if (!target_argc && !pid) - { - printf("Usage:\n"); - printf("%s -- \n", argv[0]); - printf("Or:\n"); - printf("%s -pid \n", argv[0]); - return 0; - } - - Coverage coverage, newcoverage; - rust::Vec coverage_vector; - - for (int i = 0; i < num_iterations; i++) - { - RunTarget(target_argc, target_argv, pid, 0xFFFFFFFF); - - Coverage newcoverage; - - instrumentation->GetCoverage(coverage_vector, true); - printf("Coverage: %zd\n", coverage_vector.size()); - - // for (auto iter = newcoverage.begin(); iter != newcoverage.end(); iter++) - // { - // printf("Found %zd new offsets in %s\n", iter->offsets.size(), iter->module_name.c_str()); - // } - - // instrumentation->IgnoreCoverage(newcoverage); - - // MergeCoverage(coverage, newcoverage); - } - - if (outfile) - WriteCoverage(coverage, outfile); - - instrumentation->Kill(); - - return 0; -} From 52df739020369f8d318c98eba4abdb03fc0805e8 Mon Sep 17 00:00:00 2001 From: elbiazo Date: Wed, 18 Jan 2023 21:47:25 -0800 Subject: [PATCH 3/3] adding custom qemu and revision --- build.rs | 115 +++++++++++++++++++++++++--------- src/CMakeLists.txt | 153 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 240 insertions(+), 28 deletions(-) create mode 100644 src/CMakeLists.txt diff --git a/build.rs b/build.rs index 2f37d4b..0c4d735 100644 --- a/build.rs +++ b/build.rs @@ -1,15 +1,16 @@ use std::{ - env, + env, fs, path::Path, process::{exit, Command}, }; use cmake::Config; -use git2::Repository; +use git2::{Oid, Repository}; use which::which; -// TODO: make a way to use official tinyinst -const TINYINST_URL: &str = "https://github.com/elbiazo/TinyInst.git"; +const TINYINST_URL: &str = "https://github.com/googleprojectzero/TinyInst.git"; +const TINYINST_DIRNAME: &str = "Tinyinst"; +const TINYINST_REVISION: &str = "cfb9b15a53e5e6489f2f72c77e804fb0a7af94b5"; fn build_dep_check(tools: &[&str]) { for tool in tools { @@ -25,38 +26,93 @@ fn main() { build_dep_check(&["git", "python", "cxxbridge"]); + let custum_tinyinst_dir = + env::var_os("CUSTOM_TINYINST_DIR").map(|x| x.to_string_lossy().to_string()); + let custum_tinyinst_no_build = env::var("CUSTOM_TINYINST_NO_BUILD").is_ok(); + + println!("cargo:rerun-if-env-changed=CUSTOM_TINYINST_DIR"); + println!("cargo:rerun-if-env-changed=CUSTOM_TINYINST_NO_BUILD"); + let out_dir = env::var_os("OUT_DIR").unwrap(); let out_dir_path = Path::new(&out_dir); - let tinyinst_path = out_dir_path.join("Tinyinst"); - // Clone - println!("cargo:warning=Pulling TinyInst from github"); - let tinyinst_repo = match Repository::clone(TINYINST_URL, &tinyinst_path) { - Ok(repo) => repo, - _ => Repository::open(&tinyinst_path).expect("Failed to open repository"), + let mut target_dir = out_dir_path.to_path_buf(); + target_dir.pop(); + target_dir.pop(); + target_dir.pop(); + + let tinyinst_path = if let Some(tinyinst_dir) = custum_tinyinst_dir.as_ref() { + Path::new(&tinyinst_dir).to_path_buf() + } else { + let tinyinst_path = out_dir_path.join(TINYINST_DIRNAME); + let tinyinst_rev = target_dir.join("TINYINST_REVISION"); + // if revision exists and its different, remove Tinyinst dir + if tinyinst_rev.exists() + && fs::read_to_string(&tinyinst_rev).expect("Failed to read TINYINST_REVISION") + != TINYINST_REVISION + { + println!("cargo:warning=Removing Tinyinst dir. Revision changed"); + let _ = fs::remove_dir_all(&tinyinst_path); + } + + // Check if directory doesn't exist, clone + if !tinyinst_path.is_dir() { + println!("cargo:warning=Pulling TinyInst from github"); + let tinyinst_repo = match Repository::clone(TINYINST_URL, &tinyinst_path) { + Ok(repo) => repo, + _ => Repository::open(&tinyinst_path).expect("Failed to open repository"), + }; + + // checkout correct commit + let oid = Oid::from_str(TINYINST_REVISION).unwrap(); + let commit = tinyinst_repo.find_commit(oid).unwrap(); + + let _ = tinyinst_repo.branch(TINYINST_REVISION, &commit, false); + let obj = tinyinst_repo + .revparse_single(&("refs/heads/".to_owned() + TINYINST_REVISION)) + .unwrap(); + + tinyinst_repo.checkout_tree(&obj, None).unwrap(); + + tinyinst_repo + .set_head(&("refs/heads/".to_owned() + TINYINST_REVISION)) + .unwrap(); + + let mut submodules = tinyinst_repo.submodules().unwrap(); + + // do git submodule --init --recursive on Tinyinst + for submodule in &mut submodules { + submodule.update(true, None).unwrap(); + } + + // write the revision to target dir + fs::write(&tinyinst_rev, TINYINST_REVISION).unwrap(); + } + tinyinst_path }; - let mut submodules = tinyinst_repo.submodules().unwrap(); - // do git submodule --init --recursive on Tinyinst - for submodule in &mut submodules { - submodule.update(true, None).unwrap(); + if !custum_tinyinst_no_build { + println!( + "cargo:warning=Generating Bridge files. and building for {}", + &tinyinst_path.to_string_lossy() + ); + copy_tinyinst_files(&tinyinst_path); + + let _ = Config::new(&tinyinst_path) + .generator("Visual Studio 17 2022") // make this configurable from env variable + .build_target("tinyinst") + .profile("Release") // without this, it goes into RelWithDbInfo folder?? + .out_dir(&tinyinst_path) + .build(); } - println!("cargo:warning=Generating Bridge files."); - copy_tinyinst_files(&tinyinst_path); - - let dst = Config::new(&tinyinst_path) - .generator("Visual Studio 17 2022") // make this configurable from env variable - .build_target("tinyinst") - .profile("Release") // without this, it goes into RelWithDbInfo folder?? - .build(); - - println!("cargo:warning={}", dst.display()); - println!("cargo:rustc-link-search={}\\build\\Release", dst.display()); // debug build? + println!( + "cargo:rustc-link-search={}\\build\\Release", + &tinyinst_path.to_string_lossy() + ); println!( "cargo:rustc-link-search={}\\build\\third_party\\obj\\wkit\\lib", - dst.display() - ); //xed - + &tinyinst_path.to_string_lossy() + ); println!("cargo:rustc-link-lib=static=tinyinst"); println!("cargo:rustc-link-lib=static=xed"); println!("cargo:rustc-link-lib=dylib=dbghelp"); @@ -123,4 +179,7 @@ fn copy_tinyinst_files(tinyinst_path: &Path) { // aflcov std::fs::copy("./src/aflcov.cpp", tinyinst_path.join("aflcov.cpp")).unwrap(); std::fs::copy("./src/aflcov.h", tinyinst_path.join("aflcov.h")).unwrap(); + + // cmake file + std::fs::copy("./src/CMakeLists.txt", tinyinst_path.join("CMakeLists.txt")).unwrap(); } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..cff2b00 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,153 @@ +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +cmake_minimum_required(VERSION "3.1") +set (CMAKE_CXX_STANDARD 17) + +# Determine whether TinyInst should be build for arm64 or x86 +if(APPLE AND NOT DEFINED ${ARCHITECTURE}) + EXECUTE_PROCESS(COMMAND uname -m COMMAND tr -d '\n' OUTPUT_VARIABLE ARCHITECTURE) + if(${ARCHITECTURE} MATCHES arm64) + add_definitions(-DARM64) + endif() +endif() + +add_subdirectory(third_party) + +project("tinyinst") + +include_directories(${CMAKE_CURRENT_BINARY_DIR}/third_party/obj/wkit/include) + +if(${ARCHITECTURE} MATCHES arm64) + set (arch_specific_files + arch/arm64/reg.h + arch/arm64/arm64_helpers.h + arch/arm64/arm64_helpers.cpp + arch/arm64/arm64_assembler.h + arch/arm64/arm64_assembler.cpp + arch/arm64/arm64_litecov.cpp + ) +else() + set (arch_specific_files + arch/x86/reg.h + arch/x86/x86_helpers.h + arch/x86/x86_helpers.cpp + arch/x86/x86_assembler.h + arch/x86/x86_assembler.cpp + arch/x86/x86_litecov.cpp + ) +endif() + +set (cross_platform_files + common.h + common.cpp + assembler.h + instruction.h + tinyinst.h + tinyinst.cpp + coverage.h + coverage.cpp + litecov.h + litecov.cpp + unwind.h + bridge.cc + bridge.h + shim.cc + shim.h + runresult.h + instrumentation.cpp + instrumentation.h + tinyinstinstrumentation.cpp + tinyinstinstrumentation.h + aflcov.cpp + aflcov.h +) + +if (WIN32) + set (platform_specific_files + Windows/debugger.h + Windows/debugger.cpp + Windows/winunwind.cpp + Windows/winunwind.h + ) +elseif (APPLE) + if (${ARCHITECTURE} MATCHES arm64) + set(CMAKE_REQUIRED_LINK_OPTIONS "-arch;arm64") + endif() + + add_custom_command( + OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/macOS/mig_client.c + ${CMAKE_CURRENT_SOURCE_DIR}/macOS/mig_server.c + ${CMAKE_CURRENT_SOURCE_DIR}/macOS/mig_client.h + ${CMAKE_CURRENT_SOURCE_DIR}/macOS/mig_server.h + COMMAND mig -user ${CMAKE_CURRENT_SOURCE_DIR}/macOS/mig_client.c + -server ${CMAKE_CURRENT_SOURCE_DIR}/macOS/mig_server.c + -header ${CMAKE_CURRENT_SOURCE_DIR}/macOS/mig_client.h + -sheader ${CMAKE_CURRENT_SOURCE_DIR}/macOS/mig_server.h + ${CMAKE_CURRENT_SOURCE_DIR}/macOS/mig.defs + COMMENT "Generating Mig files" + ) + + set (platform_specific_files + macOS/debugger.h + macOS/debugger.cpp + macOS/machtarget.h + macOS/machtarget.cpp + macOS/mig_client.h + macOS/mig_client.c + macOS/mig_server.h + macOS/mig_server.c + macOS/unwindmacos.cpp + macOS/unwindmacos.h + macOS/dyld_cache_map_parser.cpp + macOS/dyld_cache_map_parser.h + ) +endif() + +add_library(tinyinst STATIC + ${arch_specific_files} + ${arch_specific_files} + ${platform_specific_files} + ${cross_platform_files} +) + +target_include_directories(tinyinst PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR}/third_party/obj/wkit/include +) + +if((${ARCHITECTURE} MATCHES arm64) AND APPLE) + add_dependencies(tinyinst reil) + target_link_libraries(tinyinst reil) +else() + add_dependencies(tinyinst xed) + if (WIN32) + target_link_libraries(tinyinst + ${CMAKE_CURRENT_BINARY_DIR}/third_party/obj/wkit/lib/xed.lib + Dbghelp.lib + ) + elseif (APPLE) + target_link_libraries(tinyinst + ${CMAKE_CURRENT_BINARY_DIR}/third_party/obj/wkit/lib/libxed.a + ) + endif() +endif() + +project("litecov") + +add_executable(litecov + tinyinst-coverage.cpp +) + +target_link_libraries(litecov tinyinst)