Package ghidra.pcode.emu.jit

# Class JitPassage.ExitPcodeOp

java.lang.Object
ghidra.program.model.pcode.PcodeOp
ghidra.pcode.emu.jit.JitPassage.ExitPcodeOp

Enclosing class:
  `JitPassage`

public static class JitPassage.ExitPcodeOp extends PcodeOp
A synthetic p-code op that represents a return from the `JitCompiledPassage.run(int)` method.

When execution encounters this op (and the corresponding `JitPassage.ExtBranch`), the emulator's program counter and context values are set to the `branch target`, and the appropriate entry point is returned.

This is used in a few ways: The simplest, though perhaps not obvious, way is when the decoder encounters an existing entry point. We avoid re-translating the same instructions by forcing the stride to end. However, the last instruction in that stride would have fall through, causing dangling control flow. To mitigate that, we append a synthetic exit op to return the existing entry point. The emulator can then resume execution accordingly.

The next is even less obvious. When the emulation client (or user) injects Sleigh, a common mistake is to forget control flow. The decoder detects this when "falling through" does not actually advance the program counter. In this case, we append this synthetic op to exit the translated passage. While it still results in an endless loop (just like the interpretation-based emulator), it's easier to interrupt and diagnose when we exit the translation between each "iteration."

The last is a small hack: The decoder needs to know whether each instruction (possibly instrumented by an inject) falls through. To do this, it appends an exit op to the very end of the instruction's (and inject's) ops and performs rudimentary control flow analysis (see `JitControlFlowModel.BlockSplitter`). It then seeks a path from start to exit. If one is found, it has fall through. This "probe" op is not included in the decoded stride.

- ## Field Summary

  ### Fields inherited from class ghidra.program.model.pcode.PcodeOp

  `BOOL_AND, BOOL_NEGATE, BOOL_OR, BOOL_XOR, BRANCH, BRANCHIND, CALL, CALLIND, CALLOTHER, CAST, CBRANCH, COPY, CPOOLREF, EXTRACT, FLOAT_ABS, FLOAT_ADD, FLOAT_CEIL, FLOAT_DIV, FLOAT_EQUAL, FLOAT_FLOAT2FLOAT, FLOAT_FLOOR, FLOAT_INT2FLOAT, FLOAT_LESS, FLOAT_LESSEQUAL, FLOAT_MULT, FLOAT_NAN, FLOAT_NEG, FLOAT_NOTEQUAL, FLOAT_ROUND, FLOAT_SQRT, FLOAT_SUB, FLOAT_TRUNC, INDIRECT, INSERT, INT_2COMP, INT_ADD, INT_AND, INT_CARRY, INT_DIV, INT_EQUAL, INT_LEFT, INT_LESS, INT_LESSEQUAL, INT_MULT, INT_NEGATE, INT_NOTEQUAL, INT_OR, INT_REM, INT_RIGHT, INT_SBORROW, INT_SCARRY, INT_SDIV, INT_SEXT, INT_SLESS, INT_SLESSEQUAL, INT_SREM, INT_SRIGHT, INT_SUB, INT_XOR, INT_ZEXT, LOAD, LZCOUNT, MULTIEQUAL, NEW, PCODE_MAX, PIECE, POPCOUNT, PTRADD, PTRSUB, RETURN, SEGMENTOP, STORE, SUBPIECE, UNIMPLEMENTED`

- ## Method Summary

  Modifier and Type
  Method
  Description
  `static JitPassage.ExitPcodeOp`
  `cond(JitPassage.AddrCtx at)`
  Construct a synthetic conditional exit op
  `static JitPassage.ExitPcodeOp`
  `exit(JitPassage.AddrCtx at)`
  Construct a synthetic exit op

  ### Methods inherited from class ghidra.program.model.pcode.PcodeOp

  `decode, encodeRaw, getBasicIter, getInput, getInputs, getInsertIter, getMnemonic, getMnemonic, getNumInputs, getOpcode, getOpcode, getOutput, getParent, getSeqnum, getSlot, hashCode, insertInput, isAssignment, isCommutative, isCommutative, isDead, removeInput, setInput, setOpcode, setOrder, setOutput, setTime, toString`

  ### Methods inherited from class java.lang.Object

  `clone, equals, finalize, getClass, notify, notifyAll, wait, wait, wait`

- ## Method Details

  - ### exit

    public static JitPassage.ExitPcodeOp exit(JitPassage.AddrCtx at)
    Construct a synthetic exit op
    Parameters:
      `at` - the address and context value to set on the emulator when exiting the `JitCompiledPassage.run(int)` method
    Returns:
      the op

  - ### cond

    public static JitPassage.ExitPcodeOp cond(JitPassage.AddrCtx at)
    Construct a synthetic conditional exit op
    Parameters:
      `at` - the address and context value to set on the emulator when exiting the `JitCompiledPassage.run(int)` method
    Returns:
      the op