Callback

Struct Callback 

Source
pub struct Callback(/* private fields */);
Expand description

A reference to a given callback slot which can be used to install, enable, disable, or otherwise reference, a closure-based callback.

Since this is a reference to a callback slot and does not include storage for the callback itself, it can be trivially copied, as well as included in the callback itself (for the purposes of enabling/disabling).

§Example

use panda::prelude::*;
use panda::Callback;

let mut count = 0;
let bb_callback = Callback::new();
bb_callback.before_block_exec(move |_, _| {
    count += 1;
    println!("Basic block #{}", count);

    if count > 5 {
        bb_callback.disable();
    }
});

Panda::new()
   .generic("x86_64")
   .run();

§Note

Callback closures must have a static lifetime in order to live past the end of the function. This means that the only references a callback can include are references to static variables or leaked objects on the heap (See Box::leak for more info).

If you’d like to reference shared data without leaking, this can be accomplished via reference counting. See Arc for more info. If you want to capture data owned by the current function without sharing it, you can mark your closure as move in order to move all the variables you capture into your closure. (Such as in the above example, where count is moved into the closure for modification)

Implementations§

Source§

impl Callback

Source

pub fn new() -> Self

Create a new callback slot which can then be used to install or modify a given callback.

Examples found in repository?
examples/ppp_callback_export.rs (line 12)
10fn main() {
11    let mut i = 0;
12    let callback = panda::Callback::new();
13    callback.before_block_exec(move |cpu, _| {
14        if i % 2 == 0 {
15            on_every_even_block::trigger(cpu);
16        } else {
17            if on_every_odd_block::trigger(cpu) {
18                callback.disable();
19            }
20        }
21        i += 1;
22    });
23
24    on_every_even_block::add_callback(on_even_test);
25    on_every_odd_block::add_callback(on_odd_test);
26
27    Panda::new().generic("x86_64").replay("test").run();
28}
More examples
Hide additional examples
examples/closures.rs (line 8)
5fn main() {
6    // Callbacks can capture state
7    let mut count = 1;
8    let bb_callback = Callback::new();
9    bb_callback.before_block_exec(move |cpu, _| {
10        println!("Block: {} | PC: {:#x?}", count, panda::regs::get_pc(cpu));
11        count += 1;
12        if count > 5 {
13            // callbacks can disable themselves by capturing a copy
14            // of the `Callback` reference to it
15            bb_callback.disable();
16        }
17    });
18
19    // If you don't need to enable and disable the callback, you can just
20    // use method chaining instead of assigning to a variable
21    PppCallback::new().on_rec_auxv(|_, _, auxv| {
22        // print out the auxillary vector when any process starts
23        dbg!(auxv);
24    });
25
26    Panda::new().generic("x86_64").replay("test").run();
27}
Source

pub fn enable(&self)

Enable the callback assigned to the given slot, if any.

Source

pub fn disable(&self)

Disable the callback assigned to the given slot, if any.

Examples found in repository?
examples/ppp_callback_export.rs (line 18)
10fn main() {
11    let mut i = 0;
12    let callback = panda::Callback::new();
13    callback.before_block_exec(move |cpu, _| {
14        if i % 2 == 0 {
15            on_every_even_block::trigger(cpu);
16        } else {
17            if on_every_odd_block::trigger(cpu) {
18                callback.disable();
19            }
20        }
21        i += 1;
22    });
23
24    on_every_even_block::add_callback(on_even_test);
25    on_every_odd_block::add_callback(on_odd_test);
26
27    Panda::new().generic("x86_64").replay("test").run();
28}
More examples
Hide additional examples
examples/closures.rs (line 15)
5fn main() {
6    // Callbacks can capture state
7    let mut count = 1;
8    let bb_callback = Callback::new();
9    bb_callback.before_block_exec(move |cpu, _| {
10        println!("Block: {} | PC: {:#x?}", count, panda::regs::get_pc(cpu));
11        count += 1;
12        if count > 5 {
13            // callbacks can disable themselves by capturing a copy
14            // of the `Callback` reference to it
15            bb_callback.disable();
16        }
17    });
18
19    // If you don't need to enable and disable the callback, you can just
20    // use method chaining instead of assigning to a variable
21    PppCallback::new().on_rec_auxv(|_, _, auxv| {
22        // print out the auxillary vector when any process starts
23        dbg!(auxv);
24    });
25
26    Panda::new().generic("x86_64").replay("test").run();
27}
Source§

impl Callback

Source

pub fn before_block_translate<F>(self, callback: F)
where F: FnMut(&mut CPUState, target_ptr_t) + 'static,

Installs the given callback, assigning it to this Callback’s slot. Any callbacks previously stored in that slot will be freed.

Called before translation of each basic block.

Callback ID: PANDA_CB_BEFORE_BLOCK_TRANSLATE

Arguments:
 CPUState *env:   the current CPU state
 target_ptr_t pc: the guest PC we are about to translate

Helper call location: cpu-exec.c

Return value:
 none
Source

pub fn after_block_translate<F>(self, callback: F)
where F: FnMut(&mut CPUState, &mut TranslationBlock) + 'static,

