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