From 7e0dc68430c509ad50c6b0c9887f7e642a4bba2d Mon Sep 17 00:00:00 2001 From: Romain Malmain Date: Mon, 27 Jan 2025 12:32:35 +0100 Subject: [PATCH] Refactor read/write hooks (#99) * Refactor read/write hooks * add PC to the callbacks * simplify code, merge common code * remove useless tcg frees * use tcg_constant_tl as much as possible, removing most #if in libafl code. --- include/libafl/hook.h | 2 +- include/libafl/hooks/tcg/instruction.h | 5 +- include/libafl/hooks/tcg/read_write.h | 43 ++--- libafl/cpu.c | 3 +- libafl/exit.c | 1 - libafl/hooks/tcg/cmp.c | 8 +- libafl/hooks/tcg/instruction.c | 39 ++--- libafl/hooks/tcg/read_write.c | 230 +++++++++++-------------- libafl/system.c | 9 +- tcg/tcg-op-ldst.c | 39 +++-- tcg/tcg-op-vec.c | 14 +- 11 files changed, 179 insertions(+), 214 deletions(-) diff --git a/include/libafl/hook.h b/include/libafl/hook.h index 6add522880..fa7b9919b7 100644 --- a/include/libafl/hook.h +++ b/include/libafl/hook.h @@ -53,7 +53,7 @@ } // TODO: cleanup this -extern target_ulong libafl_gen_cur_pc; +extern tcg_target_ulong libafl_gen_cur_pc; extern size_t libafl_qemu_hooks_num; void libafl_tcg_gen_asan(TCGTemp* addr, size_t size); diff --git a/include/libafl/hooks/tcg/instruction.h b/include/libafl/hooks/tcg/instruction.h index 3deeb398a5..3ddd81c1fb 100644 --- a/include/libafl/hooks/tcg/instruction.h +++ b/include/libafl/hooks/tcg/instruction.h @@ -14,6 +14,8 @@ #define LIBAFL_TABLES_HASH(p) \ (((13 * ((size_t)(p))) ^ (((size_t)(p)) >> 15)) % LIBAFL_TABLES_SIZE) +typedef void (*libafl_instruction_cb)(uint64_t data, target_ulong pc); + struct libafl_instruction_hook { // data uint64_t data; @@ -28,8 +30,7 @@ struct libafl_instruction_hook { }; size_t libafl_qemu_add_instruction_hooks(target_ulong pc, - void (*callback)(uint64_t data, - target_ulong pc), + libafl_instruction_cb callback, uint64_t data, int invalidate); int libafl_qemu_remove_instruction_hook(size_t num, int invalidate); diff --git a/include/libafl/hooks/tcg/read_write.h b/include/libafl/hooks/tcg/read_write.h index 8e8f4f8118..baeb7d5673 100644 --- a/include/libafl/hooks/tcg/read_write.h +++ b/include/libafl/hooks/tcg/read_write.h @@ -2,11 +2,6 @@ #include "qemu/osdep.h" -#include "qapi/error.h" - -#include "exec/exec-all.h" -#include "exec/tb-flush.h" - #include "libafl/exit.h" #include "libafl/hook.h" @@ -17,9 +12,16 @@ #define LIBAFL_TABLES_HASH(p) \ (((13 * ((size_t)(p))) ^ (((size_t)(p)) >> 15)) % LIBAFL_TABLES_SIZE) +typedef uint64_t (*libafl_rw_gen_cb)(uint64_t data, target_ulong pc, + TCGTemp* addr, MemOpIdx oi); +typedef void (*libafl_rw_exec_cb)(uint64_t data, uint64_t id, target_ulong pc, + target_ulong addr); +typedef void (*libafl_rw_execN_cb)(uint64_t data, uint64_t id, target_ulong pc, + target_ulong addr, size_t size); + struct libafl_rw_hook { // functions - uint64_t (*gen)(uint64_t data, target_ulong pc, TCGTemp* addr, MemOpIdx oi); + libafl_rw_gen_cb gen; // data uint64_t data; @@ -36,25 +38,18 @@ struct libafl_rw_hook { struct libafl_rw_hook* next; }; -void libafl_gen_read(TCGTemp* addr, MemOpIdx oi); -void libafl_gen_write(TCGTemp* addr, MemOpIdx oi); +void libafl_gen_read(TCGTemp* pc, TCGTemp* addr, MemOpIdx oi); +void libafl_gen_write(TCGTemp* pc, TCGTemp* addr, MemOpIdx oi); -size_t libafl_add_read_hook( - uint64_t (*gen)(uint64_t data, target_ulong pc, TCGTemp* addr, MemOpIdx oi), - void (*exec1)(uint64_t data, uint64_t id, target_ulong addr), - void (*exec2)(uint64_t data, uint64_t id, target_ulong addr), - void (*exec4)(uint64_t data, uint64_t id, target_ulong addr), - void (*exec8)(uint64_t data, uint64_t id, target_ulong addr), - void (*execN)(uint64_t data, uint64_t id, target_ulong addr, size_t size), - uint64_t data); -size_t libafl_add_write_hook( - uint64_t (*gen)(uint64_t data, target_ulong pc, TCGTemp* addr, MemOpIdx oi), - void (*exec1)(uint64_t data, uint64_t id, target_ulong addr), - void (*exec2)(uint64_t data, uint64_t id, target_ulong addr), - void (*exec4)(uint64_t data, uint64_t id, target_ulong addr), - void (*exec8)(uint64_t data, uint64_t id, target_ulong addr), - void (*execN)(uint64_t data, uint64_t id, target_ulong addr, size_t size), - uint64_t data); +size_t libafl_add_read_hook(libafl_rw_gen_cb gen, libafl_rw_exec_cb exec1, + libafl_rw_exec_cb exec2, libafl_rw_exec_cb exec4, + libafl_rw_exec_cb exec8, libafl_rw_execN_cb execN, + uint64_t data); + +size_t libafl_add_write_hook(libafl_rw_gen_cb gen, libafl_rw_exec_cb exec1, + libafl_rw_exec_cb exec2, libafl_rw_exec_cb exec4, + libafl_rw_exec_cb exec8, libafl_rw_execN_cb execN, + uint64_t data); int libafl_qemu_remove_read_hook(size_t num, int invalidate); int libafl_qemu_remove_write_hook(size_t num, int invalidate); diff --git a/libafl/cpu.c b/libafl/cpu.c index e951d3a165..36e748e70b 100644 --- a/libafl/cpu.c +++ b/libafl/cpu.c @@ -140,7 +140,8 @@ int libafl_qemu_num_regs(CPUState* cpu) if (cc->gdb_num_core_regs) { num_regs = cc->gdb_num_core_regs; } else { - const GDBFeature *feature = gdb_find_static_feature(cc->gdb_core_xml_file); + const GDBFeature* feature = + gdb_find_static_feature(cc->gdb_core_xml_file); g_assert(feature); g_assert(feature->num_regs > 0); diff --git a/libafl/exit.c b/libafl/exit.c index 63879d07ab..4748bba6f9 100644 --- a/libafl/exit.c +++ b/libafl/exit.c @@ -165,7 +165,6 @@ void libafl_qemu_breakpoint_run(vaddr pc_next) if (bp->addr == pc_next) { TCGv_i64 tmp0 = tcg_constant_i64((uint64_t)pc_next); gen_helper_libafl_qemu_handle_breakpoint(tcg_env, tmp0); - tcg_temp_free_i64(tmp0); } bp = bp->next; } diff --git a/libafl/hooks/tcg/cmp.c b/libafl/hooks/tcg/cmp.c index 1353e21b3b..ef26942e73 100644 --- a/libafl/hooks/tcg/cmp.c +++ b/libafl/hooks/tcg/cmp.c @@ -116,14 +116,8 @@ void libafl_gen_cmp(target_ulong pc, TCGv op0, TCGv op1, MemOp ot) TCGv_i64 tmp0 = tcg_constant_i64(hook->data); TCGv_i64 tmp1 = tcg_constant_i64(cur_id); TCGTemp* tmp2[4] = {tcgv_i64_temp(tmp0), tcgv_i64_temp(tmp1), -#if TARGET_LONG_BITS == 32 - tcgv_i32_temp(op0), tcgv_i32_temp(op1)}; -#else - tcgv_i64_temp(op0), tcgv_i64_temp(op1)}; -#endif + tcgv_tl_temp(op0), tcgv_tl_temp(op1)}; tcg_gen_callN(info->func, info, NULL, tmp2); - tcg_temp_free_i64(tmp0); - tcg_temp_free_i64(tmp1); } hook = hook->next; } diff --git a/libafl/hooks/tcg/instruction.c b/libafl/hooks/tcg/instruction.c index 064bbbb86f..52671cf25e 100644 --- a/libafl/hooks/tcg/instruction.c +++ b/libafl/hooks/tcg/instruction.c @@ -3,18 +3,21 @@ #include "libafl/cpu.h" -target_ulong libafl_gen_cur_pc; +static TCGHelperInfo libafl_instruction_info = { + .func = NULL, + .name = "libafl_instruction_hook", + .flags = dh_callflag(void), + .typemask = dh_typemask(void, 0) | dh_typemask(i64, 1) | dh_typemask(tl, 2), +}; + +tcg_target_ulong libafl_gen_cur_pc; struct libafl_instruction_hook* libafl_qemu_instruction_hooks[LIBAFL_TABLES_SIZE]; size_t libafl_qemu_hooks_num = 0; size_t libafl_qemu_add_instruction_hooks(target_ulong pc, - void (*callback)(uint64_t data, - target_ulong pc), - uint64_t - - data, - int invalidate) + libafl_instruction_cb callback, + uint64_t data, int invalidate) { CPUState* cpu; @@ -27,13 +30,9 @@ size_t libafl_qemu_add_instruction_hooks(target_ulong pc, struct libafl_instruction_hook* hk = calloc(sizeof(struct libafl_instruction_hook), 1); hk->addr = pc; - // hk->callback = callback; hk->data = data; + hk->helper_info = libafl_instruction_info; hk->helper_info.func = callback; - hk->helper_info.name = "libafl_instruction_hook"; - hk->helper_info.flags = dh_callflag(void); - hk->helper_info.typemask = - dh_typemask(void, 0) | dh_typemask(i64, 1) | dh_typemask(tl, 2); // TODO check for overflow hk->num = libafl_qemu_hooks_num++; hk->next = libafl_qemu_instruction_hooks[idx]; @@ -117,20 +116,8 @@ void libafl_qemu_hook_instruction_run(vaddr pc_next) libafl_search_instruction_hook(pc_next); if (hk) { TCGv_i64 tmp0 = tcg_constant_i64(hk->data); -#if TARGET_LONG_BITS == 32 - TCGv_i32 tmp1 = tcg_constant_i32(pc_next); - TCGTemp* tmp2[2] = {tcgv_i64_temp(tmp0), tcgv_i32_temp(tmp1)}; -#else - TCGv_i64 tmp1 = tcg_constant_i64(pc_next); - TCGTemp* tmp2[2] = {tcgv_i64_temp(tmp0), tcgv_i64_temp(tmp1)}; -#endif - // tcg_gen_callN(hk->callback, NULL, 2, tmp2); + TCGv tmp1 = tcg_constant_tl(pc_next); + TCGTemp* tmp2[2] = {tcgv_i64_temp(tmp0), tcgv_tl_temp(tmp1)}; tcg_gen_callN(hk->helper_info.func, &hk->helper_info, NULL, tmp2); -#if TARGET_LONG_BITS == 32 - tcg_temp_free_i32(tmp1); -#else - tcg_temp_free_i64(tmp1); -#endif - tcg_temp_free_i64(tmp0); } } diff --git a/libafl/hooks/tcg/read_write.c b/libafl/hooks/tcg/read_write.c index 7ffe2c37f5..d18b253b2f 100644 --- a/libafl/hooks/tcg/read_write.c +++ b/libafl/hooks/tcg/read_write.c @@ -1,5 +1,10 @@ -#include "libafl/tcg.h" #include "libafl/hooks/tcg/read_write.h" +#include "cpu.h" +#include "exec/tb-flush.h" + +#include "libafl/tcg.h" +#include "libafl/cpu.h" +#include "libafl/hook.h" struct libafl_rw_hook* libafl_read_hooks; size_t libafl_read_hooks_num = 0; @@ -7,186 +12,166 @@ size_t libafl_read_hooks_num = 0; struct libafl_rw_hook* libafl_write_hooks; size_t libafl_write_hooks_num = 0; +#define TYPEMASK_RW_SIZED \ + (dh_typemask(void, 0) | dh_typemask(i64, 1) | dh_typemask(i64, 2) | \ + dh_typemask(i64, 3) | dh_typemask(tl, 4)) + +#define TYPEMASK_RW_UNSIZED (TYPEMASK_RW_SIZED | dh_typemask(i64, 5)) + static TCGHelperInfo libafl_exec_read_hook1_info = { .func = NULL, .name = "libafl_exec_read_hook1", .flags = dh_callflag(void), - .typemask = dh_typemask(void, 0) | dh_typemask(i64, 1) | - dh_typemask(i64, 2) | dh_typemask(tl, 3)}; + .typemask = TYPEMASK_RW_SIZED, +}; + static TCGHelperInfo libafl_exec_read_hook2_info = { .func = NULL, .name = "libafl_exec_read_hook2", .flags = dh_callflag(void), - .typemask = dh_typemask(void, 0) | dh_typemask(i64, 1) | - dh_typemask(i64, 2) | dh_typemask(tl, 3)}; + .typemask = TYPEMASK_RW_SIZED, +}; + static TCGHelperInfo libafl_exec_read_hook4_info = { .func = NULL, .name = "libafl_exec_read_hook4", .flags = dh_callflag(void), - .typemask = dh_typemask(void, 0) | dh_typemask(i64, 1) | - dh_typemask(i64, 2) | dh_typemask(tl, 3)}; + .typemask = TYPEMASK_RW_SIZED, +}; + static TCGHelperInfo libafl_exec_read_hook8_info = { .func = NULL, .name = "libafl_exec_read_hook8", .flags = dh_callflag(void), - .typemask = dh_typemask(void, 0) | dh_typemask(i64, 1) | - dh_typemask(i64, 2) | dh_typemask(tl, 3)}; + .typemask = TYPEMASK_RW_SIZED, +}; + static TCGHelperInfo libafl_exec_read_hookN_info = { .func = NULL, .name = "libafl_exec_read_hookN", .flags = dh_callflag(void), - .typemask = dh_typemask(void, 0) | dh_typemask(i64, 1) | - dh_typemask(i64, 2) | dh_typemask(tl, 3) | dh_typemask(i64, 4)}; + .typemask = TYPEMASK_RW_UNSIZED, +}; + static TCGHelperInfo libafl_exec_write_hook1_info = { .func = NULL, .name = "libafl_exec_write_hook1", .flags = dh_callflag(void), - .typemask = dh_typemask(void, 0) | dh_typemask(i64, 1) | - dh_typemask(i64, 2) | dh_typemask(tl, 3)}; + .typemask = TYPEMASK_RW_SIZED, +}; + static TCGHelperInfo libafl_exec_write_hook2_info = { .func = NULL, .name = "libafl_exec_write_hook2", .flags = dh_callflag(void), - .typemask = dh_typemask(void, 0) | dh_typemask(i64, 1) | - dh_typemask(i64, 2) | dh_typemask(tl, 3)}; + .typemask = TYPEMASK_RW_SIZED, +}; + static TCGHelperInfo libafl_exec_write_hook4_info = { .func = NULL, .name = "libafl_exec_write_hook4", .flags = dh_callflag(void), - .typemask = dh_typemask(void, 0) | dh_typemask(i64, 1) | - dh_typemask(i64, 2) | dh_typemask(tl, 3)}; + .typemask = TYPEMASK_RW_SIZED, +}; + static TCGHelperInfo libafl_exec_write_hook8_info = { .func = NULL, .name = "libafl_exec_write_hook8", .flags = dh_callflag(void), - .typemask = dh_typemask(void, 0) | dh_typemask(i64, 1) | - dh_typemask(i64, 2) | dh_typemask(tl, 3)}; + .typemask = TYPEMASK_RW_SIZED, +}; + static TCGHelperInfo libafl_exec_write_hookN_info = { .func = NULL, .name = "libafl_exec_write_hookN", .flags = dh_callflag(void), - .typemask = dh_typemask(void, 0) | dh_typemask(i64, 1) | - dh_typemask(i64, 2) | dh_typemask(tl, 3) | dh_typemask(i64, 4)}; + .typemask = TYPEMASK_RW_UNSIZED, +}; GEN_REMOVE_HOOK(read) - GEN_REMOVE_HOOK(write) -size_t libafl_add_read_hook( - uint64_t (*gen)(uint64_t data, target_ulong pc, TCGTemp* addr, MemOpIdx oi), - void (*exec1)(uint64_t data, uint64_t id, target_ulong addr), - void (*exec2)(uint64_t data, uint64_t id, target_ulong addr), - void (*exec4)(uint64_t data, uint64_t id, target_ulong addr), - void (*exec8)(uint64_t data, uint64_t id, target_ulong addr), - void (*execN)(uint64_t data, uint64_t id, target_ulong addr, size_t size), - uint64_t data) +static size_t +libafl_add_rw_hook(struct libafl_rw_hook** hooks, size_t* hooks_num, + libafl_rw_gen_cb gen, libafl_rw_exec_cb exec1, + TCGHelperInfo* exec1_info, libafl_rw_exec_cb exec2, + TCGHelperInfo* exec2_info, libafl_rw_exec_cb exec4, + TCGHelperInfo* exec4_info, libafl_rw_exec_cb exec8, + TCGHelperInfo* exec8_info, libafl_rw_execN_cb execN, + TCGHelperInfo* execN_info, uint64_t data) { CPUState* cpu; CPU_FOREACH(cpu) { tb_flush(cpu); } struct libafl_rw_hook* hook = calloc(sizeof(struct libafl_rw_hook), 1); hook->gen = gen; - /*hook->exec1 = exec1; - hook->exec2 = exec2; - hook->exec4 = exec4; - hook->exec8 = exec8; - hook->execN = execN;*/ hook->data = data; - hook->num = libafl_read_hooks_num++; - hook->next = libafl_read_hooks; - libafl_read_hooks = hook; + hook->num = (*hooks_num)++; + hook->next = *hooks; + *hooks = hook; if (exec1) { - memcpy(&hook->helper_info1, &libafl_exec_read_hook1_info, - sizeof(TCGHelperInfo)); + memcpy(&hook->helper_info1, exec1_info, sizeof(TCGHelperInfo)); hook->helper_info1.func = exec1; } if (exec2) { - memcpy(&hook->helper_info2, &libafl_exec_read_hook2_info, - sizeof(TCGHelperInfo)); + memcpy(&hook->helper_info2, exec2_info, sizeof(TCGHelperInfo)); hook->helper_info2.func = exec2; } if (exec4) { - memcpy(&hook->helper_info4, &libafl_exec_read_hook4_info, - sizeof(TCGHelperInfo)); + memcpy(&hook->helper_info4, exec4_info, sizeof(TCGHelperInfo)); hook->helper_info4.func = exec4; } if (exec8) { - memcpy(&hook->helper_info8, &libafl_exec_read_hook8_info, - sizeof(TCGHelperInfo)); + memcpy(&hook->helper_info8, exec8_info, sizeof(TCGHelperInfo)); hook->helper_info8.func = exec8; } if (execN) { - memcpy(&hook->helper_infoN, &libafl_exec_read_hookN_info, - sizeof(TCGHelperInfo)); + memcpy(&hook->helper_infoN, execN_info, sizeof(TCGHelperInfo)); hook->helper_infoN.func = execN; } return hook->num; } -size_t libafl_add_write_hook( - uint64_t (*gen)(uint64_t data, target_ulong pc, TCGTemp* addr, MemOpIdx oi), - void (*exec1)(uint64_t data, uint64_t id, target_ulong addr), - void (*exec2)(uint64_t data, uint64_t id, target_ulong addr), - void (*exec4)(uint64_t data, uint64_t id, target_ulong addr), - void (*exec8)(uint64_t data, uint64_t id, target_ulong addr), - void (*execN)(uint64_t data, uint64_t id, target_ulong addr, size_t size), - uint64_t data) +size_t libafl_add_read_hook(libafl_rw_gen_cb gen, libafl_rw_exec_cb exec1, + libafl_rw_exec_cb exec2, libafl_rw_exec_cb exec4, + libafl_rw_exec_cb exec8, libafl_rw_execN_cb execN, + uint64_t data) { - CPUState* cpu; - CPU_FOREACH(cpu) { tb_flush(cpu); } - - struct libafl_rw_hook* hook = calloc(sizeof(struct libafl_rw_hook), 1); - hook->gen = gen; - /*hook->exec1 = exec1; - hook->exec2 = exec2; - hook->exec4 = exec4; - hook->exec8 = exec8; - hook->execN = execN;*/ - hook->data = data; - hook->num = libafl_write_hooks_num++; - hook->next = libafl_write_hooks; - libafl_write_hooks = hook; - - if (exec1) { - memcpy(&hook->helper_info1, &libafl_exec_write_hook1_info, - sizeof(TCGHelperInfo)); - hook->helper_info1.func = exec1; - } - if (exec2) { - memcpy(&hook->helper_info2, &libafl_exec_write_hook2_info, - sizeof(TCGHelperInfo)); - hook->helper_info2.func = exec2; - } - if (exec4) { - memcpy(&hook->helper_info4, &libafl_exec_write_hook4_info, - sizeof(TCGHelperInfo)); - hook->helper_info4.func = exec4; - } - if (exec8) { - memcpy(&hook->helper_info8, &libafl_exec_write_hook8_info, - sizeof(TCGHelperInfo)); - hook->helper_info8.func = exec8; - } - if (execN) { - memcpy(&hook->helper_infoN, &libafl_exec_write_hookN_info, - sizeof(TCGHelperInfo)); - hook->helper_infoN.func = execN; - } - - return hook->num; + return libafl_add_rw_hook(&libafl_read_hooks, &libafl_read_hooks_num, gen, + exec1, &libafl_exec_read_hook1_info, exec2, + &libafl_exec_read_hook2_info, exec4, + &libafl_exec_read_hook4_info, exec8, + &libafl_exec_read_hook8_info, execN, + &libafl_exec_read_hookN_info, data); } -static void libafl_gen_rw(TCGTemp* addr, MemOpIdx oi, +size_t libafl_add_write_hook(libafl_rw_gen_cb gen, libafl_rw_exec_cb exec1, + libafl_rw_exec_cb exec2, libafl_rw_exec_cb exec4, + libafl_rw_exec_cb exec8, libafl_rw_execN_cb execN, + uint64_t data) +{ + return libafl_add_rw_hook(&libafl_write_hooks, &libafl_write_hooks_num, gen, + exec1, &libafl_exec_write_hook1_info, exec2, + &libafl_exec_write_hook2_info, exec4, + &libafl_exec_write_hook4_info, exec8, + &libafl_exec_write_hook8_info, execN, + &libafl_exec_write_hookN_info, data); +} + +static void libafl_gen_rw(TCGTemp* pc, TCGTemp* addr, MemOpIdx oi, struct libafl_rw_hook* hook) { size_t size = memop_size(get_memop(oi)); while (hook) { uint64_t cur_id = 0; - if (hook->gen) + + if (hook->gen) { cur_id = hook->gen(hook->data, libafl_gen_cur_pc, addr, oi); + } + TCGHelperInfo* info = NULL; if (size == 1 && hook->helper_info1.func) info = &hook->helper_info1; @@ -196,47 +181,32 @@ static void libafl_gen_rw(TCGTemp* addr, MemOpIdx oi, info = &hook->helper_info4; else if (size == 8 && hook->helper_info8.func) info = &hook->helper_info8; + if (cur_id != (uint64_t)-1) { + TCGv_i64 tmp0 = tcg_constant_i64(hook->data); + TCGv_i64 tmp1 = tcg_constant_i64(cur_id); + if (info) { - TCGv_i64 tmp0 = tcg_constant_i64(hook->data); - TCGv_i64 tmp1 = tcg_constant_i64(cur_id); - TCGTemp* tmp2[3] = {tcgv_i64_temp(tmp0), tcgv_i64_temp(tmp1), - addr}; - tcg_gen_callN(info->func, info, NULL, tmp2); - tcg_temp_free_i64(tmp0); - tcg_temp_free_i64(tmp1); + tcg_gen_call4(info->func, info, NULL, tcgv_i64_temp(tmp0), + tcgv_i64_temp(tmp1), pc, addr); } else if (hook->helper_infoN.func) { - TCGv_i64 tmp0 = tcg_constant_i64(hook->data); - TCGv_i64 tmp1 = tcg_constant_i64(cur_id); - TCGv tmp2 = tcg_constant_tl(size); - TCGTemp* tmp3[4] = {tcgv_i64_temp(tmp0), tcgv_i64_temp(tmp1), - addr, -#if TARGET_LONG_BITS == 32 - tcgv_i32_temp(tmp2)}; -#else - tcgv_i64_temp(tmp2)}; -#endif - tcg_gen_callN(hook->helper_infoN.func, &hook->helper_infoN, - NULL, tmp3); - tcg_temp_free_i64(tmp0); - tcg_temp_free_i64(tmp1); -#if TARGET_LONG_BITS == 32 - tcg_temp_free_i32(tmp2); -#else - tcg_temp_free_i64(tmp2); -#endif + TCGv tmp3 = tcg_constant_tl(size); + + tcg_gen_call5(hook->helper_infoN.func, &hook->helper_infoN, + NULL, tcgv_i64_temp(tmp0), tcgv_i64_temp(tmp1), + pc, addr, tcgv_tl_temp(tmp3)); } } hook = hook->next; } } -void libafl_gen_read(TCGTemp* addr, MemOpIdx oi) +void libafl_gen_read(TCGTemp* pc, TCGTemp* addr, MemOpIdx oi) { - libafl_gen_rw(addr, oi, libafl_read_hooks); + libafl_gen_rw(pc, addr, oi, libafl_read_hooks); } -void libafl_gen_write(TCGTemp* addr, MemOpIdx oi) +void libafl_gen_write(TCGTemp* pc, TCGTemp* addr, MemOpIdx oi) { - libafl_gen_rw(addr, oi, libafl_write_hooks); + libafl_gen_rw(pc, addr, oi, libafl_write_hooks); } diff --git a/libafl/system.c b/libafl/system.c index 5177d47f31..66b8e38e1f 100644 --- a/libafl/system.c +++ b/libafl/system.c @@ -17,12 +17,13 @@ int libafl_qemu_remove_hw_breakpoint(vaddr addr) return libafl_qemu_toggle_hw_breakpoint(addr, false); } -int libafl_qemu_toggle_hw_breakpoint(vaddr addr, bool set) { +int libafl_qemu_toggle_hw_breakpoint(vaddr addr, bool set) +{ const int type = GDB_BREAKPOINT_HW; const vaddr len = 1; - const AccelOpsClass *ops = cpus_get_accel(); - - CPUState *cs = first_cpu; + const AccelOpsClass* ops = cpus_get_accel(); + + CPUState* cs = first_cpu; int ret = 0; if (!ops->insert_breakpoint) { diff --git a/tcg/tcg-op-ldst.c b/tcg/tcg-op-ldst.c index b904799ab9..4645acae6e 100644 --- a/tcg/tcg-op-ldst.c +++ b/tcg/tcg-op-ldst.c @@ -32,6 +32,10 @@ #include "tcg-internal.h" //// --- Begin LibAFL code --- +extern tcg_target_ulong libafl_gen_cur_pc; + +void libafl_gen_read(TCGTemp* pc, TCGTemp* addr, MemOpIdx oi); +void libafl_gen_write(TCGTemp* pc, TCGTemp* addr, MemOpIdx oi); /* Copied over from the plugin_maybe_preserve_addr function * The variable needs to be free'd after use @@ -52,9 +56,6 @@ static TCGv_i64 libafl_gen_preserve_addr(TCGTemp *addr) return temp; } -void libafl_gen_read(TCGTemp *addr, MemOpIdx oi); -void libafl_gen_write(TCGTemp *addr, MemOpIdx oi); - //// --- End LibAFL code --- static void check_max_alignment(unsigned a_bits) @@ -239,7 +240,8 @@ static void tcg_gen_qemu_ld_i32_int(TCGv_i32 val, TCGTemp *addr, //// --- Begin LibAFL code --- - libafl_gen_read(tcgv_i64_temp(libafl_addr), orig_oi); + TCGv_i64 cur_pc = tcg_constant_i64(libafl_gen_cur_pc); + libafl_gen_read(tcgv_i64_temp(cur_pc), tcgv_i64_temp(libafl_addr), orig_oi); tcg_temp_free_i64(libafl_addr); //// --- End LibAFL code --- @@ -314,7 +316,8 @@ static void tcg_gen_qemu_st_i32_int(TCGv_i32 val, TCGTemp *addr, //// --- Begin LibAFL code --- - libafl_gen_write(addr, oi); + TCGv_i64 cur_pc = tcg_constant_i64(libafl_gen_cur_pc); + libafl_gen_write(tcgv_i64_temp(cur_pc), addr, oi); //// --- End LibAFL code --- @@ -380,7 +383,8 @@ static void tcg_gen_qemu_ld_i64_int(TCGv_i64 val, TCGTemp *addr, //// --- Begin LibAFL code --- - libafl_gen_read(tcgv_i64_temp(libafl_addr), orig_oi); + TCGv_i64 cur_pc = tcg_constant_i64(libafl_gen_cur_pc); + libafl_gen_read(tcgv_i64_temp(cur_pc), tcgv_i64_temp(libafl_addr), orig_oi); tcg_temp_free_i64(libafl_addr); //// --- End LibAFL code --- @@ -459,7 +463,8 @@ static void tcg_gen_qemu_st_i64_int(TCGv_i64 val, TCGTemp *addr, //// --- Begin LibAFL code --- - libafl_gen_write(addr, oi); + TCGv_i64 cur_pc = tcg_constant_i64(libafl_gen_cur_pc); + libafl_gen_write(tcgv_i64_temp(cur_pc), addr, oi); //// --- End LibAFL code --- @@ -673,7 +678,8 @@ static void tcg_gen_qemu_ld_i128_int(TCGv_i128 val, TCGTemp *addr, //// --- Begin LibAFL code --- - libafl_gen_read(addr, orig_oi); + TCGv_i64 cur_pc = tcg_constant_i64(libafl_gen_cur_pc); + libafl_gen_read(tcgv_i64_temp(cur_pc), addr, orig_oi); //// --- End LibAFL code --- @@ -795,7 +801,8 @@ static void tcg_gen_qemu_st_i128_int(TCGv_i128 val, TCGTemp *addr, //// --- Begin LibAFL code --- - libafl_gen_write(addr, orig_oi); + TCGv_i64 cur_pc = tcg_constant_i64(libafl_gen_cur_pc); + libafl_gen_write(tcgv_i64_temp(cur_pc), addr, orig_oi); //// --- End LibAFL code --- @@ -1293,11 +1300,14 @@ void tcg_gen_atomic_##NAME##_i32_chk(TCGv_i32 ret, TCGTemp *addr, \ tcg_debug_assert((memop & MO_SIZE) <= MO_32); \ if (tcg_ctx->gen_tb->cflags & CF_PARALLEL) { \ /*** --- Begin LibAFL code --- ***/ \ - libafl_gen_read(addr, make_memop_idx(memop, 0)); \ + TCGv_i64 cur_pc = tcg_constant_i64(libafl_gen_cur_pc); \ + libafl_gen_read( \ + tcgv_i64_temp(cur_pc), addr, make_memop_idx(memop, 0)); \ /*** --- End LibAFL code --- ***/ \ do_atomic_op_i32(ret, addr, val, idx, memop, table_##NAME); \ /*** --- Begin LibAFL code --- ***/ \ - libafl_gen_write(addr, make_memop_idx(memop, 0)); \ + libafl_gen_write( \ + tcgv_i64_temp(cur_pc), addr, make_memop_idx(memop, 0)); \ /*** --- End LibAFL code --- ***/ \ } else { \ do_nonatomic_op_i32(ret, addr, val, idx, memop, NEW, \ @@ -1312,11 +1322,14 @@ void tcg_gen_atomic_##NAME##_i64_chk(TCGv_i64 ret, TCGTemp *addr, \ tcg_debug_assert((memop & MO_SIZE) <= MO_64); \ if (tcg_ctx->gen_tb->cflags & CF_PARALLEL) { \ /*** --- Begin LibAFL code --- ***/ \ - libafl_gen_read(addr, make_memop_idx(memop, 0)); \ + TCGv_i64 cur_pc = tcg_constant_i64(libafl_gen_cur_pc); \ + libafl_gen_read( \ + tcgv_i64_temp(cur_pc), addr, make_memop_idx(memop, 0)); \ /*** --- End LibAFL code --- ***/ \ do_atomic_op_i64(ret, addr, val, idx, memop, table_##NAME); \ /*** --- Begin LibAFL code --- ***/ \ - libafl_gen_write(addr, make_memop_idx(memop, 0)); \ + libafl_gen_write( \ + tcgv_i64_temp(cur_pc), addr, make_memop_idx(memop, 0)); \ /*** --- End LibAFL code --- ***/ \ } else { \ do_nonatomic_op_i64(ret, addr, val, idx, memop, NEW, \ diff --git a/tcg/tcg-op-vec.c b/tcg/tcg-op-vec.c index 776a67e2c5..4b7a9bb65b 100644 --- a/tcg/tcg-op-vec.c +++ b/tcg/tcg-op-vec.c @@ -25,9 +25,10 @@ #include "tcg-internal.h" //// --- Begin LibAFL code --- +extern tcg_target_ulong libafl_gen_cur_pc; -void libafl_gen_read(TCGTemp *addr, MemOpIdx oi); -void libafl_gen_write(TCGTemp *addr, MemOpIdx oi); +void libafl_gen_read(TCGTemp* pc, TCGTemp* addr, MemOpIdx oi); +void libafl_gen_write(TCGTemp* pc, TCGTemp* addr, MemOpIdx oi); //// --- End LibAFL code --- @@ -293,7 +294,8 @@ void tcg_gen_ld_vec(TCGv_vec r, TCGv_ptr b, TCGArg o) vec_gen_ldst(INDEX_op_ld_vec, r, b, o); //// --- Begin LibAFL code --- - libafl_gen_read(tcgv_ptr_temp(b), oi); + TCGv_i64 cur_pc = tcg_constant_i64(libafl_gen_cur_pc); + libafl_gen_read(tcgv_i64_temp(cur_pc), tcgv_ptr_temp(b), oi); //// --- End LibAFL code --- } @@ -309,7 +311,8 @@ void tcg_gen_st_vec(TCGv_vec r, TCGv_ptr b, TCGArg o) vec_gen_ldst(INDEX_op_st_vec, r, b, o); //// --- Begin LibAFL code --- - libafl_gen_write(tcgv_ptr_temp(b), oi); + TCGv_i64 cur_pc = tcg_constant_i64(libafl_gen_cur_pc); + libafl_gen_write(tcgv_i64_temp(cur_pc), tcgv_ptr_temp(b), oi); //// --- End LibAFL code --- } @@ -328,7 +331,8 @@ void tcg_gen_stl_vec(TCGv_vec r, TCGv_ptr b, TCGArg o, TCGType low_type) vec_gen_3(INDEX_op_st_vec, low_type, 0, ri, bi, o); //// --- Begin LibAFL code --- - libafl_gen_write(tcgv_ptr_temp(b), oi); + TCGv_i64 cur_pc = tcg_constant_i64(libafl_gen_cur_pc); + libafl_gen_write(tcgv_i64_temp(cur_pc), tcgv_ptr_temp(b), oi); //// --- End LibAFL code --- }