Interface PcodeMachine<T>

Type Parameters:
T - the type of objects in the machine's state
All Known Implementing Classes:
AbstractPcodeMachine, AuxPcodeEmulator, PcodeEmulator

public interface PcodeMachine<T>
A machine which execute p-code on state of an abstract type
  • Method Details

    • getLanguage

      SleighLanguage getLanguage()
      Get the machine's Sleigh language (processor model)
      Returns:
      the language
    • getArithmetic

      PcodeArithmetic<T> getArithmetic()
      Get the arithmetic applied by the machine
      Returns:
      the arithmetic
    • setSoftwareInterruptMode

      void setSoftwareInterruptMode(PcodeMachine.SwiMode mode)
      Change the efficacy of p-code breakpoints

      This is used to prevent breakpoints from interrupting at inappropriate times, e.g., upon continuing from a breakpoint.

      Parameters:
      mode - the new mode
    • getSoftwareInterruptMode

      PcodeMachine.SwiMode getSoftwareInterruptMode()
      Get the current software interrupt mode
      Returns:
      the mode
    • getUseropLibrary

      PcodeUseropLibrary<T> getUseropLibrary()
      Get the userop library common to all threads in the machine.

      Note that threads may have larger libraries, but each contains all the userops in this library.

      Returns:
      the userop library
    • getStubUseropLibrary

      PcodeUseropLibrary<T> getStubUseropLibrary()
      Get a userop library which at least declares all userops available in each thread userop library.

      Thread userop libraries may have more userops than are defined in the machine's userop library. However, to compile Sleigh programs linked to thread libraries, the thread's userops must be known to the compiler. The stub library will name all userops common among the threads, even if their definitions vary. WARNING: The stub library is not required to provide implementations of the userops. Often they will throw exceptions, so do not attempt to use the returned library in an executor.

      Returns:
      the stub library
    • newThread

      PcodeThread<T> newThread()
      Create a new thread with a default name in this machine
      Returns:
      the new thread
    • newThread

      PcodeThread<T> newThread(String name)
      Create a new thread with the given name in this machine
      Parameters:
      name - the name
      Returns:
      the new thread
    • getThread

      PcodeThread<T> getThread(String name, boolean createIfAbsent)
      Get the thread, if present, with the given name
      Parameters:
      name - the name
      createIfAbsent - create a new thread if the thread does not already exist
      Returns:
      the thread, or null if absent and not created
    • getAllThreads

      Collection<? extends PcodeThread<T>> getAllThreads()
      Collect all threads present in the machine
      Returns:
      the collection of threads
    • getSharedState

      PcodeExecutorState<T> getSharedState()
      Get the machine's shared (memory) state

      The returned state will may throw IllegalArgumentException if the client requests register values of it. This state is shared among all threads in this machine.

      Returns:
      the memory state
    • setSuspended

      void setSuspended(boolean suspended)
      Set the suspension state of the machine

      This does not simply suspend all threads, but sets a machine-wide flag. A thread is suspended if either the thread's flag is set, or the machine's flag is set.

      Parameters:
      suspended - true to suspend the machine, false to let it run
      See Also:
    • isSuspended

      boolean isSuspended()
      Check the suspension state of the machine
      Returns:
      true if suspended
      See Also:
    • compileSleigh

      PcodeProgram compileSleigh(String sourceName, String source)
      Compile the given Sleigh code for execution by a thread of this machine

      This links in the userop library given at construction time and those defining the emulation userops, e.g., emu_swi.

      Parameters:
      sourceName - a user-defined source name for the resulting "program"
      source - the Sleigh source
      Returns:
      the compiled program
    • inject

      void inject(Address address, String source)
      Override the p-code at the given address with the given Sleigh source

      This will attempt to compile the given source against this machine's userop library and then inject it at the given address. The resulting p-code replaces that which would be executed by decoding the instruction at the given address. The means the machine will not decode, nor advance its counter, unless the Sleigh causes it. In most cases, the Sleigh will call DefaultPcodeThread.PcodeEmulationLibrary.emu_exec_decoded() to cause the machine to decode and execute the overridden instruction.

      Each address can have at most a single inject. If there is already one present, it is replaced and the old inject completely forgotten. The injector does not support chaining or double-wrapping, etc.

      No synchronization is provided on the internal injection storage. Clients should ensure the machine is not executing when injecting p-code. Additionally, the client must ensure only one thread is injecting p-code to the machine at a time.

      Parameters:
      address - the address to inject at
      source - the Sleigh source to compile and inject
    • clearInject

      void clearInject(Address address)
      Remove the inject, if present, at the given address
      Parameters:
      address - the address to clear
    • clearAllInjects

      void clearAllInjects()
      Remove all injects from this machine

      This will clear execution breakpoints, but not access breakpoints. See clearAccessBreakpoints().

    • addBreakpoint

      void addBreakpoint(Address address, String sleighCondition)
      Add a conditional execution breakpoint at the given address

      Breakpoints are implemented at the p-code level using an inject, without modification to the emulated image. As such, it cannot coexist with another inject. A client needing to break during an inject must use DefaultPcodeThread.PcodeEmulationLibrary.emu_swi() in the injected Sleigh.

      No synchronization is provided on the internal breakpoint storage. Clients should ensure the machine is not executing when adding breakpoints. Additionally, the client must ensure only one thread is adding breakpoints to the machine at a time.

      Parameters:
      address - the address at which to break
      sleighCondition - a Sleigh expression which controls the breakpoint
    • addAccessBreakpoint

      void addAccessBreakpoint(AddressRange range, PcodeMachine.AccessKind kind)
      Add an access breakpoint over the given range

      Access breakpoints are implemented out of band, without modification to the emulated image. The breakpoints are only effective for p-code PcodeOp.LOAD and PcodeOp.STORE operations with concrete offsets. Thus, an operation that refers directly to a memory address, e.g., a memory-mapped register, will not be trapped. Similarly, access breakpoints on registers or unique variables will not work. Access to an abstract offset that cannot be made concrete, i.e., via PcodeArithmetic.toConcrete(Object, Purpose) cannot be trapped. To interrupt on direct and/or abstract accesses, consider wrapping the relevant state and/or overriding PcodeExecutorStatePiece.getVar(Varnode, Reason) and related. For accesses to abstract offsets, consider overriding AbstractPcodeMachine.checkLoad(AddressSpace, Object, int) and/or AbstractPcodeMachine.checkStore(AddressSpace, Object, int) instead.

      A breakpoint's range cannot cross more than one page boundary. Pages are 4096 bytes each. This allows implementations to optimize checking for breakpoints. If a breakpoint does not follow this rule, the behavior is undefined. Breakpoints may overlap, but currently no indication is given as to which breakpoint interrupted emulation.

      No synchronization is provided on the internal breakpoint storage. Clients should ensure the machine is not executing when adding breakpoints. Additionally, the client must ensure only one thread is adding breakpoints to the machine at a time.

      Parameters:
      range - the address range to trap
      kind - the kind of access to trap
    • clearAccessBreakpoints

      void clearAccessBreakpoints()
      Remove all access breakpoints from this machine