1 /* 2 * QEMU Plugin API 3 * 4 * This provides the API that is available to the plugins to interact 5 * with QEMU. We have to be careful not to expose internal details of 6 * how QEMU works so we abstract out things like translation and 7 * instructions to anonymous data types: 8 * 9 * qemu_plugin_tb 10 * qemu_plugin_insn 11 * qemu_plugin_register 12 * 13 * Which can then be passed back into the API to do additional things. 14 * As such all the public functions in here are exported in 15 * qemu-plugin.h. 16 * 17 * The general life-cycle of a plugin is: 18 * 19 * - plugin is loaded, public qemu_plugin_install called 20 * - the install func registers callbacks for events 21 * - usually an atexit_cb is registered to dump info at the end 22 * - when a registered event occurs the plugin is called 23 * - some events pass additional info 24 * - during translation the plugin can decide to instrument any 25 * instruction 26 * - when QEMU exits all the registered atexit callbacks are called 27 * 28 * Copyright (C) 2017, Emilio G. Cota <cota@braap.org> 29 * Copyright (C) 2019, Linaro 30 * 31 * License: GNU GPL, version 2 or later. 32 * See the COPYING file in the top-level directory. 33 * 34 * SPDX-License-Identifier: GPL-2.0-or-later 35 * 36 */ 37 38 #include "qemu/osdep.h" 39 #include "qemu/main-loop.h" 40 #include "qemu/plugin.h" 41 #include "qemu/log.h" 42 #include "tcg/tcg.h" 43 #include "exec/exec-all.h" 44 #include "exec/gdbstub.h" 45 #include "exec/translator.h" 46 #include "disas/disas.h" 47 #include "plugin.h" 48 #ifndef CONFIG_USER_ONLY 49 #include "exec/ram_addr.h" 50 #include "qemu/plugin-memory.h" 51 #include "hw/boards.h" 52 #else 53 #include "qemu.h" 54 #ifdef CONFIG_LINUX 55 #include "loader.h" 56 #endif 57 #endif 58 59 /* Uninstall and Reset handlers */ 60 61 void qemu_plugin_uninstall(qemu_plugin_id_t id, qemu_plugin_simple_cb_t cb) 62 { 63 plugin_reset_uninstall(id, cb, false); 64 } 65 66 void qemu_plugin_reset(qemu_plugin_id_t id, qemu_plugin_simple_cb_t cb) 67 { 68 plugin_reset_uninstall(id, cb, true); 69 } 70 71 /* 72 * Plugin Register Functions 73 * 74 * This allows the plugin to register callbacks for various events 75 * during the translation. 76 */ 77 78 void qemu_plugin_register_vcpu_init_cb(qemu_plugin_id_t id, 79 qemu_plugin_vcpu_simple_cb_t cb) 80 { 81 plugin_register_cb(id, QEMU_PLUGIN_EV_VCPU_INIT, cb); 82 } 83 84 void qemu_plugin_register_vcpu_exit_cb(qemu_plugin_id_t id, 85 qemu_plugin_vcpu_simple_cb_t cb) 86 { 87 plugin_register_cb(id, QEMU_PLUGIN_EV_VCPU_EXIT, cb); 88 } 89 90 static bool tb_is_mem_only(void) 91 { 92 return tb_cflags(tcg_ctx->gen_tb) & CF_MEMI_ONLY; 93 } 94 95 void qemu_plugin_register_vcpu_tb_exec_cb(struct qemu_plugin_tb *tb, 96 qemu_plugin_vcpu_udata_cb_t cb, 97 enum qemu_plugin_cb_flags flags, 98 void *udata) 99 { 100 if (!tb_is_mem_only()) { 101 plugin_register_dyn_cb__udata(&tb->cbs, cb, flags, udata); 102 } 103 } 104 105 void qemu_plugin_register_vcpu_tb_exec_cond_cb(struct qemu_plugin_tb *tb, 106 qemu_plugin_vcpu_udata_cb_t cb, 107 enum qemu_plugin_cb_flags flags, 108 enum qemu_plugin_cond cond, 109 qemu_plugin_u64 entry, 110 uint64_t imm, 111 void *udata) 112 { 113 if (cond == QEMU_PLUGIN_COND_NEVER || tb_is_mem_only()) { 114 return; 115 } 116 if (cond == QEMU_PLUGIN_COND_ALWAYS) { 117 qemu_plugin_register_vcpu_tb_exec_cb(tb, cb, flags, udata); 118 return; 119 } 120 plugin_register_dyn_cond_cb__udata(&tb->cbs, cb, flags, 121 cond, entry, imm, udata); 122 } 123 124 void qemu_plugin_register_vcpu_tb_exec_inline_per_vcpu( 125 struct qemu_plugin_tb *tb, 126 enum qemu_plugin_op op, 127 qemu_plugin_u64 entry, 128 uint64_t imm) 129 { 130 if (!tb_is_mem_only()) { 131 plugin_register_inline_op_on_entry(&tb->cbs, 0, op, entry, imm); 132 } 133 } 134 135 void qemu_plugin_register_vcpu_insn_exec_cb(struct qemu_plugin_insn *insn, 136 qemu_plugin_vcpu_udata_cb_t cb, 137 enum qemu_plugin_cb_flags flags, 138 void *udata) 139 { 140 if (!tb_is_mem_only()) { 141 plugin_register_dyn_cb__udata(&insn->insn_cbs, cb, flags, udata); 142 } 143 } 144 145 void qemu_plugin_register_vcpu_insn_exec_cond_cb( 146 struct qemu_plugin_insn *insn, 147 qemu_plugin_vcpu_udata_cb_t cb, 148 enum qemu_plugin_cb_flags flags, 149 enum qemu_plugin_cond cond, 150 qemu_plugin_u64 entry, 151 uint64_t imm, 152 void *udata) 153 { 154 if (cond == QEMU_PLUGIN_COND_NEVER || tb_is_mem_only()) { 155 return; 156 } 157 if (cond == QEMU_PLUGIN_COND_ALWAYS) { 158 qemu_plugin_register_vcpu_insn_exec_cb(insn, cb, flags, udata); 159 return; 160 } 161 plugin_register_dyn_cond_cb__udata(&insn->insn_cbs, cb, flags, 162 cond, entry, imm, udata); 163 } 164 165 void qemu_plugin_register_vcpu_insn_exec_inline_per_vcpu( 166 struct qemu_plugin_insn *insn, 167 enum qemu_plugin_op op, 168 qemu_plugin_u64 entry, 169 uint64_t imm) 170 { 171 if (!tb_is_mem_only()) { 172 plugin_register_inline_op_on_entry(&insn->insn_cbs, 0, op, entry, imm); 173 } 174 } 175 176 177 /* 178 * We always plant memory instrumentation because they don't finalise until 179 * after the operation has complete. 180 */ 181 void qemu_plugin_register_vcpu_mem_cb(struct qemu_plugin_insn *insn, 182 qemu_plugin_vcpu_mem_cb_t cb, 183 enum qemu_plugin_cb_flags flags, 184 enum qemu_plugin_mem_rw rw, 185 void *udata) 186 { 187 plugin_register_vcpu_mem_cb(&insn->mem_cbs, cb, flags, rw, udata); 188 } 189 190 void qemu_plugin_register_vcpu_mem_inline_per_vcpu( 191 struct qemu_plugin_insn *insn, 192 enum qemu_plugin_mem_rw rw, 193 enum qemu_plugin_op op, 194 qemu_plugin_u64 entry, 195 uint64_t imm) 196 { 197 plugin_register_inline_op_on_entry(&insn->mem_cbs, rw, op, entry, imm); 198 } 199 200 void qemu_plugin_register_vcpu_tb_trans_cb(qemu_plugin_id_t id, 201 qemu_plugin_vcpu_tb_trans_cb_t cb) 202 { 203 plugin_register_cb(id, QEMU_PLUGIN_EV_VCPU_TB_TRANS, cb); 204 } 205 206 void qemu_plugin_register_vcpu_syscall_cb(qemu_plugin_id_t id, 207 qemu_plugin_vcpu_syscall_cb_t cb) 208 { 209 plugin_register_cb(id, QEMU_PLUGIN_EV_VCPU_SYSCALL, cb); 210 } 211 212 void 213 qemu_plugin_register_vcpu_syscall_ret_cb(qemu_plugin_id_t id, 214 qemu_plugin_vcpu_syscall_ret_cb_t cb) 215 { 216 plugin_register_cb(id, QEMU_PLUGIN_EV_VCPU_SYSCALL_RET, cb); 217 } 218 219 /* 220 * Plugin Queries 221 * 222 * These are queries that the plugin can make to gauge information 223 * from our opaque data types. We do not want to leak internal details 224 * here just information useful to the plugin. 225 */ 226 227 /* 228 * Translation block information: 229 * 230 * A plugin can query the virtual address of the start of the block 231 * and the number of instructions in it. It can also get access to 232 * each translated instruction. 233 */ 234 235 size_t qemu_plugin_tb_n_insns(const struct qemu_plugin_tb *tb) 236 { 237 return tb->n; 238 } 239 240 uint64_t qemu_plugin_tb_vaddr(const struct qemu_plugin_tb *tb) 241 { 242 const DisasContextBase *db = tcg_ctx->plugin_db; 243 return db->pc_first; 244 } 245 246 struct qemu_plugin_insn * 247 qemu_plugin_tb_get_insn(const struct qemu_plugin_tb *tb, size_t idx) 248 { 249 struct qemu_plugin_insn *insn; 250 if (unlikely(idx >= tb->n)) { 251 return NULL; 252 } 253 insn = g_ptr_array_index(tb->insns, idx); 254 return insn; 255 } 256 257 /* 258 * Instruction information 259 * 260 * These queries allow the plugin to retrieve information about each 261 * instruction being translated. 262 */ 263 264 size_t qemu_plugin_insn_data(const struct qemu_plugin_insn *insn, 265 void *dest, size_t len) 266 { 267 const DisasContextBase *db = tcg_ctx->plugin_db; 268 269 len = MIN(len, insn->len); 270 return translator_st(db, dest, insn->vaddr, len) ? len : 0; 271 } 272 273 size_t qemu_plugin_insn_size(const struct qemu_plugin_insn *insn) 274 { 275 return insn->len; 276 } 277 278 uint64_t qemu_plugin_insn_vaddr(const struct qemu_plugin_insn *insn) 279 { 280 return insn->vaddr; 281 } 282 283 void *qemu_plugin_insn_haddr(const struct qemu_plugin_insn *insn) 284 { 285 const DisasContextBase *db = tcg_ctx->plugin_db; 286 vaddr page0_last = db->pc_first | ~TARGET_PAGE_MASK; 287 288 if (db->fake_insn) { 289 return NULL; 290 } 291 292 /* 293 * ??? The return value is not intended for use of host memory, 294 * but as a proxy for address space and physical address. 295 * Thus we are only interested in the first byte and do not 296 * care about spanning pages. 297 */ 298 if (insn->vaddr <= page0_last) { 299 if (db->host_addr[0] == NULL) { 300 return NULL; 301 } 302 return db->host_addr[0] + insn->vaddr - db->pc_first; 303 } else { 304 if (db->host_addr[1] == NULL) { 305 return NULL; 306 } 307 return db->host_addr[1] + insn->vaddr - (page0_last + 1); 308 } 309 } 310 311 char *qemu_plugin_insn_disas(const struct qemu_plugin_insn *insn) 312 { 313 return plugin_disas(tcg_ctx->cpu, tcg_ctx->plugin_db, 314 insn->vaddr, insn->len); 315 } 316 317 const char *qemu_plugin_insn_symbol(const struct qemu_plugin_insn *insn) 318 { 319 const char *sym = lookup_symbol(insn->vaddr); 320 return sym[0] != 0 ? sym : NULL; 321 } 322 323 /* 324 * The memory queries allow the plugin to query information about a 325 * memory access. 326 */ 327 328 unsigned qemu_plugin_mem_size_shift(qemu_plugin_meminfo_t info) 329 { 330 MemOp op = get_memop(info); 331 return op & MO_SIZE; 332 } 333 334 bool qemu_plugin_mem_is_sign_extended(qemu_plugin_meminfo_t info) 335 { 336 MemOp op = get_memop(info); 337 return op & MO_SIGN; 338 } 339 340 bool qemu_plugin_mem_is_big_endian(qemu_plugin_meminfo_t info) 341 { 342 MemOp op = get_memop(info); 343 return (op & MO_BSWAP) == MO_BE; 344 } 345 346 bool qemu_plugin_mem_is_store(qemu_plugin_meminfo_t info) 347 { 348 return get_plugin_meminfo_rw(info) & QEMU_PLUGIN_MEM_W; 349 } 350 351 /* 352 * Virtual Memory queries 353 */ 354 355 #ifdef CONFIG_SOFTMMU 356 static __thread struct qemu_plugin_hwaddr hwaddr_info; 357 #endif 358 359 struct qemu_plugin_hwaddr *qemu_plugin_get_hwaddr(qemu_plugin_meminfo_t info, 360 uint64_t vaddr) 361 { 362 #ifdef CONFIG_SOFTMMU 363 CPUState *cpu = current_cpu; 364 unsigned int mmu_idx = get_mmuidx(info); 365 enum qemu_plugin_mem_rw rw = get_plugin_meminfo_rw(info); 366 hwaddr_info.is_store = (rw & QEMU_PLUGIN_MEM_W) != 0; 367 368 assert(mmu_idx < NB_MMU_MODES); 369 370 if (!tlb_plugin_lookup(cpu, vaddr, mmu_idx, 371 hwaddr_info.is_store, &hwaddr_info)) { 372 error_report("invalid use of qemu_plugin_get_hwaddr"); 373 return NULL; 374 } 375 376 return &hwaddr_info; 377 #else 378 return NULL; 379 #endif 380 } 381 382 bool qemu_plugin_hwaddr_is_io(const struct qemu_plugin_hwaddr *haddr) 383 { 384 #ifdef CONFIG_SOFTMMU 385 return haddr->is_io; 386 #else 387 return false; 388 #endif 389 } 390 391 uint64_t qemu_plugin_hwaddr_phys_addr(const struct qemu_plugin_hwaddr *haddr) 392 { 393 #ifdef CONFIG_SOFTMMU 394 if (haddr) { 395 return haddr->phys_addr; 396 } 397 #endif 398 return 0; 399 } 400 401 const char *qemu_plugin_hwaddr_device_name(const struct qemu_plugin_hwaddr *h) 402 { 403 #ifdef CONFIG_SOFTMMU 404 if (h && h->is_io) { 405 MemoryRegion *mr = h->mr; 406 if (!mr->name) { 407 unsigned maddr = (uintptr_t)mr; 408 g_autofree char *temp = g_strdup_printf("anon%08x", maddr); 409 return g_intern_string(temp); 410 } else { 411 return g_intern_string(mr->name); 412 } 413 } else { 414 return g_intern_static_string("RAM"); 415 } 416 #else 417 return g_intern_static_string("Invalid"); 418 #endif 419 } 420 421 int qemu_plugin_num_vcpus(void) 422 { 423 return plugin_num_vcpus(); 424 } 425 426 /* 427 * Plugin output 428 */ 429 void qemu_plugin_outs(const char *string) 430 { 431 qemu_log_mask(CPU_LOG_PLUGIN, "%s", string); 432 } 433 434 bool qemu_plugin_bool_parse(const char *name, const char *value, bool *ret) 435 { 436 return name && value && qapi_bool_parse(name, value, ret, NULL); 437 } 438 439 /* 440 * Binary path, start and end locations 441 */ 442 const char *qemu_plugin_path_to_binary(void) 443 { 444 char *path = NULL; 445 #ifdef CONFIG_USER_ONLY 446 TaskState *ts = get_task_state(current_cpu); 447 path = g_strdup(ts->bprm->filename); 448 #endif 449 return path; 450 } 451 452 uint64_t qemu_plugin_start_code(void) 453 { 454 uint64_t start = 0; 455 #ifdef CONFIG_USER_ONLY 456 TaskState *ts = get_task_state(current_cpu); 457 start = ts->info->start_code; 458 #endif 459 return start; 460 } 461 462 uint64_t qemu_plugin_end_code(void) 463 { 464 uint64_t end = 0; 465 #ifdef CONFIG_USER_ONLY 466 TaskState *ts = get_task_state(current_cpu); 467 end = ts->info->end_code; 468 #endif 469 return end; 470 } 471 472 uint64_t qemu_plugin_entry_code(void) 473 { 474 uint64_t entry = 0; 475 #ifdef CONFIG_USER_ONLY 476 TaskState *ts = get_task_state(current_cpu); 477 entry = ts->info->entry; 478 #endif 479 return entry; 480 } 481 482 /* 483 * Create register handles. 484 * 485 * We need to create a handle for each register so the plugin 486 * infrastructure can call gdbstub to read a register. They are 487 * currently just a pointer encapsulation of the gdb_reg but in 488 * future may hold internal plugin state so its important plugin 489 * authors are not tempted to treat them as numbers. 490 * 491 * We also construct a result array with those handles and some 492 * ancillary data the plugin might find useful. 493 */ 494 495 static GArray *create_register_handles(GArray *gdbstub_regs) 496 { 497 GArray *find_data = g_array_new(true, true, 498 sizeof(qemu_plugin_reg_descriptor)); 499 500 for (int i = 0; i < gdbstub_regs->len; i++) { 501 GDBRegDesc *grd = &g_array_index(gdbstub_regs, GDBRegDesc, i); 502 qemu_plugin_reg_descriptor desc; 503 504 /* skip "un-named" regs */ 505 if (!grd->name) { 506 continue; 507 } 508 509 /* Create a record for the plugin */ 510 desc.handle = GINT_TO_POINTER(grd->gdb_reg); 511 desc.name = g_intern_string(grd->name); 512 desc.feature = g_intern_string(grd->feature_name); 513 g_array_append_val(find_data, desc); 514 } 515 516 return find_data; 517 } 518 519 GArray *qemu_plugin_get_registers(void) 520 { 521 g_assert(current_cpu); 522 523 g_autoptr(GArray) regs = gdb_get_register_list(current_cpu); 524 return create_register_handles(regs); 525 } 526 527 int qemu_plugin_read_register(struct qemu_plugin_register *reg, GByteArray *buf) 528 { 529 g_assert(current_cpu); 530 531 return gdb_read_register(current_cpu, buf, GPOINTER_TO_INT(reg)); 532 } 533 534 struct qemu_plugin_scoreboard *qemu_plugin_scoreboard_new(size_t element_size) 535 { 536 return plugin_scoreboard_new(element_size); 537 } 538 539 void qemu_plugin_scoreboard_free(struct qemu_plugin_scoreboard *score) 540 { 541 plugin_scoreboard_free(score); 542 } 543 544 void *qemu_plugin_scoreboard_find(struct qemu_plugin_scoreboard *score, 545 unsigned int vcpu_index) 546 { 547 g_assert(vcpu_index < qemu_plugin_num_vcpus()); 548 /* we can't use g_array_index since entry size is not statically known */ 549 char *base_ptr = score->data->data; 550 return base_ptr + vcpu_index * g_array_get_element_size(score->data); 551 } 552 553 static uint64_t *plugin_u64_address(qemu_plugin_u64 entry, 554 unsigned int vcpu_index) 555 { 556 char *ptr = qemu_plugin_scoreboard_find(entry.score, vcpu_index); 557 return (uint64_t *)(ptr + entry.offset); 558 } 559 560 void qemu_plugin_u64_add(qemu_plugin_u64 entry, unsigned int vcpu_index, 561 uint64_t added) 562 { 563 *plugin_u64_address(entry, vcpu_index) += added; 564 } 565 566 uint64_t qemu_plugin_u64_get(qemu_plugin_u64 entry, 567 unsigned int vcpu_index) 568 { 569 return *plugin_u64_address(entry, vcpu_index); 570 } 571 572 void qemu_plugin_u64_set(qemu_plugin_u64 entry, unsigned int vcpu_index, 573 uint64_t val) 574 { 575 *plugin_u64_address(entry, vcpu_index) = val; 576 } 577 578 uint64_t qemu_plugin_u64_sum(qemu_plugin_u64 entry) 579 { 580 uint64_t total = 0; 581 for (int i = 0, n = qemu_plugin_num_vcpus(); i < n; ++i) { 582 total += qemu_plugin_u64_get(entry, i); 583 } 584 return total; 585 } 586