Class PcodeExecutor<T>

java.lang.Object
ghidra.pcode.exec.PcodeExecutor<T>
Type Parameters:
T - the type of values processed by the executor
Direct Known Subclasses:
DefaultPcodeThread.PcodeThreadExecutor

public class PcodeExecutor<T> extends Object
An executor of p-code programs

This is the kernel of Sleigh expression evaluation and p-code emulation. For a complete example of a p-code emulator, see PcodeEmulator.

  • Field Details

  • Constructor Details

    • PcodeExecutor

      public PcodeExecutor(SleighLanguage language, PcodeArithmetic<T> arithmetic, PcodeExecutorState<T> state, PcodeExecutorStatePiece.Reason reason)
      Construct an executor with the given bindings
      Parameters:
      language - the processor language
      arithmetic - an implementation of arithmetic p-code ops
      state - an implementation of load/store p-code ops
      reason - a reason for reading the state with this executor
  • Method Details

    • getLanguage

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

      public PcodeArithmetic<T> getArithmetic()
      Get the arithmetic applied by the executor
      Returns:
      the arithmetic
    • getState

      public PcodeExecutorState<T> getState()
      Get the state bound to this executor
      Returns:
      the state
    • getReason

      public PcodeExecutorStatePiece.Reason getReason()
      Get the reason for reading state with this executor
      Returns:
      the reason
    • executeSleigh

      public void executeSleigh(String source)
      Compile and execute a block of Sleigh
      Parameters:
      source - the Sleigh source
    • begin

      public PcodeFrame begin(PcodeProgram program)
      Begin execution of the given program
      Parameters:
      program - the program, e.g., from an injection, or a decoded instruction
      Returns:
      the frame
    • execute

      public PcodeFrame execute(PcodeProgram program, PcodeUseropLibrary<T> library)
      Execute a program using the given library
      Parameters:
      program - the program, e.g., from an injection, or a decoded instruction
      library - the library
      Returns:
      the frame
    • begin

      public PcodeFrame begin(List<PcodeOp> code, Map<Integer,String> useropNames)
      Begin execution of a list of p-code ops
      Parameters:
      code - the ops
      useropNames - the map of userop numbers to names
      Returns:
      the frame
    • execute

      public PcodeFrame execute(List<PcodeOp> code, Map<Integer,String> useropNames, PcodeUseropLibrary<T> library)
      Execute a list of p-code ops
      Parameters:
      code - the ops
      useropNames - the map of userop numbers to names
      library - the library of userops
      Returns:
      the frame
    • finish

      public void finish(PcodeFrame frame, PcodeUseropLibrary<T> library)
      Finish execution of a frame

      TODO: This is not really sufficient for continuation after a break, esp. if that break occurs within a nested call back into the executor. This would likely become common when using pCode injection.

      Parameters:
      frame - the incomplete frame
      library - the library of userops to use
    • badOp

      protected void badOp(PcodeOp op)
      Handle an unrecognized or unimplemented p-code op
      Parameters:
      op - the op
    • stepOp

      public void stepOp(PcodeOp op, PcodeFrame frame, PcodeUseropLibrary<T> library)
      Step on p-code op
      Parameters:
      op - the op
      frame - the current frame
      library - the library, invoked in case of PcodeOp.CALLOTHER
    • step

      public void step(PcodeFrame frame, PcodeUseropLibrary<T> library)
      Step a single p-code op
      Parameters:
      frame - the frame whose next op to execute
      library - the userop library
    • skip

      public void skip(PcodeFrame frame)
      Skip a single p-code op
      Parameters:
      frame - the frame whose next op to skip
    • getIntConst

      protected int getIntConst(Varnode vn)
      Assert that a varnode is constant and get its value as an integer.

      Here "constant" means a literal or immediate value. It does not read from the state.

      Parameters:
      vn - the varnode
      Returns:
      the value
    • executeUnaryOp

      public void executeUnaryOp(PcodeOp op, UnaryOpBehavior b)
      Execute the given unary op
      Parameters:
      op - the op
      b - the op behavior
    • executeBinaryOp

      public void executeBinaryOp(PcodeOp op, BinaryOpBehavior b)
      Execute the given binary op
      Parameters:
      op - the op
      b - the op behavior
    • checkLoad

      protected void checkLoad(AddressSpace space, T offset, int size)
      Extension point: logic preceding a load
      Parameters:
      space - the address space to be loaded from
      offset - the offset about to be loaded from
      size - the size in bytes to be loaded
    • executeLoad

      public void executeLoad(PcodeOp op)
      Execute a load
      Parameters:
      op - the op
    • checkStore

      protected void checkStore(AddressSpace space, T offset, int size)
      Extension point: logic preceding a store
      Parameters:
      space - the address space to be stored to
      offset - the offset about to be stored to
      size - the size in bytes to be stored
    • executeStore

      public void executeStore(PcodeOp op)
      Execute a store
      Parameters:
      op - the op
    • branchToAddress

      protected void branchToAddress(Address target)
      Extension point: Called when execution branches to a target address

      NOTE: This is not called for the fall-through case

      Parameters:
      target - the target address
    • branchToOffset

      protected void branchToOffset(T offset, PcodeFrame frame)
      Set the state's pc to the given offset and finish the frame

      This implements only part of the p-code control flow semantics. An emulator must also override branchToAddress(Address), so that it can update its internal program counter. The emulator could just read the program counter from the state after every completed frame, but receiving it "out of band" is faster.

      Parameters:
      offset - the offset (the new value of the program counter)
      frame - the frame to finish
    • doExecuteBranch

      protected void doExecuteBranch(PcodeOp op, PcodeFrame frame)
      Perform the actual logic of a branch p-code op

      This is a separate method, so that overriding executeBranch(PcodeOp, PcodeFrame) does not implicitly modify executeConditionalBranch(PcodeOp, PcodeFrame).

      Parameters:
      op - the op
      frame - the frame
    • executeBranch

      public void executeBranch(PcodeOp op, PcodeFrame frame)
      Execute a branch

      This merely defers to doExecuteBranch(PcodeOp, PcodeFrame). To instrument the operation, override this. To modify or instrument branching in general, override doExecuteBranch(PcodeOp, PcodeFrame), branchToOffset(Object, PcodeFrame), and/or branchToAddress(Address).

      Parameters:
      op - the op
      frame - the frame
    • executeConditionalBranch

      public void executeConditionalBranch(PcodeOp op, PcodeFrame frame)
      Execute a conditional branch
      Parameters:
      op - the op
      frame - the frame
    • doExecuteIndirectBranch

      protected void doExecuteIndirectBranch(PcodeOp op, PcodeFrame frame)
      Perform the actual logic of an indirect branch p-code op

      This is a separate method, so that overriding executeIndirectBranch(PcodeOp, PcodeFrame) does not implicitly modify executeIndirectCall(PcodeOp, PcodeFrame) and executeReturn(PcodeOp, PcodeFrame).

      Parameters:
      op - the op
      frame - the frame
    • executeIndirectBranch

      public void executeIndirectBranch(PcodeOp op, PcodeFrame frame)
      Execute an indirect branch

      This merely defers to doExecuteIndirectBranch(PcodeOp, PcodeFrame). To instrument the operation, override this. To modify or instrument indirect branching in general, override doExecuteIndirectBranch(PcodeOp, PcodeFrame).

      Parameters:
      op - the op
      frame - the frame
    • executeCall

      public void executeCall(PcodeOp op, PcodeFrame frame, PcodeUseropLibrary<T> library)
      Execute a call
      Parameters:
      op - the op
      frame - the frame
    • executeIndirectCall

      public void executeIndirectCall(PcodeOp op, PcodeFrame frame)
      Execute an indirect call
      Parameters:
      op - the op
      frame - the frame
    • getUseropName

      public String getUseropName(int opNo, PcodeFrame frame)
      Get the name of a userop
      Parameters:
      opNo - the userop number
      frame - the frame
      Returns:
      the name, or null if it is not defined
    • executeCallother

      public void executeCallother(PcodeOp op, PcodeFrame frame, PcodeUseropLibrary<T> library)
      Execute a userop call
      Parameters:
      op - the op
      frame - the frame
      library - the library of userops
    • onMissingUseropDef

      protected void onMissingUseropDef(PcodeOp op, PcodeFrame frame, String opName, PcodeUseropLibrary<T> library)
      Extension point: Behavior when a userop definition was not found in the library

      The default behavior is to throw a SleighLinkException.

      Parameters:
      op - the op
      frame - the frame
      opName - the name of the p-code userop
      library - the library
    • executeReturn

      public void executeReturn(PcodeOp op, PcodeFrame frame)
      Execute a return
      Parameters:
      op - the op
      frame - the frame