This patch adds a plugin API function that allows diverting the program counter during execution. A potential use case for this functionality is to skip over parts of the code, e.g., by hooking into a specific instruction and setting the PC to the next instruction in the callback.
Link: https://lists.nongnu.org/archive/html/qemu-devel/2025-08/msg00656.html Signed-off-by: Florian Hofhammer <[email protected]> --- include/qemu/qemu-plugin.h | 12 ++++++++++++ plugins/api.c | 9 +++++++++ 2 files changed, 21 insertions(+) diff --git a/include/qemu/qemu-plugin.h b/include/qemu/qemu-plugin.h index c450106af1..fe4e053c52 100644 --- a/include/qemu/qemu-plugin.h +++ b/include/qemu/qemu-plugin.h @@ -943,6 +943,18 @@ QEMU_PLUGIN_API int qemu_plugin_write_register(struct qemu_plugin_register *handle, GByteArray *buf); +/** + * qemu_plugin_set_pc() - set the program counter for the current vCPU + * + * @vaddr: the new virtual (guest) address for the program counter + * + * This function sets the program counter for the current vCPU to @vaddr and + * resumes execution at that address. This function does not return. + */ +QEMU_PLUGIN_API +G_NORETURN +void qemu_plugin_set_pc(uint64_t vaddr); + /** * qemu_plugin_read_memory_vaddr() - read from memory using a virtual address * diff --git a/plugins/api.c b/plugins/api.c index eac04cc1f6..0511b72ebb 100644 --- a/plugins/api.c +++ b/plugins/api.c @@ -41,6 +41,7 @@ #include "qemu/log.h" #include "system/memory.h" #include "tcg/tcg.h" +#include "exec/cpu-common.h" #include "exec/gdbstub.h" #include "exec/target_page.h" #include "exec/translation-block.h" @@ -457,6 +458,14 @@ int qemu_plugin_write_register(struct qemu_plugin_register *reg, return gdb_write_register(current_cpu, buf->data, GPOINTER_TO_INT(reg) - 1); } +void qemu_plugin_set_pc(uint64_t vaddr) +{ + g_assert(current_cpu); + + cpu_set_pc(current_cpu, vaddr); + cpu_loop_exit(current_cpu); +} + bool qemu_plugin_read_memory_vaddr(uint64_t addr, GByteArray *data, size_t len) { g_assert(current_cpu); -- 2.51.0
