Interface PcodeEmulationCallbacks<T>

Type Parameters:
T - the type of values in the emulator
All Known Subinterfaces:
TraceEmulationIntegration.Writer
All Known Implementing Classes:
ComposedPcodeEmulationCallbacks, PcodeEmulationCallbacks.NoPcodeEmulationCallbacks, TraceEmulationIntegration.TraceWriter

public interface PcodeEmulationCallbacks<T>
A set of callbacks available for p-code emulation.

Note that some emulator extensions (notably the JIT-accelerated emulator) may disable and/or slightly change the specification of these callbacks. Read an emulator's documentation carefully. That said, an extension should strive to adhere to this specification as closely as possible.

See PcodeEmulator for advice regarding extending the emulator versus integrating with an emulator. Use of these callbacks is favored over extending an emulator when possible, as this favors composition of such integrations.

  • Method Details

    • none

      static <T> PcodeEmulationCallbacks<T> none()
      Obtain callbacks that do nothing.
      Type Parameters:
      T - the domain
      Returns:
      PcodeEmulationCallbacks.NoPcodeEmulationCallbacks.INSTANCE
    • emulatorCreated

      default void emulatorCreated(PcodeMachine<T> machine)
      The emulator has been created, but not yet finished construction.

      WARNING: At this point, the emulator has not been fully constructed. The most the callback ought to do is save a pointer to the machine. Attempting to access the machine or invoke any of its methods will likely result in a NullPointerException. Use the sharedStateCreated(PcodeMachine) callback to access the machine after it has been constructed

      Parameters:
      machine - the emulator or abstract machine.
    • sharedStateCreated

      default void sharedStateCreated(PcodeMachine<T> machine)
      The emulator's shared state has been created.

      NOTE: It is possible for clients to interact with other parts of the machine, e.g., to create a thread, before this callback gets invoked. The shared state is created lazily, i.e., the first time PcodeMachine.getSharedState() gets called, whether by the client or the machine's internals. If a pointer to the machine is needed early, consider emulatorCreated(PcodeMachine).

      Parameters:
      machine - the emulator or abstract machine
    • threadCreated

      default void threadCreated(PcodeThread<T> thread)
      A new thread has just been created.

      The thread is fully constructed. This callback may access it.

      Parameters:
      thread - the new thread
    • getInject

      default PcodeProgram getInject(PcodeThread<T> thread, Address address)
      The emulator is preparing to decode an instruction, but is checking for injected overrides first.
      Parameters:
      thread - the thread
      address - the thread's program counter
      Returns:
      null, or a p-code program to override the instruction
      See Also:
    • beforeExecuteInject

      default void beforeExecuteInject(PcodeThread<T> thread, Address address, PcodeProgram program)
      The emulator is preparing to execute an injected program.
      Parameters:
      thread - the thread
      address - the thread's program counter
      program - the injected p-code program
      See Also:
    • afterExecuteInject

      default void afterExecuteInject(PcodeThread<T> thread, Address address)
      The emulator has just finished executing an injected p-code program.

      If the program executed a branch, then address will be the target address. Note that any sane inject ought to execute a branch, even to effect fall-through, otherwise the program counter cannot advance.

      Parameters:
      thread - the thread
      address - the thread's program counter
    • beforeDecodeInstruction

      default void beforeDecodeInstruction(PcodeThread<T> thread, Address counter, RegisterValue context)
      The emulator, having found no injects, is preparing to decode an instruction.
      Parameters:
      thread - the thread
      counter - the thread's program counter
      context - the decode contextreg value
    • beforeExecuteInstruction

      default void beforeExecuteInstruction(PcodeThread<T> thread, Instruction instruction, PcodeProgram program)
      The emulator is preparing to execute a decoded instruction.
      Parameters:
      thread - the thread
      instruction - the decoded instruction
      program - the instruction's p-code program
    • afterExecuteInstruction

      default void afterExecuteInstruction(PcodeThread<T> thread, Instruction instruction)
      The emulator has finished executing an instruction.
      Parameters:
      thread - the thread
      instruction - the just-executed instruction
    • beforeStepOp

      default void beforeStepOp(PcodeThread<T> thread, PcodeOp op, PcodeFrame frame)
      The emulator is preparing to execute a p-code op.
      Parameters:
      thread - the thread
      op - the op
      frame - the frame for the current p-code program
    • afterStepOp

      default void afterStepOp(PcodeThread<T> thread, PcodeOp op, PcodeFrame frame)
      The emulator has just executed a p-code op.
      Parameters:
      thread - the thread
      op - the op
      frame - the frame for the current p-code program
    • beforeLoad

      default void beforeLoad(PcodeThread<T> thread, PcodeOp op, AddressSpace space, T offset, int size)
      The emulator is preparing to load a value from its execution state.
      Parameters:
      thread - the thread
      op - the PcodeOp.LOAD op
      space - the address space of the operand
      offset - the offset of the operand
      size - the size of the operand
    • afterLoad

      default void afterLoad(PcodeThread<T> thread, PcodeOp op, AddressSpace space, T offset, int size, T value)
      The emulator has just loaded a value from its execution state.
      Parameters:
      thread - the thread
      op - the PcodeOp.LOAD op
      space - the address space of the operand
      offset - the offset of the operand
      size - the size of the operand
      value - the value loaded
    • beforeStore

      default void beforeStore(PcodeThread<T> thread, PcodeOp op, AddressSpace space, T offset, int size, T value)
      The emulator is preparing to store a value into its execution state.
      Parameters:
      thread - the thread
      op - the PcodeOp.STORE op
      space - the address space of the operand
      offset - the offset of the operand
      size - the size of the operand
      value - the value to store
    • afterStore

      default void afterStore(PcodeThread<T> thread, PcodeOp op, AddressSpace space, T offset, int size, T value)
      The emulator has just stored a value into its execution state.
      Parameters:
      thread - the thread
      op - the PcodeOp.STORE op
      space - the address space of the operand
      offset - the offset of the operand
      size - the size of the operand
      value - the value stored
    • afterBranch

      default void afterBranch(PcodeThread<T> thread, PcodeOp op, Address target)
      The emulator has just branched to an address.
      Parameters:
      thread - the thread
      op - the branching op
      target - the new program counter
    • handleMissingUserop

      default boolean handleMissingUserop(PcodeThread<T> thread, PcodeOp op, PcodeFrame frame, String opName, PcodeUseropLibrary<T> library)
      The emulator has encountered a userop for which it has no definition.

      Emulation has not yet been interrupted at this point. If a callback returns true, indicating the fault has been handled, then the emulator will proceed. If not, then emulation for this thread will be interrupted

      Parameters:
      thread - the thread
      op - the PcodeOp.CALLOTHER op
      frame - the frame for the current p-code program
      opName - the name of the userop being called
      library - the thread's userop library
      Returns:
      true if handled, false if not
    • dataWritten

      default <A, U> void dataWritten(PcodeThread<T> thread, PcodeExecutorStatePiece<A,U> piece, AddressSpace space, A offset, int length, U value)
      Data was written into the given state piece (abstract addressing).

      NOTE: In contrast to the operation-driven callbacks, e.g., beforeStore(PcodeThread, PcodeOp, AddressSpace, Object, int, Object), the thread parameter here may be null. It is not necessarily the thread executing the op, but the thread associated to the state being accessed. In particular, when this is the shared state, thread will be null. When this is the local state, thread will be the thread of execution. If this behavior poses a serious limitation, then we may consider changing this to always be the thread of execution.

      Type Parameters:
      A - the piece's address domain
      U - the piece's value domain
      Parameters:
      thread - the thread associated to the piece
      piece - the state piece
      space - the address space of the operand
      offset - the offset of the operand
      length - the size of the operand
      value - the value written
    • delegateDataWritten

      default <A, U> void delegateDataWritten(PcodeThread<T> thread, PcodeExecutorStatePiece<A,U> piece, AddressSpace space, A offset, int length, U value)
      Type Parameters:
      A - the piece's address domain
      U - the piece's value domain
      Parameters:
      thread - the thread associated to the piece. See dataWritten(PcodeThread, PcodeExecutorStatePiece, AddressSpace, Object, int, Object)
      piece - the state piece
      space - the address space of the operand
      offset - the offset of the operand
      length - the size of the operand
      value - the value written
    • dataWritten

      default <A, U> void dataWritten(PcodeThread<T> thread, PcodeExecutorStatePiece<A,U> piece, Address address, int length, U value)
      Data was written into the given state piece (concrete addressing).
      Type Parameters:
      A - the piece's address domain
      U - the piece's value domain
      Parameters:
      thread - the thread associated to the piece. See dataWritten(PcodeThread, PcodeExecutorStatePiece, AddressSpace, Object, int, Object)
      piece - the state piece
      address - the address of the operand
      length - the size of the operand
      value - the value written
    • delegateDataWritten

      default <A, U> void delegateDataWritten(PcodeThread<T> thread, PcodeExecutorStatePiece<A,U> piece, Address address, int length, U value)
      Type Parameters:
      A - the piece's address domain
      U - the piece's value domain
      Parameters:
      thread - the thread associated to the piece. See dataWritten(PcodeThread, PcodeExecutorStatePiece, AddressSpace, Object, int, Object)
      piece - the state piece
      address - the address of the operand
      length - the size of the operand
      value - the value written
    • readUninitialized

      default <A, U> int readUninitialized(PcodeThread<T> thread, PcodeExecutorStatePiece<A,U> piece, AddressSpace space, A offset, int length)
      The emulator is preparing to read from uninitialized portions of the given state piece (abstract addressing).

      This callback provides an opportunity for something to initialize the required portion lazily. In most cases, this should either return 0 indicating the requested portion remains uninitialized, or the full length indicating the full requested portion is now initialized. If, for some reason, the requested portion could only be partially initialized, this can return a smaller length. Partial initializations are only recognized from the starting offset. Other parts could be initialized; however, there is no mechanism for communicating that result to the emulator.

      Type Parameters:
      A - the piece's address domain
      U - the piece's value domain
      Parameters:
      thread - the thread associated to the piece. See dataWritten(PcodeThread, PcodeExecutorStatePiece, AddressSpace, Object, int, Object)
      piece - the state piece
      space - the address space of the operand
      offset - the offset of the operand
      length - the size of the operand
      Returns:
      the length of the operand just initialized, typically 0 or length
    • delegateReadUninitialized

      default <A, U> int delegateReadUninitialized(PcodeThread<T> thread, PcodeExecutorStatePiece<A,U> piece, AddressSpace space, A offset, int length)
      Type Parameters:
      A - the piece's address domain
      U - the piece's value domain
      Parameters:
      thread - the thread associated to the piece. See dataWritten(PcodeThread, PcodeExecutorStatePiece, AddressSpace, Object, int, Object)
      piece - the state piece
      space - the address space of the operand
      offset - the offset of the operand
      length - the size of the operand
      Returns:
      the length of the operand just initialized, typically 0 or length
    • readUninitialized

      default <A, U> AddressSetView readUninitialized(PcodeThread<T> thread, PcodeExecutorStatePiece<A,U> piece, AddressSetView set)
      The emulator is preparing to read from uninitialized portions of the given state piece (concrete addressing).

      This callback provides an opportunity for something to initialize the required portion lazily. This method must return the address set that remains uninitialized. If no part of the required portion was initialized, this should return set identically, so that the caller can quickly recognize that nothing has changed. Otherwise, this should copy set, remove those parts it was able to initialize, and return the copy. DO NOT modify the given set.

      Type Parameters:
      A - the piece's address domain
      U - the piece's value domain
      Parameters:
      thread - the thread associated to the piece. See dataWritten(PcodeThread, PcodeExecutorStatePiece, AddressSpace, Object, int, Object)
      piece - the state piece
      set - the uninitialized portion required
      Returns:
      the addresses in set that remain uninitialized
    • delegateReadUninitialized

      default <A, U> AddressSetView delegateReadUninitialized(PcodeThread<T> thread, PcodeExecutorStatePiece<A,U> piece, AddressSetView set)
      Type Parameters:
      A - the piece's address domain
      U - the piece's value domain
      Parameters:
      thread - the thread associated to the piece. See dataWritten(PcodeThread, PcodeExecutorStatePiece, AddressSpace, Object, int, Object)
      piece - the state piece
      set - the uninitialized portion required
      Returns:
      the addresses in set that remain uninitialized
    • wrapFor

      default PcodeStateCallbacks wrapFor(PcodeThread<T> thread)
      Obtain a callback wrapper suitable for passing into an emulator's execution states

      This will forward the calls from the state's pieces to this set of emulator callbacks, passing the given thread

      Parameters:
      thread - the thread to include in forwarded callbacks
      Returns:
      the wrapper