/*
 * plugin-gen.c - TCG-related bits of plugin infrastructure
 *
 * Copyright (C) 2018, Emilio G. Cota <cota@braap.org>
 * License: GNU GPL, version 2 or later.
 *   See the COPYING file in the top-level directory.
 *
 * We support instrumentation at an instruction granularity. That is,
 * if a plugin wants to instrument the memory accesses performed by a
 * particular instruction, it can just do that instead of instrumenting
 * all memory accesses. Thus, in order to do this we first have to
 * translate a TB, so that plugins can decide what/where to instrument.
 *
 * Injecting the desired instrumentation could be done with a second
 * translation pass that combined the instrumentation requests, but that
 * would be ugly and inefficient since we would decode the guest code twice.
 * Instead, during TB translation we add "empty" instrumentation calls for all
 * possible instrumentation events, and then once we collect the instrumentation
 * requests from plugins, we either "fill in" those empty events or remove them
 * if they have no requests.
 *
 * When "filling in" an event we first copy the empty callback's TCG ops. This
 * might seem unnecessary, but it is done to support an arbitrary number
 * of callbacks per event. Take for example a regular instruction callback.
 * We first generate a callback to an empty helper function. Then, if two
 * plugins register one callback each for this instruction, we make two copies
 * of the TCG ops generated for the empty callback, substituting the function
 * pointer that points to the empty helper function with the plugins' desired
 * callback functions. After that we remove the empty callback's ops.
 *
 * Note that the location in TCGOp.args[] of the pointer to a helper function
 * varies across different guest and host architectures. Instead of duplicating
 * the logic that figures this out, we rely on the fact that the empty
 * callbacks point to empty functions that are unique pointers in the program.
 * Thus, to find the right location we just have to look for a match in
 * TCGOp.args[]. This is the main reason why we first copy an empty callback's
 * TCG ops and then fill them in; regardless of whether we have one or many
 * callbacks for that event, the logic to add all of them is the same.
 *
 * When generating more than one callback per event, we make a small
 * optimization to avoid generating redundant operations. For instance, for the
 * second and all subsequent callbacks of an event, we do not need to reload the
 * CPU's index into a TCG temp, since the first callback did it already.
 */
#include "qemu/osdep.h"
#include "cpu.h"
#include "tcg/tcg.h"
#include "tcg/tcg-op.h"
#include "trace/mem.h"
#include "exec/exec-all.h"
#include "exec/plugin-gen.h"
#include "exec/translator.h"

#ifdef CONFIG_SOFTMMU
# define CONFIG_SOFTMMU_GATE 1
#else
# define CONFIG_SOFTMMU_GATE 0
#endif

/*
 * plugin_cb_start TCG op args[]:
 * 0: enum plugin_gen_from
 * 1: enum plugin_gen_cb
 * 2: set to 1 for mem callback that is a write, 0 otherwise.
 */

enum plugin_gen_from {
    PLUGIN_GEN_FROM_TB,
    PLUGIN_GEN_FROM_INSN,
    PLUGIN_GEN_FROM_MEM,
    PLUGIN_GEN_AFTER_INSN,
    PLUGIN_GEN_N_FROMS,
};

enum plugin_gen_cb {
    PLUGIN_GEN_CB_UDATA,
    PLUGIN_GEN_CB_INLINE,
    PLUGIN_GEN_CB_MEM,
    PLUGIN_GEN_ENABLE_MEM_HELPER,
    PLUGIN_GEN_DISABLE_MEM_HELPER,
    PLUGIN_GEN_N_CBS,
};

/*
 * These helpers are stubs that get dynamically switched out for calls
 * direct to the plugin if they are subscribed to.
 */
void HELPER(plugin_vcpu_udata_cb)(uint32_t cpu_index, void *udata)
{ }

void HELPER(plugin_vcpu_mem_cb)(unsigned int vcpu_index,
                                qemu_plugin_meminfo_t info, uint64_t vaddr,
                                void *userdata)
{ }

