From 28e791a37fff67ffa7551ef5339b58737f1b15b4 Mon Sep 17 00:00:00 2001 From: mio Date: Tue, 18 Jan 2022 19:35:43 +0100 Subject: [PATCH] Add debug tracing feature It's disabled by default, use -DUNICORN_TRACER=on to enable it --- CMakeLists.txt | 86 ++++++++++++++++++++++++++++++++++ bindings/python/setup.py | 5 +- include/uc_priv.h | 26 ++++++++++ qemu/accel/tcg/cpu-exec.c | 3 ++ qemu/accel/tcg/translate-all.c | 2 + uc.c | 28 +++++++++++ 6 files changed, 149 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b94ec1fe..e6d76cf2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,6 +20,8 @@ if (NOT UNICORN_ARCH) set(UNICORN_ARCH "x86 arm aarch64 riscv mips sparc m68k ppc") endif() +option(UNICORN_TRACER "Trace unicorn execution" OFF) + string(TOUPPER ${UNICORN_ARCH} UNICORN_ARCH) string(REPLACE " " ";" UNICORN_ARCH_LIST ${UNICORN_ARCH}) @@ -207,6 +209,9 @@ else() if (UNICORN_FUZZ) set (EXTRA_CFLAGS "${EXTRA_CFLAGS} ${CMAKE_C_FLAGS}") endif() + if(UNICORN_TRACER) + set (EXTRA_CFLAGS "${EXTRA_CFLAGS} -DUNICORN_TRACER") + endif() set(TARGET_LIST "--target-list=") if (UNICORN_HAS_X86) @@ -414,6 +419,11 @@ else() # Log and pow target_link_libraries(x86_64-softmmu m) endif() + +if(UNICORN_TRACER) + target_compile_options(x86_64-softmmu PRIVATE -DUNICORN_TRACER) +endif() + endif() if (UNICORN_HAS_ARM) @@ -452,6 +462,10 @@ else() ) endif() +if(UNICORN_TRACER) + target_compile_options(arm-softmmu PRIVATE -DUNICORN_TRACER) +endif() + add_library(armeb-softmmu ${UNICORN_ARCH_COMMON} @@ -486,6 +500,11 @@ else() -I${CMAKE_CURRENT_SOURCE_DIR}/qemu/target/arm ) endif() + +if(UNICORN_TRACER) + target_compile_options(armeb-softmmu PRIVATE -DUNICORN_TRACER) +endif() + endif() if (UNICORN_HAS_AARCH64) @@ -530,6 +549,10 @@ else() ) endif() +if(UNICORN_TRACER) + target_compile_options(aarch64-softmmu PRIVATE -DUNICORN_TRACER) +endif() + add_library(aarch64eb-softmmu ${UNICORN_ARCH_COMMON} @@ -570,6 +593,11 @@ else() -I${CMAKE_CURRENT_SOURCE_DIR}/qemu/target/arm ) endif() + +if(UNICORN_TRACER) + target_compile_options(aarch64eb-softmmu PRIVATE -DUNICORN_TRACER) +endif() + endif() if (UNICORN_HAS_M68K) @@ -600,6 +628,11 @@ else() -I${CMAKE_CURRENT_SOURCE_DIR}/qemu/target/m68k ) endif() + +if(UNICORN_TRACER) + target_compile_options(m68k-softmmu PRIVATE -DUNICORN_TRACER) +endif() + endif() if (UNICORN_HAS_MIPS) @@ -635,6 +668,10 @@ else() ) endif() +if(UNICORN_TRACER) + target_compile_options(mips-softmmu PRIVATE -DUNICORN_TRACER) +endif() + add_library(mipsel-softmmu ${UNICORN_ARCH_COMMON} @@ -667,6 +704,10 @@ else() ) endif() +if(UNICORN_TRACER) + target_compile_options(mipsel-softmmu PRIVATE -DUNICORN_TRACER) +endif() + add_library(mips64-softmmu ${UNICORN_ARCH_COMMON} @@ -699,6 +740,10 @@ else() ) endif() +if(UNICORN_TRACER) + target_compile_options(mips64-softmmu PRIVATE -DUNICORN_TRACER) +endif() + add_library(mips64el-softmmu ${UNICORN_ARCH_COMMON} @@ -730,6 +775,11 @@ else() -I${CMAKE_CURRENT_SOURCE_DIR}/qemu/target/mips ) endif() + +if(UNICORN_TRACER) + target_compile_options(mips64el-softmmu PRIVATE -DUNICORN_TRACER) +endif() + endif() if (UNICORN_HAS_SPARC) @@ -764,6 +814,10 @@ else() ) endif() +if(UNICORN_TRACER) + target_compile_options(sparc-softmmu PRIVATE -DUNICORN_TRACER) +endif() + add_library(sparc64-softmmu ${UNICORN_ARCH_COMMON} @@ -795,6 +849,11 @@ else() -I${CMAKE_CURRENT_SOURCE_DIR}/qemu/target/sparc ) endif() + +if(UNICORN_TRACER) + target_compile_options(sparc64-softmmu PRIVATE -DUNICORN_TRACER) +endif() + endif() if (UNICORN_HAS_PPC) @@ -842,6 +901,10 @@ else() ) endif() +if(UNICORN_TRACER) + target_compile_options(ppc-softmmu PRIVATE -DUNICORN_TRACER) +endif() + add_library(ppc64-softmmu ${UNICORN_ARCH_COMMON} @@ -889,6 +952,11 @@ else() -I${CMAKE_CURRENT_SOURCE_DIR}/qemu/target/ppc ) endif() + +if(UNICORN_TRACER) + target_compile_options(ppc64-softmmu PRIVATE -DUNICORN_TRACER) +endif() + endif() if (UNICORN_HAS_RISCV) @@ -921,6 +989,10 @@ else() ) endif() +if(UNICORN_TRACER) + target_compile_options(riscv32-softmmu PRIVATE -DUNICORN_TRACER) +endif() + add_library(riscv64-softmmu ${UNICORN_ARCH_COMMON} @@ -949,6 +1021,11 @@ else() -I${CMAKE_CURRENT_SOURCE_DIR}/qemu/target/riscv ) endif() + +if(UNICORN_TRACER) + target_compile_options(riscv64-softmmu PRIVATE -DUNICORN_TRACER) +endif() + endif() @@ -1113,6 +1190,15 @@ set(UNICORN_TEST_FILE ${UNICORN_TEST_FILE} test_mem) set(UNICORN_TEST_FILE ${UNICORN_TEST_FILE} test_ctl) set(UNICORN_SAMPLE_FILE ${UNICORN_SAMPLE_FILE} sample_ctl) +if(UNICORN_TRACER) + target_compile_options(unicorn-common PRIVATE -DUNICORN_TRACER) + target_compile_options(unicorn PRIVATE -DUNICORN_TRACER) +endif() + +target_compile_options(unicorn-common PRIVATE + ${UNICORN_COMPILE_OPTIONS} +) + target_compile_options(unicorn PRIVATE ${UNICORN_COMPILE_OPTIONS} ) diff --git a/bindings/python/setup.py b/bindings/python/setup.py index 9a855a27..7c3cb4ae 100755 --- a/bindings/python/setup.py +++ b/bindings/python/setup.py @@ -131,7 +131,10 @@ def build_libraries(): os.mkdir(BUILD_DIR) conf = 'Debug' if os.getenv('DEBUG', '') else 'Release' - subprocess.check_call(["cmake", '-B', BUILD_DIR, "-DCMAKE_BUILD_TYPE=" + conf]) + cmake_args = ["cmake", '-B', BUILD_DIR, "-DCMAKE_BUILD_TYPE=" + conf] + if os.getenv("TRACE", ""): + cmake_args += ["-DUNICORN_TRACER=on"] + subprocess.check_call(cmake_args) os.chdir(BUILD_DIR) threads = os.getenv("THREADS", "4") subprocess.check_call(["cmake", "--build", ".", "-j" + threads]) diff --git a/include/uc_priv.h b/include/uc_priv.h index 1262c6de..f4431a77 100644 --- a/include/uc_priv.h +++ b/include/uc_priv.h @@ -398,5 +398,31 @@ static inline int uc_addr_is_exit(uc_engine *uc, uint64_t addr) return g_tree_lookup(uc->exits, (gpointer)(&addr)) == (gpointer)1; } +#ifdef UNICORN_TRACER +#define UC_TRACE_START(loc) trace_start(get_tracer(), loc) +#define UC_TRACE_END(loc, fmt, ...) \ + trace_end(get_tracer(), loc, fmt, __VA_ARGS__) + +typedef enum trace_loc { + UC_TRACE_TB_EXEC = 0, + UC_TRACE_TB_TRANS, + UC_TRACER_MAX +} trace_loc; + +typedef struct uc_tracer { + int64_t starts[UC_TRACER_MAX]; +} uc_tracer; + +uc_tracer *get_tracer(); + +void trace_start(uc_tracer *tracer, trace_loc loc); + +void trace_end(uc_tracer *tracer, trace_loc loc, const char *fmt, ...); + +#else +#define UC_TRACE_START(loc) +#define UC_TRACE_END(loc, fmt, ...) +#endif + #endif /* vim: set ts=4 noet: */ diff --git a/qemu/accel/tcg/cpu-exec.c b/qemu/accel/tcg/cpu-exec.c index cb70582c..6c228f94 100644 --- a/qemu/accel/tcg/cpu-exec.c +++ b/qemu/accel/tcg/cpu-exec.c @@ -55,9 +55,12 @@ static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, TranslationBlock *itb) int tb_exit; uint8_t *tb_ptr = itb->tc.ptr; + UC_TRACE_START(UC_TRACE_TB_EXEC); tb_exec_lock(cpu->uc->tcg_ctx); ret = tcg_qemu_tb_exec(env, tb_ptr); tb_exec_unlock(cpu->uc->tcg_ctx); + UC_TRACE_END(UC_TRACE_TB_EXEC, "[uc] exec tb 0x%" PRIx64 ": ", itb->pc); + cpu->can_do_io = 1; last_tb = (TranslationBlock *)(ret & ~TB_EXIT_MASK); tb_exit = ret & TB_EXIT_MASK; diff --git a/qemu/accel/tcg/translate-all.c b/qemu/accel/tcg/translate-all.c index e48670eb..918a7979 100644 --- a/qemu/accel/tcg/translate-all.c +++ b/qemu/accel/tcg/translate-all.c @@ -1619,7 +1619,9 @@ TranslationBlock *tb_gen_code(CPUState *cpu, tcg_func_start(tcg_ctx); tcg_ctx->cpu = env_cpu(env); + UC_TRACE_START(UC_TRACE_TB_TRANS); gen_intermediate_code(cpu, tb, max_insns); + UC_TRACE_END(UC_TRACE_TB_TRANS, "[uc] translate tb 0x%" PRIx64 ": ", tb->pc); tcg_ctx->cpu = NULL; /* generate machine code */ diff --git a/uc.c b/uc.c index d6c3447e..0e870858 100644 --- a/uc.c +++ b/uc.c @@ -2196,3 +2196,31 @@ uc_err uc_ctl(uc_engine *uc, uc_control_type control, ...) return err; } + +#ifdef UNICORN_TRACER +uc_tracer *get_tracer() +{ + static uc_tracer tracer; + return &tracer; +} + +void trace_start(uc_tracer *tracer, trace_loc loc) +{ + tracer->starts[loc] = get_clock(); +} + +void trace_end(uc_tracer *tracer, trace_loc loc, const char *fmt, ...) +{ + va_list args; + int64_t end = get_clock(); + + va_start(args, fmt); + + vfprintf(stderr, fmt, args); + + va_end(args); + + fprintf(stderr, "%.6fms\n", + (double)(end - tracer->starts[loc]) / (double)(1000000)); +} +#endif \ No newline at end of file