-
Notifications
You must be signed in to change notification settings - Fork 13
Plugins
You should run configure with parameter --enable-plugins
. After that just run make
and make install as usual
To load a plugin with name "example_name" you should:
- Stop qemu with
stop
command - Then execute
load_plugin example_name
command - Then happily continue the work of stopped qemu, you should be fine (sidenote: all commands should be executed via monitor)
You can also execute list_plugins
to see the list of loaded plugins, and
stop_plugin example_name
to stop plugin, as the name suggests.
All plugins should be located in path_to_qemu/plugins/plugins_src/
and be written in pure C.
Every plugin should have mandatory parts (for reference check existing plugins):
- Structure
init_info
. Here you can identify which signals your plugin would provide, dependencies on other plugins, and os version. If plugin generates signals, then they MUST be mentioned insignals_list
field, otherwise automatic loading of plugins wouldn't work and needed plugins will have to be loaded manually. - Function
pi_start
. Here you can subscribe to signals, define specific monitor commands for your plugin, register helper functions, and fill the table of functions that this plugin is providing in a straight-forward way, not through signals mechanism. Other parts of plugin are not obligatory, but are containing plugins' functionality.
Basically, you perform instrumentation by subscribing to specific signal and providing
function that will process gotten data. This would be performed during translation; if you
want to process data during actual execution, you should use helper functions (look at function
tcg_context_register_helper
and tcg_gen_callN
).
To make plugin actually buildable, you should add corresponding info to plugins_src/Makefile
and plugins_src/Makefile.plugins
(again, check how it is done for existing plugins for
reference).
To exchange the data between qemu and plugins, and between plugins themselves, we introduce signal-subsctiber mechanism. It works as following: firstly one of plugins registers signals which would be generated by it. Other plugin, that wishes to be notificated every time those signals emit, should subscribe to needed signals and set which function would process gotten data. At some place, that is specified in your plugin, a signal would be generated and data would be transfered to QEMU, which in it's turn would forward gotten data to all plugins, that were subscribed to this signal.
How exactly these should be used:
- First of all signals that would be provided by plugin should be mentioned in
init_info
structure (signal groups, to be more specific). - In
pi_start
those signals should be registered viaplugin_reg_signal(s1)
function, wheres1
is a string identificator that identifies the group of signals (i.e. "syscalls"). This function will return pointer toSignal_info
, which should be used for signal generation. - To generate a signal you should use function
plugin_gen_signal(si, s2, data, env)
, wheresi
- is Signal_info that you got after signal registration,s2
- is a string identificator that identifies specific signal inside of group (i.e. "file_open"),data
- data casted tovoid*
, basically the useful info that signal is providing, andenv
-CPUArchState* var
, that is widely used for analyses. The pair ofs1
ands2
(signals group and specific signal inside of it) should be unique to your signal, and currently, this should be tracked by programmer himself. - To subscribe to a signal you should use a
plugin_subscribe(func, s1, s2)
function, wherefunc
- name of the function, that will process the signal, ands1
ands2
- are string ids, same as above. When you will try to subscribe to signal, mechanism would check whether corresponding plugins has already been loaded, and if not, would try to find and load them. That's exactly the reason why you should have all your signals mentioned ininit_info
structure, because that's the place where loader would look for them. If you wouldn't define signals there, you would have to load needed plugins (providers) by hand. - It also worth mentioning, that if you set
dependencies
ininit_info
structure, system will try to find and load mentioned dependency-plugins on load of your plugin.
I hope these names are self-explanatory:
PLUGIN_QEMU_BEFORE_GEN_TB,
PLUGIN_QEMU_INSTR_TRANSLATE,
PLUGIN_QEMU_EXCEPTION,
PLUGIN_QEMU_EXCEPTION_HANDLER,
PLUGIN_QEMU_INSTRUCTION_EXCEPTION,
PLUGIN_QEMU_INTERRUPT,
PLUGIN_QEMU_TLB_SET_PAGE,
PLUGIN_QEMU_CPU_PAUSED,
PLUGIN_QEMU_PAGE_DIR_UPD,
PLUGIN_QEMU_CPUS_STOPPED