Skip to content

Commit 4fc66b6

Browse files
Merge pull request #30 from rmalmain/sync_exit
Sync Exit
2 parents b0c8272 + 466658f commit 4fc66b6

File tree

14 files changed

+175
-69
lines changed

14 files changed

+175
-69
lines changed

accel/tcg/cpu-exec.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -715,21 +715,21 @@ static inline void cpu_handle_debug_exception(CPUState *cpu)
715715

716716
//// --- Begin LibAFL code ---
717717

718-
void libafl_sync_breakpoint_cpu(void);
718+
void libafl_sync_exit_cpu(void);
719719

720720
//// --- End LibAFL code ---
721721

722722
static inline bool cpu_handle_exception(CPUState *cpu, int *ret)
723723
{
724724
//// --- Begin LibAFL code ---
725725

726-
#define EXCP_LIBAFL_BP 0xf4775747
726+
#define EXCP_LIBAFL_EXIT 0xf4775747
727727

728-
if (cpu->exception_index == EXCP_LIBAFL_BP) {
728+
if (cpu->exception_index == EXCP_LIBAFL_EXIT) {
729729
*ret = cpu->exception_index;
730730
cpu->exception_index = -1;
731731

732-
libafl_sync_breakpoint_cpu();
732+
libafl_sync_exit_cpu();
733733
return true;
734734
}
735735

accel/tcg/tcg-runtime.c

Lines changed: 10 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@
4949
#include <stdlib.h>
5050
#include <string.h>
5151

52+
#include "libafl_extras/exit.h"
53+
5254
void libafl_save_qemu_snapshot(char *name, bool sync);
5355
void libafl_load_qemu_snapshot(char *name, bool sync);
5456

@@ -130,57 +132,24 @@ void libafl_load_qemu_snapshot(char *name, bool sync)
130132

131133
#endif
132134

133-
#define EXCP_LIBAFL_BP 0xf4775747
135+
#define EXCP_LIBAFL_EXIT 0xf4775747
134136

135137
#ifdef CONFIG_USER_ONLY
136-
__thread int libafl_qemu_break_asap = 0;
137-
__thread CPUState* libafl_breakpoint_cpu;
138-
__thread vaddr libafl_breakpoint_pc;
139-
#else
140-
int libafl_qemu_break_asap = 0;
141-
CPUState* libafl_breakpoint_cpu;
142-
vaddr libafl_breakpoint_pc;
143-
#endif
144-
145-
#ifdef TARGET_ARM
146-
#define THUMB_MASK(value) (value | cpu_env(libafl_breakpoint_cpu)->thumb)
138+
extern __thread int libafl_qemu_break_asap;
147139
#else
148-
#define THUMB_MASK(value) value
140+
extern int libafl_qemu_break_asap;
149141
#endif
150142

151-
void libafl_qemu_trigger_breakpoint(CPUState* cpu);
152-
153-
void libafl_sync_breakpoint_cpu(void);
154-
155-
void libafl_sync_breakpoint_cpu(void)
156-
{
157-
if (libafl_breakpoint_pc) {
158-
CPUClass* cc = CPU_GET_CLASS(libafl_breakpoint_cpu);
159-
cc->set_pc(libafl_breakpoint_cpu, THUMB_MASK(libafl_breakpoint_pc));
160-
}
161-
libafl_breakpoint_pc = 0;
162-
}
163-
164-
void libafl_qemu_trigger_breakpoint(CPUState* cpu)
143+
void HELPER(libafl_qemu_handle_breakpoint)(CPUArchState *env, uint64_t pc)
165144
{
166-
libafl_breakpoint_cpu = cpu;
167-
#ifndef CONFIG_USER_ONLY
168-
qemu_system_debug_request();
169-
cpu->stopped = true;
170-
#endif
171-
if (cpu->running) {
172-
cpu->exception_index = EXCP_LIBAFL_BP;
173-
cpu_loop_exit(cpu);
174-
} else {
175-
libafl_qemu_break_asap = 1;//TODO add a field to CPU
176-
}
145+
CPUState* cpu = env_cpu(env);
146+
libafl_exit_request_breakpoint(cpu, (target_ulong) pc);
177147
}
178148

179-
void HELPER(libafl_qemu_handle_breakpoint)(CPUArchState *env, uint64_t pc)
149+
void HELPER(libafl_qemu_handle_sync_backdoor)(CPUArchState *env, uint64_t pc)
180150
{
181151
CPUState* cpu = env_cpu(env);
182-
libafl_breakpoint_pc = (target_ulong)pc;
183-
libafl_qemu_trigger_breakpoint(cpu);
152+
libafl_exit_request_sync_backdoor(cpu, (target_ulong) pc);
184153
}
185154

186155
//// --- End LibAFL code ---

accel/tcg/tcg-runtime.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,9 @@ DEF_HELPER_FLAGS_5(gvec_bitsel, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
327327
//// --- Begin LibAFL code ---
328328

329329
DEF_HELPER_FLAGS_2(libafl_qemu_handle_breakpoint, TCG_CALL_NO_RWG,
330-
void, env, i64)
330+
void, env, i64)
331+
332+
DEF_HELPER_FLAGS_2(libafl_qemu_handle_sync_backdoor, TCG_CALL_NO_RWG,
333+
void, env, i64)
331334

332335
//// --- End LibAFL code ---

accel/tcg/translator.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,13 @@ void translator_loop(CPUState *cpu, TranslationBlock *tb, int *max_insns,
272272

273273
db->pc_next += 4;
274274
goto post_translate_insn;
275+
} else if (backdoor == 0x66) {
276+
// First update pc_next to restart at next instruction
277+
db->pc_next += 4;
278+
279+
TCGv_i64 tmp0 = tcg_constant_i64((uint64_t)db->pc_next);
280+
gen_helper_libafl_qemu_handle_sync_backdoor(tcg_env, tmp0);
281+
tcg_temp_free_i64(tmp0);
275282
}
276283
}
277284
}