static void do_gen_mem_cb(TCGv vaddr, uint32_t info)
{
    TCGv_i32 cpu_index = tcg_temp_new_i32();
    TCGv_i32 meminfo = tcg_const_i32(info);
    TCGv_i64 vaddr64 = tcg_temp_new_i64();
    TCGv_ptr udata = tcg_const_ptr(NULL);

    tcg_gen_ld_i32(cpu_index, cpu_env,
                   -offsetof(ArchCPU, env) + offsetof(CPUState, cpu_index));
    tcg_gen_extu_tl_i64(vaddr64, vaddr);

    gen_helper_plugin_vcpu_mem_cb(cpu_index, meminfo, vaddr64, udata);

    tcg_temp_free_ptr(udata);
    tcg_temp_free_i64(vaddr64);
    tcg_temp_free_i32(meminfo);
    tcg_temp_free_i32(cpu_index);
}

static void gen_empty_udata_cb(void)
{
    TCGv_i32 cpu_index = tcg_temp_new_i32();
    TCGv_ptr udata = tcg_const_ptr(NULL); /* will be overwritten later */

    tcg_gen_ld_i32(cpu_index, cpu_env,
                   -offsetof(ArchCPU, env) + offsetof(CPUState, cpu_index));
    gen_helper_plugin_vcpu_udata_cb(cpu_index, udata);

    tcg_temp_free_ptr(udata);
    tcg_temp_free_i32(cpu_index);
}

/*
 * For now we only support addi_i64.
 * When we support more ops, we can generate one empty inline cb for each.
 */
static void gen_empty_inline_cb(void)
{
    TCGv_i64 val = tcg_temp_new_i64();
    TCGv_ptr ptr = tcg_const_ptr(NULL); /* overwritten later */

    tcg_gen_ld_i64(val, ptr, 0);
    /* pass an immediate != 0 so that it doesn't get optimized away */
    tcg_gen_addi_i64(val, val, 0xdeadface);
    tcg_gen_st_i64(val, ptr, 0);
    tcg_temp_free_ptr(ptr);
    tcg_temp_free_i64(val);
}

static void gen_empty_mem_cb(TCGv addr, uint32_t info)
{
    do_gen_mem_cb(addr, info);
}

/*
 * Share the same function for enable/disable. When enabling, the NULL
 * pointer will be overwritten later.
 */
static void gen_empty_mem_helper(void)
{
    TCGv_ptr ptr;

    ptr = tcg_const_ptr(NULL);
    tcg_gen_st_ptr(ptr, cpu_env, offsetof(CPUState, plugin_mem_cbs) -
                                 offsetof(ArchCPU, env));
    tcg_temp_free_ptr(ptr);
}

static inline
void gen_plugin_cb_start(enum plugin_gen_from from,
                         enum plugin_gen_cb type, unsigned wr)
{
    TCGOp *op;

    tcg_gen_plugin_cb_start(from, type, wr);
    op = tcg_last_op();
    QSIMPLEQ_INSERT_TAIL(&tcg_ctx->plugin_ops, op, plugin_link);
}

static void gen_wrapped(enum plugin_gen_from from,
                        enum plugin_gen_cb type, void (*func)(void))
{
    gen_plugin_cb_start(from, type, 0);
    func();
    tcg_gen_plugin_cb_end();
}

static inline void plugin_gen_empty_callback(enum plugin_gen_from from)
{
    switch (from) {
    case PLUGIN_GEN_AFTER_INSN:
        gen_wrapped(from, PLUGIN_GEN_DISABLE_MEM_HELPER,
                    gen_empty_mem_helper);
        break;
    case PLUGIN_GEN_FROM_INSN:
        /*
         * Note: plugin_gen_inject() relies on ENABLE_MEM_HELPER being
         * the first callback of an instruction
         */
        gen_wrapped(from, PLUGIN_GEN_ENABLE_MEM_HELPER,
                    gen_empty_mem_helper);
        /* fall through */
    case PLUGIN_GEN_FROM_TB:
        gen_wrapped(from, PLUGIN_GEN_CB_UDATA, gen_empty_udata_cb);
        gen_wrapped(from, PLUGIN_GEN_CB_INLINE, gen_empty_inline_cb);
        break;
    default:
        g_assert_not_reached();
    }
}

union mem_gen_fn {
    void (*mem_fn)(TCGv, uint32_t);
    void (*inline_fn)(void);
};

