mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-06 03:50:02 +02:00
GP-4209: GhidraTime-MSTTD integration. Type hints for (most) Python agents.
This commit is contained in:
parent
deb49d5322
commit
21a1602579
93 changed files with 6453 additions and 4118 deletions
|
@ -43,6 +43,7 @@ import ghidra.trace.model.program.TraceVariableSnapProgramView;
|
|||
import ghidra.trace.model.thread.TraceThread;
|
||||
import ghidra.trace.model.time.schedule.PatchStep;
|
||||
import ghidra.trace.model.time.schedule.TraceSchedule;
|
||||
import ghidra.trace.model.time.schedule.TraceSchedule.ScheduleForm;
|
||||
import ghidra.trace.util.TraceRegisterUtils;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
@ -389,22 +390,47 @@ public enum ControlMode {
|
|||
*/
|
||||
public DebuggerCoordinates validateCoordinates(PluginTool tool,
|
||||
DebuggerCoordinates coordinates, ActivationCause cause) {
|
||||
if (!followsPresent()) {
|
||||
if (!followsPresent() || cause != ActivationCause.USER) {
|
||||
return coordinates;
|
||||
}
|
||||
Target target = coordinates.getTarget();
|
||||
if (target == null) {
|
||||
return coordinates;
|
||||
}
|
||||
if (cause == ActivationCause.USER &&
|
||||
(!coordinates.getTime().isSnapOnly() || coordinates.getSnap() != target.getSnap())) {
|
||||
tool.setStatusInfo(
|
||||
"Cannot navigate time in %s mode. Switch to Trace or Emulate mode first."
|
||||
|
||||
ScheduleForm form =
|
||||
target.getSupportedTimeForm(coordinates.getObject(), coordinates.getSnap());
|
||||
if (form == null) {
|
||||
if (coordinates.getTime().isSnapOnly() &&
|
||||
coordinates.getSnap() == target.getSnap()) {
|
||||
return coordinates;
|
||||
}
|
||||
else {
|
||||
tool.setStatusInfo("""
|
||||
Cannot navigate time in %s mode. Switch to Trace or Emulate mode first."""
|
||||
.formatted(name),
|
||||
true);
|
||||
return null;
|
||||
true);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return coordinates;
|
||||
TraceSchedule norm = form.validate(coordinates.getTrace(), coordinates.getTime());
|
||||
if (norm != null) {
|
||||
return coordinates.time(norm);
|
||||
}
|
||||
|
||||
String errMsg = switch (form) {
|
||||
case SNAP_ONLY -> """
|
||||
Target can only navigate to snapshots. Switch to Emulate mode first.""";
|
||||
case SNAP_EVT_STEPS -> """
|
||||
Target can only replay steps on the event thread. Switch to Emulate mode \
|
||||
first.""";
|
||||
case SNAP_ANY_STEPS -> """
|
||||
Target cannot perform p-code steps. Switch to Emulate mode first.""";
|
||||
case SNAP_ANY_STEPS_OPS -> throw new AssertionError();
|
||||
};
|
||||
|
||||
tool.setStatusInfo(errMsg, true);
|
||||
return null;
|
||||
}
|
||||
|
||||
protected TracePlatform platformFor(DebuggerCoordinates coordinates, Address address) {
|
||||
|
|
|
@ -34,8 +34,12 @@ import ghidra.trace.model.breakpoint.TraceBreakpointKind;
|
|||
import ghidra.trace.model.guest.TracePlatform;
|
||||
import ghidra.trace.model.memory.TraceMemoryState;
|
||||
import ghidra.trace.model.stack.TraceStackFrame;
|
||||
import ghidra.trace.model.target.TraceObject;
|
||||
import ghidra.trace.model.target.path.KeyPath;
|
||||
import ghidra.trace.model.thread.TraceThread;
|
||||
import ghidra.trace.model.time.TraceSnapshot;
|
||||
import ghidra.trace.model.time.schedule.TraceSchedule;
|
||||
import ghidra.trace.model.time.schedule.TraceSchedule.ScheduleForm;
|
||||
import ghidra.util.Swing;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
@ -278,13 +282,51 @@ public interface Target {
|
|||
* Get the current snapshot key for the target
|
||||
*
|
||||
* <p>
|
||||
* For most targets, this is the most recently created snapshot.
|
||||
* For most targets, this is the most recently created snapshot. For time-traveling targets, if
|
||||
* may not be. If this returns a negative number, then it refers to a scratch snapshot and
|
||||
* almost certainly indicates time travel with instruction steps. Use {@link #getTime()} in that
|
||||
* case to get a more precise schedule.
|
||||
*
|
||||
* @return the snapshot
|
||||
*/
|
||||
// TODO: Should this be TraceSchedule getTime()?
|
||||
long getSnap();
|
||||
|
||||
/**
|
||||
* Get the current time
|
||||
*
|
||||
* @return the current time
|
||||
*/
|
||||
default TraceSchedule getTime() {
|
||||
long snap = getSnap();
|
||||
if (snap >= 0) {
|
||||
return TraceSchedule.snap(snap);
|
||||
}
|
||||
TraceSnapshot snapshot = getTrace().getTimeManager().getSnapshot(snap, false);
|
||||
if (snapshot == null) {
|
||||
return null;
|
||||
}
|
||||
return snapshot.getSchedule();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the form of schedules supported by "activate" on the back end
|
||||
*
|
||||
* <p>
|
||||
* A non-null return value indicates the back end supports time travel. If it does, the return
|
||||
* value indicates the form of schedules that can be activated, (i.e., via some "go to time"
|
||||
* command). NOTE: Switching threads is considered an event by every time-traveling back end
|
||||
* that we know of. Events are usually mapped to a Ghidra trace's snapshots, and so most back
|
||||
* ends are constrained to schedules of the form {@link ScheduleForm#SNAP_EVT_STEPS}. A back-end
|
||||
* based on emulation may support thread switching. To support p-code op stepping, the back-end
|
||||
* will certainly have to be based on p-code emulation, and it must be using the same Sleigh
|
||||
* language as Ghidra.
|
||||
*
|
||||
* @param obj the object (or an ancestor) that may support time travel
|
||||
* @param snap the <em>destination</em> snapshot
|
||||
* @return the form
|
||||
*/
|
||||
public ScheduleForm getSupportedTimeForm(TraceObject obj, long snap);
|
||||
|
||||
/**
|
||||
* Collect all actions that implement the given common debugger command
|
||||
*
|
||||
|
|
|
@ -402,7 +402,16 @@ public class DebuggerCoordinates {
|
|||
return new DebuggerCoordinates(trace, platform, target, thread, view, newTime, frame, path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get these same coordinates with time replaced by the given schedule
|
||||
*
|
||||
* @param newTime the new schedule
|
||||
* @return the new coordinates
|
||||
*/
|
||||
public DebuggerCoordinates time(TraceSchedule newTime) {
|
||||
if (Objects.equals(time, newTime)) {
|
||||
return this;
|
||||
}
|
||||
if (trace == null) {
|
||||
return NOWHERE;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue