diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c index 63ff70bcfe..c63e04787b 100644 --- a/accel/tcg/translate-all.c +++ b/accel/tcg/translate-all.c @@ -362,7 +362,7 @@ TranslationBlock *libafl_gen_edge(CPUState *cpu, target_ulong src_block, hook->cur_id = 0; if (hook->gen) hook->cur_id = hook->gen(hook->data, src_block, dst_block); - if (hook->cur_id != (uint64_t)-1 && hook->helper_info.func) + if (hook->cur_id != (uint64_t)-1 && (hook->helper_info.func || hook->jit)) no_exec_hook = 0; hook = hook->next; } @@ -417,10 +417,11 @@ TranslationBlock *libafl_gen_edge(CPUState *cpu, target_ulong src_block, tcg_ctx->cpu = env_cpu(env); hook = libafl_edge_hooks; - size_t hcount = 0; + size_t hcount = 0, hins = 0; while (hook) { if (hook->cur_id != (uint64_t)-1 && hook->helper_info.func) { hcount++; + hins++; TCGv_i64 tmp0 = tcg_constant_i64(hook->data); TCGv_i64 tmp1 = tcg_constant_i64(hook->cur_id); TCGTemp *tmp2[2] = { tcgv_i64_temp(tmp0), tcgv_i64_temp(tmp1) }; @@ -428,12 +429,16 @@ TranslationBlock *libafl_gen_edge(CPUState *cpu, target_ulong src_block, tcg_temp_free_i64(tmp0); tcg_temp_free_i64(tmp1); } + if (hook->cur_id != (uint64_t)-1 && hook->jit) { + hcount++; + hins += hook->jit(hook->data, hook->cur_id); + } hook = hook->next; } tcg_gen_goto_tb(0); tcg_gen_exit_tb(tb, 0); tb->size = hcount; - tb->icount = hcount; + tb->icount = hins; assert(tb->size != 0); tcg_ctx->cpu = NULL; diff --git a/libafl_extras/hook.c b/libafl_extras/hook.c index 99534b4275..82be46e352 100644 --- a/libafl_extras/hook.c +++ b/libafl_extras/hook.c @@ -221,6 +221,18 @@ size_t libafl_add_edge_hook(uint64_t (*gen)(uint64_t data, target_ulong src, tar GEN_REMOVE_HOOK(edge) +void libafl_qemu_edge_hook_set_jit(size_t num, size_t (*jit)(uint64_t data, uint64_t id)) { + struct libafl_edge_hook* hk = libafl_edge_hooks; + while (hk) { + if (hk->num == num) { + hk->jit = jit; + return; + } else { + hk = hk->next; + } + } +} + static TCGHelperInfo libafl_exec_block_hook_info = { .func = NULL, .name = "libafl_exec_block_hook", \ .flags = dh_callflag(void), \ diff --git a/libafl_extras/hook.h b/libafl_extras/hook.h index 671403249c..f16030ad88 100644 --- a/libafl_extras/hook.h +++ b/libafl_extras/hook.h @@ -57,6 +57,7 @@ int libafl_qemu_remove_backdoor_hook(size_t num, int invalidate); struct libafl_edge_hook { uint64_t (*gen)(uint64_t data, target_ulong src, target_ulong dst); // void (*exec)(uint64_t data, uint64_t id); + size_t (*jit)(uint64_t data, uint64_t id); // optional opt uint64_t data; size_t num; uint64_t cur_id; @@ -70,6 +71,7 @@ size_t libafl_add_edge_hook(uint64_t (*gen)(uint64_t data, target_ulong src, tar void (*exec)(uint64_t data, uint64_t id), uint64_t data); int libafl_qemu_remove_edge_hook(size_t num, int invalidate); +void libafl_qemu_edge_hook_set_jit(size_t num, size_t (*jit)(uint64_t, uint64_t)); // no param names to avoid to be marked as safe struct libafl_block_hook { uint64_t (*gen)(uint64_t data, target_ulong pc); diff --git a/libafl_extras/jit.c b/libafl_extras/jit.c new file mode 100644 index 0000000000..15277613da --- /dev/null +++ b/libafl_extras/jit.c @@ -0,0 +1,45 @@ +#include "qemu/osdep.h" +#include "qapi/error.h" + +#include "exec/exec-all.h" + +#include "jit.h" + +#ifndef TARGET_LONG_BITS +#error "TARGET_LONG_BITS not defined" +#endif + +/* +pub extern "C" fn trace_edge_hitcount(id: u64, _data: u64) { + unsafe { + EDGES_MAP[id as usize] = EDGES_MAP[id as usize].wrapping_add(1); + } +} + +pub extern "C" fn trace_edge_single(id: u64, _data: u64) { + unsafe { + EDGES_MAP[id as usize] = 1; + } +} +*/ + +// from libafl_targets coverage.rs +// correct size doesn't matter here +uint8_t __afl_area_ptr_local[65536] __attribute__((weak)); + +size_t libafl_jit_trace_edge_hitcount(uint64_t data, uint64_t id) { + TCGv_ptr map_ptr = tcg_constant_ptr(__afl_area_ptr_local); + TCGv_i32 counter = tcg_temp_new_i32(); + tcg_gen_ld8u_i32(counter, map_ptr, (tcg_target_long)id); + tcg_gen_addi_i32(counter, counter, 1); + tcg_gen_st8_i32(counter, map_ptr, (tcg_target_long)id); + return 3; // # instructions +} + +size_t libafl_jit_trace_edge_single(uint64_t data, uint64_t id) { + TCGv_ptr map_ptr = tcg_constant_ptr(__afl_area_ptr_local); + TCGv_i32 counter = tcg_temp_new_i32(); + tcg_gen_movi_i32(counter, 1); + tcg_gen_st8_i32(counter, map_ptr, (tcg_target_long)id); + return 2; // # instructions +} diff --git a/libafl_extras/jit.h b/libafl_extras/jit.h new file mode 100644 index 0000000000..24a8374397 --- /dev/null +++ b/libafl_extras/jit.h @@ -0,0 +1,12 @@ +#pragma once + +#include "qemu/osdep.h" +#include "qapi/error.h" + +#include "tcg/tcg-op.h" +#include "tcg/tcg-internal.h" +#include "tcg/tcg-temp-internal.h" + +size_t libafl_jit_trace_edge_hitcount(uint64_t data, uint64_t id); +size_t libafl_jit_trace_edge_single(uint64_t data, uint64_t id); + diff --git a/libafl_extras/meson.build b/libafl_extras/meson.build index faf24f01e2..6b179fdc23 100644 --- a/libafl_extras/meson.build +++ b/libafl_extras/meson.build @@ -3,4 +3,4 @@ specific_ss.add(when: 'CONFIG_SOFTMMU', if_true: [files( 'syx-snapshot/syx-snapshot.c', 'syx-snapshot/channel-buffer-writeback.c', )]) -specific_ss.add(files('exit.c', 'hook.c')) +specific_ss.add(files('exit.c', 'hook.c', 'jit.c'))