mirror of
https://github.com/xemu-project/xemu.git
synced 2024-11-27 05:20:50 +00:00
Fix TCG relocation bug (exposed by fault after brcond op). Add FIXME for
annother potential bug. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3968 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
41df841110
commit
2ba1eeb62c
39
tcg/tcg.c
39
tcg/tcg.c
@ -97,6 +97,9 @@ void tcg_out_reloc(TCGContext *s, uint8_t *code_ptr, int type,
|
|||||||
|
|
||||||
l = &s->labels[label_index];
|
l = &s->labels[label_index];
|
||||||
if (l->has_value) {
|
if (l->has_value) {
|
||||||
|
/* FIXME: This is wrong. We can not resolve the relocation
|
||||||
|
immediately because the caller has not yet written the
|
||||||
|
initial value. */
|
||||||
patch_reloc(code_ptr, type, l->u.value + addend);
|
patch_reloc(code_ptr, type, l->u.value + addend);
|
||||||
} else {
|
} else {
|
||||||
/* add a new relocation entry */
|
/* add a new relocation entry */
|
||||||
@ -1649,8 +1652,7 @@ void dump_op_count(void)
|
|||||||
|
|
||||||
|
|
||||||
static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
|
static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
|
||||||
int do_search_pc,
|
long search_pc)
|
||||||
const uint8_t *searched_pc)
|
|
||||||
{
|
{
|
||||||
int opc, op_index, macro_op_index;
|
int opc, op_index, macro_op_index;
|
||||||
const TCGOpDef *def;
|
const TCGOpDef *def;
|
||||||
@ -1754,7 +1756,7 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
tcg_reg_alloc_bb_end(s);
|
tcg_reg_alloc_bb_end(s);
|
||||||
if (do_search_pc) {
|
if (search_pc >= 0) {
|
||||||
s->code_ptr += def->copy_size;
|
s->code_ptr += def->copy_size;
|
||||||
args += def->nb_args;
|
args += def->nb_args;
|
||||||
} else {
|
} else {
|
||||||
@ -1771,13 +1773,11 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
|
|||||||
}
|
}
|
||||||
args += def->nb_args;
|
args += def->nb_args;
|
||||||
next: ;
|
next: ;
|
||||||
if (do_search_pc) {
|
if (search_pc >= 0 && search_pc < s->code_ptr - gen_code_buf) {
|
||||||
if (searched_pc < s->code_ptr) {
|
if (macro_op_index >= 0)
|
||||||
if (macro_op_index >= 0)
|
return macro_op_index;
|
||||||
return macro_op_index;
|
else
|
||||||
else
|
return op_index;
|
||||||
return op_index;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
op_index++;
|
op_index++;
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
@ -1802,7 +1802,7 @@ int dyngen_code(TCGContext *s, uint8_t *gen_code_buf)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
tcg_gen_code_common(s, gen_code_buf, 0, NULL);
|
tcg_gen_code_common(s, gen_code_buf, -1);
|
||||||
|
|
||||||
/* flush instruction cache */
|
/* flush instruction cache */
|
||||||
flush_icache_range((unsigned long)gen_code_buf,
|
flush_icache_range((unsigned long)gen_code_buf,
|
||||||
@ -1810,11 +1810,16 @@ int dyngen_code(TCGContext *s, uint8_t *gen_code_buf)
|
|||||||
return s->code_ptr - gen_code_buf;
|
return s->code_ptr - gen_code_buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* return the index of the micro operation such as the pc after is <
|
static uint8_t *dummy_code_buf;
|
||||||
search_pc. Note: gen_code_buf is accessed during the operation, but
|
|
||||||
its content should not be modified. Return -1 if not found. */
|
/* Return the index of the micro operation such as the pc after is <
|
||||||
int dyngen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf,
|
offset bytes from the start of the TB.
|
||||||
const uint8_t *searched_pc)
|
We have to use a dummy code buffer here to avoid clobbering the
|
||||||
|
oringinal code. Because we terminate code generation part way through
|
||||||
|
we can end up with unresolved relocations. Return -1 if not found. */
|
||||||
|
int dyngen_code_search_pc(TCGContext *s, long offset)
|
||||||
{
|
{
|
||||||
return tcg_gen_code_common(s, gen_code_buf, 1, searched_pc);
|
if (!dummy_code_buf)
|
||||||
|
dummy_code_buf = qemu_malloc(code_gen_max_block_size());
|
||||||
|
return tcg_gen_code_common(s, dummy_code_buf, offset);
|
||||||
}
|
}
|
||||||
|
@ -257,8 +257,7 @@ void tcg_context_init(TCGContext *s);
|
|||||||
void tcg_func_start(TCGContext *s);
|
void tcg_func_start(TCGContext *s);
|
||||||
|
|
||||||
int dyngen_code(TCGContext *s, uint8_t *gen_code_buf);
|
int dyngen_code(TCGContext *s, uint8_t *gen_code_buf);
|
||||||
int dyngen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf,
|
int dyngen_code_search_pc(TCGContext *s, long offset);
|
||||||
const uint8_t *searched_pc);
|
|
||||||
|
|
||||||
void tcg_set_frame(TCGContext *s, int reg,
|
void tcg_set_frame(TCGContext *s, int reg,
|
||||||
tcg_target_long start, tcg_target_long size);
|
tcg_target_long start, tcg_target_long size);
|
||||||
|
@ -187,8 +187,7 @@ int cpu_restore_state(TranslationBlock *tb,
|
|||||||
s->tb_jmp_offset = NULL;
|
s->tb_jmp_offset = NULL;
|
||||||
s->tb_next = tb->tb_next;
|
s->tb_next = tb->tb_next;
|
||||||
#endif
|
#endif
|
||||||
j = dyngen_code_search_pc(s, (uint8_t *)tc_ptr,
|
j = dyngen_code_search_pc(s, searched_pc - tc_ptr);
|
||||||
(void *)searched_pc);
|
|
||||||
if (j < 0)
|
if (j < 0)
|
||||||
return -1;
|
return -1;
|
||||||
/* now find start of instruction before */
|
/* now find start of instruction before */
|
||||||
|
Loading…
Reference in New Issue
Block a user