Class JitPassage

java.lang.Object
ghidra.pcode.exec.PcodeProgram
ghidra.pcode.emu.jit.JitPassage

public class JitPassage extends PcodeProgram
A selection of instructions decoded from an emulation target, the generated p-code ops, and associated metadata.

Note that the generated p-code ops include those injected by the emulator's client using PcodeMachine.inject(Address, String) and PcodeThread.inject(Address, String), which also includes breakpoints, i.e, PcodeMachine.addBreakpoint(Address, String).

See Also:
  • Constructor Details

  • Method Details

    • hasFallthrough

      public static boolean hasFallthrough(PcodeOp op)
      Check if a given p-code op could fall through

      Conditional branches and non-branching ops are the only ones that can fall through. Note that for JIT purposes, a CALL op does not fall through! For decompilation, it hints that it's branching to a subroutine that usually returns back to the caller, but the JIT compiler does not take that hint. 1) There's no guarantee it will actually return. 2) Even if it did, it would be via a PcodeOp.RETURN, which is an indirect branch. An indirect branch is not sufficient to join two strides in the same passage. Thus, we have little to gain by falling through a call, and the more likely outcome is the JIT and/or ASM library will eliminate the code following the call.

      Parameters:
      op - the op to consider
      Returns:
      true if the op does or could fall through
    • getInCtx

      protected static RegisterValue getInCtx(InstructionContext insCtx)
      Derive the decode context value from the given instruction context
      Parameters:
      insCtx - the context
      Returns:
      the input decode context from the instruction whose context was given
    • getInCtx

      protected static RegisterValue getInCtx(Instruction instruction)
      Derive the decode context value from the given instruction
      Parameters:
      instruction - the instruction
      Returns:
      the input decode context from the instruction
    • decodeError

      public static JitPassage.DecodeErrorInstruction decodeError(Language language, Address address, RegisterValue ctx, String message)
      Create an instruction to indicate a decode error

      The resulting instruction will produce a single JitPassage.DecodeErrorPcodeOp. The translator will generate code that throws a DecodePcodeExecutionException should execution reach it.

      Parameters:
      language - the emulation target language
      address - the address where decode was attempted
      ctx - the input decode context
      message - a message for the DecodePcodeExecutionException
      Returns:
      the new "instruction"
    • getInstructions

      public List<Instruction> getInstructions()
      Get all of the instructions in the passage.

      These are grouped by stride. Within each stride, the instructions are listed in decode order. The strides are ordered by seed address-context pair, with context value taking precedence.

      Returns:
      the list of instructions
    • getCode

      public List<PcodeOp> getCode()

      Conventionally, the first instruction of the program is the entry. Note this might not be the initial seed. If the decoded passage contains a branch to an address preceding the seed, and a stride results from it, then that stride's p-code will occur earlier in the list. This is not a problem. The code generator will export many entry points, and the seed must be among them. "Entering" at that seed is achieved using a switch table at the start of the generated bytecode.

      Overrides:
      getCode in class PcodeProgram
    • getEntry

      public JitPassage.AddrCtx getEntry()
      Get the initial seed of this passage.

      This is informational only. It should be used in naming things and/or in diagnostics.

      Returns:
      the address-context pair
    • getDecodeLibrary

      public PcodeUseropLibrary<Object> getDecodeLibrary()
      Get the userop library that was used during decode of the passage

      This often wraps the emulator's userop library. Downstream components, namely the JitDataFlowModel, will need this when translating calls to userops.

      Returns:
      the library
    • getBranches

      public Map<PcodeOp,JitPassage.Branch> getBranches()
      Get all of the (non-fall-through) branches in the passage
      Returns:
      the branches, keyed by JitPassage.Branch.from().
    • toString

      public String toString()
      Overrides:
      toString in class PcodeProgram
    • getOpEntry

      public JitPassage.AddrCtx getOpEntry(PcodeOp op)
      Check if a given p-code op is the first of an instruction.

      NOTE: If an instruction is at an address with an inject, then the first op produced by the inject is considered the "entry" to the instruction. This is to ensure that any control flow to the injected address executes the injected code, not just the instruction's code.

      Parameters:
      op - the op to check.
      Returns:
      the address-context pair that generated the op, if it is the first there, or null
    • getErrorMessage

      public String getErrorMessage(PcodeOp op)
      If the given p-code op is known to cause an error, e.g., an unimplemented instruction, get the error message.
      Parameters:
      op - the p-code op causing the error
      Returns:
      the message for the error caused