reorganize stuff

This commit is contained in:
Romain Malmain 2025-04-29 14:26:42 +02:00
parent 5682a6d841
commit 7633d5fce5
No known key found for this signature in database
GPG Key ID: 02E4A13F7415468A
21 changed files with 367 additions and 262 deletions

View File

@ -45,6 +45,15 @@
#include "internal-common.h"
#include "internal-target.h"
//// --- Begin LibAFL code ---
#include "libafl/exit.h"
#include "libafl/tcg.h"
#include "libafl/hooks/tcg/edge.h"
//// --- End LibAFL code ---
/* -icount align implementation. */
typedef struct SyncClocks {
@ -702,12 +711,6 @@ static inline void cpu_handle_debug_exception(CPUState *cpu)
}
}
//// --- Begin LibAFL code ---
#include "libafl/exit.h"
//// --- End LibAFL code ---
static inline bool cpu_handle_exception(CPUState *cpu, int *ret)
{
//// --- Begin LibAFL code ---
@ -958,14 +961,6 @@ static inline void cpu_loop_exec_tb(CPUState *cpu, TranslationBlock *tb,
#endif
}
//// --- Begin LibAFL code ---
TranslationBlock *libafl_gen_edge(CPUState *cpu, target_ulong src_block,
target_ulong dst_block, int exit_n, target_ulong cs_base,
uint32_t flags, int cflags);
//// --- End LibAFL code ---
/* main execution loop */
static int __attribute__((noinline))

View File

@ -54,6 +54,7 @@ void tb_reset_jump(TranslationBlock *tb, int n);
TranslationBlock *tb_link_page(TranslationBlock *tb);
void cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
uintptr_t host_pc);
int encode_search(TranslationBlock *tb, uint8_t *block);
/**
* tlb_init - initialize a CPU's TLB

View File

@ -31,24 +31,6 @@
#include "exec/helper-info.c.inc"
#undef HELPER_H
//// --- Begin LibAFL code ---
#include "libafl/exit.h"
void HELPER(libafl_qemu_handle_breakpoint)(CPUArchState *env, uint64_t pc)
{
CPUState* cpu = env_cpu(env);
libafl_exit_request_breakpoint(cpu, (target_ulong) pc);
}
void HELPER(libafl_qemu_handle_custom_insn)(CPUArchState *env, uint64_t pc, uint32_t kind)
{
CPUState* cpu = env_cpu(env);
libafl_exit_request_custom_insn(cpu, (target_ulong) pc, (enum libafl_custom_insn_kind) kind);
}
//// --- End LibAFL code ---
/* 32-bit helpers */
int32_t HELPER(div_i32)(int32_t arg1, int32_t arg2)

View File

