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_inline_per_vcpu( 106 struct qemu_plugin_tb *tb, 107 enum qemu_plugin_op op, 108 qemu_plugin_u64 entry, 109 uint64_t imm) 110 { 111 if (!tb_is_mem_only()) { 112 plugin_register_inline_op_on_entry(&tb->cbs, 0, op, entry, imm); 113 } 114 } 115 116 void qemu_plugin_register_vcpu_insn_exec_cb(struct qemu_plugin_insn *insn, 117 qemu_plugin_vcpu_udata_cb_t cb, 118 enum qemu_plugin_cb_flags flags, 119 void *udata) 120 { 121 if (!tb_is_mem_only()) { 122 plugin_register_dyn_cb__udata(&insn->insn_cbs, cb, flags, udata); 123 } 124 } 125 126 void qemu_plugin_register_vcpu_insn_exec_inline_per_vcpu( 127 struct qemu_plugin_insn *insn, 128 enum qemu_plugin_op op, 129 qemu_plugin_u64 entry, 130 uint64_t imm) 131 { 132 if (!tb_is_mem_only()) { 133 plugin_register_inline_op_on_entry(&insn->insn_cbs, 0, op, entry, imm); 134 } 135 } 136 137 138 /* 139 * We always plant memory instrumentation because they don't finalise until 140 * after the operation has complete. 141 */ 142 void qemu_plugin_register_vcpu_mem_cb(struct qemu_plugin_insn *insn, 143 qemu_plugin_vcpu_mem_cb_t cb, 144 enum qemu_plugin_cb_flags flags, 145 enum qemu_plugin_mem_rw rw, 146 void *udata) 147 { 148 plugin_register_vcpu_mem_cb(&insn->mem_cbs, cb, flags, rw, udata); 149 } 150 151 void qemu_plugin_register_vcpu_mem_inline_per_vcpu( 152 struct qemu_plugin_insn *insn, 153 enum qemu_plugin_mem_rw rw, 154 enum qemu_plugin_op op, 155 qemu_plugin_u64 entry, 156 uint64_t imm) 157 { 158 plugin_register_inline_op_on_entry(&insn->mem_cbs, rw, op, entry, imm); 159 } 160 161 void qemu_plugin_register_vcpu_tb_trans_cb(qemu_plugin_id_t id, 162 qemu_plugin_vcpu_tb_trans_cb_t cb) 163 { 164 plugin_register_cb(id, QEMU_PLUGIN_EV_VCPU_TB_TRANS, cb); 165 } 166 167 void qemu_plugin_register_vcpu_syscall_cb(qemu_plugin_id_t id, 168 qemu_plugin_vcpu_syscall_cb_t cb) 169 { 170 plugin_register_cb(id, QEMU_PLUGIN_EV_VCPU_SYSCALL, cb); 171 } 172 173 void 174 qemu_plugin_register_vcpu_syscall_ret_cb(qemu_plugin_id_t id, 175 qemu_plugin_vcpu_syscall_ret_cb_t cb) 176 { 177 plugin_register_cb(id, QEMU_PLUGIN_EV_VCPU_SYSCALL_RET, cb); 178 } 179 180 /* 181 * Plugin Queries 182 * 183 * These are queries that the plugin can make to gauge information 184 * from our opaque data types. We do not want to leak internal details 185 * here just information useful to the plugin. 186 */ 187 188 /* 189 * Translation block information: 190 * 191 * A plugin can query the virtual address of the start of the block 192 * and the number of instructions in it. It can also get access to 193 * each translated instruction. 194 */ 195 196 size_t qemu_plugin_tb_n_insns(const struct qemu_plugin_tb *tb) 197 { 198 return tb->n; 199 } 200 201 uint64_t qemu_plugin_tb_vaddr(const struct qemu_plugin_tb *tb) 202 { 203 return tb->vaddr; 204 } 205 206 struct qemu_plugin_insn * 207 qemu_plugin_tb_get_insn(const struct qemu_plugin_tb *tb, size_t idx) 208 { 209 struct qemu_plugin_insn *insn; 210 if (unlikely(idx >= tb->n)) { 211 return NULL; 212 } 213 insn = g_ptr_array_index(tb->insns, idx); 214 return insn; 215 } 216 217 /* 218 * Instruction information 219 * 220 * These queries allow the plugin to retrieve information about each 221 * instruction being translated. 222 */ 223 224 size_t qemu_plugin_insn_data(const struct qemu_plugin_insn *insn, 225 void *dest, size_t len) 226 { 227 const DisasContextBase *db = tcg_ctx->plugin_db; 228 229 len = MIN(len, insn->len); 230 return translator_st(db, dest, insn->vaddr, len) ? len : 0; 231 } 232 233 size_t qemu_plugin_insn_size(const struct qemu_plugin_insn *insn) 234 { 235 return insn->len; 236 } 237 238 uint64_t qemu_plugin_insn_vaddr(const struct qemu_plugin_insn *insn) 239 { 240 return insn->vaddr; 241 } 242 243 void *qemu_plugin_insn_haddr(const struct qemu_plugin_insn *insn) 244 { 245 const DisasContextBase *db = tcg_ctx->plugin_db; 246 vaddr page0_last = db->pc_first | ~TARGET_PAGE_MASK; 247 248 if (db->fake_insn) { 249 return NULL; 250 } 251 252 /* 253 * ??? The return value is not intended for use of host memory, 254 * but as a proxy for address space and physical address. 255 * Thus we are only interested in the first byte and do not 256 * care about spanning pages. 257 */ 258 if (insn->vaddr <= page0_last) { 259 if (db->host_addr[0] == NULL) { 260 return NULL; 261 } 262 return db->host_addr[0] + insn->vaddr - db->pc_first; 263 } else { 264 if (db->host_addr[1] == NULL) { 265 return NULL; 266 } 267 return db->host_addr[1] + insn->vaddr - (page0_last + 1); 268 } 269 } 270 271 char *qemu_plugin_insn_disas(const struct qemu_plugin_insn *insn) 272 { 273 CPUState *cpu = current_cpu; 274 return plugin_disas(cpu, insn->vaddr, insn->len); 275 } 276 277 const char *qemu_plugin_insn_symbol(const struct qemu_plugin_insn *insn) 278 { 279 const char *sym = lookup_symbol(insn->vaddr); 280 return sym[0] != 0 ? sym : NULL; 281 } 282 283 /* 284 * The memory queries allow the plugin to query information about a 285 * memory access. 286 */ 287 288 unsigned qemu_plugin_mem_size_shift(qemu_plugin_meminfo_t info) 289 { 290 MemOp op = get_memop(info); 291 return op & MO_SIZE; 292 } 293 294 bool qemu_plugin_mem_is_sign_extended(qemu_plugin_meminfo_t info) 295 { 296 MemOp op = get_memop(info); 297 return op & MO_SIGN; 298 } 299 300 bool qemu_plugin_mem_is_big_endian(qemu_plugin_meminfo_t info) 301 { 302 MemOp op = get_memop(info); 303 return (op & MO_BSWAP) == MO_BE; 304 } 305 306 bool qemu_plugin_mem_is_store(qemu_plugin_meminfo_t info) 307 { 308 return get_plugin_meminfo_rw(info) & QEMU_PLUGIN_MEM_W; 309 } 310 311 /* 312 * Virtual Memory queries 313 */ 314 315 #ifdef CONFIG_SOFTMMU 316 static __thread struct qemu_plugin_hwaddr hwaddr_info; 317 #endif 318 319 struct qemu_plugin_hwaddr *qemu_plugin_get_hwaddr(qemu_plugin_meminfo_t info, 320 uint64_t vaddr) 321 { 322 #ifdef CONFIG_SOFTMMU 323 CPUState *cpu = current_cpu; 324 unsigned int mmu_idx = get_mmuidx(info); 325 enum qemu_plugin_mem_rw rw = get_plugin_meminfo_rw(info); 326 hwaddr_info.is_store = (rw & QEMU_PLUGIN_MEM_W) != 0; 327 328 assert(mmu_idx < NB_MMU_MODES); 329 330 if (!tlb_plugin_lookup(cpu, vaddr, mmu_idx, 331 hwaddr_info.is_store, &hwaddr_info)) { 332 error_report("invalid use of qemu_plugin_get_hwaddr"); 333 return NULL; 334 } 335 336 return &hwaddr_info; 337 #else 338 return NULL; 339 #endif 340 } 341 342 bool qemu_plugin_hwaddr_is_io(const struct qemu_plugin_hwaddr *haddr) 343 { 344 #ifdef CONFIG_SOFTMMU 345 return haddr->is_io; 346 #else 347 return false; 348 #endif 349 } 350 351 uint64_t qemu_plugin_hwaddr_phys_addr(const struct qemu_plugin_hwaddr *haddr) 352 { 353 #ifdef CONFIG_SOFTMMU 354 if (haddr) { 355 return haddr->phys_addr; 356 } 357 #endif 358 return 0; 359 } 360 361 const char *qemu_plugin_hwaddr_device_name(const struct qemu_plugin_hwaddr *h) 362 { 363 #ifdef CONFIG_SOFTMMU 364 if (h && h->is_io) { 365 MemoryRegion *mr = h->mr; 366 if (!mr->name) { 367 unsigned maddr = (uintptr_t)mr; 368 g_autofree char *temp = g_strdup_printf("anon%08x", maddr); 369 return g_intern_string(temp); 370 } else { 371 return g_intern_string(mr->name); 372 } 373 } else { 374 return g_intern_static_string("RAM"); 375 } 376 #else 377 return g_intern_static_string("Invalid"); 378 #endif 379 } 380 381 int qemu_plugin_num_vcpus(void) 382 { 383 return plugin_num_vcpus(); 384 } 385 386 /* 387 * Plugin output 388 */ 389 void qemu_plugin_outs(const char *string) 390 { 391 qemu_log_mask(CPU_LOG_PLUGIN, "%s", string); 392 } 393 394 bool qemu_plugin_bool_parse(const char *name, const char *value, bool *ret) 395 { 396 return name && value && qapi_bool_parse(name, value, ret, NULL); 397 } 398 399 /* 400 * Binary path, start and end locations 401 */ 402 const char *qemu_plugin_path_to_binary(void) 403 { 404 char *path = NULL; 405 #ifdef CONFIG_USER_ONLY 406 TaskState *ts = get_task_state(current_cpu); 407 path = g_strdup(ts->bprm->filename); 408 #endif 409 return path; 410 } 411 412 uint64_t qemu_plugin_start_code(void) 413 { 414 uint64_t start = 0; 415 #ifdef CONFIG_USER_ONLY 416 TaskState *ts = get_task_state(current_cpu); 417 start = ts->info->start_code; 418 #endif 419 return start; 420 } 421 422 uint64_t qemu_plugin_end_code(void) 423 { 424 uint64_t end = 0; 425 #ifdef CONFIG_USER_ONLY 426 TaskState *ts = get_task_state(current_cpu); 427 end = ts->info->end_code; 428 #endif 429 return end; 430 } 431 432 uint64_t qemu_plugin_entry_code(void) 433 { 434 uint64_t entry = 0; 435 #ifdef CONFIG_USER_ONLY 436 TaskState *ts = get_task_state(current_cpu); 437 entry = ts->info->entry; 438 #endif 439 return entry; 440 } 441 442 /* 443 * Create register handles. 444 * 445 * We need to create a handle for each register so the plugin 446 * infrastructure can call gdbstub to read a register. They are 447 * currently just a pointer encapsulation of the gdb_reg but in 448 * future may hold internal plugin state so its important plugin 449 * authors are not tempted to treat them as numbers. 450 * 451 * We also construct a result array with those handles and some 452 * ancillary data the plugin might find useful. 453 */ 454 455 static GArray *create_register_handles(GArray *gdbstub_regs) 456 { 457 GArray *find_data = g_array_new(true, true, 458 sizeof(qemu_plugin_reg_descriptor)); 459 460 for (int i = 0; i < gdbstub_regs->len; i++) { 461 GDBRegDesc *grd = &g_array_index(gdbstub_regs, GDBRegDesc, i); 462 qemu_plugin_reg_descriptor desc; 463 464 /* skip "un-named" regs */ 465 if (!grd->name) { 466 continue; 467 } 468 469 /* Create a record for the plugin */ 470 desc.handle = GINT_TO_POINTER(grd->gdb_reg); 471 desc.name = g_intern_string(grd->name); 472 desc.feature = g_intern_string(grd->feature_name); 473 g_array_append_val(find_data, desc); 474 } 475 476 return find_data; 477 } 478 479 GArray *qemu_plugin_get_registers(void) 480 { 481 g_assert(current_cpu); 482 483 g_autoptr(GArray) regs = gdb_get_register_list(current_cpu); 484 return create_register_handles(regs); 485 } 486 487 int qemu_plugin_read_register(struct qemu_plugin_register *reg, GByteArray *buf) 488 { 489 g_assert(current_cpu); 490 491 return gdb_read_register(current_cpu, buf, GPOINTER_TO_INT(reg)); 492 } 493 494 struct qemu_plugin_scoreboard *qemu_plugin_scoreboard_new(size_t element_size) 495 { 496 return plugin_scoreboard_new(element_size); 497 } 498 499 void qemu_plugin_scoreboard_free(struct qemu_plugin_scoreboard *score) 500 { 501 plugin_scoreboard_free(score); 502 } 503 504 void *qemu_plugin_scoreboard_find(struct qemu_plugin_scoreboard *score, 505 unsigned int vcpu_index) 506 { 507 g_assert(vcpu_index < qemu_plugin_num_vcpus()); 508 /* we can't use g_array_index since entry size is not statically known */ 509 char *base_ptr = score->data->data; 510 return base_ptr + vcpu_index * g_array_get_element_size(score->data); 511 } 512 513 static uint64_t *plugin_u64_address(qemu_plugin_u64 entry, 514 unsigned int vcpu_index) 515 { 516 char *ptr = qemu_plugin_scoreboard_find(entry.score, vcpu_index); 517 return (uint64_t *)(ptr + entry.offset); 518 } 519 520 void qemu_plugin_u64_add(qemu_plugin_u64 entry, unsigned int vcpu_index, 521 uint64_t added) 522 { 523 *plugin_u64_address(entry, vcpu_index) += added; 524 } 525 526 uint64_t qemu_plugin_u64_get(qemu_plugin_u64 entry, 527 unsigned int vcpu_index) 528 { 529 return *plugin_u64_address(entry, vcpu_index); 530 } 531 532 void qemu_plugin_u64_set(qemu_plugin_u64 entry, unsigned int vcpu_index, 533 uint64_t val) 534 { 535 *plugin_u64_address(entry, vcpu_index) = val; 536 } 537 538 uint64_t qemu_plugin_u64_sum(qemu_plugin_u64 entry) 539 { 540 uint64_t total = 0; 541 for (int i = 0, n = qemu_plugin_num_vcpus(); i < n; ++i) { 542 total += qemu_plugin_u64_get(entry, i); 543 } 544 return total; 545 } 546