diff --git a/qemu/aarch64.h b/qemu/aarch64.h index b919a355..fad1d153 100644 --- a/qemu/aarch64.h +++ b/qemu/aarch64.h @@ -2945,6 +2945,7 @@ #define tcg_init tcg_init_aarch64 #define tcg_invert_cond tcg_invert_cond_aarch64 #define tcg_la_bb_end tcg_la_bb_end_aarch64 +#define tcg_la_br_end tcg_la_br_end_aarch64 #define tcg_la_func_end tcg_la_func_end_aarch64 #define tcg_liveness_analysis tcg_liveness_analysis_aarch64 #define tcg_malloc tcg_malloc_aarch64 diff --git a/qemu/arm.h b/qemu/arm.h index bf858302..88617c02 100644 --- a/qemu/arm.h +++ b/qemu/arm.h @@ -2945,6 +2945,7 @@ #define tcg_init tcg_init_arm #define tcg_invert_cond tcg_invert_cond_arm #define tcg_la_bb_end tcg_la_bb_end_arm +#define tcg_la_br_end tcg_la_br_end_arm #define tcg_la_func_end tcg_la_func_end_arm #define tcg_liveness_analysis tcg_liveness_analysis_arm #define tcg_malloc tcg_malloc_arm diff --git a/qemu/header_gen.py b/qemu/header_gen.py index 021f8a65..ed74332d 100644 --- a/qemu/header_gen.py +++ b/qemu/header_gen.py @@ -2951,6 +2951,7 @@ symbols = ( 'tcg_init', 'tcg_invert_cond', 'tcg_la_bb_end', + 'tcg_la_br_end', 'tcg_la_func_end', 'tcg_liveness_analysis', 'tcg_malloc', diff --git a/qemu/m68k.h b/qemu/m68k.h index ceb5ca47..8314001b 100644 --- a/qemu/m68k.h +++ b/qemu/m68k.h @@ -2945,6 +2945,7 @@ #define tcg_init tcg_init_m68k #define tcg_invert_cond tcg_invert_cond_m68k #define tcg_la_bb_end tcg_la_bb_end_m68k +#define tcg_la_br_end tcg_la_br_end_m68k #define tcg_la_func_end tcg_la_func_end_m68k #define tcg_liveness_analysis tcg_liveness_analysis_m68k #define tcg_malloc tcg_malloc_m68k diff --git a/qemu/mips.h b/qemu/mips.h index 3c789c04..75269fb8 100644 --- a/qemu/mips.h +++ b/qemu/mips.h @@ -2945,6 +2945,7 @@ #define tcg_init tcg_init_mips #define tcg_invert_cond tcg_invert_cond_mips #define tcg_la_bb_end tcg_la_bb_end_mips +#define tcg_la_br_end tcg_la_br_end_mips #define tcg_la_func_end tcg_la_func_end_mips #define tcg_liveness_analysis tcg_liveness_analysis_mips #define tcg_malloc tcg_malloc_mips diff --git a/qemu/mips64.h b/qemu/mips64.h index 8fb5418e..b5c2908e 100644 --- a/qemu/mips64.h +++ b/qemu/mips64.h @@ -2945,6 +2945,7 @@ #define tcg_init tcg_init_mips64 #define tcg_invert_cond tcg_invert_cond_mips64 #define tcg_la_bb_end tcg_la_bb_end_mips64 +#define tcg_la_br_end tcg_la_br_end_mips64 #define tcg_la_func_end tcg_la_func_end_mips64 #define tcg_liveness_analysis tcg_liveness_analysis_mips64 #define tcg_malloc tcg_malloc_mips64 diff --git a/qemu/mips64el.h b/qemu/mips64el.h index 8a668325..522f998c 100644 --- a/qemu/mips64el.h +++ b/qemu/mips64el.h @@ -2945,6 +2945,7 @@ #define tcg_init tcg_init_mips64el #define tcg_invert_cond tcg_invert_cond_mips64el #define tcg_la_bb_end tcg_la_bb_end_mips64el +#define tcg_la_br_end tcg_la_br_end_mips64el #define tcg_la_func_end tcg_la_func_end_mips64el #define tcg_liveness_analysis tcg_liveness_analysis_mips64el #define tcg_malloc tcg_malloc_mips64el diff --git a/qemu/mipsel.h b/qemu/mipsel.h index 0def605f..26398a30 100644 --- a/qemu/mipsel.h +++ b/qemu/mipsel.h @@ -2945,6 +2945,7 @@ #define tcg_init tcg_init_mipsel #define tcg_invert_cond tcg_invert_cond_mipsel #define tcg_la_bb_end tcg_la_bb_end_mipsel +#define tcg_la_br_end tcg_la_br_end_mipsel #define tcg_la_func_end tcg_la_func_end_mipsel #define tcg_liveness_analysis tcg_liveness_analysis_mipsel #define tcg_malloc tcg_malloc_mipsel diff --git a/qemu/sparc.h b/qemu/sparc.h index 59a835f6..6a5cb27e 100644 --- a/qemu/sparc.h +++ b/qemu/sparc.h @@ -2945,6 +2945,7 @@ #define tcg_init tcg_init_sparc #define tcg_invert_cond tcg_invert_cond_sparc #define tcg_la_bb_end tcg_la_bb_end_sparc +#define tcg_la_br_end tcg_la_br_end_sparc #define tcg_la_func_end tcg_la_func_end_sparc #define tcg_liveness_analysis tcg_liveness_analysis_sparc #define tcg_malloc tcg_malloc_sparc diff --git a/qemu/sparc64.h b/qemu/sparc64.h index 043736b6..e67bbf00 100644 --- a/qemu/sparc64.h +++ b/qemu/sparc64.h @@ -2945,6 +2945,7 @@ #define tcg_init tcg_init_sparc64 #define tcg_invert_cond tcg_invert_cond_sparc64 #define tcg_la_bb_end tcg_la_bb_end_sparc64 +#define tcg_la_br_end tcg_la_br_end_sparc64 #define tcg_la_func_end tcg_la_func_end_sparc64 #define tcg_liveness_analysis tcg_liveness_analysis_sparc64 #define tcg_malloc tcg_malloc_sparc64 diff --git a/qemu/tcg/tcg.c b/qemu/tcg/tcg.c index abdcb9e4..c55878bc 100644 --- a/qemu/tcg/tcg.c +++ b/qemu/tcg/tcg.c @@ -1445,6 +1445,18 @@ static inline void tcg_la_bb_end(TCGContext *s, uint8_t *dead_temps, } } +/* + Unicorn: for brcond, we should refresh liveness states for TCG globals +*/ +static inline void tcg_la_br_end(TCGContext *s, uint8_t *mem_temps) +{ + int i; + memset(mem_temps, 1, s->nb_globals); + for(i = s->nb_globals; i < s->nb_temps; i++) { + mem_temps[i] = s->temps[i].temp_local; + } +} + /* Liveness analysis : update the opc_dead_args array to tell if a given input arguments is dead. Instructions updating dead temporaries are removed. */ @@ -1682,12 +1694,20 @@ static void tcg_liveness_analysis(TCGContext *s) } /* if end of basic block, update */ - if (def->flags & TCG_OPF_BB_END && op != INDEX_op_brcond_i32) { + if (def->flags & TCG_OPF_BB_END) { // Unicorn: do not optimize dead temps on brcond, // this causes problem because check_exit_request() inserts // brcond instruction in the middle of the TB, // which incorrectly flags end-of-block - tcg_la_bb_end(s, dead_temps, mem_temps); + if (op != INDEX_op_brcond_i32) + tcg_la_bb_end(s, dead_temps, mem_temps); + // Unicorn: we do not touch dead temps for brcond, + // but we should refresh TCG globals In-Memory states, + // otherwise, important CPU states(especially conditional flags) might be forgotten, + // result in wrongly generated host code that run into wrong branch. + // Refer to https://github.com/unicorn-engine/unicorn/issues/287 for further information + else + tcg_la_br_end(s, mem_temps); } else if (def->flags & TCG_OPF_SIDE_EFFECTS) { /* globals should be synced to memory */ memset(mem_temps, 1, s->nb_globals); diff --git a/qemu/x86_64.h b/qemu/x86_64.h index b2656541..57b72a98 100644 --- a/qemu/x86_64.h +++ b/qemu/x86_64.h @@ -2945,6 +2945,7 @@ #define tcg_init tcg_init_x86_64 #define tcg_invert_cond tcg_invert_cond_x86_64 #define tcg_la_bb_end tcg_la_bb_end_x86_64 +#define tcg_la_br_end tcg_la_br_end_x86_64 #define tcg_la_func_end tcg_la_func_end_x86_64 #define tcg_liveness_analysis tcg_liveness_analysis_x86_64 #define tcg_malloc tcg_malloc_x86_64