@ -323,13 +323,3 @@ DEF_HELPER_FLAGS_4(gvec_leus32, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
DEF_HELPER_FLAGS_4(gvec_leus64, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
DEF_HELPER_FLAGS_5(gvec_bitsel, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
//// --- Begin LibAFL code ---
DEF_HELPER_FLAGS_2(libafl_qemu_handle_breakpoint, TCG_CALL_NO_RWG,
void, env, i64)
DEF_HELPER_FLAGS_3(libafl_qemu_handle_custom_insn, TCG_CALL_NO_RWG,
void, env, i64, i32)
//// --- End LibAFL code ---

View File

@ -132,8 +132,10 @@ static int64_t decode_sleb128(const uint8_t **pp)
line. The seed for the first line is { tb->pc, 0..., tb->tc.ptr }.
That is, the first column is seeded with the guest pc, the last column
with the host pc, and the middle columns with zeros. */
static int encode_search(TranslationBlock *tb, uint8_t *block)
/*
static
*/
int encode_search(TranslationBlock *tb, uint8_t *block)
{
uint8_t *highwater = tcg_ctx->code_gen_highwater;
uint64_t *insn_data = tcg_ctx->gen_insn_data;
@ -299,208 +301,6 @@ static int setjmp_gen_code(CPUArchState *env, TranslationBlock *tb,
return tcg_gen_code(tcg_ctx, tb, pc);
}
/* Called with mmap_lock held for user mode emulation. */
TranslationBlock *libafl_gen_edge(CPUState *cpu, target_ulong src_block,
target_ulong dst_block, int exit_n,
target_ulong cs_base, uint32_t flags,
int cflags)
{
CPUArchState *env = cpu_env(cpu);
TranslationBlock *tb;
tb_page_addr_t phys_pc;
tcg_insn_unit *gen_code_buf;
int gen_code_size, search_size, max_insns;
int64_t ti;
void *host_pc;
// edge hooks generation callbacks
// early check if it should be skipped or not
bool no_exec_hook = libafl_qemu_hook_edge_gen(src_block, dst_block);
if (no_exec_hook) {
// no exec hooks to run for edges, not point in generating a TB
return NULL;
}
target_ulong pc = src_block ^ reverse_bits((target_ulong)exit_n);
assert_memory_lock();
qemu_thread_jit_write();
// TODO: this (get_page_addr_code_hostp) is a bottleneck in systemmode, investigate why
phys_pc = get_page_addr_code_hostp(env, src_block, &host_pc);
phys_pc ^= reverse_bits((tb_page_addr_t)exit_n);
// if (phys_pc == -1) {
// /* Generate a one-shot TB with 1 insn in it */
// cflags = (cflags & ~CF_COUNT_MASK) | 1;
// }
/* Generate a one-shot TB with max 16 insn in it */
cflags = (cflags & ~CF_COUNT_MASK) | LIBAFL_MAX_INSNS;
QEMU_BUILD_BUG_ON(LIBAFL_MAX_INSNS > TCG_MAX_INSNS);
max_insns = cflags & CF_COUNT_MASK;
if (max_insns == 0) {
max_insns = TCG_MAX_INSNS;
}
QEMU_BUILD_BUG_ON(CF_COUNT_MASK + 1 != TCG_MAX_INSNS);
buffer_overflow:
assert_no_pages_locked();
tb = tcg_tb_alloc(tcg_ctx);
if (unlikely(!tb)) {
/* flush must be done */
tb_flush(cpu);
mmap_unlock();
/* Make the execution loop process the flush as soon as possible. */
cpu->exception_index = EXCP_INTERRUPT;
cpu_loop_exit(cpu);
}
gen_code_buf = tcg_ctx->code_gen_ptr;
tb->tc.ptr = tcg_splitwx_to_rx(gen_code_buf);
if (!(cflags & CF_PCREL)) {
tb->pc = pc;
}
tb->cs_base = cs_base;
tb->flags = flags;
tb->cflags = cflags | CF_IS_EDGE;
tb_set_page_addr0(tb, phys_pc);
tb_set_page_addr1(tb, -1);
// if (phys_pc != -1) {
// tb_lock_page0(phys_pc);
// }
tcg_ctx->gen_tb = tb;
tcg_ctx->addr_type = TARGET_LONG_BITS == 32 ? TCG_TYPE_I32 : TCG_TYPE_I64;
#ifdef CONFIG_SOFTMMU
tcg_ctx->page_bits = TARGET_PAGE_BITS;
tcg_ctx->page_mask = TARGET_PAGE_MASK;
tcg_ctx->tlb_dyn_max_bits = CPU_TLB_DYN_MAX_BITS;
#endif
tcg_ctx->insn_start_words = TARGET_INSN_START_WORDS;
#ifdef TCG_GUEST_DEFAULT_MO
tcg_ctx->guest_mo = TCG_GUEST_DEFAULT_MO;
#else
tcg_ctx->guest_mo = TCG_MO_ALL;
#endif
restart_translate:
trace_translate_block(tb, pc, tb->tc.ptr);
gen_code_size = libafl_setjmp_gen_code(env, tb, pc, host_pc, &max_insns, &ti);
if (unlikely(gen_code_size < 0)) {
switch (gen_code_size) {
case -1:
/*
* Overflow of code_gen_buffer, or the current slice of it.
*
* TODO: We don't need to re-do gen_intermediate_code, nor
* should we re-do the tcg optimization currently hidden
* inside tcg_gen_code. All that should be required is to
* flush the TBs, allocate a new TB, re-initialize it per
* above, and re-do the actual code generation.
*/
qemu_log_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT,
"Restarting code generation for "
"code_gen_buffer overflow\n");
tb_unlock_pages(tb);
tcg_ctx->gen_tb = NULL;
goto buffer_overflow;
case -2:
assert(false && "This should never happen for edge code. There must be a bug.");
/*
* The code generated for the TranslationBlock is too large.
* The maximum size allowed by the unwind info is 64k.
* There may be stricter constraints from relocations
* in the tcg backend.
*
* Try again with half as many insns as we attempted this time.
* If a single insn overflows, there's a bug somewhere...
*/
assert(max_insns > 1);
max_insns /= 2;
qemu_log_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT,
"Restarting code generation with "
"smaller translation block (max %d insns)\n",
max_insns);
/*
* The half-sized TB may not cross pages.
* TODO: Fix all targets that cross pages except with
* the first insn, at which point this can't be reached.
*/
// phys_p2 = tb_page_addr1(tb);
// if (unlikely(phys_p2 != -1)) {
// tb_unlock_page1(phys_pc, phys_p2);
// tb_set_page_addr1(tb, -1);
// }
goto restart_translate;
case -3:
/*
* We had a page lock ordering problem. In order to avoid
* deadlock we had to drop the lock on page0, which means
* that everything we translated so far is compromised.
* Restart with locks held on both pages.
*/
qemu_log_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT,
"Restarting code generation with re-locked pages");
goto restart_translate;
default:
g_assert_not_reached();
}
}
tcg_ctx->gen_tb = NULL;
search_size = encode_search(tb, (void *)gen_code_buf + gen_code_size);
if (unlikely(search_size < 0)) {
tb_unlock_pages(tb);
goto buffer_overflow;
}
tb->tc.size = gen_code_size;
/*
* For CF_PCREL, attribute all executions of the generated code
* to its first mapping.
*/
perf_report_code(pc, tb, tcg_splitwx_to_rx(gen_code_buf));
qatomic_set(&tcg_ctx->code_gen_ptr, (void *)
ROUND_UP((uintptr_t)gen_code_buf + gen_code_size + search_size,
CODE_GEN_ALIGN));
/* init jump list */
qemu_spin_init(&tb->jmp_lock);
tb->jmp_list_head = (uintptr_t)NULL;
tb->jmp_list_next[0] = (uintptr_t)NULL;
tb->jmp_list_next[1] = (uintptr_t)NULL;
tb->jmp_dest[0] = (uintptr_t)NULL;
tb->jmp_dest[1] = (uintptr_t)NULL;
/* init original jump addresses which have been set during tcg_gen_code() */
if (tb->jmp_reset_offset[0] != TB_JMP_OFFSET_INVALID) {
tb_reset_jump(tb, 0);
}
if (tb->jmp_reset_offset[1] != TB_JMP_OFFSET_INVALID) {
tb_reset_jump(tb, 1);
}
assert_no_pages_locked();
#ifndef CONFIG_USER_ONLY
tb->page_addr[0] = tb->page_addr[1] = -1;
#endif
return tb;
}
//// --- End LibAFL code ---
/* Called with mmap_lock held for user mode emulation. */
TranslationBlock *tb_gen_code(CPUState *cpu,
vaddr pc, uint64_t cs_base,

View File

@ -31,6 +31,14 @@
#include "migration/vmstate.h"
#include "system/tcg.h"
//// --- Begin LibAFL code ---
#ifndef CONFIG_USER_ONLY
#include "libafl/syx-snapshot/device-save.h"
#endif
//// --- End LibAFL code ---
bool cpu_has_work(CPUState *cpu)
{
return cpu->cc->sysemu_ops->has_work(cpu);
@ -214,7 +222,16 @@ static int cpu_common_post_load(void *opaque, int version_id)
* memory we've translated code from. So we must flush all TBs,
* which will now be stale.
*/
tb_flush(cpu);
//tb_flush(cpu);
//// --- Begin LibAFL code ---
// flushing the TBs every restore makes it really slow
// TODO handle writes to X code with specific calls to tb_invalidate_phys_addr
if (!libafl_devices_is_restoring()) {
tb_flush(cpu);
}
//// --- End LibAFL code ---
}
return 0;

View File

@ -100,10 +100,6 @@ static inline void stl_phys_notdirty(AddressSpace *as, hwaddr addr, uint32_t val
#include "exec/cpu-defs.h"
#include "exec/target_page.h"
//// --- Begin LibAFL code ---
IntervalTreeRoot* pageflags_get_root(void);
//// --- End LibAFL code ---
CPUArchState *cpu_copy(CPUArchState *env);
#include "cpu.h"

View File

@ -11,4 +11,10 @@
#include "exec/helper-gen.h.inc"
#undef HELPER_H
//// --- Begin LibAFL code ---
#define HELPER_H "libafl/tcg-helper.h"
#include "exec/helper-gen.h.inc"
#undef HELPER_H
//// --- End LibAFL code ---
#endif /* HELPER_GEN_COMMON_H */

View File

@ -13,4 +13,10 @@
#include "exec/helper-proto.h.inc"
#undef HELPER_H
//// --- Begin LibAFL code ---
#define HELPER_H "libafl/tcg-helper.h"
#include "exec/helper-proto.h.inc"
#undef HELPER_H
//// --- End LibAFL code ---
#endif /* HELPER_PROTO_COMMON_H */

View File

@ -1,7 +1,8 @@
#pragma once
#include "qemu/osdep.h"
#include "exec/cpu-defs.h"
#include "exec/cpu_ldst.h"
#include "hw/core/cpu.h"
#define EXCP_LIBAFL_EXIT 0xf4775747

View File

@ -0,0 +1,4 @@
DEF_HELPER_FLAGS_2(libafl_qemu_handle_breakpoint, TCG_CALL_NO_RWG,
void, env, i64)
DEF_HELPER_FLAGS_3(libafl_qemu_handle_custom_insn, TCG_CALL_NO_RWG,
void, env, i64, i32)

View File

@ -1,10 +1,8 @@
#pragma once
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "tcg/tcg.h"
#include "tcg/helper-info.h"
void tcg_gen_callN(void* func, TCGHelperInfo* info, TCGTemp* ret,
TCGTemp** args);

View File

@ -77,7 +77,10 @@ G_NORETURN void cpu_loop_exit_sigbus(CPUState *cpu, target_ulong addr,
MMUAccessType access_type,
uintptr_t ra);
G_NORETURN void cpu_loop(CPUArchState *env);
//// --- Begin LibAFL code ---
/* G_NORETURN */
//// --- End LibAFL code ---
void cpu_loop(CPUArchState *env);
void target_exception_dump(CPUArchState *env, const char *fmt, int code);
#define EXCP_DUMP(env, fmt, code) \

View File

@ -96,4 +96,8 @@ int walk_memory_regions(void *, walk_memory_regions_fn);
void page_dump(FILE *f);
//// --- Begin LibAFL code ---
IntervalTreeRoot* pageflags_get_root(void);
//// --- End LibAFL code ---
#endif

View File

@ -2,18 +2,16 @@
#ifdef CONFIG_USER_ONLY
#include "qemu.h"
#include "user-internals.h"
#include "user/cpu_loop.h"
#endif
#include "exec/gdbstub.h"
#include "exec/cpu-defs.h"
#include "exec/tb-flush.h"
#include "exec/exec-all.h"
#include "hw/core/sysemu-cpu-ops.h"
#include "libafl/cpu.h"
#include "libafl/exit.h"
#include "libafl/hook.h"
int gdb_write_register(CPUState* cpu, uint8_t* mem_buf, int reg);

View File

@ -2,8 +2,6 @@
#include "tcg/tcg.h"
#include "tcg/tcg-op.h"
#include "tcg/tcg-temp-internal.h"
#include "sysemu/runstate.h"
#include "cpu.h"
#include "libafl/cpu.h"

View File

@ -5,6 +5,8 @@ specific_ss.add(files(
'jit.c',
'utils.c',
'gdb.c',
'tcg.c',
'tcg-helper.c',
# TCG-related hooks
'hooks/tcg/backdoor.c',

22
libafl/tcg-helper.c Normal file
View File

@ -0,0 +1,22 @@
#include "qemu/osdep.h"
#include "qemu/host-utils.h"
#include "exec/cpu-common.h"
#include "exec/helper-proto-common.h"
#include "libafl/exit.h"
#define HELPER_H "libafl/tcg-helper.h"
#include "exec/helper-info.c.inc"
#undef HELPER_H
void HELPER(libafl_qemu_handle_breakpoint)(CPUArchState *env, uint64_t pc)
{
CPUState* cpu = env_cpu(env);
libafl_exit_request_breakpoint(cpu, (target_ulong) pc);
}
void HELPER(libafl_qemu_handle_custom_insn)(CPUArchState *env, uint64_t pc, uint32_t kind)
{
CPUState* cpu = env_cpu(env);
libafl_exit_request_custom_insn(cpu, (target_ulong) pc, (enum libafl_custom_insn_kind) kind);
}

279
libafl/tcg.c Normal file
View File

@ -0,0 +1,279 @@
#include "qemu/osdep.h"
#include "qemu/log.h"
#include "exec/cpu-common.h"
#include "accel/tcg/internal-common.h"
#include "accel/tcg/internal-target.h"
#include "accel/tcg/trace.h"
#include "tcg/insn-start-words.h"
#include "tcg/perf.h"
#include "libafl/tcg.h"
#include "libafl/hooks/tcg/edge.h"
static target_ulong reverse_bits(target_ulong num)
{
unsigned int count = sizeof(num) * 8 - 1;
target_ulong reverse_num = num;
num >>= 1;
while(num)
{
reverse_num <<= 1;
reverse_num |= num & 1;
num >>= 1;
count--;
}
reverse_num <<= count;
return reverse_num;
}
/*
* Isolate the portion of code gen which can setjmp/longjmp.
* Return the size of the generated code, or negative on error.
*/
static int libafl_setjmp_gen_code(CPUArchState *env, TranslationBlock *tb,
vaddr pc, void *host_pc,
int *max_insns, int64_t *ti)
{
int ret = sigsetjmp(tcg_ctx->jmp_trans, 0);
if (unlikely(ret != 0)) {
return ret;
}
tcg_func_start(tcg_ctx);
tcg_ctx->cpu = env_cpu(env);
// -- start gen_intermediate_code
const int num_insns = 1; // do "as-if" we were translating a single target instruction
#ifndef TARGET_INSN_START_EXTRA_WORDS
tcg_gen_insn_start(pc);
#elif TARGET_INSN_START_EXTRA_WORDS == 1
tcg_gen_insn_start(pc, 0);
#elif TARGET_INSN_START_EXTRA_WORDS == 2
tcg_gen_insn_start(pc, 0, 0);
#else
#error Unhandled TARGET_INSN_START_EXTRA_WORDS value
#endif
// run edge hooks
libafl_qemu_hook_edge_run();
tcg_gen_goto_tb(0);
tcg_gen_exit_tb(tb, 0);
// This is obviously wrong, but it is required that the number / size of target instruction translated
// is at least 1. For now, we make it so that no problem occurs later on.
tb->icount = num_insns; // number of target instructions translated in the TB.
tb->size = num_insns; // size (in target bytes) of target instructions translated in the TB.
// -- end gen_intermediate_code
assert(tb->size != 0);
tcg_ctx->cpu = NULL;
*max_insns = tb->icount;
return tcg_gen_code(tcg_ctx, tb, pc);
}
/* Called with mmap_lock held for user mode emulation. */
TranslationBlock *libafl_gen_edge(CPUState *cpu, target_ulong src_block,
target_ulong dst_block, int exit_n,
target_ulong cs_base, uint32_t flags,
int cflags)
{
CPUArchState *env = cpu_env(cpu);
TranslationBlock *tb;
tb_page_addr_t phys_pc;
tcg_insn_unit *gen_code_buf;
int gen_code_size, search_size, max_insns;
int64_t ti;
void *host_pc;
// edge hooks generation callbacks
// early check if it should be skipped or not
bool no_exec_hook = libafl_qemu_hook_edge_gen(src_block, dst_block);
if (no_exec_hook) {
// no exec hooks to run for edges, not point in generating a TB
return NULL;
}
target_ulong pc = src_block ^ reverse_bits((target_ulong)exit_n);
assert_memory_lock();
qemu_thread_jit_write();
// TODO: this (get_page_addr_code_hostp) is a bottleneck in systemmode, investigate why
phys_pc = get_page_addr_code_hostp(env, src_block, &host_pc);
phys_pc ^= reverse_bits((tb_page_addr_t)exit_n);
// if (phys_pc == -1) {
// /* Generate a one-shot TB with 1 insn in it */
// cflags = (cflags & ~CF_COUNT_MASK) | 1;
// }
/* Generate a one-shot TB with max 16 insn in it */
cflags = (cflags & ~CF_COUNT_MASK) | LIBAFL_MAX_INSNS;
QEMU_BUILD_BUG_ON(LIBAFL_MAX_INSNS > TCG_MAX_INSNS);
max_insns = cflags & CF_COUNT_MASK;
if (max_insns == 0) {
max_insns = TCG_MAX_INSNS;
}
QEMU_BUILD_BUG_ON(CF_COUNT_MASK + 1 != TCG_MAX_INSNS);
buffer_overflow:
assert_no_pages_locked();
tb = tcg_tb_alloc(tcg_ctx);
if (unlikely(!tb)) {
/* flush must be done */
tb_flush(cpu);
mmap_unlock();
/* Make the execution loop process the flush as soon as possible. */
cpu->exception_index = EXCP_INTERRUPT;
cpu_loop_exit(cpu);
}
gen_code_buf = tcg_ctx->code_gen_ptr;
tb->tc.ptr = tcg_splitwx_to_rx(gen_code_buf);
if (!(cflags & CF_PCREL)) {
tb->pc = pc;
}
tb->cs_base = cs_base;
tb->flags = flags;
tb->cflags = cflags | CF_IS_EDGE;
tb_set_page_addr0(tb, phys_pc);
tb_set_page_addr1(tb, -1);
// if (phys_pc != -1) {
// tb_lock_page0(phys_pc);
// }
tcg_ctx->gen_tb = tb;
tcg_ctx->addr_type = TARGET_LONG_BITS == 32 ? TCG_TYPE_I32 : TCG_TYPE_I64;
#ifdef CONFIG_SOFTMMU
tcg_ctx->page_bits = TARGET_PAGE_BITS;
tcg_ctx->page_mask = TARGET_PAGE_MASK;
tcg_ctx->tlb_dyn_max_bits = CPU_TLB_DYN_MAX_BITS;
#endif
tcg_ctx->insn_start_words = TARGET_INSN_START_WORDS;
#ifdef TCG_GUEST_DEFAULT_MO
tcg_ctx->guest_mo = TCG_GUEST_DEFAULT_MO;
#else
tcg_ctx->guest_mo = TCG_MO_ALL;
#endif
restart_translate:
trace_translate_block(tb, pc, tb->tc.ptr);
gen_code_size = libafl_setjmp_gen_code(env, tb, pc, host_pc, &max_insns, &ti);
if (unlikely(gen_code_size < 0)) {
switch (gen_code_size) {
case -1:
/*
* Overflow of code_gen_buffer, or the current slice of it.
*
* TODO: We don't need to re-do gen_intermediate_code, nor
* should we re-do the tcg optimization currently hidden
* inside tcg_gen_code. All that should be required is to
* flush the TBs, allocate a new TB, re-initialize it per
* above, and re-do the actual code generation.
*/
qemu_log_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT,
"Restarting code generation for "
"code_gen_buffer overflow\n");
tb_unlock_pages(tb);
tcg_ctx->gen_tb = NULL;
goto buffer_overflow;
case -2:
assert(false && "This should never happen for edge code. There must be a bug.");
/*
* The code generated for the TranslationBlock is too large.
* The maximum size allowed by the unwind info is 64k.
* There may be stricter constraints from relocations
* in the tcg backend.
*
* Try again with half as many insns as we attempted this time.
* If a single insn overflows, there's a bug somewhere...
*/
assert(max_insns > 1);
max_insns /= 2;
qemu_log_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT,
"Restarting code generation with "
"smaller translation block (max %d insns)\n",
max_insns);
/*
* The half-sized TB may not cross pages.
* TODO: Fix all targets that cross pages except with
* the first insn, at which point this can't be reached.
*/
// phys_p2 = tb_page_addr1(tb);
// if (unlikely(phys_p2 != -1)) {
// tb_unlock_page1(phys_pc, phys_p2);
// tb_set_page_addr1(tb, -1);
// }
goto restart_translate;
case -3:
/*
* We had a page lock ordering problem. In order to avoid
* deadlock we had to drop the lock on page0, which means
* that everything we translated so far is compromised.
* Restart with locks held on both pages.
*/
qemu_log_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT,
"Restarting code generation with re-locked pages");
goto restart_translate;
default:
g_assert_not_reached();
}
}
tcg_ctx->gen_tb = NULL;
search_size = encode_search(tb, (void *)gen_code_buf + gen_code_size);
if (unlikely(search_size < 0)) {
tb_unlock_pages(tb);
goto buffer_overflow;
}
tb->tc.size = gen_code_size;
/*
* For CF_PCREL, attribute all executions of the generated code
* to its first mapping.
*/
perf_report_code(pc, tb, tcg_splitwx_to_rx(gen_code_buf));
qatomic_set(&tcg_ctx->code_gen_ptr, (void *)
ROUND_UP((uintptr_t)gen_code_buf + gen_code_size + search_size,
CODE_GEN_ALIGN));
/* init jump list */
qemu_spin_init(&tb->jmp_lock);
tb->jmp_list_head = (uintptr_t)NULL;
tb->jmp_list_next[0] = (uintptr_t)NULL;
tb->jmp_list_next[1] = (uintptr_t)NULL;
tb->jmp_dest[0] = (uintptr_t)NULL;
tb->jmp_dest[1] = (uintptr_t)NULL;
/* init original jump addresses which have been set during tcg_gen_code() */
if (tb->jmp_reset_offset[0] != TB_JMP_OFFSET_INVALID) {
tb_reset_jump(tb, 0);
}
if (tb->jmp_reset_offset[1] != TB_JMP_OFFSET_INVALID) {
tb_reset_jump(tb, 1);
}
assert_no_pages_locked();
#ifndef CONFIG_USER_ONLY
tb->page_addr[0] = tb->page_addr[1] = -1;
#endif
return tb;
}

View File

@ -25,6 +25,10 @@
#include "signal-common.h"
#include "user-mmap.h"
//// --- Begin LibAFL code ---
#include "libafl/exit.h"
//// --- End LibAFL code ---
/***********************************************************/
/* CPUX86 core interface */

View File

@ -64,7 +64,6 @@ abi_long do_syscall(CPUArchState *cpu_env, int num, abi_long arg1,
abi_long arg5, abi_long arg6, abi_long arg7,
abi_long arg8);
extern __thread CPUState *thread_cpu;
/* G_NORETURN */ void cpu_loop(CPUArchState *env);
abi_long get_errno(abi_long ret);
const char *target_strerror(int err);
int get_osversion(void);