Florian Hofhammer <florian.hofham...@epfl.ch> writes: > Hello,
(Added the *-user MAINTAINERS to the CC) > I'm currently working a lot with QEMU plugins for dynamic analysis of > userspace binaries (i.e., running under qemu-user). While working on > that, I found that the QEMU plugin API luckily has been getting more > and more capabilities with recent versions but that I'm still lacking > some functionality for my use cases. We are slowly expanding the capabilities although we don't want to go to fast lest we introduce APIs we need to fix later. That said we carry the warning that the plugin API "reserves the right to change or break the API should it need to do so" so hopefully plugin authors know what to expect. > More specifically, the "vcpu_syscall_cb" and "vcpu_syscall_ret" > callbacks already allow me to instrument syscall translation entry and > exit points. While the register read/write APIs also allow me to > modify register contents in my syscall callback implementations, there > is currently no good way to emulate a syscall myself in the plugin or > explicitly set the syscall return value (as it will be overwritten > with the original syscall's return value again, even if I set the > corresponding guest register). > > I was wondering whether the QEMU community would be open to extending > the plugin API so that a plugin can fully emulate a syscall without > the original syscall being executed by QEMU. I will defer to the *-user maintainers here. One thing we are keen to avoid is plugins being used as a mechanism to work around the GPL requirements of QEMU itself. It would be useful if you could outline the use case for a plugin doing the emulation itself? I'm fairly sure there are some syscalls where the plugin wouldn't be able to do an emulation that makes sense, for example fork/vfork/execve because QEMU itself has to do a bunch of housekeeping to keep track of stuff. Also while the write memory helpers can take the place of QEMU's own logic they come with a bunch of caveats about memory consistency. There is stuff we do during lock_user() which those mechanisms don't. > I had multiple approaches > for that in mind, with some working patches locally that I'd be happy > to share and build such a feature on: > > 1. Change the API of the existing callbacks so that the syscall entry > point callback returns "bool" instead of "void" and if any of the > registered callbacks returns true, execution of the actual syscall is > skipped. > 2. Introduce a new API function that sets a flag for a specific > syscall to be skipped: > 2a. A function that's called once in the manner of "always skip the > syscall with this specific syscall number" or > 2b. a function that's called every time in the syscall entry point > callback in the manner of "skip this specific instance of the > syscall". > > I'd be happy to get your opinion on those proposals and to > develop/submit the corresponding patches! Another option would be to have a set_pc function that would restart the execution at new PC. Then the vcpu_syscall_cb callback could set the PC to post the syscall with whatever state it wants to set up. > > Thanks in advance and best regards, > Florian -- Alex Bennée Virtualisation Tech Lead @ Linaro