Installs the given callback, assigning it to this Callback’s slot. Any callbacks previously stored in that slot will be freed.

Called after execution of every basic block. If exitCode > TB_EXIT_IDX1, then the block exited early.

Callback ID: PANDA_CB_AFTER_BLOCK_EXEC

   after_block_exec:

   Arguments:
    CPUState *env:        the current CPU state
    TranslationBlock *tb: the TB we just executed
    uint8_t exitCode:     why the block execution exited

   Helper call location: cpu-exec.c

   Return value:
    none
Source

pub fn before_block_exec_invalidate_opt<F>(self, callback: F)
where F: FnMut(&mut CPUState, &mut TranslationBlock) -> bool + 'static,

Installs the given callback, assigning it to this Callback’s slot. Any callbacks previously stored in that slot will be freed.

Called before execution of every basic block, with the option to invalidate the TB.

Callback ID: PANDA_CB_BEFORE_BLOCK_EXEC_INVALIDATE_OPT

   before_block_exec_invalidate_opt:

   Arguments:
    CPUState *env:        the current CPU state
    TranslationBlock *tb: the TB we are about to execute

   Helper call location: cpu-exec.c (indirectly)

   Return value:
    true if we should invalidate the current translation block
    and retranslate, false otherwise.
Source

pub fn before_block_exec<F>(self, callback: F)
where F: FnMut(&mut CPUState, &mut TranslationBlock) + 'static,

Installs the given callback, assigning it to this Callback’s slot. Any callbacks previously stored in that slot will be freed.

Called before execution of every basic block.

Callback ID: PANDA_CB_BEFORE_BLOCK_EXEC

   Arguments:
    CPUState *env:        the current CPU state
    TranslationBlock *tb: the TB we are about to execute

   Helper call location: cpu-exec.c

   Return value:
    none
Examples found in repository?
examples/ppp_callback_export.rs (lines 13-22)
10fn main() {
11    let mut i = 0;
12    let callback = panda::Callback::new();
13    callback.before_block_exec(move |cpu, _| {
14        if i % 2 == 0 {
15            on_every_even_block::trigger(cpu);
16        } else {
17            if on_every_odd_block::trigger(cpu) {
18                callback.disable();
19            }
20        }
21        i += 1;
22    });
23
24    on_every_even_block::add_callback(on_even_test);
25    on_every_odd_block::add_callback(on_odd_test);
26
27    Panda::new().generic("x86_64").replay("test").run();
28}
More examples
Hide additional examples
examples/closures.rs (lines 9-17)
5fn main() {
6    // Callbacks can capture state
7    let mut count = 1;
8    let bb_callback = Callback::new();
9    bb_callback.before_block_exec(move |cpu, _| {
10        println!("Block: {} | PC: {:#x?}", count, panda::regs::get_pc(cpu));
11        count += 1;
12        if count > 5 {
13            // callbacks can disable themselves by capturing a copy
14            // of the `Callback` reference to it
15            bb_callback.disable();
16        }
17    });
18
19    // If you don't need to enable and disable the callback, you can just
20    // use method chaining instead of assigning to a variable
21    PppCallback::new().on_rec_auxv(|_, _, auxv| {
22        // print out the auxillary vector when any process starts
23        dbg!(auxv);
24    });
25
26    Panda::new().generic("x86_64").replay("test").run();
27}
Source

pub fn after_block_exec<F>(self, callback: F)
where F: FnMut(&mut CPUState, &mut TranslationBlock, u8) + 'static,

Installs the given callback, assigning it to this Callback’s slot. Any callbacks previously stored in that slot will be freed.

Called after execution of every basic block. If exitCode > TB_EXIT_IDX1, then the block exited early.

Callback ID: PANDA_CB_AFTER_BLOCK_EXEC

   Arguments:
    CPUState *env:        the current CPU state
    TranslationBlock *tb: the TB we just executed
    uint8_t exitCode:     why the block execution exited

   Helper call location: cpu-exec.c

   Return value:
    none
Source

pub fn insn_translate<F>(self, callback: F)
where F: FnMut(&mut CPUState, target_ptr_t) -> bool + 'static,

Installs the given callback, assigning it to this Callback’s slot. Any callbacks previously stored in that slot will be freed.

Called before the translation of each instruction.

Callback ID: PANDA_CB_INSN_TRANSLATE

   Arguments:
    CPUState *env:   the current CPU state
    target_ptr_t pc: the guest PC we are about to translate

   Helper call location: panda/target/ARCH/translate.c

   Return value:
    true if PANDA should insert instrumentation into the generated code,
    false otherwise

   Notes:
    This allows a plugin writer to instrument only a small number of
    instructions, avoiding the performance hit of instrumenting everything.
    If you do want to instrument every single instruction, just return
    true. See the documentation for PANDA_CB_INSN_EXEC for more detail.
Source

pub fn insn_exec<F>(self, callback: F)
where F: FnMut(&mut CPUState, target_ptr_t) + 'static,

Installs the given callback, assigning it to this Callback’s slot. Any callbacks previously stored in that slot will be freed.

