From b9ada873ecc0b86128169aae0bd7ad648c0f921b Mon Sep 17 00:00:00 2001 From: Shuntian Liu Date: Mon, 30 Aug 2021 18:56:10 +0000 Subject: [PATCH] i#2974 trace support for AArch64, part 7: Add translation info in fixup_indirect_trace_exit Added translation information when fixing up the indirect trace exits and added call to fixup_indirect_trace_exit when recreating the fragment ilist Issues: #1569, #2974 --- core/arch/interp.c | 49 ++++++++++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/core/arch/interp.c b/core/arch/interp.c index c5e31eddde0..d3ab325d573 100644 --- a/core/arch/interp.c +++ b/core/arch/interp.c @@ -5420,6 +5420,7 @@ recreate_fragment_ilist(dcontext_t *dcontext, byte *pc, instrlist_destroy(dcontext, bb); } + IF_AARCH64(fixup_indirect_trace_exit(dcontext, ilist)); /* PR 214962: re-apply client changes, this time storing translation * info for modified instrs */ @@ -8292,7 +8293,7 @@ d_r_emulate(dcontext_t *dcontext, app_pc pc, priv_mcontext_t *mc) int fixup_indirect_trace_exit(dcontext_t *dcontext, instrlist_t *trace) { - instr_t *instr, *prev, *branch; + instr_t *instr, *prev, *new_instr; instr_t *trace_exit_label; app_pc target = 0; app_pc ind_target = 0; @@ -8342,31 +8343,36 @@ fixup_indirect_trace_exit(dcontext_t *dcontext, instrlist_t *trace) /* Add the trace exit label. */ instrlist_append(trace, trace_exit_label); /* ldr x0, TLS_REG0_SLOT */ - instrlist_append( - trace, - instr_create_restore_from_tls(dcontext, scratch, TLS_REG0_SLOT)); + new_instr = + instr_create_restore_from_tls(dcontext, scratch, TLS_REG0_SLOT); + instr_set_translation(new_instr, instr_get_translation(instr)); + instrlist_append(trace, new_instr); added_size += AARCH64_INSTR_SIZE; /* if x2 alerady contains the jump_target, then there is no need to store * it away and load value of jump target into it */ if (jump_target_reg != IBL_TARGET_REG) { /* str x2, TLS_REG2_SLOT */ - instrlist_append(trace, - instr_create_save_to_tls(dcontext, IBL_TARGET_REG, - TLS_REG2_SLOT)); + new_instr = + instr_create_save_to_tls(dcontext, IBL_TARGET_REG, TLS_REG2_SLOT); + + instr_set_translation(new_instr, instr_get_translation(instr)); + instrlist_append(trace, new_instr); added_size += AARCH64_INSTR_SIZE; /* mov IBL_TARGET_REG, jump_target */ ASSERT(jump_target_reg != DR_REG_NULL); - instrlist_append(trace, - XINST_CREATE_move(dcontext, - opnd_create_reg(IBL_TARGET_REG), - opnd_create_reg(jump_target_reg))); + new_instr = + XINST_CREATE_move(dcontext, opnd_create_reg(IBL_TARGET_REG), + opnd_create_reg(jump_target_reg)); + instr_set_translation(new_instr, instr_get_translation(instr)); + instrlist_append(trace, new_instr); added_size += AARCH64_INSTR_SIZE; } /* b ibl_target */ - branch = XINST_CREATE_jump(dcontext, opnd_create_pc(ind_target)); - instr_exit_branch_set_type(branch, indirect_type); - instrlist_append(trace, branch); + new_instr = XINST_CREATE_jump(dcontext, opnd_create_pc(ind_target)); + instr_set_translation(new_instr, instr_get_translation(instr)); + instr_exit_branch_set_type(new_instr, indirect_type); + instrlist_append(trace, new_instr); added_size += AARCH64_INSTR_SIZE; } } else if ((instr->opcode == OP_cbz || instr->opcode == OP_cbnz || @@ -8376,7 +8382,6 @@ fixup_indirect_trace_exit(dcontext_t *dcontext, instrlist_t *trace) * only mangled instruction (by mangle_cbr_stolen_reg) reached here. */ - /* Next instruction should be a LDR_TLS_slot. */ instr_t *next = instr_get_next(instr); /* Get the actual target of the cbz/cbnz. */ @@ -8388,19 +8393,21 @@ fixup_indirect_trace_exit(dcontext_t *dcontext, instrlist_t *trace) instrlist_append(trace, trace_exit_label); /* ldr cbz_reg, TLS_REG0_SLOT */ reg_id_t mangled_reg = ((*(uint *)next->bytes) & 31) + DR_REG_START_GPR; - instrlist_append( - trace, - instr_create_restore_from_tls(dcontext, mangled_reg, TLS_REG0_SLOT)); + new_instr = + instr_create_restore_from_tls(dcontext, mangled_reg, TLS_REG0_SLOT); + instr_set_translation(new_instr, instr_get_translation(instr)); + instrlist_append(trace, new_instr); added_size += AARCH64_INSTR_SIZE; /* b fall_target */ - branch = XINST_CREATE_jump(dcontext, fall_target); - instrlist_append(trace, branch); + new_instr = XINST_CREATE_jump(dcontext, fall_target); + instr_set_translation(new_instr, instr_get_translation(instr)); + instrlist_append(trace, new_instr); added_size += AARCH64_INSTR_SIZE; /* Because of the jump, a new stub was created. * and it is possible that this jump is leaving the fragment * in which case we should not increase the size of the fragment */ - if (instr_is_exit_cti(branch)) { + if (instr_is_exit_cti(new_instr)) { added_size += DIRECT_EXIT_STUB_SIZE(0); } }