api.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528
  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. #include "qemu/osdep.h"
  38. #include "qemu/main-loop.h"
  39. #include "qemu/plugin.h"
  40. #include "qemu/log.h"
  41. #include "tcg/tcg.h"
  42. #include "exec/gdbstub.h"
  43. #include "exec/target_page.h"
  44. #include "exec/translation-block.h"
  45. #include "exec/translator.h"
  46. #include "disas/disas.h"
  47. #include "plugin.h"
  48. #ifndef CONFIG_USER_ONLY
  49. #include "qapi/error.h"
  50. #include "migration/blocker.h"
  51. #include "qemu/plugin-memory.h"
  52. #include "hw/boards.h"
  53. #else
  54. #include "qemu.h"
  55. #ifdef CONFIG_LINUX
  56. #include "loader.h"
  57. #endif
  58. #endif
  59. /* Uninstall and Reset handlers */
  60. void qemu_plugin_uninstall(qemu_plugin_id_t id, qemu_plugin_simple_cb_t cb)
  61. {
  62. plugin_reset_uninstall(id, cb, false);
  63. }
  64. void qemu_plugin_reset(qemu_plugin_id_t id, qemu_plugin_simple_cb_t cb)
  65. {
  66. plugin_reset_uninstall(id, cb, true);
  67. }
  68. /*
  69. * Plugin Register Functions
  70. *
  71. * This allows the plugin to register callbacks for various events
  72. * during the translation.
  73. */
  74. void qemu_plugin_register_vcpu_init_cb(qemu_plugin_id_t id,
  75. qemu_plugin_vcpu_simple_cb_t cb)
  76. {
  77. plugin_register_cb(id, QEMU_PLUGIN_EV_VCPU_INIT, cb);
  78. }
  79. void qemu_plugin_register_vcpu_exit_cb(qemu_plugin_id_t id,
  80. qemu_plugin_vcpu_simple_cb_t cb)
  81. {
  82. plugin_register_cb(id, QEMU_PLUGIN_EV_VCPU_EXIT, cb);
  83. }
  84. static bool tb_is_mem_only(void)
  85. {
  86. return tb_cflags(tcg_ctx->gen_tb) & CF_MEMI_ONLY;
  87. }
  88. void qemu_plugin_register_vcpu_tb_exec_cb(struct qemu_plugin_tb *tb,
  89. qemu_plugin_vcpu_udata_cb_t cb,
  90. enum qemu_plugin_cb_flags flags,
  91. void *udata)
  92. {
  93. if (!tb_is_mem_only()) {
  94. plugin_register_dyn_cb__udata(&tb->cbs, cb, flags, udata);
  95. }
  96. }
  97. void qemu_plugin_register_vcpu_tb_exec_cond_cb(struct qemu_plugin_tb *tb,
  98. qemu_plugin_vcpu_udata_cb_t cb,
  99. enum qemu_plugin_cb_flags flags,
  100. enum qemu_plugin_cond cond,
  101. qemu_plugin_u64 entry,
  102. uint64_t imm,
  103. void *udata)
  104. {
  105. if (cond == QEMU_PLUGIN_COND_NEVER || tb_is_mem_only()) {
  106. return;
  107. }
  108. if (cond == QEMU_PLUGIN_COND_ALWAYS) {
  109. qemu_plugin_register_vcpu_tb_exec_cb(tb, cb, flags, udata);
  110. return;
  111. }
  112. plugin_register_dyn_cond_cb__udata(&tb->cbs, cb, flags,
  113. cond, entry, imm, udata);
  114. }
  115. void qemu_plugin_register_vcpu_tb_exec_inline_per_vcpu(
  116. struct qemu_plugin_tb *tb,
  117. enum qemu_plugin_op op,
  118. qemu_plugin_u64 entry,
  119. uint64_t imm)
  120. {
  121. if (!tb_is_mem_only()) {
  122. plugin_register_inline_op_on_entry(&tb->cbs, 0, op, entry, imm);
  123. }
  124. }
  125. void qemu_plugin_register_vcpu_insn_exec_cb(struct qemu_plugin_insn *insn,
  126. qemu_plugin_vcpu_udata_cb_t cb,
  127. enum qemu_plugin_cb_flags flags,
  128. void *udata)
  129. {
  130. if (!tb_is_mem_only()) {
  131. plugin_register_dyn_cb__udata(&insn->insn_cbs, cb, flags, udata);
  132. }
  133. }
  134. void qemu_plugin_register_vcpu_insn_exec_cond_cb(
  135. struct qemu_plugin_insn *insn,
  136. qemu_plugin_vcpu_udata_cb_t cb,
  137. enum qemu_plugin_cb_flags flags,
  138. enum qemu_plugin_cond cond,
  139. qemu_plugin_u64 entry,
  140. uint64_t imm,
  141. void *udata)
  142. {
  143. if (cond == QEMU_PLUGIN_COND_NEVER || tb_is_mem_only()) {
  144. return;
  145. }
  146. if (cond == QEMU_PLUGIN_COND_ALWAYS) {
  147. qemu_plugin_register_vcpu_insn_exec_cb(insn, cb, flags, udata);
  148. return;
  149. }
  150. plugin_register_dyn_cond_cb__udata(&insn->insn_cbs, cb, flags,
  151. cond, entry, imm, udata);
  152. }
  153. void qemu_plugin_register_vcpu_insn_exec_inline_per_vcpu(
  154. struct qemu_plugin_insn *insn,
  155. enum qemu_plugin_op op,
  156. qemu_plugin_u64 entry,
  157. uint64_t imm)
  158. {
  159. if (!tb_is_mem_only()) {
  160. plugin_register_inline_op_on_entry(&insn->insn_cbs, 0, op, entry, imm);
  161. }
  162. }
  163. /*
  164. * We always plant memory instrumentation because they don't finalise until
  165. * after the operation has complete.
  166. */
  167. void qemu_plugin_register_vcpu_mem_cb(struct qemu_plugin_insn *insn,
  168. qemu_plugin_vcpu_mem_cb_t cb,
  169. enum qemu_plugin_cb_flags flags,
  170. enum qemu_plugin_mem_rw rw,
  171. void *udata)
  172. {
  173. plugin_register_vcpu_mem_cb(&insn->mem_cbs, cb, flags, rw, udata);
  174. }
  175. void qemu_plugin_register_vcpu_mem_inline_per_vcpu(
  176. struct qemu_plugin_insn *insn,
  177. enum qemu_plugin_mem_rw rw,
  178. enum qemu_plugin_op op,
  179. qemu_plugin_u64 entry,
  180. uint64_t imm)
  181. {
  182. plugin_register_inline_op_on_entry(&insn->mem_cbs, rw, op, entry, imm);
  183. }
  184. void qemu_plugin_register_vcpu_tb_trans_cb(qemu_plugin_id_t id,
  185. qemu_plugin_vcpu_tb_trans_cb_t cb)
  186. {
  187. plugin_register_cb(id, QEMU_PLUGIN_EV_VCPU_TB_TRANS, cb);
  188. }
  189. void qemu_plugin_register_vcpu_syscall_cb(qemu_plugin_id_t id,
  190. qemu_plugin_vcpu_syscall_cb_t cb)
  191. {
  192. plugin_register_cb(id, QEMU_PLUGIN_EV_VCPU_SYSCALL, cb);
  193. }
  194. void
  195. qemu_plugin_register_vcpu_syscall_ret_cb(qemu_plugin_id_t id,
  196. qemu_plugin_vcpu_syscall_ret_cb_t cb)
  197. {
  198. plugin_register_cb(id, QEMU_PLUGIN_EV_VCPU_SYSCALL_RET, cb);
  199. }
  200. /*
  201. * Plugin Queries
  202. *
  203. * These are queries that the plugin can make to gauge information
  204. * from our opaque data types. We do not want to leak internal details
  205. * here just information useful to the plugin.
  206. */
  207. /*
  208. * Translation block information:
  209. *
  210. * A plugin can query the virtual address of the start of the block
  211. * and the number of instructions in it. It can also get access to
  212. * each translated instruction.
  213. */
  214. size_t qemu_plugin_tb_n_insns(const struct qemu_plugin_tb *tb)
  215. {
  216. return tb->n;
  217. }
  218. uint64_t qemu_plugin_tb_vaddr(const struct qemu_plugin_tb *tb)
  219. {
  220. const DisasContextBase *db = tcg_ctx->plugin_db;
  221. return db->pc_first;
  222. }
  223. struct qemu_plugin_insn *
  224. qemu_plugin_tb_get_insn(const struct qemu_plugin_tb *tb, size_t idx)
  225. {
  226. struct qemu_plugin_insn *insn;
  227. if (unlikely(idx >= tb->n)) {
  228. return NULL;
  229. }
  230. insn = g_ptr_array_index(tb->insns, idx);
  231. return insn;
  232. }
  233. /*
  234. * Instruction information
  235. *
  236. * These queries allow the plugin to retrieve information about each
  237. * instruction being translated.
  238. */
  239. size_t qemu_plugin_insn_data(const struct qemu_plugin_insn *insn,
  240. void *dest, size_t len)
  241. {
  242. const DisasContextBase *db = tcg_ctx->plugin_db;
  243. len = MIN(len, insn->len);
  244. return translator_st(db, dest, insn->vaddr, len) ? len : 0;
  245. }
  246. size_t qemu_plugin_insn_size(const struct qemu_plugin_insn *insn)
  247. {
  248. return insn->len;
  249. }
  250. uint64_t qemu_plugin_insn_vaddr(const struct qemu_plugin_insn *insn)
  251. {
  252. return insn->vaddr;
  253. }
  254. void *qemu_plugin_insn_haddr(const struct qemu_plugin_insn *insn)
  255. {
  256. const DisasContextBase *db = tcg_ctx->plugin_db;
  257. vaddr page0_last = db->pc_first | ~qemu_target_page_mask();
  258. if (db->fake_insn) {
  259. return NULL;
  260. }
  261. /*
  262. * ??? The return value is not intended for use of host memory,
  263. * but as a proxy for address space and physical address.
  264. * Thus we are only interested in the first byte and do not
  265. * care about spanning pages.
  266. */
  267. if (insn->vaddr <= page0_last) {
  268. if (db->host_addr[0] == NULL) {
  269. return NULL;
  270. }
  271. return db->host_addr[0] + insn->vaddr - db->pc_first;
  272. } else {
  273. if (db->host_addr[1] == NULL) {
  274. return NULL;
  275. }
  276. return db->host_addr[1] + insn->vaddr - (page0_last + 1);
  277. }
  278. }
  279. char *qemu_plugin_insn_disas(const struct qemu_plugin_insn *insn)
  280. {
  281. return plugin_disas(tcg_ctx->cpu, tcg_ctx->plugin_db,
  282. insn->vaddr, insn->len);
  283. }
  284. const char *qemu_plugin_insn_symbol(const struct qemu_plugin_insn *insn)
  285. {
  286. const char *sym = lookup_symbol(insn->vaddr);
  287. return sym[0] != 0 ? sym : NULL;
  288. }
  289. /*
  290. * The memory queries allow the plugin to query information about a
  291. * memory access.
  292. */
  293. unsigned qemu_plugin_mem_size_shift(qemu_plugin_meminfo_t info)
  294. {
  295. MemOp op = get_memop(info);
  296. return op & MO_SIZE;
  297. }
  298. bool qemu_plugin_mem_is_sign_extended(qemu_plugin_meminfo_t info)
  299. {
  300. MemOp op = get_memop(info);
  301. return op & MO_SIGN;
  302. }
  303. bool qemu_plugin_mem_is_big_endian(qemu_plugin_meminfo_t info)
  304. {
  305. MemOp op = get_memop(info);
  306. return (op & MO_BSWAP) == MO_BE;
  307. }
  308. bool qemu_plugin_mem_is_store(qemu_plugin_meminfo_t info)
  309. {
  310. return get_plugin_meminfo_rw(info) & QEMU_PLUGIN_MEM_W;
  311. }
  312. qemu_plugin_mem_value qemu_plugin_mem_get_value(qemu_plugin_meminfo_t info)
  313. {
  314. uint64_t low = current_cpu->neg.plugin_mem_value_low;
  315. qemu_plugin_mem_value value;
  316. switch (qemu_plugin_mem_size_shift(info)) {
  317. case 0:
  318. value.type = QEMU_PLUGIN_MEM_VALUE_U8;
  319. value.data.u8 = (uint8_t)low;
  320. break;
  321. case 1:
  322. value.type = QEMU_PLUGIN_MEM_VALUE_U16;
  323. value.data.u16 = (uint16_t)low;
  324. break;
  325. case 2:
  326. value.type = QEMU_PLUGIN_MEM_VALUE_U32;
  327. value.data.u32 = (uint32_t)low;
  328. break;
  329. case 3:
  330. value.type = QEMU_PLUGIN_MEM_VALUE_U64;
  331. value.data.u64 = low;
  332. break;
  333. case 4:
  334. value.type = QEMU_PLUGIN_MEM_VALUE_U128;
  335. value.data.u128.low = low;
  336. value.data.u128.high = current_cpu->neg.plugin_mem_value_high;
  337. break;
  338. default:
  339. g_assert_not_reached();
  340. }
  341. return value;
  342. }
  343. int qemu_plugin_num_vcpus(void)
  344. {
  345. return plugin_num_vcpus();
  346. }
  347. /*
  348. * Plugin output
  349. */
  350. void qemu_plugin_outs(const char *string)
  351. {
  352. qemu_log_mask(CPU_LOG_PLUGIN, "%s", string);
  353. }
  354. bool qemu_plugin_bool_parse(const char *name, const char *value, bool *ret)
  355. {
  356. return name && value && qapi_bool_parse(name, value, ret, NULL);
  357. }
  358. /*
  359. * Create register handles.
  360. *
  361. * We need to create a handle for each register so the plugin
  362. * infrastructure can call gdbstub to read a register. They are
  363. * currently just a pointer encapsulation of the gdb_reg but in
  364. * future may hold internal plugin state so its important plugin
  365. * authors are not tempted to treat them as numbers.
  366. *
  367. * We also construct a result array with those handles and some
  368. * ancillary data the plugin might find useful.
  369. */
  370. static GArray *create_register_handles(GArray *gdbstub_regs)
  371. {
  372. GArray *find_data = g_array_new(true, true,
  373. sizeof(qemu_plugin_reg_descriptor));
  374. for (int i = 0; i < gdbstub_regs->len; i++) {
  375. GDBRegDesc *grd = &g_array_index(gdbstub_regs, GDBRegDesc, i);
  376. qemu_plugin_reg_descriptor desc;
  377. /* skip "un-named" regs */
  378. if (!grd->name) {
  379. continue;
  380. }
  381. /* Create a record for the plugin */
  382. desc.handle = GINT_TO_POINTER(grd->gdb_reg + 1);
  383. desc.name = g_intern_string(grd->name);
  384. desc.feature = g_intern_string(grd->feature_name);
  385. g_array_append_val(find_data, desc);
  386. }
  387. return find_data;
  388. }
  389. GArray *qemu_plugin_get_registers(void)
  390. {
  391. g_assert(current_cpu);
  392. g_autoptr(GArray) regs = gdb_get_register_list(current_cpu);
  393. return create_register_handles(regs);
  394. }
  395. bool qemu_plugin_read_memory_vaddr(uint64_t addr, GByteArray *data, size_t len)
  396. {
  397. g_assert(current_cpu);
  398. if (len == 0) {
  399. return false;
  400. }
  401. g_byte_array_set_size(data, len);
  402. int result = cpu_memory_rw_debug(current_cpu, addr, data->data,
  403. data->len, false);
  404. if (result < 0) {
  405. return false;
  406. }
  407. return true;
  408. }
  409. int qemu_plugin_read_register(struct qemu_plugin_register *reg, GByteArray *buf)
  410. {
  411. g_assert(current_cpu);
  412. return gdb_read_register(current_cpu, buf, GPOINTER_TO_INT(reg) - 1);
  413. }
  414. struct qemu_plugin_scoreboard *qemu_plugin_scoreboard_new(size_t element_size)
  415. {
  416. return plugin_scoreboard_new(element_size);
  417. }
  418. void qemu_plugin_scoreboard_free(struct qemu_plugin_scoreboard *score)
  419. {
  420. plugin_scoreboard_free(score);
  421. }
  422. void *qemu_plugin_scoreboard_find(struct qemu_plugin_scoreboard *score,
  423. unsigned int vcpu_index)
  424. {
  425. g_assert(vcpu_index < qemu_plugin_num_vcpus());
  426. /* we can't use g_array_index since entry size is not statically known */
  427. char *base_ptr = score->data->data;
  428. return base_ptr + vcpu_index * g_array_get_element_size(score->data);
  429. }
  430. static uint64_t *plugin_u64_address(qemu_plugin_u64 entry,
  431. unsigned int vcpu_index)
  432. {
  433. char *ptr = qemu_plugin_scoreboard_find(entry.score, vcpu_index);
  434. return (uint64_t *)(ptr + entry.offset);
  435. }
  436. void qemu_plugin_u64_add(qemu_plugin_u64 entry, unsigned int vcpu_index,
  437. uint64_t added)
  438. {
  439. *plugin_u64_address(entry, vcpu_index) += added;
  440. }
  441. uint64_t qemu_plugin_u64_get(qemu_plugin_u64 entry,
  442. unsigned int vcpu_index)
  443. {
  444. return *plugin_u64_address(entry, vcpu_index);
  445. }
  446. void qemu_plugin_u64_set(qemu_plugin_u64 entry, unsigned int vcpu_index,
  447. uint64_t val)
  448. {
  449. *plugin_u64_address(entry, vcpu_index) = val;
  450. }
  451. uint64_t qemu_plugin_u64_sum(qemu_plugin_u64 entry)
  452. {
  453. uint64_t total = 0;
  454. for (int i = 0, n = qemu_plugin_num_vcpus(); i < n; ++i) {
  455. total += qemu_plugin_u64_get(entry, i);
  456. }
  457. return total;
  458. }