diff --git a/qemu/tcg/tcg-be-ldst.h b/qemu/tcg/tcg-be-ldst.h index cafe8ed9..ec1e686a 100644 --- a/qemu/tcg/tcg-be-ldst.h +++ b/qemu/tcg/tcg-be-ldst.h @@ -57,7 +57,7 @@ static inline void tcg_out_tb_init(TCGContext *s) static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l); static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l); -static void tcg_out_tb_finalize(TCGContext *s) +static bool tcg_out_tb_finalize(TCGContext *s) { TCGLabelQemuLdst *lb = s->be->ldst_labels; int i, n = s->be->nb_ldst_labels; @@ -69,7 +69,16 @@ static void tcg_out_tb_finalize(TCGContext *s) } else { tcg_out_qemu_st_slow_path(s, lb + i); } + + /* Test for (pending) buffer overflow. The assumption is that any + one operation beginning below the high water mark cannot overrun + the buffer completely. Thus we can test for overflow after + generating code without having to check during generation. */ + if (unlikely((void *)s->code_ptr > s->code_gen_highwater)) { + return false; + } } + return true; } /* diff --git a/qemu/tcg/tcg-be-null.h b/qemu/tcg/tcg-be-null.h index ba2da3c5..5217d62c 100644 --- a/qemu/tcg/tcg-be-null.h +++ b/qemu/tcg/tcg-be-null.h @@ -40,6 +40,7 @@ static inline void tcg_out_tb_init(TCGContext *s) * Generate TB finalization at the end of block */ -static inline void tcg_out_tb_finalize(TCGContext *s) +static inline bool tcg_out_tb_finalize(TCGContext *s) { + return true; } diff --git a/qemu/tcg/tcg.c b/qemu/tcg/tcg.c index 7d02f37c..727ebaa7 100644 --- a/qemu/tcg/tcg.c +++ b/qemu/tcg/tcg.c @@ -107,7 +107,7 @@ static void tcg_out_call(TCGContext *s, tcg_insn_unit *target); static int tcg_target_const_match(tcg_target_long val, TCGType type, const TCGArgConstraint *arg_ct); static void tcg_out_tb_init(TCGContext *s); -static void tcg_out_tb_finalize(TCGContext *s); +static bool tcg_out_tb_finalize(TCGContext *s); #if TCG_TARGET_INSN_UNIT_SIZE == 1 static QEMU_UNUSED_FUNC inline void tcg_out8(TCGContext *s, uint8_t v) @@ -2497,7 +2497,9 @@ int tcg_gen_code(TCGContext *s, tcg_insn_unit *gen_code_buf) s->gen_insn_end_off[num_insns] = tcg_current_code_size(s); /* Generate TB finalization at the end of block */ - tcg_out_tb_finalize(s); + if (!tcg_out_tb_finalize(s)) { + return -1; + } /* flush instruction cache */ flush_icache_range((uintptr_t)s->code_buf, (uintptr_t)s->code_ptr);