static void gen_mem_wrapped(enum plugin_gen_cb type,
                            const union mem_gen_fn *f, TCGv addr,
                            uint32_t info, bool is_mem)
{
    int wr = !!(info & TRACE_MEM_ST);

    gen_plugin_cb_start(PLUGIN_GEN_FROM_MEM, type, wr);
    if (is_mem) {
        f->mem_fn(addr, info);
    } else {
        f->inline_fn();
    }
    tcg_gen_plugin_cb_end();
}

void plugin_gen_empty_mem_callback(TCGv addr, uint32_t info)
{
    union mem_gen_fn fn;

    fn.mem_fn = gen_empty_mem_cb;
    gen_mem_wrapped(PLUGIN_GEN_CB_MEM, &fn, addr, info, true);

    fn.inline_fn = gen_empty_inline_cb;
    gen_mem_wrapped(PLUGIN_GEN_CB_INLINE, &fn, 0, info, false);
}

static TCGOp *find_op(TCGOp *op, TCGOpcode opc)
{
    while (op) {
        if (op->opc == opc) {
            return op;
        }
        op = QTAILQ_NEXT(op, link);
    }
    return NULL;
}

static TCGOp *rm_ops_range(TCGOp *begin, TCGOp *end)
{
    TCGOp *ret = QTAILQ_NEXT(end, link);

    QTAILQ_REMOVE_SEVERAL(&tcg_ctx->ops, begin, end, link);
    return ret;
}

/* remove all ops until (and including) plugin_cb_end */
static TCGOp *rm_ops(TCGOp *op)
{
    TCGOp *end_op = find_op(op, INDEX_op_plugin_cb_end);

    tcg_debug_assert(end_op);
    return rm_ops_range(op, end_op);
}

static TCGOp *copy_op_nocheck(TCGOp **begin_op, TCGOp *op)
{
    *begin_op = QTAILQ_NEXT(*begin_op, link);
    tcg_debug_assert(*begin_op);
    op = tcg_op_insert_after(tcg_ctx, op, (*begin_op)->opc);
    memcpy(op->args, (*begin_op)->args, sizeof(op->args));
    return op;
}

static TCGOp *copy_op(TCGOp **begin_op, TCGOp *op, TCGOpcode opc)
{
    op = copy_op_nocheck(begin_op, op);
    tcg_debug_assert((*begin_op)->opc == opc);
    return op;
}

static TCGOp *copy_extu_i32_i64(TCGOp **begin_op, TCGOp *op)
{
    if (TCG_TARGET_REG_BITS == 32) {
        /* mov_i32 */
        op = copy_op(begin_op, op, INDEX_op_mov_i32);
        /* mov_i32 w/ $0 */
        op = copy_op(begin_op, op, INDEX_op_mov_i32);
    } else {
        /* extu_i32_i64 */
        op = copy_op(begin_op, op, INDEX_op_extu_i32_i64);
    }
    return op;
}

static TCGOp *copy_mov_i64(TCGOp **begin_op, TCGOp *op)
{
    if (TCG_TARGET_REG_BITS == 32) {
        /* 2x mov_i32 */
        op = copy_op(begin_op, op, INDEX_op_mov_i32);
        op = copy_op(begin_op, op, INDEX_op_mov_i32);
    } else {
        /* mov_i64 */
        op = copy_op(begin_op, op, INDEX_op_mov_i64);
    }
    return op;
}

static TCGOp *copy_const_ptr(TCGOp **begin_op, TCGOp *op, void *ptr)
{
    if (UINTPTR_MAX == UINT32_MAX) {
        /* mov_i32 */
        op = copy_op(begin_op, op, INDEX_op_mov_i32);
        op->args[1] = tcgv_i32_arg(tcg_constant_i32((uintptr_t)ptr));
    } else {
        /* mov_i64 */
        op = copy_op(begin_op, op, INDEX_op_mov_i64);
        op->args[1] = tcgv_i64_arg(tcg_constant_i64((uintptr_t)ptr));
    }
    return op;
}

static TCGOp *copy_extu_tl_i64(TCGOp **begin_op, TCGOp *op)
{
    if (TARGET_LONG_BITS == 32) {
        /* extu_i32_i64 */
        op = copy_extu_i32_i64(begin_op, op);
    } else {
        /* mov_i64 */
        op = copy_mov_i64(begin_op, op);
    }
    return op;
}

