*/
#include "qemu/osdep.h"
-#include "qemu-common.h"
#include "qemu/error-report.h"
#include "cpu.h"
#include "tcg/tcg.h"
#include "exec/gen-icount.h"
#include "exec/log.h"
#include "exec/translator.h"
+#include "exec/plugin-gen.h"
/* Pairs with tcg_clear_temp_count.
To be called by #TranslatorOps.{translate_insn,tb_stop} if
CPUState *cpu, TranslationBlock *tb, int max_insns)
{
int bp_insn = 0;
+ bool plugin_enabled;
/* Initialize DisasContext */
db->tb = tb;
ops->tb_start(db, cpu);
tcg_debug_assert(db->is_jmp == DISAS_NEXT); /* no early exit */
+ plugin_enabled = plugin_gen_tb_start(cpu, tb);
+
while (true) {
db->num_insns++;
ops->insn_start(db, cpu);
tcg_debug_assert(db->is_jmp == DISAS_NEXT); /* no early exit */
+ if (plugin_enabled) {
+ plugin_gen_insn_start(cpu, db);
+ }
+
/* Pass breakpoint hits to target for further processing */
if (!db->singlestep_enabled
&& unlikely(!QTAILQ_EMPTY(&cpu->breakpoints))) {
/* Accept I/O on the last instruction. */
gen_io_start();
ops->translate_insn(db, cpu);
- gen_io_end();
} else {
ops->translate_insn(db, cpu);
}
break;
}
+ /*
+ * We can't instrument after instructions that change control
+ * flow although this only really affects post-load operations.
+ */
+ if (plugin_enabled) {
+ plugin_gen_insn_end();
+ }
+
/* Stop translation if the output buffer is full,
or we have executed all of the allowed instructions. */
if (tcg_op_buf_full() || db->num_insns >= db->max_insns) {
ops->tb_stop(db, cpu);
gen_tb_end(db->tb, db->num_insns - bp_insn);
+ if (plugin_enabled) {
+ plugin_gen_tb_end(cpu);
+ }
+
/* The disas_log hook may use these values rather than recompute. */
db->tb->size = db->pc_next - db->pc_first;
db->tb->icount = db->num_insns;