@@ -19,12 +19,11 @@ static target_ulong reverse_bits(target_ulong num)
19
19
target_ulong reverse_num = num ;
20
20
21
21
num >>= 1 ;
22
- while (num )
23
- {
24
- reverse_num <<= 1 ;
25
- reverse_num |= num & 1 ;
26
- num >>= 1 ;
27
- count -- ;
22
+ while (num ) {
23
+ reverse_num <<= 1 ;
24
+ reverse_num |= num & 1 ;
25
+ num >>= 1 ;
26
+ count -- ;
28
27
}
29
28
reverse_num <<= count ;
30
29
return reverse_num ;
@@ -34,9 +33,9 @@ static target_ulong reverse_bits(target_ulong num)
34
33
* Isolate the portion of code gen which can setjmp/longjmp.
35
34
* Return the size of the generated code, or negative on error.
36
35
*/
37
- static int libafl_setjmp_gen_code (CPUArchState * env , TranslationBlock * tb ,
38
- vaddr pc , void * host_pc ,
39
- int * max_insns , int64_t * ti )
36
+ static int libafl_setjmp_gen_code (CPUArchState * env , TranslationBlock * tb ,
37
+ vaddr pc , void * host_pc , int * max_insns ,
38
+ int64_t * ti )
40
39
{
41
40
int ret = sigsetjmp (tcg_ctx -> jmp_trans , 0 );
42
41
if (unlikely (ret != 0 )) {
@@ -48,7 +47,8 @@ static int libafl_setjmp_gen_code(CPUArchState *env, TranslationBlock *tb,
48
47
tcg_ctx -> cpu = env_cpu (env );
49
48
50
49
// -- start gen_intermediate_code
51
- const int num_insns = 1 ; // do "as-if" we were translating a single target instruction
50
+ const int num_insns =
51
+ 1 ; // do "as-if" we were translating a single target instruction
52
52
53
53
#ifndef TARGET_INSN_START_EXTRA_WORDS
54
54
tcg_gen_insn_start (pc );
@@ -66,10 +66,13 @@ static int libafl_setjmp_gen_code(CPUArchState *env, TranslationBlock *tb,
66
66
tcg_gen_goto_tb (0 );
67
67
tcg_gen_exit_tb (tb , 0 );
68
68
69
- // This is obviously wrong, but it is required that the number / size of target instruction translated
70
- // is at least 1. For now, we make it so that no problem occurs later on.
71
- tb -> icount = num_insns ; // number of target instructions translated in the TB.
72
- tb -> size = num_insns ; // size (in target bytes) of target instructions translated in the TB.
69
+ // This is obviously wrong, but it is required that the number / size of
70
+ // target instruction translated is at least 1. For now, we make it so that
71
+ // no problem occurs later on.
72
+ tb -> icount =
73
+ num_insns ; // number of target instructions translated in the TB.
74
+ tb -> size = num_insns ; // size (in target bytes) of target instructions
75
+ // translated in the TB.
73
76
// -- end gen_intermediate_code
74
77
75
78
assert (tb -> size != 0 );
@@ -80,18 +83,18 @@ static int libafl_setjmp_gen_code(CPUArchState *env, TranslationBlock *tb,
80
83
}
81
84
82
85
/* Called with mmap_lock held for user mode emulation. */
83
- TranslationBlock * libafl_gen_edge (CPUState * cpu , target_ulong src_block ,
86
+ TranslationBlock * libafl_gen_edge (CPUState * cpu , target_ulong src_block ,
84
87
target_ulong dst_block , int exit_n ,
85
88
target_ulong cs_base , uint32_t flags ,
86
89
int cflags )
87
90
{
88
- CPUArchState * env = cpu_env (cpu );
89
- TranslationBlock * tb ;
91
+ CPUArchState * env = cpu_env (cpu );
92
+ TranslationBlock * tb ;
90
93
tb_page_addr_t phys_pc ;
91
- tcg_insn_unit * gen_code_buf ;
94
+ tcg_insn_unit * gen_code_buf ;
92
95
int gen_code_size , search_size , max_insns ;
93
96
int64_t ti ;
94
- void * host_pc ;
97
+ void * host_pc ;
95
98
96
99
// edge hooks generation callbacks
97
100
// early check if it should be skipped or not
@@ -106,7 +109,8 @@ TranslationBlock *libafl_gen_edge(CPUState *cpu, target_ulong src_block,
106
109
assert_memory_lock ();
107
110
qemu_thread_jit_write ();
108
111
109
- // TODO: this (get_page_addr_code_hostp) is a bottleneck in systemmode, investigate why
112
+ // TODO: this (get_page_addr_code_hostp) is a bottleneck in systemmode,
113
+ // investigate why
110
114
phys_pc = get_page_addr_code_hostp (env , src_block , & host_pc );
111
115
phys_pc ^= reverse_bits ((tb_page_addr_t )exit_n );
112
116
@@ -125,7 +129,7 @@ TranslationBlock *libafl_gen_edge(CPUState *cpu, target_ulong src_block,
125
129
}
126
130
QEMU_BUILD_BUG_ON (CF_COUNT_MASK + 1 != TCG_MAX_INSNS );
127
131
128
- buffer_overflow :
132
+ buffer_overflow :
129
133
assert_no_pages_locked ();
130
134
tb = tcg_tb_alloc (tcg_ctx );
131
135
if (unlikely (!tb )) {
@@ -167,77 +171,80 @@ TranslationBlock *libafl_gen_edge(CPUState *cpu, target_ulong src_block,
167
171
tcg_ctx -> guest_mo = TCG_MO_ALL ;
168
172
#endif
169
173
170
- restart_translate :
174
+ restart_translate :
171
175
trace_translate_block (tb , pc , tb -> tc .ptr );
172
176
173
- gen_code_size = libafl_setjmp_gen_code (env , tb , pc , host_pc , & max_insns , & ti );
177
+ gen_code_size =
178
+ libafl_setjmp_gen_code (env , tb , pc , host_pc , & max_insns , & ti );
174
179
if (unlikely (gen_code_size < 0 )) {
175
180
switch (gen_code_size ) {
176
- case -1 :
177
- /*
178
- * Overflow of code_gen_buffer, or the current slice of it.
179
- *
180
- * TODO: We don't need to re-do gen_intermediate_code, nor
181
- * should we re-do the tcg optimization currently hidden
182
- * inside tcg_gen_code. All that should be required is to
183
- * flush the TBs, allocate a new TB, re-initialize it per
184
- * above, and re-do the actual code generation.
185
- */
186
- qemu_log_mask (CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT ,
187
- "Restarting code generation for "
188
- "code_gen_buffer overflow\n" );
189
- tb_unlock_pages (tb );
190
- tcg_ctx -> gen_tb = NULL ;
191
- goto buffer_overflow ;
192
-
193
- case -2 :
194
- assert (false && "This should never happen for edge code. There must be a bug." );
195
- /*
196
- * The code generated for the TranslationBlock is too large.
197
- * The maximum size allowed by the unwind info is 64k.
198
- * There may be stricter constraints from relocations
199
- * in the tcg backend.
200
- *
201
- * Try again with half as many insns as we attempted this time.
202
- * If a single insn overflows, there's a bug somewhere...
203
- */
204
- assert (max_insns > 1 );
205
- max_insns /= 2 ;
206
- qemu_log_mask (CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT ,
207
- "Restarting code generation with "
208
- "smaller translation block (max %d insns)\n" ,
209
- max_insns );
210
-
211
- /*
212
- * The half-sized TB may not cross pages.
213
- * TODO: Fix all targets that cross pages except with
214
- * the first insn, at which point this can't be reached.
215
- */
216
- // phys_p2 = tb_page_addr1(tb);
217
- // if (unlikely(phys_p2 != -1)) {
218
- // tb_unlock_page1(phys_pc, phys_p2);
219
- // tb_set_page_addr1(tb, -1);
220
- // }
221
- goto restart_translate ;
222
-
223
- case -3 :
224
- /*
225
- * We had a page lock ordering problem. In order to avoid
226
- * deadlock we had to drop the lock on page0, which means
227
- * that everything we translated so far is compromised.
228
- * Restart with locks held on both pages.
229
- */
230
- qemu_log_mask (CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT ,
231
- "Restarting code generation with re-locked pages" );
232
- goto restart_translate ;
233
-
234
- default :
235
- g_assert_not_reached ();
181
+ case -1 :
182
+ /*
183
+ * Overflow of code_gen_buffer, or the current slice of it.
184
+ *
185
+ * TODO: We don't need to re-do gen_intermediate_code, nor
186
+ * should we re-do the tcg optimization currently hidden
187
+ * inside tcg_gen_code. All that should be required is to
188
+ * flush the TBs, allocate a new TB, re-initialize it per
189
+ * above, and re-do the actual code generation.
190
+ */
191
+ qemu_log_mask (CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT ,
192
+ "Restarting code generation for "
193
+ "code_gen_buffer overflow\n" );
194
+ tb_unlock_pages (tb );
195
+ tcg_ctx -> gen_tb = NULL ;
196
+ goto buffer_overflow ;
197
+
198
+ case -2 :
199
+ assert (
200
+ false &&
201
+ "This should never happen for edge code. There must be a bug." );
202
+ /*
203
+ * The code generated for the TranslationBlock is too large.
204
+ * The maximum size allowed by the unwind info is 64k.
205
+ * There may be stricter constraints from relocations
206
+ * in the tcg backend.
207
+ *
208
+ * Try again with half as many insns as we attempted this time.
209
+ * If a single insn overflows, there's a bug somewhere...
210
+ */
211
+ assert (max_insns > 1 );
212
+ max_insns /= 2 ;
213
+ qemu_log_mask (CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT ,
214
+ "Restarting code generation with "
215
+ "smaller translation block (max %d insns)\n" ,
216
+ max_insns );
217
+
218
+ /*
219
+ * The half-sized TB may not cross pages.
220
+ * TODO: Fix all targets that cross pages except with
221
+ * the first insn, at which point this can't be reached.
222
+ */
223
+ // phys_p2 = tb_page_addr1(tb);
224
+ // if (unlikely(phys_p2 != -1)) {
225
+ // tb_unlock_page1(phys_pc, phys_p2);
226
+ // tb_set_page_addr1(tb, -1);
227
+ // }
228
+ goto restart_translate ;
229
+
230
+ case -3 :
231
+ /*
232
+ * We had a page lock ordering problem. In order to avoid
233
+ * deadlock we had to drop the lock on page0, which means
234
+ * that everything we translated so far is compromised.
235
+ * Restart with locks held on both pages.
236
+ */
237
+ qemu_log_mask (CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT ,
238
+ "Restarting code generation with re-locked pages" );
239
+ goto restart_translate ;
240
+
241
+ default :
242
+ g_assert_not_reached ();
236
243
}
237
244
}
238
245
tcg_ctx -> gen_tb = NULL ;
239
246
240
- search_size = encode_search (tb , (void * )gen_code_buf + gen_code_size );
247
+ search_size = encode_search (tb , (void * )gen_code_buf + gen_code_size );
241
248
if (unlikely (search_size < 0 )) {
242
249
tb_unlock_pages (tb );
243
250
goto buffer_overflow ;
@@ -250,9 +257,10 @@ TranslationBlock *libafl_gen_edge(CPUState *cpu, target_ulong src_block,
250
257
*/
251
258
perf_report_code (pc , tb , tcg_splitwx_to_rx (gen_code_buf ));
252
259
253
- qatomic_set (& tcg_ctx -> code_gen_ptr , (void * )
254
- ROUND_UP ((uintptr_t )gen_code_buf + gen_code_size + search_size ,
255
- CODE_GEN_ALIGN ));
260
+ qatomic_set (
261
+ & tcg_ctx -> code_gen_ptr ,
262
+ (void * )ROUND_UP ((uintptr_t )gen_code_buf + gen_code_size + search_size ,
263
+ CODE_GEN_ALIGN ));
256
264
257
265
/* init jump list */
258
266
qemu_spin_init (& tb -> jmp_lock );
0 commit comments