Called before execution of any instruction identified by the PANDA_CB_INSN_TRANSLATE callback.

Callback ID: PANDA_CB_INSN_EXEC

   Arguments:
    CPUState *env:   the current CPU state
    target_ptr_t pc: the guest PC we are about to execute

   Helper call location: TBA

   Return value:
    unused

   Notes:
    This instrumentation is implemented by generating a call to a
    helper function just before the instruction itself is generated.
    This is fairly expensive, which is why it's only enabled via
    the PANDA_CB_INSN_TRANSLATE callback.
Source

pub fn after_insn_translate<F>(self, callback: F)
where F: FnMut(&mut CPUState, target_ptr_t) -> bool + 'static,

Installs the given callback, assigning it to this Callback’s slot. Any callbacks previously stored in that slot will be freed.

Called after the translation of each instruction.

Callback ID: PANDA_CB_AFTER_INSN_TRANSLATE

   Arguments:
    CPUState *env:   the current CPU state
    target_ptr_t pc: the next guest PC we've translated

   Helper call location: panda/target/ARCH/translate.c

   Return value:
    true if PANDA should insert instrumentation into the generated code,
    false otherwise

   Notes:
    See `insn_translate`, callbacks are registered via PANDA_CB_AFTER_INSN_EXEC
Source

pub fn after_insn_exec<F>(self, callback: F)
where F: FnMut(&mut CPUState, target_ptr_t) + 'static,

Installs the given callback, assigning it to this Callback’s slot. Any callbacks previously stored in that slot will be freed.

Called after execution of an instruction identified by the PANDA_CB_AFTER_INSN_TRANSLATE callback

Callback ID: PANDA_CB_AFTER_INSN_EXEC

   Arguments:
    CPUState *env:   the current CPU state
    target_ptr_t pc: the next guest PC already executed

   Helper call location: TBA

   Return value:
    unused

   Notes:
    See `insn_exec`. Enabled via the PANDA_CB_AFTER_INSN_TRANSLATE callback.
Source

pub fn virt_mem_before_read<F>(self, callback: F)
where F: FnMut(&mut CPUState, target_ptr_t, target_ptr_t, usize) + 'static,

Installs the given callback, assigning it to this Callback’s slot. Any callbacks previously stored in that slot will be freed.

Called before memory is read.

Callback ID: PANDA_CB_VIRT_MEM_BEFORE_READ

   Arguments:
    CPUState *env:     the current CPU state
    target_ptr_t pc:   the guest PC doing the read
    target_ptr_t addr: the (virtual) address being read
    size_t size:       the size of the read

   Helper call location: TBA

   Return value:
    none
Source

pub fn virt_mem_before_write<F>(self, callback: F)
where F: FnMut(&mut CPUState, target_ptr_t, target_ptr_t, usize, *mut u8) + 'static,

Installs the given callback, assigning it to this Callback’s slot. Any callbacks previously stored in that slot will be freed.

Called before memory is written.

Callback ID: PANDA_CB_VIRT_MEM_BEFORE_WRITE

   Arguments:
    CPUState *env:     the current CPU state
    target_ptr_t pc:   the guest PC doing the write
    target_ptr_t addr: the (virtual) address being written
    size_t size:       the size of the write
    uint8_t *buf:      pointer to the data that is to be written

   Helper call location: TBA

   Return value:
    none
Source

pub fn phys_mem_before_read<F>(self, callback: F)
where F: FnMut(&mut CPUState, target_ptr_t, target_ptr_t, usize) + 'static,

Installs the given callback, assigning it to this Callback’s slot. Any callbacks previously stored in that slot will be freed.

Called after memory is read.

Callback ID: PANDA_CB_PHYS_MEM_BEFORE_READ

   Arguments:
    CPUState *env:     the current CPU state
    target_ptr_t pc:   the guest PC doing the read
    target_ptr_t addr: the (physical) address being read
    size_t size:       the size of the read

   Helper call location: TBA

   Return value:
    none
Source

pub fn phys_mem_before_write<F>(self, callback: F)
where F: FnMut(&mut CPUState, target_ptr_t, target_ptr_t, usize, *mut u8) + 'static,

Installs the given callback, assigning it to this Callback’s slot. Any callbacks previously stored in that slot will be freed.

Called before memory is written.

Callback ID: PANDA_CB_PHYS_MEM_BEFORE_WRITE

   Arguments:
    CPUState *env:     the current CPU state
    target_ptr_t pc:   the guest PC doing the write
    target_ptr_t addr: the (physical) address being written
    size_t size:       the size of the write
    uint8_t *buf:      pointer to the data that is to be written

   Helper call location: TBA

   Return value:
    none
Source

pub fn virt_mem_after_read<F>(self, callback: F)
where F: FnMut(&mut CPUState, target_ptr_t, target_ptr_t, usize, *mut u8) + 'static,

Installs the given callback, assigning it to this Callback’s slot. Any callbacks previously stored in that slot will be freed.

Called after memory is read.

