qemu-plugin.h (20295B)
1/* 2 * Copyright (C) 2017, Emilio G. Cota <cota@braap.org> 3 * Copyright (C) 2019, Linaro 4 * 5 * License: GNU GPL, version 2 or later. 6 * See the COPYING file in the top-level directory. 7 * 8 * SPDX-License-Identifier: GPL-2.0-or-later 9 */ 10#ifndef QEMU_PLUGIN_API_H 11#define QEMU_PLUGIN_API_H 12 13#include <inttypes.h> 14#include <stdbool.h> 15#include <stddef.h> 16 17/* 18 * For best performance, build the plugin with -fvisibility=hidden so that 19 * QEMU_PLUGIN_LOCAL is implicit. Then, just mark qemu_plugin_install with 20 * QEMU_PLUGIN_EXPORT. For more info, see 21 * https://gcc.gnu.org/wiki/Visibility 22 */ 23#if defined _WIN32 || defined __CYGWIN__ 24 #ifdef BUILDING_DLL 25 #define QEMU_PLUGIN_EXPORT __declspec(dllexport) 26 #else 27 #define QEMU_PLUGIN_EXPORT __declspec(dllimport) 28 #endif 29 #define QEMU_PLUGIN_LOCAL 30#else 31 #define QEMU_PLUGIN_EXPORT __attribute__((visibility("default"))) 32 #define QEMU_PLUGIN_LOCAL __attribute__((visibility("hidden"))) 33#endif 34 35/** 36 * typedef qemu_plugin_id_t - Unique plugin ID 37 */ 38typedef uint64_t qemu_plugin_id_t; 39 40/* 41 * Versioning plugins: 42 * 43 * The plugin API will pass a minimum and current API version that 44 * QEMU currently supports. The minimum API will be incremented if an 45 * API needs to be deprecated. 46 * 47 * The plugins export the API they were built against by exposing the 48 * symbol qemu_plugin_version which can be checked. 49 */ 50 51extern QEMU_PLUGIN_EXPORT int qemu_plugin_version; 52 53#define QEMU_PLUGIN_VERSION 1 54 55/** 56 * struct qemu_info_t - system information for plugins 57 * 58 * This structure provides for some limited information about the 59 * system to allow the plugin to make decisions on how to proceed. For 60 * example it might only be suitable for running on some guest 61 * architectures or when under full system emulation. 62 */ 63typedef struct qemu_info_t { 64 /** @target_name: string describing architecture */ 65 const char *target_name; 66 /** @version: minimum and current plugin API level */ 67 struct { 68 int min; 69 int cur; 70 } version; 71 /** @system_emulation: is this a full system emulation? */ 72 bool system_emulation; 73 union { 74 /** @system: information relevant to system emulation */ 75 struct { 76 /** @system.smp_vcpus: initial number of vCPUs */ 77 int smp_vcpus; 78 /** @system.max_vcpus: maximum possible number of vCPUs */ 79 int max_vcpus; 80 } system; 81 }; 82} qemu_info_t; 83 84/** 85 * qemu_plugin_install() - Install a plugin 86 * @id: this plugin's opaque ID 87 * @info: a block describing some details about the guest 88 * @argc: number of arguments 89 * @argv: array of arguments (@argc elements) 90 * 91 * All plugins must export this symbol which is called when the plugin 92 * is first loaded. Calling qemu_plugin_uninstall() from this function 93 * is a bug. 94 * 95 * Note: @info is only live during the call. Copy any information we 96 * want to keep. @argv remains valid throughout the lifetime of the 97 * loaded plugin. 98 * 99 * Return: 0 on successful loading, !0 for an error. 100 */ 101QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id, 102 const qemu_info_t *info, 103 int argc, char **argv); 104 105/** 106 * typedef qemu_plugin_simple_cb_t - simple callback 107 * @id: the unique qemu_plugin_id_t 108 * 109 * This callback passes no information aside from the unique @id. 110 */ 111typedef void (*qemu_plugin_simple_cb_t)(qemu_plugin_id_t id); 112 113/** 114 * typedef qemu_plugin_udata_cb_t - callback with user data 115 * @id: the unique qemu_plugin_id_t 116 * @userdata: a pointer to some user data supplied when the callback 117 * was registered. 118 */ 119typedef void (*qemu_plugin_udata_cb_t)(qemu_plugin_id_t id, void *userdata); 120 121/** 122 * typedef qemu_plugin_vcpu_simple_cb_t - vcpu callback 123 * @id: the unique qemu_plugin_id_t 124 * @vcpu_index: the current vcpu context 125 */ 126typedef void (*qemu_plugin_vcpu_simple_cb_t)(qemu_plugin_id_t id, 127 unsigned int vcpu_index); 128 129/** 130 * typedef qemu_plugin_vcpu_udata_cb_t - vcpu callback 131 * @vcpu_index: the current vcpu context 132 * @userdata: a pointer to some user data supplied when the callback 133 * was registered. 134 */ 135typedef void (*qemu_plugin_vcpu_udata_cb_t)(unsigned int vcpu_index, 136 void *userdata); 137 138/** 139 * qemu_plugin_uninstall() - Uninstall a plugin 140 * @id: this plugin's opaque ID 141 * @cb: callback to be called once the plugin has been removed 142 * 143 * Do NOT assume that the plugin has been uninstalled once this function 144 * returns. Plugins are uninstalled asynchronously, and therefore the given 145 * plugin receives callbacks until @cb is called. 146 * 147 * Note: Calling this function from qemu_plugin_install() is a bug. 148 */ 149void qemu_plugin_uninstall(qemu_plugin_id_t id, qemu_plugin_simple_cb_t cb); 150 151/** 152 * qemu_plugin_reset() - Reset a plugin 153 * @id: this plugin's opaque ID 154 * @cb: callback to be called once the plugin has been reset 155 * 156 * Unregisters all callbacks for the plugin given by @id. 157 * 158 * Do NOT assume that the plugin has been reset once this function returns. 159 * Plugins are reset asynchronously, and therefore the given plugin receives 160 * callbacks until @cb is called. 161 */ 162void qemu_plugin_reset(qemu_plugin_id_t id, qemu_plugin_simple_cb_t cb); 163 164/** 165 * qemu_plugin_register_vcpu_init_cb() - register a vCPU initialization callback 166 * @id: plugin ID 167 * @cb: callback function 168 * 169 * The @cb function is called every time a vCPU is initialized. 170 * 171 * See also: qemu_plugin_register_vcpu_exit_cb() 172 */ 173void qemu_plugin_register_vcpu_init_cb(qemu_plugin_id_t id, 174 qemu_plugin_vcpu_simple_cb_t cb); 175 176/** 177 * qemu_plugin_register_vcpu_exit_cb() - register a vCPU exit callback 178 * @id: plugin ID 179 * @cb: callback function 180 * 181 * The @cb function is called every time a vCPU exits. 182 * 183 * See also: qemu_plugin_register_vcpu_init_cb() 184 */ 185void qemu_plugin_register_vcpu_exit_cb(qemu_plugin_id_t id, 186 qemu_plugin_vcpu_simple_cb_t cb); 187 188/** 189 * qemu_plugin_register_vcpu_idle_cb() - register a vCPU idle callback 190 * @id: plugin ID 191 * @cb: callback function 192 * 193 * The @cb function is called every time a vCPU idles. 194 */ 195void qemu_plugin_register_vcpu_idle_cb(qemu_plugin_id_t id, 196 qemu_plugin_vcpu_simple_cb_t cb); 197 198/** 199 * qemu_plugin_register_vcpu_resume_cb() - register a vCPU resume callback 200 * @id: plugin ID 201 * @cb: callback function 202 * 203 * The @cb function is called every time a vCPU resumes execution. 204 */ 205void qemu_plugin_register_vcpu_resume_cb(qemu_plugin_id_t id, 206 qemu_plugin_vcpu_simple_cb_t cb); 207 208/** struct qemu_plugin_tb - Opaque handle for a translation block */ 209struct qemu_plugin_tb; 210/** struct qemu_plugin_insn - Opaque handle for a translated instruction */ 211struct qemu_plugin_insn; 212 213/** 214 * enum qemu_plugin_cb_flags - type of callback 215 * 216 * @QEMU_PLUGIN_CB_NO_REGS: callback does not access the CPU's regs 217 * @QEMU_PLUGIN_CB_R_REGS: callback reads the CPU's regs 218 * @QEMU_PLUGIN_CB_RW_REGS: callback reads and writes the CPU's regs 219 * 220 * Note: currently unused, plugins cannot read or change system 221 * register state. 222 */ 223enum qemu_plugin_cb_flags { 224 QEMU_PLUGIN_CB_NO_REGS, 225 QEMU_PLUGIN_CB_R_REGS, 226 QEMU_PLUGIN_CB_RW_REGS, 227}; 228 229enum qemu_plugin_mem_rw { 230 QEMU_PLUGIN_MEM_R = 1, 231 QEMU_PLUGIN_MEM_W, 232 QEMU_PLUGIN_MEM_RW, 233}; 234 235/** 236 * typedef qemu_plugin_vcpu_tb_trans_cb_t - translation callback 237 * @id: unique plugin id 238 * @tb: opaque handle used for querying and instrumenting a block. 239 */ 240typedef void (*qemu_plugin_vcpu_tb_trans_cb_t)(qemu_plugin_id_t id, 241 struct qemu_plugin_tb *tb); 242 243/** 244 * qemu_plugin_register_vcpu_tb_trans_cb() - register a translate cb 245 * @id: plugin ID 246 * @cb: callback function 247 * 248 * The @cb function is called every time a translation occurs. The @cb 249 * function is passed an opaque qemu_plugin_type which it can query 250 * for additional information including the list of translated 251 * instructions. At this point the plugin can register further 252 * callbacks to be triggered when the block or individual instruction 253 * executes. 254 */ 255void qemu_plugin_register_vcpu_tb_trans_cb(qemu_plugin_id_t id, 256 qemu_plugin_vcpu_tb_trans_cb_t cb); 257 258/** 259 * qemu_plugin_register_vcpu_tb_exec_cb() - register execution callback 260 * @tb: the opaque qemu_plugin_tb handle for the translation 261 * @cb: callback function 262 * @flags: does the plugin read or write the CPU's registers? 263 * @userdata: any plugin data to pass to the @cb? 264 * 265 * The @cb function is called every time a translated unit executes. 266 */ 267void qemu_plugin_register_vcpu_tb_exec_cb(struct qemu_plugin_tb *tb, 268 qemu_plugin_vcpu_udata_cb_t cb, 269 enum qemu_plugin_cb_flags flags, 270 void *userdata); 271 272/** 273 * enum qemu_plugin_op - describes an inline op 274 * 275 * @QEMU_PLUGIN_INLINE_ADD_U64: add an immediate value uint64_t 276 * 277 * Note: currently only a single inline op is supported. 278 */ 279 280enum qemu_plugin_op { 281 QEMU_PLUGIN_INLINE_ADD_U64, 282}; 283 284/** 285 * qemu_plugin_register_vcpu_tb_exec_inline() - execution inline op 286 * @tb: the opaque qemu_plugin_tb handle for the translation 287 * @op: the type of qemu_plugin_op (e.g. ADD_U64) 288 * @ptr: the target memory location for the op 289 * @imm: the op data (e.g. 1) 290 * 291 * Insert an inline op to every time a translated unit executes. 292 * Useful if you just want to increment a single counter somewhere in 293 * memory. 294 * 295 * Note: ops are not atomic so in multi-threaded/multi-smp situations 296 * you will get inexact results. 297 */ 298void qemu_plugin_register_vcpu_tb_exec_inline(struct qemu_plugin_tb *tb, 299 enum qemu_plugin_op op, 300 void *ptr, uint64_t imm); 301 302/** 303 * qemu_plugin_register_vcpu_insn_exec_cb() - register insn execution cb 304 * @insn: the opaque qemu_plugin_insn handle for an instruction 305 * @cb: callback function 306 * @flags: does the plugin read or write the CPU's registers? 307 * @userdata: any plugin data to pass to the @cb? 308 * 309 * The @cb function is called every time an instruction is executed 310 */ 311void qemu_plugin_register_vcpu_insn_exec_cb(struct qemu_plugin_insn *insn, 312 qemu_plugin_vcpu_udata_cb_t cb, 313 enum qemu_plugin_cb_flags flags, 314 void *userdata); 315 316/** 317 * qemu_plugin_register_vcpu_insn_exec_inline() - insn execution inline op 318 * @insn: the opaque qemu_plugin_insn handle for an instruction 319 * @op: the type of qemu_plugin_op (e.g. ADD_U64) 320 * @ptr: the target memory location for the op 321 * @imm: the op data (e.g. 1) 322 * 323 * Insert an inline op to every time an instruction executes. Useful 324 * if you just want to increment a single counter somewhere in memory. 325 */ 326void qemu_plugin_register_vcpu_insn_exec_inline(struct qemu_plugin_insn *insn, 327 enum qemu_plugin_op op, 328 void *ptr, uint64_t imm); 329 330/** 331 * qemu_plugin_tb_n_insns() - query helper for number of insns in TB 332 * @tb: opaque handle to TB passed to callback 333 * 334 * Returns: number of instructions in this block 335 */ 336size_t qemu_plugin_tb_n_insns(const struct qemu_plugin_tb *tb); 337 338/** 339 * qemu_plugin_tb_vaddr() - query helper for vaddr of TB start 340 * @tb: opaque handle to TB passed to callback 341 * 342 * Returns: virtual address of block start 343 */ 344uint64_t qemu_plugin_tb_vaddr(const struct qemu_plugin_tb *tb); 345 346/** 347 * qemu_plugin_tb_get_insn() - retrieve handle for instruction 348 * @tb: opaque handle to TB passed to callback 349 * @idx: instruction number, 0 indexed 350 * 351 * The returned handle can be used in follow up helper queries as well 352 * as when instrumenting an instruction. It is only valid for the 353 * lifetime of the callback. 354 * 355 * Returns: opaque handle to instruction 356 */ 357struct qemu_plugin_insn * 358qemu_plugin_tb_get_insn(const struct qemu_plugin_tb *tb, size_t idx); 359 360/** 361 * qemu_plugin_insn_data() - return ptr to instruction data 362 * @insn: opaque instruction handle from qemu_plugin_tb_get_insn() 363 * 364 * Note: data is only valid for duration of callback. See 365 * qemu_plugin_insn_size() to calculate size of stream. 366 * 367 * Returns: pointer to a stream of bytes containing the value of this 368 * instructions opcode. 369 */ 370const void *qemu_plugin_insn_data(const struct qemu_plugin_insn *insn); 371 372/** 373 * qemu_plugin_insn_size() - return size of instruction 374 * @insn: opaque instruction handle from qemu_plugin_tb_get_insn() 375 * 376 * Returns: size of instruction in bytes 377 */ 378size_t qemu_plugin_insn_size(const struct qemu_plugin_insn *insn); 379 380/** 381 * qemu_plugin_insn_vaddr() - return vaddr of instruction 382 * @insn: opaque instruction handle from qemu_plugin_tb_get_insn() 383 * 384 * Returns: virtual address of instruction 385 */ 386uint64_t qemu_plugin_insn_vaddr(const struct qemu_plugin_insn *insn); 387 388/** 389 * qemu_plugin_insn_haddr() - return hardware addr of instruction 390 * @insn: opaque instruction handle from qemu_plugin_tb_get_insn() 391 * 392 * Returns: hardware (physical) target address of instruction 393 */ 394void *qemu_plugin_insn_haddr(const struct qemu_plugin_insn *insn); 395 396/** 397 * typedef qemu_plugin_meminfo_t - opaque memory transaction handle 398 * 399 * This can be further queried using the qemu_plugin_mem_* query 400 * functions. 401 */ 402typedef uint32_t qemu_plugin_meminfo_t; 403/** struct qemu_plugin_hwaddr - opaque hw address handle */ 404struct qemu_plugin_hwaddr; 405 406/** 407 * qemu_plugin_mem_size_shift() - get size of access 408 * @info: opaque memory transaction handle 409 * 410 * Returns: size of access in ^2 (0=byte, 1=16bit, 2=32bit etc...) 411 */ 412unsigned int qemu_plugin_mem_size_shift(qemu_plugin_meminfo_t info); 413/** 414 * qemu_plugin_mem_is_sign_extended() - was the access sign extended 415 * @info: opaque memory transaction handle 416 * 417 * Returns: true if it was, otherwise false 418 */ 419bool qemu_plugin_mem_is_sign_extended(qemu_plugin_meminfo_t info); 420/** 421 * qemu_plugin_mem_is_big_endian() - was the access big endian 422 * @info: opaque memory transaction handle 423 * 424 * Returns: true if it was, otherwise false 425 */ 426bool qemu_plugin_mem_is_big_endian(qemu_plugin_meminfo_t info); 427/** 428 * qemu_plugin_mem_is_store() - was the access a store 429 * @info: opaque memory transaction handle 430 * 431 * Returns: true if it was, otherwise false 432 */ 433bool qemu_plugin_mem_is_store(qemu_plugin_meminfo_t info); 434 435/** 436 * qemu_plugin_get_hwaddr() - return handle for memory operation 437 * @info: opaque memory info structure 438 * @vaddr: the virtual address of the memory operation 439 * 440 * For system emulation returns a qemu_plugin_hwaddr handle to query 441 * details about the actual physical address backing the virtual 442 * address. For linux-user guests it just returns NULL. 443 * 444 * This handle is *only* valid for the duration of the callback. Any 445 * information about the handle should be recovered before the 446 * callback returns. 447 */ 448struct qemu_plugin_hwaddr *qemu_plugin_get_hwaddr(qemu_plugin_meminfo_t info, 449 uint64_t vaddr); 450 451/* 452 * The following additional queries can be run on the hwaddr structure to 453 * return information about it - namely whether it is for an IO access and the 454 * physical address associated with the access. 455 */ 456 457/** 458 * qemu_plugin_hwaddr_is_io() - query whether memory operation is IO 459 * @haddr: address handle from qemu_plugin_get_hwaddr() 460 * 461 * Returns true if the handle's memory operation is to memory-mapped IO, or 462 * false if it is to RAM 463 */ 464bool qemu_plugin_hwaddr_is_io(const struct qemu_plugin_hwaddr *haddr); 465 466/** 467 * qemu_plugin_hwaddr_phys_addr() - query physical address for memory operation 468 * @haddr: address handle from qemu_plugin_get_hwaddr() 469 * 470 * Returns the physical address associated with the memory operation 471 * 472 * Note that the returned physical address may not be unique if you are dealing 473 * with multiple address spaces. 474 */ 475uint64_t qemu_plugin_hwaddr_phys_addr(const struct qemu_plugin_hwaddr *haddr); 476 477/* 478 * Returns a string representing the device. The string is valid for 479 * the lifetime of the plugin. 480 */ 481const char *qemu_plugin_hwaddr_device_name(const struct qemu_plugin_hwaddr *h); 482 483typedef void 484(*qemu_plugin_vcpu_mem_cb_t)(unsigned int vcpu_index, 485 qemu_plugin_meminfo_t info, uint64_t vaddr, 486 void *userdata); 487 488void qemu_plugin_register_vcpu_mem_cb(struct qemu_plugin_insn *insn, 489 qemu_plugin_vcpu_mem_cb_t cb, 490 enum qemu_plugin_cb_flags flags, 491 enum qemu_plugin_mem_rw rw, 492 void *userdata); 493 494void qemu_plugin_register_vcpu_mem_inline(struct qemu_plugin_insn *insn, 495 enum qemu_plugin_mem_rw rw, 496 enum qemu_plugin_op op, void *ptr, 497 uint64_t imm); 498 499 500 501typedef void 502(*qemu_plugin_vcpu_syscall_cb_t)(qemu_plugin_id_t id, unsigned int vcpu_index, 503 int64_t num, uint64_t a1, uint64_t a2, 504 uint64_t a3, uint64_t a4, uint64_t a5, 505 uint64_t a6, uint64_t a7, uint64_t a8); 506 507void qemu_plugin_register_vcpu_syscall_cb(qemu_plugin_id_t id, 508 qemu_plugin_vcpu_syscall_cb_t cb); 509 510typedef void 511(*qemu_plugin_vcpu_syscall_ret_cb_t)(qemu_plugin_id_t id, unsigned int vcpu_idx, 512 int64_t num, int64_t ret); 513 514void 515qemu_plugin_register_vcpu_syscall_ret_cb(qemu_plugin_id_t id, 516 qemu_plugin_vcpu_syscall_ret_cb_t cb); 517 518 519/** 520 * qemu_plugin_insn_disas() - return disassembly string for instruction 521 * @insn: instruction reference 522 * 523 * Returns an allocated string containing the disassembly 524 */ 525 526char *qemu_plugin_insn_disas(const struct qemu_plugin_insn *insn); 527 528/** 529 * qemu_plugin_insn_symbol() - best effort symbol lookup 530 * @insn: instruction reference 531 * 532 * Return a static string referring to the symbol. This is dependent 533 * on the binary QEMU is running having provided a symbol table. 534 */ 535const char *qemu_plugin_insn_symbol(const struct qemu_plugin_insn *insn); 536 537/** 538 * qemu_plugin_vcpu_for_each() - iterate over the existing vCPU 539 * @id: plugin ID 540 * @cb: callback function 541 * 542 * The @cb function is called once for each existing vCPU. 543 * 544 * See also: qemu_plugin_register_vcpu_init_cb() 545 */ 546void qemu_plugin_vcpu_for_each(qemu_plugin_id_t id, 547 qemu_plugin_vcpu_simple_cb_t cb); 548 549void qemu_plugin_register_flush_cb(qemu_plugin_id_t id, 550 qemu_plugin_simple_cb_t cb); 551 552/** 553 * qemu_plugin_register_atexit_cb() - register exit callback 554 * @id: plugin ID 555 * @cb: callback 556 * @userdata: user data for callback 557 * 558 * The @cb function is called once execution has finished. Plugins 559 * should be able to free all their resources at this point much like 560 * after a reset/uninstall callback is called. 561 * 562 * In user-mode it is possible a few un-instrumented instructions from 563 * child threads may run before the host kernel reaps the threads. 564 */ 565void qemu_plugin_register_atexit_cb(qemu_plugin_id_t id, 566 qemu_plugin_udata_cb_t cb, void *userdata); 567 568/* returns -1 in user-mode */ 569int qemu_plugin_n_vcpus(void); 570 571/* returns -1 in user-mode */ 572int qemu_plugin_n_max_vcpus(void); 573 574/** 575 * qemu_plugin_outs() - output string via QEMU's logging system 576 * @string: a string 577 */ 578void qemu_plugin_outs(const char *string); 579 580/** 581 * qemu_plugin_bool_parse() - parses a boolean argument in the form of 582 * "<argname>=[on|yes|true|off|no|false]" 583 * 584 * @name: argument name, the part before the equals sign 585 * @val: argument value, what's after the equals sign 586 * @ret: output return value 587 * 588 * returns true if the combination @name=@val parses correctly to a boolean 589 * argument, and false otherwise 590 */ 591bool qemu_plugin_bool_parse(const char *name, const char *val, bool *ret); 592 593#endif /* QEMU_PLUGIN_API_H */