]> Git Repo - qemu.git/blob - include/qemu/qemu-plugin.h
plugin: add qemu_plugin_insn_disas helper
[qemu.git] / include / qemu / qemu-plugin.h
1 /*
2  * Copyright (C) 2017, Emilio G. Cota <[email protected]>
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
16 /*
17  * For best performance, build the plugin with -fvisibility=hidden so that
18  * QEMU_PLUGIN_LOCAL is implicit. Then, just mark qemu_plugin_install with
19  * QEMU_PLUGIN_EXPORT. For more info, see
20  *   https://gcc.gnu.org/wiki/Visibility
21  */
22 #if defined _WIN32 || defined __CYGWIN__
23   #ifdef BUILDING_DLL
24     #define QEMU_PLUGIN_EXPORT __declspec(dllexport)
25   #else
26     #define QEMU_PLUGIN_EXPORT __declspec(dllimport)
27   #endif
28   #define QEMU_PLUGIN_LOCAL
29 #else
30   #if __GNUC__ >= 4
31     #define QEMU_PLUGIN_EXPORT __attribute__((visibility("default")))
32     #define QEMU_PLUGIN_LOCAL  __attribute__((visibility("hidden")))
33   #else
34     #define QEMU_PLUGIN_EXPORT
35     #define QEMU_PLUGIN_LOCAL
36   #endif
37 #endif
38
39 typedef uint64_t qemu_plugin_id_t;
40
41 typedef struct {
42     /* string describing architecture */
43     const char *target_name;
44     /* is this a full system emulation? */
45     bool system_emulation;
46     union {
47         /*
48          * smp_vcpus may change if vCPUs can be hot-plugged, max_vcpus
49          * is the system-wide limit.
50          */
51         struct {
52             int smp_vcpus;
53             int max_vcpus;
54         } system;
55     };
56 } qemu_info_t;
57
58 /**
59  * qemu_plugin_install() - Install a plugin
60  * @id: this plugin's opaque ID
61  * @info: a block describing some details about the guest
62  * @argc: number of arguments
63  * @argv: array of arguments (@argc elements)
64  *
65  * All plugins must export this symbol.
66  *
67  * Note: Calling qemu_plugin_uninstall() from this function is a bug. To raise
68  * an error during install, return !0.
69  *
70  * Note: @info is only live during the call. Copy any information we
71  * want to keep.
72  *
73  * Note: @argv remains valid throughout the lifetime of the loaded plugin.
74  */
75 QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id,
76                                            const qemu_info_t *info,
77                                            int argc, char **argv);
78
79 /*
80  * Prototypes for the various callback styles we will be registering
81  * in the following functions.
82  */
83 typedef void (*qemu_plugin_simple_cb_t)(qemu_plugin_id_t id);
84
85 typedef void (*qemu_plugin_udata_cb_t)(qemu_plugin_id_t id, void *userdata);
86
87 typedef void (*qemu_plugin_vcpu_simple_cb_t)(qemu_plugin_id_t id,
88                                              unsigned int vcpu_index);
89
90 typedef void (*qemu_plugin_vcpu_udata_cb_t)(unsigned int vcpu_index,
91                                             void *userdata);
92
93 /**
94  * qemu_plugin_uninstall() - Uninstall a plugin
95  * @id: this plugin's opaque ID
96  * @cb: callback to be called once the plugin has been removed
97  *
98  * Do NOT assume that the plugin has been uninstalled once this function
99  * returns. Plugins are uninstalled asynchronously, and therefore the given
100  * plugin receives callbacks until @cb is called.
101  *
102  * Note: Calling this function from qemu_plugin_install() is a bug.
103  */
104 void qemu_plugin_uninstall(qemu_plugin_id_t id, qemu_plugin_simple_cb_t cb);
105
106 /**
107  * qemu_plugin_reset() - Reset a plugin
108  * @id: this plugin's opaque ID
109  * @cb: callback to be called once the plugin has been reset
110  *
111  * Unregisters all callbacks for the plugin given by @id.
112  *
113  * Do NOT assume that the plugin has been reset once this function returns.
114  * Plugins are reset asynchronously, and therefore the given plugin receives
115  * callbacks until @cb is called.
116  */
117 void qemu_plugin_reset(qemu_plugin_id_t id, qemu_plugin_simple_cb_t cb);
118
119 /**
120  * qemu_plugin_register_vcpu_init_cb() - register a vCPU initialization callback
121  * @id: plugin ID
122  * @cb: callback function
123  *
124  * The @cb function is called every time a vCPU is initialized.
125  *
126  * See also: qemu_plugin_register_vcpu_exit_cb()
127  */
128 void qemu_plugin_register_vcpu_init_cb(qemu_plugin_id_t id,
129                                        qemu_plugin_vcpu_simple_cb_t cb);
130
131 /**
132  * qemu_plugin_register_vcpu_exit_cb() - register a vCPU exit callback
133  * @id: plugin ID
134  * @cb: callback function
135  *
136  * The @cb function is called every time a vCPU exits.
137  *
138  * See also: qemu_plugin_register_vcpu_init_cb()
139  */
140 void qemu_plugin_register_vcpu_exit_cb(qemu_plugin_id_t id,
141                                        qemu_plugin_vcpu_simple_cb_t cb);
142
143 /**
144  * qemu_plugin_register_vcpu_idle_cb() - register a vCPU idle callback
145  * @id: plugin ID
146  * @cb: callback function
147  *
148  * The @cb function is called every time a vCPU idles.
149  */
150 void qemu_plugin_register_vcpu_idle_cb(qemu_plugin_id_t id,
151                                        qemu_plugin_vcpu_simple_cb_t cb);
152
153 /**
154  * qemu_plugin_register_vcpu_resume_cb() - register a vCPU resume callback
155  * @id: plugin ID
156  * @cb: callback function
157  *
158  * The @cb function is called every time a vCPU resumes execution.
159  */
160 void qemu_plugin_register_vcpu_resume_cb(qemu_plugin_id_t id,
161                                          qemu_plugin_vcpu_simple_cb_t cb);
162
163 /*
164  * Opaque types that the plugin is given during the translation and
165  * instrumentation phase.
166  */
167 struct qemu_plugin_tb;
168 struct qemu_plugin_insn;
169
170 enum qemu_plugin_cb_flags {
171     QEMU_PLUGIN_CB_NO_REGS, /* callback does not access the CPU's regs */
172     QEMU_PLUGIN_CB_R_REGS,  /* callback reads the CPU's regs */
173     QEMU_PLUGIN_CB_RW_REGS, /* callback reads and writes the CPU's regs */
174 };
175
176 enum qemu_plugin_mem_rw {
177     QEMU_PLUGIN_MEM_R = 1,
178     QEMU_PLUGIN_MEM_W,
179     QEMU_PLUGIN_MEM_RW,
180 };
181
182 /**
183  * qemu_plugin_register_vcpu_tb_trans_cb() - register a translate cb
184  * @id: plugin ID
185  * @cb: callback function
186  *
187  * The @cb function is called every time a translation occurs. The @cb
188  * function is passed an opaque qemu_plugin_type which it can query
189  * for additional information including the list of translated
190  * instructions. At this point the plugin can register further
191  * callbacks to be triggered when the block or individual instruction
192  * executes.
193  */
194 typedef void (*qemu_plugin_vcpu_tb_trans_cb_t)(qemu_plugin_id_t id,
195                                                struct qemu_plugin_tb *tb);
196
197 void qemu_plugin_register_vcpu_tb_trans_cb(qemu_plugin_id_t id,
198                                            qemu_plugin_vcpu_tb_trans_cb_t cb);
199
200 /**
201  * qemu_plugin_register_vcpu_tb_trans_exec_cb() - register execution callback
202  * @tb: the opaque qemu_plugin_tb handle for the translation
203  * @cb: callback function
204  * @flags: does the plugin read or write the CPU's registers?
205  * @userdata: any plugin data to pass to the @cb?
206  *
207  * The @cb function is called every time a translated unit executes.
208  */
209 void qemu_plugin_register_vcpu_tb_exec_cb(struct qemu_plugin_tb *tb,
210                                           qemu_plugin_vcpu_udata_cb_t cb,
211                                           enum qemu_plugin_cb_flags flags,
212                                           void *userdata);
213
214 enum qemu_plugin_op {
215     QEMU_PLUGIN_INLINE_ADD_U64,
216 };
217
218 /**
219  * qemu_plugin_register_vcpu_tb_trans_exec_inline() - execution inline op
220  * @tb: the opaque qemu_plugin_tb handle for the translation
221  * @op: the type of qemu_plugin_op (e.g. ADD_U64)
222  * @ptr: the target memory location for the op
223  * @imm: the op data (e.g. 1)
224  *
225  * Insert an inline op to every time a translated unit executes.
226  * Useful if you just want to increment a single counter somewhere in
227  * memory.
228  */
229 void qemu_plugin_register_vcpu_tb_exec_inline(struct qemu_plugin_tb *tb,
230                                               enum qemu_plugin_op op,
231                                               void *ptr, uint64_t imm);
232
233 /**
234  * qemu_plugin_register_vcpu_insn_exec_cb() - register insn execution cb
235  * @insn: the opaque qemu_plugin_insn handle for an instruction
236  * @cb: callback function
237  * @flags: does the plugin read or write the CPU's registers?
238  * @userdata: any plugin data to pass to the @cb?
239  *
240  * The @cb function is called every time an instruction is executed
241  */
242 void qemu_plugin_register_vcpu_insn_exec_cb(struct qemu_plugin_insn *insn,
243                                             qemu_plugin_vcpu_udata_cb_t cb,
244                                             enum qemu_plugin_cb_flags flags,
245                                             void *userdata);
246
247 /**
248  * qemu_plugin_register_vcpu_insn_exec_inline() - insn execution inline op
249  * @insn: the opaque qemu_plugin_insn handle for an instruction
250  * @cb: callback function
251  * @op: the type of qemu_plugin_op (e.g. ADD_U64)
252  * @ptr: the target memory location for the op
253  * @imm: the op data (e.g. 1)
254  *
255  * Insert an inline op to every time an instruction executes. Useful
256  * if you just want to increment a single counter somewhere in memory.
257  */
258 void qemu_plugin_register_vcpu_insn_exec_inline(struct qemu_plugin_insn *insn,
259                                                 enum qemu_plugin_op op,
260                                                 void *ptr, uint64_t imm);
261
262 /*
263  * Helpers to query information about the instructions in a block
264  */
265 size_t qemu_plugin_tb_n_insns(const struct qemu_plugin_tb *tb);
266
267 uint64_t qemu_plugin_tb_vaddr(const struct qemu_plugin_tb *tb);
268
269 struct qemu_plugin_insn *
270 qemu_plugin_tb_get_insn(const struct qemu_plugin_tb *tb, size_t idx);
271
272 const void *qemu_plugin_insn_data(const struct qemu_plugin_insn *insn);
273
274 size_t qemu_plugin_insn_size(const struct qemu_plugin_insn *insn);
275
276 uint64_t qemu_plugin_insn_vaddr(const struct qemu_plugin_insn *insn);
277 void *qemu_plugin_insn_haddr(const struct qemu_plugin_insn *insn);
278
279 /*
280  * Memory Instrumentation
281  *
282  * The anonymous qemu_plugin_meminfo_t and qemu_plugin_hwaddr types
283  * can be used in queries to QEMU to get more information about a
284  * given memory access.
285  */
286 typedef uint32_t qemu_plugin_meminfo_t;
287 struct qemu_plugin_hwaddr;
288
289 /* meminfo queries */
290 unsigned int qemu_plugin_mem_size_shift(qemu_plugin_meminfo_t info);
291 bool qemu_plugin_mem_is_sign_extended(qemu_plugin_meminfo_t info);
292 bool qemu_plugin_mem_is_big_endian(qemu_plugin_meminfo_t info);
293 bool qemu_plugin_mem_is_store(qemu_plugin_meminfo_t info);
294
295 /*
296  * qemu_plugin_get_hwaddr():
297  * @vaddr: the virtual address of the memory operation
298  *
299  * For system emulation returns a qemu_plugin_hwaddr handle to query
300  * details about the actual physical address backing the virtual
301  * address. For linux-user guests it just returns NULL.
302  *
303  * This handle is *only* valid for the duration of the callback. Any
304  * information about the handle should be recovered before the
305  * callback returns.
306  */
307 struct qemu_plugin_hwaddr *qemu_plugin_get_hwaddr(qemu_plugin_meminfo_t info,
308                                                   uint64_t vaddr);
309
310 /*
311  * The following additional queries can be run on the hwaddr structure
312  * to return information about it. For non-IO accesses the device
313  * offset will be into the appropriate block of RAM.
314  */
315 bool qemu_plugin_hwaddr_is_io(struct qemu_plugin_hwaddr *hwaddr);
316 uint64_t qemu_plugin_hwaddr_device_offset(const struct qemu_plugin_hwaddr *haddr);
317
318 typedef void
319 (*qemu_plugin_vcpu_mem_cb_t)(unsigned int vcpu_index,
320                              qemu_plugin_meminfo_t info, uint64_t vaddr,
321                              void *userdata);
322
323 void qemu_plugin_register_vcpu_mem_cb(struct qemu_plugin_insn *insn,
324                                       qemu_plugin_vcpu_mem_cb_t cb,
325                                       enum qemu_plugin_cb_flags flags,
326                                       enum qemu_plugin_mem_rw rw,
327                                       void *userdata);
328
329 void qemu_plugin_register_vcpu_mem_inline(struct qemu_plugin_insn *insn,
330                                           enum qemu_plugin_mem_rw rw,
331                                           enum qemu_plugin_op op, void *ptr,
332                                           uint64_t imm);
333
334
335
336 typedef void
337 (*qemu_plugin_vcpu_syscall_cb_t)(qemu_plugin_id_t id, unsigned int vcpu_index,
338                                  int64_t num, uint64_t a1, uint64_t a2,
339                                  uint64_t a3, uint64_t a4, uint64_t a5,
340                                  uint64_t a6, uint64_t a7, uint64_t a8);
341
342 void qemu_plugin_register_vcpu_syscall_cb(qemu_plugin_id_t id,
343                                           qemu_plugin_vcpu_syscall_cb_t cb);
344
345 typedef void
346 (*qemu_plugin_vcpu_syscall_ret_cb_t)(qemu_plugin_id_t id, unsigned int vcpu_idx,
347                                      int64_t num, int64_t ret);
348
349 void
350 qemu_plugin_register_vcpu_syscall_ret_cb(qemu_plugin_id_t id,
351                                          qemu_plugin_vcpu_syscall_ret_cb_t cb);
352
353
354 /**
355  * qemu_plugin_insn_disas() - return disassembly string for instruction
356  * @insn: instruction reference
357  *
358  * Returns an allocated string containing the disassembly
359  */
360
361 char *qemu_plugin_insn_disas(const struct qemu_plugin_insn *insn);
362
363 /**
364  * qemu_plugin_vcpu_for_each() - iterate over the existing vCPU
365  * @id: plugin ID
366  * @cb: callback function
367  *
368  * The @cb function is called once for each existing vCPU.
369  *
370  * See also: qemu_plugin_register_vcpu_init_cb()
371  */
372 void qemu_plugin_vcpu_for_each(qemu_plugin_id_t id,
373                                qemu_plugin_vcpu_simple_cb_t cb);
374
375 void qemu_plugin_register_flush_cb(qemu_plugin_id_t id,
376                                    qemu_plugin_simple_cb_t cb);
377
378 void qemu_plugin_register_atexit_cb(qemu_plugin_id_t id,
379                                     qemu_plugin_udata_cb_t cb, void *userdata);
380
381 /* returns -1 in user-mode */
382 int qemu_plugin_n_vcpus(void);
383
384 /* returns -1 in user-mode */
385 int qemu_plugin_n_max_vcpus(void);
386
387 #endif /* QEMU_PLUGIN_API_H */
This page took 0.045075 seconds and 4 git commands to generate.