Callback ID: PANDA_CB_VIRT_MEM_AFTER_READ

   Arguments:
    CPUState *env:     the current CPU state
    target_ptr_t pc:   the guest PC doing the read
    target_ptr_t addr: the (virtual) address being read
    size_t size:       the size of the read
    uint8_t *buf:      pointer to data just read

   Helper call location: TBA

   Return value:
    none
Source

pub fn virt_mem_after_write<F>(self, callback: F)
where F: FnMut(&mut CPUState, target_ptr_t, target_ptr_t, usize, *mut u8) + 'static,

Installs the given callback, assigning it to this Callback’s slot. Any callbacks previously stored in that slot will be freed.

Called after memory is written.

Callback ID: PANDA_CB_VIRT_MEM_AFTER_WRITE

   Arguments:
    CPUState *env:     the current CPU state
    target_ptr_t pc:   the guest PC doing the write
    target_ptr_t addr: the (virtual) address being written
    size_t size:       the size of the write
    uint8_t *buf:      pointer to the data that was written

   Helper call location: TBA

   Return value:
    none
Source

pub fn phys_mem_after_read<F>(self, callback: F)
where F: FnMut(&mut CPUState, target_ptr_t, target_ptr_t, usize, *mut u8) + 'static,

Installs the given callback, assigning it to this Callback’s slot. Any callbacks previously stored in that slot will be freed.

Called after memory is read.

Callback ID: PANDA_CB_PHYS_MEM_AFTER_READ

   Arguments:
    CPUState *env:     the current CPU state
    target_ptr_t pc:   the guest PC doing the read
    target_ptr_t addr: the (physical) address being read
    size_t size:       the size of the read
    uint8_t *buf:      pointer to data just read

   Helper call location: TBA

   Return value:
    none
Source

pub fn phys_mem_after_write<F>(self, callback: F)
where F: FnMut(&mut CPUState, target_ptr_t, target_ptr_t, usize, *mut u8) + 'static,

Installs the given callback, assigning it to this Callback’s slot. Any callbacks previously stored in that slot will be freed.

Called after memory is written.

Callback ID: PANDA_CB_PHYS_MEM_AFTER_WRITE

   Arguments:
    CPUState *env:     the current CPU state
    target_ptr_t pc:   the guest PC doing the write
    target_ptr_t addr: the (physical) address being written
    size_t size:       the size of the write
    uint8_t *buf:      pointer to the data that was written

   Helper call location: TBA

   Return value:
    none
Source

pub fn mmio_after_read<F>(self, callback: F)
where F: FnMut(&mut CPUState, target_ptr_t, target_ptr_t, usize, *mut u64) + 'static,

Installs the given callback, assigning it to this Callback’s slot. Any callbacks previously stored in that slot will be freed.

Called after MMIO memory is read.

Callback ID: PANDA_CB_MMIO_AFTER_READ

   Arguments:
    CPUState *env:          the current CPU state
    target_ptr_t physaddr:  the physical address being read from
    target_ptr_t vaddr:     the virtual address being read from
    size_t size:            the size of the read
    uin64_t *val:           the value being read

   Helper call location: cputlb.c

   Return value:
    none
Source

pub fn mmio_before_write<F>(self, callback: F)
where F: FnMut(&mut CPUState, target_ptr_t, target_ptr_t, usize, *mut u64) + 'static,

Installs the given callback, assigning it to this Callback’s slot. Any callbacks previously stored in that slot will be freed.

Called after MMIO memory is written to.

Callback ID: PANDA_CB_MMIO_BEFORE_WRITE

   Arguments:
    CPUState *env:          the current CPU state
    target_ptr_t physaddr:  the physical address being written to
    target_ptr_t vaddr:     the virtual address being written to
    size_t size:            the size of the write
    uin64_t *val:           the value being written

   Helper call location: cputlb.c

   Return value:
    none
Source

pub fn hd_read<F>(self, callback: F)
where F: FnMut(&mut CPUState) + 'static,

Installs the given callback, assigning it to this Callback’s slot. Any callbacks previously stored in that slot will be freed.

Called when there is a hard drive read

Callback ID: PANDA_CB_HD_READ

   Note: this was added to panda_cb_type enum but no callback prototype inserted
   Here is a stub.  I'm not sure what the args should be.
   Arguments
   CPUState *env
Source

pub fn hd_write<F>(self, callback: F)
where F: FnMut(&mut CPUState) + 'static,

Installs the given callback, assigning it to this Callback’s slot. Any callbacks previously stored in that slot will be freed.

Called when there is a hard drive write

Callback ID: PANDA_CB_HD_WRITE

   Note: this was added to panda_cb_type enum but no callback prototype inserted
   Here is a stub.  I'm not sure what the args should be.
   Arguments
   CPUState *env
Source

pub fn guest_hypercall<F>(self, callback: F)
where F: FnMut(&mut CPUState) -> bool + 'static,

Installs the given callback, assigning it to this Callback’s slot. Any callbacks previously stored in that slot will be freed.

Called when a program inside the guest makes a hypercall to pass information from inside the guest to a plugin

