Skip to content
c8kie edited this page Apr 12, 2017 · 1 revision

Using 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.

Writing plugins

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 in signals_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).

Use of signal-subscriber mechanism

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 via plugin_reg_signal(s1) function, where s1 is a string identificator that identifies the group of signals (i.e. "syscalls"). This function will return pointer to Signal_info, which should be used for signal generation.
  • To generate a signal you should use function plugin_gen_signal(si, s2, data, env), where si - 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 to void*, basically the useful info that signal is providing, and env - CPUArchState* var, that is widely used for analyses. The pair of s1 and s2 (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, where func - name of the function, that will process the signal, and s1 and s2 - 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 in init_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 in init_info structure, system will try to find and load mentioned dependency-plugins on load of your plugin.

List of qemu-provided callbacks

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
Clone this wiki locally