cpu-target.c

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
#include "tcg/tcg-op.h"
4949
#include "tcg/tcg-internal.h"
5050
#include "exec/helper-head.h"
51+
#include "libafl_extras/exit.h"
5152

5253
#define LIBAFL_TABLES_SIZE 16384
5354
#define LIBAFL_TABLES_HASH(p) (((13*((size_t)(p))) ^ (((size_t)(p)) >> 15)) % LIBAFL_TABLES_SIZE)
@@ -95,12 +96,6 @@ int libafl_qemu_remove_hook(size_t num, int invalidate);
9596
struct libafl_hook* libafl_search_hook(target_ulong addr);
9697
void libafl_flush_jit(void);
9798

98-
#ifdef CONFIG_USER_ONLY
99-
extern __thread CPUState* libafl_breakpoint_cpu;
100-
#else
101-
extern CPUState* libafl_breakpoint_cpu;
102-
#endif
103-
10499
extern int libafl_restoring_devices;
105100

106101
/*
@@ -146,7 +141,7 @@ CPUState* libafl_qemu_current_cpu(void)
146141
{
147142
#ifndef CONFIG_USER_ONLY
148143
if (current_cpu == NULL) {
149-
return libafl_breakpoint_cpu;
144+
return libafl_last_exit_cpu();
150145
}
151146
#endif
152147
return current_cpu;

libafl_extras/exit.c

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
#include "exit.h"
2+
3+
#include "sysemu/runstate.h"
4+
5+
// TODO: merge with definition in tcg-runtime.c
6+
#define EXCP_LIBAFL_EXIT 0xf4775747
7+
8+
#ifdef CONFIG_USER_ONLY
9+
__thread int libafl_qemu_break_asap = 0;
10+
__thread CPUState* libafl_breakpoint_cpu;
11+
__thread vaddr libafl_breakpoint_pc;
12+
__thread static struct libafl_exit_reason last_exit_reason;
13+
#else
14+
static struct libafl_exit_reason last_exit_reason;
15+
#endif
16+
17+
#ifdef TARGET_ARM
18+
#define THUMB_MASK(value) (value | cpu_env(libafl_breakpoint_cpu)->thumb)
19+
#else
20+
#define THUMB_MASK(value) value
21+
#endif
22+
23+
static bool expected_exit = false;
24+
25+
void libafl_sync_exit_cpu(void)
26+
{
27+
if (last_exit_reason.next_pc) {
28+
CPUClass* cc = CPU_GET_CLASS(last_exit_reason.cpu);
29+
cc->set_pc(last_exit_reason.cpu, THUMB_MASK(last_exit_reason.next_pc));
30+
}
31+
last_exit_reason.next_pc = 0;
32+
}
33+
34+
bool libafl_exit_asap(void){
35+
return last_exit_reason.exit_asap;
36+
}
37+
38+
static void prepare_qemu_exit(CPUState* cpu, ulong next_pc)
39+
{
40+
expected_exit = true;
41+
last_exit_reason.cpu = cpu;
42+
last_exit_reason.next_pc = next_pc;
43+
44+
#ifndef CONFIG_USER_ONLY
45+
qemu_system_debug_request();
46+
cpu->stopped = true;
47+
#endif
48+
if (cpu->running) {
49+
cpu->exception_index = EXCP_LIBAFL_EXIT;
50+
cpu_loop_exit(cpu);
51+
} else {
52+
last_exit_reason.exit_asap = 1;
53+
}
54+
}
55+
56+
CPUState* libafl_last_exit_cpu(void)
57+
{
58+
if (expected_exit) {
59+
return last_exit_reason.cpu;
60+
}
61+
62+
return NULL;
63+
}
64+
65+
void libafl_exit_request_sync_backdoor(CPUState* cpu, target_ulong pc)
66+
{
67+
last_exit_reason.kind = SYNC_BACKDOOR;
68+
69+
prepare_qemu_exit(cpu, pc);
70+
}
71+
72+
void libafl_exit_request_breakpoint(CPUState* cpu, target_ulong pc)
73+
{
74+
last_exit_reason.kind = BREAKPOINT;
75+
last_exit_reason.data.breakpoint.addr = pc;
76+
77+
prepare_qemu_exit(cpu, pc);
78+
}
79+
80+
void libafl_exit_signal_vm_start(void)
81+
{
82+
last_exit_reason.cpu = NULL;
83+
expected_exit = false;
84+
}
85+
86+
struct libafl_exit_reason* libafl_get_exit_reason(void)
87+
{
88+
if (expected_exit) {
89+
return &last_exit_reason;
90+
}
91+
92+
return NULL;
93+
}

libafl_extras/exit.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#pragma once
2+
3+
#include "qemu/osdep.h"
4+
#include "exec/cpu-defs.h"
5+
6+
enum libafl_exit_reason_kind {
7+
BREAKPOINT = 0,
8+
SYNC_BACKDOOR = 1
9+
};
10+
11+
struct libafl_exit_reason_breakpoint {
12+
target_ulong addr;
13+
};
14+
15+
struct libafl_exit_reason_sync_backdoor { };
16+
17+
struct libafl_exit_reason {
18+
enum libafl_exit_reason_kind kind;
19+
CPUState* cpu; // CPU that triggered an exit.
20+
vaddr next_pc; // The PC that should be stored in the CPU when re-entering.
21+
int exit_asap; // TODO: add a field to CPU
22+
union {
23+
struct libafl_exit_reason_breakpoint breakpoint; // kind == BREAKPOINT
24+
struct libafl_exit_reason_sync_backdoor backdoor; // kind == SYNC_BACKDOOR
25+
} data;
26+
};
27+
28+
// Only makes sense to call if an exit was expected
29+
// Will return NULL if there was no exit expected.
30+
CPUState* libafl_last_exit_cpu(void);
31+
32+
void libafl_exit_signal_vm_start(void);
33+
bool libafl_exit_asap(void);
34+
void libafl_sync_exit_cpu(void);
35+
36+
void libafl_exit_request_sync_backdoor(CPUState* cpu, target_ulong pc);
37+
void libafl_exit_request_breakpoint(CPUState* cpu, target_ulong pc);
38+
struct libafl_exit_reason* libafl_get_exit_reason(void);

linux-user/aarch64/cpu_loop.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,9 @@ void cpu_loop(CPUARMState *env)
9999

100100
//// --- Begin LibAFL code ---
101101

102-
#define EXCP_LIBAFL_BP 0xf4775747
102+
#define EXCP_LIBAFL_EXIT 0xf4775747
103103

104-
case EXCP_LIBAFL_BP:
104+
case EXCP_LIBAFL_EXIT:
105105
return;
106106

107107
//// --- End LibAFL code ---

linux-user/arm/cpu_loop.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -340,9 +340,9 @@ void cpu_loop(CPUARMState *env)
340340

341341
//// --- Begin LibAFL code ---
342342

343-
#define EXCP_LIBAFL_BP 0xf4775747
343+
#define EXCP_LIBAFL_EXIT 0xf4775747
344344

345-
case EXCP_LIBAFL_BP:
345+
case EXCP_LIBAFL_EXIT:
346346
return;
347347

348348
//// --- End LibAFL code ---

linux-user/hexagon/cpu_loop.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,9 @@ void cpu_loop(CPUHexagonState *env)
4949

5050
//// --- Begin LibAFL code ---
5151

52-
#define EXCP_LIBAFL_BP 0xf4775747
52+
#define EXCP_LIBAFL_EXIT 0xf4775747
5353

54-
case EXCP_LIBAFL_BP:
54+
case EXCP_LIBAFL_EXIT:
5555
return;
5656

5757
//// --- End LibAFL code ---

0 commit comments

Comments
 (0)