Callback ID: PANDA_CB_GUEST_HYPERCALL

   Arguments:
    CPUState *env: the current CPU state

   Helper call location: target/i386/misc_helper.c

   Return value:
    true if the callback has processed the hypercall, false if the
    hypercall has been ignored.

   Notes:
    On x86, this is called whenever CPUID is executed. On ARM, the
    MCR instructions is used. Plugins should check for magic values
    in the registers to determine if it really is a guest hypercall.
    Parameters can be passed in other registers. If the plugin
    processes the hypercall, it should return true so the execution
    of the normal instruction is skipped.
Source

pub fn monitor<F>(self, callback: F)
where F: FnMut(&mut Monitor, *const u8) + 'static,

Installs the given callback, assigning it to this Callback’s slot. Any callbacks previously stored in that slot will be freed.

Called when someone uses the plugin_cmd monitor command.

Callback ID: PANDA_CB_MONITOR

   Arguments:
    Monitor *mon:    a pointer to the Monitor
    const char *cmd: the command string passed to plugin_cmd

   Helper call location: TBA

   Return value:
    unused

   Notes:
    The command is passed as a single string. No parsing is performed
    on the string before it is passed to the plugin, so each plugin
    must parse the string as it deems appropriate (e.g. by using strtok
    and getopt) to do more complex option processing.
    It is recommended that each plugin implementing this callback respond
    to the "help" message by listing the commands supported by the plugin.
    Note that every loaded plugin will have the opportunity to respond to
    each plugin_cmd; thus it is a good idea to ensure that your plugin's
    monitor commands are uniquely named, e.g. by using the plugin name
    as a prefix ("sample_do_foo" rather than "do_foo").
Source

pub fn cpu_restore_state<F>(self, callback: F)
where F: FnMut(&mut CPUState, &mut TranslationBlock) + 'static,

Installs the given callback, assigning it to this Callback’s slot. Any callbacks previously stored in that slot will be freed.

Called inside of cpu_restore_state(), when there is a CPU fault/exception.

Callback ID: PANDA_CB_CPU_RESTORE_STATE

   Arguments:
    CPUState *env:        the current CPU state
    TranslationBlock *tb: the current translation block

   Helper call location: translate-all.c

   Return value:
    none
Source

pub fn before_loadvm<F>(self, callback: F)
where F: FnMut() + 'static,

Installs the given callback, assigning it to this Callback’s slot. Any callbacks previously stored in that slot will be freed.

Called at start of replay, before loadvm is called. This allows us to hook devices’ loadvm handlers. Remember to unregister the existing handler for the device first. See the example in the sample plugin.

Callback ID: PANDA_CB_BEFORE_LOADVM

   Arguments:
    none

   Helper call location: TBA

   Return value:
    unused
Source

pub fn asid_changed<F>(self, callback: F)
where F: FnMut(&mut CPUState, target_ptr_t, target_ptr_t) -> bool + 'static,

Installs the given callback, assigning it to this Callback’s slot. Any callbacks previously stored in that slot will be freed.

Called when asid changes.

Callback ID: PANDA_CB_ASID_CHANGED

   Arguments:
    CPUState *env:       pointer to CPUState
    target_ptr_t oldval: old asid value
    target_ptr_t newval: new asid value

   Helper call location: target/i386/helper.c, target/arm/helper.c

   Return value:
    true if the asid should be prevented from being changed
    false otherwise

   Notes:
    The callback is only invoked implemented for x86 and ARM.
    This should break plugins which rely on it to detect context
    switches in any other architecture.
Source

pub fn replay_hd_transfer<F>(self, callback: F)
where F: FnMut(&mut CPUState, u32, target_ptr_t, target_ptr_t, usize) + 'static,

Installs the given callback, assigning it to this Callback’s slot. Any callbacks previously stored in that slot will be freed.

In replay only. Some kind of data transfer involving hard drive.

Callback ID:     PANDA_CB_REPLAY_HD_TRANSFER,

   Arguments:
    CPUState *env:          pointer to CPUState
    uint32_t type:          type of transfer  (Hd_transfer_type)
    target_ptr_t src_addr:  address for src
    target_ptr_t dest_addr: address for dest
    size_t num_bytes:       size of transfer in bytes

   Helper call location: panda/src/rr/rr_log.c

   Return value:
    none

   Helper call location: TBA

   Notes:
    Unlike most callbacks, this is neither a "before" or "after" callback.
    In replay the transfer doesn't really happen. We are *at* the point at
    which it happened, really.
Source

pub fn replay_net_transfer<F>(self, callback: F)
where F: FnMut(&mut CPUState, u32, u64, u64, usize) + 'static,

Installs the given callback, assigning it to this Callback’s slot. Any callbacks previously stored in that slot will be freed.

In replay only, some kind of data transfer within the network card (currently, only the E1000 is supported).