static TCGOp *copy_ld_i64(TCGOp **begin_op, TCGOp *op)
{
    if (TCG_TARGET_REG_BITS == 32) {
        /* 2x ld_i32 */
        op = copy_op(begin_op, op, INDEX_op_ld_i32);
        op = copy_op(begin_op, op, INDEX_op_ld_i32);
    } else {
        /* ld_i64 */
        op = copy_op(begin_op, op, INDEX_op_ld_i64);
    }
    return op;
}

static TCGOp *copy_st_i64(TCGOp **begin_op, TCGOp *op)
{
    if (TCG_TARGET_REG_BITS == 32) {
        /* 2x st_i32 */
        op = copy_op(begin_op, op, INDEX_op_st_i32);
        op = copy_op(begin_op, op, INDEX_op_st_i32);
    } else {
        /* st_i64 */
        op = copy_op(begin_op, op, INDEX_op_st_i64);
    }
    return op;
}

static TCGOp *copy_add_i64(TCGOp **begin_op, TCGOp *op, uint64_t v)
{
    if (TCG_TARGET_REG_BITS == 32) {
        /* all 32-bit backends must implement add2_i32 */
        g_assert(TCG_TARGET_HAS_add2_i32);
        op = copy_op(begin_op, op, INDEX_op_add2_i32);
        op->args[4] = tcgv_i32_arg(tcg_constant_i32(v));
        op->args[5] = tcgv_i32_arg(tcg_constant_i32(v >> 32));
    } else {
        op = copy_op(begin_op, op, INDEX_op_add_i64);
        op->args[2] = tcgv_i64_arg(tcg_constant_i64(v));
    }
    return op;
}

static TCGOp *copy_st_ptr(TCGOp **begin_op, TCGOp *op)
{
    if (UINTPTR_MAX == UINT32_MAX) {
        /* st_i32 */
        op = copy_op(begin_op, op, INDEX_op_st_i32);
    } else {
        /* st_i64 */
        op = copy_st_i64(begin_op, op);
    }
    return op;
}

static TCGOp *copy_call(TCGOp **begin_op, TCGOp *op, void *empty_func,
                        void *func, unsigned tcg_flags, int *cb_idx)
{
    /* copy all ops until the call */
    do {
        op = copy_op_nocheck(begin_op, op);
    } while (op->opc != INDEX_op_call);

    /* fill in the op call */
    op->param1 = (*begin_op)->param1;
    op->param2 = (*begin_op)->param2;
    tcg_debug_assert(op->life == 0);
    if (*cb_idx == -1) {
        int i;

        /*
         * Instead of working out the position of the callback in args[], just
         * look for @empty_func, since it should be a unique pointer.
         */
        for (i = 0; i < MAX_OPC_PARAM_ARGS; i++) {
            if ((uintptr_t)(*begin_op)->args[i] == (uintptr_t)empty_func) {
                *cb_idx = i;
                break;
            }
        }
        tcg_debug_assert(i < MAX_OPC_PARAM_ARGS);
    }
    op->args[*cb_idx] = (uintptr_t)func;
    op->args[*cb_idx + 1] = tcg_flags;

    return op;
}

/*
 * When we append/replace ops here we are sensitive to changing patterns of
 * TCGOps generated by the tcg_gen_FOO calls when we generated the
 * empty callbacks. This will assert very quickly in a debug build as
 * we assert the ops we are replacing are the correct ones.
 */
static TCGOp *append_udata_cb(const struct qemu_plugin_dyn_cb *cb,
                              TCGOp *begin_op, TCGOp *op, int *cb_idx)
{
    /* const_ptr */
    op = copy_const_ptr(&begin_op, op, cb->userp);

    /* copy the ld_i32, but note that we only have to copy it once */
    begin_op = QTAILQ_NEXT(begin_op, link);
    tcg_debug_assert(begin_op && begin_op->opc == INDEX_op_ld_i32);
    if (*cb_idx == -1) {
        op = tcg_op_insert_after(tcg_ctx, op, INDEX_op_ld_i32);
        memcpy(op->args, begin_op->args, sizeof(op->args));
    }

    /* call */
    op = copy_call(&begin_op, op, HELPER(plugin_vcpu_udata_cb),
                   cb->f.vcpu_udata, cb->tcg_flags, cb_idx);

    return op;
}

