target/s390x: fake instruction loading when handling 'ex'
The s390x EXecute instruction is a bit weird as we synthesis the executed instruction from what we have stored in memory. This missed the plugin instrumentation. Work around this with a special helper to inform the rest of the translator about the instruction so things stay consistent. Reviewed-by: David Hildenbrand <david@redhat.com> Acked-by: Ilya Leoshkevich <iii@linux.ibm.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Alex Bennée <alex.bennee@linaro.org> Cc: Richard Henderson <richard.henderson@linaro.org> Message-Id: <20221027183637.2772968-26-alex.bennee@linaro.org>
This commit is contained in:
parent
621aab6c7d
commit
9fa97e04ae
@ -211,6 +211,23 @@ translator_ldq_swap(CPUArchState *env, DisasContextBase *db,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* translator_fake_ldb - fake instruction load
|
||||
* @insn8: byte of instruction
|
||||
* @pc: program counter of instruction
|
||||
*
|
||||
* This is a special case helper used where the instruction we are
|
||||
* about to translate comes from somewhere else (e.g. being
|
||||
* re-synthesised for s390x "ex"). It ensures we update other areas of
|
||||
* the translator with details of the executed instruction.
|
||||
*/
|
||||
|
||||
static inline void translator_fake_ldb(uint8_t insn8, abi_ptr pc)
|
||||
{
|
||||
plugin_insn_append(pc, &insn8, sizeof(insn8));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return whether addr is on the same page as where disassembly started.
|
||||
* Translators can use this to enforce the rule that only single-insn
|
||||
|
@ -6317,12 +6317,18 @@ static const DisasInsn *extract_insn(CPUS390XState *env, DisasContext *s)
|
||||
if (unlikely(s->ex_value)) {
|
||||
/* Drop the EX data now, so that it's clear on exception paths. */
|
||||
TCGv_i64 zero = tcg_const_i64(0);
|
||||
int i;
|
||||
tcg_gen_st_i64(zero, cpu_env, offsetof(CPUS390XState, ex_value));
|
||||
tcg_temp_free_i64(zero);
|
||||
|
||||
/* Extract the values saved by EXECUTE. */
|
||||
insn = s->ex_value & 0xffffffffffff0000ull;
|
||||
ilen = s->ex_value & 0xf;
|
||||
/* register insn bytes with translator so plugins work */
|
||||
for (i = 0; i < ilen; i++) {
|
||||
uint8_t byte = extract64(insn, 56 - (i * 8), 8);
|
||||
translator_fake_ldb(byte, pc + i);
|
||||
}
|
||||
op = insn >> 56;
|
||||
} else {
|
||||
insn = ld_code2(env, s, pc);
|
||||
|
Loading…
Reference in New Issue
Block a user