Class TraceSchedule

java.lang.Object
ghidra.trace.model.time.schedule.TraceSchedule
All Implemented Interfaces:
Comparable<TraceSchedule>

public class TraceSchedule extends Object implements Comparable<TraceSchedule>
A sequence of emulator stepping commands, essentially comprising a "point in time."
  • Field Details

    • ZERO

      public static final TraceSchedule ZERO
      The initial snapshot (with no steps)
  • Constructor Details

    • TraceSchedule

      public TraceSchedule(long snap, Sequence steps, Sequence pSteps, TraceSchedule.Source source)
      Construct the given schedule
      Parameters:
      snap - the initial trace snapshot
      steps - the step sequence
      pSteps - the p-code step sequence
      source - if the p-code steps are known not to exceed one instruction
    • TraceSchedule

      public TraceSchedule(long snap, Sequence steps, Sequence pSteps)
      Construct the given schedule, but assumed abnormal
      Parameters:
      snap - the initial trace snapshot
      steps - the step sequence
      pSteps - the p-code step sequence
  • Method Details

    • snap

      public static final TraceSchedule snap(long snap)
      Create a schedule that consists solely of a snapshot
      Parameters:
      snap - the snapshot key
      Returns:
      the schedule
    • parse

      public static TraceSchedule parse(String spec, TraceSchedule.Source source, TraceSchedule.TimeRadix radix)
      Parse schedule in the form "snap[:steps[.pSteps]]"

      A schedule consists of a snap, a optional Sequence of thread instruction-level steps, and optional p-code-level steps (pSteps). The form of steps and pSteps is specified by Sequence.parse(String, TimeRadix). Each sequence consists of stepping selected threads forward, and/or patching machine state.

      Parameters:
      spec - the string specification
      source - the presumed source of the schedule
      radix - the radix
      Returns:
      the parsed schedule
    • parse

      public static TraceSchedule parse(String spec, TraceSchedule.TimeRadix radix)
      As in parse(String, Source, TimeRadix), but assumed abnormal
      Parameters:
      spec - the string specification
      radix - the radix
      Returns:
      the parsed schedule
    • parse

      public static TraceSchedule parse(String spec)
      Parameters:
      spec - the string specification
      Returns:
      the parse sequence
    • toString

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

      public String toString(TraceSchedule.TimeRadix radix)
    • compareSchedule

      public CompareResult compareSchedule(TraceSchedule that)
      Richly compare two schedules

      Schedules starting at different snapshots are never related, because there is no emulator/simulator stepping action which advances to the next snapshot. Though p-code steps may comprise a partial step, we do not consider a partial step to be a prefix of a full step, since we cannot know a priori how many p-code steps comprise a full instruction step. Consider, e.g., the user may specify 100 p-code steps, which could effect 20 instruction steps.

      Parameters:
      that - the object of comparison (this being the subject)
      Returns:
      a result describing the relationship from subject to object
    • equals

      public boolean equals(Object obj)
      Overrides:
      equals in class Object
    • hashCode

      public int hashCode()
      Overrides:
      hashCode in class Object
    • compareTo

      public int compareTo(TraceSchedule o)
      Specified by:
      compareTo in interface Comparable<TraceSchedule>
    • isSnapOnly

      public boolean isSnapOnly()
      Check if this schedule requires any stepping
      Returns:
      true if no stepping is required, i.e., the resulting state can be realized simply by loading a snapshot
    • hasSteps

      public boolean hasSteps()
      Check if this schedule has instruction steps
      Returns:
      true if this indicates at least one instruction step
    • getSnap

      public long getSnap()
      Get the source snapshot
      Returns:
      the snapshot key
    • getLastThreadKey

      public long getLastThreadKey()
      Get the last thread key stepped by this schedule
      Returns:
      the thread key
    • getEventThread

      public TraceThread getEventThread(Trace trace)
      Get the event thread for this schedule in the context of the given trace

      This is the thread stepped when no thread is specified for the first step of the sequence.

      Parameters:
      trace - the trace containing the source snapshot and threads
      Returns:
      the thread to use as "last thread" for the sequence
    • getLastThread

      public TraceThread getLastThread(Trace trace)
      Get the last thread stepped by this schedule in the context of the given trace
      Parameters:
      trace - the trace containing the source snapshot and threads
      Returns:
      the thread last stepped, or the "event thread" when no steps are taken, or null
    • requireLastThread

      public TraceThread requireLastThread(Trace trace)
      Get the last thread stepped by this schedule in the context of the given trace
      Parameters:
      trace - the trace containing the source snapshot and threads
      Returns:
      the thread last stepped, or the "event thread" when no steps are taken
      Throws:
      IllegalArgumentException - if the last thread cannot be determined from this schedule and the given trace.
    • totalTickCount

      public long totalTickCount()
      Compute the total number of ticks taken, including the p-code ticks

      This is suitable for use with TaskMonitor.initialize(long), where that monitor will be passed to execute(Trace, PcodeMachine, TaskMonitor) or similar. Note that patch steps do not count as ticks.

      Returns:
      the number of ticks
    • totalPatchCount

      public long totalPatchCount()
      Compute the total number of patches applied
      Returns:
      the number of patches
    • tickCount

      public long tickCount()
      Compute the number of ticks taken, excluding p-code ticks
      Returns:
      the number of ticks
    • patchCount

      public long patchCount()
      Compute the number of patches, excluding p-code patches
      Returns:
      the number of patches
    • pTickCount

      public long pTickCount()
      Compute the number of p-code ticks taken
      Returns:
      the number of ticks
    • pPatchCount

      public long pPatchCount()
      Compute the number of p-code patches applied
      Returns:
      the number of patches
    • execute

      public void execute(Trace trace, PcodeMachine<?> machine, TaskMonitor monitor) throws CancelledException
      Realize the machine state for this schedule using the given trace and machine

      This method executes this schedule and trailing p-code steps on the given machine, assuming that machine is already "positioned" at the initial snapshot. Assuming successful execution, that machine is now said to be "positioned" at this schedule, and its state is the result of said execution.

      Parameters:
      trace - the trace containing the source snapshot and threads
      machine - a machine bound to the trace whose current state reflects the initial snapshot
      monitor - a monitor for cancellation and progress reporting
      Throws:
      CancelledException - if the execution is cancelled
    • validate

      public void validate(Trace trace)
      Validate this schedule for the given trace

      This performs a dry run of the sequence on the given trace. If the schedule starts on the "last thread," it verifies the snapshot gives the event thread. It also checks that every thread key in the sequence exists in the trace.

      Parameters:
      trace - the trace against which to validate this schedule
    • finish

      public void finish(Trace trace, TraceSchedule position, PcodeMachine<?> machine, TaskMonitor monitor) throws CancelledException
      Realize the machine state for this schedule using the given trace and pre-positioned machine

      This method executes the remaining steps of this schedule and trailing p-code steps on the given machine, assuming that machine is already "positioned" at another given schedule. Assuming successful execution, that machine is now said to be "positioned" at this schedule, and its state is the result of said execution.

      Parameters:
      trace - the trace containing the source snapshot and threads
      position - the current schedule of the given machine
      machine - a machine bound to the trace whose current state reflects the given position
      monitor - a monitor for cancellation and progress reporting
      Throws:
      CancelledException - if the execution is cancelled
      IllegalArgumentException - if the given position is not a prefix of this schedule
    • steppedForward

      public TraceSchedule steppedForward(TraceThread thread, long tickCount)
      Returns the equivalent of executing the schedule (ignoring p-code steps) followed by stepping the given thread count more instructions

      This schedule is left unmodified. If it had any p-code steps, those steps are dropped in the resulting schedule.

      Parameters:
      thread - the thread to step, or null for the "last thread"
      tickCount - the number of ticks to take the thread forward
      Returns:
      the resulting schedule
    • skippedForward

      public TraceSchedule skippedForward(TraceThread thread, long tickCount)
      Behaves as in steppedForward(TraceThread, long), but by appending skips
      Parameters:
      thread - the thread to step, or null for the "last thread"
      tickCount - the number of skips to take the thread forward
      Returns:
      the resulting schedule
    • doSteppedBackward

      protected TraceSchedule doSteppedBackward(Trace trace, long tickCount, Set<Long> visited)
    • steppedBackward

      public TraceSchedule steppedBackward(Trace trace, long stepCount)
      Returns the equivalent of executing count instructions (and all p-code operations) less than this schedule

      This schedule is left unmodified. If it had any p-code steps, those steps and subsequent patches are dropped in the resulting schedule. If count exceeds this schedule's steps, it will try (recursively) to step the source snapshot's schedule backward, if known. Both ticks and patches counts as steps.

      Parameters:
      trace - the trace of this schedule, for context
      stepCount - the number of steps to take backward
      Returns:
      the resulting schedule or null if it cannot be computed
    • steppedPcodeForward

      public TraceSchedule steppedPcodeForward(TraceThread thread, int pTickCount)
      Returns the equivalent of executing the schedule followed by stepping the given thread pTickCount more p-code operations
      Parameters:
      thread - the thread to step, or null for the "last thread"
      pTickCount - the number of p-code ticks to take the thread forward
      Returns:
      the resulting schedule
    • skippedPcodeForward

      public TraceSchedule skippedPcodeForward(TraceThread thread, int pTickCount)
      Behaves as in steppedPcodeForward(TraceThread, int), but by appending skips
      Parameters:
      thread - the thread to step, or null for the "last thread"
      pTickCount - the number of p-code skips to take the thread forward
      Returns:
      the resulting schedule
    • steppedPcodeBackward

      public TraceSchedule steppedPcodeBackward(int pStepCount)
      Returns the equivalent of executing count p-code operations less than this schedule

      If pStepCount exceeds the p-code steps of this schedule, null is returned, since we cannot know a priori how many p-code steps would be required to complete the preceding instruction step. Both p-code ticks and p-code patches counts as p-code steps.

      Parameters:
      pStepCount - the number of p-code steps to take backward
      Returns:
      the resulting schedule or null if it cannot be computed
    • patched

      public TraceSchedule patched(TraceThread thread, Language language, String sleigh)
      Returns the equivalent of executing this schedule then performing a given patch
      Parameters:
      thread - the thread context for the patch; cannot be null
      language - the sleigh language for the patch
      sleigh - a single line of sleigh, excluding the terminating semicolon.
      Returns:
      the resulting schedule
    • patched

      public TraceSchedule patched(TraceThread thread, Language language, List<String> sleigh)
      Returns the equivalent of executing this schedule then performing the given patches
      Parameters:
      thread - the thread context for the patch; cannot be null
      language - the sleigh language for the patch
      sleigh - the lines of sleigh, excluding the terminating semicolons
      Returns:
      the resulting schedule
    • advanced

      public TraceSchedule advanced(TraceSchedule next)
      Compute the schedule resulting from this schedule advanced by the given schedule

      This operation cannot be used to append instruction steps after p-code steps. Thus, if this schedule contains any p-code steps and next has instruction steps, an error will be

      Parameters:
      next - the schedule to append. Its snap is ignored.
      Returns:
      the complete schedule
      Throws:
      IllegalArgumentException - if the result would have instruction steps following p-code steps
    • dropPSteps

      public TraceSchedule dropPSteps()
      Drop the p-code steps
      Returns:
      the schedule without ops
    • getThreads

      public Set<TraceThread> getThreads(Trace trace)
      Get the threads involved in the schedule
      Parameters:
      trace - the trace whose threads to get
      Returns:
      the set of threads
    • assumeRecorded

      public TraceSchedule assumeRecorded()
    • differsOnlyByPatch

      public boolean differsOnlyByPatch(TraceSchedule that)