Callback ID:     PANDA_CB_REPLAY_NET_TRANSFER,

   Arguments:
    CPUState *env:          pointer to CPUState
    uint32_t type:          type of transfer  (Net_transfer_type)
    uint64_t src_addr:      address for src
    uint64_t dest_addr:     address for dest
    size_t num_bytes:       size of transfer in bytes

   Helper call location: panda/src/rr/rr_log.c

   Return value:
    none

   Notes:
    Unlike most callbacks, this is neither a "before" or "after" callback.
    In replay the transfer doesn't really happen. We are *at* the point at
    which it happened, really.
    Also, the src_addr and dest_addr may be for either host (ie. a location
    in the emulated network device) or guest, depending upon the type.
Source

pub fn replay_serial_receive<F>(self, callback: F)
where F: FnMut(&mut CPUState, target_ptr_t, u8) + 'static,

Installs the given callback, assigning it to this Callback’s slot. Any callbacks previously stored in that slot will be freed.

In replay only, called when a byte is received on the serial port.

Callback ID:     PANDA_CB_REPLAY_SERIAL_RECEIVE,

   Arguments:
    CPUState *env:          pointer to CPUState
    target_ptr_t fifo_addr: address of the data within the fifo
    uint8_t value:          value received

   Helper call location: panda/src/rr/rr_log.c

   Return value:
    unused
Source

pub fn replay_serial_read<F>(self, callback: F)
where F: FnMut(&mut CPUState, target_ptr_t, u32, u8) + 'static,

Installs the given callback, assigning it to this Callback’s slot. Any callbacks previously stored in that slot will be freed.

In replay only, called when a byte read from the serial RX FIFO

Callback ID:     PANDA_CB_REPLAY_SERIAL_READ,

   Arguments:
    CPUState *env:          pointer to CPUState
    target_ptr_t fifo_addr: address of the data within the fifo (source)
    uint32_t port_addr:     address of the IO port where data is being read (destination)
    uint8_t value:          value read

   Helper call location: panda/src/rr/rr_log.c

   Return value:
    none
Source

pub fn replay_serial_send<F>(self, callback: F)
where F: FnMut(&mut CPUState, target_ptr_t, u8) + 'static,

Installs the given callback, assigning it to this Callback’s slot. Any callbacks previously stored in that slot will be freed.

In replay only, called when a byte is sent on the serial port.

Callback ID:     PANDA_CB_REPLAY_SERIAL_SEND,

   Arguments:
    CPUState *env:          pointer to CPUState
    target_ptr_t fifo_addr: address of the data within the fifo
    uint8_t value:          value received

   Helper call location: panda/src/rr/rr_log.c

   Return value:
    none
Source

pub fn replay_serial_write<F>(self, callback: F)
where F: FnMut(&mut CPUState, target_ptr_t, u32, u8) + 'static,

Installs the given callback, assigning it to this Callback’s slot. Any callbacks previously stored in that slot will be freed.

In replay only, called when a byte written to the serial TX FIFO

Callback ID:     PANDA_CB_REPLAY_SERIAL_WRITE,


   Arguments:
    CPUState *env:          pointer to CPUState
    target_ptr_t fifo_addr: address of the data within the fifo (source)
    uint32_t port_addr:     address of the IO port where data is being read (destination)
    uint8_t value:          value read

   Helper call location: panda/src/rr/rr_log.c

   Return value:
    none
Source

pub fn replay_before_dma<F>(self, callback: F)
where F: FnMut(&mut CPUState, *const u8, hwaddr, usize, bool) + 'static,

Installs the given callback, assigning it to this Callback’s slot. Any callbacks previously stored in that slot will be freed.

In replay only. We are about to dma between qemu buffer and guest memory.

Callback ID:     PANDA_CB_REPLAY_BEFORE_DMA,

   Arguments:
    CPUState *env:      pointer to CPUState
    const uint8_t *buf: pointer to the QEMU's device buffer ussed in the transfer
    hwaddr addr:        address written to in the guest RAM
    size_t size:        size of transfer
    bool is_write:      indicates whether the DMA transfer writes to memory

   Helper call location: exec.c

   Return value:
    none
Source

pub fn replay_after_dma<F>(self, callback: F)
where F: FnMut(&mut CPUState, *mut u8, hwaddr, usize, bool) + 'static,

Installs the given callback, assigning it to this Callback’s slot. Any callbacks previously stored in that slot will be freed.

In replay only, we are about to dma between qemu buffer and guest memory

Callback ID:     PANDA_CB_REPLAY_AFTER_DMA,

   Arguments:
    CPUState *env:      pointer to CPUState
    const uint8_t *buf: pointer to the QEMU's device buffer ussed in the transfer
    hwaddr addr:        address written to in the guest RAM
    size_t size:        size of transfer
    bool is_write:      indicates whether the DMA transfer writes to memory

   Helper call location: exec.c

   Return value:
    none
Source

pub fn replay_handle_packet<F>(self, callback: F)
where F: FnMut(&mut CPUState, *mut u8, usize, u8, u64) + 'static,

Installs the given callback, assigning it to this Callback’s slot. Any callbacks previously stored in that slot will be freed.

In replay only, we have a packet (incoming / outgoing) in hand.

Callback ID:   PANDA_CB_REPLAY_HANDLE_PACKET,

   Arguments:
    CPUState *env:         pointer to CPUState
    uint8_t *buf:          buffer containing packet data
    size_t size:           num bytes in buffer
    uint8_t direction:     either `PANDA_NET_RX` or `PANDA_NET_TX`
    uint64_t buf_addr_rec: the address of `buf` at the time of recording

   Helper call location: panda/src/rr/rr_log.c

   Return value:
    none

   Notes:
    `buf_addr_rec` corresponds to the address of the device buffer of
    the emulated NIC. I.e. it is the address of a VM-host-side buffer.
    It is useful for implementing network tainting in an OS-agnostic
    way, in conjunction with taint2_label_io().

    FIXME: The `buf_addr_rec` maps to the `uint8_t *buf` field of the
    internal `RR_handle_packet_args` struct. The field is dumped/loaded
    to/from the trace without proper serialization/deserialization. As
    a result, a 64bit build of PANDA will not be able to process traces
    produced by a 32bit of PANDA, and vice-versa.
    There are more internal structs that suffer from the same issue.
    This is an oversight that will eventually be fixed. But as the
    real impact is minimal (virtually nobody uses 32bit builds),
    the fix has a very low priority in the bugfix list.
Source

pub fn after_cpu_exec_enter<F>(self, callback: F)
where F: FnMut(&mut CPUState) + 'static,

Installs the given callback, assigning it to this Callback’s slot. Any callbacks previously stored in that slot will be freed.

Called after cpu_exec calls cpu_exec_enter function.

Callback ID: PANDA_CB_AFTER_CPU_EXEC_ENTER

   Arguments:
    CPUState *env: the current CPU state

   Helper call location: cpu-exec.c

   Return value:
    none
Source

pub fn before_cpu_exec_exit<F>(self, callback: F)
where F: FnMut(&mut CPUState, bool) + 'static,

Installs the given callback, assigning it to this Callback’s slot. Any callbacks previously stored in that slot will be freed.

Called before cpu_exec calls cpu_exec_exit function.

Callback ID: PANDA_CB_BEFORE_CPU_EXEC_EXIT

   Arguments:
    CPUState *env: the current CPU state
    bool ranBlock: true if ran a block since previous cpu_exec_enter

   Helper call location: cpu-exec.c

   Return value:
    none
Source

pub fn after_machine_init<F>(self, callback: F)
where F: FnMut(&mut CPUState) + 'static,

Installs the given callback, assigning it to this Callback’s slot. Any callbacks previously stored in that slot will be freed.

Called right after the machine has been initialized, but before any guest code runs.

Callback ID:     PANDA_CB_AFTER_MACHINE_INIT

   Arguments:
    void *cpu_env: pointer to CPUState

   Helper call location: TBA

   Return value:
    none

   Notes:
    This callback allows initialization of components that need
    access to the RAM, CPU object, etc. E.g. for the taint2 plugin,
    this is the appropriate place to call taint2_enable_taint().
Source

pub fn after_loadvm<F>(self, callback: F)
where F: FnMut(&mut CPUState) + 'static,

Installs the given callback, assigning it to this Callback’s slot. Any callbacks previously stored in that slot will be freed.

Called right after a snapshot has been loaded (either with loadvm or replay initialization), but before any guest code runs.

Callback ID:     PANDA_CB_AFTER_LOADVM

   Arguments:
    void *cpu_env: pointer to CPUState

   Return value:
    none
Source

pub fn top_loop<F>(self, callback: F)
where F: FnMut(&mut CPUState) + 'static,

Installs the given callback, assigning it to this Callback’s slot. Any callbacks previously stored in that slot will be freed.

Called at the top of the loop that manages emulation.

Callback ID:     PANDA_CB_TOP_LOOP

   Arguments:
    CPUState *env:          pointer to CPUState

   Helper call location: cpus.c

   Return value:
    unused
Source

pub fn during_machine_init<F>(self, callback: F)
where F: FnMut(&mut MachineState) + 'static,

Installs the given callback, assigning it to this Callback’s slot. Any callbacks previously stored in that slot will be freed.

Called in the middle of machine initialization

Callback ID:     PANDA_CB_DURING_MACHINE_INIT

   Arguments:
     MachineState *machine: pointer to the machine state

   Return value:
     None
Source

pub fn main_loop_wait<F>(self, callback: F)
where F: FnMut() + 'static,

Installs the given callback, assigning it to this Callback’s slot. Any callbacks previously stored in that slot will be freed.

Called in IO thread in place where monitor cmds are processed

Callback ID:     PANDA_CB_MAIN_LOOP_WAIT

   Arguments:
     None

   Return value:
     None
Source

pub fn pre_shutdown<F>(self, callback: F)
where F: FnMut() + 'static,

Installs the given callback, assigning it to this Callback’s slot. Any callbacks previously stored in that slot will be freed.

Called just before qemu shuts down

Callback ID:     PANDA_CB_PRE_SHUTDOWN


   Arguments:
     None

   Return value:
     None
Source

pub fn unassigned_io_read<F>(self, callback: F)
where F: FnMut(&mut CPUState, target_ptr_t, hwaddr, usize, u64) -> bool + 'static,

