Skip to content

Commit

Permalink
i#2974 trace support for AArch64, part 7: Add translation info in
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Vincent-lau committed Aug 30, 2021
1 parent e6d9fd6 commit b9ada87
Showing 1 changed file with 28 additions and 21 deletions.
49 changes: 28 additions & 21 deletions core/arch/interp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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 ||
Expand All @@ -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. */
Expand All @@ -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);
}
}
Expand Down

0 comments on commit b9ada87

Please sign in to comment.