Class PcodeFrame

java.lang.Object
ghidra.pcode.exec.PcodeFrame

public class PcodeFrame extends Object
The executor's internal counter

To distinguish the program counter of a p-code program from the program counter of the machine it models, we address p-code ops by "index." When derived from an instruction, the address and index together form the "sequence number." Because the executor care's not about the derivation of a p-code program, it counts through indices. The frame carries with it the p-code ops comprising its current p-code program.

A p-code emulator feeds p-code to an executor by decoding one instruction at a time. Thus, the "current p-code program" comprises only those ops generated by a single instruction. Or else, it is a user-supplied p-code program, e.g., to evaluate a Sleigh expression. The frame completes the program by falling-through, i.e., stepping past the final op, or by branching externally, i.e., to a different machine instruction. The emulator must then update its program counter accordingly and proceed to the next instruction.

  • Constructor Details

    • PcodeFrame

      public PcodeFrame(Language language, List<PcodeOp> code, Map<Integer,String> useropNames)
      Construct a frame of p-code execution

      The passed in code should be an immutable list. It is returned directly by getCode(), which would otherwise allow mutation. The frame does not create its own immutable copy as a matter of efficiency. Instead, the provider of the code should create an immutable copy, probably once, e.g., when compiling a PcodeProgram.

      Parameters:
      language - the language to which the program applies
      code - the program's p-code
      useropNames - a map of additional sleigh/p-code userops linked to the program
  • Method Details

    • toString

      public String toString()
      Overrides:
      toString in class Object
    • count

      public int count()
      The number of p-code ops executed

      Contrast this to index(), which marks the next op to be executed. This counts the number of ops executed, which will differ from index when an internal branch is taken.

      Returns:
      the count
    • index

      public int index()
      The index of the next p-code op to be executed

      If the last p-code op resulted in a branch, this will instead return -1.

      Returns:
      the index, i.e, p-code "program counter."
      See Also:
    • nextOp

      public PcodeOp nextOp()
      Get the op at the current index, and then advance that index

      This is used in the execution loop to retrieve each op to execute

      Returns:
      the op to execute
    • advance

      public int advance()
      Advance the index
      Returns:
      the value of the index before it was advanced
    • stepBack

      public int stepBack()
      Step the index back one
      Returns:
      the value of the index before it was stepped back
    • getUseropName

      public String getUseropName(int userop)
      Get the name of the userop for the given number
      Parameters:
      userop - the userop number, as encoded in the first operand of PcodeOp.CALLOTHER
      Returns:
      the name of the userop, as expressed in the Sleigh source
    • getUseropNames

      public Map<Integer,String> getUseropNames()
      Get the map of userop numbers to names
      Returns:
      the map
    • isFallThrough

      public boolean isFallThrough()
      Check if the index has advanced past the end of the p-code program

      If the index has advanced beyond the program, it implies the program has finished executing. In the case of instruction emulation, no branch was encountered. The machine should advance to the fall-through instruction.

      Returns:
      true if the program completed without branching
      See Also:
    • isBranch

      public boolean isBranch()
      Check if the p-code program has executed a branch

      Branches can be internal, i.e., within the current program, or external, i.e., to another machine instructions. This refers strictly to the latter.

      Returns:
      true if the program completed with an external branch
      See Also:
    • isFinished

      public boolean isFinished()
      Check if the p-code program is completely executed
      Returns:
      true if execution finished, either in fall-through or an external branch
      See Also:
    • branch

      public void branch(int rel)
      Perform an internal branch, relative to the current op.

      Because index advances before execution of each op, the index is adjusted by an extra -1.

      Parameters:
      rel - the adjustment to the index
    • finishAsBranch

      public void finishAsBranch()
      Complete the p-code program, indicating an external branch
    • getCode

      public List<PcodeOp> getCode()
      Get all the ops in the current p-code program.
      Returns:
      the list of ops
    • copyCode

      public PcodeOp[] copyCode()
      Copy the frame's code (shallow copy) into a new array
      Returns:
      the array of ops
    • getBranched

      public int getBranched()
      Get the index of the last (branch) op executed

      The behavior here is a bit strange for compatibility with EmulateInstructionStateModifier. If the p-code program (likely derived from a machine instruction) completed with fall-through, then this will return -1. If it completed on a branch, then this will return the index of that branch.

      Returns: