Skip to content

Commit a6fb2a6

Browse files
committed
Save jit state before/after callback
1 parent f332346 commit a6fb2a6

File tree

10 files changed

+115
-41
lines changed

10 files changed

+115
-41
lines changed

qemu/accel/tcg/cpu-exec.c

+4-3
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ static inline TranslationBlock *tb_find(CPUState *cpu,
274274
}
275275

276276
if (HOOK_BOUND_CHECK(hook, (uint64_t)tb->pc)) {
277-
((uc_hook_edge_gen_t)hook->callback)(uc, &cur_tb, &prev_tb, hook->user_data);
277+
JIT_CALLBACK_GUARD(((uc_hook_edge_gen_t)hook->callback)(uc, &cur_tb, &prev_tb, hook->user_data));
278278
}
279279
}
280280
}
@@ -334,6 +334,7 @@ static inline void cpu_handle_debug_exception(CPUState *cpu)
334334
static inline bool cpu_handle_exception(CPUState *cpu, int *ret)
335335
{
336336
bool catched = false;
337+
bool executable = false;
337338
struct uc_struct *uc = cpu->uc;
338339
struct hook *hook;
339340

@@ -347,7 +348,7 @@ static inline bool cpu_handle_exception(CPUState *cpu, int *ret)
347348
if (hook->to_delete) {
348349
continue;
349350
}
350-
catched = ((uc_cb_hookinsn_invalid_t)hook->callback)(uc, hook->user_data);
351+
JIT_CALLBACK_GUARD_VAR(catched, ((uc_cb_hookinsn_invalid_t)hook->callback)(uc, hook->user_data));
351352
if (catched) {
352353
break;
353354
}
@@ -401,7 +402,7 @@ static inline bool cpu_handle_exception(CPUState *cpu, int *ret)
401402
if (hook->to_delete) {
402403
continue;
403404
}
404-
((uc_cb_hookintr_t)hook->callback)(uc, cpu->exception_index, hook->user_data);
405+
JIT_CALLBACK_GUARD(((uc_cb_hookintr_t)hook->callback)(uc, cpu->exception_index, hook->user_data));
405406
catched = true;
406407
}
407408
// Unicorn: If un-catched interrupt, stop executions.

qemu/accel/tcg/cputlb.c

+21-11
Original file line numberDiff line numberDiff line change
@@ -1475,7 +1475,9 @@ load_helper(CPUArchState *env, target_ulong addr, TCGMemOpIdx oi,
14751475
continue;
14761476
if (!HOOK_BOUND_CHECK(hook, paddr))
14771477
continue;
1478-
if ((handled = ((uc_cb_eventmem_t)hook->callback)(uc, UC_MEM_FETCH_UNMAPPED, paddr, size, 0, hook->user_data)))
1478+
JIT_CALLBACK_GUARD_VAR(handled,
1479+
((uc_cb_eventmem_t)hook->callback)(uc, UC_MEM_FETCH_UNMAPPED, paddr, size, 0, hook->user_data));
1480+
if (handled)
14791481
break;
14801482

14811483
// the last callback may already asked to stop emulation
@@ -1490,7 +1492,9 @@ load_helper(CPUArchState *env, target_ulong addr, TCGMemOpIdx oi,
14901492
continue;
14911493
if (!HOOK_BOUND_CHECK(hook, paddr))
14921494
continue;
1493-
if ((handled = ((uc_cb_eventmem_t)hook->callback)(uc, UC_MEM_READ_UNMAPPED, paddr, size, 0, hook->user_data)))
1495+
JIT_CALLBACK_GUARD_VAR(handled,
1496+
((uc_cb_eventmem_t)hook->callback)(uc, UC_MEM_READ_UNMAPPED, paddr, size, 0, hook->user_data));
1497+
if (handled)
14941498
break;
14951499

14961500
// the last callback may already asked to stop emulation
@@ -1551,7 +1555,7 @@ load_helper(CPUArchState *env, target_ulong addr, TCGMemOpIdx oi,
15511555
continue;
15521556
if (!HOOK_BOUND_CHECK(hook, paddr))
15531557
continue;
1554-
((uc_cb_hookmem_t)hook->callback)(env->uc, UC_MEM_READ, paddr, size, 0, hook->user_data);
1558+
JIT_CALLBACK_GUARD(((uc_cb_hookmem_t)hook->callback)(env->uc, UC_MEM_READ, paddr, size, 0, hook->user_data));
15551559

15561560
// the last callback may already asked to stop emulation
15571561
if (uc->stop_request)
@@ -1566,7 +1570,9 @@ load_helper(CPUArchState *env, target_ulong addr, TCGMemOpIdx oi,
15661570
continue;
15671571
if (!HOOK_BOUND_CHECK(hook, paddr))
15681572
continue;
1569-
if ((handled = ((uc_cb_eventmem_t)hook->callback)(uc, UC_MEM_READ_PROT, paddr, size, 0, hook->user_data)))
1573+
JIT_CALLBACK_GUARD_VAR(handled,
1574+
((uc_cb_eventmem_t)hook->callback)(uc, UC_MEM_READ_PROT, paddr, size, 0, hook->user_data));
1575+
if (handled)
15701576
break;
15711577

15721578
// the last callback may already asked to stop emulation
@@ -1610,7 +1616,9 @@ load_helper(CPUArchState *env, target_ulong addr, TCGMemOpIdx oi,
16101616
continue;
16111617
if (!HOOK_BOUND_CHECK(hook, paddr))
16121618
continue;
1613-
if ((handled = ((uc_cb_eventmem_t)hook->callback)(uc, UC_MEM_FETCH_PROT, paddr, size, 0, hook->user_data)))
1619+
JIT_CALLBACK_GUARD_VAR(handled,
1620+
((uc_cb_eventmem_t)hook->callback)(uc, UC_MEM_FETCH_PROT, paddr, size, 0, hook->user_data));
1621+
if (handled)
16141622
break;
16151623

16161624
// the last callback may already asked to stop emulation
@@ -1718,8 +1726,7 @@ load_helper(CPUArchState *env, target_ulong addr, TCGMemOpIdx oi,
17181726
continue;
17191727
if (!HOOK_BOUND_CHECK(hook, paddr))
17201728
continue;
1721-
((uc_cb_hookmem_t)hook->callback)(env->uc, UC_MEM_READ_AFTER, paddr, size, res, hook->user_data);
1722-
1729+
JIT_CALLBACK_GUARD(((uc_cb_hookmem_t)hook->callback)(env->uc, UC_MEM_READ_AFTER, paddr, size, res, hook->user_data));
17231730
// the last callback may already asked to stop emulation
17241731
if (uc->stop_request)
17251732
break;
@@ -2062,8 +2069,7 @@ store_helper(CPUArchState *env, target_ulong addr, uint64_t val,
20622069
continue;
20632070
if (!HOOK_BOUND_CHECK(hook, paddr))
20642071
continue;
2065-
((uc_cb_hookmem_t)hook->callback)(uc, UC_MEM_WRITE, paddr, size, val, hook->user_data);
2066-
2072+
JIT_CALLBACK_GUARD(((uc_cb_hookmem_t)hook->callback)(uc, UC_MEM_WRITE, paddr, size, val, hook->user_data));
20672073
// the last callback may already asked to stop emulation
20682074
if (uc->stop_request)
20692075
break;
@@ -2078,7 +2084,9 @@ store_helper(CPUArchState *env, target_ulong addr, uint64_t val,
20782084
continue;
20792085
if (!HOOK_BOUND_CHECK(hook, paddr))
20802086
continue;
2081-
if ((handled = ((uc_cb_eventmem_t)hook->callback)(uc, UC_MEM_WRITE_UNMAPPED, paddr, size, val, hook->user_data)))
2087+
JIT_CALLBACK_GUARD_VAR(handled,
2088+
((uc_cb_eventmem_t)hook->callback)(uc, UC_MEM_WRITE_UNMAPPED, paddr, size, val, hook->user_data));
2089+
if (handled)
20822090
break;
20832091

20842092
// the last callback may already asked to stop emulation
@@ -2125,7 +2133,9 @@ store_helper(CPUArchState *env, target_ulong addr, uint64_t val,
21252133
continue;
21262134
if (!HOOK_BOUND_CHECK(hook, paddr))
21272135
continue;
2128-
if ((handled = ((uc_cb_eventmem_t)hook->callback)(uc, UC_MEM_WRITE_PROT, paddr, size, val, hook->user_data)))
2136+
JIT_CALLBACK_GUARD_VAR(handled,
2137+
((uc_cb_eventmem_t)hook->callback)(uc, UC_MEM_WRITE_PROT, paddr, size, val, hook->user_data));
2138+
if (handled)
21292139
break;
21302140

21312141
// the last callback may already asked to stop emulation

qemu/accel/tcg/translate-all.c

+3
Original file line numberDiff line numberDiff line change
@@ -2183,6 +2183,9 @@ static void tb_exec_change(struct uc_struct *uc, bool executable)
21832183
if (uc->current_executable != executable) {
21842184
jit_write_protect(executable);
21852185
uc->current_executable = executable;
2186+
assert(
2187+
executable == thread_executable()
2188+
);
21862189
}
21872190
}
21882191
#else /* not needed on non-Darwin platforms */

qemu/include/tcg/tcg-apple-jit.h

+35
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,48 @@ __attribute__((unused)) static bool thread_executable()
6363
return thread_mask() == 1;
6464
}
6565

66+
#define JIT_CALLBACK_GUARD(x) \
67+
{ \
68+
bool executable = uc->current_executable; \
69+
assert (executable == thread_executable()); \
70+
x; \
71+
if (executable != thread_executable()) { \
72+
jit_write_protect(executable); \
73+
} \
74+
} \
75+
76+
77+
#define JIT_CALLBACK_GUARD_VAR(var, x) \
78+
{ \
79+
bool executable = uc->current_executable; \
80+
assert (executable == thread_executable()); \
81+
var = x; \
82+
if (executable != thread_executable()) { \
83+
jit_write_protect(executable); \
84+
} \
85+
} \
86+
87+
6688
#else /* defined(__aarch64__) && defined(CONFIG_DARWIN) */
6789

6890
static inline void jit_write_protect(int enabled)
6991
{
7092
return;
7193
}
7294

95+
#define JIT_CALLBACK_GUARD(x) \
96+
{ \
97+
(void*)uc; \
98+
x; \
99+
} \
100+
101+
102+
#define JIT_CALLBACK_GUARD_VAR(var, x) \
103+
{ \
104+
(void*)uc; \
105+
var = x; \
106+
} \
107+
73108
#endif
74109

75110
#endif /* define TCG_APPLE_JIT_H */

qemu/softmmu/ioport.c

+25-13
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
#include "cpu.h"
3030
#include "exec/memory.h"
3131
#include "uc_priv.h"
32-
32+
#include "tcg/tcg-apple-jit.h"
3333

3434
void cpu_outb(struct uc_struct *uc, uint32_t addr, uint8_t val)
3535
{
@@ -43,8 +43,9 @@ void cpu_outb(struct uc_struct *uc, uint32_t addr, uint8_t val)
4343
HOOK_FOREACH(uc, hook, UC_HOOK_INSN) {
4444
if (hook->to_delete)
4545
continue;
46-
if (hook->insn == UC_X86_INS_OUT)
47-
((uc_cb_insn_out_t)hook->callback)(uc, addr, 1, val, hook->user_data);
46+
if (hook->insn == UC_X86_INS_OUT) {
47+
JIT_CALLBACK_GUARD(((uc_cb_insn_out_t)hook->callback)(uc, addr, 1, val, hook->user_data));
48+
}
4849
}
4950
}
5051

@@ -63,8 +64,9 @@ void cpu_outw(struct uc_struct *uc, uint32_t addr, uint16_t val)
6364
HOOK_FOREACH(uc, hook, UC_HOOK_INSN) {
6465
if (hook->to_delete)
6566
continue;
66-
if (hook->insn == UC_X86_INS_OUT)
67-
((uc_cb_insn_out_t)hook->callback)(uc, addr, 2, val, hook->user_data);
67+
if (hook->insn == UC_X86_INS_OUT) {
68+
JIT_CALLBACK_GUARD(((uc_cb_insn_out_t)hook->callback)(uc, addr, 2, val, hook->user_data));
69+
}
6870
}
6971
}
7072

@@ -83,8 +85,9 @@ void cpu_outl(struct uc_struct *uc, uint32_t addr, uint32_t val)
8385
HOOK_FOREACH(uc, hook, UC_HOOK_INSN) {
8486
if (hook->to_delete)
8587
continue;
86-
if (hook->insn == UC_X86_INS_OUT)
87-
((uc_cb_insn_out_t)hook->callback)(uc, addr, 4, val, hook->user_data);
88+
if (hook->insn == UC_X86_INS_OUT) {
89+
JIT_CALLBACK_GUARD(((uc_cb_insn_out_t)hook->callback)(uc, addr, 4, val, hook->user_data));
90+
}
8891
}
8992
}
9093

@@ -102,8 +105,11 @@ uint8_t cpu_inb(struct uc_struct *uc, uint32_t addr)
102105
HOOK_FOREACH(uc, hook, UC_HOOK_INSN) {
103106
if (hook->to_delete)
104107
continue;
105-
if (hook->insn == UC_X86_INS_IN)
106-
return ((uc_cb_insn_in_t)hook->callback)(uc, addr, 1, hook->user_data);
108+
if (hook->insn == UC_X86_INS_IN) {
109+
uint8_t ret;
110+
JIT_CALLBACK_GUARD_VAR(ret, ((uc_cb_insn_in_t)hook->callback)(uc, addr, 1, hook->user_data));
111+
return ret;
112+
}
107113
}
108114

109115
return 0;
@@ -124,8 +130,11 @@ uint16_t cpu_inw(struct uc_struct *uc, uint32_t addr)
124130
HOOK_FOREACH(uc, hook, UC_HOOK_INSN) {
125131
if (hook->to_delete)
126132
continue;
127-
if (hook->insn == UC_X86_INS_IN)
128-
return ((uc_cb_insn_in_t)hook->callback)(uc, addr, 2, hook->user_data);
133+
if (hook->insn == UC_X86_INS_IN) {
134+
uint16_t ret;
135+
JIT_CALLBACK_GUARD_VAR(ret, ((uc_cb_insn_in_t)hook->callback)(uc, addr, 2, hook->user_data));
136+
return ret;
137+
}
129138
}
130139

131140
return 0;
@@ -148,8 +157,11 @@ uint32_t cpu_inl(struct uc_struct *uc, uint32_t addr)
148157
HOOK_FOREACH(uc, hook, UC_HOOK_INSN) {
149158
if (hook->to_delete)
150159
continue;
151-
if (hook->insn == UC_X86_INS_IN)
152-
return ((uc_cb_insn_in_t)hook->callback)(uc, addr, 4, hook->user_data);
160+
if (hook->insn == UC_X86_INS_IN) {
161+
uint32_t ret;
162+
JIT_CALLBACK_GUARD_VAR(ret, ((uc_cb_insn_in_t)hook->callback)(uc, addr, 4, hook->user_data));
163+
return ret;
164+
}
153165
}
154166

155167
return 0;

qemu/softmmu/unicorn_vtlb.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ bool unicorn_fill_tlb(CPUState *cs, vaddr address, int size,
6363
continue;
6464
}
6565
handled = true;
66-
if ((ret = ((uc_cb_tlbevent_t)hook->callback)(uc, address & TARGET_PAGE_MASK, rw_to_mem_type(rw), &e, hook->user_data))) {
66+
JIT_CALLBACK_GUARD_VAR(ret, ((uc_cb_tlbevent_t)hook->callback)(uc, address & TARGET_PAGE_MASK, rw_to_mem_type(rw), &e, hook->user_data));
67+
if (ret) {
6768
break;
6869
}
6970
}

qemu/target/arm/op_helper.c

+4-1
Original file line numberDiff line numberDiff line change
@@ -939,6 +939,7 @@ uint32_t HELPER(uc_hooksys64)(CPUARMState *env, uint32_t insn, void *hk)
939939
struct hook *hook = (struct hook*)hk;
940940
uc_arm64_cp_reg cp_reg;
941941
uint32_t rt;
942+
uc_engine *uc = env->uc;
942943

943944
if (hook->to_delete) {
944945
return 0;
@@ -965,5 +966,7 @@ uint32_t HELPER(uc_hooksys64)(CPUARMState *env, uint32_t insn, void *hk)
965966
cp_reg.val = 0;
966967
}
967968

968-
return ((uc_cb_insn_sys_t)(hook->callback))(env->uc, uc_rt, &cp_reg, hook->user_data);
969+
uint32_t ret;
970+
JIT_CALLBACK_GUARD_VAR(ret, ((uc_cb_insn_sys_t)(hook->callback))(env->uc, uc_rt, &cp_reg, hook->user_data));
971+
return ret;
969972
}

qemu/target/i386/misc_helper.c

+5-2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "exec/ioport.h"
2626

2727
#include "uc_priv.h"
28+
#include "tcg/tcg-apple-jit.h"
2829

2930
void helper_outb(CPUX86State *env, uint32_t port, uint32_t data)
3031
{
@@ -105,6 +106,7 @@ void helper_into(CPUX86State *env, int next_eip_addend)
105106
void helper_cpuid(CPUX86State *env)
106107
{
107108
uint32_t eax, ebx, ecx, edx;
109+
uc_engine *uc = env->uc;
108110
struct hook *hook;
109111
int skip_cpuid = 0;
110112

@@ -120,8 +122,9 @@ void helper_cpuid(CPUX86State *env)
120122

121123
// Multiple cpuid callbacks returning different values is undefined.
122124
// true -> skip the cpuid instruction
123-
if (hook->insn == UC_X86_INS_CPUID)
124-
skip_cpuid = ((uc_cb_insn_cpuid_t)hook->callback)(env->uc, hook->user_data);
125+
if (hook->insn == UC_X86_INS_CPUID) {
126+
JIT_CALLBACK_GUARD_VAR(skip_cpuid, ((uc_cb_insn_cpuid_t)hook->callback)(env->uc, hook->user_data));
127+
}
125128

126129
// the last callback may already asked to stop emulation
127130
if (env->uc->stop_request)

qemu/target/i386/seg_helper.c

+10-4
Original file line numberDiff line numberDiff line change
@@ -973,14 +973,17 @@ void helper_syscall(CPUX86State *env, int next_eip_addend)
973973
{
974974
// Unicorn: call registered syscall hooks
975975
struct hook *hook;
976+
uc_engine *uc = env->uc;
977+
976978
HOOK_FOREACH_VAR_DECLARE;
977979
HOOK_FOREACH(env->uc, hook, UC_HOOK_INSN) {
978980
if (hook->to_delete)
979981
continue;
980982
if (!HOOK_BOUND_CHECK(hook, env->eip))
981983
continue;
982-
if (hook->insn == UC_X86_INS_SYSCALL)
983-
((uc_cb_insn_syscall_t)hook->callback)(env->uc, hook->user_data);
984+
if (hook->insn == UC_X86_INS_SYSCALL) {
985+
JIT_CALLBACK_GUARD(((uc_cb_insn_syscall_t)hook->callback)(env->uc, hook->user_data));
986+
}
984987

985988
// the last callback may already asked to stop emulation
986989
if (env->uc->stop_request)
@@ -2348,14 +2351,17 @@ void helper_sysenter(CPUX86State *env, int next_eip_addend)
23482351
{
23492352
// Unicorn: call registered SYSENTER hooks
23502353
struct hook *hook;
2354+
uc_engine *uc = env->uc;
2355+
23512356
HOOK_FOREACH_VAR_DECLARE;
23522357
HOOK_FOREACH(env->uc, hook, UC_HOOK_INSN) {
23532358
if (hook->to_delete)
23542359
continue;
23552360
if (!HOOK_BOUND_CHECK(hook, env->eip))
23562361
continue;
2357-
if (hook->insn == UC_X86_INS_SYSENTER)
2358-
((uc_cb_insn_syscall_t)hook->callback)(env->uc, hook->user_data);
2362+
if (hook->insn == UC_X86_INS_SYSENTER) {
2363+
JIT_CALLBACK_GUARD(((uc_cb_insn_syscall_t)hook->callback)(env->uc, hook->user_data));
2364+
}
23592365

23602366
// the last callback may already asked to stop emulation
23612367
if (env->uc->stop_request)

0 commit comments

Comments
 (0)