mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-21 12:22:34 +08:00
Merge remote-tracking branch 'origin/GP-5194_Dan_removeLegacyDBTraceTables--SQUASHED'
This commit is contained in:
+19
-18
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -21,16 +21,16 @@ import java.util.function.BiFunction;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import ghidra.debug.api.breakpoint.LogicalBreakpoint;
|
||||
import ghidra.debug.api.breakpoint.LogicalBreakpointsChangeListener;
|
||||
import ghidra.debug.api.breakpoint.LogicalBreakpoint.State;
|
||||
import ghidra.debug.api.breakpoint.LogicalBreakpointsChangeListener;
|
||||
import ghidra.framework.plugintool.ServiceInfo;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.util.CodeUnitLocation;
|
||||
import ghidra.program.util.ProgramLocation;
|
||||
import ghidra.trace.model.Trace;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpoint;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointLocation;
|
||||
import ghidra.trace.model.program.TraceProgramView;
|
||||
|
||||
@ServiceInfo(
|
||||
@@ -99,10 +99,10 @@ public interface DebuggerLogicalBreakpointService {
|
||||
* If the given trace breakpoint is not part of any logical breakpoint, e.g., because the trace
|
||||
* is not opened in the tool or events are still being processed, then null is returned.
|
||||
*
|
||||
* @param bpt the trace breakpoint
|
||||
* @param loc the trace breakpoint location
|
||||
* @return the logical breakpoint, or null
|
||||
*/
|
||||
LogicalBreakpoint getBreakpoint(TraceBreakpoint bpt);
|
||||
LogicalBreakpoint getBreakpoint(TraceBreakpointLocation loc);
|
||||
|
||||
/**
|
||||
* Get the collected logical breakpoints (at present) at the given location.
|
||||
@@ -297,10 +297,10 @@ public interface DebuggerLogicalBreakpointService {
|
||||
*
|
||||
* <p>
|
||||
* If the given location refers to a static image, this behaves as in
|
||||
* {@link #placeBreakpointAt(Program, Address, TraceBreakpointKind)}. If it refers to a trace
|
||||
* view, this behaves as in {@link #placeBreakpointAt(Trace, Address, TraceBreakpointKind)},
|
||||
* ignoring the view's current snapshot in favor of the present. The name is only saved for a
|
||||
* program breakpoint.
|
||||
* {@link #placeBreakpointAt(Program, Address, long, Collection, String)}. If it refers to a
|
||||
* trace view, this behaves as in *
|
||||
* {@link #placeBreakpointAt(Trace, Address, long, Collection, String)}, ignoring the view's
|
||||
* current snapshot in favor of the present. The name is only saved for a program breakpoint.
|
||||
*
|
||||
* @param loc the location
|
||||
* @param length size of the breakpoint, may be ignored by debugger
|
||||
@@ -348,7 +348,7 @@ public interface DebuggerLogicalBreakpointService {
|
||||
/**
|
||||
* Disable a collection of logical breakpoints on target, if applicable
|
||||
*
|
||||
* @see #enableAll(Collection)
|
||||
* @see #enableAll(Collection, Trace)
|
||||
* @param col the collection
|
||||
* @param trace a trace, if the command should be limited to the given trace
|
||||
* @return a future which completes when all associated specifications have been disabled
|
||||
@@ -358,7 +358,7 @@ public interface DebuggerLogicalBreakpointService {
|
||||
/**
|
||||
* Delete, if possible, a collection of logical breakpoints on target, if applicable
|
||||
*
|
||||
* @see #enableAll(Collection)
|
||||
* @see #enableAll(Collection, Trace)
|
||||
* @param col the collection
|
||||
* @param trace a trace, if the command should be limited to the given trace
|
||||
* @return a future which completes when all associated specifications have been deleted
|
||||
@@ -371,7 +371,7 @@ public interface DebuggerLogicalBreakpointService {
|
||||
* @param col the trace breakpoints
|
||||
* @return a future which completes when the command has been processed
|
||||
*/
|
||||
CompletableFuture<Void> enableLocs(Collection<TraceBreakpoint> col);
|
||||
CompletableFuture<Void> enableLocs(Collection<TraceBreakpointLocation> col);
|
||||
|
||||
/**
|
||||
* Disable the given locations
|
||||
@@ -379,7 +379,7 @@ public interface DebuggerLogicalBreakpointService {
|
||||
* @param col the trace breakpoints
|
||||
* @return a future which completes when the command has been processed
|
||||
*/
|
||||
CompletableFuture<Void> disableLocs(Collection<TraceBreakpoint> col);
|
||||
CompletableFuture<Void> disableLocs(Collection<TraceBreakpointLocation> col);
|
||||
|
||||
/**
|
||||
* Delete the given locations
|
||||
@@ -387,7 +387,7 @@ public interface DebuggerLogicalBreakpointService {
|
||||
* @param col the trace breakpoints
|
||||
* @return a future which completes when the command has been processed
|
||||
*/
|
||||
CompletableFuture<Void> deleteLocs(Collection<TraceBreakpoint> col);
|
||||
CompletableFuture<Void> deleteLocs(Collection<TraceBreakpointLocation> col);
|
||||
|
||||
/**
|
||||
* Generate an informational message when toggling the breakpoints
|
||||
@@ -397,7 +397,8 @@ public interface DebuggerLogicalBreakpointService {
|
||||
* is for toggling breakpoints. If the breakpoint set is empty, this should return null, since
|
||||
* the usual behavior in that case is to prompt to place a new breakpoint.
|
||||
*
|
||||
* @see #generateStatusEnable(Collection, Trace))
|
||||
* @see #generateStatusEnable(Collection, Trace)
|
||||
* @param bs the set of logical breakpoints
|
||||
* @param loc a representative location
|
||||
* @return the status message, or null
|
||||
*/
|
||||
@@ -407,12 +408,12 @@ public interface DebuggerLogicalBreakpointService {
|
||||
* Generate an informational message when toggling the breakpoints at the given location
|
||||
*
|
||||
* <p>
|
||||
* This works in the same manner as {@link #generateStatusEnable(Collection, Trace))}, except it
|
||||
* This works in the same manner as {@link #generateStatusEnable(Collection, Trace)}, except it
|
||||
* is for toggling breakpoints at a given location. If there are no breakpoints at the location,
|
||||
* this should return null, since the usual behavior in that case is to prompt to place a new
|
||||
* breakpoint.
|
||||
*
|
||||
* @see #generateStatusEnable(Collection)
|
||||
* @see #generateStatusEnable(Collection, Trace)
|
||||
* @param loc the location
|
||||
* @return the status message, or null
|
||||
*/
|
||||
|
||||
+5
-5
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -18,11 +18,11 @@ package ghidra.debug.api.action;
|
||||
import ghidra.debug.api.tracemgr.DebuggerCoordinates;
|
||||
import ghidra.framework.plugintool.ServiceProvider;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressSpace;
|
||||
import ghidra.program.util.ProgramLocation;
|
||||
import ghidra.trace.model.TraceAddressSnapRange;
|
||||
import ghidra.trace.model.guest.TracePlatform;
|
||||
import ghidra.trace.model.stack.TraceStack;
|
||||
import ghidra.trace.util.TraceAddressSpace;
|
||||
|
||||
/**
|
||||
* The actual tracking logic for a location tracking spec
|
||||
@@ -73,8 +73,8 @@ public interface LocationTracker {
|
||||
* @param coordinates the provider's current coordinates
|
||||
* @return true if re-computation and "goto" is warranted
|
||||
*/
|
||||
boolean affectedByBytesChange(TraceAddressSpace space,
|
||||
TraceAddressSnapRange range, DebuggerCoordinates coordinates);
|
||||
boolean affectedByBytesChange(AddressSpace space, TraceAddressSnapRange range,
|
||||
DebuggerCoordinates coordinates);
|
||||
|
||||
/**
|
||||
* Check if the address should be recomputed given the indicated stack change
|
||||
|
||||
+6
-15
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -20,9 +20,8 @@ import javax.swing.Icon;
|
||||
import ghidra.debug.api.tracemgr.DebuggerCoordinates;
|
||||
import ghidra.framework.options.SaveState;
|
||||
import ghidra.framework.plugintool.AutoConfigState.ConfigFieldCodec;
|
||||
import ghidra.program.model.address.AddressSpace;
|
||||
import ghidra.trace.model.TraceAddressSnapRange;
|
||||
import ghidra.trace.model.memory.TraceMemorySpace;
|
||||
import ghidra.trace.util.TraceAddressSpace;
|
||||
|
||||
/**
|
||||
* A specification for automatic navigation of the dynamic listing
|
||||
@@ -67,21 +66,13 @@ public interface LocationTrackingSpec {
|
||||
* @param current the current coordinates
|
||||
* @return true if the change affects the tracked address for the given coordinates
|
||||
*/
|
||||
static boolean changeIsCurrent(TraceAddressSpace space, TraceAddressSnapRange range,
|
||||
static boolean changeIsCurrent(AddressSpace space, TraceAddressSnapRange range,
|
||||
DebuggerCoordinates current) {
|
||||
if (space == null) {
|
||||
return false;
|
||||
}
|
||||
if (!space.getAddressSpace().isMemorySpace()) {
|
||||
if (current.getThread() == null) {
|
||||
return false;
|
||||
}
|
||||
TraceMemorySpace memSpace = current.getTrace()
|
||||
.getMemoryManager()
|
||||
.getMemoryRegisterSpace(current.getThread(), current.getFrame(), false);
|
||||
if (memSpace == null || memSpace.getAddressSpace() != space.getAddressSpace()) {
|
||||
return false;
|
||||
}
|
||||
if (!space.isMemorySpace() && !current.isRegisterSpace(space)) {
|
||||
return false;
|
||||
}
|
||||
if (!range.getLifespan().contains(current.getSnap())) {
|
||||
return false;
|
||||
|
||||
+13
-11
@@ -28,8 +28,8 @@ import ghidra.program.model.listing.Bookmark;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.util.ProgramLocation;
|
||||
import ghidra.trace.model.Trace;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpoint;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointLocation;
|
||||
import resources.MultiIcon;
|
||||
|
||||
/**
|
||||
@@ -471,6 +471,8 @@ public interface LogicalBreakpoint {
|
||||
*/
|
||||
INCONSISTENT_MIXED(Mode.MIXED, Consistency.INCONSISTENT, NAME_MARKER_INCON_MIX, ICON_MARKER_INCON_MIX);
|
||||
|
||||
public static final List<State> VALUES = List.of(values());
|
||||
|
||||
public final Mode mode;
|
||||
public final Consistency consistency;
|
||||
public final String display;
|
||||
@@ -658,7 +660,7 @@ public interface LogicalBreakpoint {
|
||||
* Get the sleigh injection when emulating this breakpoint
|
||||
*
|
||||
* @return the sleigh injection
|
||||
* @see TraceBreakpoint#getEmuSleigh()
|
||||
* @see TraceBreakpointLocation#getEmuSleigh(long)
|
||||
*/
|
||||
String getEmuSleigh();
|
||||
|
||||
@@ -666,7 +668,7 @@ public interface LogicalBreakpoint {
|
||||
* Set the sleigh injection when emulating this breakpoint
|
||||
*
|
||||
* @param sleigh the sleigh injection
|
||||
* @see TraceBreakpoint#setEmuSleigh(String)
|
||||
* @see TraceBreakpointLocation#setEmuSleigh(long,String)
|
||||
*/
|
||||
void setEmuSleigh(String sleigh);
|
||||
|
||||
@@ -699,7 +701,7 @@ public interface LogicalBreakpoint {
|
||||
*
|
||||
* @return the set of trace breakpoints
|
||||
*/
|
||||
Set<TraceBreakpoint> getTraceBreakpoints();
|
||||
Set<TraceBreakpointLocation> getTraceBreakpoints();
|
||||
|
||||
/**
|
||||
* Get all trace breakpoints for the given trace which map to this logical breakpoint.
|
||||
@@ -707,15 +709,15 @@ public interface LogicalBreakpoint {
|
||||
* @param trace the trace
|
||||
* @return the set of trace breakpoints
|
||||
*/
|
||||
Set<TraceBreakpoint> getTraceBreakpoints(Trace trace);
|
||||
Set<TraceBreakpointLocation> getTraceBreakpoints(Trace trace);
|
||||
|
||||
/**
|
||||
* Get the traces for which this logical breakpoint has an address.
|
||||
*
|
||||
* <p>
|
||||
* Note, this does not necessarily indicate that a {@link TraceBreakpoint} is present for each
|
||||
* trace, but rather that for each returned trace, the logical breakpoint can be mapped to an
|
||||
* address in that trace. See {@link #getParticipatingTraces()}.
|
||||
* Note, this does not necessarily indicate that a {@link TraceBreakpointLocation} is present
|
||||
* for each trace, but rather that for each returned trace, the logical breakpoint can be mapped
|
||||
* to an address in that trace. See {@link #getParticipatingTraces()}.
|
||||
*
|
||||
* @return a copy of the set of traces
|
||||
*/
|
||||
@@ -725,8 +727,8 @@ public interface LogicalBreakpoint {
|
||||
* Get the traces for which this logical breakpoint has a trace breakpoint.
|
||||
*
|
||||
* <p>
|
||||
* Note, unlike {@link #getMappedTraces()}, this does indicate that a {@link TraceBreakpoint} is
|
||||
* present for each trace.
|
||||
* Note, unlike {@link #getMappedTraces()}, this does indicate that a
|
||||
* {@link TraceBreakpointLocation} is present for each trace.
|
||||
*
|
||||
* @return the set of traces
|
||||
*/
|
||||
@@ -779,7 +781,7 @@ public interface LogicalBreakpoint {
|
||||
* @param loc the location
|
||||
* @return the state
|
||||
*/
|
||||
State computeStateForLocation(TraceBreakpoint loc);
|
||||
State computeStateForLocation(TraceBreakpointLocation loc);
|
||||
|
||||
/**
|
||||
* Compute the state for all involved traces and program.
|
||||
|
||||
+4
-4
@@ -17,7 +17,7 @@ package ghidra.debug.api.breakpoint;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpoint;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointLocation;
|
||||
|
||||
public interface LogicalBreakpointsChangeListener {
|
||||
default void breakpointAdded(LogicalBreakpoint added) {
|
||||
@@ -47,12 +47,12 @@ public interface LogicalBreakpointsChangeListener {
|
||||
}
|
||||
}
|
||||
|
||||
default void locationAdded(TraceBreakpoint added) {
|
||||
default void locationAdded(TraceBreakpointLocation added) {
|
||||
}
|
||||
|
||||
default void locationUpdated(TraceBreakpoint updated) {
|
||||
default void locationUpdated(TraceBreakpointLocation updated) {
|
||||
}
|
||||
|
||||
default void locationRemoved(TraceBreakpoint removed) {
|
||||
default void locationRemoved(TraceBreakpointLocation removed) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,8 +29,7 @@ import ghidra.program.model.lang.Register;
|
||||
import ghidra.program.model.lang.RegisterValue;
|
||||
import ghidra.trace.model.Trace;
|
||||
import ghidra.trace.model.TraceExecutionState;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpoint;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind;
|
||||
import ghidra.trace.model.breakpoint.*;
|
||||
import ghidra.trace.model.guest.TracePlatform;
|
||||
import ghidra.trace.model.memory.TraceMemoryState;
|
||||
import ghidra.trace.model.stack.TraceStackFrame;
|
||||
@@ -617,12 +616,12 @@ public interface Target {
|
||||
* @param breakpoint the breakpoint
|
||||
* @return true if valid
|
||||
*/
|
||||
boolean isBreakpointValid(TraceBreakpoint breakpoint);
|
||||
boolean isBreakpointValid(TraceBreakpointLocation breakpoint);
|
||||
|
||||
/**
|
||||
* @see #deleteBreakpoint(TraceBreakpoint)
|
||||
* @see #deleteBreakpoint(TraceBreakpointCommon)
|
||||
*/
|
||||
CompletableFuture<Void> deleteBreakpointAsync(TraceBreakpoint breakpoint);
|
||||
CompletableFuture<Void> deleteBreakpointAsync(TraceBreakpointCommon breakpoint);
|
||||
|
||||
/**
|
||||
* Delete the given breakpoint from the target
|
||||
@@ -633,12 +632,13 @@ public interface Target {
|
||||
*
|
||||
* @param breakpoint the breakpoint to delete
|
||||
*/
|
||||
void deleteBreakpoint(TraceBreakpoint breakpoint);
|
||||
void deleteBreakpoint(TraceBreakpointCommon breakpoint);
|
||||
|
||||
/**
|
||||
* @see #toggleBreakpoint(TraceBreakpoint, boolean)
|
||||
* @see #toggleBreakpoint(TraceBreakpointLocation, boolean)
|
||||
*/
|
||||
CompletableFuture<Void> toggleBreakpointAsync(TraceBreakpoint breakpoint, boolean enabled);
|
||||
CompletableFuture<Void> toggleBreakpointAsync(TraceBreakpointCommon breakpoint,
|
||||
boolean enabled);
|
||||
|
||||
/**
|
||||
* Toggle the given breakpoint on the target
|
||||
@@ -651,7 +651,7 @@ public interface Target {
|
||||
* @param breakpoint the breakpoint to toggle
|
||||
* @param enabled true to enable, false to disable
|
||||
*/
|
||||
void toggleBreakpoint(TraceBreakpoint breakpoint, boolean enabled);
|
||||
void toggleBreakpoint(TraceBreakpointCommon breakpoint, boolean enabled);
|
||||
|
||||
/**
|
||||
* @see #forceTerminate()
|
||||
|
||||
+37
-36
@@ -27,15 +27,16 @@ import ghidra.framework.model.*;
|
||||
import ghidra.framework.options.SaveState;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
import ghidra.framework.store.LockException;
|
||||
import ghidra.program.model.address.AddressSpace;
|
||||
import ghidra.trace.database.DBTraceContentHandler;
|
||||
import ghidra.trace.model.Lifespan;
|
||||
import ghidra.trace.model.Trace;
|
||||
import ghidra.trace.model.guest.TracePlatform;
|
||||
import ghidra.trace.model.program.TraceProgramView;
|
||||
import ghidra.trace.model.stack.*;
|
||||
import ghidra.trace.model.stack.TraceStack;
|
||||
import ghidra.trace.model.stack.TraceStackFrame;
|
||||
import ghidra.trace.model.target.TraceObject;
|
||||
import ghidra.trace.model.target.path.KeyPath;
|
||||
import ghidra.trace.model.thread.TraceObjectThread;
|
||||
import ghidra.trace.model.thread.TraceThread;
|
||||
import ghidra.trace.model.time.TraceSnapshot;
|
||||
import ghidra.trace.model.time.schedule.TraceSchedule;
|
||||
@@ -315,36 +316,34 @@ public class DebuggerCoordinates {
|
||||
return thread(trace.getThreadManager().getThread(thread.getKey()));
|
||||
}
|
||||
|
||||
private static KeyPath resolvePath(TraceThread thread, Integer frameLevel,
|
||||
TraceSchedule time) {
|
||||
if (thread instanceof TraceObjectThread tot) {
|
||||
TraceObject objThread = tot.getObject();
|
||||
if (frameLevel == null) {
|
||||
return objThread.getCanonicalPath();
|
||||
}
|
||||
TraceStack stack;
|
||||
long snap = time.getSnap();
|
||||
try {
|
||||
stack = thread.getTrace().getStackManager().getStack(thread, snap, false);
|
||||
}
|
||||
catch (IllegalStateException e) {
|
||||
// Schema does not specify a stack
|
||||
return objThread.getCanonicalPath();
|
||||
}
|
||||
if (stack == null) {
|
||||
return objThread.getCanonicalPath();
|
||||
}
|
||||
TraceStackFrame frame = stack.getFrame(snap, frameLevel, false);
|
||||
if (frame == null) {
|
||||
return objThread.getCanonicalPath();
|
||||
}
|
||||
return ((TraceObjectStackFrame) frame).getObject().getCanonicalPath();
|
||||
private static KeyPath resolvePath(TraceThread thread, Integer frameLevel, TraceSchedule time) {
|
||||
if (thread == null) {
|
||||
return KeyPath.of();
|
||||
}
|
||||
return null;
|
||||
TraceObject objThread = thread.getObject();
|
||||
if (frameLevel == null) {
|
||||
return objThread.getCanonicalPath();
|
||||
}
|
||||
TraceStack stack;
|
||||
long snap = time.getSnap();
|
||||
try {
|
||||
stack = thread.getTrace().getStackManager().getStack(thread, snap, false);
|
||||
}
|
||||
catch (IllegalStateException e) {
|
||||
// Schema does not specify a stack
|
||||
return objThread.getCanonicalPath();
|
||||
}
|
||||
if (stack == null) {
|
||||
return objThread.getCanonicalPath();
|
||||
}
|
||||
TraceStackFrame frame = stack.getFrame(snap, frameLevel, false);
|
||||
if (frame == null) {
|
||||
return objThread.getCanonicalPath();
|
||||
}
|
||||
return frame.getObject().getCanonicalPath();
|
||||
}
|
||||
|
||||
private static KeyPath choose(KeyPath curPath,
|
||||
KeyPath newPath) {
|
||||
private static KeyPath choose(KeyPath curPath, KeyPath newPath) {
|
||||
if (curPath == null) {
|
||||
return newPath;
|
||||
}
|
||||
@@ -525,9 +524,7 @@ public class DebuggerCoordinates {
|
||||
if (object == null) {
|
||||
return null;
|
||||
}
|
||||
return object.queryCanonicalAncestorsInterface(TraceObjectThread.class)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
return object.queryCanonicalAncestorsInterface(TraceThread.class).findFirst().orElse(null);
|
||||
}
|
||||
|
||||
private static Integer resolveFrame(Trace trace, KeyPath path) {
|
||||
@@ -535,10 +532,9 @@ public class DebuggerCoordinates {
|
||||
if (object == null) {
|
||||
return null;
|
||||
}
|
||||
TraceObjectStackFrame frame =
|
||||
object.queryCanonicalAncestorsInterface(TraceObjectStackFrame.class)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
TraceStackFrame frame = object.queryCanonicalAncestorsInterface(TraceStackFrame.class)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
return frame == null ? null : frame.getLevel();
|
||||
}
|
||||
|
||||
@@ -669,6 +665,11 @@ public class DebuggerCoordinates {
|
||||
return registerContainer = object.findRegisterContainer(getFrame());
|
||||
}
|
||||
|
||||
public boolean isRegisterSpace(AddressSpace space) {
|
||||
TraceObject container = getRegisterContainer();
|
||||
return container != null && container.getCanonicalPath().toString().equals(space.getName());
|
||||
}
|
||||
|
||||
public synchronized long getViewSnap() {
|
||||
if (viewSnap != null) {
|
||||
return viewSnap;
|
||||
|
||||
@@ -53,7 +53,6 @@ import ghidra.trace.model.program.TraceProgramView;
|
||||
import ghidra.trace.model.target.TraceObject;
|
||||
import ghidra.trace.model.target.TraceObjectValue;
|
||||
import ghidra.trace.model.target.path.KeyPath;
|
||||
import ghidra.trace.model.thread.TraceObjectThread;
|
||||
import ghidra.trace.model.thread.TraceThread;
|
||||
import ghidra.trace.model.time.schedule.TraceSchedule;
|
||||
import ghidra.util.MathUtilities;
|
||||
@@ -1452,11 +1451,7 @@ public interface FlatDebuggerAPI {
|
||||
}
|
||||
|
||||
default ActionContext createContext(TraceThread thread) {
|
||||
if (thread instanceof TraceObjectThread objThread) {
|
||||
return createContext(objThread.getObject());
|
||||
}
|
||||
return new DebuggerSingleObjectPathActionContext(
|
||||
KeyPath.parse(thread.getPath()));
|
||||
return createContext(thread.getObject());
|
||||
}
|
||||
|
||||
default ActionContext createContext(Trace trace) {
|
||||
|
||||
@@ -21,7 +21,7 @@ import java.util.Map;
|
||||
import com.sun.jdi.*;
|
||||
|
||||
import ghidra.app.plugin.core.debug.client.tracermi.*;
|
||||
import ghidra.app.plugin.core.debug.client.tracermi.RmiMethodRegistry.TraceMethod;
|
||||
import ghidra.app.plugin.core.debug.client.tracermi.RmiMethodRegistry.TraceRmiMethod;
|
||||
import ghidra.dbg.jdi.manager.impl.DebugStatus;
|
||||
import ghidra.dbg.jdi.manager.impl.JdiManagerImpl;
|
||||
import ghidra.program.model.address.*;
|
||||
@@ -144,7 +144,7 @@ public class JdiConnector {
|
||||
}
|
||||
|
||||
public void registerRemoteMethod(JdiMethods methods, java.lang.reflect.Method m, String name) {
|
||||
TraceMethod annot = m.getAnnotation(TraceMethod.class);
|
||||
TraceRmiMethod annot = m.getAnnotation(TraceRmiMethod.class);
|
||||
if (annot == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
+113
-113
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -26,7 +26,7 @@ public class RmiMethodRegistry {
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public static @interface TraceMethod {
|
||||
public static @interface TraceRmiMethod {
|
||||
String action() default "";
|
||||
|
||||
String display() default "";
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ package ghidra.app.plugin.core.debug.client.tracermi;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Parameter;
|
||||
|
||||
import ghidra.trace.model.target.iface.TraceObjectMethod.ParameterDescription;
|
||||
import ghidra.trace.model.target.iface.TraceMethod.ParameterDescription;
|
||||
import ghidra.trace.model.target.schema.*;
|
||||
import ghidra.trace.model.target.schema.TraceObjectSchema.SchemaName;
|
||||
|
||||
|
||||
+55
-75
@@ -51,7 +51,8 @@ import ghidra.trace.model.breakpoint.*;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind.TraceBreakpointKindSet;
|
||||
import ghidra.trace.model.guest.TracePlatform;
|
||||
import ghidra.trace.model.memory.*;
|
||||
import ghidra.trace.model.stack.*;
|
||||
import ghidra.trace.model.stack.TraceStack;
|
||||
import ghidra.trace.model.stack.TraceStackFrame;
|
||||
import ghidra.trace.model.target.*;
|
||||
import ghidra.trace.model.target.iface.*;
|
||||
import ghidra.trace.model.target.info.TraceObjectInterfaceUtils;
|
||||
@@ -60,7 +61,8 @@ import ghidra.trace.model.target.path.PathFilter.Align;
|
||||
import ghidra.trace.model.target.schema.*;
|
||||
import ghidra.trace.model.target.schema.PrimitiveTraceObjectSchema.MinimalSchemaContext;
|
||||
import ghidra.trace.model.target.schema.TraceObjectSchema.SchemaName;
|
||||
import ghidra.trace.model.thread.*;
|
||||
import ghidra.trace.model.thread.TraceProcess;
|
||||
import ghidra.trace.model.thread.TraceThread;
|
||||
import ghidra.trace.model.time.schedule.TraceSchedule.ScheduleForm;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
@@ -186,12 +188,12 @@ public class TraceRmiTarget extends AbstractTarget {
|
||||
}
|
||||
|
||||
protected ScheduleForm getSupportedTimeFormByAttribute(TraceObject obj, long snap) {
|
||||
TraceObject eventScope = obj.findSuitableInterface(TraceObjectEventScope.class);
|
||||
TraceObject eventScope = obj.findSuitableInterface(TraceEventScope.class);
|
||||
if (eventScope == null) {
|
||||
return null;
|
||||
}
|
||||
TraceObjectValue timeSupportStr =
|
||||
eventScope.getAttribute(snap, TraceObjectEventScope.KEY_TIME_SUPPORT);
|
||||
eventScope.getAttribute(snap, TraceEventScope.KEY_TIME_SUPPORT);
|
||||
if (timeSupportStr == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -213,11 +215,7 @@ public class TraceRmiTarget extends AbstractTarget {
|
||||
|
||||
@Override
|
||||
public TraceExecutionState getThreadExecutionState(TraceThread thread) {
|
||||
if (!(thread instanceof TraceObjectThread tot)) {
|
||||
Msg.error(this, "Non-object thread with Trace RMI!");
|
||||
return TraceExecutionState.ALIVE;
|
||||
}
|
||||
return tot.getObject().getExecutionState(getSnap());
|
||||
return thread.getObject().getExecutionState(getSnap());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -226,7 +224,7 @@ public class TraceRmiTarget extends AbstractTarget {
|
||||
if (object == null) {
|
||||
return null;
|
||||
}
|
||||
return object.queryCanonicalAncestorsInterface(TraceObjectThread.class)
|
||||
return object.queryCanonicalAncestorsInterface(TraceThread.class)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
@@ -237,7 +235,7 @@ public class TraceRmiTarget extends AbstractTarget {
|
||||
if (object == null) {
|
||||
return null;
|
||||
}
|
||||
return object.queryCanonicalAncestorsInterface(TraceObjectStackFrame.class)
|
||||
return object.queryCanonicalAncestorsInterface(TraceStackFrame.class)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
@@ -303,7 +301,7 @@ public class TraceRmiTarget extends AbstractTarget {
|
||||
return null;
|
||||
}
|
||||
TraceObjectValue attrEnabled =
|
||||
object.getAttribute(getSnap(), TraceObjectTogglable.KEY_ENABLED);
|
||||
object.getAttribute(getSnap(), TraceTogglable.KEY_ENABLED);
|
||||
boolean enabled = attrEnabled != null && attrEnabled.getValue() instanceof Boolean b && b;
|
||||
return !enabled;
|
||||
}
|
||||
@@ -549,7 +547,7 @@ public class TraceRmiTarget extends AbstractTarget {
|
||||
}
|
||||
return schema
|
||||
.getInterfaces()
|
||||
.contains(TraceObjectFocusScope.class) &&
|
||||
.contains(TraceFocusScope.class) &&
|
||||
!connection.getMethods().getByAction(ActionName.ACTIVATE).isEmpty();
|
||||
}
|
||||
|
||||
@@ -557,7 +555,7 @@ public class TraceRmiTarget extends AbstractTarget {
|
||||
public KeyPath getFocus() {
|
||||
TraceObjectValue focusVal = trace.getObjectManager()
|
||||
.getRootObject()
|
||||
.getAttribute(getSnap(), TraceObjectFocusScope.KEY_FOCUS);
|
||||
.getAttribute(getSnap(), TraceFocusScope.KEY_FOCUS);
|
||||
if (focusVal == null || !focusVal.isObject()) {
|
||||
return null;
|
||||
}
|
||||
@@ -740,7 +738,7 @@ public class TraceRmiTarget extends AbstractTarget {
|
||||
|
||||
record ReadMemMatcher(int score, List<ParamSpec> spec) implements MethodMatcher {
|
||||
static final ReadMemMatcher HAS_PROC_RANGE = new ReadMemMatcher(2, List.of(
|
||||
new TypeParamSpec("process", TraceObjectProcess.class),
|
||||
new TypeParamSpec("process", TraceProcess.class),
|
||||
new TypeParamSpec("range", AddressRange.class)));
|
||||
static final ReadMemMatcher HAS_RANGE = new ReadMemMatcher(1, List.of(
|
||||
new TypeParamSpec("range", AddressRange.class)));
|
||||
@@ -749,7 +747,7 @@ public class TraceRmiTarget extends AbstractTarget {
|
||||
|
||||
record WriteMemMatcher(int score, List<ParamSpec> spec) implements MethodMatcher {
|
||||
static final WriteMemMatcher HAS_PROC_START_DATA = new WriteMemMatcher(2, List.of(
|
||||
new TypeParamSpec("process", TraceObjectProcess.class),
|
||||
new TypeParamSpec("process", TraceProcess.class),
|
||||
new TypeParamSpec("start", Address.class),
|
||||
new TypeParamSpec("data", byte[].class)));
|
||||
static final WriteMemMatcher HAS_START_DATA = new WriteMemMatcher(1, List.of(
|
||||
@@ -760,43 +758,43 @@ public class TraceRmiTarget extends AbstractTarget {
|
||||
|
||||
record ReadRegsMatcher(int score, List<ParamSpec> spec) implements MethodMatcher {
|
||||
static final ReadRegsMatcher HAS_CONTAINER = new ReadRegsMatcher(3, List.of(
|
||||
new TypeParamSpec("container", TraceObjectRegisterContainer.class)));
|
||||
new TypeParamSpec("container", TraceRegisterContainer.class)));
|
||||
static final ReadRegsMatcher HAS_REGISTER = new ReadRegsMatcher(1, List.of(
|
||||
new TypeParamSpec("register", TraceObjectRegister.class)));
|
||||
new TypeParamSpec("register", TraceRegister.class)));
|
||||
static final List<ReadRegsMatcher> ALL = matchers(HAS_CONTAINER, HAS_REGISTER);
|
||||
}
|
||||
|
||||
record WriteRegMatcher(int score, List<ParamSpec> spec) implements MethodMatcher {
|
||||
static final WriteRegMatcher HAS_FRAME_NAME_VALUE = new WriteRegMatcher(3, List.of(
|
||||
new TypeParamSpec("frame", TraceObjectStackFrame.class),
|
||||
new TypeParamSpec("frame", TraceStackFrame.class),
|
||||
new TypeParamSpec("name", String.class),
|
||||
new TypeParamSpec("value", byte[].class)));
|
||||
static final WriteRegMatcher HAS_THREAD_NAME_VALUE = new WriteRegMatcher(2, List.of(
|
||||
new TypeParamSpec("thread", TraceObjectThread.class),
|
||||
new TypeParamSpec("thread", TraceThread.class),
|
||||
new TypeParamSpec("name", String.class),
|
||||
new TypeParamSpec("value", byte[].class)));
|
||||
static final WriteRegMatcher HAS_REG_VALUE = new WriteRegMatcher(1, List.of(
|
||||
new TypeParamSpec("register", TraceObjectRegister.class),
|
||||
new TypeParamSpec("register", TraceRegister.class),
|
||||
new TypeParamSpec("value", byte[].class)));
|
||||
static final List<WriteRegMatcher> ALL = matchers(HAS_FRAME_NAME_VALUE, HAS_REG_VALUE);
|
||||
}
|
||||
|
||||
record BreakExecMatcher(int score, List<ParamSpec> spec) implements MethodMatcher {
|
||||
static final BreakExecMatcher HAS_PROC_ADDR_COND_CMDS = new BreakExecMatcher(8, List.of(
|
||||
new TypeParamSpec("process", TraceObjectProcess.class),
|
||||
new TypeParamSpec("process", TraceProcess.class),
|
||||
new TypeParamSpec("address", Address.class),
|
||||
new NameParamSpec("condition", String.class),
|
||||
new NameParamSpec("commands", String.class)));
|
||||
static final BreakExecMatcher HAS_PROC_ADDR_COND = new BreakExecMatcher(7, List.of(
|
||||
new TypeParamSpec("process", TraceObjectProcess.class),
|
||||
new TypeParamSpec("process", TraceProcess.class),
|
||||
new TypeParamSpec("address", Address.class),
|
||||
new NameParamSpec("condition", String.class)));
|
||||
static final BreakExecMatcher HAS_PROC_ADDR_CMDS = new BreakExecMatcher(6, List.of(
|
||||
new TypeParamSpec("process", TraceObjectProcess.class),
|
||||
new TypeParamSpec("process", TraceProcess.class),
|
||||
new TypeParamSpec("address", Address.class),
|
||||
new NameParamSpec("commands", String.class)));
|
||||
static final BreakExecMatcher HAS_PROC_ADDR = new BreakExecMatcher(5, List.of(
|
||||
new TypeParamSpec("process", TraceObjectProcess.class),
|
||||
new TypeParamSpec("process", TraceProcess.class),
|
||||
new TypeParamSpec("address", Address.class)));
|
||||
static final BreakExecMatcher HAS_ADDR_COND_CMDS = new BreakExecMatcher(4, List.of(
|
||||
new TypeParamSpec("address", Address.class),
|
||||
@@ -818,20 +816,20 @@ public class TraceRmiTarget extends AbstractTarget {
|
||||
// TODO: Probably need a better way to deal with optional requirements
|
||||
record BreakAccMatcher(int score, List<ParamSpec> spec) implements MethodMatcher {
|
||||
static final BreakAccMatcher HAS_PROC_RNG_COND_CMDS = new BreakAccMatcher(8, List.of(
|
||||
new TypeParamSpec("process", TraceObjectProcess.class),
|
||||
new TypeParamSpec("process", TraceProcess.class),
|
||||
new TypeParamSpec("range", AddressRange.class),
|
||||
new NameParamSpec("condition", String.class),
|
||||
new NameParamSpec("commands", String.class)));
|
||||
static final BreakAccMatcher HAS_PROC_RNG_COND = new BreakAccMatcher(7, List.of(
|
||||
new TypeParamSpec("process", TraceObjectProcess.class),
|
||||
new TypeParamSpec("process", TraceProcess.class),
|
||||
new TypeParamSpec("range", AddressRange.class),
|
||||
new NameParamSpec("condition", String.class)));
|
||||
static final BreakAccMatcher HAS_PROC_RNG_CMDS = new BreakAccMatcher(6, List.of(
|
||||
new TypeParamSpec("process", TraceObjectProcess.class),
|
||||
new TypeParamSpec("process", TraceProcess.class),
|
||||
new TypeParamSpec("range", AddressRange.class),
|
||||
new NameParamSpec("commands", String.class)));
|
||||
static final BreakAccMatcher HAS_PROC_RNG = new BreakAccMatcher(5, List.of(
|
||||
new TypeParamSpec("process", TraceObjectProcess.class),
|
||||
new TypeParamSpec("process", TraceProcess.class),
|
||||
new TypeParamSpec("range", AddressRange.class)));
|
||||
static final BreakAccMatcher HAS_RNG_COND_CMDS = new BreakAccMatcher(4, List.of(
|
||||
new TypeParamSpec("range", AddressRange.class),
|
||||
@@ -852,19 +850,19 @@ public class TraceRmiTarget extends AbstractTarget {
|
||||
|
||||
record DelBreakMatcher(int score, List<ParamSpec> spec) implements MethodMatcher {
|
||||
static final DelBreakMatcher HAS_LOC = new DelBreakMatcher(2, List.of(
|
||||
new TypeParamSpec("location", TraceObjectBreakpointLocation.class)));
|
||||
new TypeParamSpec("location", TraceBreakpointLocation.class)));
|
||||
static final DelBreakMatcher HAS_SPEC = new DelBreakMatcher(1, List.of(
|
||||
new TypeParamSpec("specification", TraceObjectBreakpointSpec.class)));
|
||||
new TypeParamSpec("specification", TraceBreakpointSpec.class)));
|
||||
static final List<DelBreakMatcher> ALL = matchers(HAS_LOC, HAS_SPEC);
|
||||
static final List<DelBreakMatcher> SPEC = matchers(HAS_SPEC);
|
||||
}
|
||||
|
||||
record ToggleBreakMatcher(int score, List<ParamSpec> spec) implements MethodMatcher {
|
||||
static final ToggleBreakMatcher HAS_LOC = new ToggleBreakMatcher(2, List.of(
|
||||
new TypeParamSpec("location", TraceObjectBreakpointLocation.class),
|
||||
new TypeParamSpec("location", TraceBreakpointLocation.class),
|
||||
new TypeParamSpec("enabled", Boolean.class)));
|
||||
static final ToggleBreakMatcher HAS_SPEC = new ToggleBreakMatcher(1, List.of(
|
||||
new TypeParamSpec("specification", TraceObjectBreakpointSpec.class),
|
||||
new TypeParamSpec("specification", TraceBreakpointSpec.class),
|
||||
new TypeParamSpec("enabled", Boolean.class)));
|
||||
static final List<ToggleBreakMatcher> ALL = matchers(HAS_LOC, HAS_SPEC);
|
||||
static final List<ToggleBreakMatcher> SPEC = matchers(HAS_SPEC);
|
||||
@@ -1079,8 +1077,8 @@ public class TraceRmiTarget extends AbstractTarget {
|
||||
}
|
||||
|
||||
protected TraceObject getProcessForSpace(AddressSpace space) {
|
||||
List<TraceObjectProcess> processes = trace.getObjectManager()
|
||||
.queryAllInterface(Lifespan.at(getSnap()), TraceObjectProcess.class)
|
||||
List<TraceProcess> processes = trace.getObjectManager()
|
||||
.queryAllInterface(Lifespan.at(getSnap()), TraceProcess.class)
|
||||
.toList();
|
||||
if (processes.size() == 1) {
|
||||
return processes.get(0).getObject();
|
||||
@@ -1089,11 +1087,10 @@ public class TraceRmiTarget extends AbstractTarget {
|
||||
return null;
|
||||
}
|
||||
for (TraceMemoryRegion region : trace.getMemoryManager()
|
||||
.getRegionsIntersecting(
|
||||
Lifespan.at(getSnap()),
|
||||
.getRegionsIntersecting(Lifespan.at(getSnap()),
|
||||
new AddressRangeImpl(space.getMinAddress(), space.getMaxAddress()))) {
|
||||
TraceObject obj = ((TraceObjectMemoryRegion) region).getObject();
|
||||
return obj.findCanonicalAncestorsInterface(TraceObjectProcess.class)
|
||||
TraceObject obj = region.getObject();
|
||||
return obj.findCanonicalAncestorsInterface(TraceProcess.class)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
@@ -1207,11 +1204,7 @@ public class TraceRmiTarget extends AbstractTarget {
|
||||
if (readRegs == null) {
|
||||
return AsyncUtils.nil();
|
||||
}
|
||||
if (!(thread instanceof TraceObjectThread tot)) {
|
||||
Msg.error(this, "Non-object trace with TraceRmi!");
|
||||
return AsyncUtils.nil();
|
||||
}
|
||||
TraceObject container = tot.getObject().findRegisterContainer(frame);
|
||||
TraceObject container = thread.getObject().findRegisterContainer(frame);
|
||||
if (container == null) {
|
||||
Msg.error(this,
|
||||
"Cannot find register container for thread,frame: " + thread + "," + frame);
|
||||
@@ -1229,8 +1222,7 @@ public class TraceRmiTarget extends AbstractTarget {
|
||||
keys.add("[" + lower + "]");
|
||||
}
|
||||
Set<TraceObject> regs = container
|
||||
.findSuccessorsInterface(Lifespan.at(getSnap()), TraceObjectRegister.class,
|
||||
true)
|
||||
.findSuccessorsInterface(Lifespan.at(getSnap()), TraceRegister.class, true)
|
||||
.filter(p -> keys.contains(p.getLastEntry().getEntryKey().toLowerCase()))
|
||||
.map(r -> r.getDestination(null))
|
||||
.collect(Collectors.toSet());
|
||||
@@ -1303,14 +1295,13 @@ public class TraceRmiTarget extends AbstractTarget {
|
||||
return findRegister(container, filter, parent);
|
||||
}
|
||||
|
||||
protected FoundRegister findRegister(TraceObjectThread thread, int frame,
|
||||
Register register) {
|
||||
protected FoundRegister findRegister(TraceThread thread, int frame, Register register) {
|
||||
TraceObject container = thread.getObject().findRegisterContainer(frame);
|
||||
if (container == null) {
|
||||
Msg.error(this, "No register container for thread=" + thread + ",frame=" + frame);
|
||||
return null;
|
||||
}
|
||||
PathFilter filter = container.getSchema().searchFor(TraceObjectRegister.class, true);
|
||||
PathFilter filter = container.getSchema().searchFor(TraceRegister.class, true);
|
||||
return findRegister(container, filter, register);
|
||||
}
|
||||
|
||||
@@ -1337,11 +1328,7 @@ public class TraceRmiTarget extends AbstractTarget {
|
||||
if (writeReg == null) {
|
||||
return AsyncUtils.nil();
|
||||
}
|
||||
if (!(thread instanceof TraceObjectThread tot)) {
|
||||
Msg.error(this, "Non-object trace with TraceRmi!");
|
||||
return AsyncUtils.nil();
|
||||
}
|
||||
FoundRegister found = findRegister(tot, frameLevel, value.getRegister());
|
||||
FoundRegister found = findRegister(thread, frameLevel, value.getRegister());
|
||||
if (found == null) {
|
||||
Msg.warn(this, "Could not find register " + value.getRegister() + " in object model.");
|
||||
}
|
||||
@@ -1352,7 +1339,7 @@ public class TraceRmiTarget extends AbstractTarget {
|
||||
RemoteParameter paramThread = writeReg.params.get("thread");
|
||||
if (paramThread != null) {
|
||||
return writeReg.method.invokeAsync(Map.ofEntries(
|
||||
Map.entry(paramThread.name(), tot.getObject()),
|
||||
Map.entry(paramThread.name(), thread.getObject()),
|
||||
Map.entry(writeReg.params.get("name").name(), found.name()),
|
||||
Map.entry(writeReg.params.get("value").name(), getBytes(value))))
|
||||
.toCompletableFuture()
|
||||
@@ -1363,12 +1350,8 @@ public class TraceRmiTarget extends AbstractTarget {
|
||||
if (paramFrame != null) {
|
||||
TraceStack stack = trace.getStackManager().getLatestStack(thread, getSnap());
|
||||
TraceStackFrame frame = stack.getFrame(getSnap(), frameLevel, false);
|
||||
if (!(frame instanceof TraceObjectStackFrame tof)) {
|
||||
Msg.error(this, "Non-object trace with TraceRmi!");
|
||||
return AsyncUtils.nil();
|
||||
}
|
||||
return writeReg.method.invokeAsync(Map.ofEntries(
|
||||
Map.entry(paramFrame.name(), tof.getObject()),
|
||||
Map.entry(paramFrame.name(), frame.getObject()),
|
||||
Map.entry(writeReg.params.get("name").name(), found.name()),
|
||||
Map.entry(writeReg.params.get("value").name(), getBytes(value))))
|
||||
.toCompletableFuture()
|
||||
@@ -1398,11 +1381,8 @@ public class TraceRmiTarget extends AbstractTarget {
|
||||
if (register == null) {
|
||||
return false;
|
||||
}
|
||||
if (!(thread instanceof TraceObjectThread tot)) {
|
||||
return false;
|
||||
}
|
||||
// May be primitive or object
|
||||
FoundRegister found = findRegister(tot, frame, register);
|
||||
FoundRegister found = findRegister(thread, frame, register);
|
||||
if (found == null) {
|
||||
return false;
|
||||
}
|
||||
@@ -1596,7 +1576,7 @@ public class TraceRmiTarget extends AbstractTarget {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBreakpointValid(TraceBreakpoint breakpoint) {
|
||||
public boolean isBreakpointValid(TraceBreakpointLocation breakpoint) {
|
||||
long snap = getSnap();
|
||||
if (breakpoint.getName(snap).endsWith("emu-" + breakpoint.getMinAddress(snap))) {
|
||||
return false;
|
||||
@@ -1607,7 +1587,7 @@ public class TraceRmiTarget extends AbstractTarget {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected CompletableFuture<Void> deleteBreakpointSpecAsync(TraceObjectBreakpointSpec spec) {
|
||||
protected CompletableFuture<Void> deleteBreakpointSpecAsync(TraceBreakpointSpec spec) {
|
||||
KeyPath path = spec.getObject().getCanonicalPath();
|
||||
MatchedMethod delBreak =
|
||||
matches.getBest(DelBreakMatcher.class, path, ActionName.DELETE, DelBreakMatcher.SPEC);
|
||||
@@ -1621,7 +1601,7 @@ public class TraceRmiTarget extends AbstractTarget {
|
||||
}
|
||||
|
||||
// TODO: Would this make sense for any debugger? To delete individual locations?
|
||||
protected CompletableFuture<Void> deleteBreakpointLocAsync(TraceObjectBreakpointLocation loc) {
|
||||
protected CompletableFuture<Void> deleteBreakpointLocAsync(TraceBreakpointLocation loc) {
|
||||
KeyPath path = loc.getObject().getCanonicalPath();
|
||||
MatchedMethod delBreak =
|
||||
matches.getBest(DelBreakMatcher.class, path, ActionName.DELETE, DelBreakMatcher.ALL);
|
||||
@@ -1639,18 +1619,18 @@ public class TraceRmiTarget extends AbstractTarget {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> deleteBreakpointAsync(TraceBreakpoint breakpoint) {
|
||||
if (breakpoint instanceof TraceObjectBreakpointLocation loc) {
|
||||
public CompletableFuture<Void> deleteBreakpointAsync(TraceBreakpointCommon breakpoint) {
|
||||
if (breakpoint instanceof TraceBreakpointLocation loc) {
|
||||
return deleteBreakpointLocAsync(loc);
|
||||
}
|
||||
if (breakpoint instanceof TraceObjectBreakpointSpec spec) {
|
||||
if (breakpoint instanceof TraceBreakpointSpec spec) {
|
||||
return deleteBreakpointSpecAsync(spec);
|
||||
}
|
||||
Msg.error(this, "Unrecognized TraceBreakpoint: " + breakpoint);
|
||||
return AsyncUtils.nil();
|
||||
}
|
||||
|
||||
protected CompletableFuture<Void> toggleBreakpointSpecAsync(TraceObjectBreakpointSpec spec,
|
||||
protected CompletableFuture<Void> toggleBreakpointSpecAsync(TraceBreakpointSpec spec,
|
||||
boolean enabled) {
|
||||
KeyPath path = spec.getObject().getCanonicalPath();
|
||||
MatchedMethod toggleBreak =
|
||||
@@ -1667,7 +1647,7 @@ public class TraceRmiTarget extends AbstractTarget {
|
||||
.thenApply(__ -> null);
|
||||
}
|
||||
|
||||
protected CompletableFuture<Void> toggleBreakpointLocAsync(TraceObjectBreakpointLocation loc,
|
||||
protected CompletableFuture<Void> toggleBreakpointLocAsync(TraceBreakpointLocation loc,
|
||||
boolean enabled) {
|
||||
KeyPath path = loc.getObject().getCanonicalPath();
|
||||
MatchedMethod toggleBreak =
|
||||
@@ -1690,12 +1670,12 @@ public class TraceRmiTarget extends AbstractTarget {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> toggleBreakpointAsync(TraceBreakpoint breakpoint,
|
||||
public CompletableFuture<Void> toggleBreakpointAsync(TraceBreakpointCommon breakpoint,
|
||||
boolean enabled) {
|
||||
if (breakpoint instanceof TraceObjectBreakpointLocation loc) {
|
||||
if (breakpoint instanceof TraceBreakpointLocation loc) {
|
||||
return toggleBreakpointLocAsync(loc, enabled);
|
||||
}
|
||||
if (breakpoint instanceof TraceObjectBreakpointSpec spec) {
|
||||
if (breakpoint instanceof TraceBreakpointSpec spec) {
|
||||
return toggleBreakpointSpecAsync(spec, enabled);
|
||||
}
|
||||
Msg.error(this, "Unrecognized TraceBreakpoint: " + breakpoint);
|
||||
|
||||
+2
-2
@@ -37,8 +37,8 @@ import ghidra.debug.api.target.ActionName;
|
||||
import ghidra.debug.api.tracermi.RemoteMethod;
|
||||
import ghidra.debug.api.tracermi.RemoteParameter;
|
||||
import ghidra.framework.options.PropertyBoolean;
|
||||
import ghidra.trace.model.target.iface.TraceObjectMethod.Param;
|
||||
import ghidra.trace.model.target.iface.TraceObjectMethod.ParameterDescription;
|
||||
import ghidra.trace.model.target.iface.TraceMethod.Param;
|
||||
import ghidra.trace.model.target.iface.TraceMethod.ParameterDescription;
|
||||
import ghidra.trace.model.target.schema.*;
|
||||
import ghidra.trace.model.target.schema.PrimitiveTraceObjectSchema.MinimalSchemaContext;
|
||||
import ghidra.trace.model.target.schema.TraceObjectSchema.SchemaName;
|
||||
|
||||
@@ -343,16 +343,16 @@ public class PopulateDemoTrace extends GhidraScript {
|
||||
*/
|
||||
mainLabel = trace.getSymbolManager()
|
||||
.labels()
|
||||
.create(snap, null, addr(0x00400000), "main", global, SourceType.USER_DEFINED);
|
||||
.create(snap, addr(0x00400000), "main", global, SourceType.USER_DEFINED);
|
||||
cloneLabel = trace.getSymbolManager()
|
||||
.labels()
|
||||
.create(snap, null, addr(0x00400060), "clone", global, SourceType.USER_DEFINED);
|
||||
.create(snap, addr(0x00400060), "clone", global, SourceType.USER_DEFINED);
|
||||
childLabel = trace.getSymbolManager()
|
||||
.labels()
|
||||
.create(snap, null, addr(0x00400034), "child", global, SourceType.USER_DEFINED);
|
||||
.create(snap, addr(0x00400034), "child", global, SourceType.USER_DEFINED);
|
||||
exitLabel = trace.getSymbolManager()
|
||||
.labels()
|
||||
.create(snap, null, addr(0x00400061), "exit", global, SourceType.USER_DEFINED);
|
||||
.create(snap, addr(0x00400061), "exit", global, SourceType.USER_DEFINED);
|
||||
|
||||
/**
|
||||
* Note the use of getProgramView as a means of using components intended for Program
|
||||
|
||||
+4
-4
@@ -29,8 +29,8 @@ import ghidra.debug.api.modules.ModuleMapProposal;
|
||||
import ghidra.debug.api.modules.ModuleMapProposal.ModuleMapEntry;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.trace.model.Trace;
|
||||
import ghidra.trace.model.memory.TraceObjectMemoryRegion;
|
||||
import ghidra.trace.model.modules.TraceObjectModule;
|
||||
import ghidra.trace.model.memory.TraceMemoryRegion;
|
||||
import ghidra.trace.model.modules.TraceModule;
|
||||
import ghidra.trace.model.target.TraceObjectValue;
|
||||
import ghidra.trace.util.TraceEvent;
|
||||
import ghidra.trace.util.TraceEvents;
|
||||
@@ -76,8 +76,8 @@ public class ByModuleAutoMapSpec implements AutoMapSpec {
|
||||
|
||||
@Override
|
||||
public boolean objectHasType(TraceObjectValue value) {
|
||||
return value.getParent().queryInterface(TraceObjectModule.class) != null ||
|
||||
value.getParent().queryInterface(TraceObjectMemoryRegion.class) != null;
|
||||
return value.getParent().queryInterface(TraceModule.class) != null ||
|
||||
value.getParent().queryInterface(TraceMemoryRegion.class) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+2
-2
@@ -29,7 +29,7 @@ import ghidra.debug.api.modules.RegionMapProposal;
|
||||
import ghidra.debug.api.modules.RegionMapProposal.RegionMapEntry;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.trace.model.Trace;
|
||||
import ghidra.trace.model.memory.TraceObjectMemoryRegion;
|
||||
import ghidra.trace.model.memory.TraceMemoryRegion;
|
||||
import ghidra.trace.model.target.TraceObjectValue;
|
||||
import ghidra.trace.util.TraceEvent;
|
||||
import ghidra.trace.util.TraceEvents;
|
||||
@@ -61,7 +61,7 @@ public class ByRegionAutoMapSpec implements AutoMapSpec {
|
||||
|
||||
@Override
|
||||
public boolean objectHasType(TraceObjectValue value) {
|
||||
return value.getParent().queryInterface(TraceObjectMemoryRegion.class) != null;
|
||||
return value.getParent().queryInterface(TraceMemoryRegion.class) != null;
|
||||
}
|
||||
|
||||
static String getInfoForRegions(Trace trace, long snap) {
|
||||
|
||||
+2
-2
@@ -28,8 +28,8 @@ import ghidra.debug.api.modules.MapProposal;
|
||||
import ghidra.debug.api.modules.SectionMapProposal;
|
||||
import ghidra.debug.api.modules.SectionMapProposal.SectionMapEntry;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.trace.database.module.TraceObjectSection;
|
||||
import ghidra.trace.model.Trace;
|
||||
import ghidra.trace.model.modules.TraceSection;
|
||||
import ghidra.trace.model.target.TraceObjectValue;
|
||||
import ghidra.trace.util.TraceEvent;
|
||||
import ghidra.trace.util.TraceEvents;
|
||||
@@ -61,7 +61,7 @@ public class BySectionAutoMapSpec implements AutoMapSpec {
|
||||
|
||||
@Override
|
||||
public boolean objectHasType(TraceObjectValue value) {
|
||||
return value.getParent().queryInterface(TraceObjectSection.class) != null;
|
||||
return value.getParent().queryInterface(TraceSection.class) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+46
-3
@@ -40,11 +40,13 @@ import ghidra.framework.options.SaveState;
|
||||
import ghidra.framework.plugintool.*;
|
||||
import ghidra.framework.plugintool.annotation.AutoConfigStateField;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressSpace;
|
||||
import ghidra.program.util.ProgramLocation;
|
||||
import ghidra.trace.model.*;
|
||||
import ghidra.trace.model.stack.TraceStack;
|
||||
import ghidra.trace.model.stack.TraceStackFrame;
|
||||
import ghidra.trace.model.target.TraceObjectValue;
|
||||
import ghidra.trace.model.thread.TraceThread;
|
||||
import ghidra.trace.util.TraceAddressSpace;
|
||||
import ghidra.trace.util.TraceEvents;
|
||||
import ghidra.util.Msg;
|
||||
|
||||
@@ -60,10 +62,12 @@ public class DebuggerTrackLocationTrait {
|
||||
|
||||
public ForTrackingListener() {
|
||||
listenFor(TraceEvents.BYTES_CHANGED, this::registersChanged);
|
||||
listenFor(TraceEvents.STACK_CHANGED, this::stackChanged);
|
||||
//listenFor(TraceEvents.STACK_CHANGED, this::stackChanged);
|
||||
listenFor(TraceEvents.VALUE_CREATED, this::valueCreated);
|
||||
listenFor(TraceEvents.VALUE_LIFESPAN_CHANGED, this::valueLifespanChanged);
|
||||
}
|
||||
|
||||
private void registersChanged(TraceAddressSpace space, TraceAddressSnapRange range,
|
||||
private void registersChanged(AddressSpace space, TraceAddressSnapRange range,
|
||||
byte[] oldValue, byte[] newValue) {
|
||||
if (current.getView() == null || spec == null) {
|
||||
// Should only happen during transitional times, if at all.
|
||||
@@ -85,6 +89,42 @@ public class DebuggerTrackLocationTrait {
|
||||
}
|
||||
doTrack(TrackCause.DB_CHANGE);
|
||||
}
|
||||
|
||||
private void valueCreated(TraceObjectValue value) {
|
||||
if (!value.getLifespan().contains(current.getSnap())) {
|
||||
return;
|
||||
}
|
||||
if (!value.getEntryKey().equals(TraceStackFrame.KEY_PC)) {
|
||||
return;
|
||||
}
|
||||
TraceStackFrame frame = value.getParent().queryInterface(TraceStackFrame.class);
|
||||
if (frame == null) {
|
||||
return;
|
||||
}
|
||||
if (!tracker.affectedByStackChange(frame.getStack(), current)) {
|
||||
return;
|
||||
}
|
||||
doTrack(TrackCause.DB_CHANGE);
|
||||
}
|
||||
|
||||
private void valueLifespanChanged(TraceObjectValue value, Lifespan oldLife,
|
||||
Lifespan newLife) {
|
||||
long snap = current.getSnap();
|
||||
if (oldLife.contains(snap) == newLife.contains(snap)) {
|
||||
return;
|
||||
}
|
||||
if (!value.getEntryKey().equals(TraceStackFrame.KEY_PC)) {
|
||||
return;
|
||||
}
|
||||
TraceStackFrame frame = value.getParent().queryInterface(TraceStackFrame.class);
|
||||
if (frame == null) {
|
||||
return;
|
||||
}
|
||||
if (!tracker.affectedByStackChange(frame.getStack(), current)) {
|
||||
return;
|
||||
}
|
||||
doTrack(TrackCause.DB_CHANGE);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: This may already be deprecated....
|
||||
@@ -297,6 +337,9 @@ public class DebuggerTrackLocationTrait {
|
||||
trackedLocation = newLocation;
|
||||
locationTracked();
|
||||
}
|
||||
catch (TraceClosedException ex) {
|
||||
// Silently continue
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
Msg.error(this, "Error while computing location: " + ex);
|
||||
}
|
||||
|
||||
+5
-5
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -22,10 +22,10 @@ import ghidra.debug.api.action.*;
|
||||
import ghidra.debug.api.tracemgr.DebuggerCoordinates;
|
||||
import ghidra.framework.plugintool.ServiceProvider;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressSpace;
|
||||
import ghidra.program.util.ProgramLocation;
|
||||
import ghidra.trace.model.TraceAddressSnapRange;
|
||||
import ghidra.trace.model.stack.TraceStack;
|
||||
import ghidra.trace.util.TraceAddressSpace;
|
||||
|
||||
public enum NoneLocationTrackingSpec implements LocationTrackingSpec, LocationTracker {
|
||||
INSTANCE;
|
||||
@@ -77,8 +77,8 @@ public enum NoneLocationTrackingSpec implements LocationTrackingSpec, LocationTr
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean affectedByBytesChange(TraceAddressSpace space,
|
||||
TraceAddressSnapRange range, DebuggerCoordinates coordinates) {
|
||||
public boolean affectedByBytesChange(AddressSpace space, TraceAddressSnapRange range,
|
||||
DebuggerCoordinates coordinates) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -22,13 +22,13 @@ import ghidra.debug.api.action.*;
|
||||
import ghidra.debug.api.tracemgr.DebuggerCoordinates;
|
||||
import ghidra.framework.plugintool.ServiceProvider;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressSpace;
|
||||
import ghidra.program.util.ProgramLocation;
|
||||
import ghidra.trace.model.Trace;
|
||||
import ghidra.trace.model.TraceAddressSnapRange;
|
||||
import ghidra.trace.model.stack.TraceStack;
|
||||
import ghidra.trace.model.stack.TraceStackFrame;
|
||||
import ghidra.trace.model.thread.TraceThread;
|
||||
import ghidra.trace.util.TraceAddressSpace;
|
||||
|
||||
public enum PCByStackLocationTrackingSpec implements LocationTrackingSpec, LocationTracker {
|
||||
INSTANCE;
|
||||
@@ -124,7 +124,7 @@ public enum PCByStackLocationTrackingSpec implements LocationTrackingSpec, Locat
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean affectedByBytesChange(TraceAddressSpace space, TraceAddressSnapRange range,
|
||||
public boolean affectedByBytesChange(AddressSpace space, TraceAddressSnapRange range,
|
||||
DebuggerCoordinates coordinates) {
|
||||
return false;
|
||||
}
|
||||
|
||||
+4
-4
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -22,10 +22,10 @@ import ghidra.debug.api.action.*;
|
||||
import ghidra.debug.api.tracemgr.DebuggerCoordinates;
|
||||
import ghidra.framework.plugintool.ServiceProvider;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressSpace;
|
||||
import ghidra.program.util.ProgramLocation;
|
||||
import ghidra.trace.model.TraceAddressSnapRange;
|
||||
import ghidra.trace.model.stack.TraceStack;
|
||||
import ghidra.trace.util.TraceAddressSpace;
|
||||
|
||||
public enum PCLocationTrackingSpec implements LocationTrackingSpec, LocationTracker {
|
||||
INSTANCE;
|
||||
@@ -91,7 +91,7 @@ public enum PCLocationTrackingSpec implements LocationTrackingSpec, LocationTrac
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean affectedByBytesChange(TraceAddressSpace space, TraceAddressSnapRange range,
|
||||
public boolean affectedByBytesChange(AddressSpace space, TraceAddressSnapRange range,
|
||||
DebuggerCoordinates coordinates) {
|
||||
return BY_REG.affectedByBytesChange(space, range, coordinates);
|
||||
}
|
||||
|
||||
+4
-6
@@ -29,7 +29,6 @@ import ghidra.trace.model.memory.TraceMemorySpace;
|
||||
import ghidra.trace.model.memory.TraceMemoryState;
|
||||
import ghidra.trace.model.stack.TraceStack;
|
||||
import ghidra.trace.model.thread.TraceThread;
|
||||
import ghidra.trace.util.TraceAddressSpace;
|
||||
|
||||
public interface RegisterLocationTrackingSpec extends LocationTrackingSpec, LocationTracker {
|
||||
Register computeRegister(DebuggerCoordinates coordinates);
|
||||
@@ -102,18 +101,17 @@ public interface RegisterLocationTrackingSpec extends LocationTrackingSpec, Loca
|
||||
}
|
||||
|
||||
@Override
|
||||
default boolean affectedByBytesChange(TraceAddressSpace space,
|
||||
TraceAddressSnapRange range, DebuggerCoordinates coordinates) {
|
||||
default boolean affectedByBytesChange(AddressSpace space, TraceAddressSnapRange range,
|
||||
DebuggerCoordinates coordinates) {
|
||||
if (!LocationTrackingSpec.changeIsCurrent(space, range, coordinates)) {
|
||||
return false;
|
||||
}
|
||||
Register register = computeRegister(coordinates);
|
||||
AddressSpace as = space.getAddressSpace();
|
||||
if (register == null || register.getAddressSpace() != as) {
|
||||
if (register == null) {
|
||||
return false;
|
||||
}
|
||||
AddressRange regRng = coordinates.getPlatform()
|
||||
.getConventionalRegisterRange(as.isRegisterSpace() ? as : null, register);
|
||||
.getConventionalRegisterRange(space.isRegisterSpace() ? space : null, register);
|
||||
return range.getRange().intersects(regRng);
|
||||
}
|
||||
|
||||
|
||||
+4
-6
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -28,13 +28,11 @@ import ghidra.framework.plugintool.ServiceProvider;
|
||||
import ghidra.pcode.exec.*;
|
||||
import ghidra.pcode.exec.DebuggerPcodeUtils.WatchValue;
|
||||
import ghidra.pcode.exec.SleighUtils.AddressOf;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressSetView;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.util.ProgramLocation;
|
||||
import ghidra.trace.model.TraceAddressSnapRange;
|
||||
import ghidra.trace.model.guest.TracePlatform;
|
||||
import ghidra.trace.model.stack.TraceStack;
|
||||
import ghidra.trace.util.TraceAddressSpace;
|
||||
|
||||
/**
|
||||
* A tracking specification for the address of a given Sleigh expression
|
||||
@@ -151,7 +149,7 @@ public class WatchLocationTrackingSpec implements LocationTrackingSpec {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean affectedByBytesChange(TraceAddressSpace space, TraceAddressSnapRange range,
|
||||
public boolean affectedByBytesChange(AddressSpace space, TraceAddressSnapRange range,
|
||||
DebuggerCoordinates coordinates) {
|
||||
return LocationTrackingSpec.changeIsCurrent(space, range, coordinates) &&
|
||||
(reads == null || reads.intersects(range.getX1(), range.getX2()));
|
||||
|
||||
+5
-4
@@ -24,13 +24,14 @@ import ghidra.debug.api.breakpoint.LogicalBreakpoint.State;
|
||||
import ghidra.pcode.exec.SleighUtils;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.util.ProgramLocation;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpoint;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointLocation;
|
||||
|
||||
public class BreakpointLocationRow {
|
||||
private final DebuggerBreakpointsProvider provider;
|
||||
private final TraceBreakpoint loc;
|
||||
private final TraceBreakpointLocation loc;
|
||||
|
||||
public BreakpointLocationRow(DebuggerBreakpointsProvider provider, TraceBreakpoint loc) {
|
||||
public BreakpointLocationRow(DebuggerBreakpointsProvider provider,
|
||||
TraceBreakpointLocation loc) {
|
||||
this.provider = provider;
|
||||
this.loc = loc;
|
||||
}
|
||||
@@ -116,7 +117,7 @@ public class BreakpointLocationRow {
|
||||
return !SleighUtils.UNCONDITIONAL_BREAK.equals(loc.getEmuSleigh(getSnap()));
|
||||
}
|
||||
|
||||
public TraceBreakpoint getTraceBreakpoint() {
|
||||
public TraceBreakpointLocation getTraceBreakpoint() {
|
||||
return loc;
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -19,7 +19,7 @@ import java.util.Collection;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import docking.DefaultActionContext;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpoint;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointLocation;
|
||||
|
||||
public class DebuggerBreakpointLocationsActionContext extends DefaultActionContext {
|
||||
private final Collection<BreakpointLocationRow> selection;
|
||||
@@ -32,7 +32,7 @@ public class DebuggerBreakpointLocationsActionContext extends DefaultActionConte
|
||||
return selection;
|
||||
}
|
||||
|
||||
public Collection<TraceBreakpoint> getLocations() {
|
||||
public Collection<TraceBreakpointLocation> getLocations() {
|
||||
return selection.stream().map(row -> row.getTraceBreakpoint()).collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
|
||||
+33
-31
@@ -57,8 +57,8 @@ import ghidra.program.model.address.AddressRange;
|
||||
import ghidra.program.util.MarkerLocation;
|
||||
import ghidra.program.util.ProgramLocation;
|
||||
import ghidra.trace.model.*;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpoint;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointLocation;
|
||||
import ghidra.trace.util.TraceEvents;
|
||||
import ghidra.util.*;
|
||||
import ghidra.util.database.ObjectKey;
|
||||
@@ -230,11 +230,13 @@ public class DebuggerBreakpointsProvider extends ComponentProviderAdapter
|
||||
|
||||
protected static class BreakpointLocationTableModel
|
||||
extends RowWrappedEnumeratedColumnTableModel< //
|
||||
BreakpointLocationTableColumns, ObjectKey, BreakpointLocationRow, TraceBreakpoint> {
|
||||
BreakpointLocationTableColumns, ObjectKey, BreakpointLocationRow, //
|
||||
TraceBreakpointLocation> {
|
||||
|
||||
public BreakpointLocationTableModel(DebuggerBreakpointsProvider provider) {
|
||||
super(provider.getTool(), "Locations", BreakpointLocationTableColumns.class,
|
||||
TraceBreakpoint::getObjectKey, loc -> new BreakpointLocationRow(provider, loc),
|
||||
TraceBreakpointLocation::getObjectKey,
|
||||
loc -> new BreakpointLocationRow(provider, loc),
|
||||
BreakpointLocationRow::getTraceBreakpoint);
|
||||
}
|
||||
|
||||
@@ -376,7 +378,7 @@ public class DebuggerBreakpointsProvider extends ComponentProviderAdapter
|
||||
if (context instanceof DebuggerBreakpointLocationsActionContext) {
|
||||
DebuggerBreakpointLocationsActionContext ctx =
|
||||
(DebuggerBreakpointLocationsActionContext) context;
|
||||
Collection<TraceBreakpoint> sel = ctx.getLocations();
|
||||
Collection<TraceBreakpointLocation> sel = ctx.getLocations();
|
||||
breakpointService.enableLocs(sel).exceptionally(ex -> {
|
||||
breakpointError("Enable Breakpoints", "Could not enable breakpoints", ex);
|
||||
return null;
|
||||
@@ -455,7 +457,7 @@ public class DebuggerBreakpointsProvider extends ComponentProviderAdapter
|
||||
if (context instanceof DebuggerBreakpointLocationsActionContext) {
|
||||
DebuggerBreakpointLocationsActionContext ctx =
|
||||
(DebuggerBreakpointLocationsActionContext) context;
|
||||
Collection<TraceBreakpoint> sel = ctx.getLocations();
|
||||
Collection<TraceBreakpointLocation> sel = ctx.getLocations();
|
||||
breakpointService.disableLocs(sel).exceptionally(ex -> {
|
||||
breakpointError("Disable Breakpoints", "Could not disable breakpoints", ex);
|
||||
return null;
|
||||
@@ -526,7 +528,7 @@ public class DebuggerBreakpointsProvider extends ComponentProviderAdapter
|
||||
if (context instanceof DebuggerBreakpointLocationsActionContext) {
|
||||
DebuggerBreakpointLocationsActionContext ctx =
|
||||
(DebuggerBreakpointLocationsActionContext) context;
|
||||
Collection<TraceBreakpoint> sel = ctx.getLocations();
|
||||
Collection<TraceBreakpointLocation> sel = ctx.getLocations();
|
||||
breakpointService.deleteLocs(sel).exceptionally(ex -> {
|
||||
breakpointError("Clear Breakpoints", "Could not clear breakpoints", ex);
|
||||
return null;
|
||||
@@ -700,26 +702,26 @@ public class DebuggerBreakpointsProvider extends ComponentProviderAdapter
|
||||
reloadBreakpointLocations(trace);
|
||||
}
|
||||
|
||||
private boolean isVisible(TraceBreakpoint location) {
|
||||
private boolean isVisible(TraceBreakpointLocation location) {
|
||||
long snap = traceManager.getCurrentFor(trace).getSnap();
|
||||
return location.isValid(snap);
|
||||
}
|
||||
|
||||
private void locationAdded(TraceBreakpoint location) {
|
||||
private void locationAdded(TraceBreakpointLocation location) {
|
||||
if (!isVisible(location)) {
|
||||
return;
|
||||
}
|
||||
breakpointLocationAdded(location);
|
||||
}
|
||||
|
||||
private void locationChanged(TraceBreakpoint location) {
|
||||
private void locationChanged(TraceBreakpointLocation location) {
|
||||
if (!isVisible(location)) {
|
||||
return;
|
||||
}
|
||||
breakpointLocationUpdated(location);
|
||||
}
|
||||
|
||||
private void locationLifespanChanged(TraceBreakpoint location, Lifespan oldSpan,
|
||||
private void locationLifespanChanged(TraceBreakpointLocation location, Lifespan oldSpan,
|
||||
Lifespan newSpan) {
|
||||
long snap = traceManager.getCurrentFor(trace).getSnap();
|
||||
boolean isLiveOld = oldSpan.contains(snap);
|
||||
@@ -735,7 +737,7 @@ public class DebuggerBreakpointsProvider extends ComponentProviderAdapter
|
||||
}
|
||||
}
|
||||
|
||||
private void locationDeleted(TraceBreakpoint location) {
|
||||
private void locationDeleted(TraceBreakpointLocation location) {
|
||||
if (!isVisible(location)) {
|
||||
return;
|
||||
}
|
||||
@@ -955,15 +957,15 @@ public class DebuggerBreakpointsProvider extends ComponentProviderAdapter
|
||||
return;
|
||||
}
|
||||
Lifespan span = Lifespan.at(currentFor.getSnap());
|
||||
Collection<TraceBreakpoint> visible = new ArrayList<>();
|
||||
Collection<TraceBreakpointLocation> visible = new ArrayList<>();
|
||||
for (AddressRange range : trace.getBaseAddressFactory().getAddressSet()) {
|
||||
Collection<? extends TraceBreakpoint> breaks =
|
||||
Collection<? extends TraceBreakpointLocation> breaks =
|
||||
trace.getBreakpointManager().getBreakpointsIntersecting(span, range);
|
||||
if (mode.useEmulatedBreakpoints()) {
|
||||
visible.addAll(breaks);
|
||||
}
|
||||
else {
|
||||
for (TraceBreakpoint l : breaks) {
|
||||
for (TraceBreakpointLocation l : breaks) {
|
||||
if (target.isBreakpointValid(l)) {
|
||||
visible.add(l);
|
||||
}
|
||||
@@ -982,19 +984,19 @@ public class DebuggerBreakpointsProvider extends ComponentProviderAdapter
|
||||
loadBreakpointLocations(trace);
|
||||
}
|
||||
|
||||
private void breakpointLocationAdded(TraceBreakpoint location) {
|
||||
private void breakpointLocationAdded(TraceBreakpointLocation location) {
|
||||
locationTableModel.addItem(location);
|
||||
}
|
||||
|
||||
private void breakpointLocationUpdated(TraceBreakpoint location) {
|
||||
private void breakpointLocationUpdated(TraceBreakpointLocation location) {
|
||||
locationTableModel.updateItem(location);
|
||||
}
|
||||
|
||||
private void breakpointLocationsUpdated(Collection<TraceBreakpoint> locations) {
|
||||
private void breakpointLocationsUpdated(Collection<TraceBreakpointLocation> locations) {
|
||||
locationTableModel.updateAllItems(locations);
|
||||
}
|
||||
|
||||
private void breakpointLocationRemoved(TraceBreakpoint location) {
|
||||
private void breakpointLocationRemoved(TraceBreakpointLocation location) {
|
||||
locationTableModel.deleteItem(location);
|
||||
}
|
||||
|
||||
@@ -1304,12 +1306,12 @@ public class DebuggerBreakpointsProvider extends ComponentProviderAdapter
|
||||
}
|
||||
}
|
||||
else if (ctx instanceof DebuggerBreakpointLocationsActionContext locCtx) {
|
||||
Collection<TraceBreakpoint> locations = locCtx.getLocations();
|
||||
Collection<TraceBreakpointLocation> locations = locCtx.getLocations();
|
||||
if (locations.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
for (TraceBreakpoint tb : locations) {
|
||||
traces.add(tb.getTrace());
|
||||
for (TraceBreakpointLocation loc : locations) {
|
||||
traces.add(loc.getTrace());
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -1338,9 +1340,9 @@ public class DebuggerBreakpointsProvider extends ComponentProviderAdapter
|
||||
return true;
|
||||
}
|
||||
else if (ctx instanceof DebuggerBreakpointLocationsActionContext locCtx) {
|
||||
for (TraceBreakpoint tb : locCtx.getLocations()) {
|
||||
long snap = traceManager.getCurrentFor(tb.getTrace()).getSnap();
|
||||
if (!EXECUTE_KINDS.containsAll(tb.getKinds(snap))) {
|
||||
for (TraceBreakpointLocation loc : locCtx.getLocations()) {
|
||||
long snap = traceManager.getCurrentFor(loc.getTrace()).getSnap();
|
||||
if (!EXECUTE_KINDS.containsAll(loc.getKinds(snap))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1371,9 +1373,9 @@ public class DebuggerBreakpointsProvider extends ComponentProviderAdapter
|
||||
return sleigh;
|
||||
}
|
||||
else if (ctx instanceof DebuggerBreakpointLocationsActionContext locCtx) {
|
||||
for (TraceBreakpoint tb : locCtx.getLocations()) {
|
||||
long snap = traceManager.getCurrentFor(tb.getTrace()).getSnap();
|
||||
String s = tb.getEmuSleigh(snap);
|
||||
for (TraceBreakpointLocation loc : locCtx.getLocations()) {
|
||||
long snap = traceManager.getCurrentFor(loc.getTrace()).getSnap();
|
||||
String s = loc.getEmuSleigh(snap);
|
||||
if (sleigh != null && !sleigh.equals(s)) {
|
||||
return null;
|
||||
}
|
||||
@@ -1397,9 +1399,9 @@ public class DebuggerBreakpointsProvider extends ComponentProviderAdapter
|
||||
}
|
||||
}
|
||||
else if (ctx instanceof DebuggerBreakpointLocationsActionContext locCtx) {
|
||||
for (TraceBreakpoint tb : locCtx.getLocations()) {
|
||||
long snap = traceManager.getCurrentFor(tb.getTrace()).getSnap();
|
||||
tb.setEmuSleigh(snap, sleigh);
|
||||
for (TraceBreakpointLocation loc : locCtx.getLocations()) {
|
||||
long snap = traceManager.getCurrentFor(loc.getTrace()).getSnap();
|
||||
loc.setEmuSleigh(snap, sleigh);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -1466,7 +1468,7 @@ public class DebuggerBreakpointsProvider extends ComponentProviderAdapter
|
||||
breakpointTableModel, breakpointFilterPanel);
|
||||
}
|
||||
|
||||
public void setSelectedLocations(Set<TraceBreakpoint> sel) {
|
||||
public void setSelectedLocations(Set<TraceBreakpointLocation> sel) {
|
||||
DebuggerResources.setSelectedRows(sel, locationTableModel::getRow, locationTable,
|
||||
locationTableModel, locationFilterPanel);
|
||||
}
|
||||
|
||||
+2
-2
@@ -28,7 +28,7 @@ import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.listing.*;
|
||||
import ghidra.program.model.symbol.*;
|
||||
import ghidra.trace.model.Lifespan;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpoint;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointLocation;
|
||||
import ghidra.trace.model.memory.TraceMemoryManager;
|
||||
import ghidra.trace.model.memory.TraceMemoryState;
|
||||
import ghidra.trace.model.program.TraceProgramView;
|
||||
@@ -220,7 +220,7 @@ public class DebuggerCopyPlan {
|
||||
public void copy(TraceProgramView from, AddressRange fromRange, Program into,
|
||||
Address intoAddress, TaskMonitor monitor) throws Exception {
|
||||
long snap = from.getSnap();
|
||||
for (TraceBreakpoint bpt : from.getTrace()
|
||||
for (TraceBreakpointLocation bpt : from.getTrace()
|
||||
.getBreakpointManager()
|
||||
.getBreakpointsIntersecting(Lifespan.at(from.getSnap()), fromRange)) {
|
||||
monitor.checkCancelled();
|
||||
|
||||
+3
-3
@@ -32,7 +32,7 @@ import ghidra.program.model.address.*;
|
||||
import ghidra.trace.model.Lifespan;
|
||||
import ghidra.trace.model.Trace;
|
||||
import ghidra.trace.model.memory.TraceMemoryFlag;
|
||||
import ghidra.trace.model.memory.TraceObjectMemoryRegion;
|
||||
import ghidra.trace.model.memory.TraceMemoryRegion;
|
||||
import ghidra.trace.model.target.path.KeyPath;
|
||||
import ghidra.trace.model.target.schema.TraceObjectSchema;
|
||||
import ghidra.util.layout.PairLayout;
|
||||
@@ -161,8 +161,8 @@ public class DebuggerAddRegionDialog extends ReusableDialogComponentProvider {
|
||||
if (rootSchema == null) {
|
||||
return "";
|
||||
}
|
||||
KeyPath suitable = rootSchema.searchForSuitableContainer(TraceObjectMemoryRegion.class,
|
||||
current.getPath());
|
||||
KeyPath suitable =
|
||||
rootSchema.searchForSuitableContainer(TraceMemoryRegion.class, current.getPath());
|
||||
if (suitable == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
+3
-5
@@ -55,8 +55,7 @@ import ghidra.framework.options.SaveState;
|
||||
import ghidra.framework.plugintool.*;
|
||||
import ghidra.framework.plugintool.annotation.AutoConfigStateField;
|
||||
import ghidra.framework.plugintool.annotation.AutoServiceConsumed;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressSetView;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.model.mem.Memory;
|
||||
import ghidra.program.model.mem.MemoryBlock;
|
||||
@@ -65,7 +64,6 @@ import ghidra.program.util.ProgramSelection;
|
||||
import ghidra.trace.model.Trace;
|
||||
import ghidra.trace.model.TraceDomainObjectListener;
|
||||
import ghidra.trace.model.program.TraceProgramView;
|
||||
import ghidra.trace.util.TraceAddressSpace;
|
||||
import ghidra.trace.util.TraceEvents;
|
||||
import ghidra.util.Swing;
|
||||
|
||||
@@ -99,8 +97,8 @@ public class DebuggerMemoryBytesProvider extends ProgramByteViewerComponentProvi
|
||||
listenFor(TraceEvents.BYTES_CHANGED, this::bytesChanged);
|
||||
}
|
||||
|
||||
private void bytesChanged(TraceAddressSpace space) {
|
||||
if (space.getAddressSpace().isMemorySpace()) {
|
||||
private void bytesChanged(AddressSpace space) {
|
||||
if (space.isMemorySpace()) {
|
||||
currCache.invalidate();
|
||||
prevCache.invalidate();
|
||||
}
|
||||
|
||||
+14
-13
@@ -29,13 +29,14 @@ import ghidra.framework.plugintool.ServiceProvider;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressRange;
|
||||
import ghidra.trace.model.Trace;
|
||||
import ghidra.trace.model.memory.*;
|
||||
import ghidra.trace.model.memory.TraceMemoryRegion;
|
||||
import ghidra.trace.model.memory.TraceMemory;
|
||||
import ghidra.trace.model.target.TraceObject;
|
||||
import ghidra.trace.model.target.path.KeyPath;
|
||||
import ghidra.trace.model.target.schema.TraceObjectSchema;
|
||||
import ghidra.trace.model.thread.TraceObjectProcess;
|
||||
import ghidra.trace.model.thread.TraceProcess;
|
||||
|
||||
public class DebuggerRegionsPanel extends AbstractObjectsTableBasedPanel<TraceObjectMemoryRegion> {
|
||||
public class DebuggerRegionsPanel extends AbstractObjectsTableBasedPanel<TraceMemoryRegion> {
|
||||
|
||||
private static class RegionKeyColumn extends TraceValueKeyColumn {
|
||||
@Override
|
||||
@@ -66,7 +67,7 @@ public class DebuggerRegionsPanel extends AbstractObjectsTableBasedPanel<TraceOb
|
||||
|
||||
private static class RegionStartColumn extends AbstractTraceValueObjectAddressColumn {
|
||||
public RegionStartColumn() {
|
||||
super(TraceObjectMemoryRegion.KEY_RANGE);
|
||||
super(TraceMemoryRegion.KEY_RANGE);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -82,7 +83,7 @@ public class DebuggerRegionsPanel extends AbstractObjectsTableBasedPanel<TraceOb
|
||||
|
||||
private static class RegionEndColumn extends AbstractTraceValueObjectAddressColumn {
|
||||
public RegionEndColumn() {
|
||||
super(TraceObjectMemoryRegion.KEY_RANGE);
|
||||
super(TraceMemoryRegion.KEY_RANGE);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -98,7 +99,7 @@ public class DebuggerRegionsPanel extends AbstractObjectsTableBasedPanel<TraceOb
|
||||
|
||||
private static class RegionLengthColumn extends AbstractTraceValueObjectLengthColumn {
|
||||
public RegionLengthColumn() {
|
||||
super(TraceObjectMemoryRegion.KEY_RANGE);
|
||||
super(TraceMemoryRegion.KEY_RANGE);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -120,7 +121,7 @@ public class DebuggerRegionsPanel extends AbstractObjectsTableBasedPanel<TraceOb
|
||||
|
||||
public static class RegionReadColumn extends RegionFlagColumn {
|
||||
public RegionReadColumn() {
|
||||
super(TraceObjectMemoryRegion.KEY_READABLE);
|
||||
super(TraceMemoryRegion.KEY_READABLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -131,7 +132,7 @@ public class DebuggerRegionsPanel extends AbstractObjectsTableBasedPanel<TraceOb
|
||||
|
||||
public static class RegionWriteColumn extends RegionFlagColumn {
|
||||
public RegionWriteColumn() {
|
||||
super(TraceObjectMemoryRegion.KEY_WRITABLE);
|
||||
super(TraceMemoryRegion.KEY_WRITABLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -142,7 +143,7 @@ public class DebuggerRegionsPanel extends AbstractObjectsTableBasedPanel<TraceOb
|
||||
|
||||
public static class RegionExecuteColumn extends RegionFlagColumn {
|
||||
public RegionExecuteColumn() {
|
||||
super(TraceObjectMemoryRegion.KEY_EXECUTABLE);
|
||||
super(TraceMemoryRegion.KEY_EXECUTABLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -174,7 +175,7 @@ public class DebuggerRegionsPanel extends AbstractObjectsTableBasedPanel<TraceOb
|
||||
|
||||
protected static ModelQuery successorRegions(TraceObjectSchema rootSchema, KeyPath path) {
|
||||
TraceObjectSchema schema = rootSchema.getSuccessorSchema(path);
|
||||
return new ModelQuery(schema.searchFor(TraceObjectMemoryRegion.class, path, true));
|
||||
return new ModelQuery(schema.searchFor(TraceMemoryRegion.class, path, true));
|
||||
}
|
||||
|
||||
protected Set<TraceMemoryRegion> getSelectedRegions(DebuggerObjectActionContext ctx) {
|
||||
@@ -182,7 +183,7 @@ public class DebuggerRegionsPanel extends AbstractObjectsTableBasedPanel<TraceOb
|
||||
}
|
||||
|
||||
public DebuggerRegionsPanel(DebuggerRegionsProvider provider) {
|
||||
super(provider.plugin, provider, TraceObjectMemoryRegion.class);
|
||||
super(provider.plugin, provider, TraceMemoryRegion.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -194,14 +195,14 @@ public class DebuggerRegionsPanel extends AbstractObjectsTableBasedPanel<TraceOb
|
||||
protected ModelQuery computeQuery(TraceObject object) {
|
||||
TraceObjectSchema rootSchema = object.getRoot().getSchema();
|
||||
KeyPath seedPath = object.getCanonicalPath();
|
||||
KeyPath processPath = rootSchema.searchForAncestor(TraceObjectProcess.class, seedPath);
|
||||
KeyPath processPath = rootSchema.searchForAncestor(TraceProcess.class, seedPath);
|
||||
if (processPath != null) {
|
||||
ModelQuery result = successorRegions(rootSchema, processPath);
|
||||
if (!result.isEmpty()) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
KeyPath memoryPath = rootSchema.searchForSuitable(TraceObjectMemory.class, seedPath);
|
||||
KeyPath memoryPath = rootSchema.searchForSuitable(TraceMemory.class, seedPath);
|
||||
if (memoryPath != null) {
|
||||
ModelQuery result = successorRegions(rootSchema, memoryPath);
|
||||
if (!result.isEmpty()) {
|
||||
|
||||
+22
-22
@@ -23,15 +23,17 @@ import ghidra.debug.api.tracemgr.DebuggerCoordinates;
|
||||
import ghidra.framework.model.DomainObjectChangeRecord;
|
||||
import ghidra.framework.model.DomainObjectEvent;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.trace.database.module.TraceObjectSection;
|
||||
import ghidra.trace.model.*;
|
||||
import ghidra.trace.model.breakpoint.*;
|
||||
import ghidra.trace.model.memory.*;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointLocation;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointManager;
|
||||
import ghidra.trace.model.memory.TraceMemoryManager;
|
||||
import ghidra.trace.model.memory.TraceMemoryRegion;
|
||||
import ghidra.trace.model.modules.*;
|
||||
import ghidra.trace.model.target.TraceObject;
|
||||
import ghidra.trace.model.target.TraceObjectValue;
|
||||
import ghidra.trace.model.target.path.KeyPath;
|
||||
import ghidra.trace.model.thread.*;
|
||||
import ghidra.trace.model.thread.TraceThread;
|
||||
import ghidra.trace.model.thread.TraceThreadManager;
|
||||
import ghidra.trace.model.time.TraceTimeManager;
|
||||
import ghidra.trace.util.TraceEvents;
|
||||
import ghidra.util.Swing;
|
||||
@@ -100,7 +102,7 @@ public class DebuggerMemviewTraceListener extends TraceDomainObjectListener {
|
||||
}
|
||||
|
||||
private void threadChanged(TraceThread thread) {
|
||||
if (!trackThreads || !trackTrace || !(thread instanceof TraceObjectThread objThread)) {
|
||||
if (!trackThreads || !trackTrace) {
|
||||
return;
|
||||
}
|
||||
AddressFactory factory = thread.getTrace().getBaseAddressFactory();
|
||||
@@ -108,7 +110,7 @@ public class DebuggerMemviewTraceListener extends TraceDomainObjectListener {
|
||||
Long threadId = thread.getKey();
|
||||
|
||||
AddressRange rng = rng(defaultSpace, threadId, threadId);
|
||||
TraceObject obj = objThread.getObject();
|
||||
TraceObject obj = thread.getObject();
|
||||
obj.getCanonicalParents(Lifespan.ALL).forEach(p -> {
|
||||
MemoryBox box = new MemoryBox(currentTrace, "Thread " + thread.getName(p.getMinSnap()),
|
||||
MemviewBoxType.THREAD, rng, p.getLifespan());
|
||||
@@ -118,13 +120,12 @@ public class DebuggerMemviewTraceListener extends TraceDomainObjectListener {
|
||||
}
|
||||
|
||||
private void regionChanged(TraceMemoryRegion region) {
|
||||
if (!trackRegions || !trackTrace ||
|
||||
!(region instanceof TraceObjectMemoryRegion objRegion)) {
|
||||
if (!trackRegions || !trackTrace) {
|
||||
return;
|
||||
}
|
||||
|
||||
TraceObject obj = objRegion.getObject();
|
||||
obj.getOrderedValues(Lifespan.ALL, TraceObjectMemoryRegion.KEY_RANGE, true).forEach(v -> {
|
||||
TraceObject obj = region.getObject();
|
||||
obj.getOrderedValues(Lifespan.ALL, TraceMemoryRegion.KEY_RANGE, true).forEach(v -> {
|
||||
if (region.getName(v.getMinSnap()).equals("full memory")) {
|
||||
return;
|
||||
}
|
||||
@@ -136,12 +137,12 @@ public class DebuggerMemviewTraceListener extends TraceDomainObjectListener {
|
||||
}
|
||||
|
||||
private void moduleChanged(TraceModule module) {
|
||||
if (!trackModules || !trackTrace || !(module instanceof TraceObjectModule objModule)) {
|
||||
if (!trackModules || !trackTrace) {
|
||||
return;
|
||||
}
|
||||
|
||||
TraceObject obj = objModule.getObject();
|
||||
obj.getOrderedValues(Lifespan.ALL, TraceObjectModule.KEY_RANGE, true).forEach(v -> {
|
||||
TraceObject obj = module.getObject();
|
||||
obj.getOrderedValues(Lifespan.ALL, TraceModule.KEY_RANGE, true).forEach(v -> {
|
||||
MemoryBox box = new MemoryBox(currentTrace, "Module " + module.getName(v.getMinSnap()),
|
||||
MemviewBoxType.MODULE, v.castValue(), v.getLifespan());
|
||||
updateList.add(box);
|
||||
@@ -150,12 +151,12 @@ public class DebuggerMemviewTraceListener extends TraceDomainObjectListener {
|
||||
}
|
||||
|
||||
private void sectionChanged(TraceSection section) {
|
||||
if (!trackSections || !trackTrace || !(section instanceof TraceObjectSection objSection)) {
|
||||
if (!trackSections || !trackTrace) {
|
||||
return;
|
||||
}
|
||||
|
||||
TraceObject obj = objSection.getObject();
|
||||
obj.getOrderedValues(Lifespan.ALL, TraceObjectSection.KEY_RANGE, true).forEach(v -> {
|
||||
TraceObject obj = section.getObject();
|
||||
obj.getOrderedValues(Lifespan.ALL, TraceSection.KEY_RANGE, true).forEach(v -> {
|
||||
MemoryBox box = new MemoryBox(currentTrace, "Module " + section.getName(v.getMinSnap()),
|
||||
MemviewBoxType.IMAGE, v.castValue(), v.getLifespan());
|
||||
updateList.add(box);
|
||||
@@ -163,14 +164,13 @@ public class DebuggerMemviewTraceListener extends TraceDomainObjectListener {
|
||||
updateLabelDebouncer.contact(null);
|
||||
}
|
||||
|
||||
private void breakpointChanged(TraceBreakpoint bpt) {
|
||||
if (!trackBreakpoints || !trackTrace ||
|
||||
!(bpt instanceof TraceObjectBreakpointLocation objBpt)) {
|
||||
private void breakpointChanged(TraceBreakpointLocation bpt) {
|
||||
if (!trackBreakpoints || !trackTrace) {
|
||||
return;
|
||||
}
|
||||
|
||||
TraceObject obj = objBpt.getObject();
|
||||
obj.getOrderedValues(Lifespan.ALL, TraceObjectBreakpointLocation.KEY_RANGE, true)
|
||||
TraceObject obj = bpt.getObject();
|
||||
obj.getOrderedValues(Lifespan.ALL, TraceBreakpointLocation.KEY_RANGE, true)
|
||||
.forEach(v -> {
|
||||
MemoryBox box =
|
||||
new MemoryBox(currentTrace, "Module " + bpt.getName(v.getMinSnap()),
|
||||
@@ -301,7 +301,7 @@ public class DebuggerMemviewTraceListener extends TraceDomainObjectListener {
|
||||
regionChanged(region);
|
||||
}
|
||||
TraceBreakpointManager breakpointManager = trace.getBreakpointManager();
|
||||
for (TraceBreakpoint bpt : breakpointManager.getAllBreakpoints()) {
|
||||
for (TraceBreakpointLocation bpt : breakpointManager.getAllBreakpointLocations()) {
|
||||
breakpointChanged(bpt);
|
||||
}
|
||||
updateLabelDebouncer.contact(null);
|
||||
|
||||
+2
-2
@@ -130,7 +130,7 @@ public interface ObjectDefaultActionsMixin {
|
||||
default boolean performDefaultAction(TraceObject object) {
|
||||
Set<Class<? extends TraceObjectInterface>> interfaces =
|
||||
object.getSchema().getInterfaces();
|
||||
if (interfaces.contains(TraceObjectActivatable.class)) {
|
||||
if (interfaces.contains(TraceActivatable.class)) {
|
||||
activatePath(object.getCanonicalPath());
|
||||
return true;
|
||||
}
|
||||
@@ -138,7 +138,7 @@ public interface ObjectDefaultActionsMixin {
|
||||
* Should I check aliveAndPresent() here? If I do, behavior changes when target is dead,
|
||||
* which might be unexpected.
|
||||
*/
|
||||
if (interfaces.contains(TraceObjectTogglable.class)) {
|
||||
if (interfaces.contains(TraceTogglable.class)) {
|
||||
toggleObject(object);
|
||||
return true;
|
||||
}
|
||||
|
||||
+11
-11
@@ -26,8 +26,8 @@ import generic.theme.GIcon;
|
||||
import ghidra.app.plugin.core.debug.gui.DebuggerResources;
|
||||
import ghidra.framework.model.*;
|
||||
import ghidra.trace.model.*;
|
||||
import ghidra.trace.model.breakpoint.TraceObjectBreakpointLocation;
|
||||
import ghidra.trace.model.breakpoint.TraceObjectBreakpointSpec;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointLocation;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointSpec;
|
||||
import ghidra.trace.model.target.TraceObject;
|
||||
import ghidra.trace.model.target.TraceObjectValue;
|
||||
import ghidra.trace.model.target.iface.*;
|
||||
@@ -65,10 +65,10 @@ public class ObjectTreeModel implements DisplaysModified {
|
||||
if (!value.getParent()
|
||||
.getSchema()
|
||||
.getInterfaces()
|
||||
.contains(TraceObjectEventScope.class)) {
|
||||
.contains(TraceEventScope.class)) {
|
||||
return false;
|
||||
}
|
||||
if (!TraceObjectEventScope.KEY_EVENT_THREAD.equals(value.getEntryKey())) {
|
||||
if (!TraceEventScope.KEY_EVENT_THREAD.equals(value.getEntryKey())) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -77,12 +77,12 @@ public class ObjectTreeModel implements DisplaysModified {
|
||||
protected boolean isEnabledValue(TraceObjectValue value) {
|
||||
Set<Class<? extends TraceObjectInterface>> interfaces =
|
||||
value.getParent().getSchema().getInterfaces();
|
||||
if (!interfaces.contains(TraceObjectBreakpointSpec.class) &&
|
||||
!interfaces.contains(TraceObjectBreakpointLocation.class) &&
|
||||
!interfaces.contains(TraceObjectTogglable.class)) {
|
||||
if (!interfaces.contains(TraceBreakpointSpec.class) &&
|
||||
!interfaces.contains(TraceBreakpointLocation.class) &&
|
||||
!interfaces.contains(TraceTogglable.class)) {
|
||||
return false;
|
||||
}
|
||||
if (!TraceObjectTogglable.KEY_ENABLED.equals(value.getEntryKey())) {
|
||||
if (!TraceTogglable.KEY_ENABLED.equals(value.getEntryKey())) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -675,7 +675,7 @@ public class ObjectTreeModel implements DisplaysModified {
|
||||
|
||||
protected TraceObject getEventObject(TraceObject object) {
|
||||
TraceObject scope = object
|
||||
.findCanonicalAncestorsInterface(TraceObjectEventScope.class)
|
||||
.findCanonicalAncestorsInterface(TraceEventScope.class)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
if (scope == null) {
|
||||
@@ -685,7 +685,7 @@ public class ObjectTreeModel implements DisplaysModified {
|
||||
return null;
|
||||
}
|
||||
TraceObjectValue eventValue =
|
||||
scope.getAttribute(snap, TraceObjectEventScope.KEY_EVENT_THREAD);
|
||||
scope.getAttribute(snap, TraceEventScope.KEY_EVENT_THREAD);
|
||||
if (eventValue == null || !eventValue.isObject()) {
|
||||
return null;
|
||||
}
|
||||
@@ -712,7 +712,7 @@ public class ObjectTreeModel implements DisplaysModified {
|
||||
if (type.contains("Breakpoint") || type.contains("Watchpoint")) {
|
||||
TraceObject object = edge.getChild();
|
||||
TraceObjectValue en =
|
||||
object.getAttribute(snap, TraceObjectTogglable.KEY_ENABLED);
|
||||
object.getAttribute(snap, TraceTogglable.KEY_ENABLED);
|
||||
// includes true or non-boolean values
|
||||
if (en == null || !Objects.equals(false, en.getValue())) {
|
||||
return DebuggerResources.ICON_SET_BREAKPOINT;
|
||||
|
||||
+19
-20
@@ -31,20 +31,20 @@ import ghidra.docking.settings.Settings;
|
||||
import ghidra.framework.plugintool.Plugin;
|
||||
import ghidra.framework.plugintool.ServiceProvider;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.trace.database.module.TraceObjectSection;
|
||||
import ghidra.trace.model.Trace;
|
||||
import ghidra.trace.model.modules.*;
|
||||
import ghidra.trace.model.modules.TraceModule;
|
||||
import ghidra.trace.model.modules.TraceSection;
|
||||
import ghidra.trace.model.target.TraceObject;
|
||||
import ghidra.trace.model.target.TraceObjectValue;
|
||||
import ghidra.trace.model.target.path.KeyPath;
|
||||
import ghidra.trace.model.target.schema.TraceObjectSchema;
|
||||
import ghidra.trace.model.thread.TraceObjectProcess;
|
||||
import ghidra.trace.model.thread.TraceProcess;
|
||||
|
||||
public class DebuggerModulesPanel extends AbstractObjectsTableBasedPanel<TraceObjectModule> {
|
||||
public class DebuggerModulesPanel extends AbstractObjectsTableBasedPanel<TraceModule> {
|
||||
|
||||
private static class ModuleBaseColumn extends AbstractTraceValueObjectAddressColumn {
|
||||
public ModuleBaseColumn() {
|
||||
super(TraceObjectModule.KEY_RANGE);
|
||||
super(TraceModule.KEY_RANGE);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -60,7 +60,7 @@ public class DebuggerModulesPanel extends AbstractObjectsTableBasedPanel<TraceOb
|
||||
|
||||
private static class ModuleMaxColumn extends AbstractTraceValueObjectAddressColumn {
|
||||
public ModuleMaxColumn() {
|
||||
super(TraceObjectModule.KEY_RANGE);
|
||||
super(TraceModule.KEY_RANGE);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -76,7 +76,7 @@ public class DebuggerModulesPanel extends AbstractObjectsTableBasedPanel<TraceOb
|
||||
|
||||
private static class ModuleNameColumn extends TraceValueObjectAttributeColumn<String> {
|
||||
public ModuleNameColumn() {
|
||||
super(TraceObjectModule.KEY_MODULE_NAME, String.class);
|
||||
super(TraceModule.KEY_MODULE_NAME, String.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -98,7 +98,7 @@ public class DebuggerModulesPanel extends AbstractObjectsTableBasedPanel<TraceOb
|
||||
return "";
|
||||
}
|
||||
ValueAttribute<AddressRange> attr =
|
||||
rowObject.getAttribute(TraceObjectModule.KEY_RANGE, AddressRange.class);
|
||||
rowObject.getAttribute(TraceModule.KEY_RANGE, AddressRange.class);
|
||||
if (attr == null) {
|
||||
return "";
|
||||
}
|
||||
@@ -131,7 +131,7 @@ public class DebuggerModulesPanel extends AbstractObjectsTableBasedPanel<TraceOb
|
||||
|
||||
private static class ModuleLengthColumn extends AbstractTraceValueObjectLengthColumn {
|
||||
public ModuleLengthColumn() {
|
||||
super(TraceObjectModule.KEY_RANGE);
|
||||
super(TraceModule.KEY_RANGE);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -166,12 +166,12 @@ public class DebuggerModulesPanel extends AbstractObjectsTableBasedPanel<TraceOb
|
||||
continue;
|
||||
}
|
||||
TraceObject child = value.getChild();
|
||||
TraceObjectModule module = child.queryInterface(TraceObjectModule.class);
|
||||
TraceModule module = child.queryInterface(TraceModule.class);
|
||||
if (module != null) {
|
||||
result.add(module);
|
||||
continue;
|
||||
}
|
||||
TraceObjectSection section = child.queryInterface(TraceObjectSection.class);
|
||||
TraceSection section = child.queryInterface(TraceSection.class);
|
||||
if (section != null) {
|
||||
result.add(section.getModule());
|
||||
continue;
|
||||
@@ -188,12 +188,12 @@ public class DebuggerModulesPanel extends AbstractObjectsTableBasedPanel<TraceOb
|
||||
continue;
|
||||
}
|
||||
TraceObject child = value.getChild();
|
||||
TraceObjectModule module = child.queryInterface(TraceObjectModule.class);
|
||||
TraceModule module = child.queryInterface(TraceModule.class);
|
||||
if (module != null) {
|
||||
result.addAll(module.getSections(ctx.getSnap()));
|
||||
continue;
|
||||
}
|
||||
TraceObjectSection section = child.queryInterface(TraceObjectSection.class);
|
||||
TraceSection section = child.queryInterface(TraceSection.class);
|
||||
if (section != null) {
|
||||
result.add(section);
|
||||
continue;
|
||||
@@ -206,12 +206,12 @@ public class DebuggerModulesPanel extends AbstractObjectsTableBasedPanel<TraceOb
|
||||
AddressSet result = new AddressSet();
|
||||
for (TraceObjectValue value : ctx.getObjectValues()) {
|
||||
TraceObject child = value.getChild();
|
||||
TraceObjectModule module = child.queryInterface(TraceObjectModule.class);
|
||||
TraceModule module = child.queryInterface(TraceModule.class);
|
||||
if (module != null) {
|
||||
result.add(module.getRange(ctx.getSnap()));
|
||||
continue;
|
||||
}
|
||||
TraceObjectSection section = child.queryInterface(TraceObjectSection.class);
|
||||
TraceSection section = child.queryInterface(TraceSection.class);
|
||||
if (section != null) {
|
||||
result.add(section.getRange(ctx.getSnap()));
|
||||
continue;
|
||||
@@ -222,13 +222,13 @@ public class DebuggerModulesPanel extends AbstractObjectsTableBasedPanel<TraceOb
|
||||
|
||||
protected static ModelQuery successorModules(TraceObjectSchema rootSchema, KeyPath path) {
|
||||
TraceObjectSchema schema = rootSchema.getSuccessorSchema(path);
|
||||
return new ModelQuery(schema.searchFor(TraceObjectModule.class, path, true));
|
||||
return new ModelQuery(schema.searchFor(TraceModule.class, path, true));
|
||||
}
|
||||
|
||||
private final DebuggerModulesProvider provider;
|
||||
|
||||
public DebuggerModulesPanel(DebuggerModulesProvider provider) {
|
||||
super(provider.plugin, provider, TraceObjectModule.class);
|
||||
super(provider.plugin, provider, TraceModule.class);
|
||||
this.provider = provider;
|
||||
}
|
||||
|
||||
@@ -241,15 +241,14 @@ public class DebuggerModulesPanel extends AbstractObjectsTableBasedPanel<TraceOb
|
||||
protected ModelQuery computeQuery(TraceObject object) {
|
||||
TraceObjectSchema rootSchema = object.getRoot().getSchema();
|
||||
KeyPath seedPath = object.getCanonicalPath();
|
||||
KeyPath processPath = rootSchema.searchForAncestor(TraceObjectProcess.class, seedPath);
|
||||
KeyPath processPath = rootSchema.searchForAncestor(TraceProcess.class, seedPath);
|
||||
if (processPath != null) {
|
||||
ModelQuery result = successorModules(rootSchema, processPath);
|
||||
if (!result.isEmpty()) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
KeyPath containerPath =
|
||||
rootSchema.searchForSuitableContainer(TraceObjectModule.class, seedPath);
|
||||
KeyPath containerPath = rootSchema.searchForSuitableContainer(TraceModule.class, seedPath);
|
||||
if (containerPath != null) {
|
||||
ModelQuery result = successorModules(rootSchema, containerPath);
|
||||
if (!result.isEmpty()) {
|
||||
|
||||
+1
-1
@@ -547,7 +547,7 @@ public class DebuggerModulesProvider extends ComponentProviderAdapter
|
||||
DebuggerModulesPanel modulesPanel;
|
||||
DebuggerSectionsPanel sectionsPanel;
|
||||
|
||||
// TODO: Lazy construction of these dialogs?
|
||||
// LATER?: Lazy construction of these dialogs?
|
||||
private final DebuggerBlockChooserDialog blockChooserDialog;
|
||||
private final DebuggerModuleMapProposalDialog moduleProposalDialog;
|
||||
private final DebuggerSectionMapProposalDialog sectionProposalDialog;
|
||||
|
||||
+16
-19
@@ -30,22 +30,21 @@ import ghidra.framework.plugintool.Plugin;
|
||||
import ghidra.framework.plugintool.ServiceProvider;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressRange;
|
||||
import ghidra.trace.database.module.TraceObjectSection;
|
||||
import ghidra.trace.model.Trace;
|
||||
import ghidra.trace.model.modules.TraceObjectModule;
|
||||
import ghidra.trace.model.modules.TraceModule;
|
||||
import ghidra.trace.model.modules.TraceSection;
|
||||
import ghidra.trace.model.target.TraceObject;
|
||||
import ghidra.trace.model.target.TraceObjectValue;
|
||||
import ghidra.trace.model.target.path.KeyPath;
|
||||
import ghidra.trace.model.target.schema.TraceObjectSchema;
|
||||
import ghidra.trace.model.thread.TraceObjectProcess;
|
||||
import ghidra.trace.model.thread.TraceProcess;
|
||||
|
||||
public class DebuggerSectionsPanel extends AbstractObjectsTableBasedPanel<TraceObjectSection> {
|
||||
public class DebuggerSectionsPanel extends AbstractObjectsTableBasedPanel<TraceSection> {
|
||||
|
||||
private static class SectionStartColumn extends AbstractTraceValueObjectAddressColumn {
|
||||
|
||||
public SectionStartColumn() {
|
||||
super(TraceObjectSection.KEY_RANGE);
|
||||
super(TraceSection.KEY_RANGE);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -61,7 +60,7 @@ public class DebuggerSectionsPanel extends AbstractObjectsTableBasedPanel<TraceO
|
||||
|
||||
private static class SectionEndColumn extends AbstractTraceValueObjectAddressColumn {
|
||||
public SectionEndColumn() {
|
||||
super(TraceObjectSection.KEY_RANGE);
|
||||
super(TraceSection.KEY_RANGE);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -120,8 +119,8 @@ public class DebuggerSectionsPanel extends AbstractObjectsTableBasedPanel<TraceO
|
||||
if (module == null) {
|
||||
return "";
|
||||
}
|
||||
TraceObjectValue nameEntry = module.getAttribute(row.currentSnap(),
|
||||
TraceObjectModule.KEY_MODULE_NAME);
|
||||
TraceObjectValue nameEntry =
|
||||
module.getAttribute(row.currentSnap(), TraceModule.KEY_MODULE_NAME);
|
||||
if (nameEntry == null) {
|
||||
return "";
|
||||
}
|
||||
@@ -133,7 +132,7 @@ public class DebuggerSectionsPanel extends AbstractObjectsTableBasedPanel<TraceO
|
||||
|
||||
private static class SectionLengthColumn extends AbstractTraceValueObjectLengthColumn {
|
||||
public SectionLengthColumn() {
|
||||
super(TraceObjectSection.KEY_RANGE);
|
||||
super(TraceSection.KEY_RANGE);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -161,21 +160,20 @@ public class DebuggerSectionsPanel extends AbstractObjectsTableBasedPanel<TraceO
|
||||
}
|
||||
|
||||
private static TraceObject getModule(ValueRow row) {
|
||||
TraceObjectValue moduleEntry =
|
||||
row.getAttributeEntry(TraceObjectSection.KEY_MODULE);
|
||||
TraceObjectValue moduleEntry = row.getAttributeEntry(TraceSection.KEY_MODULE);
|
||||
if (moduleEntry != null && moduleEntry.isObject()) {
|
||||
return moduleEntry.getChild();
|
||||
}
|
||||
return row.getValue()
|
||||
.getChild()
|
||||
.findCanonicalAncestorsInterface(TraceObjectModule.class)
|
||||
.findCanonicalAncestorsInterface(TraceModule.class)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
protected static ModelQuery successorSections(TraceObjectSchema rootSchema, KeyPath path) {
|
||||
TraceObjectSchema schema = rootSchema.getSuccessorSchema(path);
|
||||
return new ModelQuery(schema.searchFor(TraceObjectSection.class, path, true));
|
||||
return new ModelQuery(schema.searchFor(TraceSection.class, path, true));
|
||||
}
|
||||
|
||||
private class SectionsBySelectedModulesTableFilter implements TableFilter<ValueRow> {
|
||||
@@ -201,7 +199,7 @@ public class DebuggerSectionsPanel extends AbstractObjectsTableBasedPanel<TraceO
|
||||
new SectionsBySelectedModulesTableFilter();
|
||||
|
||||
public DebuggerSectionsPanel(DebuggerModulesProvider provider) {
|
||||
super(provider.plugin, provider, TraceObjectSection.class);
|
||||
super(provider.plugin, provider, TraceSection.class);
|
||||
this.provider = provider;
|
||||
}
|
||||
|
||||
@@ -214,19 +212,18 @@ public class DebuggerSectionsPanel extends AbstractObjectsTableBasedPanel<TraceO
|
||||
protected ModelQuery computeQuery(TraceObject object) {
|
||||
TraceObjectSchema rootSchema = object.getRoot().getSchema();
|
||||
KeyPath seedPath = object.getCanonicalPath();
|
||||
KeyPath processPath = rootSchema.searchForAncestor(TraceObjectProcess.class, seedPath);
|
||||
KeyPath processPath = rootSchema.searchForAncestor(TraceProcess.class, seedPath);
|
||||
if (processPath != null) {
|
||||
ModelQuery result = successorSections(rootSchema, processPath);
|
||||
ModelQuery result = successorSections(rootSchema, processPath);
|
||||
if (!result.isEmpty()) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
// Yes, anchor on the *module* container when searching for sections
|
||||
KeyPath containerPath =
|
||||
rootSchema.searchForSuitableContainer(TraceObjectModule.class, seedPath);
|
||||
KeyPath containerPath = rootSchema.searchForSuitableContainer(TraceModule.class, seedPath);
|
||||
|
||||
if (containerPath != null) {
|
||||
ModelQuery result = successorSections(rootSchema, containerPath);
|
||||
ModelQuery result = successorSections(rootSchema, containerPath);
|
||||
if (!result.isEmpty()) {
|
||||
return result;
|
||||
}
|
||||
|
||||
+3
-3
@@ -25,8 +25,8 @@ import ghidra.debug.api.ValStr;
|
||||
import ghidra.framework.options.SaveState;
|
||||
import ghidra.framework.plugintool.AutoConfigState.ConfigStateField;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
import ghidra.trace.model.target.iface.TraceObjectMethod;
|
||||
import ghidra.trace.model.target.iface.TraceObjectMethod.ParameterDescription;
|
||||
import ghidra.trace.model.target.iface.TraceMethod;
|
||||
import ghidra.trace.model.target.iface.TraceMethod.ParameterDescription;
|
||||
|
||||
@Deprecated(forRemoval = true, since = "11.3")
|
||||
public class DebuggerMethodInvocationDialog
|
||||
@@ -71,7 +71,7 @@ public class DebuggerMethodInvocationDialog
|
||||
protected Map<String, ValStr<?>> validateArguments(
|
||||
Map<String, ParameterDescription<?>> parameters, Map<String, ValStr<?>> arguments) {
|
||||
Map<String, ?> args = ValStr.toPlainMap(arguments);
|
||||
return ValStr.fromPlainMap(TraceObjectMethod.validateArguments(parameters, args, false));
|
||||
return ValStr.fromPlainMap(TraceMethod.validateArguments(parameters, args, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+19
-28
@@ -69,9 +69,9 @@ import ghidra.trace.model.guest.TracePlatform;
|
||||
import ghidra.trace.model.listing.*;
|
||||
import ghidra.trace.model.memory.*;
|
||||
import ghidra.trace.model.program.TraceProgramView;
|
||||
import ghidra.trace.model.target.TraceObject;
|
||||
import ghidra.trace.model.thread.TraceThread;
|
||||
import ghidra.trace.util.*;
|
||||
import ghidra.trace.util.TraceEvents;
|
||||
import ghidra.trace.util.TraceRegisterUtils;
|
||||
import ghidra.util.HelpLocation;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.classfinder.ClassSearcher;
|
||||
@@ -283,37 +283,28 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
|
||||
listenFor(TraceEvents.THREAD_LIFESPAN_CHANGED, this::threadDestroyed);
|
||||
}
|
||||
|
||||
private boolean isVisibleObjectsMode(AddressSpace space) {
|
||||
TraceObject container = current.getRegisterContainer();
|
||||
return container != null &&
|
||||
container.getCanonicalPath().toString().equals(space.getName());
|
||||
}
|
||||
|
||||
private boolean isVisible(TraceAddressSpace space) {
|
||||
private boolean isVisible(AddressSpace space) {
|
||||
if (!space.isRegisterSpace()) {
|
||||
return true; // Memory-mapped, visible no matter the active thread
|
||||
}
|
||||
TraceThread curThread = current.getThread();
|
||||
if (curThread == null) {
|
||||
return false;
|
||||
}
|
||||
if (space.getAddressSpace().isOverlaySpace()) {
|
||||
return isVisibleObjectsMode(space.getAddressSpace());
|
||||
if (space.isOverlaySpace()) {
|
||||
return current.isRegisterSpace(space);
|
||||
}
|
||||
if (!space.getAddressSpace().isRegisterSpace()) {
|
||||
return true; // Memory-mapped, visible no matter the active thread
|
||||
if (space.isRegisterSpace()) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
if (space.getThread() != curThread) {
|
||||
return false;
|
||||
}
|
||||
if (space.getFrameLevel() != current.getFrame()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isVisible(TraceAddressSpace space, TraceAddressSnapRange range) {
|
||||
private boolean isVisible(AddressSpace space, TraceAddressSnapRange range) {
|
||||
if (!isVisible(space)) {
|
||||
return false;
|
||||
}
|
||||
if (space.getAddressSpace().isMemorySpace()) {
|
||||
if (space.isMemorySpace()) {
|
||||
return current.getPlatform()
|
||||
.getLanguage()
|
||||
.getRegisterAddresses()
|
||||
@@ -351,7 +342,7 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
|
||||
}
|
||||
}
|
||||
|
||||
private void registerValueChanged(TraceAddressSpace space, TraceAddressSnapRange range,
|
||||
private void registerValueChanged(AddressSpace space, TraceAddressSnapRange range,
|
||||
byte[] oldIsNull, byte[] newVal) {
|
||||
if (!isVisible(space, range)) {
|
||||
return;
|
||||
@@ -359,7 +350,7 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
|
||||
refreshRange(range.getRange());
|
||||
}
|
||||
|
||||
private void registerStateChanged(TraceAddressSpace space, TraceAddressSnapRange range,
|
||||
private void registerStateChanged(AddressSpace space, TraceAddressSnapRange range,
|
||||
TraceMemoryState oldState, TraceMemoryState newState) {
|
||||
if (!isVisible(space, range)) {
|
||||
return;
|
||||
@@ -368,7 +359,7 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
|
||||
refreshRange(range.getRange());
|
||||
}
|
||||
|
||||
private void registerTypeAdded(TraceAddressSpace space, TraceAddressSnapRange range,
|
||||
private void registerTypeAdded(AddressSpace space, TraceAddressSnapRange range,
|
||||
TraceCodeUnit oldIsNull, TraceCodeUnit newUnit) {
|
||||
if (!isVisible(space, range)) {
|
||||
return;
|
||||
@@ -376,7 +367,7 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
|
||||
refreshRange(range.getRange());
|
||||
}
|
||||
|
||||
private void registerTypeReplaced(TraceAddressSpace space, TraceAddressSnapRange range,
|
||||
private void registerTypeReplaced(AddressSpace space, TraceAddressSnapRange range,
|
||||
long oldTypeID, long newTypeID) {
|
||||
if (!isVisible(space, range)) {
|
||||
return;
|
||||
@@ -384,7 +375,7 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
|
||||
refreshRange(range.getRange());
|
||||
}
|
||||
|
||||
private void registerTypeLifespanChanged(TraceAddressSpace space, TraceCodeUnit unit,
|
||||
private void registerTypeLifespanChanged(AddressSpace space, TraceCodeUnit unit,
|
||||
Lifespan oldSpan, Lifespan newSpan) {
|
||||
if (!isVisible(space)) {
|
||||
return;
|
||||
@@ -402,7 +393,7 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
|
||||
refreshRange(range); // Slightly wasteful, as we already have the data unit
|
||||
}
|
||||
|
||||
private void registerTypeRemoved(TraceAddressSpace space, TraceAddressSnapRange range,
|
||||
private void registerTypeRemoved(AddressSpace space, TraceAddressSnapRange range,
|
||||
TraceCodeUnit oldUnit, TraceCodeUnit newIsNull) {
|
||||
if (!isVisible(space)) {
|
||||
return;
|
||||
|
||||
+8
-8
@@ -34,15 +34,15 @@ import ghidra.framework.plugintool.annotation.AutoServiceConsumed;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.listing.Function;
|
||||
import ghidra.trace.model.Trace;
|
||||
import ghidra.trace.model.stack.TraceObjectStack;
|
||||
import ghidra.trace.model.stack.TraceObjectStackFrame;
|
||||
import ghidra.trace.model.stack.TraceStack;
|
||||
import ghidra.trace.model.stack.TraceStackFrame;
|
||||
import ghidra.trace.model.target.TraceObject;
|
||||
import ghidra.trace.model.target.TraceObjectValue;
|
||||
import ghidra.trace.model.target.path.KeyPath;
|
||||
import ghidra.trace.model.target.path.PathFilter;
|
||||
import ghidra.trace.model.target.schema.TraceObjectSchema;
|
||||
|
||||
public class DebuggerStackPanel extends AbstractObjectsTableBasedPanel<TraceObjectStackFrame>
|
||||
public class DebuggerStackPanel extends AbstractObjectsTableBasedPanel<TraceStackFrame>
|
||||
implements ListSelectionListener {
|
||||
|
||||
private static class FrameLevelColumn extends TraceValueKeyColumn {
|
||||
@@ -59,7 +59,7 @@ public class DebuggerStackPanel extends AbstractObjectsTableBasedPanel<TraceObje
|
||||
|
||||
private static class FramePcColumn extends TraceValueObjectAttributeColumn<Address> {
|
||||
public FramePcColumn() {
|
||||
super(TraceObjectStackFrame.KEY_PC, Address.class);
|
||||
super(TraceStackFrame.KEY_PC, Address.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -72,7 +72,7 @@ public class DebuggerStackPanel extends AbstractObjectsTableBasedPanel<TraceObje
|
||||
if (!(row.getValue().getValue() instanceof TraceObject object)) {
|
||||
return null;
|
||||
}
|
||||
TraceObjectValue attrPc = object.getAttribute(snap, TraceObjectStackFrame.KEY_PC);
|
||||
TraceObjectValue attrPc = object.getAttribute(snap, TraceStackFrame.KEY_PC);
|
||||
if (attrPc == null || !(attrPc.getValue() instanceof Address pc)) {
|
||||
return null;
|
||||
}
|
||||
@@ -177,7 +177,7 @@ public class DebuggerStackPanel extends AbstractObjectsTableBasedPanel<TraceObje
|
||||
protected DebuggerTraceManagerService traceManager;
|
||||
|
||||
public DebuggerStackPanel(DebuggerStackProvider provider) {
|
||||
super(provider.plugin, provider, TraceObjectStackFrame.class);
|
||||
super(provider.plugin, provider, TraceStackFrame.class);
|
||||
this.provider = provider;
|
||||
}
|
||||
|
||||
@@ -190,12 +190,12 @@ public class DebuggerStackPanel extends AbstractObjectsTableBasedPanel<TraceObje
|
||||
protected ModelQuery computeQuery(TraceObject object) {
|
||||
TraceObjectSchema rootSchema = object.getRoot().getSchema();
|
||||
KeyPath stackPath =
|
||||
rootSchema.searchForSuitable(TraceObjectStack.class, object.getCanonicalPath());
|
||||
rootSchema.searchForSuitable(TraceStack.class, object.getCanonicalPath());
|
||||
if (stackPath == null) {
|
||||
return ModelQuery.EMPTY;
|
||||
}
|
||||
TraceObjectSchema stackSchema = rootSchema.getSuccessorSchema(stackPath);
|
||||
PathFilter filter = stackSchema.searchFor(TraceObjectStackFrame.class, stackPath, true);
|
||||
PathFilter filter = stackSchema.searchFor(TraceStackFrame.class, stackPath, true);
|
||||
return new ModelQuery(filter);
|
||||
}
|
||||
|
||||
|
||||
+7
-14
@@ -27,6 +27,7 @@ import ghidra.pcode.exec.DebuggerPcodeUtils.PrettyBytes;
|
||||
import ghidra.pcode.exec.DebuggerPcodeUtils.WatchValue;
|
||||
import ghidra.pcode.exec.ValueLocation;
|
||||
import ghidra.program.model.address.AddressRange;
|
||||
import ghidra.program.model.address.AddressSpace;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.lang.Language;
|
||||
import ghidra.program.model.listing.*;
|
||||
@@ -35,8 +36,7 @@ import ghidra.program.model.pcode.Varnode;
|
||||
import ghidra.trace.model.Trace;
|
||||
import ghidra.trace.model.guest.TracePlatform;
|
||||
import ghidra.trace.model.listing.TraceCodeUnit;
|
||||
import ghidra.trace.model.memory.*;
|
||||
import ghidra.trace.util.TraceAddressSpace;
|
||||
import ghidra.trace.model.memory.TraceMemoryState;
|
||||
import ghidra.util.HTMLUtilities;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.exception.InvalidInputException;
|
||||
@@ -366,17 +366,9 @@ public interface VariableValueRow {
|
||||
* @param snap the snapshot key
|
||||
* @return the composite state
|
||||
*/
|
||||
static TraceMemoryState computeState(Trace trace, TraceAddressSpace space, AddressRange range,
|
||||
static TraceMemoryState computeState(Trace trace, AddressSpace space, AddressRange range,
|
||||
long snap) {
|
||||
TraceMemoryManager mem = trace.getMemoryManager();
|
||||
TraceMemoryOperations ops;
|
||||
if (space != null && space.getAddressSpace().isRegisterSpace()) {
|
||||
ops = mem.getMemoryRegisterSpace(space.getThread(), space.getFrameLevel(), false);
|
||||
}
|
||||
else {
|
||||
ops = mem;
|
||||
}
|
||||
return ops != null && ops.isKnown(snap, range)
|
||||
return trace.getMemoryManager().isKnown(snap, range)
|
||||
? TraceMemoryState.KNOWN
|
||||
: TraceMemoryState.UNKNOWN;
|
||||
}
|
||||
@@ -387,10 +379,11 @@ public interface VariableValueRow {
|
||||
* @param unit the code unit
|
||||
* @param snap the snapshot key
|
||||
* @return the composite state.
|
||||
* @see #computeState(Trace, TraceAddressSpace, AddressRange, long)
|
||||
* @see #computeState(Trace, AddressSpace, AddressRange, long)
|
||||
*/
|
||||
static TraceMemoryState computeState(TraceCodeUnit unit, long snap) {
|
||||
return computeState(unit.getTrace(), unit.getTraceSpace(), unit.getRange(), snap);
|
||||
return computeState(unit.getTrace(), unit.getAddress().getAddressSpace(), unit.getRange(),
|
||||
snap);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+2
-4
@@ -46,7 +46,6 @@ import ghidra.trace.model.memory.*;
|
||||
import ghidra.trace.model.stack.TraceStack;
|
||||
import ghidra.trace.model.stack.TraceStackFrame;
|
||||
import ghidra.trace.model.thread.TraceThread;
|
||||
import ghidra.trace.util.TraceAddressSpace;
|
||||
import ghidra.trace.util.TraceEvents;
|
||||
import ghidra.util.MathUtilities;
|
||||
import ghidra.util.Msg;
|
||||
@@ -672,10 +671,9 @@ public enum VariableValueUtils {
|
||||
listenFor(TraceEvents.BYTES_CHANGED, this::bytesChanged);
|
||||
}
|
||||
|
||||
private void bytesChanged(TraceAddressSpace space, TraceAddressSnapRange range) {
|
||||
TraceThread thread = space.getThread();
|
||||
private void bytesChanged(AddressSpace space, TraceAddressSnapRange range) {
|
||||
// TODO: Consider the lifespan, too? Would have to use viewport....
|
||||
if (thread == null || thread == coordinates.getThread()) {
|
||||
if (space.isMemorySpace() || coordinates.isRegisterSpace(space)) {
|
||||
invalidateCache();
|
||||
}
|
||||
}
|
||||
|
||||
+12
-12
@@ -38,17 +38,17 @@ import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.listing.Function;
|
||||
import ghidra.trace.model.Trace;
|
||||
import ghidra.trace.model.target.TraceObject;
|
||||
import ghidra.trace.model.target.iface.TraceObjectExecutionStateful;
|
||||
import ghidra.trace.model.target.iface.TraceExecutionStateful;
|
||||
import ghidra.trace.model.target.path.KeyPath;
|
||||
import ghidra.trace.model.target.schema.TraceObjectSchema;
|
||||
import ghidra.trace.model.thread.TraceObjectProcess;
|
||||
import ghidra.trace.model.thread.TraceObjectThread;
|
||||
import ghidra.trace.model.thread.TraceProcess;
|
||||
import ghidra.trace.model.thread.TraceThread;
|
||||
|
||||
public class DebuggerThreadsPanel extends AbstractObjectsTableBasedPanel<TraceObjectThread> {
|
||||
public class DebuggerThreadsPanel extends AbstractObjectsTableBasedPanel<TraceThread> {
|
||||
|
||||
protected static ModelQuery successorThreads(TraceObjectSchema rootSchema, KeyPath path) {
|
||||
TraceObjectSchema schema = rootSchema.getSuccessorSchema(path);
|
||||
return new ModelQuery(schema.searchFor(TraceObjectThread.class, path, true));
|
||||
return new ModelQuery(schema.searchFor(TraceThread.class, path, true));
|
||||
}
|
||||
|
||||
private static class ThreadPathColumn extends TraceValueKeyColumn {
|
||||
@@ -246,7 +246,7 @@ public class DebuggerThreadsPanel extends AbstractObjectsTableBasedPanel<TraceOb
|
||||
private static class ThreadStateColumn extends TraceValueObjectAttributeColumn<String> {
|
||||
public ThreadStateColumn() {
|
||||
// NB. The recorder converts enums to strings
|
||||
super(TraceObjectExecutionStateful.KEY_STATE, String.class);
|
||||
super(TraceExecutionStateful.KEY_STATE, String.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -258,7 +258,7 @@ public class DebuggerThreadsPanel extends AbstractObjectsTableBasedPanel<TraceOb
|
||||
private static class ThreadCommentColumn
|
||||
extends TraceValueObjectEditableAttributeColumn<String> {
|
||||
public ThreadCommentColumn() {
|
||||
super(TraceObjectThread.KEY_COMMENT, String.class);
|
||||
super(TraceThread.KEY_COMMENT, String.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -315,7 +315,7 @@ public class DebuggerThreadsPanel extends AbstractObjectsTableBasedPanel<TraceOb
|
||||
};
|
||||
|
||||
public DebuggerThreadsPanel(DebuggerThreadsProvider provider) {
|
||||
super(provider.plugin, provider, TraceObjectThread.class);
|
||||
super(provider.plugin, provider, TraceThread.class);
|
||||
this.provider = provider;
|
||||
setLimitToSnap(false); // TODO: Toggle for this?
|
||||
|
||||
@@ -346,18 +346,18 @@ public class DebuggerThreadsPanel extends AbstractObjectsTableBasedPanel<TraceOb
|
||||
protected ModelQuery computeQuery(TraceObject object) {
|
||||
TraceObjectSchema rootSchema = object.getRoot().getSchema();
|
||||
KeyPath seedPath = object.getCanonicalPath();
|
||||
KeyPath processPath = rootSchema.searchForAncestor(TraceObjectProcess.class, seedPath);
|
||||
KeyPath processPath = rootSchema.searchForAncestor(TraceProcess.class, seedPath);
|
||||
if (processPath != null) {
|
||||
ModelQuery result = successorThreads(rootSchema, processPath);
|
||||
ModelQuery result = successorThreads(rootSchema, processPath);
|
||||
if (!result.isEmpty()) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
KeyPath containerPath =
|
||||
rootSchema.searchForSuitableContainer(TraceObjectThread.class, seedPath);
|
||||
rootSchema.searchForSuitableContainer(TraceThread.class, seedPath);
|
||||
|
||||
if (containerPath != null) {
|
||||
ModelQuery result = successorThreads(rootSchema, containerPath);
|
||||
ModelQuery result = successorThreads(rootSchema, containerPath);
|
||||
if (!result.isEmpty()) {
|
||||
return result;
|
||||
}
|
||||
|
||||
+14
-19
@@ -42,11 +42,15 @@ import ghidra.trace.model.Lifespan;
|
||||
import ghidra.trace.model.Trace;
|
||||
import ghidra.trace.model.bookmark.TraceBookmark;
|
||||
import ghidra.trace.model.bookmark.TraceBookmarkManager;
|
||||
import ghidra.trace.model.breakpoint.*;
|
||||
import ghidra.trace.model.memory.*;
|
||||
import ghidra.trace.model.modules.*;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointLocation;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointManager;
|
||||
import ghidra.trace.model.memory.TraceMemoryManager;
|
||||
import ghidra.trace.model.memory.TraceMemoryRegion;
|
||||
import ghidra.trace.model.modules.TraceModule;
|
||||
import ghidra.trace.model.modules.TraceModuleManager;
|
||||
import ghidra.trace.model.target.TraceObject;
|
||||
import ghidra.trace.model.thread.*;
|
||||
import ghidra.trace.model.thread.TraceThread;
|
||||
import ghidra.trace.model.thread.TraceThreadManager;
|
||||
import ghidra.util.HelpLocation;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.classfinder.ClassSearcher;
|
||||
@@ -74,7 +78,7 @@ import resources.ResourceManager;
|
||||
)
|
||||
|
||||
public class TimeOverviewColorPlugin extends AbstractDebuggerPlugin {
|
||||
|
||||
|
||||
@AutoServiceConsumed
|
||||
private DebuggerTraceManagerService traceManager;
|
||||
@AutoServiceConsumed
|
||||
@@ -82,7 +86,6 @@ public class TimeOverviewColorPlugin extends AbstractDebuggerPlugin {
|
||||
@SuppressWarnings("unused")
|
||||
private final AutoService.Wiring autoServiceWiring;
|
||||
|
||||
|
||||
public static final String HELP_TOPIC = "OverviewPlugin";
|
||||
private static final String ACTIVE_SERVICES = "ActiveServices";
|
||||
private List<TimeOverviewColorService> allServices;
|
||||
@@ -270,27 +273,19 @@ public class TimeOverviewColorPlugin extends AbstractDebuggerPlugin {
|
||||
Trace trace = traceManager.getCurrentTrace();
|
||||
TraceThreadManager threadManager = trace.getThreadManager();
|
||||
for (TraceThread thread : threadManager.getAllThreads()) {
|
||||
if (thread instanceof TraceObjectThread objThread) {
|
||||
addObject(set, objThread.getObject());
|
||||
}
|
||||
addObject(set, thread.getObject());
|
||||
}
|
||||
TraceModuleManager moduleManager = trace.getModuleManager();
|
||||
for (TraceModule module : moduleManager.getAllModules()) {
|
||||
if (module instanceof TraceObjectModule objModule) {
|
||||
addObject(set, objModule.getObject());
|
||||
}
|
||||
addObject(set, module.getObject());
|
||||
}
|
||||
TraceMemoryManager memoryManager = trace.getMemoryManager();
|
||||
for (TraceMemoryRegion region : memoryManager.getAllRegions()) {
|
||||
if (region instanceof TraceObjectMemoryRegion objRegion) {
|
||||
addObject(set, objRegion.getObject());
|
||||
}
|
||||
addObject(set, region.getObject());
|
||||
}
|
||||
TraceBreakpointManager breakpointManager = trace.getBreakpointManager();
|
||||
for (TraceBreakpoint bpt : breakpointManager.getAllBreakpoints()) {
|
||||
if (bpt instanceof TraceObjectBreakpointLocation objBreakpoint) {
|
||||
addObject(set, objBreakpoint.getObject());
|
||||
}
|
||||
for (TraceBreakpointLocation bpt : breakpointManager.getAllBreakpointLocations()) {
|
||||
addObject(set, bpt.getObject());
|
||||
}
|
||||
TraceBookmarkManager bookmarkManager = trace.getBookmarkManager();
|
||||
for (TraceBookmark mark : bookmarkManager.getAllBookmarks()) {
|
||||
|
||||
+118
-157
@@ -23,11 +23,15 @@ import ghidra.framework.model.DomainObjectChangeRecord;
|
||||
import ghidra.framework.model.DomainObjectEvent;
|
||||
import ghidra.trace.model.*;
|
||||
import ghidra.trace.model.bookmark.TraceBookmark;
|
||||
import ghidra.trace.model.breakpoint.*;
|
||||
import ghidra.trace.model.memory.*;
|
||||
import ghidra.trace.model.modules.*;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointLocation;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointManager;
|
||||
import ghidra.trace.model.memory.TraceMemoryManager;
|
||||
import ghidra.trace.model.memory.TraceMemoryRegion;
|
||||
import ghidra.trace.model.modules.TraceModule;
|
||||
import ghidra.trace.model.modules.TraceModuleManager;
|
||||
import ghidra.trace.model.target.TraceObject;
|
||||
import ghidra.trace.model.thread.*;
|
||||
import ghidra.trace.model.thread.TraceThread;
|
||||
import ghidra.trace.model.thread.TraceThreadManager;
|
||||
import ghidra.trace.util.TraceEvents;
|
||||
import ghidra.util.Swing;
|
||||
|
||||
@@ -118,193 +122,150 @@ public class TimeOverviewEventListener extends TraceDomainObjectListener {
|
||||
regionChanged(region);
|
||||
}
|
||||
TraceBreakpointManager breakpointManager = trace.getBreakpointManager();
|
||||
for (TraceBreakpoint bpt : breakpointManager.getAllBreakpoints()) {
|
||||
for (TraceBreakpointLocation bpt : breakpointManager.getAllBreakpointLocations()) {
|
||||
bptChanged(bpt);
|
||||
}
|
||||
}
|
||||
|
||||
private void threadAdded(TraceThread thread) {
|
||||
if (!(thread instanceof TraceObjectThread objThread)) {
|
||||
return;
|
||||
}
|
||||
|
||||
TraceObject obj = objThread.getObject();
|
||||
obj.getOrderedValues(Lifespan.ALL, TraceObjectBreakpointLocation.KEY_RANGE, true)
|
||||
.forEach(v -> {
|
||||
long snap = v.getMinSnap();
|
||||
p.updateMap(snap, TimeType.BPT_ADDED, thread.getName(snap), true);
|
||||
});
|
||||
private void threadAdded(TraceThread thread) {
|
||||
TraceObject obj = thread.getObject();
|
||||
obj.getOrderedValues(Lifespan.ALL, TraceBreakpointLocation.KEY_RANGE, true)
|
||||
.forEach(v -> {
|
||||
long snap = v.getMinSnap();
|
||||
p.updateMap(snap, TimeType.BPT_ADDED, thread.getName(snap), true);
|
||||
});
|
||||
}
|
||||
|
||||
private void threadChanged(TraceThread thread) {
|
||||
if (!(thread instanceof TraceObjectThread objThread)) {
|
||||
return;
|
||||
}
|
||||
|
||||
TraceObject obj = objThread.getObject();
|
||||
obj.getOrderedValues(Lifespan.ALL, TraceObjectThread.KEY_TID, true)
|
||||
.forEach(v -> {
|
||||
long snapMin = v.getMinSnap();
|
||||
long snapMax = v.getMaxSnap();
|
||||
if (snapMin == snapMax) {
|
||||
p.updateMap(snapMin, TimeType.THREAD_CHANGED, thread.getName(snapMin), true);
|
||||
}
|
||||
else {
|
||||
p.updateMap(snapMin, TimeType.THREAD_ADDED, thread.getName(snapMin), true);
|
||||
p.updateMap(snapMax, TimeType.THREAD_REMOVED, thread.getName(snapMax), true);
|
||||
}
|
||||
});
|
||||
TraceObject obj = thread.getObject();
|
||||
obj.getOrderedValues(Lifespan.ALL, TraceThread.KEY_TID, true).forEach(v -> {
|
||||
long snapMin = v.getMinSnap();
|
||||
long snapMax = v.getMaxSnap();
|
||||
if (snapMin == snapMax) {
|
||||
p.updateMap(snapMin, TimeType.THREAD_CHANGED, thread.getName(snapMin),
|
||||
true);
|
||||
}
|
||||
else {
|
||||
p.updateMap(snapMin, TimeType.THREAD_ADDED, thread.getName(snapMin), true);
|
||||
p.updateMap(snapMax, TimeType.THREAD_REMOVED, thread.getName(snapMax),
|
||||
true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void threadDeleted(TraceThread thread) {
|
||||
if (!(thread instanceof TraceObjectThread objThread)) {
|
||||
return;
|
||||
}
|
||||
|
||||
TraceObject obj = objThread.getObject();
|
||||
obj.getOrderedValues(Lifespan.ALL, TraceObjectBreakpointLocation.KEY_RANGE, true)
|
||||
.forEach(v -> {
|
||||
long snap = v.getMaxSnap();
|
||||
p.updateMap(snap, TimeType.THREAD_REMOVED, thread.getName(snap), true);
|
||||
});
|
||||
TraceObject obj = thread.getObject();
|
||||
obj.getOrderedValues(Lifespan.ALL, TraceBreakpointLocation.KEY_RANGE, true)
|
||||
.forEach(v -> {
|
||||
long snap = v.getMaxSnap();
|
||||
p.updateMap(snap, TimeType.THREAD_REMOVED, thread.getName(snap), true);
|
||||
});
|
||||
}
|
||||
|
||||
private void moduleAdded(TraceModule module) {
|
||||
if (!(module instanceof TraceObjectModule objMod)) {
|
||||
return;
|
||||
}
|
||||
|
||||
TraceObject obj = objMod.getObject();
|
||||
obj.getOrderedValues(Lifespan.ALL, TraceObjectBreakpointLocation.KEY_RANGE, true)
|
||||
.forEach(v -> {
|
||||
long snap = v.getMinSnap();
|
||||
p.updateMap(snap, TimeType.MODULE_ADDED, module.getName(snap), true);
|
||||
});
|
||||
TraceObject obj = module.getObject();
|
||||
obj.getOrderedValues(Lifespan.ALL, TraceBreakpointLocation.KEY_RANGE, true)
|
||||
.forEach(v -> {
|
||||
long snap = v.getMinSnap();
|
||||
p.updateMap(snap, TimeType.MODULE_ADDED, module.getName(snap), true);
|
||||
});
|
||||
}
|
||||
|
||||
private void moduleChanged(TraceModule module) {
|
||||
if (!(module instanceof TraceObjectModule objMod)) {
|
||||
return;
|
||||
}
|
||||
|
||||
TraceObject obj = objMod.getObject();
|
||||
obj.getOrderedValues(Lifespan.ALL, TraceObjectBreakpointLocation.KEY_RANGE, true)
|
||||
.forEach(v -> {
|
||||
long snapMin = v.getMinSnap();
|
||||
long snapMax = v.getMaxSnap();
|
||||
if (snapMin == snapMax) {
|
||||
p.updateMap(snapMin, TimeType.MODULE_CHANGED, module.getName(snapMin), true);
|
||||
}
|
||||
else {
|
||||
p.updateMap(snapMin, TimeType.MODULE_ADDED, module.getName(snapMin), true);
|
||||
p.updateMap(snapMax, TimeType.MODULE_REMOVED, module.getName(snapMax), true);
|
||||
}
|
||||
});
|
||||
TraceObject obj = module.getObject();
|
||||
obj.getOrderedValues(Lifespan.ALL, TraceBreakpointLocation.KEY_RANGE, true)
|
||||
.forEach(v -> {
|
||||
long snapMin = v.getMinSnap();
|
||||
long snapMax = v.getMaxSnap();
|
||||
if (snapMin == snapMax) {
|
||||
p.updateMap(snapMin, TimeType.MODULE_CHANGED, module.getName(snapMin),
|
||||
true);
|
||||
}
|
||||
else {
|
||||
p.updateMap(snapMin, TimeType.MODULE_ADDED, module.getName(snapMin), true);
|
||||
p.updateMap(snapMax, TimeType.MODULE_REMOVED, module.getName(snapMax),
|
||||
true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void moduleDeleted(TraceModule module) {
|
||||
if (!(module instanceof TraceObjectModule objMod)) {
|
||||
return;
|
||||
}
|
||||
|
||||
TraceObject obj = objMod.getObject();
|
||||
obj.getOrderedValues(Lifespan.ALL, TraceObjectBreakpointLocation.KEY_RANGE, true)
|
||||
.forEach(v -> {
|
||||
long snap = v.getMaxSnap();
|
||||
p.updateMap(snap, TimeType.MODULE_REMOVED, module.getName(snap), true);
|
||||
});
|
||||
TraceObject obj = module.getObject();
|
||||
obj.getOrderedValues(Lifespan.ALL, TraceBreakpointLocation.KEY_RANGE, true)
|
||||
.forEach(v -> {
|
||||
long snap = v.getMaxSnap();
|
||||
p.updateMap(snap, TimeType.MODULE_REMOVED, module.getName(snap), true);
|
||||
});
|
||||
}
|
||||
|
||||
private void regionAdded(TraceMemoryRegion region) {
|
||||
if (!(region instanceof TraceObjectMemoryRegion objReg)) {
|
||||
return;
|
||||
}
|
||||
|
||||
TraceObject obj = objReg.getObject();
|
||||
obj.getOrderedValues(Lifespan.ALL, TraceObjectBreakpointLocation.KEY_RANGE, true)
|
||||
.forEach(v -> {
|
||||
long snap = v.getMinSnap();
|
||||
p.updateMap(snap, TimeType.REGION_ADDED, region.getName(snap), true);
|
||||
});
|
||||
TraceObject obj = region.getObject();
|
||||
obj.getOrderedValues(Lifespan.ALL, TraceBreakpointLocation.KEY_RANGE, true)
|
||||
.forEach(v -> {
|
||||
long snap = v.getMinSnap();
|
||||
p.updateMap(snap, TimeType.REGION_ADDED, region.getName(snap), true);
|
||||
});
|
||||
}
|
||||
|
||||
private void regionChanged(TraceMemoryRegion region) {
|
||||
if (!(region instanceof TraceObjectMemoryRegion objReg)) {
|
||||
return;
|
||||
}
|
||||
|
||||
TraceObject obj = objReg.getObject();
|
||||
obj.getOrderedValues(Lifespan.ALL, TraceObjectBreakpointLocation.KEY_RANGE, true)
|
||||
.forEach(v -> {
|
||||
long snapMin = v.getMinSnap();
|
||||
long snapMax = v.getMaxSnap();
|
||||
if (snapMin == snapMax) {
|
||||
p.updateMap(snapMin, TimeType.REGION_CHANGED, region.getName(snapMin), true);
|
||||
}
|
||||
else {
|
||||
p.updateMap(snapMin, TimeType.REGION_ADDED, region.getName(snapMin), true);
|
||||
p.updateMap(snapMax, TimeType.REGION_REMOVED, region.getName(snapMax), true);
|
||||
}
|
||||
});
|
||||
TraceObject obj = region.getObject();
|
||||
obj.getOrderedValues(Lifespan.ALL, TraceBreakpointLocation.KEY_RANGE, true)
|
||||
.forEach(v -> {
|
||||
long snapMin = v.getMinSnap();
|
||||
long snapMax = v.getMaxSnap();
|
||||
if (snapMin == snapMax) {
|
||||
p.updateMap(snapMin, TimeType.REGION_CHANGED, region.getName(snapMin),
|
||||
true);
|
||||
}
|
||||
else {
|
||||
p.updateMap(snapMin, TimeType.REGION_ADDED, region.getName(snapMin), true);
|
||||
p.updateMap(snapMax, TimeType.REGION_REMOVED, region.getName(snapMax),
|
||||
true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void regionDeleted(TraceMemoryRegion region) {
|
||||
if (!(region instanceof TraceObjectMemoryRegion objReg)) {
|
||||
return;
|
||||
}
|
||||
|
||||
TraceObject obj = objReg.getObject();
|
||||
obj.getOrderedValues(Lifespan.ALL, TraceObjectBreakpointLocation.KEY_RANGE, true)
|
||||
.forEach(v -> {
|
||||
long snap = v.getMaxSnap();
|
||||
p.updateMap(snap, TimeType.REGION_REMOVED, region.getName(snap), true);
|
||||
});
|
||||
TraceObject obj = region.getObject();
|
||||
obj.getOrderedValues(Lifespan.ALL, TraceBreakpointLocation.KEY_RANGE, true)
|
||||
.forEach(v -> {
|
||||
long snap = v.getMaxSnap();
|
||||
p.updateMap(snap, TimeType.REGION_REMOVED, region.getName(snap), true);
|
||||
});
|
||||
}
|
||||
|
||||
private void bptAdded(TraceBreakpoint bpt) {
|
||||
if (!(bpt instanceof TraceObjectBreakpointLocation objBpt)) {
|
||||
return;
|
||||
}
|
||||
|
||||
TraceObject obj = objBpt.getObject();
|
||||
obj.getOrderedValues(Lifespan.ALL, TraceObjectBreakpointLocation.KEY_RANGE, true)
|
||||
.forEach(v -> {
|
||||
long snap = v.getMinSnap();
|
||||
p.updateMap(snap, TimeType.BPT_ADDED, bpt.getName(snap), true);
|
||||
});
|
||||
private void bptAdded(TraceBreakpointLocation bpt) {
|
||||
TraceObject obj = bpt.getObject();
|
||||
obj.getOrderedValues(Lifespan.ALL, TraceBreakpointLocation.KEY_RANGE, true)
|
||||
.forEach(v -> {
|
||||
long snap = v.getMinSnap();
|
||||
p.updateMap(snap, TimeType.BPT_ADDED, bpt.getName(snap), true);
|
||||
});
|
||||
}
|
||||
|
||||
private void bptChanged(TraceBreakpoint bpt) {
|
||||
if (!(bpt instanceof TraceObjectBreakpointLocation objBpt)) {
|
||||
return;
|
||||
}
|
||||
|
||||
TraceObject obj = objBpt.getObject();
|
||||
obj.getOrderedValues(Lifespan.ALL, TraceObjectBreakpointLocation.KEY_RANGE, true)
|
||||
.forEach(v -> {
|
||||
long snapMin = v.getMinSnap();
|
||||
long snapMax = v.getMaxSnap();
|
||||
if (snapMin == snapMax) {
|
||||
p.updateMap(snapMin, TimeType.BPT_CHANGED, bpt.getName(snapMin), true);
|
||||
}
|
||||
else {
|
||||
p.updateMap(snapMin, TimeType.BPT_ADDED, bpt.getName(snapMin), true);
|
||||
p.updateMap(snapMax, TimeType.BPT_REMOVED, bpt.getName(snapMax), true);
|
||||
}
|
||||
});
|
||||
private void bptChanged(TraceBreakpointLocation bpt) {
|
||||
TraceObject obj = bpt.getObject();
|
||||
obj.getOrderedValues(Lifespan.ALL, TraceBreakpointLocation.KEY_RANGE, true)
|
||||
.forEach(v -> {
|
||||
long snapMin = v.getMinSnap();
|
||||
long snapMax = v.getMaxSnap();
|
||||
if (snapMin == snapMax) {
|
||||
p.updateMap(snapMin, TimeType.BPT_CHANGED, bpt.getName(snapMin), true);
|
||||
}
|
||||
else {
|
||||
p.updateMap(snapMin, TimeType.BPT_ADDED, bpt.getName(snapMin), true);
|
||||
p.updateMap(snapMax, TimeType.BPT_REMOVED, bpt.getName(snapMax), true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void bptDeleted(TraceBreakpoint bpt) {
|
||||
if (!(bpt instanceof TraceObjectBreakpointLocation objBpt)) {
|
||||
return;
|
||||
}
|
||||
|
||||
TraceObject obj = objBpt.getObject();
|
||||
obj.getOrderedValues(Lifespan.ALL, TraceObjectBreakpointLocation.KEY_RANGE, true)
|
||||
.forEach(v -> {
|
||||
long snap = v.getMaxSnap();
|
||||
p.updateMap(snap, TimeType.BPT_REMOVED, bpt.getName(snap), true);
|
||||
});
|
||||
private void bptDeleted(TraceBreakpointLocation bpt) {
|
||||
TraceObject obj = bpt.getObject();
|
||||
obj.getOrderedValues(Lifespan.ALL, TraceBreakpointLocation.KEY_RANGE, true)
|
||||
.forEach(v -> {
|
||||
long snap = v.getMaxSnap();
|
||||
p.updateMap(snap, TimeType.BPT_REMOVED, bpt.getName(snap), true);
|
||||
});
|
||||
}
|
||||
|
||||
private void bookmarkAdded(TraceBookmark bookmark) {
|
||||
|
||||
+4
-5
@@ -78,7 +78,6 @@ import ghidra.trace.model.*;
|
||||
import ghidra.trace.model.guest.TracePlatform;
|
||||
import ghidra.trace.model.program.TraceProgramView;
|
||||
import ghidra.trace.model.time.schedule.TraceSchedule;
|
||||
import ghidra.trace.util.TraceAddressSpace;
|
||||
import ghidra.trace.util.TraceEvents;
|
||||
import ghidra.util.HelpLocation;
|
||||
import ghidra.util.Msg;
|
||||
@@ -260,14 +259,14 @@ public class DebuggerWatchesProvider extends ComponentProviderAdapter
|
||||
}
|
||||
}
|
||||
|
||||
private void bytesChanged(TraceAddressSpace space, TraceAddressSnapRange range) {
|
||||
if (space.getThread() == current.getThread() || space.getThread() == null) {
|
||||
private void bytesChanged(AddressSpace space, TraceAddressSnapRange range) {
|
||||
if (space.isMemorySpace() || current.isRegisterSpace(space)) {
|
||||
addChanged(range.getRange());
|
||||
}
|
||||
}
|
||||
|
||||
private void stateChanged(TraceAddressSpace space, TraceAddressSnapRange range) {
|
||||
if (space.getThread() == current.getThread() || space.getThread() == null) {
|
||||
private void stateChanged(AddressSpace space, TraceAddressSnapRange range) {
|
||||
if (space.isMemorySpace() || current.isRegisterSpace(space)) {
|
||||
addChanged(range.getRange());
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -529,7 +529,7 @@ public class DefaultWatchRow implements WatchRow {
|
||||
DebuggerCoordinates current = provider.current;
|
||||
Trace trace = current.getTrace();
|
||||
Collection<? extends TraceLabelSymbol> labels =
|
||||
trace.getSymbolManager().labels().getAt(current.getSnap(), null, address, false);
|
||||
trace.getSymbolManager().labels().getAt(current.getSnap(), address, false);
|
||||
if (!labels.isEmpty()) {
|
||||
return labels.iterator().next();
|
||||
}
|
||||
|
||||
+6
-6
@@ -22,7 +22,7 @@ import ghidra.trace.model.Lifespan;
|
||||
import ghidra.trace.model.Trace;
|
||||
import ghidra.trace.model.target.TraceObject;
|
||||
import ghidra.trace.model.target.TraceObjectValue;
|
||||
import ghidra.trace.model.target.iface.TraceObjectEnvironment;
|
||||
import ghidra.trace.model.target.iface.TraceEnvironment;
|
||||
import ghidra.trace.model.target.path.KeyPath;
|
||||
import ghidra.trace.model.target.path.PathFilter;
|
||||
import ghidra.util.Msg;
|
||||
@@ -67,7 +67,7 @@ public interface DebuggerPlatformOpinion extends ExtensionPoint {
|
||||
}
|
||||
TraceObject root = object.getRoot();
|
||||
KeyPath pathToEnv = root.getSchema()
|
||||
.searchForSuitable(TraceObjectEnvironment.class, object.getCanonicalPath());
|
||||
.searchForSuitable(TraceEnvironment.class, object.getCanonicalPath());
|
||||
if (pathToEnv == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -86,15 +86,15 @@ public interface DebuggerPlatformOpinion extends ExtensionPoint {
|
||||
}
|
||||
|
||||
static String getDebugggerFromEnv(TraceObject env, long snap) {
|
||||
return getStringAttribute(env, snap, TraceObjectEnvironment.KEY_DEBUGGER);
|
||||
return getStringAttribute(env, snap, TraceEnvironment.KEY_DEBUGGER);
|
||||
}
|
||||
|
||||
static String getArchitectureFromEnv(TraceObject env, long snap) {
|
||||
return getStringAttribute(env, snap, TraceObjectEnvironment.KEY_ARCH);
|
||||
return getStringAttribute(env, snap, TraceEnvironment.KEY_ARCH);
|
||||
}
|
||||
|
||||
static String getOperatingSystemFromEnv(TraceObject env, long snap) {
|
||||
return getStringAttribute(env, snap, TraceObjectEnvironment.KEY_OS);
|
||||
return getStringAttribute(env, snap, TraceEnvironment.KEY_OS);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -105,7 +105,7 @@ public interface DebuggerPlatformOpinion extends ExtensionPoint {
|
||||
* @return the endianness, or null
|
||||
*/
|
||||
static Endian getEndianFromEnv(TraceObject env, long snap) {
|
||||
String strEndian = getStringAttribute(env, snap, TraceObjectEnvironment.KEY_ENDIAN);
|
||||
String strEndian = getStringAttribute(env, snap, TraceEnvironment.KEY_ENDIAN);
|
||||
if (strEndian == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
+22
-19
@@ -20,7 +20,7 @@ import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import ghidra.async.AsyncFence;
|
||||
import ghidra.debug.api.target.Target;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpoint;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointLocation;
|
||||
|
||||
/**
|
||||
* A de-duplicated collection of breakpoint action items necessary to implement a logical breakpoint
|
||||
@@ -37,11 +37,12 @@ public class BreakpointActionSet extends LinkedHashSet<BreakpointActionItem> {
|
||||
* Add an item to enable a target breakpoint
|
||||
*
|
||||
* @param target the target
|
||||
* @param bpt the target breakpoint
|
||||
* @param loc the target breakpoint
|
||||
* @return the added item
|
||||
*/
|
||||
public EnableTargetBreakpointActionItem planEnableTarget(Target target, TraceBreakpoint bpt) {
|
||||
EnableTargetBreakpointActionItem action = new EnableTargetBreakpointActionItem(target, bpt);
|
||||
public EnableTargetBreakpointActionItem planEnableTarget(Target target,
|
||||
TraceBreakpointLocation loc) {
|
||||
EnableTargetBreakpointActionItem action = new EnableTargetBreakpointActionItem(target, loc);
|
||||
add(action);
|
||||
return action;
|
||||
}
|
||||
@@ -49,12 +50,12 @@ public class BreakpointActionSet extends LinkedHashSet<BreakpointActionItem> {
|
||||
/**
|
||||
* Add an item to enable an emulated breakpoint
|
||||
*
|
||||
* @param bpt the trace breakpoint
|
||||
* @param loc the trace breakpoint
|
||||
* @param snap the snap
|
||||
* @return the added item
|
||||
*/
|
||||
public EnableEmuBreakpointActionItem planEnableEmu(TraceBreakpoint bpt, long snap) {
|
||||
EnableEmuBreakpointActionItem action = new EnableEmuBreakpointActionItem(bpt, snap);
|
||||
public EnableEmuBreakpointActionItem planEnableEmu(TraceBreakpointLocation loc, long snap) {
|
||||
EnableEmuBreakpointActionItem action = new EnableEmuBreakpointActionItem(loc, snap);
|
||||
add(action);
|
||||
return action;
|
||||
}
|
||||
@@ -63,12 +64,13 @@ public class BreakpointActionSet extends LinkedHashSet<BreakpointActionItem> {
|
||||
* Add an item to disable a target breakpoint
|
||||
*
|
||||
* @param target the target
|
||||
* @param bpt the target breakpoint
|
||||
* @param loc the target breakpoint
|
||||
* @return the added item
|
||||
*/
|
||||
public DisableTargetBreakpointActionItem planDisableTarget(Target target, TraceBreakpoint bpt) {
|
||||
public DisableTargetBreakpointActionItem planDisableTarget(Target target,
|
||||
TraceBreakpointLocation loc) {
|
||||
DisableTargetBreakpointActionItem action =
|
||||
new DisableTargetBreakpointActionItem(target, bpt);
|
||||
new DisableTargetBreakpointActionItem(target, loc);
|
||||
add(action);
|
||||
return action;
|
||||
}
|
||||
@@ -76,12 +78,12 @@ public class BreakpointActionSet extends LinkedHashSet<BreakpointActionItem> {
|
||||
/**
|
||||
* Add an item to disable an emulated breakpoint
|
||||
*
|
||||
* @param bpt the trace breakpoint
|
||||
* @param loc the trace breakpoint
|
||||
* @param snap the snap
|
||||
* @return the added item
|
||||
*/
|
||||
public DisableEmuBreakpointActionItem planDisableEmu(TraceBreakpoint bpt, long snap) {
|
||||
DisableEmuBreakpointActionItem action = new DisableEmuBreakpointActionItem(bpt, snap);
|
||||
public DisableEmuBreakpointActionItem planDisableEmu(TraceBreakpointLocation loc, long snap) {
|
||||
DisableEmuBreakpointActionItem action = new DisableEmuBreakpointActionItem(loc, snap);
|
||||
add(action);
|
||||
return action;
|
||||
}
|
||||
@@ -90,11 +92,12 @@ public class BreakpointActionSet extends LinkedHashSet<BreakpointActionItem> {
|
||||
* Add an item to delete a target breakpoint
|
||||
*
|
||||
* @param target the target
|
||||
* @param bpt the target breakpoint
|
||||
* @param loc the target breakpoint
|
||||
* @return the added item
|
||||
*/
|
||||
public DeleteTargetBreakpointActionItem planDeleteTarget(Target target, TraceBreakpoint bpt) {
|
||||
DeleteTargetBreakpointActionItem action = new DeleteTargetBreakpointActionItem(target, bpt);
|
||||
public DeleteTargetBreakpointActionItem planDeleteTarget(Target target,
|
||||
TraceBreakpointLocation loc) {
|
||||
DeleteTargetBreakpointActionItem action = new DeleteTargetBreakpointActionItem(target, loc);
|
||||
add(action);
|
||||
return action;
|
||||
}
|
||||
@@ -102,12 +105,12 @@ public class BreakpointActionSet extends LinkedHashSet<BreakpointActionItem> {
|
||||
/**
|
||||
* Add an item to delete an emulated breakpoint
|
||||
*
|
||||
* @param bpt the trace breakpoint
|
||||
* @param loc the trace breakpoint
|
||||
* @param snap the snap
|
||||
* @return the added item
|
||||
*/
|
||||
public DeleteEmuBreakpointActionItem planDeleteEmu(TraceBreakpoint bpt, long snap) {
|
||||
DeleteEmuBreakpointActionItem action = new DeleteEmuBreakpointActionItem(bpt, snap);
|
||||
public DeleteEmuBreakpointActionItem planDeleteEmu(TraceBreakpointLocation loc, long snap) {
|
||||
DeleteEmuBreakpointActionItem action = new DeleteEmuBreakpointActionItem(loc, snap);
|
||||
add(action);
|
||||
return action;
|
||||
}
|
||||
|
||||
+36
-35
@@ -45,15 +45,13 @@ import ghidra.framework.model.*;
|
||||
import ghidra.framework.plugintool.*;
|
||||
import ghidra.framework.plugintool.annotation.AutoServiceConsumed;
|
||||
import ghidra.framework.plugintool.util.PluginStatus;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressRange;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.listing.*;
|
||||
import ghidra.program.util.*;
|
||||
import ghidra.trace.model.*;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpoint;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointLocation;
|
||||
import ghidra.trace.model.program.TraceProgramView;
|
||||
import ghidra.trace.util.TraceAddressSpace;
|
||||
import ghidra.trace.util.TraceEvents;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.datastruct.ListenerSet;
|
||||
@@ -228,7 +226,7 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
|
||||
info.reloadBreakpoints(c);
|
||||
}
|
||||
|
||||
private void breakpointAdded(TraceBreakpoint tb) {
|
||||
private void breakpointAdded(TraceBreakpointLocation tb) {
|
||||
if (!tb.isValid(info.snap)) {
|
||||
return;
|
||||
}
|
||||
@@ -241,7 +239,7 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
|
||||
}
|
||||
}
|
||||
|
||||
private void breakpointChanged(TraceBreakpoint tb) {
|
||||
private void breakpointChanged(TraceBreakpointLocation tb) {
|
||||
if (!tb.isValid(info.snap)) {
|
||||
return;
|
||||
}
|
||||
@@ -258,8 +256,8 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
|
||||
}
|
||||
}
|
||||
|
||||
private void breakpointLifespanChanged(TraceAddressSpace spaceIsNull, TraceBreakpoint tb,
|
||||
Lifespan oldSpan, Lifespan newSpan) {
|
||||
private void breakpointLifespanChanged(AddressSpace spaceIsNull,
|
||||
TraceBreakpointLocation tb, Lifespan oldSpan, Lifespan newSpan) {
|
||||
// NOTE: User/script probably modified historical breakpoint
|
||||
boolean isInOld = oldSpan.contains(info.snap);
|
||||
boolean isInNew = newSpan.contains(info.snap);
|
||||
@@ -280,7 +278,7 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
|
||||
}
|
||||
}
|
||||
|
||||
private void breakpointDeleted(TraceBreakpoint tb) {
|
||||
private void breakpointDeleted(TraceBreakpointLocation tb) {
|
||||
// Could check snap, but might as well just be sure it's gone
|
||||
info.forgetTraceBreakpoint(c.r, tb);
|
||||
}
|
||||
@@ -360,7 +358,8 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
|
||||
long length, Collection<TraceBreakpointKind> kinds);
|
||||
|
||||
protected LogicalBreakpointInternal getOrCreateLogicalBreakpointFor(AddCollector a,
|
||||
Address address, TraceBreakpoint tb, long snap) throws TrackedTooSoonException {
|
||||
Address address, TraceBreakpointLocation tb, long snap)
|
||||
throws TrackedTooSoonException {
|
||||
Set<LogicalBreakpointInternal> set =
|
||||
logicalByAddress.computeIfAbsent(address, __ -> new HashSet<>());
|
||||
for (LogicalBreakpointInternal lb : set) {
|
||||
@@ -377,7 +376,7 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
|
||||
}
|
||||
|
||||
protected boolean removeLogicalBreakpoint(Address address, LogicalBreakpoint lb) {
|
||||
for (TraceBreakpoint tb : lb.getTraceBreakpoints()) {
|
||||
for (TraceBreakpointLocation tb : lb.getTraceBreakpoints()) {
|
||||
InfoPerTrace info = traceInfos.get(tb.getTrace());
|
||||
if (info != null) {
|
||||
info.logicalByBreakpoint.remove(tb);
|
||||
@@ -435,7 +434,8 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
|
||||
}
|
||||
|
||||
protected class InfoPerTrace extends AbstractInfo {
|
||||
final Map<TraceBreakpoint, LogicalBreakpointInternal> logicalByBreakpoint = new HashMap<>();
|
||||
final Map<TraceBreakpointLocation, LogicalBreakpointInternal> logicalByBreakpoint =
|
||||
new HashMap<>();
|
||||
|
||||
final Trace trace;
|
||||
final TraceBreakpointsListener breakpointListener;
|
||||
@@ -486,12 +486,12 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
|
||||
}
|
||||
|
||||
protected void forgetAllBreakpoints(RemoveCollector r) {
|
||||
Collection<TraceBreakpoint> toForget = new ArrayList<>();
|
||||
Collection<TraceBreakpointLocation> toForget = new ArrayList<>();
|
||||
for (AddressRange range : trace.getBaseAddressFactory().getAddressSet()) {
|
||||
toForget.addAll(
|
||||
trace.getBreakpointManager().getBreakpointsIntersecting(Lifespan.ALL, range));
|
||||
}
|
||||
for (TraceBreakpoint tb : toForget) {
|
||||
for (TraceBreakpointLocation tb : toForget) {
|
||||
forgetTraceBreakpoint(r, tb);
|
||||
}
|
||||
}
|
||||
@@ -504,16 +504,16 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
|
||||
*/
|
||||
ControlMode mode = getMode(trace);
|
||||
|
||||
for (Entry<TraceBreakpoint, LogicalBreakpointInternal> ent : Set
|
||||
for (Entry<TraceBreakpointLocation, LogicalBreakpointInternal> ent : Set
|
||||
.copyOf(logicalByBreakpoint.entrySet())) {
|
||||
TraceBreakpoint tb = ent.getKey();
|
||||
TraceBreakpointLocation tb = ent.getKey();
|
||||
LogicalBreakpoint lb = ent.getValue();
|
||||
if (!mode.useEmulatedBreakpoints() &&
|
||||
(target == null || !target.isBreakpointValid(tb))) {
|
||||
forgetTraceBreakpoint(r, tb);
|
||||
continue;
|
||||
}
|
||||
if (!trace.getBreakpointManager().getAllBreakpoints().contains(tb)) {
|
||||
if (!trace.getBreakpointManager().getAllBreakpointLocations().contains(tb)) {
|
||||
forgetTraceBreakpoint(r, tb);
|
||||
continue;
|
||||
}
|
||||
@@ -536,7 +536,7 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
|
||||
if (!mode.useEmulatedBreakpoints() && target == null) {
|
||||
return;
|
||||
}
|
||||
Collection<TraceBreakpoint> visible = new ArrayList<>();
|
||||
Collection<TraceBreakpointLocation> visible = new ArrayList<>();
|
||||
for (AddressRange range : trace.getBaseAddressFactory().getAddressSet()) {
|
||||
visible.addAll(trace.getBreakpointManager()
|
||||
.getBreakpointsIntersecting(Lifespan.at(snap), range));
|
||||
@@ -545,8 +545,8 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
|
||||
}
|
||||
|
||||
protected void trackTraceBreakpoints(AddCollector a,
|
||||
Collection<TraceBreakpoint> breakpoints, ControlMode mode) {
|
||||
for (TraceBreakpoint tb : breakpoints) {
|
||||
Collection<TraceBreakpointLocation> breakpoints, ControlMode mode) {
|
||||
for (TraceBreakpointLocation tb : breakpoints) {
|
||||
try {
|
||||
/**
|
||||
* Sadly, even something as simple as toggling a breakpoint can cause so many
|
||||
@@ -562,7 +562,7 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
|
||||
}
|
||||
}
|
||||
|
||||
protected ProgramLocation computeStaticLocation(TraceBreakpoint tb) {
|
||||
protected ProgramLocation computeStaticLocation(TraceBreakpointLocation tb) {
|
||||
if (traceManager == null || !traceManager.getOpenTraces().contains(tb.getTrace())) {
|
||||
/**
|
||||
* Mapping service will throw an exception otherwise. NB: When trace is opened,
|
||||
@@ -579,7 +579,8 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
|
||||
new DefaultTraceLocation(trace, null, Lifespan.at(snap), minAddress));
|
||||
}
|
||||
|
||||
protected void trackTraceBreakpoint(AddCollector a, TraceBreakpoint tb, ControlMode mode,
|
||||
protected void trackTraceBreakpoint(AddCollector a, TraceBreakpointLocation tb,
|
||||
ControlMode mode,
|
||||
boolean forceUpdate) throws TrackedTooSoonException {
|
||||
if (!mode.useEmulatedBreakpoints() &&
|
||||
(target == null || !target.isBreakpointValid(tb))) {
|
||||
@@ -607,7 +608,7 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
|
||||
}
|
||||
|
||||
protected LogicalBreakpointInternal removeFromLogicalBreakpoint(RemoveCollector r,
|
||||
TraceBreakpoint tb) {
|
||||
TraceBreakpointLocation tb) {
|
||||
LogicalBreakpointInternal lb = logicalByBreakpoint.remove(tb);
|
||||
if (lb == null || !lb.untrackBreakpoint(tb)) {
|
||||
return null;
|
||||
@@ -624,7 +625,7 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
|
||||
return lb;
|
||||
}
|
||||
|
||||
protected void forgetTraceBreakpoint(RemoveCollector r, TraceBreakpoint tb) {
|
||||
protected void forgetTraceBreakpoint(RemoveCollector r, TraceBreakpointLocation tb) {
|
||||
LogicalBreakpointInternal lb = removeFromLogicalBreakpoint(r, tb);
|
||||
if (lb == null) {
|
||||
return; // Warnings already logged
|
||||
@@ -1114,7 +1115,7 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
|
||||
}
|
||||
|
||||
@Override
|
||||
public LogicalBreakpoint getBreakpoint(TraceBreakpoint bpt) {
|
||||
public LogicalBreakpoint getBreakpoint(TraceBreakpointLocation bpt) {
|
||||
Trace trace = bpt.getTrace();
|
||||
synchronized (lock) {
|
||||
InfoPerTrace info = traceInfos.get(trace);
|
||||
@@ -1271,18 +1272,18 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
|
||||
}
|
||||
|
||||
interface TargetBreakpointConsumer {
|
||||
void accept(BreakpointActionSet actions, Target target, TraceBreakpoint tb);
|
||||
void accept(BreakpointActionSet actions, Target target, TraceBreakpointLocation tb);
|
||||
}
|
||||
|
||||
interface EmuBreakpointConsumer {
|
||||
void accept(BreakpointActionSet actions, TraceBreakpoint tb, long snap);
|
||||
void accept(BreakpointActionSet actions, TraceBreakpointLocation tb, long snap);
|
||||
}
|
||||
|
||||
interface ProgramBreakpointConsumer {
|
||||
void accept(LogicalBreakpoint lb);
|
||||
}
|
||||
|
||||
private void planActOnLoc(BreakpointActionSet actions, TraceBreakpoint tb,
|
||||
private void planActOnLoc(BreakpointActionSet actions, TraceBreakpointLocation tb,
|
||||
TargetBreakpointConsumer targetBptConsumer, EmuBreakpointConsumer emuLocConsumer) {
|
||||
ControlMode mode = getMode(tb.getTrace());
|
||||
if (mode.useEmulatedBreakpoints()) {
|
||||
@@ -1293,7 +1294,7 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
|
||||
}
|
||||
}
|
||||
|
||||
private void planActOnLocTarget(BreakpointActionSet actions, TraceBreakpoint tb,
|
||||
private void planActOnLocTarget(BreakpointActionSet actions, TraceBreakpointLocation tb,
|
||||
TargetBreakpointConsumer targetBptConsumer) {
|
||||
Target target = targetService == null ? null : targetService.getTarget(tb.getTrace());
|
||||
if (target == null) {
|
||||
@@ -1302,7 +1303,7 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
|
||||
targetBptConsumer.accept(actions, target, tb);
|
||||
}
|
||||
|
||||
private void planActOnLocEmu(BreakpointActionSet actions, TraceBreakpoint tb,
|
||||
private void planActOnLocEmu(BreakpointActionSet actions, TraceBreakpointLocation tb,
|
||||
EmuBreakpointConsumer emuLocConsumer) {
|
||||
InfoPerTrace info = traceInfos.get(tb.getTrace());
|
||||
if (info == null) {
|
||||
@@ -1312,12 +1313,12 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
|
||||
emuLocConsumer.accept(actions, tb, info.snap);
|
||||
}
|
||||
|
||||
protected CompletableFuture<Void> actOnLocs(Collection<TraceBreakpoint> col,
|
||||
protected CompletableFuture<Void> actOnLocs(Collection<TraceBreakpointLocation> col,
|
||||
TargetBreakpointConsumer targetBptConsumer,
|
||||
EmuBreakpointConsumer emuLocConsumer,
|
||||
ProgramBreakpointConsumer progConsumer) {
|
||||
BreakpointActionSet actions = new BreakpointActionSet();
|
||||
for (TraceBreakpoint tb : col) {
|
||||
for (TraceBreakpointLocation tb : col) {
|
||||
LogicalBreakpoint lb = getBreakpoint(tb);
|
||||
if (col.containsAll(lb.getTraceBreakpoints())) {
|
||||
progConsumer.accept(lb);
|
||||
@@ -1328,19 +1329,19 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> enableLocs(Collection<TraceBreakpoint> col) {
|
||||
public CompletableFuture<Void> enableLocs(Collection<TraceBreakpointLocation> col) {
|
||||
return actOnLocs(col, BreakpointActionSet::planEnableTarget,
|
||||
BreakpointActionSet::planEnableEmu, LogicalBreakpoint::enableForProgram);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> disableLocs(Collection<TraceBreakpoint> col) {
|
||||
public CompletableFuture<Void> disableLocs(Collection<TraceBreakpointLocation> col) {
|
||||
return actOnLocs(col, BreakpointActionSet::planDisableTarget,
|
||||
BreakpointActionSet::planDisableEmu, LogicalBreakpoint::disableForProgram);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> deleteLocs(Collection<TraceBreakpoint> col) {
|
||||
public CompletableFuture<Void> deleteLocs(Collection<TraceBreakpointLocation> col) {
|
||||
return actOnLocs(col, BreakpointActionSet::planDeleteTarget,
|
||||
BreakpointActionSet::planDeleteEmu, lb -> {
|
||||
// Never delete bookmark when user requests deleting locations
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user