Installs the given callback, assigning it to this Callback’s slot. Any callbacks previously stored in that slot will be freed.

Called when the guest attempts to read from an unmapped peripheral via MMIO

Callback ID:     PANDA_CB_UNASSIGNED_IO_WRITE

   Arguments:
     pc: Guest program counter at time of write
     addr: Physical address written to
     size: Size of write
     val: Pointer to a buffer that will be passed to the guest as the result of the read

   Return value:
     True if value read was changed by a PANDA plugin and should be returned
     False if error-logic (invalid write) should be run
Source

pub fn unassigned_io_write<F>(self, callback: F)
where F: FnMut(&mut CPUState, target_ptr_t, hwaddr, usize, u64) -> bool + 'static,

Installs the given callback, assigning it to this Callback’s slot. Any callbacks previously stored in that slot will be freed.

Called when the guest attempts to write to an unmapped peripheral via MMIO

Callback ID:     PANDA_CB_UNASSIGNED_IO_WRITE

   Arguments:
     pc: Guest program counter at time of write
     addr: Physical address written to
     size: Size of write
     val: Data being written, up to 8 bytes

   Return value:
     True if the write should be allowed without error
     False if normal behavior should be used (error-logic)
Source

pub fn before_handle_exception<F>(self, callback: F)
where F: FnMut(&mut CPUState, i32) -> i32 + 'static,

Installs the given callback, assigning it to this Callback’s slot. Any callbacks previously stored in that slot will be freed.

Called just before we are about to handle an exception.

Callback ID:     PANDA_CB_BEFORE_HANDLE_EXCEPTION 

   Note: only called for cpu->exception_index > 0

   Aguments:
     exception_index (the current exception number)

   Return value:
     a new exception_index.

   Note: There might be more than one callback for this location.
   First callback that returns an exception index that *differs*
   from the one passed as an arg wins. That is what we return as
   the new exception index, which will replace
   cpu->exception_index
Source

pub fn before_handle_interrupt<F>(self, callback: F)
where F: FnMut(&mut CPUState, i32) -> i32 + 'static,

Installs the given callback, assigning it to this Callback’s slot. Any callbacks previously stored in that slot will be freed.

Source

pub fn start_block_exec<F>(self, callback: F)
where F: FnMut(&mut CPUState, &mut TranslationBlock) + 'static,

Installs the given callback, assigning it to this Callback’s slot. Any callbacks previously stored in that slot will be freed.

Callback ID: PANDA_CB_START_BLOCK_EXEC

  start_block_exec:
   This is like before_block_exec except its part of the TCG stream.

  Arguments:
   CPUState *env:        the current CPU state
   TranslationBlock *tb: the TB we are executing

  Helper call location: cpu-exec.c

  Return value:
   none
Source

pub fn end_block_exec<F>(self, callback: F)
where F: FnMut(&mut CPUState, &mut TranslationBlock) + 'static,

Installs the given callback, assigning it to this Callback’s slot. Any callbacks previously stored in that slot will be freed.

Callback ID: PANDA_CB_END_BLOCK_EXEC

   end_block_exec:
    This is like after_block_exec except its part of the TCG stream.

   Arguments:
    CPUState *env:        the current CPU state
    TranslationBlock *tb: the TB we are executing

   Helper call location: cpu-exec.c

   Return value:
    none
Source

pub fn before_tcg_codegen<F>(self, callback: F)
where F: FnMut(&mut CPUState, &mut TranslationBlock) + 'static,

Installs the given callback, assigning it to this Callback’s slot. Any callbacks previously stored in that slot will be freed.

Callback ID: PANDA_CB_BEFORE_TCG_CODEGEN

   before_tcg_codegen:
    Called before host code generation for every basic block. Enables
    inspection and modification of the TCG block after lifting from guest
    code.

   Arguments:
    CPUState *env:        the current CPU state
    TranslationBlock *tb: the TB about to be compiled

   Helper call location: translate-all.c

   Return value:
    None

Trait Implementations§

Source§

impl Clone for Callback

Source§

fn clone(&self) -> Callback

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Ord for Callback

Source§

fn cmp(&self, other: &Callback) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · Source§

fn max(self, other: Self) -> Self
where Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · Source§

fn min(self, other: Self) -> Self
where Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · Source§

fn clamp(self, min: Self, max: Self) -> Self
where Self: Sized,

Restrict a value to a certain interval. Read more
Source§

impl PartialEq for Callback

Source§

fn eq(&self, other: &Callback) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl PartialOrd for Callback

Source§

fn partial_cmp(&self, other: &Callback) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · Source§

fn lt(&self, other: &Rhs) -> bool

Tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · Source§

fn le(&self, other: &Rhs) -> bool

Tests less than or equal to (for self and other) and is used by the <= operator. Read more
1.0.0 · Source§

fn gt(&self, other: &Rhs) -> bool

Tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · Source§

fn ge(&self, other: &Rhs) -> bool

Tests greater than or equal to (for self and other) and is used by the >= operator. Read more
Source§

impl Copy for Callback

Source§

impl Eq for Callback

Source§

impl StructuralPartialEq for Callback

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.