static TCGOp *append_inline_cb(const struct qemu_plugin_dyn_cb *cb,
                               TCGOp *begin_op, TCGOp *op,
                               int *unused)
{
    /* const_ptr */
    op = copy_const_ptr(&begin_op, op, cb->userp);

    /* ld_i64 */
    op = copy_ld_i64(&begin_op, op);

    /* add_i64 */
    op = copy_add_i64(&begin_op, op, cb->inline_insn.imm);

    /* st_i64 */
    op = copy_st_i64(&begin_op, op);

    return op;
}

static TCGOp *append_mem_cb(const struct qemu_plugin_dyn_cb *cb,
                            TCGOp *begin_op, TCGOp *op, int *cb_idx)
{
    enum plugin_gen_cb type = begin_op->args[1];

    tcg_debug_assert(type == PLUGIN_GEN_CB_MEM);

    /* const_i32 == mov_i32 ("info", so it remains as is) */
    op = copy_op(&begin_op, op, INDEX_op_mov_i32);

    /* const_ptr */
    op = copy_const_ptr(&begin_op, op, cb->userp);

    /* copy the ld_i32, but note that we only have to copy it once */
    begin_op = QTAILQ_NEXT(begin_op, link);
    tcg_debug_assert(begin_op && begin_op->opc == INDEX_op_ld_i32);
    if (*cb_idx == -1) {
        op = tcg_op_insert_after(tcg_ctx, op, INDEX_op_ld_i32);
        memcpy(op->args, begin_op->args, sizeof(op->args));
    }

    /* extu_tl_i64 */
    op = copy_extu_tl_i64(&begin_op, op);

    if (type == PLUGIN_GEN_CB_MEM) {
        /* call */
        op = copy_call(&begin_op, op, HELPER(plugin_vcpu_mem_cb),
                       cb->f.vcpu_udata, cb->tcg_flags, cb_idx);
    }

    return op;
}

typedef TCGOp *(*inject_fn)(const struct qemu_plugin_dyn_cb *cb,
                            TCGOp *begin_op, TCGOp *op, int *intp);
typedef bool (*op_ok_fn)(const TCGOp *op, const struct qemu_plugin_dyn_cb *cb);

static bool op_ok(const TCGOp *op, const struct qemu_plugin_dyn_cb *cb)
{
    return true;
}

static bool op_rw(const TCGOp *op, const struct qemu_plugin_dyn_cb *cb)
{
    int w;

    w = op->args[2];
    return !!(cb->rw & (w + 1));
}

static inline
void inject_cb_type(const GArray *cbs, TCGOp *begin_op, inject_fn inject,
                    op_ok_fn ok)
{
    TCGOp *end_op;
    TCGOp *op;
    int cb_idx = -1;
    int i;

    if (!cbs || cbs->len == 0) {
        rm_ops(begin_op);
        return;
    }

    end_op = find_op(begin_op, INDEX_op_plugin_cb_end);
    tcg_debug_assert(end_op);

    op = end_op;
    for (i = 0; i < cbs->len; i++) {
        struct qemu_plugin_dyn_cb *cb =
            &g_array_index(cbs, struct qemu_plugin_dyn_cb, i);

        if (!ok(begin_op, cb)) {
            continue;
        }
        op = inject(cb, begin_op, op, &cb_idx);
    }
    rm_ops_range(begin_op, end_op);
}

static void
inject_udata_cb(const GArray *cbs, TCGOp *begin_op)
{
    inject_cb_type(cbs, begin_op, append_udata_cb, op_ok);
}

static void
inject_inline_cb(const GArray *cbs, TCGOp *begin_op, op_ok_fn ok)
{
    inject_cb_type(cbs, begin_op, append_inline_cb, ok);
}

static void
inject_mem_cb(const GArray *cbs, TCGOp *begin_op)
{
    inject_cb_type(cbs, begin_op, append_mem_cb, op_rw);
}

/* we could change the ops in place, but we can reuse more code by copying */
static void inject_mem_helper(TCGOp *begin_op, GArray *arr)
{
    TCGOp *orig_op = begin_op;
    TCGOp *end_op;
    TCGOp *op;

    end_op = find_op(begin_op, INDEX_op_plugin_cb_end);
    tcg_debug_assert(end_op);

    /* const ptr */
    op = copy_const_ptr(&begin_op, end_op, arr);

    /* st_ptr */
    op = copy_st_ptr(&begin_op, op);

    rm_ops_range(orig_op, end_op);
}

