Skip to content

Commit 86d38fb

Browse files
authored
Add pre/post cpu_run hooks + Refactoring (#82)
* Add cpu_run pre/post exec hooks, to hook the cpu just before / after it runs target code. * Refactor hooks to separate them in different files * Remove most extern variables * Reduce the amount of extra code in QEMU * Add clang-format script
1 parent 11b27cc commit 86d38fb

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+2147
-1498
lines changed

accel/kvm/kvm-all.c

+18
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,12 @@
5252
#include "hw/boards.h"
5353
#include "sysemu/stats.h"
5454

55+
//// --- Begin LibAFL code ---
56+
57+
#include "libafl/hooks/cpu_run.h"
58+
59+
//// --- End LibAFL code ---
60+
5561
/* This check must be after config-host.h is included */
5662
#ifdef CONFIG_EVENTFD
5763
#include <sys/eventfd.h>
@@ -2866,10 +2872,22 @@ int kvm_cpu_exec(CPUState *cpu)
28662872
*/
28672873
smp_rmb();
28682874

2875+
//// --- Begin LibAFL code ---
2876+
2877+
libafl_hook_cpu_run_pre_exec(cpu);
2878+
2879+
//// --- End LibAFL code ---
2880+
28692881
run_ret = kvm_vcpu_ioctl(cpu, KVM_RUN, 0);
28702882

28712883
attrs = kvm_arch_post_run(cpu, run);
28722884

2885+
//// --- Begin LibAFL code ---
2886+
2887+
libafl_hook_cpu_run_post_exec(cpu);
2888+
2889+
//// --- End LibAFL code ---
2890+
28732891
#ifdef KVM_HAVE_MCE_INJECTION
28742892
if (unlikely(have_sigbus_pending)) {
28752893
bql_lock();

accel/tcg/translate-all.c

+10-51
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,8 @@
6868

6969
//// --- Begin LibAFL code ---
7070

71-
#include "libafl/hook.h"
71+
#include "libafl/hooks/tcg/block.h"
72+
#include "libafl/hooks/tcg/edge.h"
7273

7374
//// --- End LibAFL code ---
7475

@@ -284,24 +285,7 @@ static int setjmp_gen_code(CPUArchState *env, TranslationBlock *tb,
284285

285286
//// --- Begin LibAFL code ---
286287

287-
struct libafl_block_hook* hook = libafl_block_hooks;
288-
while (hook) {
289-
uint64_t cur_id = 0;
290-
if (hook->gen)
291-
cur_id = hook->gen(hook->data, pc);
292-
if (cur_id != (uint64_t)-1 && hook->helper_info.func) {
293-
TCGv_i64 tmp0 = tcg_constant_i64(hook->data);
294-
TCGv_i64 tmp1 = tcg_constant_i64(cur_id);
295-
TCGTemp *tmp2[2] = { tcgv_i64_temp(tmp0), tcgv_i64_temp(tmp1) };
296-
tcg_gen_callN(&hook->helper_info, NULL, tmp2);
297-
tcg_temp_free_i64(tmp0);
298-
tcg_temp_free_i64(tmp1);
299-
}
300-
if (cur_id != (uint64_t)-1 && hook->jit) {
301-
hook->jit(hook->data, cur_id);
302-
}
303-
hook = hook->next;
304-
}
288+
libafl_qemu_hook_block_run(pc);
305289

306290
//// --- End LibAFL code ---
307291

@@ -361,21 +345,9 @@ static int libafl_setjmp_gen_code(CPUArchState *env, TranslationBlock *tb,
361345
#error Unhandled TARGET_INSN_START_EXTRA_WORDS value
362346
#endif
363347

364-
struct libafl_edge_hook* hook = libafl_edge_hooks;
365-
while (hook) {
366-
if (hook->cur_id != (uint64_t)-1 && hook->helper_info.func) {
367-
TCGv_i64 tmp0 = tcg_constant_i64(hook->data);
368-
TCGv_i64 tmp1 = tcg_constant_i64(hook->cur_id);
369-
TCGTemp *tmp2[2] = { tcgv_i64_temp(tmp0), tcgv_i64_temp(tmp1) };
370-
tcg_gen_callN(&hook->helper_info, NULL, tmp2);
371-
tcg_temp_free_i64(tmp0);
372-
tcg_temp_free_i64(tmp1);
373-
}
374-
if (hook->cur_id != (uint64_t)-1 && hook->jit) {
375-
hook->jit(hook->data, hook->cur_id);
376-
}
377-
hook = hook->next;
378-
}
348+
// run edge hooks
349+
libafl_qemu_hook_edge_run();
350+
379351
tcg_gen_goto_tb(0);
380352
tcg_gen_exit_tb(tb, 0);
381353

@@ -430,16 +402,7 @@ TranslationBlock *libafl_gen_edge(CPUState *cpu, target_ulong src_block,
430402
QEMU_BUILD_BUG_ON(CF_COUNT_MASK + 1 != TCG_MAX_INSNS);
431403

432404
// edge hooks generation callbacks
433-
struct libafl_edge_hook* hook = libafl_edge_hooks;
434-
int no_exec_hook = 1;
435-
while (hook) {
436-
hook->cur_id = 0;
437-
if (hook->gen)
438-
hook->cur_id = hook->gen(hook->data, src_block, dst_block);
439-
if (hook->cur_id != (uint64_t)-1 && (hook->helper_info.func || hook->jit))
440-
no_exec_hook = 0;
441-
hook = hook->next;
442-
}
405+
bool no_exec_hook = libafl_qemu_hook_edge_gen(src_block, dst_block);
443406
if (no_exec_hook)
444407
return NULL;
445408

@@ -749,13 +712,9 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
749712
tb->tc.size = gen_code_size;
750713

751714
//// --- Begin LibAFL code ---
752-
struct libafl_block_hook *hook = libafl_block_hooks;
753-
while (hook)
754-
{
755-
if (hook->post_gen)
756-
hook->post_gen(hook->data, pc, tb->size);
757-
hook = hook->next;
758-
}
715+
716+
libafl_qemu_hook_block_post_gen(tb, pc);
717+
759718
//// --- End LibAFL code ---
760719

761720
/*

accel/tcg/translator.c

+6-39
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,9 @@ static void gen_tb_end(const TranslationBlock *tb, uint32_t cflags,
104104
#include "libafl/exit.h"
105105
#include "libafl/hook.h"
106106

107+
#include "libafl/hooks/tcg/instruction.h"
108+
#include "libafl/hooks/tcg/backdoor.h"
109+
107110
#ifndef TARGET_LONG_BITS
108111
#error "TARGET_LONG_BITS not defined"
109112
#endif
@@ -168,37 +171,10 @@ void translator_loop(CPUState *cpu, TranslationBlock *tb, int *max_insns,
168171

169172
//// --- Begin LibAFL code ---
170173

171-
struct libafl_hook* hk = libafl_search_instruction_hook(db->pc_next);
172-
if (hk) {
173-
TCGv_i64 tmp0 = tcg_constant_i64(hk->data);
174-
#if TARGET_LONG_BITS == 32
175-
TCGv_i32 tmp1 = tcg_constant_i32(db->pc_next);
176-
TCGTemp *tmp2[2] = { tcgv_i64_temp(tmp0), tcgv_i32_temp(tmp1) };
177-
#else
178-
TCGv_i64 tmp1 = tcg_constant_i64(db->pc_next);
179-
TCGTemp *tmp2[2] = { tcgv_i64_temp(tmp0), tcgv_i64_temp(tmp1) };
180-
#endif
181-
// tcg_gen_callN(hk->callback, NULL, 2, tmp2);
182-
tcg_gen_callN(&hk->helper_info, NULL, tmp2);
183-
#if TARGET_LONG_BITS == 32
184-
tcg_temp_free_i32(tmp1);
185-
#else
186-
tcg_temp_free_i64(tmp1);
187-
#endif
188-
tcg_temp_free_i64(tmp0);
189-
}
190-
191-
struct libafl_breakpoint* bp = libafl_qemu_breakpoints;
192-
while (bp) {
193-
if (bp->addr == db->pc_next) {
194-
TCGv_i64 tmp0 = tcg_constant_i64((uint64_t)db->pc_next);
195-
gen_helper_libafl_qemu_handle_breakpoint(tcg_env, tmp0);
196-
tcg_temp_free_i64(tmp0);
197-
}
198-
bp = bp->next;
199-
}
174+
libafl_qemu_hook_instruction_run(db->pc_next);
200175

201176
libafl_gen_cur_pc = db->pc_next;
177+
libafl_qemu_breakpoint_run(libafl_gen_cur_pc);
202178

203179
// 0x0f, 0x3a, 0xf2, 0x44
204180
uint8_t backdoor = translator_ldub(cpu_env(cpu), db, db->pc_next);
@@ -209,16 +185,7 @@ void translator_loop(CPUState *cpu, TranslationBlock *tb, int *max_insns,
209185
if (backdoor == 0xf2) {
210186
backdoor = translator_ldub(cpu_env(cpu), db, db->pc_next +3);
211187
if (backdoor == 0x44) {
212-
struct libafl_backdoor_hook* bhk = libafl_backdoor_hooks;
213-
while (bhk) {
214-
TCGv_i64 tmp0 = tcg_constant_i64(bhk->data);
215-
TCGv tmp2 = tcg_constant_tl(db->pc_next);
216-
TCGTemp *args[3] = { tcgv_i64_temp(tmp0), tcgv_ptr_temp(tcg_env), tcgv_tl_temp(tmp2) };
217-
218-
tcg_gen_callN(&bhk->helper_info, NULL, args);
219-
220-
bhk = bhk->next;
221-
}
188+
libafl_qemu_hook_backdoor_run(db->pc_next);
222189

223190
db->pc_next += 4;
224191
goto post_translate_insn;

include/libafl/exit.h

+9-6
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
#pragma once
22

33
#include "qemu/osdep.h"
4+
45
#include "exec/cpu-defs.h"
6+
#include "exec/translator.h"
57

68
#define EXCP_LIBAFL_EXIT 0xf4775747
79

@@ -10,14 +12,13 @@ struct libafl_breakpoint {
1012
struct libafl_breakpoint* next;
1113
};
1214

13-
extern struct libafl_breakpoint* libafl_qemu_breakpoints;
14-
1515
// in cpu-target.c
16-
void libafl_breakpoint_invalidate(CPUState *cpu, target_ulong pc);
16+
void libafl_breakpoint_invalidate(CPUState* cpu, target_ulong pc);
1717

1818
int libafl_qemu_set_breakpoint(target_ulong pc);
1919
int libafl_qemu_remove_breakpoint(target_ulong pc);
2020
void libafl_qemu_trigger_breakpoint(CPUState* cpu);
21+
void libafl_qemu_breakpoint_run(vaddr pc_next);
2122

2223
enum libafl_exit_reason_kind {
2324
INTERNAL = 0,
@@ -31,7 +32,8 @@ struct libafl_exit_reason_breakpoint {
3132
};
3233

3334
// A synchronous exit has been triggered.
34-
struct libafl_exit_reason_sync_exit { };
35+
struct libafl_exit_reason_sync_exit {
36+
};
3537

3638
// QEMU exited on its own for some reason.
3739
struct libafl_exit_reason_internal {
@@ -46,7 +48,7 @@ struct libafl_exit_reason {
4648
union {
4749
struct libafl_exit_reason_internal internal;
4850
struct libafl_exit_reason_breakpoint breakpoint; // kind == BREAKPOINT
49-
struct libafl_exit_reason_sync_exit sync_exit; // kind == SYNC_EXIT
51+
struct libafl_exit_reason_sync_exit sync_exit; // kind == SYNC_EXIT
5052
} data;
5153
};
5254

@@ -58,7 +60,8 @@ void libafl_exit_signal_vm_start(void);
5860
bool libafl_exit_asap(void);
5961
void libafl_sync_exit_cpu(void);
6062

61-
void libafl_exit_request_internal(CPUState* cpu, uint64_t pc, ShutdownCause cause, int signal);
63+
void libafl_exit_request_internal(CPUState* cpu, uint64_t pc,
64+
ShutdownCause cause, int signal);
6265
void libafl_exit_request_sync_backdoor(CPUState* cpu, target_ulong pc);
6366
void libafl_exit_request_breakpoint(CPUState* cpu, target_ulong pc);
6467
struct libafl_exit_reason* libafl_get_exit_reason(void);

0 commit comments

Comments
 (0)