Package ghidra.pcode.emu.jit

# 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:
  - `Passage decoding`

- ## Nested Class Summary

  Nested Classes
  Modifier and Type
  Class
  Description
  `static final class`
  `JitPassage.AddrCtx`
  An address-context pair
  `static interface`
  `JitPassage.Branch`
  A branch in the p-code
  `static class`
  `JitPassage.DecodedPcodeOp`
  An extension of `PcodeOp` that carries along with it the address and decode context where it occurred.
  `static class`
  `JitPassage.DecodeErrorInstruction`
  An instruction denoting a decode error
  `static class`
  `JitPassage.DecodeErrorPcodeOp`
  A synthetic p-code op denoting a decode error
  `static class`
  `JitPassage.EntryPcodeOp`
  A synthetic op representing the initial seed of a decoded passage.
  `static final record`
  `JitPassage.ErrBranch`
  A "branch" representing an error
  `static class`
  `JitPassage.ExitPcodeOp`
  A synthetic p-code op that represents a return from the `JitCompiledPassage.run(int)` method.
  `static interface`
  `JitPassage.ExtBranch`
  A branch to an address (and context value) not in the same passage
  `static interface`
  `JitPassage.IndBranch`
  A branch to a dynamic address
  `static interface`
  `JitPassage.IntBranch`
  A branch to another p-code op in the same passage
  `static class`
  `JitPassage.NopPcodeOp`
  A synthetic p-code op meant to encode "no operation"
  `static interface`
  `JitPassage.PBranch`
  A branch as analyzed within a passage
  `static interface`
  `JitPassage.RBranch`
  A branch with known intra-instruction reachability
  `static enum`
  `JitPassage.Reachability`
  Describes the manner in which something is reachable, wrt.
  `static final record`
  `JitPassage.RExtBranch`
  A `JitPassage.ExtBranch` as added to the passage
  `static final record`
  `JitPassage.RIndBranch`
  A `JitPassage.IndBranch` as added to the passage
  `static final record`
  `JitPassage.RIntBranch`
  A `JitPassage.IntBranch` as added to the passage
  `static interface`
  `JitPassage.SBranch`
  A branch as analyzed within an instruction step
  `static final record`
  `JitPassage.SExtBranch`
  An `JitPassage.ExtBranch` as analyzed during one instruction step
  `static final record`
  `JitPassage.SIndBranch`
  An `JitPassage.IndBranch` as analyzed during one instruction step
  `static final record`
  `JitPassage.SIntBranch`
  An `JitPassage.IntBranch` as analyzed during one instruction step

  ## Nested classes/interfaces inherited from class ghidra.pcode.exec.PcodeProgram

  `PcodeProgram.MyAppender, PcodeProgram.MyFormatter`

- ## Field Summary

  ### Fields inherited from class ghidra.pcode.exec.PcodeProgram

  `code, language, useropNames`

- ## Constructor Summary

  Constructors
  Constructor
  Description
  `JitPassage(SleighLanguage language, JitPassage.AddrCtx entry, List<PcodeOp> code, PcodeUseropLibrary<Object> decodeLibrary, List<Instruction> instructions, Map<PcodeOp,JitPassage.PBranch> branches, Map<PcodeOp,JitPassage.AddrCtx> entries)`
  Construct a new passage

- ## Method Summary

  Modifier and Type
  Method
  Description
  `static JitPassage.DecodeErrorInstruction`
  `decodeError(Language language, Address address, RegisterValue ctx, String message)`
  Create an instruction to indicate a decode error
  `Map<PcodeOp,JitPassage.PBranch>`
  `getBranches()`
  Get all of the (non-fall-through) branches in the passage
  `List<PcodeOp>`
  `getCode()`
  `PcodeUseropLibrary<Object>`
  `getDecodeLibrary()`
  Get the userop library that was used during decode of the passage
  `JitPassage.AddrCtx`
  `getEntry()`
  Get the initial seed of this passage.
  `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.
  `protected static RegisterValue`
  `getInCtx(InstructionContext insCtx)`
  Derive the decode context value from the given instruction context
  `protected static RegisterValue`
  `getInCtx(Instruction instruction)`
  Derive the decode context value from the given instruction
  `List<Instruction>`
  `getInstructions()`
  Get all of the instructions in the passage.
  `JitPassage.AddrCtx`
  `getOpEntry(PcodeOp op)`
  Check if a given p-code op is the first of an instruction.
  `static boolean`
  `hasFallthrough(PcodeOp op)`
  Check if a given p-code op could fall through
  `String`
  `toString()`

  ### Methods inherited from class ghidra.pcode.exec.PcodeProgram

  `execute, format, format, fromInject, fromInstruction, fromInstruction, getHead, getLanguage, getUseropName`

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

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

- ## Constructor Details

  - ### JitPassage

    public JitPassage(SleighLanguage language, JitPassage.AddrCtx entry, List<PcodeOp> code, PcodeUseropLibrary<Object> decodeLibrary, List<Instruction> instructions, Map<PcodeOp,JitPassage.PBranch> branches, Map<PcodeOp,JitPassage.AddrCtx> entries)
    Construct a new passage
    Parameters:
      `language` - the translation source language, i.e., the emulation target language. See `PcodeProgram.getLanguage()`
      `entry` - see `getEntry()`
      `code` - the p-code ops, grouped by stride. Within each stride, they are ordered as decoded and produced by their instructions. The strides are sorted by seed, with precedence to the decode context value. See `getInstructions()`. See `getCode()`.
      `decodeLibrary` - see `getDecodeLibrary()`
      `instructions` - see `getInstructions()`
      `branches` - see `getBranches()`
      `entries` - see `getOpEntry(PcodeOp)`

- ## 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.PBranch> 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