/*
 * Tracking memory accesses performed from helpers requires extra work.
 * If an instruction is emulated with helpers, we do two things:
 * (1) copy the CB descriptors, and keep track of it so that they can be
 * freed later on, and (2) point CPUState.plugin_mem_cbs to the descriptors, so
 * that we can read them at run-time (i.e. when the helper executes).
 * This run-time access is performed from qemu_plugin_vcpu_mem_cb.
 *
 * Note that plugin_gen_disable_mem_helpers undoes (2). Since it
 * is possible that the code we generate after the instruction is
 * dead, we also add checks before generating tb_exit etc.
 */
static void inject_mem_enable_helper(struct qemu_plugin_insn *plugin_insn,
                                     TCGOp *begin_op)
{
    GArray *cbs[2];
    GArray *arr;
    size_t n_cbs, i;

    cbs[0] = plugin_insn->cbs[PLUGIN_CB_MEM][PLUGIN_CB_REGULAR];
    cbs[1] = plugin_insn->cbs[PLUGIN_CB_MEM][PLUGIN_CB_INLINE];

    n_cbs = 0;
    for (i = 0; i < ARRAY_SIZE(cbs); i++) {
        n_cbs += cbs[i]->len;
    }

    plugin_insn->mem_helper = plugin_insn->calls_helpers && n_cbs;
    if (likely(!plugin_insn->mem_helper)) {
        rm_ops(begin_op);
        return;
    }

    arr = g_array_sized_new(false, false,
                            sizeof(struct qemu_plugin_dyn_cb), n_cbs);

    for (i = 0; i < ARRAY_SIZE(cbs); i++) {
        g_array_append_vals(arr, cbs[i]->data, cbs[i]->len);
    }

    qemu_plugin_add_dyn_cb_arr(arr);
    inject_mem_helper(begin_op, arr);
}

static void inject_mem_disable_helper(struct qemu_plugin_insn *plugin_insn,
                                      TCGOp *begin_op)
{
    if (likely(!plugin_insn->mem_helper)) {
        rm_ops(begin_op);
        return;
    }
    inject_mem_helper(begin_op, NULL);
}

/* called before finishing a TB with exit_tb, goto_tb or goto_ptr */
void plugin_gen_disable_mem_helpers(void)
{
    TCGv_ptr ptr;

    if (likely(tcg_ctx->plugin_insn == NULL ||
               !tcg_ctx->plugin_insn->mem_helper)) {
        return;
    }
    ptr = tcg_const_ptr(NULL);
    tcg_gen_st_ptr(ptr, cpu_env, offsetof(CPUState, plugin_mem_cbs) -
                                 offsetof(ArchCPU, env));
    tcg_temp_free_ptr(ptr);
    tcg_ctx->plugin_insn->mem_helper = false;
}

static void plugin_gen_tb_udata(const struct qemu_plugin_tb *ptb,
                                TCGOp *begin_op)
{
    inject_udata_cb(ptb->cbs[PLUGIN_CB_REGULAR], begin_op);
}

static void plugin_gen_tb_inline(const struct qemu_plugin_tb *ptb,
                                 TCGOp *begin_op)
{
    inject_inline_cb(ptb->cbs[PLUGIN_CB_INLINE], begin_op, op_ok);
}

static void plugin_gen_insn_udata(const struct qemu_plugin_tb *ptb,
                                  TCGOp *begin_op, int insn_idx)
{
    struct qemu_plugin_insn *insn = g_ptr_array_index(ptb->insns, insn_idx);

    inject_udata_cb(insn->cbs[PLUGIN_CB_INSN][PLUGIN_CB_REGULAR], begin_op);
}

static void plugin_gen_insn_inline(const struct qemu_plugin_tb *ptb,
                                   TCGOp *begin_op, int insn_idx)
{
    struct qemu_plugin_insn *insn = g_ptr_array_index(ptb->insns, insn_idx);
    inject_inline_cb(insn->cbs[PLUGIN_CB_INSN][PLUGIN_CB_INLINE],
                     begin_op, op_ok);
}

