138b47b19SEmilio G. Cota /* 238b47b19SEmilio G. Cota * Copyright (C) 2017, Emilio G. Cota <cota@braap.org> 338b47b19SEmilio G. Cota * 438b47b19SEmilio G. Cota * License: GNU GPL, version 2 or later. 538b47b19SEmilio G. Cota * See the COPYING file in the top-level directory. 638b47b19SEmilio G. Cota * 738b47b19SEmilio G. Cota * plugin-gen.h - TCG-dependent definitions for generating plugin code 838b47b19SEmilio G. Cota * 938b47b19SEmilio G. Cota * This header should be included only from plugin.c and C files that emit 1038b47b19SEmilio G. Cota * TCG code. 1138b47b19SEmilio G. Cota */ 1238b47b19SEmilio G. Cota #ifndef QEMU_PLUGIN_GEN_H 1338b47b19SEmilio G. Cota #define QEMU_PLUGIN_GEN_H 1438b47b19SEmilio G. Cota 1538b47b19SEmilio G. Cota #include "qemu/plugin.h" 1638b47b19SEmilio G. Cota #include "tcg/tcg.h" 1738b47b19SEmilio G. Cota 1838b47b19SEmilio G. Cota struct DisasContextBase; 1938b47b19SEmilio G. Cota 2038b47b19SEmilio G. Cota #ifdef CONFIG_PLUGIN 2138b47b19SEmilio G. Cota 22cfd405eaSAlex Bennée bool plugin_gen_tb_start(CPUState *cpu, const TranslationBlock *tb, bool supress); 2338b47b19SEmilio G. Cota void plugin_gen_tb_end(CPUState *cpu); 2438b47b19SEmilio G. Cota void plugin_gen_insn_start(CPUState *cpu, const struct DisasContextBase *db); 2538b47b19SEmilio G. Cota void plugin_gen_insn_end(void); 2638b47b19SEmilio G. Cota 2738b47b19SEmilio G. Cota void plugin_gen_disable_mem_helpers(void); 2838b47b19SEmilio G. Cota void plugin_gen_empty_mem_callback(TCGv addr, uint32_t info); 2938b47b19SEmilio G. Cota 30*357af9beSAlex Bennée static inline void plugin_insn_append(abi_ptr pc, const void *from, size_t size) 31763f7e12SEmilio G. Cota { 32763f7e12SEmilio G. Cota struct qemu_plugin_insn *insn = tcg_ctx->plugin_insn; 33*357af9beSAlex Bennée abi_ptr off; 34763f7e12SEmilio G. Cota 35763f7e12SEmilio G. Cota if (insn == NULL) { 36763f7e12SEmilio G. Cota return; 37763f7e12SEmilio G. Cota } 38*357af9beSAlex Bennée off = pc - insn->vaddr; 39*357af9beSAlex Bennée if (off < insn->data->len) { 40*357af9beSAlex Bennée g_byte_array_set_size(insn->data, off); 41*357af9beSAlex Bennée } else if (off > insn->data->len) { 42*357af9beSAlex Bennée /* we have an unexpected gap */ 43*357af9beSAlex Bennée g_assert_not_reached(); 44*357af9beSAlex Bennée } 45763f7e12SEmilio G. Cota 46763f7e12SEmilio G. Cota insn->data = g_byte_array_append(insn->data, from, size); 47763f7e12SEmilio G. Cota } 48763f7e12SEmilio G. Cota 4938b47b19SEmilio G. Cota #else /* !CONFIG_PLUGIN */ 5038b47b19SEmilio G. Cota 5138b47b19SEmilio G. Cota static inline 52cfd405eaSAlex Bennée bool plugin_gen_tb_start(CPUState *cpu, const TranslationBlock *tb, bool supress) 5338b47b19SEmilio G. Cota { 5438b47b19SEmilio G. Cota return false; 5538b47b19SEmilio G. Cota } 5638b47b19SEmilio G. Cota 5738b47b19SEmilio G. Cota static inline 5838b47b19SEmilio G. Cota void plugin_gen_insn_start(CPUState *cpu, const struct DisasContextBase *db) 5938b47b19SEmilio G. Cota { } 6038b47b19SEmilio G. Cota 6138b47b19SEmilio G. Cota static inline void plugin_gen_insn_end(void) 6238b47b19SEmilio G. Cota { } 6338b47b19SEmilio G. Cota 6438b47b19SEmilio G. Cota static inline void plugin_gen_tb_end(CPUState *cpu) 6538b47b19SEmilio G. Cota { } 6638b47b19SEmilio G. Cota 6738b47b19SEmilio G. Cota static inline void plugin_gen_disable_mem_helpers(void) 6838b47b19SEmilio G. Cota { } 6938b47b19SEmilio G. Cota 7038b47b19SEmilio G. Cota static inline void plugin_gen_empty_mem_callback(TCGv addr, uint32_t info) 7138b47b19SEmilio G. Cota { } 7238b47b19SEmilio G. Cota 73*357af9beSAlex Bennée static inline void plugin_insn_append(abi_ptr pc, const void *from, size_t size) 74763f7e12SEmilio G. Cota { } 75763f7e12SEmilio G. Cota 7638b47b19SEmilio G. Cota #endif /* CONFIG_PLUGIN */ 7738b47b19SEmilio G. Cota 7838b47b19SEmilio G. Cota #endif /* QEMU_PLUGIN_GEN_H */ 7938b47b19SEmilio G. Cota 80