diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c index dd8b5f61f3..ceacb4faf5 100644 --- a/tcg/i386/tcg-target.c +++ b/tcg/i386/tcg-target.c @@ -318,7 +318,7 @@ static void tcg_out_jxx(TCGContext *s, int opc, int label_index) tcg_out8(s, 0x80 + opc); } tcg_out_reloc(s, s->code_ptr, R_386_PC32, label_index, -4); - tcg_out32(s, -4); + s->code_ptr += 4; } } diff --git a/tcg/tcg.c b/tcg/tcg.c index 4ddc62ff17..a206e5380d 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -97,9 +97,9 @@ void tcg_out_reloc(TCGContext *s, uint8_t *code_ptr, int type, l = &s->labels[label_index]; 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. */ + /* FIXME: This may break relocations on RISC targets that + modify instruction fields in place. The caller may not have + written the initial value. */ patch_reloc(code_ptr, type, l->u.value + addend); } else { /* add a new relocation entry */ @@ -1810,16 +1810,11 @@ int dyngen_code(TCGContext *s, uint8_t *gen_code_buf) return s->code_ptr - gen_code_buf; } -static uint8_t *dummy_code_buf; - /* Return the index of the micro operation such as the pc after is < - offset bytes from the start of the TB. - 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) + offset bytes from the start of the TB. The contents of gen_code_buf must + not be changed, though writing the same values is ok. + Return -1 if not found. */ +int dyngen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf, long offset) { - if (!dummy_code_buf) - dummy_code_buf = qemu_malloc(code_gen_max_block_size()); - return tcg_gen_code_common(s, dummy_code_buf, offset); + return tcg_gen_code_common(s, gen_code_buf, offset); } diff --git a/tcg/tcg.h b/tcg/tcg.h index 11ffb0cd46..09fb9ef990 100644 --- a/tcg/tcg.h +++ b/tcg/tcg.h @@ -257,7 +257,7 @@ void tcg_context_init(TCGContext *s); void tcg_func_start(TCGContext *s); int dyngen_code(TCGContext *s, uint8_t *gen_code_buf); -int dyngen_code_search_pc(TCGContext *s, long offset); +int dyngen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf, long offset); void tcg_set_frame(TCGContext *s, int reg, tcg_target_long start, tcg_target_long size); diff --git a/tcg/x86_64/tcg-target.c b/tcg/x86_64/tcg-target.c index b4b3e7d29a..0ee7d2344e 100644 --- a/tcg/x86_64/tcg-target.c +++ b/tcg/x86_64/tcg-target.c @@ -431,7 +431,7 @@ static void tcg_out_jxx(TCGContext *s, int opc, int label_index) tcg_out8(s, 0x80 + opc); } tcg_out_reloc(s, s->code_ptr, R_386_PC32, label_index, -4); - tcg_out32(s, -4); + s->code_ptr += 4; } } diff --git a/translate-all.c b/translate-all.c index 2000083d85..f100a98258 100644 --- a/translate-all.c +++ b/translate-all.c @@ -187,7 +187,7 @@ int cpu_restore_state(TranslationBlock *tb, s->tb_jmp_offset = NULL; s->tb_next = tb->tb_next; #endif - j = dyngen_code_search_pc(s, searched_pc - tc_ptr); + j = dyngen_code_search_pc(s, (uint8_t *)tc_ptr, searched_pc - tc_ptr); if (j < 0) return -1; /* now find start of instruction before */