static void plugin_gen_mem_regular(const struct qemu_plugin_tb *ptb,
                                   TCGOp *begin_op, int insn_idx)
{
    struct qemu_plugin_insn *insn = g_ptr_array_index(ptb->insns, insn_idx);
    inject_mem_cb(insn->cbs[PLUGIN_CB_MEM][PLUGIN_CB_REGULAR], begin_op);
}

static void plugin_gen_mem_inline(const struct qemu_plugin_tb *ptb,
                                  TCGOp *begin_op, int insn_idx)
{
    const GArray *cbs;
    struct qemu_plugin_insn *insn = g_ptr_array_index(ptb->insns, insn_idx);

    cbs = insn->cbs[PLUGIN_CB_MEM][PLUGIN_CB_INLINE];
    inject_inline_cb(cbs, begin_op, op_rw);
}

static void plugin_gen_enable_mem_helper(const struct qemu_plugin_tb *ptb,
                                         TCGOp *begin_op, int insn_idx)
{
    struct qemu_plugin_insn *insn = g_ptr_array_index(ptb->insns, insn_idx);
    inject_mem_enable_helper(insn, begin_op);
}

static void plugin_gen_disable_mem_helper(const struct qemu_plugin_tb *ptb,
                                          TCGOp *begin_op, int insn_idx)
{
    struct qemu_plugin_insn *insn = g_ptr_array_index(ptb->insns, insn_idx);
    inject_mem_disable_helper(insn, begin_op);
}

static void plugin_inject_cb(const struct qemu_plugin_tb *ptb, TCGOp *begin_op,
                             int insn_idx)
{
    enum plugin_gen_from from = begin_op->args[0];
    enum plugin_gen_cb type = begin_op->args[1];

    switch (from) {
    case PLUGIN_GEN_FROM_TB:
        switch (type) {
        case PLUGIN_GEN_CB_UDATA:
            plugin_gen_tb_udata(ptb, begin_op);
            return;
        case PLUGIN_GEN_CB_INLINE:
            plugin_gen_tb_inline(ptb, begin_op);
            return;
        default:
            g_assert_not_reached();
        }
    case PLUGIN_GEN_FROM_INSN:
        switch (type) {
        case PLUGIN_GEN_CB_UDATA:
            plugin_gen_insn_udata(ptb, begin_op, insn_idx);
            return;
        case PLUGIN_GEN_CB_INLINE:
            plugin_gen_insn_inline(ptb, begin_op, insn_idx);
            return;
        case PLUGIN_GEN_ENABLE_MEM_HELPER:
            plugin_gen_enable_mem_helper(ptb, begin_op, insn_idx);
            return;
        default:
            g_assert_not_reached();
        }
    case PLUGIN_GEN_FROM_MEM:
        switch (type) {
        case PLUGIN_GEN_CB_MEM:
            plugin_gen_mem_regular(ptb, begin_op, insn_idx);
            return;
        case PLUGIN_GEN_CB_INLINE:
            plugin_gen_mem_inline(ptb, begin_op, insn_idx);
            return;
        default:
            g_assert_not_reached();
        }
    case PLUGIN_GEN_AFTER_INSN:
        switch (type) {
        case PLUGIN_GEN_DISABLE_MEM_HELPER:
            plugin_gen_disable_mem_helper(ptb, begin_op, insn_idx);
            return;
        default:
            g_assert_not_reached();
        }
    default:
        g_assert_not_reached();
    }
}

/* #define DEBUG_PLUGIN_GEN_OPS */
static void pr_ops(void)
{
#ifdef DEBUG_PLUGIN_GEN_OPS
    TCGOp *op;
    int i = 0;

    QTAILQ_FOREACH(op, &tcg_ctx->ops, link) {
        const char *name = "";
        const char *type = "";

        if (op->opc == INDEX_op_plugin_cb_start) {
            switch (op->args[0]) {
            case PLUGIN_GEN_FROM_TB:
                name = "tb";
                break;
            case PLUGIN_GEN_FROM_INSN:
                name = "insn";
                break;
            case PLUGIN_GEN_FROM_MEM:
                name = "mem";
                break;
            case PLUGIN_GEN_AFTER_INSN:
                name = "after insn";
                break;
            default:
                break;
            }
            switch (op->args[1]) {
            case PLUGIN_GEN_CB_UDATA:
                type = "udata";
                break;
            case PLUGIN_GEN_CB_INLINE:
                type = "inline";
                break;
            case PLUGIN_GEN_CB_MEM:
                type = "mem";
                break;
            case PLUGIN_GEN_ENABLE_MEM_HELPER:
                type = "enable mem helper";
                break;
            case PLUGIN_GEN_DISABLE_MEM_HELPER:
                type = "disable mem helper";
                break;
            default:
                break;
            }
        }
        printf("op[%2i]: %s %s %s\n", i, tcg_op_defs[op->opc].name, name, type);
        i++;
    }
#endif
}

