xemu/include/qemu/qemu-plugin.h
Markus Armbruster 52581c718c Clean up header guards that don't match their file name
Header guard symbols should match their file name to make guard
collisions less likely.

Cleaned up with scripts/clean-header-guards.pl, followed by some
renaming of new guard symbols picked by the script to better ones.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <20220506134911.2856099-2-armbru@redhat.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
[Change to generated file ebpf/rss.bpf.skeleton.h backed out]
2022-05-11 16:49:06 +02:00

629 lines
21 KiB
C

/*
* Copyright (C) 2017, Emilio G. Cota <cota@braap.org>
* Copyright (C) 2019, Linaro
*
* License: GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#ifndef QEMU_QEMU_PLUGIN_H
#define QEMU_QEMU_PLUGIN_H
#include <inttypes.h>
#include <stdbool.h>
#include <stddef.h>
/*
* For best performance, build the plugin with -fvisibility=hidden so that
* QEMU_PLUGIN_LOCAL is implicit. Then, just mark qemu_plugin_install with
* QEMU_PLUGIN_EXPORT. For more info, see
* https://gcc.gnu.org/wiki/Visibility
*/
#if defined _WIN32 || defined __CYGWIN__
#ifdef BUILDING_DLL
#define QEMU_PLUGIN_EXPORT __declspec(dllexport)
#else
#define QEMU_PLUGIN_EXPORT __declspec(dllimport)
#endif
#define QEMU_PLUGIN_LOCAL
#else
#define QEMU_PLUGIN_EXPORT __attribute__((visibility("default")))
#define QEMU_PLUGIN_LOCAL __attribute__((visibility("hidden")))
#endif
/**
* typedef qemu_plugin_id_t - Unique plugin ID
*/
typedef uint64_t qemu_plugin_id_t;
/*
* Versioning plugins:
*
* The plugin API will pass a minimum and current API version that
* QEMU currently supports. The minimum API will be incremented if an
* API needs to be deprecated.
*
* The plugins export the API they were built against by exposing the
* symbol qemu_plugin_version which can be checked.
*/
extern QEMU_PLUGIN_EXPORT int qemu_plugin_version;
#define QEMU_PLUGIN_VERSION 1
/**
* struct qemu_info_t - system information for plugins
*
* This structure provides for some limited information about the
* system to allow the plugin to make decisions on how to proceed. For
* example it might only be suitable for running on some guest
* architectures or when under full system emulation.
*/
typedef struct qemu_info_t {
/** @target_name: string describing architecture */
const char *target_name;
/** @version: minimum and current plugin API level */
struct {
int min;
int cur;
} version;
/** @system_emulation: is this a full system emulation? */
bool system_emulation;
union {
/** @system: information relevant to system emulation */
struct {
/** @system.smp_vcpus: initial number of vCPUs */
int smp_vcpus;
/** @system.max_vcpus: maximum possible number of vCPUs */
int max_vcpus;
} system;
};
} qemu_info_t;
/**
* qemu_plugin_install() - Install a plugin
* @id: this plugin's opaque ID
* @info: a block describing some details about the guest
* @argc: number of arguments
* @argv: array of arguments (@argc elements)
*
* All plugins must export this symbol which is called when the plugin
* is first loaded. Calling qemu_plugin_uninstall() from this function
* is a bug.
*
* Note: @info is only live during the call. Copy any information we
* want to keep. @argv remains valid throughout the lifetime of the
* loaded plugin.
*
* Return: 0 on successful loading, !0 for an error.
*/
QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id,
const qemu_info_t *info,
int argc, char **argv);
/**
* typedef qemu_plugin_simple_cb_t - simple callback
* @id: the unique qemu_plugin_id_t
*
* This callback passes no information aside from the unique @id.
*/
typedef void (*qemu_plugin_simple_cb_t)(qemu_plugin_id_t id);
/**
* typedef qemu_plugin_udata_cb_t - callback with user data
* @id: the unique qemu_plugin_id_t
* @userdata: a pointer to some user data supplied when the callback
* was registered.
*/
typedef void (*qemu_plugin_udata_cb_t)(qemu_plugin_id_t id, void *userdata);
/**
* typedef qemu_plugin_vcpu_simple_cb_t - vcpu callback
* @id: the unique qemu_plugin_id_t
* @vcpu_index: the current vcpu context
*/
typedef void (*qemu_plugin_vcpu_simple_cb_t)(qemu_plugin_id_t id,
unsigned int vcpu_index);
/**
* typedef qemu_plugin_vcpu_udata_cb_t - vcpu callback
* @vcpu_index: the current vcpu context
* @userdata: a pointer to some user data supplied when the callback
* was registered.
*/
typedef void (*qemu_plugin_vcpu_udata_cb_t)(unsigned int vcpu_index,
void *userdata);
/**
* qemu_plugin_uninstall() - Uninstall a plugin
* @id: this plugin's opaque ID
* @cb: callback to be called once the plugin has been removed
*
* Do NOT assume that the plugin has been uninstalled once this function
* returns. Plugins are uninstalled asynchronously, and therefore the given
* plugin receives callbacks until @cb is called.
*
* Note: Calling this function from qemu_plugin_install() is a bug.
*/
void qemu_plugin_uninstall(qemu_plugin_id_t id, qemu_plugin_simple_cb_t cb);
/**
* qemu_plugin_reset() - Reset a plugin
* @id: this plugin's opaque ID
* @cb: callback to be called once the plugin has been reset
*
* Unregisters all callbacks for the plugin given by @id.
*
* Do NOT assume that the plugin has been reset once this function returns.
* Plugins are reset asynchronously, and therefore the given plugin receives
* callbacks until @cb is called.
*/
void qemu_plugin_reset(qemu_plugin_id_t id, qemu_plugin_simple_cb_t cb);
/**
* qemu_plugin_register_vcpu_init_cb() - register a vCPU initialization callback
* @id: plugin ID
* @cb: callback function
*
* The @cb function is called every time a vCPU is initialized.
*
* See also: qemu_plugin_register_vcpu_exit_cb()
*/
void qemu_plugin_register_vcpu_init_cb(qemu_plugin_id_t id,
qemu_plugin_vcpu_simple_cb_t cb);
/**
* qemu_plugin_register_vcpu_exit_cb() - register a vCPU exit callback
* @id: plugin ID
* @cb: callback function
*
* The @cb function is called every time a vCPU exits.
*
* See also: qemu_plugin_register_vcpu_init_cb()
*/
void qemu_plugin_register_vcpu_exit_cb(qemu_plugin_id_t id,
qemu_plugin_vcpu_simple_cb_t cb);
/**
* qemu_plugin_register_vcpu_idle_cb() - register a vCPU idle callback
* @id: plugin ID
* @cb: callback function
*
* The @cb function is called every time a vCPU idles.
*/
void qemu_plugin_register_vcpu_idle_cb(qemu_plugin_id_t id,
qemu_plugin_vcpu_simple_cb_t cb);
/**
* qemu_plugin_register_vcpu_resume_cb() - register a vCPU resume callback
* @id: plugin ID
* @cb: callback function
*
* The @cb function is called every time a vCPU resumes execution.
*/
void qemu_plugin_register_vcpu_resume_cb(qemu_plugin_id_t id,
qemu_plugin_vcpu_simple_cb_t cb);
/** struct qemu_plugin_tb - Opaque handle for a translation block */
struct qemu_plugin_tb;
/** struct qemu_plugin_insn - Opaque handle for a translated instruction */
struct qemu_plugin_insn;
/**
* enum qemu_plugin_cb_flags - type of callback
*
* @QEMU_PLUGIN_CB_NO_REGS: callback does not access the CPU's regs
* @QEMU_PLUGIN_CB_R_REGS: callback reads the CPU's regs
* @QEMU_PLUGIN_CB_RW_REGS: callback reads and writes the CPU's regs
*
* Note: currently unused, plugins cannot read or change system
* register state.
*/
enum qemu_plugin_cb_flags {
QEMU_PLUGIN_CB_NO_REGS,
QEMU_PLUGIN_CB_R_REGS,
QEMU_PLUGIN_CB_RW_REGS,
};
enum qemu_plugin_mem_rw {
QEMU_PLUGIN_MEM_R = 1,
QEMU_PLUGIN_MEM_W,
QEMU_PLUGIN_MEM_RW,
};
/**
* typedef qemu_plugin_vcpu_tb_trans_cb_t - translation callback
* @id: unique plugin id
* @tb: opaque handle used for querying and instrumenting a block.
*/
typedef void (*qemu_plugin_vcpu_tb_trans_cb_t)(qemu_plugin_id_t id,
struct qemu_plugin_tb *tb);
/**
* qemu_plugin_register_vcpu_tb_trans_cb() - register a translate cb
* @id: plugin ID
* @cb: callback function
*
* The @cb function is called every time a translation occurs. The @cb
* function is passed an opaque qemu_plugin_type which it can query
* for additional information including the list of translated
* instructions. At this point the plugin can register further
* callbacks to be triggered when the block or individual instruction
* executes.
*/
void qemu_plugin_register_vcpu_tb_trans_cb(qemu_plugin_id_t id,
qemu_plugin_vcpu_tb_trans_cb_t cb);
/**
* qemu_plugin_register_vcpu_tb_exec_cb() - register execution callback
* @tb: the opaque qemu_plugin_tb handle for the translation
* @cb: callback function
* @flags: does the plugin read or write the CPU's registers?
* @userdata: any plugin data to pass to the @cb?
*
* The @cb function is called every time a translated unit executes.
*/
void qemu_plugin_register_vcpu_tb_exec_cb(struct qemu_plugin_tb *tb,
qemu_plugin_vcpu_udata_cb_t cb,
enum qemu_plugin_cb_flags flags,
void *userdata);
/**
* enum qemu_plugin_op - describes an inline op
*
* @QEMU_PLUGIN_INLINE_ADD_U64: add an immediate value uint64_t
*
* Note: currently only a single inline op is supported.
*/
enum qemu_plugin_op {
QEMU_PLUGIN_INLINE_ADD_U64,
};
/**
* qemu_plugin_register_vcpu_tb_exec_inline() - execution inline op
* @tb: the opaque qemu_plugin_tb handle for the translation
* @op: the type of qemu_plugin_op (e.g. ADD_U64)
* @ptr: the target memory location for the op
* @imm: the op data (e.g. 1)
*
* Insert an inline op to every time a translated unit executes.
* Useful if you just want to increment a single counter somewhere in
* memory.
*
* Note: ops are not atomic so in multi-threaded/multi-smp situations
* you will get inexact results.
*/
void qemu_plugin_register_vcpu_tb_exec_inline(struct qemu_plugin_tb *tb,
enum qemu_plugin_op op,
void *ptr, uint64_t imm);
/**
* qemu_plugin_register_vcpu_insn_exec_cb() - register insn execution cb
* @insn: the opaque qemu_plugin_insn handle for an instruction
* @cb: callback function
* @flags: does the plugin read or write the CPU's registers?
* @userdata: any plugin data to pass to the @cb?
*
* The @cb function is called every time an instruction is executed
*/
void qemu_plugin_register_vcpu_insn_exec_cb(struct qemu_plugin_insn *insn,
qemu_plugin_vcpu_udata_cb_t cb,
enum qemu_plugin_cb_flags flags,
void *userdata);
/**
* qemu_plugin_register_vcpu_insn_exec_inline() - insn execution inline op
* @insn: the opaque qemu_plugin_insn handle for an instruction
* @op: the type of qemu_plugin_op (e.g. ADD_U64)
* @ptr: the target memory location for the op
* @imm: the op data (e.g. 1)
*
* Insert an inline op to every time an instruction executes. Useful
* if you just want to increment a single counter somewhere in memory.
*/
void qemu_plugin_register_vcpu_insn_exec_inline(struct qemu_plugin_insn *insn,
enum qemu_plugin_op op,
void *ptr, uint64_t imm);
/**
* qemu_plugin_tb_n_insns() - query helper for number of insns in TB
* @tb: opaque handle to TB passed to callback
*
* Returns: number of instructions in this block
*/
size_t qemu_plugin_tb_n_insns(const struct qemu_plugin_tb *tb);
/**
* qemu_plugin_tb_vaddr() - query helper for vaddr of TB start
* @tb: opaque handle to TB passed to callback
*
* Returns: virtual address of block start
*/
uint64_t qemu_plugin_tb_vaddr(const struct qemu_plugin_tb *tb);
/**
* qemu_plugin_tb_get_insn() - retrieve handle for instruction
* @tb: opaque handle to TB passed to callback
* @idx: instruction number, 0 indexed
*
* The returned handle can be used in follow up helper queries as well
* as when instrumenting an instruction. It is only valid for the
* lifetime of the callback.
*
* Returns: opaque handle to instruction
*/
struct qemu_plugin_insn *
qemu_plugin_tb_get_insn(const struct qemu_plugin_tb *tb, size_t idx);
/**
* qemu_plugin_insn_data() - return ptr to instruction data
* @insn: opaque instruction handle from qemu_plugin_tb_get_insn()
*
* Note: data is only valid for duration of callback. See
* qemu_plugin_insn_size() to calculate size of stream.
*
* Returns: pointer to a stream of bytes containing the value of this
* instructions opcode.
*/
const void *qemu_plugin_insn_data(const struct qemu_plugin_insn *insn);
/**
* qemu_plugin_insn_size() - return size of instruction
* @insn: opaque instruction handle from qemu_plugin_tb_get_insn()
*
* Returns: size of instruction in bytes
*/
size_t qemu_plugin_insn_size(const struct qemu_plugin_insn *insn);
/**
* qemu_plugin_insn_vaddr() - return vaddr of instruction
* @insn: opaque instruction handle from qemu_plugin_tb_get_insn()
*
* Returns: virtual address of instruction
*/
uint64_t qemu_plugin_insn_vaddr(const struct qemu_plugin_insn *insn);
/**
* qemu_plugin_insn_haddr() - return hardware addr of instruction
* @insn: opaque instruction handle from qemu_plugin_tb_get_insn()
*
* Returns: hardware (physical) target address of instruction
*/
void *qemu_plugin_insn_haddr(const struct qemu_plugin_insn *insn);
/**
* typedef qemu_plugin_meminfo_t - opaque memory transaction handle
*
* This can be further queried using the qemu_plugin_mem_* query
* functions.
*/
typedef uint32_t qemu_plugin_meminfo_t;
/** struct qemu_plugin_hwaddr - opaque hw address handle */
struct qemu_plugin_hwaddr;
/**
* qemu_plugin_mem_size_shift() - get size of access
* @info: opaque memory transaction handle
*
* Returns: size of access in ^2 (0=byte, 1=16bit, 2=32bit etc...)
*/
unsigned int qemu_plugin_mem_size_shift(qemu_plugin_meminfo_t info);
/**
* qemu_plugin_mem_is_sign_extended() - was the access sign extended
* @info: opaque memory transaction handle
*
* Returns: true if it was, otherwise false
*/
bool qemu_plugin_mem_is_sign_extended(qemu_plugin_meminfo_t info);
/**
* qemu_plugin_mem_is_big_endian() - was the access big endian
* @info: opaque memory transaction handle
*
* Returns: true if it was, otherwise false
*/
bool qemu_plugin_mem_is_big_endian(qemu_plugin_meminfo_t info);
/**
* qemu_plugin_mem_is_store() - was the access a store
* @info: opaque memory transaction handle
*
* Returns: true if it was, otherwise false
*/
bool qemu_plugin_mem_is_store(qemu_plugin_meminfo_t info);
/**
* qemu_plugin_get_hwaddr() - return handle for memory operation
* @info: opaque memory info structure
* @vaddr: the virtual address of the memory operation
*
* For system emulation returns a qemu_plugin_hwaddr handle to query
* details about the actual physical address backing the virtual
* address. For linux-user guests it just returns NULL.
*
* This handle is *only* valid for the duration of the callback. Any
* information about the handle should be recovered before the
* callback returns.
*/
struct qemu_plugin_hwaddr *qemu_plugin_get_hwaddr(qemu_plugin_meminfo_t info,
uint64_t vaddr);
/*
* The following additional queries can be run on the hwaddr structure to
* return information about it - namely whether it is for an IO access and the
* physical address associated with the access.
*/
/**
* qemu_plugin_hwaddr_is_io() - query whether memory operation is IO
* @haddr: address handle from qemu_plugin_get_hwaddr()
*
* Returns true if the handle's memory operation is to memory-mapped IO, or
* false if it is to RAM
*/
bool qemu_plugin_hwaddr_is_io(const struct qemu_plugin_hwaddr *haddr);
/**
* qemu_plugin_hwaddr_phys_addr() - query physical address for memory operation
* @haddr: address handle from qemu_plugin_get_hwaddr()
*
* Returns the physical address associated with the memory operation
*
* Note that the returned physical address may not be unique if you are dealing
* with multiple address spaces.
*/
uint64_t qemu_plugin_hwaddr_phys_addr(const struct qemu_plugin_hwaddr *haddr);
/*
* Returns a string representing the device. The string is valid for
* the lifetime of the plugin.
*/
const char *qemu_plugin_hwaddr_device_name(const struct qemu_plugin_hwaddr *h);
typedef void
(*qemu_plugin_vcpu_mem_cb_t)(unsigned int vcpu_index,
qemu_plugin_meminfo_t info, uint64_t vaddr,
void *userdata);
void qemu_plugin_register_vcpu_mem_cb(struct qemu_plugin_insn *insn,
qemu_plugin_vcpu_mem_cb_t cb,
enum qemu_plugin_cb_flags flags,
enum qemu_plugin_mem_rw rw,
void *userdata);
void qemu_plugin_register_vcpu_mem_inline(struct qemu_plugin_insn *insn,
enum qemu_plugin_mem_rw rw,
enum qemu_plugin_op op, void *ptr,
uint64_t imm);
typedef void
(*qemu_plugin_vcpu_syscall_cb_t)(qemu_plugin_id_t id, unsigned int vcpu_index,
int64_t num, uint64_t a1, uint64_t a2,
uint64_t a3, uint64_t a4, uint64_t a5,
uint64_t a6, uint64_t a7, uint64_t a8);
void qemu_plugin_register_vcpu_syscall_cb(qemu_plugin_id_t id,
qemu_plugin_vcpu_syscall_cb_t cb);
typedef void
(*qemu_plugin_vcpu_syscall_ret_cb_t)(qemu_plugin_id_t id, unsigned int vcpu_idx,
int64_t num, int64_t ret);
void
qemu_plugin_register_vcpu_syscall_ret_cb(qemu_plugin_id_t id,
qemu_plugin_vcpu_syscall_ret_cb_t cb);
/**
* qemu_plugin_insn_disas() - return disassembly string for instruction
* @insn: instruction reference
*
* Returns an allocated string containing the disassembly
*/
char *qemu_plugin_insn_disas(const struct qemu_plugin_insn *insn);
/**
* qemu_plugin_insn_symbol() - best effort symbol lookup
* @insn: instruction reference
*
* Return a static string referring to the symbol. This is dependent
* on the binary QEMU is running having provided a symbol table.
*/
const char *qemu_plugin_insn_symbol(const struct qemu_plugin_insn *insn);
/**
* qemu_plugin_vcpu_for_each() - iterate over the existing vCPU
* @id: plugin ID
* @cb: callback function
*
* The @cb function is called once for each existing vCPU.
*
* See also: qemu_plugin_register_vcpu_init_cb()
*/
void qemu_plugin_vcpu_for_each(qemu_plugin_id_t id,
qemu_plugin_vcpu_simple_cb_t cb);
void qemu_plugin_register_flush_cb(qemu_plugin_id_t id,
qemu_plugin_simple_cb_t cb);
/**
* qemu_plugin_register_atexit_cb() - register exit callback
* @id: plugin ID
* @cb: callback
* @userdata: user data for callback
*
* The @cb function is called once execution has finished. Plugins
* should be able to free all their resources at this point much like
* after a reset/uninstall callback is called.
*
* In user-mode it is possible a few un-instrumented instructions from
* child threads may run before the host kernel reaps the threads.
*/
void qemu_plugin_register_atexit_cb(qemu_plugin_id_t id,
qemu_plugin_udata_cb_t cb, void *userdata);
/* returns -1 in user-mode */
int qemu_plugin_n_vcpus(void);
/* returns -1 in user-mode */
int qemu_plugin_n_max_vcpus(void);
/**
* qemu_plugin_outs() - output string via QEMU's logging system
* @string: a string
*/
void qemu_plugin_outs(const char *string);
/**
* qemu_plugin_bool_parse() - parses a boolean argument in the form of
* "<argname>=[on|yes|true|off|no|false]"
*
* @name: argument name, the part before the equals sign
* @val: argument value, what's after the equals sign
* @ret: output return value
*
* returns true if the combination @name=@val parses correctly to a boolean
* argument, and false otherwise
*/
bool qemu_plugin_bool_parse(const char *name, const char *val, bool *ret);
/**
* qemu_plugin_path_to_binary() - path to binary file being executed
*
* Return a string representing the path to the binary. For user-mode
* this is the main executable. For system emulation we currently
* return NULL. The user should g_free() the string once no longer
* needed.
*/
const char *qemu_plugin_path_to_binary(void);
/**
* qemu_plugin_start_code() - returns start of text segment
*
* Returns the nominal start address of the main text segment in
* user-mode. Currently returns 0 for system emulation.
*/
uint64_t qemu_plugin_start_code(void);
/**
* qemu_plugin_end_code() - returns end of text segment
*
* Returns the nominal end address of the main text segment in
* user-mode. Currently returns 0 for system emulation.
*/
uint64_t qemu_plugin_end_code(void);
/**
* qemu_plugin_entry_code() - returns start address for module
*
* Returns the nominal entry address of the main text segment in
* user-mode. Currently returns 0 for system emulation.
*/
uint64_t qemu_plugin_entry_code(void);
#endif /* QEMU_QEMU_PLUGIN_H */