static void plugin_gen_inject(const struct qemu_plugin_tb *plugin_tb)
{
    TCGOp *op;
    int insn_idx;

    pr_ops();
    insn_idx = -1;
    QSIMPLEQ_FOREACH(op, &tcg_ctx->plugin_ops, plugin_link) {
        enum plugin_gen_from from = op->args[0];
        enum plugin_gen_cb type = op->args[1];

        tcg_debug_assert(op->opc == INDEX_op_plugin_cb_start);
        /* ENABLE_MEM_HELPER is the first callback of an instruction */
        if (from == PLUGIN_GEN_FROM_INSN &&
            type == PLUGIN_GEN_ENABLE_MEM_HELPER) {
            insn_idx++;
        }
        plugin_inject_cb(plugin_tb, op, insn_idx);
    }
    pr_ops();
}

bool plugin_gen_tb_start(CPUState *cpu, const TranslationBlock *tb, bool mem_only)
{
    struct qemu_plugin_tb *ptb = tcg_ctx->plugin_tb;
    bool ret = false;

    if (test_bit(QEMU_PLUGIN_EV_VCPU_TB_TRANS, cpu->plugin_mask)) {
        ret = true;

        QSIMPLEQ_INIT(&tcg_ctx->plugin_ops);
        ptb->vaddr = tb->pc;
        ptb->vaddr2 = -1;
        get_page_addr_code_hostp(cpu->env_ptr, tb->pc, &ptb->haddr1);
        ptb->haddr2 = NULL;
        ptb->mem_only = mem_only;

        plugin_gen_empty_callback(PLUGIN_GEN_FROM_TB);
    }
    return ret;
}

void plugin_gen_insn_start(CPUState *cpu, const DisasContextBase *db)
{
    struct qemu_plugin_tb *ptb = tcg_ctx->plugin_tb;
    struct qemu_plugin_insn *pinsn;

    pinsn = qemu_plugin_tb_insn_get(ptb);
    tcg_ctx->plugin_insn = pinsn;
    pinsn->vaddr = db->pc_next;
    plugin_gen_empty_callback(PLUGIN_GEN_FROM_INSN);

    /*
     * Detect page crossing to get the new host address.
     * Note that we skip this when haddr1 == NULL, e.g. when we're
     * fetching instructions from a region not backed by RAM.
     */
    if (likely(ptb->haddr1 != NULL && ptb->vaddr2 == -1) &&
        unlikely((db->pc_next & TARGET_PAGE_MASK) !=
                 (db->pc_first & TARGET_PAGE_MASK))) {
        get_page_addr_code_hostp(cpu->env_ptr, db->pc_next,
                                 &ptb->haddr2);
        ptb->vaddr2 = db->pc_next;
    }
    if (likely(ptb->vaddr2 == -1)) {
        pinsn->haddr = ptb->haddr1 + pinsn->vaddr - ptb->vaddr;
    } else {
        pinsn->haddr = ptb->haddr2 + pinsn->vaddr - ptb->vaddr2;
    }
}

void plugin_gen_insn_end(void)
{
    plugin_gen_empty_callback(PLUGIN_GEN_AFTER_INSN);
}

void plugin_gen_tb_end(CPUState *cpu)
{
    struct qemu_plugin_tb *ptb = tcg_ctx->plugin_tb;
    int i;

    /* collect instrumentation requests */
    qemu_plugin_tb_trans_cb(cpu, ptb);

    /* inject the instrumentation at the appropriate places */
    plugin_gen_inject(ptb);

    /* clean up */
    for (i = 0; i < PLUGIN_N_CB_SUBTYPES; i++) {
        if (ptb->cbs[i]) {
            g_array_set_size(ptb->cbs[i], 0);
        }
    }
    ptb->n = 0;
    tcg_ctx->plugin_insn = NULL;
}
