GP-5194: Remove Deprecated 'Legacy mode' for DBTrace.

This commit is contained in:
Dan 2025-06-27 16:00:08 +00:00
parent 8367ac7354
commit 7e7c8a5e86
312 changed files with 5925 additions and 9830 deletions

View file

@ -21,16 +21,16 @@ import java.util.function.BiFunction;
import java.util.function.Supplier;
import ghidra.debug.api.breakpoint.LogicalBreakpoint;
import ghidra.debug.api.breakpoint.LogicalBreakpointsChangeListener;
import ghidra.debug.api.breakpoint.LogicalBreakpoint.State;
import ghidra.debug.api.breakpoint.LogicalBreakpointsChangeListener;
import ghidra.framework.plugintool.ServiceInfo;
import ghidra.program.model.address.Address;
import ghidra.program.model.listing.Program;
import ghidra.program.util.CodeUnitLocation;
import ghidra.program.util.ProgramLocation;
import ghidra.trace.model.Trace;
import ghidra.trace.model.breakpoint.TraceBreakpoint;
import ghidra.trace.model.breakpoint.TraceBreakpointKind;
import ghidra.trace.model.breakpoint.TraceBreakpointLocation;
import ghidra.trace.model.program.TraceProgramView;
@ServiceInfo(
@ -99,10 +99,10 @@ public interface DebuggerLogicalBreakpointService {
* If the given trace breakpoint is not part of any logical breakpoint, e.g., because the trace
* is not opened in the tool or events are still being processed, then null is returned.
*
* @param bpt the trace breakpoint
* @param loc the trace breakpoint location
* @return the logical breakpoint, or null
*/
LogicalBreakpoint getBreakpoint(TraceBreakpoint bpt);
LogicalBreakpoint getBreakpoint(TraceBreakpointLocation loc);
/**
* Get the collected logical breakpoints (at present) at the given location.
@ -297,10 +297,10 @@ public interface DebuggerLogicalBreakpointService {
*
* <p>
* If the given location refers to a static image, this behaves as in
* {@link #placeBreakpointAt(Program, Address, TraceBreakpointKind)}. If it refers to a trace
* view, this behaves as in {@link #placeBreakpointAt(Trace, Address, TraceBreakpointKind)},
* ignoring the view's current snapshot in favor of the present. The name is only saved for a
* program breakpoint.
* {@link #placeBreakpointAt(Program, Address, long, Collection, String)}. If it refers to a
* trace view, this behaves as in *
* {@link #placeBreakpointAt(Trace, Address, long, Collection, String)}, ignoring the view's
* current snapshot in favor of the present. The name is only saved for a program breakpoint.
*
* @param loc the location
* @param length size of the breakpoint, may be ignored by debugger
@ -348,7 +348,7 @@ public interface DebuggerLogicalBreakpointService {
/**
* Disable a collection of logical breakpoints on target, if applicable
*
* @see #enableAll(Collection)
* @see #enableAll(Collection, Trace)
* @param col the collection
* @param trace a trace, if the command should be limited to the given trace
* @return a future which completes when all associated specifications have been disabled
@ -358,7 +358,7 @@ public interface DebuggerLogicalBreakpointService {
/**
* Delete, if possible, a collection of logical breakpoints on target, if applicable
*
* @see #enableAll(Collection)
* @see #enableAll(Collection, Trace)
* @param col the collection
* @param trace a trace, if the command should be limited to the given trace
* @return a future which completes when all associated specifications have been deleted
@ -371,7 +371,7 @@ public interface DebuggerLogicalBreakpointService {
* @param col the trace breakpoints
* @return a future which completes when the command has been processed
*/
CompletableFuture<Void> enableLocs(Collection<TraceBreakpoint> col);
CompletableFuture<Void> enableLocs(Collection<TraceBreakpointLocation> col);
/**
* Disable the given locations
@ -379,7 +379,7 @@ public interface DebuggerLogicalBreakpointService {
* @param col the trace breakpoints
* @return a future which completes when the command has been processed
*/
CompletableFuture<Void> disableLocs(Collection<TraceBreakpoint> col);
CompletableFuture<Void> disableLocs(Collection<TraceBreakpointLocation> col);
/**
* Delete the given locations
@ -387,7 +387,7 @@ public interface DebuggerLogicalBreakpointService {
* @param col the trace breakpoints
* @return a future which completes when the command has been processed
*/
CompletableFuture<Void> deleteLocs(Collection<TraceBreakpoint> col);
CompletableFuture<Void> deleteLocs(Collection<TraceBreakpointLocation> col);
/**
* Generate an informational message when toggling the breakpoints
@ -397,7 +397,8 @@ public interface DebuggerLogicalBreakpointService {
* is for toggling breakpoints. If the breakpoint set is empty, this should return null, since
* the usual behavior in that case is to prompt to place a new breakpoint.
*
* @see #generateStatusEnable(Collection, Trace))
* @see #generateStatusEnable(Collection, Trace)
* @param bs the set of logical breakpoints
* @param loc a representative location
* @return the status message, or null
*/
@ -407,12 +408,12 @@ public interface DebuggerLogicalBreakpointService {
* Generate an informational message when toggling the breakpoints at the given location
*
* <p>
* This works in the same manner as {@link #generateStatusEnable(Collection, Trace))}, except it
* This works in the same manner as {@link #generateStatusEnable(Collection, Trace)}, except it
* is for toggling breakpoints at a given location. If there are no breakpoints at the location,
* this should return null, since the usual behavior in that case is to prompt to place a new
* breakpoint.
*
* @see #generateStatusEnable(Collection)
* @see #generateStatusEnable(Collection, Trace)
* @param loc the location
* @return the status message, or null
*/

View file

@ -18,11 +18,11 @@ package ghidra.debug.api.action;
import ghidra.debug.api.tracemgr.DebuggerCoordinates;
import ghidra.framework.plugintool.ServiceProvider;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSpace;
import ghidra.program.util.ProgramLocation;
import ghidra.trace.model.TraceAddressSnapRange;
import ghidra.trace.model.guest.TracePlatform;
import ghidra.trace.model.stack.TraceStack;
import ghidra.trace.util.TraceAddressSpace;
/**
* The actual tracking logic for a location tracking spec
@ -73,8 +73,8 @@ public interface LocationTracker {
* @param coordinates the provider's current coordinates
* @return true if re-computation and "goto" is warranted
*/
boolean affectedByBytesChange(TraceAddressSpace space,
TraceAddressSnapRange range, DebuggerCoordinates coordinates);
boolean affectedByBytesChange(AddressSpace space, TraceAddressSnapRange range,
DebuggerCoordinates coordinates);
/**
* Check if the address should be recomputed given the indicated stack change

View file

@ -20,9 +20,8 @@ import javax.swing.Icon;
import ghidra.debug.api.tracemgr.DebuggerCoordinates;
import ghidra.framework.options.SaveState;
import ghidra.framework.plugintool.AutoConfigState.ConfigFieldCodec;
import ghidra.program.model.address.AddressSpace;
import ghidra.trace.model.TraceAddressSnapRange;
import ghidra.trace.model.memory.TraceMemorySpace;
import ghidra.trace.util.TraceAddressSpace;
/**
* A specification for automatic navigation of the dynamic listing
@ -67,21 +66,13 @@ public interface LocationTrackingSpec {
* @param current the current coordinates
* @return true if the change affects the tracked address for the given coordinates
*/
static boolean changeIsCurrent(TraceAddressSpace space, TraceAddressSnapRange range,
static boolean changeIsCurrent(AddressSpace space, TraceAddressSnapRange range,
DebuggerCoordinates current) {
if (space == null) {
return false;
}
if (!space.getAddressSpace().isMemorySpace()) {
if (current.getThread() == null) {
return false;
}
TraceMemorySpace memSpace = current.getTrace()
.getMemoryManager()
.getMemoryRegisterSpace(current.getThread(), current.getFrame(), false);
if (memSpace == null || memSpace.getAddressSpace() != space.getAddressSpace()) {
return false;
}
if (!space.isMemorySpace() && !current.isRegisterSpace(space)) {
return false;
}
if (!range.getLifespan().contains(current.getSnap())) {
return false;

View file

@ -28,8 +28,8 @@ import ghidra.program.model.listing.Bookmark;
import ghidra.program.model.listing.Program;
import ghidra.program.util.ProgramLocation;
import ghidra.trace.model.Trace;
import ghidra.trace.model.breakpoint.TraceBreakpoint;
import ghidra.trace.model.breakpoint.TraceBreakpointKind;
import ghidra.trace.model.breakpoint.TraceBreakpointLocation;
import resources.MultiIcon;
/**
@ -471,6 +471,8 @@ public interface LogicalBreakpoint {
*/
INCONSISTENT_MIXED(Mode.MIXED, Consistency.INCONSISTENT, NAME_MARKER_INCON_MIX, ICON_MARKER_INCON_MIX);
public static final List<State> VALUES = List.of(values());
public final Mode mode;
public final Consistency consistency;
public final String display;
@ -658,7 +660,7 @@ public interface LogicalBreakpoint {
* Get the sleigh injection when emulating this breakpoint
*
* @return the sleigh injection
* @see TraceBreakpoint#getEmuSleigh()
* @see TraceBreakpointLocation#getEmuSleigh(long)
*/
String getEmuSleigh();
@ -666,7 +668,7 @@ public interface LogicalBreakpoint {
* Set the sleigh injection when emulating this breakpoint
*
* @param sleigh the sleigh injection
* @see TraceBreakpoint#setEmuSleigh(String)
* @see TraceBreakpointLocation#setEmuSleigh(long,String)
*/
void setEmuSleigh(String sleigh);
@ -699,7 +701,7 @@ public interface LogicalBreakpoint {
*
* @return the set of trace breakpoints
*/
Set<TraceBreakpoint> getTraceBreakpoints();
Set<TraceBreakpointLocation> getTraceBreakpoints();
/**
* Get all trace breakpoints for the given trace which map to this logical breakpoint.
@ -707,15 +709,15 @@ public interface LogicalBreakpoint {
* @param trace the trace
* @return the set of trace breakpoints
*/
Set<TraceBreakpoint> getTraceBreakpoints(Trace trace);
Set<TraceBreakpointLocation> getTraceBreakpoints(Trace trace);
/**
* Get the traces for which this logical breakpoint has an address.
*
* <p>
* Note, this does not necessarily indicate that a {@link TraceBreakpoint} is present for each
* trace, but rather that for each returned trace, the logical breakpoint can be mapped to an
* address in that trace. See {@link #getParticipatingTraces()}.
* Note, this does not necessarily indicate that a {@link TraceBreakpointLocation} is present
* for each trace, but rather that for each returned trace, the logical breakpoint can be mapped
* to an address in that trace. See {@link #getParticipatingTraces()}.
*
* @return a copy of the set of traces
*/
@ -725,8 +727,8 @@ public interface LogicalBreakpoint {
* Get the traces for which this logical breakpoint has a trace breakpoint.
*
* <p>
* Note, unlike {@link #getMappedTraces()}, this does indicate that a {@link TraceBreakpoint} is
* present for each trace.
* Note, unlike {@link #getMappedTraces()}, this does indicate that a
* {@link TraceBreakpointLocation} is present for each trace.
*
* @return the set of traces
*/
@ -779,7 +781,7 @@ public interface LogicalBreakpoint {
* @param loc the location
* @return the state
*/
State computeStateForLocation(TraceBreakpoint loc);
State computeStateForLocation(TraceBreakpointLocation loc);
/**
* Compute the state for all involved traces and program.

View file

@ -17,7 +17,7 @@ package ghidra.debug.api.breakpoint;
import java.util.Collection;
import ghidra.trace.model.breakpoint.TraceBreakpoint;
import ghidra.trace.model.breakpoint.TraceBreakpointLocation;
public interface LogicalBreakpointsChangeListener {
default void breakpointAdded(LogicalBreakpoint added) {
@ -47,12 +47,12 @@ public interface LogicalBreakpointsChangeListener {
}
}
default void locationAdded(TraceBreakpoint added) {
default void locationAdded(TraceBreakpointLocation added) {
}
default void locationUpdated(TraceBreakpoint updated) {
default void locationUpdated(TraceBreakpointLocation updated) {
}
default void locationRemoved(TraceBreakpoint removed) {
default void locationRemoved(TraceBreakpointLocation removed) {
}
}

View file

@ -29,8 +29,7 @@ import ghidra.program.model.lang.Register;
import ghidra.program.model.lang.RegisterValue;
import ghidra.trace.model.Trace;
import ghidra.trace.model.TraceExecutionState;
import ghidra.trace.model.breakpoint.TraceBreakpoint;
import ghidra.trace.model.breakpoint.TraceBreakpointKind;
import ghidra.trace.model.breakpoint.*;
import ghidra.trace.model.guest.TracePlatform;
import ghidra.trace.model.memory.TraceMemoryState;
import ghidra.trace.model.stack.TraceStackFrame;
@ -617,12 +616,12 @@ public interface Target {
* @param breakpoint the breakpoint
* @return true if valid
*/
boolean isBreakpointValid(TraceBreakpoint breakpoint);
boolean isBreakpointValid(TraceBreakpointLocation breakpoint);
/**
* @see #deleteBreakpoint(TraceBreakpoint)
* @see #deleteBreakpoint(TraceBreakpointCommon)
*/
CompletableFuture<Void> deleteBreakpointAsync(TraceBreakpoint breakpoint);
CompletableFuture<Void> deleteBreakpointAsync(TraceBreakpointCommon breakpoint);
/**
* Delete the given breakpoint from the target
@ -633,12 +632,13 @@ public interface Target {
*
* @param breakpoint the breakpoint to delete
*/
void deleteBreakpoint(TraceBreakpoint breakpoint);
void deleteBreakpoint(TraceBreakpointCommon breakpoint);
/**
* @see #toggleBreakpoint(TraceBreakpoint, boolean)
* @see #toggleBreakpoint(TraceBreakpointLocation, boolean)
*/
CompletableFuture<Void> toggleBreakpointAsync(TraceBreakpoint breakpoint, boolean enabled);
CompletableFuture<Void> toggleBreakpointAsync(TraceBreakpointCommon breakpoint,
boolean enabled);
/**
* Toggle the given breakpoint on the target
@ -651,7 +651,7 @@ public interface Target {
* @param breakpoint the breakpoint to toggle
* @param enabled true to enable, false to disable
*/
void toggleBreakpoint(TraceBreakpoint breakpoint, boolean enabled);
void toggleBreakpoint(TraceBreakpointCommon breakpoint, boolean enabled);
/**
* @see #forceTerminate()

View file

@ -27,15 +27,16 @@ import ghidra.framework.model.*;
import ghidra.framework.options.SaveState;
import ghidra.framework.plugintool.PluginTool;
import ghidra.framework.store.LockException;
import ghidra.program.model.address.AddressSpace;
import ghidra.trace.database.DBTraceContentHandler;
import ghidra.trace.model.Lifespan;
import ghidra.trace.model.Trace;
import ghidra.trace.model.guest.TracePlatform;
import ghidra.trace.model.program.TraceProgramView;
import ghidra.trace.model.stack.*;
import ghidra.trace.model.stack.TraceStack;
import ghidra.trace.model.stack.TraceStackFrame;
import ghidra.trace.model.target.TraceObject;
import ghidra.trace.model.target.path.KeyPath;
import ghidra.trace.model.thread.TraceObjectThread;
import ghidra.trace.model.thread.TraceThread;
import ghidra.trace.model.time.TraceSnapshot;
import ghidra.trace.model.time.schedule.TraceSchedule;
@ -315,36 +316,34 @@ public class DebuggerCoordinates {
return thread(trace.getThreadManager().getThread(thread.getKey()));
}
private static KeyPath resolvePath(TraceThread thread, Integer frameLevel,
TraceSchedule time) {
if (thread instanceof TraceObjectThread tot) {
TraceObject objThread = tot.getObject();
if (frameLevel == null) {
return objThread.getCanonicalPath();
}
TraceStack stack;
long snap = time.getSnap();
try {
stack = thread.getTrace().getStackManager().getStack(thread, snap, false);
}
catch (IllegalStateException e) {
// Schema does not specify a stack
return objThread.getCanonicalPath();
}
if (stack == null) {
return objThread.getCanonicalPath();
}
TraceStackFrame frame = stack.getFrame(snap, frameLevel, false);
if (frame == null) {
return objThread.getCanonicalPath();
}
return ((TraceObjectStackFrame) frame).getObject().getCanonicalPath();
private static KeyPath resolvePath(TraceThread thread, Integer frameLevel, TraceSchedule time) {
if (thread == null) {
return KeyPath.of();
}
return null;
TraceObject objThread = thread.getObject();
if (frameLevel == null) {
return objThread.getCanonicalPath();
}
TraceStack stack;
long snap = time.getSnap();
try {
stack = thread.getTrace().getStackManager().getStack(thread, snap, false);
}
catch (IllegalStateException e) {
// Schema does not specify a stack
return objThread.getCanonicalPath();
}
if (stack == null) {
return objThread.getCanonicalPath();
}
TraceStackFrame frame = stack.getFrame(snap, frameLevel, false);
if (frame == null) {
return objThread.getCanonicalPath();
}
return frame.getObject().getCanonicalPath();
}
private static KeyPath choose(KeyPath curPath,
KeyPath newPath) {
private static KeyPath choose(KeyPath curPath, KeyPath newPath) {
if (curPath == null) {
return newPath;
}
@ -525,9 +524,7 @@ public class DebuggerCoordinates {
if (object == null) {
return null;
}
return object.queryCanonicalAncestorsInterface(TraceObjectThread.class)
.findFirst()
.orElse(null);
return object.queryCanonicalAncestorsInterface(TraceThread.class).findFirst().orElse(null);
}
private static Integer resolveFrame(Trace trace, KeyPath path) {
@ -535,10 +532,9 @@ public class DebuggerCoordinates {
if (object == null) {
return null;
}
TraceObjectStackFrame frame =
object.queryCanonicalAncestorsInterface(TraceObjectStackFrame.class)
.findFirst()
.orElse(null);
TraceStackFrame frame = object.queryCanonicalAncestorsInterface(TraceStackFrame.class)
.findFirst()
.orElse(null);
return frame == null ? null : frame.getLevel();
}
@ -669,6 +665,11 @@ public class DebuggerCoordinates {
return registerContainer = object.findRegisterContainer(getFrame());
}
public boolean isRegisterSpace(AddressSpace space) {
TraceObject container = getRegisterContainer();
return container != null && container.getCanonicalPath().toString().equals(space.getName());
}
public synchronized long getViewSnap() {
if (viewSnap != null) {
return viewSnap;

View file

@ -53,7 +53,6 @@ import ghidra.trace.model.program.TraceProgramView;
import ghidra.trace.model.target.TraceObject;
import ghidra.trace.model.target.TraceObjectValue;
import ghidra.trace.model.target.path.KeyPath;
import ghidra.trace.model.thread.TraceObjectThread;
import ghidra.trace.model.thread.TraceThread;
import ghidra.trace.model.time.schedule.TraceSchedule;
import ghidra.util.MathUtilities;
@ -1452,11 +1451,7 @@ public interface FlatDebuggerAPI {
}
default ActionContext createContext(TraceThread thread) {
if (thread instanceof TraceObjectThread objThread) {
return createContext(objThread.getObject());
}
return new DebuggerSingleObjectPathActionContext(
KeyPath.parse(thread.getPath()));
return createContext(thread.getObject());
}
default ActionContext createContext(Trace trace) {

View file

@ -21,7 +21,7 @@ import java.util.Map;
import com.sun.jdi.*;
import ghidra.app.plugin.core.debug.client.tracermi.*;
import ghidra.app.plugin.core.debug.client.tracermi.RmiMethodRegistry.TraceMethod;
import ghidra.app.plugin.core.debug.client.tracermi.RmiMethodRegistry.TraceRmiMethod;
import ghidra.dbg.jdi.manager.impl.DebugStatus;
import ghidra.dbg.jdi.manager.impl.JdiManagerImpl;
import ghidra.program.model.address.*;
@ -144,7 +144,7 @@ public class JdiConnector {
}
public void registerRemoteMethod(JdiMethods methods, java.lang.reflect.Method m, String name) {
TraceMethod annot = m.getAnnotation(TraceMethod.class);
TraceRmiMethod annot = m.getAnnotation(TraceRmiMethod.class);
if (annot == null) {
return;
}

View file

@ -24,11 +24,11 @@ import com.sun.jdi.*;
import com.sun.jdi.request.*;
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.program.model.address.Address;
import ghidra.program.model.address.AddressRange;
import ghidra.rmi.trace.TraceRmi.MemoryState;
import ghidra.trace.model.target.iface.TraceObjectMethod.Param;
import ghidra.trace.model.target.iface.TraceMethod.Param;
import ghidra.util.Msg;
public class JdiMethods implements RmiMethods {
@ -45,14 +45,14 @@ public class JdiMethods implements RmiMethods {
public void registerMethods() {
Class<?> cls = this.getClass();
for (java.lang.reflect.Method m : cls.getMethods()) {
TraceMethod annot = m.getAnnotation(TraceMethod.class);
TraceRmiMethod annot = m.getAnnotation(TraceRmiMethod.class);
if (annot != null) {
connector.registerRemoteMethod(this, m, m.getName());
}
}
}
@TraceMethod(action = "refresh", display = "Refresh VM")
@TraceRmiMethod(action = "refresh", display = "Refresh VM")
public void refresh_vm(@Param(schema = "VirtualMachine", name = "vm") RmiTraceObject obj) {
try (RmiTransaction tx = cmds.state.trace.openTx("RefreshVM")) {
String path = obj.getPath();
@ -61,7 +61,7 @@ public class JdiMethods implements RmiMethods {
}
}
@TraceMethod(action = "refresh", display = "Refresh process")
@TraceRmiMethod(action = "refresh", display = "Refresh process")
public void refresh_process(
@Param(schema = "ProcessRef", name = "process") RmiTraceObject obj) {
try (RmiTransaction tx = cmds.state.trace.openTx("RefreshProcess")) {
@ -71,7 +71,7 @@ public class JdiMethods implements RmiMethods {
}
}
@TraceMethod(action = "refresh", display = "Refresh thread groups")
@TraceRmiMethod(action = "refresh", display = "Refresh thread groups")
public void refresh_thread_groups(
@Param(
schema = "ThreadGroupReferenceContainer",
@ -89,7 +89,7 @@ public class JdiMethods implements RmiMethods {
}
}
@TraceMethod(action = "refresh", display = "Refresh thread group")
@TraceRmiMethod(action = "refresh", display = "Refresh thread group")
public void refresh_thread_group_proxy(
@Param(schema = "ThreadGroupReferenceProxy", name = "proxy") RmiTraceObject obj) {
try (RmiTransaction tx = cmds.state.trace.openTx("RefreshThreadGroup")) {
@ -105,7 +105,7 @@ public class JdiMethods implements RmiMethods {
}
}
@TraceMethod(action = "refresh", display = "Refresh thread group")
@TraceRmiMethod(action = "refresh", display = "Refresh thread group")
public void refresh_thread_group(
@Param(schema = "ThreadGroupReference", name = "group") RmiTraceObject obj) {
try (RmiTransaction tx = cmds.state.trace.openTx("RefreshThreadGroup")) {
@ -115,7 +115,7 @@ public class JdiMethods implements RmiMethods {
}
}
@TraceMethod(action = "refresh", display = "Refresh threads")
@TraceRmiMethod(action = "refresh", display = "Refresh threads")
public void refresh_threads(
@Param(schema = "ThreadContainer", name = "container") RmiTraceObject obj) {
try (RmiTransaction tx = cmds.state.trace.openTx("RefreshThreads")) {
@ -126,7 +126,7 @@ public class JdiMethods implements RmiMethods {
}
}
@TraceMethod(action = "refresh", display = "Refresh threads")
@TraceRmiMethod(action = "refresh", display = "Refresh threads")
public void refresh_threadrefs(
@Param(schema = "ThreadReferenceContainer", name = "container") RmiTraceObject obj) {
try (RmiTransaction tx = cmds.state.trace.openTx("RefreshThreads")) {
@ -147,7 +147,7 @@ public class JdiMethods implements RmiMethods {
}
}
@TraceMethod(action = "refresh", display = "Refresh thread")
@TraceRmiMethod(action = "refresh", display = "Refresh thread")
public void refresh_thread(@Param(schema = "Thread", name = "thread") RmiTraceObject obj) {
try (RmiTransaction tx = cmds.state.trace.openTx("RefreshThread")) {
String path = obj.getPath();
@ -156,14 +156,14 @@ public class JdiMethods implements RmiMethods {
}
}
@TraceMethod(action = "refresh", display = "Refresh stack")
@TraceRmiMethod(action = "refresh", display = "Refresh stack")
public void refresh_stack(@Param(schema = "Stack", name = "stack") RmiTraceObject obj) {
try (RmiTransaction tx = cmds.state.trace.openTx("RefreshStack")) {
cmds.ghidraTracePutFrames();
}
}
@TraceMethod(action = "refresh", display = "Refresh registers")
@TraceRmiMethod(action = "refresh", display = "Refresh registers")
public void refresh_registers(
@Param(schema = "RegisterContainer", name = "container") RmiTraceObject obj) {
try (RmiTransaction tx = cmds.state.trace.openTx("RefreshRegisters")) {
@ -171,7 +171,7 @@ public class JdiMethods implements RmiMethods {
}
}
@TraceMethod(action = "refresh", display = "Refresh modules")
@TraceRmiMethod(action = "refresh", display = "Refresh modules")
public void refresh_modules(
@Param(schema = "ModuleReferenceContainer", name = "container") RmiTraceObject obj) {
try (RmiTransaction tx = cmds.state.trace.openTx("RefreshModules")) {
@ -179,7 +179,7 @@ public class JdiMethods implements RmiMethods {
}
}
@TraceMethod(action = "refresh", display = "Refresh module")
@TraceRmiMethod(action = "refresh", display = "Refresh module")
public void refresh_module(
@Param(schema = "ModuleReference", name = "module") RmiTraceObject obj) {
try (RmiTransaction tx = cmds.state.trace.openTx("RefreshModule")) {
@ -189,7 +189,7 @@ public class JdiMethods implements RmiMethods {
}
}
@TraceMethod(action = "refresh", display = "Refresh monitor info")
@TraceRmiMethod(action = "refresh", display = "Refresh monitor info")
public void refresh_monitors(
@Param(schema = "MonitorInfoContainer", name = "container") RmiTraceObject obj) {
try (RmiTransaction tx = cmds.state.trace.openTx("RefreshMonitorInfo")) {
@ -203,7 +203,7 @@ public class JdiMethods implements RmiMethods {
}
}
@TraceMethod(action = "refresh", display = "Refresh monitor info")
@TraceRmiMethod(action = "refresh", display = "Refresh monitor info")
public void refresh_monitor_info(
@Param(schema = "MonitorInfo", name = "monitor_info") RmiTraceObject obj) {
try (RmiTransaction tx = cmds.state.trace.openTx("RefreshMonitorInfo")) {
@ -213,13 +213,13 @@ public class JdiMethods implements RmiMethods {
}
}
@TraceMethod(action = "refresh", display = "Refresh fields")
@TraceRmiMethod(action = "refresh", display = "Refresh fields")
public void refresh_canonical_fields(
@Param(schema = "CanonicalFieldContainer", name = "container") RmiTraceObject obj) {
refresh_fields(obj);
}
@TraceMethod(action = "refresh", display = "Refresh fields")
@TraceRmiMethod(action = "refresh", display = "Refresh fields")
public void refresh_fields(
@Param(schema = "FieldContainer", name = "container") RmiTraceObject obj) {
try (RmiTransaction tx = cmds.state.trace.openTx("RefreshFields")) {
@ -235,7 +235,7 @@ public class JdiMethods implements RmiMethods {
}
}
@TraceMethod(action = "refresh", display = "Refresh objects")
@TraceRmiMethod(action = "refresh", display = "Refresh objects")
public void refresh_objects(
@Param(schema = "ObjectReferenceContainer", name = "container") RmiTraceObject obj) {
try (RmiTransaction tx = cmds.state.trace.openTx("RefreshObjects")) {
@ -261,7 +261,7 @@ public class JdiMethods implements RmiMethods {
}
}
@TraceMethod(action = "refresh", display = "Refresh object")
@TraceRmiMethod(action = "refresh", display = "Refresh object")
public void refresh_object_proxy(
@Param(schema = "ObjectReferenceProxy", name = "proxy") RmiTraceObject obj) {
try (RmiTransaction tx = cmds.state.trace.openTx("RefreshObject")) {
@ -283,7 +283,7 @@ public class JdiMethods implements RmiMethods {
}
}
@TraceMethod(action = "refresh", display = "Refresh object")
@TraceRmiMethod(action = "refresh", display = "Refresh object")
public void refresh_object(
@Param(schema = "ObjectReference", name = "object") RmiTraceObject obj) {
try (RmiTransaction tx = cmds.state.trace.openTx("RefreshInstance")) {
@ -293,13 +293,13 @@ public class JdiMethods implements RmiMethods {
}
}
@TraceMethod(action = "refresh", display = "Refresh methods")
@TraceRmiMethod(action = "refresh", display = "Refresh methods")
public void refresh_canonical_methods(
@Param(schema = "CanonicalMethodContainer", name = "container") RmiTraceObject obj) {
refresh_methods(obj);
}
@TraceMethod(action = "refresh", display = "Refresh methods")
@TraceRmiMethod(action = "refresh", display = "Refresh methods")
public void refresh_methods(
@Param(schema = "MethodContainer", name = "container") RmiTraceObject obj) {
try (RmiTransaction tx = cmds.state.trace.openTx("RefreshMethods")) {
@ -310,7 +310,7 @@ public class JdiMethods implements RmiMethods {
}
}
@TraceMethod(action = "refresh", display = "Refresh method")
@TraceRmiMethod(action = "refresh", display = "Refresh method")
public void refresh_method(@Param(schema = "Method", name = "method") RmiTraceObject obj) {
try (RmiTransaction tx = cmds.state.trace.openTx("RefreshMethod")) {
String path = obj.getPath();
@ -319,7 +319,7 @@ public class JdiMethods implements RmiMethods {
}
}
@TraceMethod(action = "refresh", display = "Refresh arguments")
@TraceRmiMethod(action = "refresh", display = "Refresh arguments")
public void refresh_arguments(
@Param(schema = "ArgumentContainer", name = "container") RmiTraceObject obj) {
try (RmiTransaction tx = cmds.state.trace.openTx("RefreshArguments")) {
@ -330,7 +330,7 @@ public class JdiMethods implements RmiMethods {
}
}
@TraceMethod(display = "Load class")
@TraceRmiMethod(display = "Load class")
public boolean find_canonical_class(
@Param(
schema = "CanonicalReferenceTypeContainer",
@ -344,7 +344,7 @@ public class JdiMethods implements RmiMethods {
return find_class(obj, targetClass);
}
@TraceMethod(display = "Load class")
@TraceRmiMethod(display = "Load class")
public boolean find_class(
@Param(
schema = "ReferenceTypeContainer",
@ -370,12 +370,12 @@ public class JdiMethods implements RmiMethods {
* NB. Did not assign action="refresh" because this method is expensive. Assigning that action
* name will cause the UI to do it upon expanding the node, which we <em>do not</em> want.
*/
@TraceMethod(display = "Refresh memory")
@TraceRmiMethod(display = "Refresh memory")
public void refresh_memory(@Param(schema = "Memory", name = "memory") RmiTraceObject obj) {
refresh_reference_types(obj);
}
@TraceMethod(display = "Refresh reference types")
@TraceRmiMethod(display = "Refresh reference types")
public void refresh_canonical_reference_types(
@Param(
schema = "CanonicalReferenceTypeContainer",
@ -387,7 +387,7 @@ public class JdiMethods implements RmiMethods {
* NB. Did not assign action="refresh" because this method is expensive. Assigning that action
* name will cause the UI to do it upon expanding the node, which we <em>do not</em> want.
*/
@TraceMethod(display = "Refresh reference types")
@TraceRmiMethod(display = "Refresh reference types")
public void refresh_reference_types(
@Param(schema = "ReferenceTypeContainer", name = "container") RmiTraceObject obj) {
try (RmiTransaction tx = cmds.state.trace.openTx("RefreshReferenceTypes")) {
@ -430,7 +430,7 @@ public class JdiMethods implements RmiMethods {
}
}
@TraceMethod(action = "refresh", display = "Refresh reference type")
@TraceRmiMethod(action = "refresh", display = "Refresh reference type")
public void refresh_reference_type_proxy(
@Param(schema = "ReferenceTypeProxy", name = "proxy") RmiTraceObject obj) {
try (RmiTransaction tx = cmds.state.trace.openTx("RefreshReferenceType")) {
@ -452,13 +452,13 @@ public class JdiMethods implements RmiMethods {
}
}
@TraceMethod(action = "refresh", display = "Refresh reference type")
@TraceRmiMethod(action = "refresh", display = "Refresh reference type")
public void refresh_canonical_reference_type(
@Param(schema = "CanonicalReferenceType", name = "container") RmiTraceObject obj) {
refresh_reference_type(obj);
}
@TraceMethod(action = "refresh", display = "Refresh reference type")
@TraceRmiMethod(action = "refresh", display = "Refresh reference type")
public void refresh_reference_type(
@Param(schema = "ReferenceType", name = "reference_type") RmiTraceObject obj) {
try (RmiTransaction tx = cmds.state.trace.openTx("RefreshReferenceType")) {
@ -468,7 +468,7 @@ public class JdiMethods implements RmiMethods {
}
}
@TraceMethod(display = "Load reference type")
@TraceRmiMethod(display = "Load reference type")
public void load_reftype(
@Param(schema = "ReferenceType", name = "reference_type") RmiTraceObject obj) {
try (RmiTransaction tx = cmds.state.trace.openTx("RefreshReferenceType")) {
@ -480,13 +480,13 @@ public class JdiMethods implements RmiMethods {
}
}
@TraceMethod(action = "refresh", display = "Refresh variables")
@TraceRmiMethod(action = "refresh", display = "Refresh variables")
public void refresh_canonical_variables(
@Param(schema = "CanonicalVariableContainer", name = "container") RmiTraceObject obj) {
refresh_variables(obj);
}
@TraceMethod(action = "refresh", display = "Refresh variables")
@TraceRmiMethod(action = "refresh", display = "Refresh variables")
public void refresh_variables(
@Param(schema = "VariableContainer", name = "container") RmiTraceObject obj) {
try (RmiTransaction tx = cmds.state.trace.openTx("RefreshVariables")) {
@ -513,7 +513,7 @@ public class JdiMethods implements RmiMethods {
}
}
@TraceMethod(action = "refresh", display = "Refresh variable")
@TraceRmiMethod(action = "refresh", display = "Refresh variable")
public void refresh_variable(
@Param(schema = "Variable", name = "variable") RmiTraceObject obj) {
try (RmiTransaction tx = cmds.state.trace.openTx("RefreshVariable")) {
@ -525,7 +525,7 @@ public class JdiMethods implements RmiMethods {
}
}
@TraceMethod(action = "refresh", display = "Refresh locations")
@TraceRmiMethod(action = "refresh", display = "Refresh locations")
public void refresh_locations(
@Param(schema = "LocationContainer", name = "container") RmiTraceObject obj) {
try (RmiTransaction tx = cmds.state.trace.openTx("RefreshLocations")) {
@ -543,7 +543,7 @@ public class JdiMethods implements RmiMethods {
}
}
@TraceMethod(action = "refresh", display = "Refresh location")
@TraceRmiMethod(action = "refresh", display = "Refresh location")
public void refresh_location(
@Param(schema = "Location", name = "location") RmiTraceObject obj) {
try (RmiTransaction tx = cmds.state.trace.openTx("RefreshLocation")) {
@ -553,7 +553,7 @@ public class JdiMethods implements RmiMethods {
}
}
@TraceMethod(action = "refresh", display = "Refresh breakpoints")
@TraceRmiMethod(action = "refresh", display = "Refresh breakpoints")
public void refresh_breakpoints(
@Param(schema = "BreakpointContainer", name = "container") RmiTraceObject obj) {
try (RmiTransaction tx = cmds.state.trace.openTx("RefreshBreakpoints")) {
@ -561,7 +561,7 @@ public class JdiMethods implements RmiMethods {
}
}
@TraceMethod(action = "refresh", display = "Refresh events")
@TraceRmiMethod(action = "refresh", display = "Refresh events")
public void refresh_events(
@Param(schema = "EventContainer", name = "container") RmiTraceObject obj) {
try (RmiTransaction tx = cmds.state.trace.openTx("RefreshEvents")) {
@ -569,7 +569,7 @@ public class JdiMethods implements RmiMethods {
}
}
@TraceMethod(action = "refresh", display = "Refresh values")
@TraceRmiMethod(action = "refresh", display = "Refresh values")
public void refresh_values(
@Param(schema = "ValueContainer", name = "container") RmiTraceObject obj) {
try (RmiTransaction tx = cmds.state.trace.openTx("RefreshValues")) {
@ -582,7 +582,7 @@ public class JdiMethods implements RmiMethods {
}
}
@TraceMethod(action = "refresh", display = "Refresh value")
@TraceRmiMethod(action = "refresh", display = "Refresh value")
public void refresh_value(@Param(schema = "Value", name = "value") RmiTraceObject obj) {
try (RmiTransaction tx = cmds.state.trace.openTx("RefreshLocation")) {
String path = obj.getPath();
@ -591,7 +591,7 @@ public class JdiMethods implements RmiMethods {
}
}
@TraceMethod(display = "Set value")
@TraceRmiMethod(display = "Set value")
public void set_value_lvar(
@Param(
schema = "Variable",
@ -609,7 +609,7 @@ public class JdiMethods implements RmiMethods {
}
}
@TraceMethod(display = "Set value")
@TraceRmiMethod(display = "Set value")
public void set_value_field(
@Param(
schema = "Field",
@ -627,7 +627,7 @@ public class JdiMethods implements RmiMethods {
}
}
@TraceMethod(action = "activate", display = "Activate")
@TraceRmiMethod(action = "activate", display = "Activate")
public void activate(@Param(schema = "OBJECT", name = "object") RmiTraceObject obj) {
try (RmiTransaction tx = cmds.state.trace.openTx("Activate")) {
String path = obj.getPath();
@ -635,7 +635,7 @@ public class JdiMethods implements RmiMethods {
}
}
@TraceMethod(action = "kill", display = "Terminate")
@TraceRmiMethod(action = "kill", display = "Terminate")
public void kill(@Param(schema = "VirtualMachine", name = "vm") RmiTraceObject obj) {
VirtualMachine vm = (VirtualMachine) getObjectFromPath(obj.getPath());
vm.exit(143);
@ -647,28 +647,28 @@ public class JdiMethods implements RmiMethods {
}
}
@TraceMethod(action = "resume", display = "Resume")
@TraceRmiMethod(action = "resume", display = "Resume")
public void resume_vm(@Param(schema = "VirtualMachine", name = "vm") RmiTraceObject obj) {
VirtualMachine vm = (VirtualMachine) getObjectFromPath(obj.getPath());
vm.resume();
connector.getHooks().setState(vm);
}
@TraceMethod(action = "resume", display = "Resume")
@TraceRmiMethod(action = "resume", display = "Resume")
public void resume_thread(@Param(schema = "Thread", name = "thread") RmiTraceObject obj) {
ThreadReference thread = (ThreadReference) getObjectFromPath(obj.getPath());
thread.resume();
connector.getHooks().setState(thread.virtualMachine());
}
@TraceMethod(action = "interrupt", display = "Suspend")
@TraceRmiMethod(action = "interrupt", display = "Suspend")
public void suspend_vm(@Param(schema = "VirtualMachine", name = "vm") RmiTraceObject obj) {
VirtualMachine vm = (VirtualMachine) getObjectFromPath(obj.getPath());
vm.suspend();
connector.getHooks().setState(vm);
}
@TraceMethod(action = "interrupt", display = "Suspend")
@TraceRmiMethod(action = "interrupt", display = "Suspend")
public void suspend_thread(@Param(schema = "Thread", name = "thread") RmiTraceObject obj) {
ThreadReference thread = (ThreadReference) getObjectFromPath(obj.getPath());
thread.suspend();
@ -679,7 +679,7 @@ public class JdiMethods implements RmiMethods {
* NB: For the VirtualMachine, the step methods add requests for break-on-step for all threads.
* These requests will remain pending until the VM is resumed.
*/
@TraceMethod(action = "step_into", display = "Step into")
@TraceRmiMethod(action = "step_into", display = "Step into")
public void step_vm_into(@Param(schema = "VirtualMachine", name = "vm") RmiTraceObject obj) {
VirtualMachine vm = connector.getJdi().getCurrentVM();
List<ThreadReference> threads = getThreadsFromValue(obj);
@ -697,7 +697,7 @@ public class JdiMethods implements RmiMethods {
vm.resume();
}
@TraceMethod(action = "step_over", display = "Step over")
@TraceRmiMethod(action = "step_over", display = "Step over")
public void step_vm_over(@Param(schema = "VirtualMachine", name = "vm") RmiTraceObject obj) {
VirtualMachine vm = connector.getJdi().getCurrentVM();
List<ThreadReference> threads = getThreadsFromValue(obj);
@ -715,7 +715,7 @@ public class JdiMethods implements RmiMethods {
vm.resume();
}
@TraceMethod(action = "step_out", display = "Step out")
@TraceRmiMethod(action = "step_out", display = "Step out")
public void step_vm_out(@Param(schema = "VirtualMachine", name = "vm") RmiTraceObject obj) {
VirtualMachine vm = connector.getJdi().getCurrentVM();
List<ThreadReference> threads = getThreadsFromValue(obj);
@ -733,7 +733,7 @@ public class JdiMethods implements RmiMethods {
vm.resume();
}
@TraceMethod(action = "step_into", display = "Step into")
@TraceRmiMethod(action = "step_into", display = "Step into")
public void step_into(@Param(schema = "Thread", name = "thread") RmiTraceObject obj) {
VirtualMachine vm = connector.getJdi().getCurrentVM();
ThreadReference thread = (ThreadReference) getObjectFromPath(obj.getPath());
@ -744,7 +744,7 @@ public class JdiMethods implements RmiMethods {
vm.resume();
}
@TraceMethod(action = "step_over", display = "Step over")
@TraceRmiMethod(action = "step_over", display = "Step over")
public void step_over(@Param(schema = "Thread", name = "thread") RmiTraceObject obj) {
VirtualMachine vm = connector.getJdi().getCurrentVM();
ThreadReference thread = (ThreadReference) getObjectFromPath(obj.getPath());
@ -755,7 +755,7 @@ public class JdiMethods implements RmiMethods {
vm.resume();
}
@TraceMethod(action = "step_out", display = "Step out")
@TraceRmiMethod(action = "step_out", display = "Step out")
public void step_out(@Param(schema = "Thread", name = "thread") RmiTraceObject obj) {
VirtualMachine vm = connector.getJdi().getCurrentVM();
ThreadReference thread = (ThreadReference) getObjectFromPath(obj.getPath());
@ -766,7 +766,7 @@ public class JdiMethods implements RmiMethods {
vm.resume();
}
@TraceMethod(display = "Thread Interrupt")
@TraceRmiMethod(display = "Thread Interrupt")
public void thread_interrupt(@Param(schema = "Thread", name = "thread") RmiTraceObject obj) {
Object object = getObjectFromPath(obj.getPath());
if (object instanceof ThreadReference thread) {
@ -775,7 +775,7 @@ public class JdiMethods implements RmiMethods {
}
}
@TraceMethod(action = "step_ext", display = "Pop stack")
@TraceRmiMethod(action = "step_ext", display = "Pop stack")
public void pop_stack(@Param(schema = "StackFrame", name = "frame") RmiTraceObject obj) {
StackFrame frame = (StackFrame) getObjectFromPath(obj.getPath());
ThreadReference thread = frame.thread();
@ -787,7 +787,7 @@ public class JdiMethods implements RmiMethods {
}
}
@TraceMethod(display = "Break on execute")
@TraceRmiMethod(display = "Break on execute")
public void break_location(@Param(schema = "Location", name = "location") RmiTraceObject obj) {
VirtualMachine vm = connector.getJdi().getCurrentVM();
Object ctxt = getObjectFromPath(obj.getPath());
@ -799,7 +799,7 @@ public class JdiMethods implements RmiMethods {
}
}
@TraceMethod(display = "Break on access")
@TraceRmiMethod(display = "Break on access")
public void break_access(@Param(schema = "Field", name = "field") RmiTraceObject obj) {
VirtualMachine vm = connector.getJdi().getCurrentVM();
Object ctxt = getObjectFromPath(obj.getPath());
@ -811,7 +811,7 @@ public class JdiMethods implements RmiMethods {
}
}
@TraceMethod(display = "Break on modify")
@TraceRmiMethod(display = "Break on modify")
public void break_modify(@Param(schema = "Field", name = "field") RmiTraceObject obj) {
VirtualMachine vm = connector.getJdi().getCurrentVM();
Object ctxt = getObjectFromPath(obj.getPath());
@ -823,7 +823,7 @@ public class JdiMethods implements RmiMethods {
}
}
@TraceMethod(display = "Break on exception")
@TraceRmiMethod(display = "Break on exception")
public void break_exception(
@Param(
schema = "ReferenceType",
@ -861,13 +861,13 @@ public class JdiMethods implements RmiMethods {
cmds.putEvents();
}
@TraceMethod(display = "Break on thread start")
@TraceRmiMethod(display = "Break on thread start")
public void break_started_container(
@Param(schema = "EventContainer", name = "container") RmiTraceObject obj) {
break_started(obj);
}
@TraceMethod(display = "Break on thread start")
@TraceRmiMethod(display = "Break on thread start")
public void break_started_thread(
@Param(schema = "Thread", name = "thread") RmiTraceObject obj) {
break_started(obj);
@ -886,18 +886,18 @@ public class JdiMethods implements RmiMethods {
cmds.putEvents();
}
@TraceMethod(display = "Break on thread exit")
@TraceRmiMethod(display = "Break on thread exit")
public void break_death_container(
@Param(schema = "EventContainer", name = "container") RmiTraceObject obj) {
break_death(obj);
}
@TraceMethod(display = "Break on thread exit")
@TraceRmiMethod(display = "Break on thread exit")
public void break_death_thread(@Param(schema = "Thread", name = "thread") RmiTraceObject obj) {
break_death(obj);
}
@TraceMethod(display = "Break on VM death")
@TraceRmiMethod(display = "Break on VM death")
public void break_vm_death(@Param(schema = "VirtualMachine", name = "vm") RmiTraceObject obj) {
VirtualMachine vm = connector.getJdi().getCurrentVM();
VMDeathRequest brkReq = vm.eventRequestManager()
@ -927,25 +927,25 @@ public class JdiMethods implements RmiMethods {
cmds.putEvents();
}
@TraceMethod(display = "Break on method enter")
@TraceRmiMethod(display = "Break on method enter")
public void break_enter_container(
@Param(schema = "EventContainer", name = "container") RmiTraceObject obj) {
break_enter(obj);
}
@TraceMethod(display = "Break on method enter")
@TraceRmiMethod(display = "Break on method enter")
public void break_enter_reftype(
@Param(schema = "ReferenceType", name = "class") RmiTraceObject obj) {
break_enter(obj);
}
@TraceMethod(display = "Break on method enter")
@TraceRmiMethod(display = "Break on method enter")
public void break_enter_instance(
@Param(schema = "ObjectReference", name = "instance") RmiTraceObject obj) {
break_enter(obj);
}
@TraceMethod(display = "Break on method enter")
@TraceRmiMethod(display = "Break on method enter")
public void break_enter_thread(@Param(schema = "Thread", name = "thread") RmiTraceObject obj) {
break_enter(obj);
}
@ -971,25 +971,25 @@ public class JdiMethods implements RmiMethods {
cmds.putEvents();
}
@TraceMethod(display = "Break on method exit")
@TraceRmiMethod(display = "Break on method exit")
public void break_exit_container(
@Param(schema = "EventContainer", name = "container") RmiTraceObject obj) {
break_exit(obj);
}
@TraceMethod(display = "Break on method exit")
@TraceRmiMethod(display = "Break on method exit")
public void break_exit_reftype(
@Param(schema = "ReferenceType", name = "class") RmiTraceObject obj) {
break_exit(obj);
}
@TraceMethod(display = "Break on method exit")
@TraceRmiMethod(display = "Break on method exit")
public void break_exit_instance(
@Param(schema = "ObjectReference", name = "instance") RmiTraceObject obj) {
break_exit(obj);
}
@TraceMethod(display = "Break on method exit")
@TraceRmiMethod(display = "Break on method exit")
public void break_exit_thread(@Param(schema = "Thread", name = "thread") RmiTraceObject obj) {
break_exit(obj);
}
@ -1007,13 +1007,13 @@ public class JdiMethods implements RmiMethods {
cmds.putEvents();
}
@TraceMethod(display = "Break on class load")
@TraceRmiMethod(display = "Break on class load")
public void break_load_container(
@Param(schema = "EventContainer", name = "container") RmiTraceObject obj) {
break_load(obj);
}
@TraceMethod(display = "Break on class load")
@TraceRmiMethod(display = "Break on class load")
public void break_load_reftype(
@Param(schema = "ReferenceType", name = "class") RmiTraceObject obj) {
break_load(obj);
@ -1027,7 +1027,7 @@ public class JdiMethods implements RmiMethods {
cmds.putEvents();
}
@TraceMethod(display = "Break on class unload")
@TraceRmiMethod(display = "Break on class unload")
public void break_unload_container(
@Param(schema = "EventContainer", name = "container") RmiTraceObject obj) {
break_unload(obj);
@ -1054,25 +1054,25 @@ public class JdiMethods implements RmiMethods {
cmds.putEvents();
}
@TraceMethod(display = "Break on monitor contended enter")
@TraceRmiMethod(display = "Break on monitor contended enter")
public void break_mon_enter_contention_container(
@Param(schema = "EventContainer", name = "container") RmiTraceObject obj) {
break_mon_enter_contention(obj);
}
@TraceMethod(display = "Break on monitor contended enter")
@TraceRmiMethod(display = "Break on monitor contended enter")
public void break_mon_enter_contention_reftype(
@Param(schema = "ReferenceType", name = "class") RmiTraceObject obj) {
break_mon_enter_contention(obj);
}
@TraceMethod(display = "Break on monitor contended enter")
@TraceRmiMethod(display = "Break on monitor contended enter")
public void break_mon_enter_contention_instance(
@Param(schema = "ObjectReference", name = "instance") RmiTraceObject obj) {
break_mon_enter_contention(obj);
}
@TraceMethod(display = "Break on monitor contended enter")
@TraceRmiMethod(display = "Break on monitor contended enter")
public void break_mon_enter_contention_thread(
@Param(schema = "Thread", name = "thread") RmiTraceObject obj) {
break_mon_enter_contention(obj);
@ -1099,25 +1099,25 @@ public class JdiMethods implements RmiMethods {
cmds.putEvents();
}
@TraceMethod(display = "Break on monitor contented entered")
@TraceRmiMethod(display = "Break on monitor contented entered")
public void break_mon_entered_contention_container(
@Param(schema = "EventContainer", name = "container") RmiTraceObject obj) {
break_mon_entered_contention(obj);
}
@TraceMethod(display = "Break on monitor contented entered")
@TraceRmiMethod(display = "Break on monitor contented entered")
public void break_mon_entered_contention_reftype(
@Param(schema = "ReferenceType", name = "class") RmiTraceObject obj) {
break_mon_entered_contention(obj);
}
@TraceMethod(display = "Break on monitor contented entered")
@TraceRmiMethod(display = "Break on monitor contented entered")
public void break_mon_entered_contention_instance(
@Param(schema = "ObjectReference", name = "instance") RmiTraceObject obj) {
break_mon_entered_contention(obj);
}
@TraceMethod(display = "Break on monitor contented entered")
@TraceRmiMethod(display = "Break on monitor contented entered")
public void break_mon_entered_contention_thread(
@Param(schema = "Thread", name = "thread") RmiTraceObject obj) {
break_mon_entered_contention(obj);
@ -1144,25 +1144,25 @@ public class JdiMethods implements RmiMethods {
cmds.putEvents();
}
@TraceMethod(display = "Break on monitor wait")
@TraceRmiMethod(display = "Break on monitor wait")
public void break_mon_wait_container(
@Param(schema = "EventContainer", name = "container") RmiTraceObject obj) {
break_mon_wait(obj);
}
@TraceMethod(display = "Break on monitor wait")
@TraceRmiMethod(display = "Break on monitor wait")
public void break_mon_wait_reftype(
@Param(schema = "ReferenceType", name = "class") RmiTraceObject obj) {
break_mon_wait(obj);
}
@TraceMethod(display = "Break on monitor wait")
@TraceRmiMethod(display = "Break on monitor wait")
public void break_mon_wait_instance(
@Param(schema = "ObjectReference", name = "instance") RmiTraceObject obj) {
break_mon_wait(obj);
}
@TraceMethod(display = "Break on monitor wait")
@TraceRmiMethod(display = "Break on monitor wait")
public void break_mon_wait_thread(
@Param(schema = "Thread", name = "thread") RmiTraceObject obj) {
break_mon_wait(obj);
@ -1189,31 +1189,31 @@ public class JdiMethods implements RmiMethods {
cmds.putEvents();
}
@TraceMethod(display = "Break on monitor waited")
@TraceRmiMethod(display = "Break on monitor waited")
public void break_mon_waited_container(
@Param(schema = "EventContainer", name = "container") RmiTraceObject obj) {
break_mon_waited(obj);
}
@TraceMethod(display = "Break on monitor waited")
@TraceRmiMethod(display = "Break on monitor waited")
public void break_mon_waited_reftype(
@Param(schema = "ReferenceType", name = "class") RmiTraceObject obj) {
break_mon_waited(obj);
}
@TraceMethod(display = "Break on monitor waited")
@TraceRmiMethod(display = "Break on monitor waited")
public void break_mon_waited_instance(
@Param(schema = "ObjectReference", name = "instance") RmiTraceObject obj) {
break_mon_waited(obj);
}
@TraceMethod(display = "Break on monitor waited")
@TraceRmiMethod(display = "Break on monitor waited")
public void break_mon_waited_thread(
@Param(schema = "Thread", name = "thread") RmiTraceObject obj) {
break_mon_waited(obj);
}
@TraceMethod(display = "Add count filter")
@TraceRmiMethod(display = "Add count filter")
public void add_count_filter(
@Param(
schema = "Event",
@ -1234,7 +1234,7 @@ public class JdiMethods implements RmiMethods {
}
}
@TraceMethod(display = "Set class filter")
@TraceRmiMethod(display = "Set class filter")
public void set_class_filter(
@Param(
schema = "Event",
@ -1349,7 +1349,7 @@ public class JdiMethods implements RmiMethods {
cmds.putEvents();
}
@TraceMethod(display = "Set source filter")
@TraceRmiMethod(display = "Set source filter")
public void set_source_filter(
@Param(
schema = "Event",
@ -1370,7 +1370,7 @@ public class JdiMethods implements RmiMethods {
cmds.putEvents();
}
@TraceMethod(display = "Set platform filter")
@TraceRmiMethod(display = "Set platform filter")
public void set_platform_filter(@Param(schema = "Event", name = "event") RmiTraceObject obj) {
Object ctxt = getObjectFromPath(obj.getPath());
if (ctxt instanceof ThreadStartRequest req) {
@ -1388,7 +1388,7 @@ public class JdiMethods implements RmiMethods {
cmds.putEvents();
}
@TraceMethod(action = "toggle", display = "Toggle breakpoint")
@TraceRmiMethod(action = "toggle", display = "Toggle breakpoint")
public void toggle_breakpoint(
@Param(schema = "BreakpointSpec", name = "breakpoint") RmiTraceObject obj) {
VirtualMachine vm = connector.getJdi().getCurrentVM();
@ -1409,7 +1409,7 @@ public class JdiMethods implements RmiMethods {
cmds.putBreakpoints();
}
@TraceMethod(action = "delete", display = "Delete breakpoint")
@TraceRmiMethod(action = "delete", display = "Delete breakpoint")
public void delete_breakpoint(
@Param(schema = "BreakpointSpec", name = "breakpoint") RmiTraceObject obj) {
VirtualMachine vm = connector.getJdi().getCurrentVM();
@ -1420,7 +1420,7 @@ public class JdiMethods implements RmiMethods {
cmds.putBreakpoints();
}
@TraceMethod(action = "toggle", display = "Toggle event")
@TraceRmiMethod(action = "toggle", display = "Toggle event")
public void toggle_event(@Param(schema = "Event", name = "event") RmiTraceObject obj) {
Object ctxt = getObjectFromPath(obj.getPath());
if (ctxt instanceof EventRequest req) {
@ -1434,7 +1434,7 @@ public class JdiMethods implements RmiMethods {
}
}
@TraceMethod(action = "delete", display = "Delete Event")
@TraceRmiMethod(action = "delete", display = "Delete Event")
public void delete_event(@Param(schema = "Event", name = "event") RmiTraceObject obj) {
VirtualMachine vm = connector.getJdi().getCurrentVM();
Object ctxt = getObjectFromPath(obj.getPath());
@ -1444,13 +1444,13 @@ public class JdiMethods implements RmiMethods {
cmds.putEvents();
}
@TraceMethod(action = "toggle", display = "Toggle scope")
@TraceRmiMethod(action = "toggle", display = "Toggle scope")
public void toggle_scope_canonical_methods(
@Param(schema = "CanonicalMethodContainer", name = "container") RmiTraceObject obj) {
toggle_scope_methods(obj);
}
@TraceMethod(action = "toggle", display = "Toggle scope")
@TraceRmiMethod(action = "toggle", display = "Toggle scope")
public void toggle_scope_methods(
@Param(schema = "MethodContainer", name = "container") RmiTraceObject obj) {
String ppath = cmds.getParentPath(obj.getPath());
@ -1459,13 +1459,13 @@ public class JdiMethods implements RmiMethods {
refresh_methods(obj);
}
@TraceMethod(action = "toggle", display = "Toggle scope")
@TraceRmiMethod(action = "toggle", display = "Toggle scope")
public void toggle_scope_canonical_fields(
@Param(schema = "CanonicalFieldContainer", name = "container") RmiTraceObject obj) {
toggle_scope_fields(obj);
}
@TraceMethod(action = "toggle", display = "Toggle scope")
@TraceRmiMethod(action = "toggle", display = "Toggle scope")
public void toggle_scope_fields(
@Param(schema = "FieldContainer", name = "container") RmiTraceObject obj) {
String ppath = cmds.getParentPath(obj.getPath());
@ -1479,7 +1479,7 @@ public class JdiMethods implements RmiMethods {
}
}
@TraceMethod(action = "read_mem", display = "Read Memory")
@TraceRmiMethod(action = "read_mem", display = "Read Memory")
public long read_mem(
@Param(
schema = "VirtualMachine",
@ -1503,7 +1503,7 @@ public class JdiMethods implements RmiMethods {
return range.getLength();
}
@TraceMethod(display = "Invoke method (no args)")
@TraceRmiMethod(display = "Invoke method (no args)")
public void execute_on_instance(
@Param(
schema = "ObjectReference",
@ -1531,7 +1531,7 @@ public class JdiMethods implements RmiMethods {
}
}
@TraceMethod(display = "Invoke static method (no args)")
@TraceRmiMethod(display = "Invoke static method (no args)")
public void execute_on_class(
@Param(
schema = "ReferenceType",
@ -1565,7 +1565,7 @@ public class JdiMethods implements RmiMethods {
}
}
@TraceMethod(display = "Invoke method (no args)")
@TraceRmiMethod(display = "Invoke method (no args)")
public void execute_method(
@Param(
schema = "Method",
@ -1596,7 +1596,7 @@ public class JdiMethods implements RmiMethods {
}
}
@TraceMethod(display = "Invoke static method (no args)")
@TraceRmiMethod(display = "Invoke static method (no args)")
public void execute_static_method(
@Param(
schema = "Method",

View file

@ -26,7 +26,7 @@ public class RmiMethodRegistry {
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public static @interface TraceMethod {
public static @interface TraceRmiMethod {
String action() default "";
String display() default "";

View file

@ -18,7 +18,7 @@ package ghidra.app.plugin.core.debug.client.tracermi;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import ghidra.trace.model.target.iface.TraceObjectMethod.ParameterDescription;
import ghidra.trace.model.target.iface.TraceMethod.ParameterDescription;
import ghidra.trace.model.target.schema.*;
import ghidra.trace.model.target.schema.TraceObjectSchema.SchemaName;

View file

@ -51,7 +51,8 @@ import ghidra.trace.model.breakpoint.*;
import ghidra.trace.model.breakpoint.TraceBreakpointKind.TraceBreakpointKindSet;
import ghidra.trace.model.guest.TracePlatform;
import ghidra.trace.model.memory.*;
import ghidra.trace.model.stack.*;
import ghidra.trace.model.stack.TraceStack;
import ghidra.trace.model.stack.TraceStackFrame;
import ghidra.trace.model.target.*;
import ghidra.trace.model.target.iface.*;
import ghidra.trace.model.target.info.TraceObjectInterfaceUtils;
@ -60,7 +61,8 @@ import ghidra.trace.model.target.path.PathFilter.Align;
import ghidra.trace.model.target.schema.*;
import ghidra.trace.model.target.schema.PrimitiveTraceObjectSchema.MinimalSchemaContext;
import ghidra.trace.model.target.schema.TraceObjectSchema.SchemaName;
import ghidra.trace.model.thread.*;
import ghidra.trace.model.thread.TraceProcess;
import ghidra.trace.model.thread.TraceThread;
import ghidra.trace.model.time.schedule.TraceSchedule.ScheduleForm;
import ghidra.util.Msg;
import ghidra.util.task.TaskMonitor;
@ -186,12 +188,12 @@ public class TraceRmiTarget extends AbstractTarget {
}
protected ScheduleForm getSupportedTimeFormByAttribute(TraceObject obj, long snap) {
TraceObject eventScope = obj.findSuitableInterface(TraceObjectEventScope.class);
TraceObject eventScope = obj.findSuitableInterface(TraceEventScope.class);
if (eventScope == null) {
return null;
}
TraceObjectValue timeSupportStr =
eventScope.getAttribute(snap, TraceObjectEventScope.KEY_TIME_SUPPORT);
eventScope.getAttribute(snap, TraceEventScope.KEY_TIME_SUPPORT);
if (timeSupportStr == null) {
return null;
}
@ -213,11 +215,7 @@ public class TraceRmiTarget extends AbstractTarget {
@Override
public TraceExecutionState getThreadExecutionState(TraceThread thread) {
if (!(thread instanceof TraceObjectThread tot)) {
Msg.error(this, "Non-object thread with Trace RMI!");
return TraceExecutionState.ALIVE;
}
return tot.getObject().getExecutionState(getSnap());
return thread.getObject().getExecutionState(getSnap());
}
@Override
@ -226,7 +224,7 @@ public class TraceRmiTarget extends AbstractTarget {
if (object == null) {
return null;
}
return object.queryCanonicalAncestorsInterface(TraceObjectThread.class)
return object.queryCanonicalAncestorsInterface(TraceThread.class)
.findFirst()
.orElse(null);
}
@ -237,7 +235,7 @@ public class TraceRmiTarget extends AbstractTarget {
if (object == null) {
return null;
}
return object.queryCanonicalAncestorsInterface(TraceObjectStackFrame.class)
return object.queryCanonicalAncestorsInterface(TraceStackFrame.class)
.findFirst()
.orElse(null);
}
@ -303,7 +301,7 @@ public class TraceRmiTarget extends AbstractTarget {
return null;
}
TraceObjectValue attrEnabled =
object.getAttribute(getSnap(), TraceObjectTogglable.KEY_ENABLED);
object.getAttribute(getSnap(), TraceTogglable.KEY_ENABLED);
boolean enabled = attrEnabled != null && attrEnabled.getValue() instanceof Boolean b && b;
return !enabled;
}
@ -549,7 +547,7 @@ public class TraceRmiTarget extends AbstractTarget {
}
return schema
.getInterfaces()
.contains(TraceObjectFocusScope.class) &&
.contains(TraceFocusScope.class) &&
!connection.getMethods().getByAction(ActionName.ACTIVATE).isEmpty();
}
@ -557,7 +555,7 @@ public class TraceRmiTarget extends AbstractTarget {
public KeyPath getFocus() {
TraceObjectValue focusVal = trace.getObjectManager()
.getRootObject()
.getAttribute(getSnap(), TraceObjectFocusScope.KEY_FOCUS);
.getAttribute(getSnap(), TraceFocusScope.KEY_FOCUS);
if (focusVal == null || !focusVal.isObject()) {
return null;
}
@ -740,7 +738,7 @@ public class TraceRmiTarget extends AbstractTarget {
record ReadMemMatcher(int score, List<ParamSpec> spec) implements MethodMatcher {
static final ReadMemMatcher HAS_PROC_RANGE = new ReadMemMatcher(2, List.of(
new TypeParamSpec("process", TraceObjectProcess.class),
new TypeParamSpec("process", TraceProcess.class),
new TypeParamSpec("range", AddressRange.class)));
static final ReadMemMatcher HAS_RANGE = new ReadMemMatcher(1, List.of(
new TypeParamSpec("range", AddressRange.class)));
@ -749,7 +747,7 @@ public class TraceRmiTarget extends AbstractTarget {
record WriteMemMatcher(int score, List<ParamSpec> spec) implements MethodMatcher {
static final WriteMemMatcher HAS_PROC_START_DATA = new WriteMemMatcher(2, List.of(
new TypeParamSpec("process", TraceObjectProcess.class),
new TypeParamSpec("process", TraceProcess.class),
new TypeParamSpec("start", Address.class),
new TypeParamSpec("data", byte[].class)));
static final WriteMemMatcher HAS_START_DATA = new WriteMemMatcher(1, List.of(
@ -760,43 +758,43 @@ public class TraceRmiTarget extends AbstractTarget {
record ReadRegsMatcher(int score, List<ParamSpec> spec) implements MethodMatcher {
static final ReadRegsMatcher HAS_CONTAINER = new ReadRegsMatcher(3, List.of(
new TypeParamSpec("container", TraceObjectRegisterContainer.class)));
new TypeParamSpec("container", TraceRegisterContainer.class)));
static final ReadRegsMatcher HAS_REGISTER = new ReadRegsMatcher(1, List.of(
new TypeParamSpec("register", TraceObjectRegister.class)));
new TypeParamSpec("register", TraceRegister.class)));
static final List<ReadRegsMatcher> ALL = matchers(HAS_CONTAINER, HAS_REGISTER);
}
record WriteRegMatcher(int score, List<ParamSpec> spec) implements MethodMatcher {
static final WriteRegMatcher HAS_FRAME_NAME_VALUE = new WriteRegMatcher(3, List.of(
new TypeParamSpec("frame", TraceObjectStackFrame.class),
new TypeParamSpec("frame", TraceStackFrame.class),
new TypeParamSpec("name", String.class),
new TypeParamSpec("value", byte[].class)));
static final WriteRegMatcher HAS_THREAD_NAME_VALUE = new WriteRegMatcher(2, List.of(
new TypeParamSpec("thread", TraceObjectThread.class),
new TypeParamSpec("thread", TraceThread.class),
new TypeParamSpec("name", String.class),
new TypeParamSpec("value", byte[].class)));
static final WriteRegMatcher HAS_REG_VALUE = new WriteRegMatcher(1, List.of(
new TypeParamSpec("register", TraceObjectRegister.class),
new TypeParamSpec("register", TraceRegister.class),
new TypeParamSpec("value", byte[].class)));
static final List<WriteRegMatcher> ALL = matchers(HAS_FRAME_NAME_VALUE, HAS_REG_VALUE);
}
record BreakExecMatcher(int score, List<ParamSpec> spec) implements MethodMatcher {
static final BreakExecMatcher HAS_PROC_ADDR_COND_CMDS = new BreakExecMatcher(8, List.of(
new TypeParamSpec("process", TraceObjectProcess.class),
new TypeParamSpec("process", TraceProcess.class),
new TypeParamSpec("address", Address.class),
new NameParamSpec("condition", String.class),
new NameParamSpec("commands", String.class)));
static final BreakExecMatcher HAS_PROC_ADDR_COND = new BreakExecMatcher(7, List.of(
new TypeParamSpec("process", TraceObjectProcess.class),
new TypeParamSpec("process", TraceProcess.class),
new TypeParamSpec("address", Address.class),
new NameParamSpec("condition", String.class)));
static final BreakExecMatcher HAS_PROC_ADDR_CMDS = new BreakExecMatcher(6, List.of(
new TypeParamSpec("process", TraceObjectProcess.class),
new TypeParamSpec("process", TraceProcess.class),
new TypeParamSpec("address", Address.class),
new NameParamSpec("commands", String.class)));
static final BreakExecMatcher HAS_PROC_ADDR = new BreakExecMatcher(5, List.of(
new TypeParamSpec("process", TraceObjectProcess.class),
new TypeParamSpec("process", TraceProcess.class),
new TypeParamSpec("address", Address.class)));
static final BreakExecMatcher HAS_ADDR_COND_CMDS = new BreakExecMatcher(4, List.of(
new TypeParamSpec("address", Address.class),
@ -818,20 +816,20 @@ public class TraceRmiTarget extends AbstractTarget {
// TODO: Probably need a better way to deal with optional requirements
record BreakAccMatcher(int score, List<ParamSpec> spec) implements MethodMatcher {
static final BreakAccMatcher HAS_PROC_RNG_COND_CMDS = new BreakAccMatcher(8, List.of(
new TypeParamSpec("process", TraceObjectProcess.class),
new TypeParamSpec("process", TraceProcess.class),
new TypeParamSpec("range", AddressRange.class),
new NameParamSpec("condition", String.class),
new NameParamSpec("commands", String.class)));
static final BreakAccMatcher HAS_PROC_RNG_COND = new BreakAccMatcher(7, List.of(
new TypeParamSpec("process", TraceObjectProcess.class),
new TypeParamSpec("process", TraceProcess.class),
new TypeParamSpec("range", AddressRange.class),
new NameParamSpec("condition", String.class)));
static final BreakAccMatcher HAS_PROC_RNG_CMDS = new BreakAccMatcher(6, List.of(
new TypeParamSpec("process", TraceObjectProcess.class),
new TypeParamSpec("process", TraceProcess.class),
new TypeParamSpec("range", AddressRange.class),
new NameParamSpec("commands", String.class)));
static final BreakAccMatcher HAS_PROC_RNG = new BreakAccMatcher(5, List.of(
new TypeParamSpec("process", TraceObjectProcess.class),
new TypeParamSpec("process", TraceProcess.class),
new TypeParamSpec("range", AddressRange.class)));
static final BreakAccMatcher HAS_RNG_COND_CMDS = new BreakAccMatcher(4, List.of(
new TypeParamSpec("range", AddressRange.class),
@ -852,19 +850,19 @@ public class TraceRmiTarget extends AbstractTarget {
record DelBreakMatcher(int score, List<ParamSpec> spec) implements MethodMatcher {
static final DelBreakMatcher HAS_LOC = new DelBreakMatcher(2, List.of(
new TypeParamSpec("location", TraceObjectBreakpointLocation.class)));
new TypeParamSpec("location", TraceBreakpointLocation.class)));
static final DelBreakMatcher HAS_SPEC = new DelBreakMatcher(1, List.of(
new TypeParamSpec("specification", TraceObjectBreakpointSpec.class)));
new TypeParamSpec("specification", TraceBreakpointSpec.class)));
static final List<DelBreakMatcher> ALL = matchers(HAS_LOC, HAS_SPEC);
static final List<DelBreakMatcher> SPEC = matchers(HAS_SPEC);
}
record ToggleBreakMatcher(int score, List<ParamSpec> spec) implements MethodMatcher {
static final ToggleBreakMatcher HAS_LOC = new ToggleBreakMatcher(2, List.of(
new TypeParamSpec("location", TraceObjectBreakpointLocation.class),
new TypeParamSpec("location", TraceBreakpointLocation.class),
new TypeParamSpec("enabled", Boolean.class)));
static final ToggleBreakMatcher HAS_SPEC = new ToggleBreakMatcher(1, List.of(
new TypeParamSpec("specification", TraceObjectBreakpointSpec.class),
new TypeParamSpec("specification", TraceBreakpointSpec.class),
new TypeParamSpec("enabled", Boolean.class)));
static final List<ToggleBreakMatcher> ALL = matchers(HAS_LOC, HAS_SPEC);
static final List<ToggleBreakMatcher> SPEC = matchers(HAS_SPEC);
@ -1079,8 +1077,8 @@ public class TraceRmiTarget extends AbstractTarget {
}
protected TraceObject getProcessForSpace(AddressSpace space) {
List<TraceObjectProcess> processes = trace.getObjectManager()
.queryAllInterface(Lifespan.at(getSnap()), TraceObjectProcess.class)
List<TraceProcess> processes = trace.getObjectManager()
.queryAllInterface(Lifespan.at(getSnap()), TraceProcess.class)
.toList();
if (processes.size() == 1) {
return processes.get(0).getObject();
@ -1089,11 +1087,10 @@ public class TraceRmiTarget extends AbstractTarget {
return null;
}
for (TraceMemoryRegion region : trace.getMemoryManager()
.getRegionsIntersecting(
Lifespan.at(getSnap()),
.getRegionsIntersecting(Lifespan.at(getSnap()),
new AddressRangeImpl(space.getMinAddress(), space.getMaxAddress()))) {
TraceObject obj = ((TraceObjectMemoryRegion) region).getObject();
return obj.findCanonicalAncestorsInterface(TraceObjectProcess.class)
TraceObject obj = region.getObject();
return obj.findCanonicalAncestorsInterface(TraceProcess.class)
.findFirst()
.orElse(null);
}
@ -1207,11 +1204,7 @@ public class TraceRmiTarget extends AbstractTarget {
if (readRegs == null) {
return AsyncUtils.nil();
}
if (!(thread instanceof TraceObjectThread tot)) {
Msg.error(this, "Non-object trace with TraceRmi!");
return AsyncUtils.nil();
}
TraceObject container = tot.getObject().findRegisterContainer(frame);
TraceObject container = thread.getObject().findRegisterContainer(frame);
if (container == null) {
Msg.error(this,
"Cannot find register container for thread,frame: " + thread + "," + frame);
@ -1229,8 +1222,7 @@ public class TraceRmiTarget extends AbstractTarget {
keys.add("[" + lower + "]");
}
Set<TraceObject> regs = container
.findSuccessorsInterface(Lifespan.at(getSnap()), TraceObjectRegister.class,
true)
.findSuccessorsInterface(Lifespan.at(getSnap()), TraceRegister.class, true)
.filter(p -> keys.contains(p.getLastEntry().getEntryKey().toLowerCase()))
.map(r -> r.getDestination(null))
.collect(Collectors.toSet());
@ -1303,14 +1295,13 @@ public class TraceRmiTarget extends AbstractTarget {
return findRegister(container, filter, parent);
}
protected FoundRegister findRegister(TraceObjectThread thread, int frame,
Register register) {
protected FoundRegister findRegister(TraceThread thread, int frame, Register register) {
TraceObject container = thread.getObject().findRegisterContainer(frame);
if (container == null) {
Msg.error(this, "No register container for thread=" + thread + ",frame=" + frame);
return null;
}
PathFilter filter = container.getSchema().searchFor(TraceObjectRegister.class, true);
PathFilter filter = container.getSchema().searchFor(TraceRegister.class, true);
return findRegister(container, filter, register);
}
@ -1337,11 +1328,7 @@ public class TraceRmiTarget extends AbstractTarget {
if (writeReg == null) {
return AsyncUtils.nil();
}
if (!(thread instanceof TraceObjectThread tot)) {
Msg.error(this, "Non-object trace with TraceRmi!");
return AsyncUtils.nil();
}
FoundRegister found = findRegister(tot, frameLevel, value.getRegister());
FoundRegister found = findRegister(thread, frameLevel, value.getRegister());
if (found == null) {
Msg.warn(this, "Could not find register " + value.getRegister() + " in object model.");
}
@ -1352,7 +1339,7 @@ public class TraceRmiTarget extends AbstractTarget {
RemoteParameter paramThread = writeReg.params.get("thread");
if (paramThread != null) {
return writeReg.method.invokeAsync(Map.ofEntries(
Map.entry(paramThread.name(), tot.getObject()),
Map.entry(paramThread.name(), thread.getObject()),
Map.entry(writeReg.params.get("name").name(), found.name()),
Map.entry(writeReg.params.get("value").name(), getBytes(value))))
.toCompletableFuture()
@ -1363,12 +1350,8 @@ public class TraceRmiTarget extends AbstractTarget {
if (paramFrame != null) {
TraceStack stack = trace.getStackManager().getLatestStack(thread, getSnap());
TraceStackFrame frame = stack.getFrame(getSnap(), frameLevel, false);
if (!(frame instanceof TraceObjectStackFrame tof)) {
Msg.error(this, "Non-object trace with TraceRmi!");
return AsyncUtils.nil();
}
return writeReg.method.invokeAsync(Map.ofEntries(
Map.entry(paramFrame.name(), tof.getObject()),
Map.entry(paramFrame.name(), frame.getObject()),
Map.entry(writeReg.params.get("name").name(), found.name()),
Map.entry(writeReg.params.get("value").name(), getBytes(value))))
.toCompletableFuture()
@ -1398,11 +1381,8 @@ public class TraceRmiTarget extends AbstractTarget {
if (register == null) {
return false;
}
if (!(thread instanceof TraceObjectThread tot)) {
return false;
}
// May be primitive or object
FoundRegister found = findRegister(tot, frame, register);
FoundRegister found = findRegister(thread, frame, register);
if (found == null) {
return false;
}
@ -1596,7 +1576,7 @@ public class TraceRmiTarget extends AbstractTarget {
}
@Override
public boolean isBreakpointValid(TraceBreakpoint breakpoint) {
public boolean isBreakpointValid(TraceBreakpointLocation breakpoint) {
long snap = getSnap();
if (breakpoint.getName(snap).endsWith("emu-" + breakpoint.getMinAddress(snap))) {
return false;
@ -1607,7 +1587,7 @@ public class TraceRmiTarget extends AbstractTarget {
return true;
}
protected CompletableFuture<Void> deleteBreakpointSpecAsync(TraceObjectBreakpointSpec spec) {
protected CompletableFuture<Void> deleteBreakpointSpecAsync(TraceBreakpointSpec spec) {
KeyPath path = spec.getObject().getCanonicalPath();
MatchedMethod delBreak =
matches.getBest(DelBreakMatcher.class, path, ActionName.DELETE, DelBreakMatcher.SPEC);
@ -1621,7 +1601,7 @@ public class TraceRmiTarget extends AbstractTarget {
}
// TODO: Would this make sense for any debugger? To delete individual locations?
protected CompletableFuture<Void> deleteBreakpointLocAsync(TraceObjectBreakpointLocation loc) {
protected CompletableFuture<Void> deleteBreakpointLocAsync(TraceBreakpointLocation loc) {
KeyPath path = loc.getObject().getCanonicalPath();
MatchedMethod delBreak =
matches.getBest(DelBreakMatcher.class, path, ActionName.DELETE, DelBreakMatcher.ALL);
@ -1639,18 +1619,18 @@ public class TraceRmiTarget extends AbstractTarget {
}
@Override
public CompletableFuture<Void> deleteBreakpointAsync(TraceBreakpoint breakpoint) {
if (breakpoint instanceof TraceObjectBreakpointLocation loc) {
public CompletableFuture<Void> deleteBreakpointAsync(TraceBreakpointCommon breakpoint) {
if (breakpoint instanceof TraceBreakpointLocation loc) {
return deleteBreakpointLocAsync(loc);
}
if (breakpoint instanceof TraceObjectBreakpointSpec spec) {
if (breakpoint instanceof TraceBreakpointSpec spec) {
return deleteBreakpointSpecAsync(spec);
}
Msg.error(this, "Unrecognized TraceBreakpoint: " + breakpoint);
return AsyncUtils.nil();
}
protected CompletableFuture<Void> toggleBreakpointSpecAsync(TraceObjectBreakpointSpec spec,
protected CompletableFuture<Void> toggleBreakpointSpecAsync(TraceBreakpointSpec spec,
boolean enabled) {
KeyPath path = spec.getObject().getCanonicalPath();
MatchedMethod toggleBreak =
@ -1667,7 +1647,7 @@ public class TraceRmiTarget extends AbstractTarget {
.thenApply(__ -> null);
}
protected CompletableFuture<Void> toggleBreakpointLocAsync(TraceObjectBreakpointLocation loc,
protected CompletableFuture<Void> toggleBreakpointLocAsync(TraceBreakpointLocation loc,
boolean enabled) {
KeyPath path = loc.getObject().getCanonicalPath();
MatchedMethod toggleBreak =
@ -1690,12 +1670,12 @@ public class TraceRmiTarget extends AbstractTarget {
}
@Override
public CompletableFuture<Void> toggleBreakpointAsync(TraceBreakpoint breakpoint,
public CompletableFuture<Void> toggleBreakpointAsync(TraceBreakpointCommon breakpoint,
boolean enabled) {
if (breakpoint instanceof TraceObjectBreakpointLocation loc) {
if (breakpoint instanceof TraceBreakpointLocation loc) {
return toggleBreakpointLocAsync(loc, enabled);
}
if (breakpoint instanceof TraceObjectBreakpointSpec spec) {
if (breakpoint instanceof TraceBreakpointSpec spec) {
return toggleBreakpointSpecAsync(spec, enabled);
}
Msg.error(this, "Unrecognized TraceBreakpoint: " + breakpoint);

View file

@ -37,8 +37,8 @@ import ghidra.debug.api.target.ActionName;
import ghidra.debug.api.tracermi.RemoteMethod;
import ghidra.debug.api.tracermi.RemoteParameter;
import ghidra.framework.options.PropertyBoolean;
import ghidra.trace.model.target.iface.TraceObjectMethod.Param;
import ghidra.trace.model.target.iface.TraceObjectMethod.ParameterDescription;
import ghidra.trace.model.target.iface.TraceMethod.Param;
import ghidra.trace.model.target.iface.TraceMethod.ParameterDescription;
import ghidra.trace.model.target.schema.*;
import ghidra.trace.model.target.schema.PrimitiveTraceObjectSchema.MinimalSchemaContext;
import ghidra.trace.model.target.schema.TraceObjectSchema.SchemaName;

View file

@ -343,16 +343,16 @@ public class PopulateDemoTrace extends GhidraScript {
*/
mainLabel = trace.getSymbolManager()
.labels()
.create(snap, null, addr(0x00400000), "main", global, SourceType.USER_DEFINED);
.create(snap, addr(0x00400000), "main", global, SourceType.USER_DEFINED);
cloneLabel = trace.getSymbolManager()
.labels()
.create(snap, null, addr(0x00400060), "clone", global, SourceType.USER_DEFINED);
.create(snap, addr(0x00400060), "clone", global, SourceType.USER_DEFINED);
childLabel = trace.getSymbolManager()
.labels()
.create(snap, null, addr(0x00400034), "child", global, SourceType.USER_DEFINED);
.create(snap, addr(0x00400034), "child", global, SourceType.USER_DEFINED);
exitLabel = trace.getSymbolManager()
.labels()
.create(snap, null, addr(0x00400061), "exit", global, SourceType.USER_DEFINED);
.create(snap, addr(0x00400061), "exit", global, SourceType.USER_DEFINED);
/**
* Note the use of getProgramView as a means of using components intended for Program

View file

@ -29,8 +29,8 @@ import ghidra.debug.api.modules.ModuleMapProposal;
import ghidra.debug.api.modules.ModuleMapProposal.ModuleMapEntry;
import ghidra.program.model.listing.Program;
import ghidra.trace.model.Trace;
import ghidra.trace.model.memory.TraceObjectMemoryRegion;
import ghidra.trace.model.modules.TraceObjectModule;
import ghidra.trace.model.memory.TraceMemoryRegion;
import ghidra.trace.model.modules.TraceModule;
import ghidra.trace.model.target.TraceObjectValue;
import ghidra.trace.util.TraceEvent;
import ghidra.trace.util.TraceEvents;
@ -76,8 +76,8 @@ public class ByModuleAutoMapSpec implements AutoMapSpec {
@Override
public boolean objectHasType(TraceObjectValue value) {
return value.getParent().queryInterface(TraceObjectModule.class) != null ||
value.getParent().queryInterface(TraceObjectMemoryRegion.class) != null;
return value.getParent().queryInterface(TraceModule.class) != null ||
value.getParent().queryInterface(TraceMemoryRegion.class) != null;
}
@Override

View file

@ -29,7 +29,7 @@ import ghidra.debug.api.modules.RegionMapProposal;
import ghidra.debug.api.modules.RegionMapProposal.RegionMapEntry;
import ghidra.program.model.listing.Program;
import ghidra.trace.model.Trace;
import ghidra.trace.model.memory.TraceObjectMemoryRegion;
import ghidra.trace.model.memory.TraceMemoryRegion;
import ghidra.trace.model.target.TraceObjectValue;
import ghidra.trace.util.TraceEvent;
import ghidra.trace.util.TraceEvents;
@ -61,7 +61,7 @@ public class ByRegionAutoMapSpec implements AutoMapSpec {
@Override
public boolean objectHasType(TraceObjectValue value) {
return value.getParent().queryInterface(TraceObjectMemoryRegion.class) != null;
return value.getParent().queryInterface(TraceMemoryRegion.class) != null;
}
static String getInfoForRegions(Trace trace, long snap) {

View file

@ -28,8 +28,8 @@ import ghidra.debug.api.modules.MapProposal;
import ghidra.debug.api.modules.SectionMapProposal;
import ghidra.debug.api.modules.SectionMapProposal.SectionMapEntry;
import ghidra.program.model.listing.Program;
import ghidra.trace.database.module.TraceObjectSection;
import ghidra.trace.model.Trace;
import ghidra.trace.model.modules.TraceSection;
import ghidra.trace.model.target.TraceObjectValue;
import ghidra.trace.util.TraceEvent;
import ghidra.trace.util.TraceEvents;
@ -61,7 +61,7 @@ public class BySectionAutoMapSpec implements AutoMapSpec {
@Override
public boolean objectHasType(TraceObjectValue value) {
return value.getParent().queryInterface(TraceObjectSection.class) != null;
return value.getParent().queryInterface(TraceSection.class) != null;
}
@Override

View file

@ -40,11 +40,13 @@ import ghidra.framework.options.SaveState;
import ghidra.framework.plugintool.*;
import ghidra.framework.plugintool.annotation.AutoConfigStateField;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSpace;
import ghidra.program.util.ProgramLocation;
import ghidra.trace.model.*;
import ghidra.trace.model.stack.TraceStack;
import ghidra.trace.model.stack.TraceStackFrame;
import ghidra.trace.model.target.TraceObjectValue;
import ghidra.trace.model.thread.TraceThread;
import ghidra.trace.util.TraceAddressSpace;
import ghidra.trace.util.TraceEvents;
import ghidra.util.Msg;
@ -60,10 +62,12 @@ public class DebuggerTrackLocationTrait {
public ForTrackingListener() {
listenFor(TraceEvents.BYTES_CHANGED, this::registersChanged);
listenFor(TraceEvents.STACK_CHANGED, this::stackChanged);
//listenFor(TraceEvents.STACK_CHANGED, this::stackChanged);
listenFor(TraceEvents.VALUE_CREATED, this::valueCreated);
listenFor(TraceEvents.VALUE_LIFESPAN_CHANGED, this::valueLifespanChanged);
}
private void registersChanged(TraceAddressSpace space, TraceAddressSnapRange range,
private void registersChanged(AddressSpace space, TraceAddressSnapRange range,
byte[] oldValue, byte[] newValue) {
if (current.getView() == null || spec == null) {
// Should only happen during transitional times, if at all.
@ -85,6 +89,42 @@ public class DebuggerTrackLocationTrait {
}
doTrack(TrackCause.DB_CHANGE);
}
private void valueCreated(TraceObjectValue value) {
if (!value.getLifespan().contains(current.getSnap())) {
return;
}
if (!value.getEntryKey().equals(TraceStackFrame.KEY_PC)) {
return;
}
TraceStackFrame frame = value.getParent().queryInterface(TraceStackFrame.class);
if (frame == null) {
return;
}
if (!tracker.affectedByStackChange(frame.getStack(), current)) {
return;
}
doTrack(TrackCause.DB_CHANGE);
}
private void valueLifespanChanged(TraceObjectValue value, Lifespan oldLife,
Lifespan newLife) {
long snap = current.getSnap();
if (oldLife.contains(snap) == newLife.contains(snap)) {
return;
}
if (!value.getEntryKey().equals(TraceStackFrame.KEY_PC)) {
return;
}
TraceStackFrame frame = value.getParent().queryInterface(TraceStackFrame.class);
if (frame == null) {
return;
}
if (!tracker.affectedByStackChange(frame.getStack(), current)) {
return;
}
doTrack(TrackCause.DB_CHANGE);
}
}
// TODO: This may already be deprecated....
@ -297,6 +337,9 @@ public class DebuggerTrackLocationTrait {
trackedLocation = newLocation;
locationTracked();
}
catch (TraceClosedException ex) {
// Silently continue
}
catch (Throwable ex) {
Msg.error(this, "Error while computing location: " + ex);
}

View file

@ -22,10 +22,10 @@ import ghidra.debug.api.action.*;
import ghidra.debug.api.tracemgr.DebuggerCoordinates;
import ghidra.framework.plugintool.ServiceProvider;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSpace;
import ghidra.program.util.ProgramLocation;
import ghidra.trace.model.TraceAddressSnapRange;
import ghidra.trace.model.stack.TraceStack;
import ghidra.trace.util.TraceAddressSpace;
public enum NoneLocationTrackingSpec implements LocationTrackingSpec, LocationTracker {
INSTANCE;
@ -77,8 +77,8 @@ public enum NoneLocationTrackingSpec implements LocationTrackingSpec, LocationTr
}
@Override
public boolean affectedByBytesChange(TraceAddressSpace space,
TraceAddressSnapRange range, DebuggerCoordinates coordinates) {
public boolean affectedByBytesChange(AddressSpace space, TraceAddressSnapRange range,
DebuggerCoordinates coordinates) {
return false;
}

View file

@ -22,13 +22,13 @@ import ghidra.debug.api.action.*;
import ghidra.debug.api.tracemgr.DebuggerCoordinates;
import ghidra.framework.plugintool.ServiceProvider;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSpace;
import ghidra.program.util.ProgramLocation;
import ghidra.trace.model.Trace;
import ghidra.trace.model.TraceAddressSnapRange;
import ghidra.trace.model.stack.TraceStack;
import ghidra.trace.model.stack.TraceStackFrame;
import ghidra.trace.model.thread.TraceThread;
import ghidra.trace.util.TraceAddressSpace;
public enum PCByStackLocationTrackingSpec implements LocationTrackingSpec, LocationTracker {
INSTANCE;
@ -124,7 +124,7 @@ public enum PCByStackLocationTrackingSpec implements LocationTrackingSpec, Locat
}
@Override
public boolean affectedByBytesChange(TraceAddressSpace space, TraceAddressSnapRange range,
public boolean affectedByBytesChange(AddressSpace space, TraceAddressSnapRange range,
DebuggerCoordinates coordinates) {
return false;
}

View file

@ -22,10 +22,10 @@ import ghidra.debug.api.action.*;
import ghidra.debug.api.tracemgr.DebuggerCoordinates;
import ghidra.framework.plugintool.ServiceProvider;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSpace;
import ghidra.program.util.ProgramLocation;
import ghidra.trace.model.TraceAddressSnapRange;
import ghidra.trace.model.stack.TraceStack;
import ghidra.trace.util.TraceAddressSpace;
public enum PCLocationTrackingSpec implements LocationTrackingSpec, LocationTracker {
INSTANCE;
@ -91,7 +91,7 @@ public enum PCLocationTrackingSpec implements LocationTrackingSpec, LocationTrac
}
@Override
public boolean affectedByBytesChange(TraceAddressSpace space, TraceAddressSnapRange range,
public boolean affectedByBytesChange(AddressSpace space, TraceAddressSnapRange range,
DebuggerCoordinates coordinates) {
return BY_REG.affectedByBytesChange(space, range, coordinates);
}

View file

@ -29,7 +29,6 @@ import ghidra.trace.model.memory.TraceMemorySpace;
import ghidra.trace.model.memory.TraceMemoryState;
import ghidra.trace.model.stack.TraceStack;
import ghidra.trace.model.thread.TraceThread;
import ghidra.trace.util.TraceAddressSpace;
public interface RegisterLocationTrackingSpec extends LocationTrackingSpec, LocationTracker {
Register computeRegister(DebuggerCoordinates coordinates);
@ -102,18 +101,17 @@ public interface RegisterLocationTrackingSpec extends LocationTrackingSpec, Loca
}
@Override
default boolean affectedByBytesChange(TraceAddressSpace space,
TraceAddressSnapRange range, DebuggerCoordinates coordinates) {
default boolean affectedByBytesChange(AddressSpace space, TraceAddressSnapRange range,
DebuggerCoordinates coordinates) {
if (!LocationTrackingSpec.changeIsCurrent(space, range, coordinates)) {
return false;
}
Register register = computeRegister(coordinates);
AddressSpace as = space.getAddressSpace();
if (register == null || register.getAddressSpace() != as) {
if (register == null) {
return false;
}
AddressRange regRng = coordinates.getPlatform()
.getConventionalRegisterRange(as.isRegisterSpace() ? as : null, register);
.getConventionalRegisterRange(space.isRegisterSpace() ? space : null, register);
return range.getRange().intersects(regRng);
}

View file

@ -28,13 +28,11 @@ import ghidra.framework.plugintool.ServiceProvider;
import ghidra.pcode.exec.*;
import ghidra.pcode.exec.DebuggerPcodeUtils.WatchValue;
import ghidra.pcode.exec.SleighUtils.AddressOf;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSetView;
import ghidra.program.model.address.*;
import ghidra.program.util.ProgramLocation;
import ghidra.trace.model.TraceAddressSnapRange;
import ghidra.trace.model.guest.TracePlatform;
import ghidra.trace.model.stack.TraceStack;
import ghidra.trace.util.TraceAddressSpace;
/**
* A tracking specification for the address of a given Sleigh expression
@ -151,7 +149,7 @@ public class WatchLocationTrackingSpec implements LocationTrackingSpec {
}
@Override
public boolean affectedByBytesChange(TraceAddressSpace space, TraceAddressSnapRange range,
public boolean affectedByBytesChange(AddressSpace space, TraceAddressSnapRange range,
DebuggerCoordinates coordinates) {
return LocationTrackingSpec.changeIsCurrent(space, range, coordinates) &&
(reads == null || reads.intersects(range.getX1(), range.getX2()));

View file

@ -24,13 +24,14 @@ import ghidra.debug.api.breakpoint.LogicalBreakpoint.State;
import ghidra.pcode.exec.SleighUtils;
import ghidra.program.model.address.Address;
import ghidra.program.util.ProgramLocation;
import ghidra.trace.model.breakpoint.TraceBreakpoint;
import ghidra.trace.model.breakpoint.TraceBreakpointLocation;
public class BreakpointLocationRow {
private final DebuggerBreakpointsProvider provider;
private final TraceBreakpoint loc;
private final TraceBreakpointLocation loc;
public BreakpointLocationRow(DebuggerBreakpointsProvider provider, TraceBreakpoint loc) {
public BreakpointLocationRow(DebuggerBreakpointsProvider provider,
TraceBreakpointLocation loc) {
this.provider = provider;
this.loc = loc;
}
@ -116,7 +117,7 @@ public class BreakpointLocationRow {
return !SleighUtils.UNCONDITIONAL_BREAK.equals(loc.getEmuSleigh(getSnap()));
}
public TraceBreakpoint getTraceBreakpoint() {
public TraceBreakpointLocation getTraceBreakpoint() {
return loc;
}
}

View file

@ -19,7 +19,7 @@ import java.util.Collection;
import java.util.stream.Collectors;
import docking.DefaultActionContext;
import ghidra.trace.model.breakpoint.TraceBreakpoint;
import ghidra.trace.model.breakpoint.TraceBreakpointLocation;
public class DebuggerBreakpointLocationsActionContext extends DefaultActionContext {
private final Collection<BreakpointLocationRow> selection;
@ -32,7 +32,7 @@ public class DebuggerBreakpointLocationsActionContext extends DefaultActionConte
return selection;
}
public Collection<TraceBreakpoint> getLocations() {
public Collection<TraceBreakpointLocation> getLocations() {
return selection.stream().map(row -> row.getTraceBreakpoint()).collect(Collectors.toList());
}
}

View file

@ -57,8 +57,8 @@ import ghidra.program.model.address.AddressRange;
import ghidra.program.util.MarkerLocation;
import ghidra.program.util.ProgramLocation;
import ghidra.trace.model.*;
import ghidra.trace.model.breakpoint.TraceBreakpoint;
import ghidra.trace.model.breakpoint.TraceBreakpointKind;
import ghidra.trace.model.breakpoint.TraceBreakpointLocation;
import ghidra.trace.util.TraceEvents;
import ghidra.util.*;
import ghidra.util.database.ObjectKey;
@ -230,11 +230,13 @@ public class DebuggerBreakpointsProvider extends ComponentProviderAdapter
protected static class BreakpointLocationTableModel
extends RowWrappedEnumeratedColumnTableModel< //
BreakpointLocationTableColumns, ObjectKey, BreakpointLocationRow, TraceBreakpoint> {
BreakpointLocationTableColumns, ObjectKey, BreakpointLocationRow, //
TraceBreakpointLocation> {
public BreakpointLocationTableModel(DebuggerBreakpointsProvider provider) {
super(provider.getTool(), "Locations", BreakpointLocationTableColumns.class,
TraceBreakpoint::getObjectKey, loc -> new BreakpointLocationRow(provider, loc),
TraceBreakpointLocation::getObjectKey,
loc -> new BreakpointLocationRow(provider, loc),
BreakpointLocationRow::getTraceBreakpoint);
}
@ -376,7 +378,7 @@ public class DebuggerBreakpointsProvider extends ComponentProviderAdapter
if (context instanceof DebuggerBreakpointLocationsActionContext) {
DebuggerBreakpointLocationsActionContext ctx =
(DebuggerBreakpointLocationsActionContext) context;
Collection<TraceBreakpoint> sel = ctx.getLocations();
Collection<TraceBreakpointLocation> sel = ctx.getLocations();
breakpointService.enableLocs(sel).exceptionally(ex -> {
breakpointError("Enable Breakpoints", "Could not enable breakpoints", ex);
return null;
@ -455,7 +457,7 @@ public class DebuggerBreakpointsProvider extends ComponentProviderAdapter
if (context instanceof DebuggerBreakpointLocationsActionContext) {
DebuggerBreakpointLocationsActionContext ctx =
(DebuggerBreakpointLocationsActionContext) context;
Collection<TraceBreakpoint> sel = ctx.getLocations();
Collection<TraceBreakpointLocation> sel = ctx.getLocations();
breakpointService.disableLocs(sel).exceptionally(ex -> {
breakpointError("Disable Breakpoints", "Could not disable breakpoints", ex);
return null;
@ -526,7 +528,7 @@ public class DebuggerBreakpointsProvider extends ComponentProviderAdapter
if (context instanceof DebuggerBreakpointLocationsActionContext) {
DebuggerBreakpointLocationsActionContext ctx =
(DebuggerBreakpointLocationsActionContext) context;
Collection<TraceBreakpoint> sel = ctx.getLocations();
Collection<TraceBreakpointLocation> sel = ctx.getLocations();
breakpointService.deleteLocs(sel).exceptionally(ex -> {
breakpointError("Clear Breakpoints", "Could not clear breakpoints", ex);
return null;
@ -700,26 +702,26 @@ public class DebuggerBreakpointsProvider extends ComponentProviderAdapter
reloadBreakpointLocations(trace);
}
private boolean isVisible(TraceBreakpoint location) {
private boolean isVisible(TraceBreakpointLocation location) {
long snap = traceManager.getCurrentFor(trace).getSnap();
return location.isValid(snap);
}
private void locationAdded(TraceBreakpoint location) {
private void locationAdded(TraceBreakpointLocation location) {
if (!isVisible(location)) {
return;
}
breakpointLocationAdded(location);
}
private void locationChanged(TraceBreakpoint location) {
private void locationChanged(TraceBreakpointLocation location) {
if (!isVisible(location)) {
return;
}
breakpointLocationUpdated(location);
}
private void locationLifespanChanged(TraceBreakpoint location, Lifespan oldSpan,
private void locationLifespanChanged(TraceBreakpointLocation location, Lifespan oldSpan,
Lifespan newSpan) {
long snap = traceManager.getCurrentFor(trace).getSnap();
boolean isLiveOld = oldSpan.contains(snap);
@ -735,7 +737,7 @@ public class DebuggerBreakpointsProvider extends ComponentProviderAdapter
}
}
private void locationDeleted(TraceBreakpoint location) {
private void locationDeleted(TraceBreakpointLocation location) {
if (!isVisible(location)) {
return;
}
@ -955,15 +957,15 @@ public class DebuggerBreakpointsProvider extends ComponentProviderAdapter
return;
}
Lifespan span = Lifespan.at(currentFor.getSnap());
Collection<TraceBreakpoint> visible = new ArrayList<>();
Collection<TraceBreakpointLocation> visible = new ArrayList<>();
for (AddressRange range : trace.getBaseAddressFactory().getAddressSet()) {
Collection<? extends TraceBreakpoint> breaks =
Collection<? extends TraceBreakpointLocation> breaks =
trace.getBreakpointManager().getBreakpointsIntersecting(span, range);
if (mode.useEmulatedBreakpoints()) {
visible.addAll(breaks);
}
else {
for (TraceBreakpoint l : breaks) {
for (TraceBreakpointLocation l : breaks) {
if (target.isBreakpointValid(l)) {
visible.add(l);
}
@ -982,19 +984,19 @@ public class DebuggerBreakpointsProvider extends ComponentProviderAdapter
loadBreakpointLocations(trace);
}
private void breakpointLocationAdded(TraceBreakpoint location) {
private void breakpointLocationAdded(TraceBreakpointLocation location) {
locationTableModel.addItem(location);
}
private void breakpointLocationUpdated(TraceBreakpoint location) {
private void breakpointLocationUpdated(TraceBreakpointLocation location) {
locationTableModel.updateItem(location);
}
private void breakpointLocationsUpdated(Collection<TraceBreakpoint> locations) {
private void breakpointLocationsUpdated(Collection<TraceBreakpointLocation> locations) {
locationTableModel.updateAllItems(locations);
}
private void breakpointLocationRemoved(TraceBreakpoint location) {
private void breakpointLocationRemoved(TraceBreakpointLocation location) {
locationTableModel.deleteItem(location);
}
@ -1304,12 +1306,12 @@ public class DebuggerBreakpointsProvider extends ComponentProviderAdapter
}
}
else if (ctx instanceof DebuggerBreakpointLocationsActionContext locCtx) {
Collection<TraceBreakpoint> locations = locCtx.getLocations();
Collection<TraceBreakpointLocation> locations = locCtx.getLocations();
if (locations.isEmpty()) {
return false;
}
for (TraceBreakpoint tb : locations) {
traces.add(tb.getTrace());
for (TraceBreakpointLocation loc : locations) {
traces.add(loc.getTrace());
}
}
else {
@ -1338,9 +1340,9 @@ public class DebuggerBreakpointsProvider extends ComponentProviderAdapter
return true;
}
else if (ctx instanceof DebuggerBreakpointLocationsActionContext locCtx) {
for (TraceBreakpoint tb : locCtx.getLocations()) {
long snap = traceManager.getCurrentFor(tb.getTrace()).getSnap();
if (!EXECUTE_KINDS.containsAll(tb.getKinds(snap))) {
for (TraceBreakpointLocation loc : locCtx.getLocations()) {
long snap = traceManager.getCurrentFor(loc.getTrace()).getSnap();
if (!EXECUTE_KINDS.containsAll(loc.getKinds(snap))) {
return false;
}
}
@ -1371,9 +1373,9 @@ public class DebuggerBreakpointsProvider extends ComponentProviderAdapter
return sleigh;
}
else if (ctx instanceof DebuggerBreakpointLocationsActionContext locCtx) {
for (TraceBreakpoint tb : locCtx.getLocations()) {
long snap = traceManager.getCurrentFor(tb.getTrace()).getSnap();
String s = tb.getEmuSleigh(snap);
for (TraceBreakpointLocation loc : locCtx.getLocations()) {
long snap = traceManager.getCurrentFor(loc.getTrace()).getSnap();
String s = loc.getEmuSleigh(snap);
if (sleigh != null && !sleigh.equals(s)) {
return null;
}
@ -1397,9 +1399,9 @@ public class DebuggerBreakpointsProvider extends ComponentProviderAdapter
}
}
else if (ctx instanceof DebuggerBreakpointLocationsActionContext locCtx) {
for (TraceBreakpoint tb : locCtx.getLocations()) {
long snap = traceManager.getCurrentFor(tb.getTrace()).getSnap();
tb.setEmuSleigh(snap, sleigh);
for (TraceBreakpointLocation loc : locCtx.getLocations()) {
long snap = traceManager.getCurrentFor(loc.getTrace()).getSnap();
loc.setEmuSleigh(snap, sleigh);
}
}
else {
@ -1466,7 +1468,7 @@ public class DebuggerBreakpointsProvider extends ComponentProviderAdapter
breakpointTableModel, breakpointFilterPanel);
}
public void setSelectedLocations(Set<TraceBreakpoint> sel) {
public void setSelectedLocations(Set<TraceBreakpointLocation> sel) {
DebuggerResources.setSelectedRows(sel, locationTableModel::getRow, locationTable,
locationTableModel, locationFilterPanel);
}

View file

@ -28,7 +28,7 @@ import ghidra.program.model.data.*;
import ghidra.program.model.listing.*;
import ghidra.program.model.symbol.*;
import ghidra.trace.model.Lifespan;
import ghidra.trace.model.breakpoint.TraceBreakpoint;
import ghidra.trace.model.breakpoint.TraceBreakpointLocation;
import ghidra.trace.model.memory.TraceMemoryManager;
import ghidra.trace.model.memory.TraceMemoryState;
import ghidra.trace.model.program.TraceProgramView;
@ -220,7 +220,7 @@ public class DebuggerCopyPlan {
public void copy(TraceProgramView from, AddressRange fromRange, Program into,
Address intoAddress, TaskMonitor monitor) throws Exception {
long snap = from.getSnap();
for (TraceBreakpoint bpt : from.getTrace()
for (TraceBreakpointLocation bpt : from.getTrace()
.getBreakpointManager()
.getBreakpointsIntersecting(Lifespan.at(from.getSnap()), fromRange)) {
monitor.checkCancelled();

View file

@ -32,7 +32,7 @@ import ghidra.program.model.address.*;
import ghidra.trace.model.Lifespan;
import ghidra.trace.model.Trace;
import ghidra.trace.model.memory.TraceMemoryFlag;
import ghidra.trace.model.memory.TraceObjectMemoryRegion;
import ghidra.trace.model.memory.TraceMemoryRegion;
import ghidra.trace.model.target.path.KeyPath;
import ghidra.trace.model.target.schema.TraceObjectSchema;
import ghidra.util.layout.PairLayout;
@ -161,8 +161,8 @@ public class DebuggerAddRegionDialog extends ReusableDialogComponentProvider {
if (rootSchema == null) {
return "";
}
KeyPath suitable = rootSchema.searchForSuitableContainer(TraceObjectMemoryRegion.class,
current.getPath());
KeyPath suitable =
rootSchema.searchForSuitableContainer(TraceMemoryRegion.class, current.getPath());
if (suitable == null) {
return "";
}

View file

@ -55,8 +55,7 @@ import ghidra.framework.options.SaveState;
import ghidra.framework.plugintool.*;
import ghidra.framework.plugintool.annotation.AutoConfigStateField;
import ghidra.framework.plugintool.annotation.AutoServiceConsumed;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSetView;
import ghidra.program.model.address.*;
import ghidra.program.model.listing.Program;
import ghidra.program.model.mem.Memory;
import ghidra.program.model.mem.MemoryBlock;
@ -65,7 +64,6 @@ import ghidra.program.util.ProgramSelection;
import ghidra.trace.model.Trace;
import ghidra.trace.model.TraceDomainObjectListener;
import ghidra.trace.model.program.TraceProgramView;
import ghidra.trace.util.TraceAddressSpace;
import ghidra.trace.util.TraceEvents;
import ghidra.util.Swing;
@ -99,8 +97,8 @@ public class DebuggerMemoryBytesProvider extends ProgramByteViewerComponentProvi
listenFor(TraceEvents.BYTES_CHANGED, this::bytesChanged);
}
private void bytesChanged(TraceAddressSpace space) {
if (space.getAddressSpace().isMemorySpace()) {
private void bytesChanged(AddressSpace space) {
if (space.isMemorySpace()) {
currCache.invalidate();
prevCache.invalidate();
}

View file

@ -29,13 +29,14 @@ import ghidra.framework.plugintool.ServiceProvider;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressRange;
import ghidra.trace.model.Trace;
import ghidra.trace.model.memory.*;
import ghidra.trace.model.memory.TraceMemoryRegion;
import ghidra.trace.model.memory.TraceMemory;
import ghidra.trace.model.target.TraceObject;
import ghidra.trace.model.target.path.KeyPath;
import ghidra.trace.model.target.schema.TraceObjectSchema;
import ghidra.trace.model.thread.TraceObjectProcess;
import ghidra.trace.model.thread.TraceProcess;
public class DebuggerRegionsPanel extends AbstractObjectsTableBasedPanel<TraceObjectMemoryRegion> {
public class DebuggerRegionsPanel extends AbstractObjectsTableBasedPanel<TraceMemoryRegion> {
private static class RegionKeyColumn extends TraceValueKeyColumn {
@Override
@ -66,7 +67,7 @@ public class DebuggerRegionsPanel extends AbstractObjectsTableBasedPanel<TraceOb
private static class RegionStartColumn extends AbstractTraceValueObjectAddressColumn {
public RegionStartColumn() {
super(TraceObjectMemoryRegion.KEY_RANGE);
super(TraceMemoryRegion.KEY_RANGE);
}
@Override
@ -82,7 +83,7 @@ public class DebuggerRegionsPanel extends AbstractObjectsTableBasedPanel<TraceOb
private static class RegionEndColumn extends AbstractTraceValueObjectAddressColumn {
public RegionEndColumn() {
super(TraceObjectMemoryRegion.KEY_RANGE);
super(TraceMemoryRegion.KEY_RANGE);
}
@Override
@ -98,7 +99,7 @@ public class DebuggerRegionsPanel extends AbstractObjectsTableBasedPanel<TraceOb
private static class RegionLengthColumn extends AbstractTraceValueObjectLengthColumn {
public RegionLengthColumn() {
super(TraceObjectMemoryRegion.KEY_RANGE);
super(TraceMemoryRegion.KEY_RANGE);
}
@Override
@ -120,7 +121,7 @@ public class DebuggerRegionsPanel extends AbstractObjectsTableBasedPanel<TraceOb
public static class RegionReadColumn extends RegionFlagColumn {
public RegionReadColumn() {
super(TraceObjectMemoryRegion.KEY_READABLE);
super(TraceMemoryRegion.KEY_READABLE);
}
@Override
@ -131,7 +132,7 @@ public class DebuggerRegionsPanel extends AbstractObjectsTableBasedPanel<TraceOb
public static class RegionWriteColumn extends RegionFlagColumn {
public RegionWriteColumn() {
super(TraceObjectMemoryRegion.KEY_WRITABLE);
super(TraceMemoryRegion.KEY_WRITABLE);
}
@Override
@ -142,7 +143,7 @@ public class DebuggerRegionsPanel extends AbstractObjectsTableBasedPanel<TraceOb
public static class RegionExecuteColumn extends RegionFlagColumn {
public RegionExecuteColumn() {
super(TraceObjectMemoryRegion.KEY_EXECUTABLE);
super(TraceMemoryRegion.KEY_EXECUTABLE);
}
@Override
@ -174,7 +175,7 @@ public class DebuggerRegionsPanel extends AbstractObjectsTableBasedPanel<TraceOb
protected static ModelQuery successorRegions(TraceObjectSchema rootSchema, KeyPath path) {
TraceObjectSchema schema = rootSchema.getSuccessorSchema(path);
return new ModelQuery(schema.searchFor(TraceObjectMemoryRegion.class, path, true));
return new ModelQuery(schema.searchFor(TraceMemoryRegion.class, path, true));
}
protected Set<TraceMemoryRegion> getSelectedRegions(DebuggerObjectActionContext ctx) {
@ -182,7 +183,7 @@ public class DebuggerRegionsPanel extends AbstractObjectsTableBasedPanel<TraceOb
}
public DebuggerRegionsPanel(DebuggerRegionsProvider provider) {
super(provider.plugin, provider, TraceObjectMemoryRegion.class);
super(provider.plugin, provider, TraceMemoryRegion.class);
}
@Override
@ -194,14 +195,14 @@ public class DebuggerRegionsPanel extends AbstractObjectsTableBasedPanel<TraceOb
protected ModelQuery computeQuery(TraceObject object) {
TraceObjectSchema rootSchema = object.getRoot().getSchema();
KeyPath seedPath = object.getCanonicalPath();
KeyPath processPath = rootSchema.searchForAncestor(TraceObjectProcess.class, seedPath);
KeyPath processPath = rootSchema.searchForAncestor(TraceProcess.class, seedPath);
if (processPath != null) {
ModelQuery result = successorRegions(rootSchema, processPath);
if (!result.isEmpty()) {
return result;
}
}
KeyPath memoryPath = rootSchema.searchForSuitable(TraceObjectMemory.class, seedPath);
KeyPath memoryPath = rootSchema.searchForSuitable(TraceMemory.class, seedPath);
if (memoryPath != null) {
ModelQuery result = successorRegions(rootSchema, memoryPath);
if (!result.isEmpty()) {

View file

@ -23,15 +23,17 @@ import ghidra.debug.api.tracemgr.DebuggerCoordinates;
import ghidra.framework.model.DomainObjectChangeRecord;
import ghidra.framework.model.DomainObjectEvent;
import ghidra.program.model.address.*;
import ghidra.trace.database.module.TraceObjectSection;
import ghidra.trace.model.*;
import ghidra.trace.model.breakpoint.*;
import ghidra.trace.model.memory.*;
import ghidra.trace.model.breakpoint.TraceBreakpointLocation;
import ghidra.trace.model.breakpoint.TraceBreakpointManager;
import ghidra.trace.model.memory.TraceMemoryManager;
import ghidra.trace.model.memory.TraceMemoryRegion;
import ghidra.trace.model.modules.*;
import ghidra.trace.model.target.TraceObject;
import ghidra.trace.model.target.TraceObjectValue;
import ghidra.trace.model.target.path.KeyPath;
import ghidra.trace.model.thread.*;
import ghidra.trace.model.thread.TraceThread;
import ghidra.trace.model.thread.TraceThreadManager;
import ghidra.trace.model.time.TraceTimeManager;
import ghidra.trace.util.TraceEvents;
import ghidra.util.Swing;
@ -100,7 +102,7 @@ public class DebuggerMemviewTraceListener extends TraceDomainObjectListener {
}
private void threadChanged(TraceThread thread) {
if (!trackThreads || !trackTrace || !(thread instanceof TraceObjectThread objThread)) {
if (!trackThreads || !trackTrace) {
return;
}
AddressFactory factory = thread.getTrace().getBaseAddressFactory();
@ -108,7 +110,7 @@ public class DebuggerMemviewTraceListener extends TraceDomainObjectListener {
Long threadId = thread.getKey();
AddressRange rng = rng(defaultSpace, threadId, threadId);
TraceObject obj = objThread.getObject();
TraceObject obj = thread.getObject();
obj.getCanonicalParents(Lifespan.ALL).forEach(p -> {
MemoryBox box = new MemoryBox(currentTrace, "Thread " + thread.getName(p.getMinSnap()),
MemviewBoxType.THREAD, rng, p.getLifespan());
@ -118,13 +120,12 @@ public class DebuggerMemviewTraceListener extends TraceDomainObjectListener {
}
private void regionChanged(TraceMemoryRegion region) {
if (!trackRegions || !trackTrace ||
!(region instanceof TraceObjectMemoryRegion objRegion)) {
if (!trackRegions || !trackTrace) {
return;
}
TraceObject obj = objRegion.getObject();
obj.getOrderedValues(Lifespan.ALL, TraceObjectMemoryRegion.KEY_RANGE, true).forEach(v -> {
TraceObject obj = region.getObject();
obj.getOrderedValues(Lifespan.ALL, TraceMemoryRegion.KEY_RANGE, true).forEach(v -> {
if (region.getName(v.getMinSnap()).equals("full memory")) {
return;
}
@ -136,12 +137,12 @@ public class DebuggerMemviewTraceListener extends TraceDomainObjectListener {
}
private void moduleChanged(TraceModule module) {
if (!trackModules || !trackTrace || !(module instanceof TraceObjectModule objModule)) {
if (!trackModules || !trackTrace) {
return;
}
TraceObject obj = objModule.getObject();
obj.getOrderedValues(Lifespan.ALL, TraceObjectModule.KEY_RANGE, true).forEach(v -> {
TraceObject obj = module.getObject();
obj.getOrderedValues(Lifespan.ALL, TraceModule.KEY_RANGE, true).forEach(v -> {
MemoryBox box = new MemoryBox(currentTrace, "Module " + module.getName(v.getMinSnap()),
MemviewBoxType.MODULE, v.castValue(), v.getLifespan());
updateList.add(box);
@ -150,12 +151,12 @@ public class DebuggerMemviewTraceListener extends TraceDomainObjectListener {
}
private void sectionChanged(TraceSection section) {
if (!trackSections || !trackTrace || !(section instanceof TraceObjectSection objSection)) {
if (!trackSections || !trackTrace) {
return;
}
TraceObject obj = objSection.getObject();
obj.getOrderedValues(Lifespan.ALL, TraceObjectSection.KEY_RANGE, true).forEach(v -> {
TraceObject obj = section.getObject();
obj.getOrderedValues(Lifespan.ALL, TraceSection.KEY_RANGE, true).forEach(v -> {
MemoryBox box = new MemoryBox(currentTrace, "Module " + section.getName(v.getMinSnap()),
MemviewBoxType.IMAGE, v.castValue(), v.getLifespan());
updateList.add(box);
@ -163,14 +164,13 @@ public class DebuggerMemviewTraceListener extends TraceDomainObjectListener {
updateLabelDebouncer.contact(null);
}
private void breakpointChanged(TraceBreakpoint bpt) {
if (!trackBreakpoints || !trackTrace ||
!(bpt instanceof TraceObjectBreakpointLocation objBpt)) {
private void breakpointChanged(TraceBreakpointLocation bpt) {
if (!trackBreakpoints || !trackTrace) {
return;
}
TraceObject obj = objBpt.getObject();
obj.getOrderedValues(Lifespan.ALL, TraceObjectBreakpointLocation.KEY_RANGE, true)
TraceObject obj = bpt.getObject();
obj.getOrderedValues(Lifespan.ALL, TraceBreakpointLocation.KEY_RANGE, true)
.forEach(v -> {
MemoryBox box =
new MemoryBox(currentTrace, "Module " + bpt.getName(v.getMinSnap()),
@ -301,7 +301,7 @@ public class DebuggerMemviewTraceListener extends TraceDomainObjectListener {
regionChanged(region);
}
TraceBreakpointManager breakpointManager = trace.getBreakpointManager();
for (TraceBreakpoint bpt : breakpointManager.getAllBreakpoints()) {
for (TraceBreakpointLocation bpt : breakpointManager.getAllBreakpointLocations()) {
breakpointChanged(bpt);
}
updateLabelDebouncer.contact(null);

View file

@ -130,7 +130,7 @@ public interface ObjectDefaultActionsMixin {
default boolean performDefaultAction(TraceObject object) {
Set<Class<? extends TraceObjectInterface>> interfaces =
object.getSchema().getInterfaces();
if (interfaces.contains(TraceObjectActivatable.class)) {
if (interfaces.contains(TraceActivatable.class)) {
activatePath(object.getCanonicalPath());
return true;
}
@ -138,7 +138,7 @@ public interface ObjectDefaultActionsMixin {
* Should I check aliveAndPresent() here? If I do, behavior changes when target is dead,
* which might be unexpected.
*/
if (interfaces.contains(TraceObjectTogglable.class)) {
if (interfaces.contains(TraceTogglable.class)) {
toggleObject(object);
return true;
}

View file

@ -26,8 +26,8 @@ import generic.theme.GIcon;
import ghidra.app.plugin.core.debug.gui.DebuggerResources;
import ghidra.framework.model.*;
import ghidra.trace.model.*;
import ghidra.trace.model.breakpoint.TraceObjectBreakpointLocation;
import ghidra.trace.model.breakpoint.TraceObjectBreakpointSpec;
import ghidra.trace.model.breakpoint.TraceBreakpointLocation;
import ghidra.trace.model.breakpoint.TraceBreakpointSpec;
import ghidra.trace.model.target.TraceObject;
import ghidra.trace.model.target.TraceObjectValue;
import ghidra.trace.model.target.iface.*;
@ -65,10 +65,10 @@ public class ObjectTreeModel implements DisplaysModified {
if (!value.getParent()
.getSchema()
.getInterfaces()
.contains(TraceObjectEventScope.class)) {
.contains(TraceEventScope.class)) {
return false;
}
if (!TraceObjectEventScope.KEY_EVENT_THREAD.equals(value.getEntryKey())) {
if (!TraceEventScope.KEY_EVENT_THREAD.equals(value.getEntryKey())) {
return false;
}
return true;
@ -77,12 +77,12 @@ public class ObjectTreeModel implements DisplaysModified {
protected boolean isEnabledValue(TraceObjectValue value) {
Set<Class<? extends TraceObjectInterface>> interfaces =
value.getParent().getSchema().getInterfaces();
if (!interfaces.contains(TraceObjectBreakpointSpec.class) &&
!interfaces.contains(TraceObjectBreakpointLocation.class) &&
!interfaces.contains(TraceObjectTogglable.class)) {
if (!interfaces.contains(TraceBreakpointSpec.class) &&
!interfaces.contains(TraceBreakpointLocation.class) &&
!interfaces.contains(TraceTogglable.class)) {
return false;
}
if (!TraceObjectTogglable.KEY_ENABLED.equals(value.getEntryKey())) {
if (!TraceTogglable.KEY_ENABLED.equals(value.getEntryKey())) {
return false;
}
return true;
@ -675,7 +675,7 @@ public class ObjectTreeModel implements DisplaysModified {
protected TraceObject getEventObject(TraceObject object) {
TraceObject scope = object
.findCanonicalAncestorsInterface(TraceObjectEventScope.class)
.findCanonicalAncestorsInterface(TraceEventScope.class)
.findFirst()
.orElse(null);
if (scope == null) {
@ -685,7 +685,7 @@ public class ObjectTreeModel implements DisplaysModified {
return null;
}
TraceObjectValue eventValue =
scope.getAttribute(snap, TraceObjectEventScope.KEY_EVENT_THREAD);
scope.getAttribute(snap, TraceEventScope.KEY_EVENT_THREAD);
if (eventValue == null || !eventValue.isObject()) {
return null;
}
@ -712,7 +712,7 @@ public class ObjectTreeModel implements DisplaysModified {
if (type.contains("Breakpoint") || type.contains("Watchpoint")) {
TraceObject object = edge.getChild();
TraceObjectValue en =
object.getAttribute(snap, TraceObjectTogglable.KEY_ENABLED);
object.getAttribute(snap, TraceTogglable.KEY_ENABLED);
// includes true or non-boolean values
if (en == null || !Objects.equals(false, en.getValue())) {
return DebuggerResources.ICON_SET_BREAKPOINT;

View file

@ -31,20 +31,20 @@ import ghidra.docking.settings.Settings;
import ghidra.framework.plugintool.Plugin;
import ghidra.framework.plugintool.ServiceProvider;
import ghidra.program.model.address.*;
import ghidra.trace.database.module.TraceObjectSection;
import ghidra.trace.model.Trace;
import ghidra.trace.model.modules.*;
import ghidra.trace.model.modules.TraceModule;
import ghidra.trace.model.modules.TraceSection;
import ghidra.trace.model.target.TraceObject;
import ghidra.trace.model.target.TraceObjectValue;
import ghidra.trace.model.target.path.KeyPath;
import ghidra.trace.model.target.schema.TraceObjectSchema;
import ghidra.trace.model.thread.TraceObjectProcess;
import ghidra.trace.model.thread.TraceProcess;
public class DebuggerModulesPanel extends AbstractObjectsTableBasedPanel<TraceObjectModule> {
public class DebuggerModulesPanel extends AbstractObjectsTableBasedPanel<TraceModule> {
private static class ModuleBaseColumn extends AbstractTraceValueObjectAddressColumn {
public ModuleBaseColumn() {
super(TraceObjectModule.KEY_RANGE);
super(TraceModule.KEY_RANGE);
}
@Override
@ -60,7 +60,7 @@ public class DebuggerModulesPanel extends AbstractObjectsTableBasedPanel<TraceOb
private static class ModuleMaxColumn extends AbstractTraceValueObjectAddressColumn {
public ModuleMaxColumn() {
super(TraceObjectModule.KEY_RANGE);
super(TraceModule.KEY_RANGE);
}
@Override
@ -76,7 +76,7 @@ public class DebuggerModulesPanel extends AbstractObjectsTableBasedPanel<TraceOb
private static class ModuleNameColumn extends TraceValueObjectAttributeColumn<String> {
public ModuleNameColumn() {
super(TraceObjectModule.KEY_MODULE_NAME, String.class);
super(TraceModule.KEY_MODULE_NAME, String.class);
}
@Override
@ -98,7 +98,7 @@ public class DebuggerModulesPanel extends AbstractObjectsTableBasedPanel<TraceOb
return "";
}
ValueAttribute<AddressRange> attr =
rowObject.getAttribute(TraceObjectModule.KEY_RANGE, AddressRange.class);
rowObject.getAttribute(TraceModule.KEY_RANGE, AddressRange.class);
if (attr == null) {
return "";
}
@ -131,7 +131,7 @@ public class DebuggerModulesPanel extends AbstractObjectsTableBasedPanel<TraceOb
private static class ModuleLengthColumn extends AbstractTraceValueObjectLengthColumn {
public ModuleLengthColumn() {
super(TraceObjectModule.KEY_RANGE);
super(TraceModule.KEY_RANGE);
}
@Override
@ -166,12 +166,12 @@ public class DebuggerModulesPanel extends AbstractObjectsTableBasedPanel<TraceOb
continue;
}
TraceObject child = value.getChild();
TraceObjectModule module = child.queryInterface(TraceObjectModule.class);
TraceModule module = child.queryInterface(TraceModule.class);
if (module != null) {
result.add(module);
continue;
}
TraceObjectSection section = child.queryInterface(TraceObjectSection.class);
TraceSection section = child.queryInterface(TraceSection.class);
if (section != null) {
result.add(section.getModule());
continue;
@ -188,12 +188,12 @@ public class DebuggerModulesPanel extends AbstractObjectsTableBasedPanel<TraceOb
continue;
}
TraceObject child = value.getChild();
TraceObjectModule module = child.queryInterface(TraceObjectModule.class);
TraceModule module = child.queryInterface(TraceModule.class);
if (module != null) {
result.addAll(module.getSections(ctx.getSnap()));
continue;
}
TraceObjectSection section = child.queryInterface(TraceObjectSection.class);
TraceSection section = child.queryInterface(TraceSection.class);
if (section != null) {
result.add(section);
continue;
@ -206,12 +206,12 @@ public class DebuggerModulesPanel extends AbstractObjectsTableBasedPanel<TraceOb
AddressSet result = new AddressSet();
for (TraceObjectValue value : ctx.getObjectValues()) {
TraceObject child = value.getChild();
TraceObjectModule module = child.queryInterface(TraceObjectModule.class);
TraceModule module = child.queryInterface(TraceModule.class);
if (module != null) {
result.add(module.getRange(ctx.getSnap()));
continue;
}
TraceObjectSection section = child.queryInterface(TraceObjectSection.class);
TraceSection section = child.queryInterface(TraceSection.class);
if (section != null) {
result.add(section.getRange(ctx.getSnap()));
continue;
@ -222,13 +222,13 @@ public class DebuggerModulesPanel extends AbstractObjectsTableBasedPanel<TraceOb
protected static ModelQuery successorModules(TraceObjectSchema rootSchema, KeyPath path) {
TraceObjectSchema schema = rootSchema.getSuccessorSchema(path);
return new ModelQuery(schema.searchFor(TraceObjectModule.class, path, true));
return new ModelQuery(schema.searchFor(TraceModule.class, path, true));
}
private final DebuggerModulesProvider provider;
public DebuggerModulesPanel(DebuggerModulesProvider provider) {
super(provider.plugin, provider, TraceObjectModule.class);
super(provider.plugin, provider, TraceModule.class);
this.provider = provider;
}
@ -241,15 +241,14 @@ public class DebuggerModulesPanel extends AbstractObjectsTableBasedPanel<TraceOb
protected ModelQuery computeQuery(TraceObject object) {
TraceObjectSchema rootSchema = object.getRoot().getSchema();
KeyPath seedPath = object.getCanonicalPath();
KeyPath processPath = rootSchema.searchForAncestor(TraceObjectProcess.class, seedPath);
KeyPath processPath = rootSchema.searchForAncestor(TraceProcess.class, seedPath);
if (processPath != null) {
ModelQuery result = successorModules(rootSchema, processPath);
if (!result.isEmpty()) {
return result;
}
}
KeyPath containerPath =
rootSchema.searchForSuitableContainer(TraceObjectModule.class, seedPath);
KeyPath containerPath = rootSchema.searchForSuitableContainer(TraceModule.class, seedPath);
if (containerPath != null) {
ModelQuery result = successorModules(rootSchema, containerPath);
if (!result.isEmpty()) {

View file

@ -547,7 +547,7 @@ public class DebuggerModulesProvider extends ComponentProviderAdapter
DebuggerModulesPanel modulesPanel;
DebuggerSectionsPanel sectionsPanel;
// TODO: Lazy construction of these dialogs?
// LATER?: Lazy construction of these dialogs?
private final DebuggerBlockChooserDialog blockChooserDialog;
private final DebuggerModuleMapProposalDialog moduleProposalDialog;
private final DebuggerSectionMapProposalDialog sectionProposalDialog;

View file

@ -30,22 +30,21 @@ import ghidra.framework.plugintool.Plugin;
import ghidra.framework.plugintool.ServiceProvider;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressRange;
import ghidra.trace.database.module.TraceObjectSection;
import ghidra.trace.model.Trace;
import ghidra.trace.model.modules.TraceObjectModule;
import ghidra.trace.model.modules.TraceModule;
import ghidra.trace.model.modules.TraceSection;
import ghidra.trace.model.target.TraceObject;
import ghidra.trace.model.target.TraceObjectValue;
import ghidra.trace.model.target.path.KeyPath;
import ghidra.trace.model.target.schema.TraceObjectSchema;
import ghidra.trace.model.thread.TraceObjectProcess;
import ghidra.trace.model.thread.TraceProcess;
public class DebuggerSectionsPanel extends AbstractObjectsTableBasedPanel<TraceObjectSection> {
public class DebuggerSectionsPanel extends AbstractObjectsTableBasedPanel<TraceSection> {
private static class SectionStartColumn extends AbstractTraceValueObjectAddressColumn {
public SectionStartColumn() {
super(TraceObjectSection.KEY_RANGE);
super(TraceSection.KEY_RANGE);
}
@Override
@ -61,7 +60,7 @@ public class DebuggerSectionsPanel extends AbstractObjectsTableBasedPanel<TraceO
private static class SectionEndColumn extends AbstractTraceValueObjectAddressColumn {
public SectionEndColumn() {
super(TraceObjectSection.KEY_RANGE);
super(TraceSection.KEY_RANGE);
}
@Override
@ -120,8 +119,8 @@ public class DebuggerSectionsPanel extends AbstractObjectsTableBasedPanel<TraceO
if (module == null) {
return "";
}
TraceObjectValue nameEntry = module.getAttribute(row.currentSnap(),
TraceObjectModule.KEY_MODULE_NAME);
TraceObjectValue nameEntry =
module.getAttribute(row.currentSnap(), TraceModule.KEY_MODULE_NAME);
if (nameEntry == null) {
return "";
}
@ -133,7 +132,7 @@ public class DebuggerSectionsPanel extends AbstractObjectsTableBasedPanel<TraceO
private static class SectionLengthColumn extends AbstractTraceValueObjectLengthColumn {
public SectionLengthColumn() {
super(TraceObjectSection.KEY_RANGE);
super(TraceSection.KEY_RANGE);
}
@Override
@ -161,21 +160,20 @@ public class DebuggerSectionsPanel extends AbstractObjectsTableBasedPanel<TraceO
}
private static TraceObject getModule(ValueRow row) {
TraceObjectValue moduleEntry =
row.getAttributeEntry(TraceObjectSection.KEY_MODULE);
TraceObjectValue moduleEntry = row.getAttributeEntry(TraceSection.KEY_MODULE);
if (moduleEntry != null && moduleEntry.isObject()) {
return moduleEntry.getChild();
}
return row.getValue()
.getChild()
.findCanonicalAncestorsInterface(TraceObjectModule.class)
.findCanonicalAncestorsInterface(TraceModule.class)
.findFirst()
.orElse(null);
}
protected static ModelQuery successorSections(TraceObjectSchema rootSchema, KeyPath path) {
TraceObjectSchema schema = rootSchema.getSuccessorSchema(path);
return new ModelQuery(schema.searchFor(TraceObjectSection.class, path, true));
return new ModelQuery(schema.searchFor(TraceSection.class, path, true));
}
private class SectionsBySelectedModulesTableFilter implements TableFilter<ValueRow> {
@ -201,7 +199,7 @@ public class DebuggerSectionsPanel extends AbstractObjectsTableBasedPanel<TraceO
new SectionsBySelectedModulesTableFilter();
public DebuggerSectionsPanel(DebuggerModulesProvider provider) {
super(provider.plugin, provider, TraceObjectSection.class);
super(provider.plugin, provider, TraceSection.class);
this.provider = provider;
}
@ -214,19 +212,18 @@ public class DebuggerSectionsPanel extends AbstractObjectsTableBasedPanel<TraceO
protected ModelQuery computeQuery(TraceObject object) {
TraceObjectSchema rootSchema = object.getRoot().getSchema();
KeyPath seedPath = object.getCanonicalPath();
KeyPath processPath = rootSchema.searchForAncestor(TraceObjectProcess.class, seedPath);
KeyPath processPath = rootSchema.searchForAncestor(TraceProcess.class, seedPath);
if (processPath != null) {
ModelQuery result = successorSections(rootSchema, processPath);
ModelQuery result = successorSections(rootSchema, processPath);
if (!result.isEmpty()) {
return result;
}
}
// Yes, anchor on the *module* container when searching for sections
KeyPath containerPath =
rootSchema.searchForSuitableContainer(TraceObjectModule.class, seedPath);
KeyPath containerPath = rootSchema.searchForSuitableContainer(TraceModule.class, seedPath);
if (containerPath != null) {
ModelQuery result = successorSections(rootSchema, containerPath);
ModelQuery result = successorSections(rootSchema, containerPath);
if (!result.isEmpty()) {
return result;
}

View file

@ -25,8 +25,8 @@ import ghidra.debug.api.ValStr;
import ghidra.framework.options.SaveState;
import ghidra.framework.plugintool.AutoConfigState.ConfigStateField;
import ghidra.framework.plugintool.PluginTool;
import ghidra.trace.model.target.iface.TraceObjectMethod;
import ghidra.trace.model.target.iface.TraceObjectMethod.ParameterDescription;
import ghidra.trace.model.target.iface.TraceMethod;
import ghidra.trace.model.target.iface.TraceMethod.ParameterDescription;
@Deprecated(forRemoval = true, since = "11.3")
public class DebuggerMethodInvocationDialog
@ -71,7 +71,7 @@ public class DebuggerMethodInvocationDialog
protected Map<String, ValStr<?>> validateArguments(
Map<String, ParameterDescription<?>> parameters, Map<String, ValStr<?>> arguments) {
Map<String, ?> args = ValStr.toPlainMap(arguments);
return ValStr.fromPlainMap(TraceObjectMethod.validateArguments(parameters, args, false));
return ValStr.fromPlainMap(TraceMethod.validateArguments(parameters, args, false));
}
@Override

View file

@ -69,9 +69,9 @@ import ghidra.trace.model.guest.TracePlatform;
import ghidra.trace.model.listing.*;
import ghidra.trace.model.memory.*;
import ghidra.trace.model.program.TraceProgramView;
import ghidra.trace.model.target.TraceObject;
import ghidra.trace.model.thread.TraceThread;
import ghidra.trace.util.*;
import ghidra.trace.util.TraceEvents;
import ghidra.trace.util.TraceRegisterUtils;
import ghidra.util.HelpLocation;
import ghidra.util.Msg;
import ghidra.util.classfinder.ClassSearcher;
@ -283,37 +283,28 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
listenFor(TraceEvents.THREAD_LIFESPAN_CHANGED, this::threadDestroyed);
}
private boolean isVisibleObjectsMode(AddressSpace space) {
TraceObject container = current.getRegisterContainer();
return container != null &&
container.getCanonicalPath().toString().equals(space.getName());
}
private boolean isVisible(TraceAddressSpace space) {
private boolean isVisible(AddressSpace space) {
if (!space.isRegisterSpace()) {
return true; // Memory-mapped, visible no matter the active thread
}
TraceThread curThread = current.getThread();
if (curThread == null) {
return false;
}
if (space.getAddressSpace().isOverlaySpace()) {
return isVisibleObjectsMode(space.getAddressSpace());
if (space.isOverlaySpace()) {
return current.isRegisterSpace(space);
}
if (!space.getAddressSpace().isRegisterSpace()) {
return true; // Memory-mapped, visible no matter the active thread
if (space.isRegisterSpace()) {
throw new AssertionError();
}
if (space.getThread() != curThread) {
return false;
}
if (space.getFrameLevel() != current.getFrame()) {
return false;
}
return true;
return false;
}
private boolean isVisible(TraceAddressSpace space, TraceAddressSnapRange range) {
private boolean isVisible(AddressSpace space, TraceAddressSnapRange range) {
if (!isVisible(space)) {
return false;
}
if (space.getAddressSpace().isMemorySpace()) {
if (space.isMemorySpace()) {
return current.getPlatform()
.getLanguage()
.getRegisterAddresses()
@ -351,7 +342,7 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
}
}
private void registerValueChanged(TraceAddressSpace space, TraceAddressSnapRange range,
private void registerValueChanged(AddressSpace space, TraceAddressSnapRange range,
byte[] oldIsNull, byte[] newVal) {
if (!isVisible(space, range)) {
return;
@ -359,7 +350,7 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
refreshRange(range.getRange());
}
private void registerStateChanged(TraceAddressSpace space, TraceAddressSnapRange range,
private void registerStateChanged(AddressSpace space, TraceAddressSnapRange range,
TraceMemoryState oldState, TraceMemoryState newState) {
if (!isVisible(space, range)) {
return;
@ -368,7 +359,7 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
refreshRange(range.getRange());
}
private void registerTypeAdded(TraceAddressSpace space, TraceAddressSnapRange range,
private void registerTypeAdded(AddressSpace space, TraceAddressSnapRange range,
TraceCodeUnit oldIsNull, TraceCodeUnit newUnit) {
if (!isVisible(space, range)) {
return;
@ -376,7 +367,7 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
refreshRange(range.getRange());
}
private void registerTypeReplaced(TraceAddressSpace space, TraceAddressSnapRange range,
private void registerTypeReplaced(AddressSpace space, TraceAddressSnapRange range,
long oldTypeID, long newTypeID) {
if (!isVisible(space, range)) {
return;
@ -384,7 +375,7 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
refreshRange(range.getRange());
}
private void registerTypeLifespanChanged(TraceAddressSpace space, TraceCodeUnit unit,
private void registerTypeLifespanChanged(AddressSpace space, TraceCodeUnit unit,
Lifespan oldSpan, Lifespan newSpan) {
if (!isVisible(space)) {
return;
@ -402,7 +393,7 @@ public class DebuggerRegistersProvider extends ComponentProviderAdapter
refreshRange(range); // Slightly wasteful, as we already have the data unit
}
private void registerTypeRemoved(TraceAddressSpace space, TraceAddressSnapRange range,
private void registerTypeRemoved(AddressSpace space, TraceAddressSnapRange range,
TraceCodeUnit oldUnit, TraceCodeUnit newIsNull) {
if (!isVisible(space)) {
return;

View file

@ -34,15 +34,15 @@ import ghidra.framework.plugintool.annotation.AutoServiceConsumed;
import ghidra.program.model.address.Address;
import ghidra.program.model.listing.Function;
import ghidra.trace.model.Trace;
import ghidra.trace.model.stack.TraceObjectStack;
import ghidra.trace.model.stack.TraceObjectStackFrame;
import ghidra.trace.model.stack.TraceStack;
import ghidra.trace.model.stack.TraceStackFrame;
import ghidra.trace.model.target.TraceObject;
import ghidra.trace.model.target.TraceObjectValue;
import ghidra.trace.model.target.path.KeyPath;
import ghidra.trace.model.target.path.PathFilter;
import ghidra.trace.model.target.schema.TraceObjectSchema;
public class DebuggerStackPanel extends AbstractObjectsTableBasedPanel<TraceObjectStackFrame>
public class DebuggerStackPanel extends AbstractObjectsTableBasedPanel<TraceStackFrame>
implements ListSelectionListener {
private static class FrameLevelColumn extends TraceValueKeyColumn {
@ -59,7 +59,7 @@ public class DebuggerStackPanel extends AbstractObjectsTableBasedPanel<TraceObje
private static class FramePcColumn extends TraceValueObjectAttributeColumn<Address> {
public FramePcColumn() {
super(TraceObjectStackFrame.KEY_PC, Address.class);
super(TraceStackFrame.KEY_PC, Address.class);
}
@Override
@ -72,7 +72,7 @@ public class DebuggerStackPanel extends AbstractObjectsTableBasedPanel<TraceObje
if (!(row.getValue().getValue() instanceof TraceObject object)) {
return null;
}
TraceObjectValue attrPc = object.getAttribute(snap, TraceObjectStackFrame.KEY_PC);
TraceObjectValue attrPc = object.getAttribute(snap, TraceStackFrame.KEY_PC);
if (attrPc == null || !(attrPc.getValue() instanceof Address pc)) {
return null;
}
@ -177,7 +177,7 @@ public class DebuggerStackPanel extends AbstractObjectsTableBasedPanel<TraceObje
protected DebuggerTraceManagerService traceManager;
public DebuggerStackPanel(DebuggerStackProvider provider) {
super(provider.plugin, provider, TraceObjectStackFrame.class);
super(provider.plugin, provider, TraceStackFrame.class);
this.provider = provider;
}
@ -190,12 +190,12 @@ public class DebuggerStackPanel extends AbstractObjectsTableBasedPanel<TraceObje
protected ModelQuery computeQuery(TraceObject object) {
TraceObjectSchema rootSchema = object.getRoot().getSchema();
KeyPath stackPath =
rootSchema.searchForSuitable(TraceObjectStack.class, object.getCanonicalPath());
rootSchema.searchForSuitable(TraceStack.class, object.getCanonicalPath());
if (stackPath == null) {
return ModelQuery.EMPTY;
}
TraceObjectSchema stackSchema = rootSchema.getSuccessorSchema(stackPath);
PathFilter filter = stackSchema.searchFor(TraceObjectStackFrame.class, stackPath, true);
PathFilter filter = stackSchema.searchFor(TraceStackFrame.class, stackPath, true);
return new ModelQuery(filter);
}

View file

@ -27,6 +27,7 @@ import ghidra.pcode.exec.DebuggerPcodeUtils.PrettyBytes;
import ghidra.pcode.exec.DebuggerPcodeUtils.WatchValue;
import ghidra.pcode.exec.ValueLocation;
import ghidra.program.model.address.AddressRange;
import ghidra.program.model.address.AddressSpace;
import ghidra.program.model.data.DataType;
import ghidra.program.model.lang.Language;
import ghidra.program.model.listing.*;
@ -35,8 +36,7 @@ import ghidra.program.model.pcode.Varnode;
import ghidra.trace.model.Trace;
import ghidra.trace.model.guest.TracePlatform;
import ghidra.trace.model.listing.TraceCodeUnit;
import ghidra.trace.model.memory.*;
import ghidra.trace.util.TraceAddressSpace;
import ghidra.trace.model.memory.TraceMemoryState;
import ghidra.util.HTMLUtilities;
import ghidra.util.Msg;
import ghidra.util.exception.InvalidInputException;
@ -366,17 +366,9 @@ public interface VariableValueRow {
* @param snap the snapshot key
* @return the composite state
*/
static TraceMemoryState computeState(Trace trace, TraceAddressSpace space, AddressRange range,
static TraceMemoryState computeState(Trace trace, AddressSpace space, AddressRange range,
long snap) {
TraceMemoryManager mem = trace.getMemoryManager();
TraceMemoryOperations ops;
if (space != null && space.getAddressSpace().isRegisterSpace()) {
ops = mem.getMemoryRegisterSpace(space.getThread(), space.getFrameLevel(), false);
}
else {
ops = mem;
}
return ops != null && ops.isKnown(snap, range)
return trace.getMemoryManager().isKnown(snap, range)
? TraceMemoryState.KNOWN
: TraceMemoryState.UNKNOWN;
}
@ -387,10 +379,11 @@ public interface VariableValueRow {
* @param unit the code unit
* @param snap the snapshot key
* @return the composite state.
* @see #computeState(Trace, TraceAddressSpace, AddressRange, long)
* @see #computeState(Trace, AddressSpace, AddressRange, long)
*/
static TraceMemoryState computeState(TraceCodeUnit unit, long snap) {
return computeState(unit.getTrace(), unit.getTraceSpace(), unit.getRange(), snap);
return computeState(unit.getTrace(), unit.getAddress().getAddressSpace(), unit.getRange(),
snap);
}
/**

View file

@ -46,7 +46,6 @@ import ghidra.trace.model.memory.*;
import ghidra.trace.model.stack.TraceStack;
import ghidra.trace.model.stack.TraceStackFrame;
import ghidra.trace.model.thread.TraceThread;
import ghidra.trace.util.TraceAddressSpace;
import ghidra.trace.util.TraceEvents;
import ghidra.util.MathUtilities;
import ghidra.util.Msg;
@ -672,10 +671,9 @@ public enum VariableValueUtils {
listenFor(TraceEvents.BYTES_CHANGED, this::bytesChanged);
}
private void bytesChanged(TraceAddressSpace space, TraceAddressSnapRange range) {
TraceThread thread = space.getThread();
private void bytesChanged(AddressSpace space, TraceAddressSnapRange range) {
// TODO: Consider the lifespan, too? Would have to use viewport....
if (thread == null || thread == coordinates.getThread()) {
if (space.isMemorySpace() || coordinates.isRegisterSpace(space)) {
invalidateCache();
}
}

View file

@ -38,17 +38,17 @@ import ghidra.program.model.address.Address;
import ghidra.program.model.listing.Function;
import ghidra.trace.model.Trace;
import ghidra.trace.model.target.TraceObject;
import ghidra.trace.model.target.iface.TraceObjectExecutionStateful;
import ghidra.trace.model.target.iface.TraceExecutionStateful;
import ghidra.trace.model.target.path.KeyPath;
import ghidra.trace.model.target.schema.TraceObjectSchema;
import ghidra.trace.model.thread.TraceObjectProcess;
import ghidra.trace.model.thread.TraceObjectThread;
import ghidra.trace.model.thread.TraceProcess;
import ghidra.trace.model.thread.TraceThread;
public class DebuggerThreadsPanel extends AbstractObjectsTableBasedPanel<TraceObjectThread> {
public class DebuggerThreadsPanel extends AbstractObjectsTableBasedPanel<TraceThread> {
protected static ModelQuery successorThreads(TraceObjectSchema rootSchema, KeyPath path) {
TraceObjectSchema schema = rootSchema.getSuccessorSchema(path);
return new ModelQuery(schema.searchFor(TraceObjectThread.class, path, true));
return new ModelQuery(schema.searchFor(TraceThread.class, path, true));
}
private static class ThreadPathColumn extends TraceValueKeyColumn {
@ -246,7 +246,7 @@ public class DebuggerThreadsPanel extends AbstractObjectsTableBasedPanel<TraceOb
private static class ThreadStateColumn extends TraceValueObjectAttributeColumn<String> {
public ThreadStateColumn() {
// NB. The recorder converts enums to strings
super(TraceObjectExecutionStateful.KEY_STATE, String.class);
super(TraceExecutionStateful.KEY_STATE, String.class);
}
@Override
@ -258,7 +258,7 @@ public class DebuggerThreadsPanel extends AbstractObjectsTableBasedPanel<TraceOb
private static class ThreadCommentColumn
extends TraceValueObjectEditableAttributeColumn<String> {
public ThreadCommentColumn() {
super(TraceObjectThread.KEY_COMMENT, String.class);
super(TraceThread.KEY_COMMENT, String.class);
}
@Override
@ -315,7 +315,7 @@ public class DebuggerThreadsPanel extends AbstractObjectsTableBasedPanel<TraceOb
};
public DebuggerThreadsPanel(DebuggerThreadsProvider provider) {
super(provider.plugin, provider, TraceObjectThread.class);
super(provider.plugin, provider, TraceThread.class);
this.provider = provider;
setLimitToSnap(false); // TODO: Toggle for this?
@ -346,18 +346,18 @@ public class DebuggerThreadsPanel extends AbstractObjectsTableBasedPanel<TraceOb
protected ModelQuery computeQuery(TraceObject object) {
TraceObjectSchema rootSchema = object.getRoot().getSchema();
KeyPath seedPath = object.getCanonicalPath();
KeyPath processPath = rootSchema.searchForAncestor(TraceObjectProcess.class, seedPath);
KeyPath processPath = rootSchema.searchForAncestor(TraceProcess.class, seedPath);
if (processPath != null) {
ModelQuery result = successorThreads(rootSchema, processPath);
ModelQuery result = successorThreads(rootSchema, processPath);
if (!result.isEmpty()) {
return result;
}
}
KeyPath containerPath =
rootSchema.searchForSuitableContainer(TraceObjectThread.class, seedPath);
rootSchema.searchForSuitableContainer(TraceThread.class, seedPath);
if (containerPath != null) {
ModelQuery result = successorThreads(rootSchema, containerPath);
ModelQuery result = successorThreads(rootSchema, containerPath);
if (!result.isEmpty()) {
return result;
}

View file

@ -42,11 +42,15 @@ import ghidra.trace.model.Lifespan;
import ghidra.trace.model.Trace;
import ghidra.trace.model.bookmark.TraceBookmark;
import ghidra.trace.model.bookmark.TraceBookmarkManager;
import ghidra.trace.model.breakpoint.*;
import ghidra.trace.model.memory.*;
import ghidra.trace.model.modules.*;
import ghidra.trace.model.breakpoint.TraceBreakpointLocation;
import ghidra.trace.model.breakpoint.TraceBreakpointManager;
import ghidra.trace.model.memory.TraceMemoryManager;
import ghidra.trace.model.memory.TraceMemoryRegion;
import ghidra.trace.model.modules.TraceModule;
import ghidra.trace.model.modules.TraceModuleManager;
import ghidra.trace.model.target.TraceObject;
import ghidra.trace.model.thread.*;
import ghidra.trace.model.thread.TraceThread;
import ghidra.trace.model.thread.TraceThreadManager;
import ghidra.util.HelpLocation;
import ghidra.util.Msg;
import ghidra.util.classfinder.ClassSearcher;
@ -82,7 +86,6 @@ public class TimeOverviewColorPlugin extends AbstractDebuggerPlugin {
@SuppressWarnings("unused")
private final AutoService.Wiring autoServiceWiring;
public static final String HELP_TOPIC = "OverviewPlugin";
private static final String ACTIVE_SERVICES = "ActiveServices";
private List<TimeOverviewColorService> allServices;
@ -270,27 +273,19 @@ public class TimeOverviewColorPlugin extends AbstractDebuggerPlugin {
Trace trace = traceManager.getCurrentTrace();
TraceThreadManager threadManager = trace.getThreadManager();
for (TraceThread thread : threadManager.getAllThreads()) {
if (thread instanceof TraceObjectThread objThread) {
addObject(set, objThread.getObject());
}
addObject(set, thread.getObject());
}
TraceModuleManager moduleManager = trace.getModuleManager();
for (TraceModule module : moduleManager.getAllModules()) {
if (module instanceof TraceObjectModule objModule) {
addObject(set, objModule.getObject());
}
addObject(set, module.getObject());
}
TraceMemoryManager memoryManager = trace.getMemoryManager();
for (TraceMemoryRegion region : memoryManager.getAllRegions()) {
if (region instanceof TraceObjectMemoryRegion objRegion) {
addObject(set, objRegion.getObject());
}
addObject(set, region.getObject());
}
TraceBreakpointManager breakpointManager = trace.getBreakpointManager();
for (TraceBreakpoint bpt : breakpointManager.getAllBreakpoints()) {
if (bpt instanceof TraceObjectBreakpointLocation objBreakpoint) {
addObject(set, objBreakpoint.getObject());
}
for (TraceBreakpointLocation bpt : breakpointManager.getAllBreakpointLocations()) {
addObject(set, bpt.getObject());
}
TraceBookmarkManager bookmarkManager = trace.getBookmarkManager();
for (TraceBookmark mark : bookmarkManager.getAllBookmarks()) {

View file

@ -23,11 +23,15 @@ import ghidra.framework.model.DomainObjectChangeRecord;
import ghidra.framework.model.DomainObjectEvent;
import ghidra.trace.model.*;
import ghidra.trace.model.bookmark.TraceBookmark;
import ghidra.trace.model.breakpoint.*;
import ghidra.trace.model.memory.*;
import ghidra.trace.model.modules.*;
import ghidra.trace.model.breakpoint.TraceBreakpointLocation;
import ghidra.trace.model.breakpoint.TraceBreakpointManager;
import ghidra.trace.model.memory.TraceMemoryManager;
import ghidra.trace.model.memory.TraceMemoryRegion;
import ghidra.trace.model.modules.TraceModule;
import ghidra.trace.model.modules.TraceModuleManager;
import ghidra.trace.model.target.TraceObject;
import ghidra.trace.model.thread.*;
import ghidra.trace.model.thread.TraceThread;
import ghidra.trace.model.thread.TraceThreadManager;
import ghidra.trace.util.TraceEvents;
import ghidra.util.Swing;
@ -118,193 +122,150 @@ public class TimeOverviewEventListener extends TraceDomainObjectListener {
regionChanged(region);
}
TraceBreakpointManager breakpointManager = trace.getBreakpointManager();
for (TraceBreakpoint bpt : breakpointManager.getAllBreakpoints()) {
for (TraceBreakpointLocation bpt : breakpointManager.getAllBreakpointLocations()) {
bptChanged(bpt);
}
}
private void threadAdded(TraceThread thread) {
if (!(thread instanceof TraceObjectThread objThread)) {
return;
}
TraceObject obj = objThread.getObject();
obj.getOrderedValues(Lifespan.ALL, TraceObjectBreakpointLocation.KEY_RANGE, true)
.forEach(v -> {
long snap = v.getMinSnap();
p.updateMap(snap, TimeType.BPT_ADDED, thread.getName(snap), true);
});
TraceObject obj = thread.getObject();
obj.getOrderedValues(Lifespan.ALL, TraceBreakpointLocation.KEY_RANGE, true)
.forEach(v -> {
long snap = v.getMinSnap();
p.updateMap(snap, TimeType.BPT_ADDED, thread.getName(snap), true);
});
}
private void threadChanged(TraceThread thread) {
if (!(thread instanceof TraceObjectThread objThread)) {
return;
}
TraceObject obj = objThread.getObject();
obj.getOrderedValues(Lifespan.ALL, TraceObjectThread.KEY_TID, true)
.forEach(v -> {
long snapMin = v.getMinSnap();
long snapMax = v.getMaxSnap();
if (snapMin == snapMax) {
p.updateMap(snapMin, TimeType.THREAD_CHANGED, thread.getName(snapMin), true);
}
else {
p.updateMap(snapMin, TimeType.THREAD_ADDED, thread.getName(snapMin), true);
p.updateMap(snapMax, TimeType.THREAD_REMOVED, thread.getName(snapMax), true);
}
});
TraceObject obj = thread.getObject();
obj.getOrderedValues(Lifespan.ALL, TraceThread.KEY_TID, true).forEach(v -> {
long snapMin = v.getMinSnap();
long snapMax = v.getMaxSnap();
if (snapMin == snapMax) {
p.updateMap(snapMin, TimeType.THREAD_CHANGED, thread.getName(snapMin),
true);
}
else {
p.updateMap(snapMin, TimeType.THREAD_ADDED, thread.getName(snapMin), true);
p.updateMap(snapMax, TimeType.THREAD_REMOVED, thread.getName(snapMax),
true);
}
});
}
private void threadDeleted(TraceThread thread) {
if (!(thread instanceof TraceObjectThread objThread)) {
return;
}
TraceObject obj = objThread.getObject();
obj.getOrderedValues(Lifespan.ALL, TraceObjectBreakpointLocation.KEY_RANGE, true)
.forEach(v -> {
long snap = v.getMaxSnap();
p.updateMap(snap, TimeType.THREAD_REMOVED, thread.getName(snap), true);
});
TraceObject obj = thread.getObject();
obj.getOrderedValues(Lifespan.ALL, TraceBreakpointLocation.KEY_RANGE, true)
.forEach(v -> {
long snap = v.getMaxSnap();
p.updateMap(snap, TimeType.THREAD_REMOVED, thread.getName(snap), true);
});
}
private void moduleAdded(TraceModule module) {
if (!(module instanceof TraceObjectModule objMod)) {
return;
}
TraceObject obj = objMod.getObject();
obj.getOrderedValues(Lifespan.ALL, TraceObjectBreakpointLocation.KEY_RANGE, true)
.forEach(v -> {
long snap = v.getMinSnap();
p.updateMap(snap, TimeType.MODULE_ADDED, module.getName(snap), true);
});
TraceObject obj = module.getObject();
obj.getOrderedValues(Lifespan.ALL, TraceBreakpointLocation.KEY_RANGE, true)
.forEach(v -> {
long snap = v.getMinSnap();
p.updateMap(snap, TimeType.MODULE_ADDED, module.getName(snap), true);
});
}
private void moduleChanged(TraceModule module) {
if (!(module instanceof TraceObjectModule objMod)) {
return;
}
TraceObject obj = objMod.getObject();
obj.getOrderedValues(Lifespan.ALL, TraceObjectBreakpointLocation.KEY_RANGE, true)
.forEach(v -> {
long snapMin = v.getMinSnap();
long snapMax = v.getMaxSnap();
if (snapMin == snapMax) {
p.updateMap(snapMin, TimeType.MODULE_CHANGED, module.getName(snapMin), true);
}
else {
p.updateMap(snapMin, TimeType.MODULE_ADDED, module.getName(snapMin), true);
p.updateMap(snapMax, TimeType.MODULE_REMOVED, module.getName(snapMax), true);
}
});
TraceObject obj = module.getObject();
obj.getOrderedValues(Lifespan.ALL, TraceBreakpointLocation.KEY_RANGE, true)
.forEach(v -> {
long snapMin = v.getMinSnap();
long snapMax = v.getMaxSnap();
if (snapMin == snapMax) {
p.updateMap(snapMin, TimeType.MODULE_CHANGED, module.getName(snapMin),
true);
}
else {
p.updateMap(snapMin, TimeType.MODULE_ADDED, module.getName(snapMin), true);
p.updateMap(snapMax, TimeType.MODULE_REMOVED, module.getName(snapMax),
true);
}
});
}
private void moduleDeleted(TraceModule module) {
if (!(module instanceof TraceObjectModule objMod)) {
return;
}
TraceObject obj = objMod.getObject();
obj.getOrderedValues(Lifespan.ALL, TraceObjectBreakpointLocation.KEY_RANGE, true)
.forEach(v -> {
long snap = v.getMaxSnap();
p.updateMap(snap, TimeType.MODULE_REMOVED, module.getName(snap), true);
});
TraceObject obj = module.getObject();
obj.getOrderedValues(Lifespan.ALL, TraceBreakpointLocation.KEY_RANGE, true)
.forEach(v -> {
long snap = v.getMaxSnap();
p.updateMap(snap, TimeType.MODULE_REMOVED, module.getName(snap), true);
});
}
private void regionAdded(TraceMemoryRegion region) {
if (!(region instanceof TraceObjectMemoryRegion objReg)) {
return;
}
TraceObject obj = objReg.getObject();
obj.getOrderedValues(Lifespan.ALL, TraceObjectBreakpointLocation.KEY_RANGE, true)
.forEach(v -> {
long snap = v.getMinSnap();
p.updateMap(snap, TimeType.REGION_ADDED, region.getName(snap), true);
});
TraceObject obj = region.getObject();
obj.getOrderedValues(Lifespan.ALL, TraceBreakpointLocation.KEY_RANGE, true)
.forEach(v -> {
long snap = v.getMinSnap();
p.updateMap(snap, TimeType.REGION_ADDED, region.getName(snap), true);
});
}
private void regionChanged(TraceMemoryRegion region) {
if (!(region instanceof TraceObjectMemoryRegion objReg)) {
return;
}
TraceObject obj = objReg.getObject();
obj.getOrderedValues(Lifespan.ALL, TraceObjectBreakpointLocation.KEY_RANGE, true)
.forEach(v -> {
long snapMin = v.getMinSnap();
long snapMax = v.getMaxSnap();
if (snapMin == snapMax) {
p.updateMap(snapMin, TimeType.REGION_CHANGED, region.getName(snapMin), true);
}
else {
p.updateMap(snapMin, TimeType.REGION_ADDED, region.getName(snapMin), true);
p.updateMap(snapMax, TimeType.REGION_REMOVED, region.getName(snapMax), true);
}
});
TraceObject obj = region.getObject();
obj.getOrderedValues(Lifespan.ALL, TraceBreakpointLocation.KEY_RANGE, true)
.forEach(v -> {
long snapMin = v.getMinSnap();
long snapMax = v.getMaxSnap();
if (snapMin == snapMax) {
p.updateMap(snapMin, TimeType.REGION_CHANGED, region.getName(snapMin),
true);
}
else {
p.updateMap(snapMin, TimeType.REGION_ADDED, region.getName(snapMin), true);
p.updateMap(snapMax, TimeType.REGION_REMOVED, region.getName(snapMax),
true);
}
});
}
private void regionDeleted(TraceMemoryRegion region) {
if (!(region instanceof TraceObjectMemoryRegion objReg)) {
return;
}
TraceObject obj = objReg.getObject();
obj.getOrderedValues(Lifespan.ALL, TraceObjectBreakpointLocation.KEY_RANGE, true)
.forEach(v -> {
long snap = v.getMaxSnap();
p.updateMap(snap, TimeType.REGION_REMOVED, region.getName(snap), true);
});
TraceObject obj = region.getObject();
obj.getOrderedValues(Lifespan.ALL, TraceBreakpointLocation.KEY_RANGE, true)
.forEach(v -> {
long snap = v.getMaxSnap();
p.updateMap(snap, TimeType.REGION_REMOVED, region.getName(snap), true);
});
}
private void bptAdded(TraceBreakpoint bpt) {
if (!(bpt instanceof TraceObjectBreakpointLocation objBpt)) {
return;
}
TraceObject obj = objBpt.getObject();
obj.getOrderedValues(Lifespan.ALL, TraceObjectBreakpointLocation.KEY_RANGE, true)
.forEach(v -> {
long snap = v.getMinSnap();
p.updateMap(snap, TimeType.BPT_ADDED, bpt.getName(snap), true);
});
private void bptAdded(TraceBreakpointLocation bpt) {
TraceObject obj = bpt.getObject();
obj.getOrderedValues(Lifespan.ALL, TraceBreakpointLocation.KEY_RANGE, true)
.forEach(v -> {
long snap = v.getMinSnap();
p.updateMap(snap, TimeType.BPT_ADDED, bpt.getName(snap), true);
});
}
private void bptChanged(TraceBreakpoint bpt) {
if (!(bpt instanceof TraceObjectBreakpointLocation objBpt)) {
return;
}
TraceObject obj = objBpt.getObject();
obj.getOrderedValues(Lifespan.ALL, TraceObjectBreakpointLocation.KEY_RANGE, true)
.forEach(v -> {
long snapMin = v.getMinSnap();
long snapMax = v.getMaxSnap();
if (snapMin == snapMax) {
p.updateMap(snapMin, TimeType.BPT_CHANGED, bpt.getName(snapMin), true);
}
else {
p.updateMap(snapMin, TimeType.BPT_ADDED, bpt.getName(snapMin), true);
p.updateMap(snapMax, TimeType.BPT_REMOVED, bpt.getName(snapMax), true);
}
});
private void bptChanged(TraceBreakpointLocation bpt) {
TraceObject obj = bpt.getObject();
obj.getOrderedValues(Lifespan.ALL, TraceBreakpointLocation.KEY_RANGE, true)
.forEach(v -> {
long snapMin = v.getMinSnap();
long snapMax = v.getMaxSnap();
if (snapMin == snapMax) {
p.updateMap(snapMin, TimeType.BPT_CHANGED, bpt.getName(snapMin), true);
}
else {
p.updateMap(snapMin, TimeType.BPT_ADDED, bpt.getName(snapMin), true);
p.updateMap(snapMax, TimeType.BPT_REMOVED, bpt.getName(snapMax), true);
}
});
}
private void bptDeleted(TraceBreakpoint bpt) {
if (!(bpt instanceof TraceObjectBreakpointLocation objBpt)) {
return;
}
TraceObject obj = objBpt.getObject();
obj.getOrderedValues(Lifespan.ALL, TraceObjectBreakpointLocation.KEY_RANGE, true)
.forEach(v -> {
long snap = v.getMaxSnap();
p.updateMap(snap, TimeType.BPT_REMOVED, bpt.getName(snap), true);
});
private void bptDeleted(TraceBreakpointLocation bpt) {
TraceObject obj = bpt.getObject();
obj.getOrderedValues(Lifespan.ALL, TraceBreakpointLocation.KEY_RANGE, true)
.forEach(v -> {
long snap = v.getMaxSnap();
p.updateMap(snap, TimeType.BPT_REMOVED, bpt.getName(snap), true);
});
}
private void bookmarkAdded(TraceBookmark bookmark) {

View file

@ -78,7 +78,6 @@ import ghidra.trace.model.*;
import ghidra.trace.model.guest.TracePlatform;
import ghidra.trace.model.program.TraceProgramView;
import ghidra.trace.model.time.schedule.TraceSchedule;
import ghidra.trace.util.TraceAddressSpace;
import ghidra.trace.util.TraceEvents;
import ghidra.util.HelpLocation;
import ghidra.util.Msg;
@ -260,14 +259,14 @@ public class DebuggerWatchesProvider extends ComponentProviderAdapter
}
}
private void bytesChanged(TraceAddressSpace space, TraceAddressSnapRange range) {
if (space.getThread() == current.getThread() || space.getThread() == null) {
private void bytesChanged(AddressSpace space, TraceAddressSnapRange range) {
if (space.isMemorySpace() || current.isRegisterSpace(space)) {
addChanged(range.getRange());
}
}
private void stateChanged(TraceAddressSpace space, TraceAddressSnapRange range) {
if (space.getThread() == current.getThread() || space.getThread() == null) {
private void stateChanged(AddressSpace space, TraceAddressSnapRange range) {
if (space.isMemorySpace() || current.isRegisterSpace(space)) {
addChanged(range.getRange());
}
}

View file

@ -529,7 +529,7 @@ public class DefaultWatchRow implements WatchRow {
DebuggerCoordinates current = provider.current;
Trace trace = current.getTrace();
Collection<? extends TraceLabelSymbol> labels =
trace.getSymbolManager().labels().getAt(current.getSnap(), null, address, false);
trace.getSymbolManager().labels().getAt(current.getSnap(), address, false);
if (!labels.isEmpty()) {
return labels.iterator().next();
}

View file

@ -22,7 +22,7 @@ import ghidra.trace.model.Lifespan;
import ghidra.trace.model.Trace;
import ghidra.trace.model.target.TraceObject;
import ghidra.trace.model.target.TraceObjectValue;
import ghidra.trace.model.target.iface.TraceObjectEnvironment;
import ghidra.trace.model.target.iface.TraceEnvironment;
import ghidra.trace.model.target.path.KeyPath;
import ghidra.trace.model.target.path.PathFilter;
import ghidra.util.Msg;
@ -67,7 +67,7 @@ public interface DebuggerPlatformOpinion extends ExtensionPoint {
}
TraceObject root = object.getRoot();
KeyPath pathToEnv = root.getSchema()
.searchForSuitable(TraceObjectEnvironment.class, object.getCanonicalPath());
.searchForSuitable(TraceEnvironment.class, object.getCanonicalPath());
if (pathToEnv == null) {
return null;
}
@ -86,15 +86,15 @@ public interface DebuggerPlatformOpinion extends ExtensionPoint {
}
static String getDebugggerFromEnv(TraceObject env, long snap) {
return getStringAttribute(env, snap, TraceObjectEnvironment.KEY_DEBUGGER);
return getStringAttribute(env, snap, TraceEnvironment.KEY_DEBUGGER);
}
static String getArchitectureFromEnv(TraceObject env, long snap) {
return getStringAttribute(env, snap, TraceObjectEnvironment.KEY_ARCH);
return getStringAttribute(env, snap, TraceEnvironment.KEY_ARCH);
}
static String getOperatingSystemFromEnv(TraceObject env, long snap) {
return getStringAttribute(env, snap, TraceObjectEnvironment.KEY_OS);
return getStringAttribute(env, snap, TraceEnvironment.KEY_OS);
}
/**
@ -105,7 +105,7 @@ public interface DebuggerPlatformOpinion extends ExtensionPoint {
* @return the endianness, or null
*/
static Endian getEndianFromEnv(TraceObject env, long snap) {
String strEndian = getStringAttribute(env, snap, TraceObjectEnvironment.KEY_ENDIAN);
String strEndian = getStringAttribute(env, snap, TraceEnvironment.KEY_ENDIAN);
if (strEndian == null) {
return null;
}

View file

@ -20,7 +20,7 @@ import java.util.concurrent.CompletableFuture;
import ghidra.async.AsyncFence;
import ghidra.debug.api.target.Target;
import ghidra.trace.model.breakpoint.TraceBreakpoint;
import ghidra.trace.model.breakpoint.TraceBreakpointLocation;
/**
* A de-duplicated collection of breakpoint action items necessary to implement a logical breakpoint
@ -37,11 +37,12 @@ public class BreakpointActionSet extends LinkedHashSet<BreakpointActionItem> {
* Add an item to enable a target breakpoint
*
* @param target the target
* @param bpt the target breakpoint
* @param loc the target breakpoint
* @return the added item
*/
public EnableTargetBreakpointActionItem planEnableTarget(Target target, TraceBreakpoint bpt) {
EnableTargetBreakpointActionItem action = new EnableTargetBreakpointActionItem(target, bpt);
public EnableTargetBreakpointActionItem planEnableTarget(Target target,
TraceBreakpointLocation loc) {
EnableTargetBreakpointActionItem action = new EnableTargetBreakpointActionItem(target, loc);
add(action);
return action;
}
@ -49,12 +50,12 @@ public class BreakpointActionSet extends LinkedHashSet<BreakpointActionItem> {
/**
* Add an item to enable an emulated breakpoint
*
* @param bpt the trace breakpoint
* @param loc the trace breakpoint
* @param snap the snap
* @return the added item
*/
public EnableEmuBreakpointActionItem planEnableEmu(TraceBreakpoint bpt, long snap) {
EnableEmuBreakpointActionItem action = new EnableEmuBreakpointActionItem(bpt, snap);
public EnableEmuBreakpointActionItem planEnableEmu(TraceBreakpointLocation loc, long snap) {
EnableEmuBreakpointActionItem action = new EnableEmuBreakpointActionItem(loc, snap);
add(action);
return action;
}
@ -63,12 +64,13 @@ public class BreakpointActionSet extends LinkedHashSet<BreakpointActionItem> {
* Add an item to disable a target breakpoint
*
* @param target the target
* @param bpt the target breakpoint
* @param loc the target breakpoint
* @return the added item
*/
public DisableTargetBreakpointActionItem planDisableTarget(Target target, TraceBreakpoint bpt) {
public DisableTargetBreakpointActionItem planDisableTarget(Target target,
TraceBreakpointLocation loc) {
DisableTargetBreakpointActionItem action =
new DisableTargetBreakpointActionItem(target, bpt);
new DisableTargetBreakpointActionItem(target, loc);
add(action);
return action;
}
@ -76,12 +78,12 @@ public class BreakpointActionSet extends LinkedHashSet<BreakpointActionItem> {
/**
* Add an item to disable an emulated breakpoint
*
* @param bpt the trace breakpoint
* @param loc the trace breakpoint
* @param snap the snap
* @return the added item
*/
public DisableEmuBreakpointActionItem planDisableEmu(TraceBreakpoint bpt, long snap) {
DisableEmuBreakpointActionItem action = new DisableEmuBreakpointActionItem(bpt, snap);
public DisableEmuBreakpointActionItem planDisableEmu(TraceBreakpointLocation loc, long snap) {
DisableEmuBreakpointActionItem action = new DisableEmuBreakpointActionItem(loc, snap);
add(action);
return action;
}
@ -90,11 +92,12 @@ public class BreakpointActionSet extends LinkedHashSet<BreakpointActionItem> {
* Add an item to delete a target breakpoint
*
* @param target the target
* @param bpt the target breakpoint
* @param loc the target breakpoint
* @return the added item
*/
public DeleteTargetBreakpointActionItem planDeleteTarget(Target target, TraceBreakpoint bpt) {
DeleteTargetBreakpointActionItem action = new DeleteTargetBreakpointActionItem(target, bpt);
public DeleteTargetBreakpointActionItem planDeleteTarget(Target target,
TraceBreakpointLocation loc) {
DeleteTargetBreakpointActionItem action = new DeleteTargetBreakpointActionItem(target, loc);
add(action);
return action;
}
@ -102,12 +105,12 @@ public class BreakpointActionSet extends LinkedHashSet<BreakpointActionItem> {
/**
* Add an item to delete an emulated breakpoint
*
* @param bpt the trace breakpoint
* @param loc the trace breakpoint
* @param snap the snap
* @return the added item
*/
public DeleteEmuBreakpointActionItem planDeleteEmu(TraceBreakpoint bpt, long snap) {
DeleteEmuBreakpointActionItem action = new DeleteEmuBreakpointActionItem(bpt, snap);
public DeleteEmuBreakpointActionItem planDeleteEmu(TraceBreakpointLocation loc, long snap) {
DeleteEmuBreakpointActionItem action = new DeleteEmuBreakpointActionItem(loc, snap);
add(action);
return action;
}

View file

@ -45,15 +45,13 @@ import ghidra.framework.model.*;
import ghidra.framework.plugintool.*;
import ghidra.framework.plugintool.annotation.AutoServiceConsumed;
import ghidra.framework.plugintool.util.PluginStatus;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressRange;
import ghidra.program.model.address.*;
import ghidra.program.model.listing.*;
import ghidra.program.util.*;
import ghidra.trace.model.*;
import ghidra.trace.model.breakpoint.TraceBreakpoint;
import ghidra.trace.model.breakpoint.TraceBreakpointKind;
import ghidra.trace.model.breakpoint.TraceBreakpointLocation;
import ghidra.trace.model.program.TraceProgramView;
import ghidra.trace.util.TraceAddressSpace;
import ghidra.trace.util.TraceEvents;
import ghidra.util.Msg;
import ghidra.util.datastruct.ListenerSet;
@ -228,7 +226,7 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
info.reloadBreakpoints(c);
}
private void breakpointAdded(TraceBreakpoint tb) {
private void breakpointAdded(TraceBreakpointLocation tb) {
if (!tb.isValid(info.snap)) {
return;
}
@ -241,7 +239,7 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
}
}
private void breakpointChanged(TraceBreakpoint tb) {
private void breakpointChanged(TraceBreakpointLocation tb) {
if (!tb.isValid(info.snap)) {
return;
}
@ -258,8 +256,8 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
}
}
private void breakpointLifespanChanged(TraceAddressSpace spaceIsNull, TraceBreakpoint tb,
Lifespan oldSpan, Lifespan newSpan) {
private void breakpointLifespanChanged(AddressSpace spaceIsNull,
TraceBreakpointLocation tb, Lifespan oldSpan, Lifespan newSpan) {
// NOTE: User/script probably modified historical breakpoint
boolean isInOld = oldSpan.contains(info.snap);
boolean isInNew = newSpan.contains(info.snap);
@ -280,7 +278,7 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
}
}
private void breakpointDeleted(TraceBreakpoint tb) {
private void breakpointDeleted(TraceBreakpointLocation tb) {
// Could check snap, but might as well just be sure it's gone
info.forgetTraceBreakpoint(c.r, tb);
}
@ -360,7 +358,8 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
long length, Collection<TraceBreakpointKind> kinds);
protected LogicalBreakpointInternal getOrCreateLogicalBreakpointFor(AddCollector a,
Address address, TraceBreakpoint tb, long snap) throws TrackedTooSoonException {
Address address, TraceBreakpointLocation tb, long snap)
throws TrackedTooSoonException {
Set<LogicalBreakpointInternal> set =
logicalByAddress.computeIfAbsent(address, __ -> new HashSet<>());
for (LogicalBreakpointInternal lb : set) {
@ -377,7 +376,7 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
}
protected boolean removeLogicalBreakpoint(Address address, LogicalBreakpoint lb) {
for (TraceBreakpoint tb : lb.getTraceBreakpoints()) {
for (TraceBreakpointLocation tb : lb.getTraceBreakpoints()) {
InfoPerTrace info = traceInfos.get(tb.getTrace());
if (info != null) {
info.logicalByBreakpoint.remove(tb);
@ -435,7 +434,8 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
}
protected class InfoPerTrace extends AbstractInfo {
final Map<TraceBreakpoint, LogicalBreakpointInternal> logicalByBreakpoint = new HashMap<>();
final Map<TraceBreakpointLocation, LogicalBreakpointInternal> logicalByBreakpoint =
new HashMap<>();
final Trace trace;
final TraceBreakpointsListener breakpointListener;
@ -486,12 +486,12 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
}
protected void forgetAllBreakpoints(RemoveCollector r) {
Collection<TraceBreakpoint> toForget = new ArrayList<>();
Collection<TraceBreakpointLocation> toForget = new ArrayList<>();
for (AddressRange range : trace.getBaseAddressFactory().getAddressSet()) {
toForget.addAll(
trace.getBreakpointManager().getBreakpointsIntersecting(Lifespan.ALL, range));
}
for (TraceBreakpoint tb : toForget) {
for (TraceBreakpointLocation tb : toForget) {
forgetTraceBreakpoint(r, tb);
}
}
@ -504,16 +504,16 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
*/
ControlMode mode = getMode(trace);
for (Entry<TraceBreakpoint, LogicalBreakpointInternal> ent : Set
for (Entry<TraceBreakpointLocation, LogicalBreakpointInternal> ent : Set
.copyOf(logicalByBreakpoint.entrySet())) {
TraceBreakpoint tb = ent.getKey();
TraceBreakpointLocation tb = ent.getKey();
LogicalBreakpoint lb = ent.getValue();
if (!mode.useEmulatedBreakpoints() &&
(target == null || !target.isBreakpointValid(tb))) {
forgetTraceBreakpoint(r, tb);
continue;
}
if (!trace.getBreakpointManager().getAllBreakpoints().contains(tb)) {
if (!trace.getBreakpointManager().getAllBreakpointLocations().contains(tb)) {
forgetTraceBreakpoint(r, tb);
continue;
}
@ -536,7 +536,7 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
if (!mode.useEmulatedBreakpoints() && target == null) {
return;
}
Collection<TraceBreakpoint> visible = new ArrayList<>();
Collection<TraceBreakpointLocation> visible = new ArrayList<>();
for (AddressRange range : trace.getBaseAddressFactory().getAddressSet()) {
visible.addAll(trace.getBreakpointManager()
.getBreakpointsIntersecting(Lifespan.at(snap), range));
@ -545,8 +545,8 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
}
protected void trackTraceBreakpoints(AddCollector a,
Collection<TraceBreakpoint> breakpoints, ControlMode mode) {
for (TraceBreakpoint tb : breakpoints) {
Collection<TraceBreakpointLocation> breakpoints, ControlMode mode) {
for (TraceBreakpointLocation tb : breakpoints) {
try {
/**
* Sadly, even something as simple as toggling a breakpoint can cause so many
@ -562,7 +562,7 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
}
}
protected ProgramLocation computeStaticLocation(TraceBreakpoint tb) {
protected ProgramLocation computeStaticLocation(TraceBreakpointLocation tb) {
if (traceManager == null || !traceManager.getOpenTraces().contains(tb.getTrace())) {
/**
* Mapping service will throw an exception otherwise. NB: When trace is opened,
@ -579,7 +579,8 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
new DefaultTraceLocation(trace, null, Lifespan.at(snap), minAddress));
}
protected void trackTraceBreakpoint(AddCollector a, TraceBreakpoint tb, ControlMode mode,
protected void trackTraceBreakpoint(AddCollector a, TraceBreakpointLocation tb,
ControlMode mode,
boolean forceUpdate) throws TrackedTooSoonException {
if (!mode.useEmulatedBreakpoints() &&
(target == null || !target.isBreakpointValid(tb))) {
@ -607,7 +608,7 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
}
protected LogicalBreakpointInternal removeFromLogicalBreakpoint(RemoveCollector r,
TraceBreakpoint tb) {
TraceBreakpointLocation tb) {
LogicalBreakpointInternal lb = logicalByBreakpoint.remove(tb);
if (lb == null || !lb.untrackBreakpoint(tb)) {
return null;
@ -624,7 +625,7 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
return lb;
}
protected void forgetTraceBreakpoint(RemoveCollector r, TraceBreakpoint tb) {
protected void forgetTraceBreakpoint(RemoveCollector r, TraceBreakpointLocation tb) {
LogicalBreakpointInternal lb = removeFromLogicalBreakpoint(r, tb);
if (lb == null) {
return; // Warnings already logged
@ -1114,7 +1115,7 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
}
@Override
public LogicalBreakpoint getBreakpoint(TraceBreakpoint bpt) {
public LogicalBreakpoint getBreakpoint(TraceBreakpointLocation bpt) {
Trace trace = bpt.getTrace();
synchronized (lock) {
InfoPerTrace info = traceInfos.get(trace);
@ -1271,18 +1272,18 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
}
interface TargetBreakpointConsumer {
void accept(BreakpointActionSet actions, Target target, TraceBreakpoint tb);
void accept(BreakpointActionSet actions, Target target, TraceBreakpointLocation tb);
}
interface EmuBreakpointConsumer {
void accept(BreakpointActionSet actions, TraceBreakpoint tb, long snap);
void accept(BreakpointActionSet actions, TraceBreakpointLocation tb, long snap);
}
interface ProgramBreakpointConsumer {
void accept(LogicalBreakpoint lb);
}
private void planActOnLoc(BreakpointActionSet actions, TraceBreakpoint tb,
private void planActOnLoc(BreakpointActionSet actions, TraceBreakpointLocation tb,
TargetBreakpointConsumer targetBptConsumer, EmuBreakpointConsumer emuLocConsumer) {
ControlMode mode = getMode(tb.getTrace());
if (mode.useEmulatedBreakpoints()) {
@ -1293,7 +1294,7 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
}
}
private void planActOnLocTarget(BreakpointActionSet actions, TraceBreakpoint tb,
private void planActOnLocTarget(BreakpointActionSet actions, TraceBreakpointLocation tb,
TargetBreakpointConsumer targetBptConsumer) {
Target target = targetService == null ? null : targetService.getTarget(tb.getTrace());
if (target == null) {
@ -1302,7 +1303,7 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
targetBptConsumer.accept(actions, target, tb);
}
private void planActOnLocEmu(BreakpointActionSet actions, TraceBreakpoint tb,
private void planActOnLocEmu(BreakpointActionSet actions, TraceBreakpointLocation tb,
EmuBreakpointConsumer emuLocConsumer) {
InfoPerTrace info = traceInfos.get(tb.getTrace());
if (info == null) {
@ -1312,12 +1313,12 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
emuLocConsumer.accept(actions, tb, info.snap);
}
protected CompletableFuture<Void> actOnLocs(Collection<TraceBreakpoint> col,
protected CompletableFuture<Void> actOnLocs(Collection<TraceBreakpointLocation> col,
TargetBreakpointConsumer targetBptConsumer,
EmuBreakpointConsumer emuLocConsumer,
ProgramBreakpointConsumer progConsumer) {
BreakpointActionSet actions = new BreakpointActionSet();
for (TraceBreakpoint tb : col) {
for (TraceBreakpointLocation tb : col) {
LogicalBreakpoint lb = getBreakpoint(tb);
if (col.containsAll(lb.getTraceBreakpoints())) {
progConsumer.accept(lb);
@ -1328,19 +1329,19 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
}
@Override
public CompletableFuture<Void> enableLocs(Collection<TraceBreakpoint> col) {
public CompletableFuture<Void> enableLocs(Collection<TraceBreakpointLocation> col) {
return actOnLocs(col, BreakpointActionSet::planEnableTarget,
BreakpointActionSet::planEnableEmu, LogicalBreakpoint::enableForProgram);
}
@Override
public CompletableFuture<Void> disableLocs(Collection<TraceBreakpoint> col) {
public CompletableFuture<Void> disableLocs(Collection<TraceBreakpointLocation> col) {
return actOnLocs(col, BreakpointActionSet::planDisableTarget,
BreakpointActionSet::planDisableEmu, LogicalBreakpoint::disableForProgram);
}
@Override
public CompletableFuture<Void> deleteLocs(Collection<TraceBreakpoint> col) {
public CompletableFuture<Void> deleteLocs(Collection<TraceBreakpointLocation> col) {
return actOnLocs(col, BreakpointActionSet::planDeleteTarget,
BreakpointActionSet::planDeleteEmu, lb -> {
// Never delete bookmark when user requests deleting locations

View file

@ -19,20 +19,20 @@ import java.util.concurrent.CompletableFuture;
import db.Transaction;
import ghidra.async.AsyncUtils;
import ghidra.trace.model.breakpoint.TraceBreakpoint;
import ghidra.trace.model.breakpoint.TraceBreakpointLocation;
public record DeleteEmuBreakpointActionItem(TraceBreakpoint bpt, long snap)
public record DeleteEmuBreakpointActionItem(TraceBreakpointLocation loc, long snap)
implements BreakpointActionItem {
@Override
public CompletableFuture<Void> execute() {
try (Transaction tx =
bpt.getTrace().openTransaction("Delete Emulated Breakpoint")) {
String emuName = PlaceEmuBreakpointActionItem.createName(bpt.getMinAddress(snap));
if (bpt.getPath().contains(emuName)) {
bpt.delete();
loc.getTrace().openTransaction("Delete Emulated Breakpoint")) {
String emuName = PlaceEmuBreakpointActionItem.createName(loc.getMinAddress(snap));
if (loc.getPath().contains(emuName)) {
loc.delete();
}
else {
bpt.setEmuEnabled(snap, false);
loc.setEmuEnabled(snap, false);
}
}
return AsyncUtils.nil();

View file

@ -18,12 +18,12 @@ package ghidra.app.plugin.core.debug.service.breakpoint;
import java.util.concurrent.CompletableFuture;
import ghidra.debug.api.target.Target;
import ghidra.trace.model.breakpoint.TraceBreakpoint;
import ghidra.trace.model.breakpoint.TraceBreakpointLocation;
public record DeleteTargetBreakpointActionItem(Target target, TraceBreakpoint bpt)
public record DeleteTargetBreakpointActionItem(Target target, TraceBreakpointLocation loc)
implements BreakpointActionItem {
@Override
public CompletableFuture<Void> execute() {
return target.deleteBreakpointAsync(bpt);
return target.deleteBreakpointAsync(loc);
}
}

View file

@ -19,15 +19,15 @@ import java.util.concurrent.CompletableFuture;
import db.Transaction;
import ghidra.async.AsyncUtils;
import ghidra.trace.model.breakpoint.TraceBreakpoint;
import ghidra.trace.model.breakpoint.TraceBreakpointLocation;
public record DisableEmuBreakpointActionItem(TraceBreakpoint bpt, long snap)
public record DisableEmuBreakpointActionItem(TraceBreakpointLocation loc, long snap)
implements BreakpointActionItem {
@Override
public CompletableFuture<Void> execute() {
try (Transaction tx =
bpt.getTrace().openTransaction("Disable Emulated Breakpoint")) {
bpt.setEmuEnabled(snap, false);
loc.getTrace().openTransaction("Disable Emulated Breakpoint")) {
loc.setEmuEnabled(snap, false);
}
return AsyncUtils.nil();
}

View file

@ -18,12 +18,12 @@ package ghidra.app.plugin.core.debug.service.breakpoint;
import java.util.concurrent.CompletableFuture;
import ghidra.debug.api.target.Target;
import ghidra.trace.model.breakpoint.TraceBreakpoint;
import ghidra.trace.model.breakpoint.TraceBreakpointLocation;
public record DisableTargetBreakpointActionItem(Target target, TraceBreakpoint bpt)
public record DisableTargetBreakpointActionItem(Target target, TraceBreakpointLocation loc)
implements BreakpointActionItem {
@Override
public CompletableFuture<Void> execute() {
return target.toggleBreakpointAsync(bpt, false);
return target.toggleBreakpointAsync(loc, false);
}
}

View file

@ -19,15 +19,15 @@ import java.util.concurrent.CompletableFuture;
import db.Transaction;
import ghidra.async.AsyncUtils;
import ghidra.trace.model.breakpoint.TraceBreakpoint;
import ghidra.trace.model.breakpoint.TraceBreakpointLocation;
public record EnableEmuBreakpointActionItem(TraceBreakpoint bpt, long snap)
public record EnableEmuBreakpointActionItem(TraceBreakpointLocation loc, long snap)
implements BreakpointActionItem {
@Override
public CompletableFuture<Void> execute() {
try (Transaction tx =
bpt.getTrace().openTransaction("Enable Emulated Breakpoint")) {
bpt.setEmuEnabled(snap, true);
loc.getTrace().openTransaction("Enable Emulated Breakpoint")) {
loc.setEmuEnabled(snap, true);
}
return AsyncUtils.nil();
}

View file

@ -18,12 +18,12 @@ package ghidra.app.plugin.core.debug.service.breakpoint;
import java.util.concurrent.CompletableFuture;
import ghidra.debug.api.target.Target;
import ghidra.trace.model.breakpoint.TraceBreakpoint;
import ghidra.trace.model.breakpoint.TraceBreakpointLocation;
public record EnableTargetBreakpointActionItem(Target target, TraceBreakpoint bpt)
public record EnableTargetBreakpointActionItem(Target target, TraceBreakpointLocation loc)
implements BreakpointActionItem {
@Override
public CompletableFuture<Void> execute() {
return target.toggleBreakpointAsync(bpt, true);
return target.toggleBreakpointAsync(loc, true);
}
}

View file

@ -21,7 +21,7 @@ import ghidra.program.model.address.Address;
import ghidra.program.model.listing.Bookmark;
import ghidra.program.model.listing.Program;
import ghidra.trace.model.Trace;
import ghidra.trace.model.breakpoint.TraceBreakpoint;
import ghidra.trace.model.breakpoint.TraceBreakpointLocation;
public interface LogicalBreakpointInternal extends LogicalBreakpoint {
/**
@ -60,13 +60,13 @@ public interface LogicalBreakpointInternal extends LogicalBreakpoint {
* @return true if it can be aggregated.
* @throws TrackedTooSoonException if the containing trace is still being added to the manager
*/
boolean canMerge(TraceBreakpoint breakpoint, long snap) throws TrackedTooSoonException;
boolean canMerge(TraceBreakpointLocation breakpoint, long snap) throws TrackedTooSoonException;
boolean trackBreakpoint(Bookmark bookmark);
boolean trackBreakpoint(TraceBreakpoint breakpoint);
boolean trackBreakpoint(TraceBreakpointLocation breakpoint);
boolean untrackBreakpoint(TraceBreakpoint breakpoint);
boolean untrackBreakpoint(TraceBreakpointLocation breakpoint);
boolean untrackBreakpoint(Program program, Bookmark bookmark);

View file

@ -27,8 +27,8 @@ import ghidra.program.model.listing.Bookmark;
import ghidra.program.model.listing.Program;
import ghidra.program.util.ProgramLocation;
import ghidra.trace.model.Trace;
import ghidra.trace.model.breakpoint.TraceBreakpoint;
import ghidra.trace.model.breakpoint.TraceBreakpointKind;
import ghidra.trace.model.breakpoint.TraceBreakpointLocation;
public class LoneLogicalBreakpoint implements LogicalBreakpointInternal {
private final Set<Trace> justThisTrace;
@ -111,12 +111,12 @@ public class LoneLogicalBreakpoint implements LogicalBreakpointInternal {
}
@Override
public Set<TraceBreakpoint> getTraceBreakpoints() {
public Set<TraceBreakpointLocation> getTraceBreakpoints() {
return breaks.getBreakpoints();
}
@Override
public Set<TraceBreakpoint> getTraceBreakpoints(Trace trace) {
public Set<TraceBreakpointLocation> getTraceBreakpoints(Trace trace) {
return breaks.getTrace() != trace ? Set.of() : getTraceBreakpoints();
}
@ -165,7 +165,7 @@ public class LoneLogicalBreakpoint implements LogicalBreakpointInternal {
}
@Override
public State computeStateForLocation(TraceBreakpoint loc) {
public State computeStateForLocation(TraceBreakpointLocation loc) {
if (!breaks.getBreakpoints().contains(loc)) {
return State.NONE;
}
@ -278,7 +278,7 @@ public class LoneLogicalBreakpoint implements LogicalBreakpointInternal {
}
@Override
public boolean canMerge(TraceBreakpoint breakpoint, long snap) {
public boolean canMerge(TraceBreakpointLocation breakpoint, long snap) {
if (!Objects.equals(kinds, breakpoint.getKinds(snap))) {
return false;
}
@ -291,7 +291,7 @@ public class LoneLogicalBreakpoint implements LogicalBreakpointInternal {
}
@Override
public boolean trackBreakpoint(TraceBreakpoint breakpoint) {
public boolean trackBreakpoint(TraceBreakpointLocation breakpoint) {
return breaks.add(breakpoint);
}
@ -301,7 +301,7 @@ public class LoneLogicalBreakpoint implements LogicalBreakpointInternal {
}
@Override
public boolean untrackBreakpoint(TraceBreakpoint breakpoint) {
public boolean untrackBreakpoint(TraceBreakpointLocation breakpoint) {
return breaks.remove(breakpoint);
}
}

View file

@ -28,8 +28,8 @@ import ghidra.program.model.listing.Bookmark;
import ghidra.program.model.listing.Program;
import ghidra.program.util.ProgramLocation;
import ghidra.trace.model.Trace;
import ghidra.trace.model.breakpoint.TraceBreakpoint;
import ghidra.trace.model.breakpoint.TraceBreakpointKind;
import ghidra.trace.model.breakpoint.TraceBreakpointLocation;
public class MappedLogicalBreakpoint implements LogicalBreakpointInternal {
@ -309,8 +309,8 @@ public class MappedLogicalBreakpoint implements LogicalBreakpointInternal {
}
@Override
public Set<TraceBreakpoint> getTraceBreakpoints() {
Set<TraceBreakpoint> result = new HashSet<>();
public Set<TraceBreakpointLocation> getTraceBreakpoints() {
Set<TraceBreakpointLocation> result = new HashSet<>();
synchronized (traceBreaks) {
for (TraceBreakpointSet breaks : traceBreaks.values()) {
result.addAll(breaks.getBreakpoints());
@ -320,7 +320,7 @@ public class MappedLogicalBreakpoint implements LogicalBreakpointInternal {
}
@Override
public Set<TraceBreakpoint> getTraceBreakpoints(Trace trace) {
public Set<TraceBreakpointLocation> getTraceBreakpoints(Trace trace) {
TraceBreakpointSet breaks;
synchronized (traceBreaks) {
breaks = traceBreaks.get(trace);
@ -400,7 +400,7 @@ public class MappedLogicalBreakpoint implements LogicalBreakpointInternal {
return progMode.combineTrace(traceMode, Perspective.TRACE);
}
protected TraceMode computeTraceModeForLocation(TraceBreakpoint loc) {
protected TraceMode computeTraceModeForLocation(TraceBreakpointLocation loc) {
TraceBreakpointSet breaks;
synchronized (traceBreaks) {
breaks = traceBreaks.get(loc.getTrace());
@ -412,7 +412,7 @@ public class MappedLogicalBreakpoint implements LogicalBreakpointInternal {
}
@Override
public State computeStateForLocation(TraceBreakpoint loc) {
public State computeStateForLocation(TraceBreakpointLocation loc) {
ProgramMode progMode = progBreak.computeMode();
TraceMode traceMode = computeTraceModeForLocation(loc);
return progMode.combineTrace(traceMode, Perspective.TRACE);
@ -478,7 +478,8 @@ public class MappedLogicalBreakpoint implements LogicalBreakpointInternal {
}
@Override
public boolean canMerge(TraceBreakpoint breakpoint, long snap) throws TrackedTooSoonException {
public boolean canMerge(TraceBreakpointLocation breakpoint, long snap)
throws TrackedTooSoonException {
TraceBreakpointSet breaks;
synchronized (traceBreaks) {
breaks = traceBreaks.get(breakpoint.getTrace());
@ -530,7 +531,7 @@ public class MappedLogicalBreakpoint implements LogicalBreakpointInternal {
}
@Override
public boolean trackBreakpoint(TraceBreakpoint breakpoint) {
public boolean trackBreakpoint(TraceBreakpointLocation breakpoint) {
TraceBreakpointSet breaks;
synchronized (traceBreaks) {
breaks = traceBreaks.get(breakpoint.getTrace());
@ -556,7 +557,7 @@ public class MappedLogicalBreakpoint implements LogicalBreakpointInternal {
}
@Override
public boolean untrackBreakpoint(TraceBreakpoint breakpoint) {
public boolean untrackBreakpoint(TraceBreakpointLocation breakpoint) {
TraceBreakpointSet breaks;
synchronized (traceBreaks) {
breaks = traceBreaks.get(breakpoint.getTrace());

View file

@ -26,7 +26,6 @@ import ghidra.trace.model.Lifespan;
import ghidra.trace.model.Trace;
import ghidra.trace.model.breakpoint.*;
import ghidra.trace.model.memory.TraceMemoryRegion;
import ghidra.trace.model.memory.TraceObjectMemoryRegion;
import ghidra.trace.model.target.TraceObject;
import ghidra.trace.model.target.path.KeyPath;
import ghidra.trace.model.target.path.PathFilter;
@ -49,42 +48,37 @@ public record PlaceEmuBreakpointActionItem(Trace trace, long snap, Address addre
this.emuSleigh = emuSleigh;
}
private TraceObjectMemoryRegion findRegion() {
private TraceMemoryRegion findRegion() {
TraceMemoryRegion region = trace.getMemoryManager().getRegionContaining(snap, address);
if (region != null) {
return (TraceObjectMemoryRegion) region;
return region;
}
AddressSpace space = address.getAddressSpace();
Collection<? extends TraceMemoryRegion> regionsInSpace = trace.getMemoryManager()
.getRegionsIntersecting(Lifespan.at(snap),
new AddressRangeImpl(space.getMinAddress(), space.getMaxAddress()));
if (!regionsInSpace.isEmpty()) {
return (TraceObjectMemoryRegion) regionsInSpace.iterator().next();
return regionsInSpace.iterator().next();
}
return null;
}
private TraceObject findBreakpointContainer() {
TraceObjectMemoryRegion region = findRegion();
TraceMemoryRegion region = findRegion();
if (region == null) {
throw new IllegalArgumentException("Address does not belong to a memory in the trace");
}
return region.getObject()
.findSuitableContainerInterface(TraceObjectBreakpointSpec.class);
return region.getObject().findSuitableContainerInterface(TraceBreakpointSpec.class);
}
private String computePath() {
String name = createName(address);
if (Trace.isLegacy(trace)) {
return "Breakpoints[" + name + "]";
}
TraceObject container = findBreakpointContainer();
if (container == null) {
throw new IllegalArgumentException(
"Address is not associated with a breakpoint container");
}
PathFilter specFilter =
container.getSchema().searchFor(TraceObjectBreakpointSpec.class, true);
PathFilter specFilter = container.getSchema().searchFor(TraceBreakpointSpec.class, true);
if (specFilter == null) {
throw new IllegalArgumentException("Cannot find path to breakpoint specifications");
}
@ -94,7 +88,7 @@ public record PlaceEmuBreakpointActionItem(Trace trace, long snap, Address addre
}
PathFilter locFilter = container.getSchema()
.getSuccessorSchema(specRelPath)
.searchFor(TraceObjectBreakpointLocation.class, true);
.searchFor(TraceBreakpointLocation.class, true);
if (locFilter == null) {
throw new IllegalArgumentException("Cannot find path to breakpoint locations");
}
@ -109,11 +103,11 @@ public record PlaceEmuBreakpointActionItem(Trace trace, long snap, Address addre
public CompletableFuture<Void> execute() {
try (Transaction tx = trace.openTransaction("Place Emulated Breakpoint")) {
// Defaults with emuEnable=true
TraceBreakpoint bpt = trace.getBreakpointManager()
TraceBreakpointLocation loc = trace.getBreakpointManager()
.addBreakpoint(computePath(), Lifespan.at(snap),
BreakpointActionItem.range(address, length), Set.of(), kinds, false, null);
bpt.setName(snap, createName(address));
bpt.setEmuSleigh(snap, emuSleigh);
loc.setName(snap, createName(address));
loc.setEmuSleigh(snap, emuSleigh);
return AsyncUtils.nil();
}
catch (DuplicateNameException e) {

View file

@ -28,8 +28,8 @@ import ghidra.framework.plugintool.PluginTool;
import ghidra.pcode.exec.SleighUtils;
import ghidra.program.model.address.Address;
import ghidra.trace.model.Trace;
import ghidra.trace.model.breakpoint.TraceBreakpoint;
import ghidra.trace.model.breakpoint.TraceBreakpointKind;
import ghidra.trace.model.breakpoint.TraceBreakpointLocation;
import utilities.util.IDHashed;
/**
@ -45,7 +45,7 @@ class TraceBreakpointSet {
private final Trace trace;
private final Address address;
private final Set<IDHashed<TraceBreakpoint>> breakpoints = new HashSet<>();
private final Set<IDHashed<TraceBreakpointLocation>> breakpoints = new HashSet<>();
private Target target;
private String emuSleigh;
@ -120,8 +120,8 @@ class TraceBreakpointSet {
*
* <p>
* In most cases, there is 0 or 1 trace breakpoints that "fit" the logical breakpoint. The mode
* is derived from one of {@link TraceBreakpoint#isEnabled(long)} or
* {@link TraceBreakpoint#isEmuEnabled(long)}, depending on the UI's control mode for this
* is derived from one of {@link TraceBreakpointLocation#isEnabled(long)} or
* {@link TraceBreakpointLocation#isEmuEnabled(long)}, depending on the UI's control mode for this
* trace.
*
* @return the mode
@ -130,7 +130,7 @@ class TraceBreakpointSet {
TraceMode mode = TraceMode.NONE;
synchronized (breakpoints) {
if (getControlMode().useEmulatedBreakpoints()) {
for (IDHashed<TraceBreakpoint> bpt : breakpoints) {
for (IDHashed<TraceBreakpointLocation> bpt : breakpoints) {
mode = mode.combine(computeEmuMode(bpt.obj));
if (mode == TraceMode.MISSING) {
return mode;
@ -138,7 +138,7 @@ class TraceBreakpointSet {
}
return mode;
}
for (IDHashed<TraceBreakpoint> bpt : breakpoints) {
for (IDHashed<TraceBreakpointLocation> bpt : breakpoints) {
mode = mode.combine(computeTargetMode(bpt.obj));
if (mode == TraceMode.MISSING) {
return mode;
@ -152,14 +152,14 @@ class TraceBreakpointSet {
* Compute the mode (enablement) of the given breakpoint
*
* <p>
* The mode is derived from one of {@link TraceBreakpoint#isEnabled(long)} or
* {@link TraceBreakpoint#isEmuEnabled(long)}, depending on the UI's control mode for this
* The mode is derived from one of {@link TraceBreakpointLocation#isEnabled(long)} or
* {@link TraceBreakpointLocation#isEmuEnabled(long)}, depending on the UI's control mode for this
* trace.
*
* @param bpt the breakpoint
* @return the mode
*/
public TraceMode computeMode(TraceBreakpoint bpt) {
public TraceMode computeMode(TraceBreakpointLocation bpt) {
return getControlMode().useEmulatedBreakpoints()
? computeEmuMode(bpt)
: computeTargetMode(bpt);
@ -171,7 +171,7 @@ class TraceBreakpointSet {
* @param bpt the breakpoint
* @return the mode
*/
public TraceMode computeTargetMode(TraceBreakpoint bpt) {
public TraceMode computeTargetMode(TraceBreakpointLocation bpt) {
return TraceMode.fromBool(bpt.isEnabled(getSnap()));
}
@ -181,7 +181,7 @@ class TraceBreakpointSet {
* @param bpt the breakpoint
* @return the mode
*/
public TraceMode computeEmuMode(TraceBreakpoint bpt) {
public TraceMode computeEmuMode(TraceBreakpointLocation bpt) {
return TraceMode.fromBool(bpt.isEmuEnabled(getSnap()));
}
@ -194,7 +194,7 @@ class TraceBreakpointSet {
String sleigh = null;
long snap = getSnap();
synchronized (breakpoints) {
for (IDHashed<TraceBreakpoint> bpt : breakpoints) {
for (IDHashed<TraceBreakpointLocation> bpt : breakpoints) {
String s = bpt.obj.getEmuSleigh(snap);
if (sleigh != null && !sleigh.equals(s)) {
return null;
@ -215,7 +215,7 @@ class TraceBreakpointSet {
long snap = getSnap();
try (Transaction tx = trace.openTransaction("Set breakpoint Sleigh")) {
synchronized (breakpoints) {
for (IDHashed<TraceBreakpoint> bpt : breakpoints) {
for (IDHashed<TraceBreakpointLocation> bpt : breakpoints) {
bpt.obj.setEmuSleigh(snap, emuSleigh);
}
}
@ -238,7 +238,7 @@ class TraceBreakpointSet {
*
* @return the breakpoints
*/
public Set<TraceBreakpoint> getBreakpoints() {
public Set<TraceBreakpointLocation> getBreakpoints() {
synchronized (breakpoints) {
return breakpoints.stream().map(e -> e.obj).collect(Collectors.toUnmodifiableSet());
}
@ -248,13 +248,13 @@ class TraceBreakpointSet {
* Add a breakpoint to this set
*
* <p>
* The caller should first call {@link #canMerge(TraceBreakpoint)} to check if the breakpoint
* The caller should first call {@link #canMerge(TraceBreakpointLocation)} to check if the breakpoint
* "fits."
*
* @param bpt the breakpoint
* @return true if the set actually changed as a result
*/
public boolean add(TraceBreakpoint bpt) {
public boolean add(TraceBreakpointLocation bpt) {
long snap = getSnap();
if (SleighUtils.UNCONDITIONAL_BREAK.equals(bpt.getEmuSleigh(snap)) && emuSleigh != null) {
try (Transaction tx = trace.openTransaction("Set breakpoint Sleigh")) {
@ -275,7 +275,7 @@ class TraceBreakpointSet {
* @param bpt the breakpoint
* @return true if it fits
*/
public boolean canMerge(TraceBreakpoint bpt) {
public boolean canMerge(TraceBreakpointLocation bpt) {
if (trace != bpt.getTrace()) {
return false;
}
@ -291,7 +291,7 @@ class TraceBreakpointSet {
* @param bpt the breakpoint
* @return true if the set actually changes as a result
*/
public boolean remove(TraceBreakpoint bpt) {
public boolean remove(TraceBreakpointLocation bpt) {
synchronized (breakpoints) {
return breakpoints.remove(new IDHashed<>(bpt));
}
@ -359,7 +359,7 @@ class TraceBreakpointSet {
private void planEnableTarget(BreakpointActionSet actions) {
synchronized (breakpoints) {
for (IDHashed<TraceBreakpoint> bpt : breakpoints) {
for (IDHashed<TraceBreakpointLocation> bpt : breakpoints) {
actions.planEnableTarget(target, bpt.obj);
}
}
@ -367,7 +367,7 @@ class TraceBreakpointSet {
private void planEnableEmu(BreakpointActionSet actions) {
synchronized (breakpoints) {
for (IDHashed<TraceBreakpoint> bpt : breakpoints) {
for (IDHashed<TraceBreakpointLocation> bpt : breakpoints) {
actions.planEnableEmu(bpt.obj, getSnap());
}
}
@ -393,7 +393,7 @@ class TraceBreakpointSet {
private void planDisableTarget(BreakpointActionSet actions, long length,
Collection<TraceBreakpointKind> kinds) {
synchronized (breakpoints) {
for (IDHashed<TraceBreakpoint> bpt : breakpoints) {
for (IDHashed<TraceBreakpointLocation> bpt : breakpoints) {
actions.planDisableTarget(target, bpt.obj);
}
}
@ -401,7 +401,7 @@ class TraceBreakpointSet {
private void planDisableEmu(BreakpointActionSet actions) {
synchronized (breakpoints) {
for (IDHashed<TraceBreakpoint> bpt : breakpoints) {
for (IDHashed<TraceBreakpointLocation> bpt : breakpoints) {
actions.planDisableEmu(bpt.obj, getSnap());
}
}
@ -427,7 +427,7 @@ class TraceBreakpointSet {
private void planDeleteTarget(BreakpointActionSet actions, long length,
Set<TraceBreakpointKind> kinds) {
synchronized (breakpoints) {
for (IDHashed<TraceBreakpoint> bpt : breakpoints) {
for (IDHashed<TraceBreakpointLocation> bpt : breakpoints) {
actions.planDeleteTarget(target, bpt.obj);
}
}
@ -435,7 +435,7 @@ class TraceBreakpointSet {
private void planDeleteEmu(BreakpointActionSet actions) {
synchronized (breakpoints) {
for (IDHashed<TraceBreakpoint> bpt : breakpoints) {
for (IDHashed<TraceBreakpointLocation> bpt : breakpoints) {
actions.planDeleteEmu(bpt.obj, getSnap());
}
}

View file

@ -18,7 +18,7 @@ package ghidra.app.plugin.core.debug.service.emulation;
import java.io.IOException;
import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.*;
import java.util.stream.Collectors;
import javax.swing.Icon;
@ -45,6 +45,7 @@ import ghidra.async.AsyncLazyMap;
import ghidra.debug.api.control.ControlMode;
import ghidra.debug.api.emulation.DebuggerPcodeEmulatorFactory;
import ghidra.debug.api.emulation.DebuggerPcodeMachine;
import ghidra.debug.api.modules.DebuggerStaticMappingChangeListener;
import ghidra.debug.api.tracemgr.DebuggerCoordinates;
import ghidra.framework.plugintool.*;
import ghidra.framework.plugintool.annotation.AutoServiceConsumed;
@ -638,7 +639,7 @@ public class DebuggerEmulationServicePlugin extends Plugin implements DebuggerEm
Lifespan span = Lifespan.at(snap);
TraceBreakpointManager bm = trace.getBreakpointManager();
for (AddressSpace as : trace.getBaseAddressFactory().getAddressSpaces()) {
for (TraceBreakpoint bpt : bm.getBreakpointsIntersecting(span,
for (TraceBreakpointLocation bpt : bm.getBreakpointsIntersecting(span,
new AddressRangeImpl(as.getMinAddress(), as.getMaxAddress()))) {
if (!bpt.isEmuEnabled(snap)) {
continue;
@ -797,14 +798,43 @@ public class DebuggerEmulationServicePlugin extends Plugin implements DebuggerEm
}
}
class TraceMappingWaiter extends CompletableFuture<Void>
implements DebuggerStaticMappingChangeListener {
private final Trace trace;
public TraceMappingWaiter(Trace trace) {
this.trace = trace;
}
@Override
public void mappingsChanged(Set<Trace> affectedTraces, Set<Program> affectedPrograms) {
if (affectedTraces.contains(trace)) {
complete(null);
}
}
public void softWait() {
try {
get(1, TimeUnit.SECONDS);
}
catch (InterruptedException | ExecutionException | TimeoutException e) {
Msg.warn(this, "Mappings not reported by service after 1 second");
}
}
}
@Override
public Trace launchProgram(Program program, Address address) throws IOException {
Trace trace = null;
try {
trace = ProgramEmulationUtils.launchEmulationTrace(program, address, this);
trace.flushEvents();
TraceMappingWaiter waiter = new TraceMappingWaiter(trace);
staticMappings.addChangeListener(waiter);
traceManager.openTrace(trace);
traceManager.activateTrace(trace);
Swing.allowSwingToProcessEvents();
waiter.softWait();
}
finally {
if (trace != null) {

View file

@ -45,7 +45,8 @@ import ghidra.trace.model.target.iface.TraceObjectInterface;
import ghidra.trace.model.target.path.*;
import ghidra.trace.model.target.schema.*;
import ghidra.trace.model.target.schema.TraceObjectSchema.SchemaName;
import ghidra.trace.model.thread.*;
import ghidra.trace.model.thread.TraceThread;
import ghidra.trace.model.thread.TraceThreadManager;
import ghidra.trace.model.time.TraceSnapshot;
import ghidra.util.*;
import ghidra.util.exception.DuplicateNameException;
@ -290,19 +291,13 @@ public class ProgramEmulationUtils {
}
public static PathPattern computePatternRegion(Trace trace) {
TraceObjectSchema root = trace.getObjectManager().getRootSchema();
if (root == null) {
return PathFilter.parse("Memory[]");
}
return computePattern(root, trace, TraceObjectMemoryRegion.class);
TraceObjectSchema root = trace.getObjectManager().requireRootSchema();
return computePattern(root, trace, TraceMemoryRegion.class);
}
public static PathPattern computePatternThread(Trace trace) {
TraceObjectSchema root = trace.getObjectManager().getRootSchema();
if (root == null) {
return PathFilter.parse("Threads[]");
}
return computePattern(root, trace, TraceObjectThread.class);
TraceObjectSchema root = trace.getObjectManager().requireRootSchema();
return computePattern(root, trace, TraceThread.class);
}
/**
@ -347,18 +342,16 @@ public class ProgramEmulationUtils {
public static void initializeRegisters(Trace trace, long snap, TraceThread thread,
Program program, Address tracePc, Address programPc, AddressRange stack) {
TraceMemoryManager memory = trace.getMemoryManager();
if (thread instanceof TraceObjectThread ot) {
TraceObject object = ot.getObject();
PathFilter regsFilter = object.getRoot()
.getSchema()
.searchForRegisterContainer(0, object.getCanonicalPath());
if (regsFilter.isNone()) {
throw new IllegalArgumentException("Cannot create register container");
}
for (PathPattern regsPattern : regsFilter.getPatterns()) {
trace.getObjectManager().createObject(regsPattern.getSingletonPath());
break;
}
TraceObject object = thread.getObject();
PathFilter regsFilter = object.getRoot()
.getSchema()
.searchForRegisterContainer(0, object.getCanonicalPath());
if (regsFilter.isNone()) {
throw new IllegalArgumentException("Cannot create register container");
}
for (PathPattern regsPattern : regsFilter.getPatterns()) {
trace.getObjectManager().createObject(regsPattern.getSingletonPath());
break;
}
TraceMemorySpace regSpace = memory.getMemoryRegisterSpace(thread, true);
if (program != null) {
@ -606,7 +599,12 @@ public class ProgramEmulationUtils {
throw new EmulatorOutOfMemoryException();
}
protected static void createObjects(Trace trace) {
/**
* Initialize a given emulation trace with some required/expected objects
*
* @param trace the trace
*/
public static void createObjects(Trace trace) {
TraceObjectManager om = trace.getObjectManager();
om.createRootObject(EMU_SESSION_SCHEMA);

View file

@ -36,7 +36,7 @@ import ghidra.program.model.lang.RegisterValue;
import ghidra.program.util.MarkerLocation;
import ghidra.program.util.ProgramLocation;
import ghidra.trace.model.TraceSpan;
import ghidra.trace.model.breakpoint.TraceBreakpoint;
import ghidra.trace.model.breakpoint.TraceBreakpointCommon;
import ghidra.trace.model.breakpoint.TraceBreakpointKind;
import ghidra.trace.model.guest.TracePlatform;
import ghidra.trace.model.program.TraceProgramView;
@ -321,12 +321,12 @@ public abstract class AbstractTarget implements Target {
}
@Override
public void deleteBreakpoint(TraceBreakpoint breakpoint) {
public void deleteBreakpoint(TraceBreakpointCommon breakpoint) {
runSync("delete breakpoint", () -> deleteBreakpointAsync(breakpoint));
}
@Override
public void toggleBreakpoint(TraceBreakpoint breakpoint, boolean enabled) {
public void toggleBreakpoint(TraceBreakpointCommon breakpoint, boolean enabled) {
String msg = enabled ? "enable breakpoint" : "disable breakpoint";
runSync(msg, () -> toggleBreakpointAsync(breakpoint, enabled));
}

View file

@ -70,24 +70,16 @@ public class DebuggerListingPluginScreenShots extends GhidraScreenShotGenerator
TraceSymbolManager symbolManager = tb.trace.getSymbolManager();
TraceNamespaceSymbol global = symbolManager.getGlobalNamespace();
TraceSymbol mainLabel = symbolManager
.labels()
.create(snap, null, tb.addr(0x00400000),
"main", global, SourceType.USER_DEFINED);
TraceSymbol mainLabel = symbolManager.labels()
.create(snap, tb.addr(0x00400000), "main", global, SourceType.USER_DEFINED);
@SuppressWarnings("unused")
TraceSymbol cloneLabel = symbolManager
.labels()
.create(snap, null, tb.addr(0x00400060),
"clone", global, SourceType.USER_DEFINED);
TraceSymbol childLabel = symbolManager
.labels()
.create(snap, null, tb.addr(0x00400032),
"child", global, SourceType.USER_DEFINED);
TraceSymbol cloneLabel = symbolManager.labels()
.create(snap, tb.addr(0x00400060), "clone", global, SourceType.USER_DEFINED);
TraceSymbol childLabel = symbolManager.labels()
.create(snap, tb.addr(0x00400032), "child", global, SourceType.USER_DEFINED);
@SuppressWarnings("unused")
TraceSymbol exitLabel = symbolManager
.labels()
.create(snap, null, tb.addr(0x00400061),
"exit", global, SourceType.USER_DEFINED);
TraceSymbol exitLabel = symbolManager.labels()
.create(snap, tb.addr(0x00400061), "exit", global, SourceType.USER_DEFINED);
Assembler assembler = Assemblers.getAssembler(tb.trace.getProgramView());

View file

@ -72,24 +72,16 @@ public class DebuggerMemoryBytesPluginScreenShots extends GhidraScreenShotGenera
TraceSymbolManager symbolManager = tb.trace.getSymbolManager();
TraceNamespaceSymbol global = symbolManager.getGlobalNamespace();
TraceSymbol mainLabel = symbolManager
.labels()
.create(snap, null, tb.addr(0x00400000),
"main", global, SourceType.USER_DEFINED);
TraceSymbol mainLabel = symbolManager.labels()
.create(snap, tb.addr(0x00400000), "main", global, SourceType.USER_DEFINED);
@SuppressWarnings("unused")
TraceSymbol cloneLabel = symbolManager
.labels()
.create(snap, null, tb.addr(0x00400060),
"clone", global, SourceType.USER_DEFINED);
TraceSymbol childLabel = symbolManager
.labels()
.create(snap, null, tb.addr(0x00400034),
"child", global, SourceType.USER_DEFINED);
TraceSymbol cloneLabel = symbolManager.labels()
.create(snap, tb.addr(0x00400060), "clone", global, SourceType.USER_DEFINED);
TraceSymbol childLabel = symbolManager.labels()
.create(snap, tb.addr(0x00400034), "child", global, SourceType.USER_DEFINED);
@SuppressWarnings("unused")
TraceSymbol exitLabel = symbolManager
.labels()
.create(snap, null, tb.addr(0x00400061),
"exit", global, SourceType.USER_DEFINED);
TraceSymbol exitLabel = symbolManager.labels()
.create(snap, tb.addr(0x00400061), "exit", global, SourceType.USER_DEFINED);
Assembler assembler = Assemblers.getAssembler(tb.trace.getProgramView());

View file

@ -33,7 +33,7 @@ import ghidra.trace.database.target.DBTraceObjectValue;
import ghidra.trace.model.Lifespan;
import ghidra.trace.model.target.TraceObject;
import ghidra.trace.model.target.TraceObject.ConflictResolution;
import ghidra.trace.model.target.iface.TraceObjectEventScope;
import ghidra.trace.model.target.iface.TraceEventScope;
import ghidra.trace.model.target.schema.SchemaContext;
import ghidra.trace.model.target.schema.XmlSchemaContext;
import ghidra.trace.model.target.schema.TraceObjectSchema.SchemaName;
@ -180,7 +180,7 @@ public class DebuggerModelPluginScreenShots extends GhidraScreenShotGenerator {
proc.child("Modules");
}
}
root.value(TraceObjectEventScope.KEY_EVENT_THREAD, l.thread);
root.value(TraceEventScope.KEY_EVENT_THREAD, l.thread);
}
traceManager.openTrace(tb.trace);

View file

@ -29,7 +29,7 @@ import ghidra.test.ToyProgramBuilder;
import ghidra.trace.database.ToyDBTraceBuilder;
import ghidra.trace.model.Lifespan;
import ghidra.trace.model.memory.TraceMemoryFlag;
import ghidra.trace.model.thread.TraceObjectThread;
import ghidra.trace.model.thread.TraceThread;
import ghidra.trace.model.time.schedule.TraceSchedule;
import help.screenshot.GhidraScreenShotGenerator;
@ -66,7 +66,7 @@ public class DebuggerPcodeStepperPluginScreenShots extends GhidraScreenShotGener
tb.range(0x00400000, 0x0040ffff), TraceMemoryFlag.READ,
TraceMemoryFlag.EXECUTE);
TraceObjectThread thread = (TraceObjectThread) tb.getOrAddThread("Threads[1]", snap0);
TraceThread thread = tb.getOrAddThread("Threads[1]", snap0);
tb.trace.getObjectManager()
.createObject(thread.getObject().getCanonicalPath().key("Registers"));

View file

@ -22,10 +22,6 @@ import db.Transaction;
import ghidra.app.plugin.core.debug.service.tracemgr.DebuggerTraceManagerServicePlugin;
import ghidra.app.services.DebuggerTraceManagerService;
import ghidra.trace.database.ToyDBTraceBuilder;
import ghidra.trace.database.target.DBTraceObjectManagerTest;
import ghidra.trace.model.target.schema.SchemaContext;
import ghidra.trace.model.target.schema.XmlSchemaContext;
import ghidra.trace.model.target.schema.TraceObjectSchema.SchemaName;
import help.screenshot.GhidraScreenShotGenerator;
public class DebuggerPlatformPluginScreenShots extends GhidraScreenShotGenerator {
@ -41,11 +37,9 @@ public class DebuggerPlatformPluginScreenShots extends GhidraScreenShotGenerator
@Test
public void testCaptureDebuggerSelectPlatformOfferDialog() throws Throwable {
SchemaContext ctx = XmlSchemaContext.deserialize(DBTraceObjectManagerTest.XML_CTX);
try (ToyDBTraceBuilder tb = new ToyDBTraceBuilder("echo", "DATA:BE:64:default")) {
try (Transaction tx = tb.startTransaction()) {
tb.trace.getObjectManager()
.createRootObject(ctx.getSchema(new SchemaName("Session")));
tb.createRootObject();
}
traceManager.openTrace(tb.trace);
traceManager.activateTrace(tb.trace);

View file

@ -45,7 +45,7 @@ import ghidra.trace.model.DefaultTraceLocation;
import ghidra.trace.model.Lifespan;
import ghidra.trace.model.target.TraceObject.ConflictResolution;
import ghidra.trace.model.target.path.KeyPath;
import ghidra.trace.model.thread.TraceObjectThread;
import ghidra.trace.model.thread.TraceThread;
import ghidra.util.task.TaskMonitor;
import help.screenshot.GhidraScreenShotGenerator;
@ -103,14 +103,10 @@ public class DebuggerThreadsPluginScreenShots extends GhidraScreenShotGenerator
sm.getSnapshot(13, true);
DBTraceThreadManager tm = tb.trace.getThreadManager();
TraceObjectThread t1 =
(TraceObjectThread) tm.addThread("Threads[1]", "main", Lifespan.nowOn(0));
TraceObjectThread t2 =
(TraceObjectThread) tm.addThread("Threads[2]", "server", Lifespan.nowOn(2));
TraceObjectThread t3 =
(TraceObjectThread) tm.addThread("Threads[3]", "handler 1", Lifespan.span(5, 10));
TraceObjectThread t4 =
(TraceObjectThread) tm.addThread("Threads[4]", "handler 2", Lifespan.span(8, 13));
TraceThread t1 = tm.addThread("Threads[1]", "main", Lifespan.nowOn(0));
TraceThread t2 = tm.addThread("Threads[2]", "server", Lifespan.nowOn(2));
TraceThread t3 = tm.addThread("Threads[3]", "handler 1", Lifespan.span(5, 10));
TraceThread t4 = tm.addThread("Threads[4]", "handler 2", Lifespan.span(8, 13));
t1.getObject().setValue(Lifespan.nowOn(0), "_state", "STOPPED");
t2.getObject().setValue(Lifespan.nowOn(0), "_state", "STOPPED");

View file

@ -62,7 +62,7 @@ public class DebuggerWatchesPluginScreenShots extends GhidraScreenShotGenerator
tb.trace.getSymbolManager()
.labels()
.create(snap1, null, tb.addr(0x7fff0004), "fiveUp",
.create(snap1, tb.addr(0x7fff0004), "fiveUp",
tb.trace.getSymbolManager().getGlobalNamespace(), SourceType.USER_DEFINED);
thread = tb.getOrAddThread("[1]", snap0);

View file

@ -48,6 +48,7 @@ import ghidra.program.model.lang.*;
import ghidra.program.model.listing.Instruction;
import ghidra.program.util.ProgramLocation;
import ghidra.program.util.ProgramSelection;
import ghidra.trace.database.ToyDBTraceBuilder.ToySchemaBuilder;
import ghidra.trace.database.listing.DBTraceInstruction;
import ghidra.trace.database.listing.DBTraceInstructionsMemoryView;
import ghidra.trace.database.memory.DBTraceMemoryManager;
@ -59,16 +60,16 @@ import ghidra.trace.model.Lifespan;
import ghidra.trace.model.guest.TraceGuestPlatform;
import ghidra.trace.model.guest.TracePlatform;
import ghidra.trace.model.memory.TraceMemoryFlag;
import ghidra.trace.model.memory.TraceObjectMemoryRegion;
import ghidra.trace.model.memory.TraceMemoryRegion;
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.ConflictResolution;
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.schema.SchemaContext;
import ghidra.trace.model.target.schema.TraceObjectSchema.SchemaName;
import ghidra.trace.model.target.schema.XmlSchemaContext;
import ghidra.trace.model.thread.TraceObjectThread;
import ghidra.trace.model.thread.TraceThread;
import ghidra.trace.model.time.schedule.TraceSchedule;
import ghidra.util.task.TaskMonitor;
@ -162,12 +163,12 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerTest {
sel, null);
}
protected TraceObjectThread createPolyglotTrace(String arch, long offset,
protected TraceThread createPolyglotTrace(String arch, long offset,
Supplier<ByteBuffer> byteSupplier) throws Exception {
return createPolyglotTrace(arch, offset, byteSupplier, true);
}
protected TraceObjectThread createPolyglotTrace(String arch, long offset,
protected TraceThread createPolyglotTrace(String arch, long offset,
Supplier<ByteBuffer> byteSupplier, boolean pcInStack) throws Exception {
createAndOpenTrace("DATA:BE:64:default");
@ -179,13 +180,12 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerTest {
assertEquals(ctx.getSchema(new SchemaName("Environment")), env.getSchema());
Lifespan zeroOn = Lifespan.nowOn(0);
env.insert(zeroOn, ConflictResolution.DENY);
env.setAttribute(zeroOn, TraceObjectEnvironment.KEY_DEBUGGER, "test");
env.setAttribute(zeroOn, TraceObjectEnvironment.KEY_ARCH, arch);
env.setAttribute(zeroOn, TraceEnvironment.KEY_DEBUGGER, "test");
env.setAttribute(zeroOn, TraceEnvironment.KEY_ARCH, arch);
DBTraceObject objBinText =
objects.createObject(KeyPath.parse("Targets[0].Memory[bin:.text]"));
TraceObjectMemoryRegion binText =
objBinText.queryInterface(TraceObjectMemoryRegion.class);
TraceMemoryRegion binText = objBinText.queryInterface(TraceMemoryRegion.class);
binText.addFlags(zeroOn, Set.of(TraceMemoryFlag.EXECUTE));
binText.setRange(zeroOn, tb.range(offset, offset + 0xffff));
// TODO: Why doesn't setRange work after insert?
@ -196,16 +196,16 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerTest {
DBTraceObject objFrame = objects
.createObject(KeyPath.parse("Targets[0].Threads[0].Stack[0]"));
objFrame.insert(zeroOn, ConflictResolution.DENY);
TraceObjectStackFrame frame = objFrame.queryInterface(TraceObjectStackFrame.class);
TraceStackFrame frame = objFrame.queryInterface(TraceStackFrame.class);
frame.setProgramCounter(zeroOn, tb.addr(offset));
}
else {
objects.createObject(
KeyPath.parse("Targets[0].Threads[0].Stack[0].Registers"))
.insert(zeroOn, ConflictResolution.DENY);
TraceObjectThread thread = objects
.getObjectByCanonicalPath(KeyPath.parse("Targets[0].Threads[0]"))
.queryInterface(TraceObjectThread.class);
TraceThread thread =
objects.getObjectByCanonicalPath(KeyPath.parse("Targets[0].Threads[0]"))
.queryInterface(TraceThread.class);
traceManager.activateThread(thread);
DBTraceMemorySpace regs =
Objects.requireNonNull(memory.getMemoryRegisterSpace(thread, true));
@ -218,14 +218,14 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerTest {
ByteBuffer bytes = byteSupplier.get();
assertEquals(bytes.remaining(), memory.putBytes(0, tb.addr(offset), bytes));
}
TraceObjectThread thread =
TraceThread thread =
objects.getObjectByCanonicalPath(KeyPath.parse("Targets[0].Threads[0]"))
.queryInterface(TraceObjectThread.class);
.queryInterface(TraceThread.class);
traceManager.activateThread(thread);
return thread;
}
protected void setLegacyProgramCounterInStack(long offset, TraceThread thread, long snap) {
protected void setProgramCounterInStack(long offset, TraceThread thread, long snap) {
try (Transaction tx = tb.startTransaction()) {
DBTraceStackManager manager = tb.trace.getStackManager();
TraceStack stack = manager.getStack(thread, snap, true);
@ -234,7 +234,7 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerTest {
}
}
protected void setLegacyProgramCounterInRegs(long offset, TraceThread thread, long snap) {
protected void setProgramCounterInRegs(long offset, TraceThread thread, long snap) {
try (Transaction tx = tb.startTransaction()) {
DBTraceMemoryManager memory = tb.trace.getMemoryManager();
DBTraceMemorySpace regs = memory.getMemoryRegisterSpace(thread, true);
@ -243,11 +243,19 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerTest {
}
}
protected void createLegacyTrace(String langID, long offset, Supplier<ByteBuffer> byteSupplier)
protected SchemaContext buildContext() {
return new ToySchemaBuilder()
.noRegisterGroups()
.useRegistersPerFrame()
.build();
}
protected void createTrace(String langID, long offset, Supplier<ByteBuffer> byteSupplier)
throws Throwable {
createAndOpenTrace(langID);
try (Transaction tx = tb.startTransaction()) {
tb.createRootObject(buildContext(), "Target");
DBTraceMemoryManager memory = tb.trace.getMemoryManager();
memory.createRegion("Memory[bin:.text]", 0, tb.range(offset, offset + 0xffff),
Set.of(TraceMemoryFlag.EXECUTE, TraceMemoryFlag.READ));
@ -275,27 +283,27 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerTest {
@Test
public void testAutoDisasembleReDisasembleX8664Offcut() throws Throwable {
enableAutoDisassembly();
createLegacyTrace("x86:LE:64:default", 0x00400000, () -> tb.buf(0xeb, 0xff, 0xc0));
createTrace("x86:LE:64:default", 0x00400000, () -> tb.buf(0xeb, 0xff, 0xc0));
TraceThread thread;
try (Transaction tx = tb.startTransaction()) {
thread = tb.getOrAddThread("Thread 1", 0);
thread = tb.getOrAddThread("Threads[1]", 0);
}
setLegacyProgramCounterInStack(0x00400000, thread, 0);
setProgramCounterInStack(0x00400000, thread, 0);
waitForPass(() -> {
DBTraceInstructionsMemoryView instructions = tb.trace.getCodeManager().instructions();
assertMnemonic("JMP", instructions.getAt(0, tb.addr(0x00400000)));
/**
* Depending on preference for branch or fall-through, the disassembler may or may not
* proceed to the following instructions. I don't really care, since the test is that the
* JMP gets deleted after the update to PC.
* proceed to the following instructions. I don't really care, since the test is that
* the JMP gets deleted after the update to PC.
*/
});
// The jump will advance one byte. Just simulate that by updating the stack and/or regs
setLegacyProgramCounterInStack(0x00400001, thread, 1);
setProgramCounterInStack(0x00400001, thread, 1);
traceManager.activateSnap(1);
waitForPass(() -> {
@ -310,22 +318,23 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerTest {
public void testAutoDisassembleReDisassembleX8664OffcutByEmulation() throws Throwable {
DebuggerEmulationService emuService = addPlugin(tool, DebuggerEmulationServicePlugin.class);
enableAutoDisassembly();
createLegacyTrace("x86:LE:64:default", 0x00400000, () -> tb.buf(0xeb, 0xff, 0xc0));
createTrace("x86:LE:64:default", 0x00400000, () -> tb.buf(0xeb, 0xff, 0xc0));
TraceThread thread;
try (Transaction tx = tb.startTransaction()) {
thread = tb.getOrAddThread("Thread 1", 0);
thread = tb.getOrAddThread("Threads[1]", 0);
tb.createObjectsFramesAndRegs(thread, Lifespan.nowOn(0), tb.host, 1);
}
setLegacyProgramCounterInRegs(0x00400000, thread, 0);
setProgramCounterInRegs(0x00400000, thread, 0);
waitForPass(() -> {
DBTraceInstructionsMemoryView instructions = tb.trace.getCodeManager().instructions();
assertMnemonic("JMP", instructions.getAt(0, tb.addr(0x00400000)));
/**
* Depending on preference for branch or fall-through, the disassembler may or may not
* proceed to the following instructions. I don't really care, since the test is that the
* JMP gets deleted after the update to PC.
* proceed to the following instructions. I don't really care, since the test is that
* the JMP gets deleted after the update to PC.
*/
});
@ -374,8 +383,8 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerTest {
assertMnemonic("JMP", instructions.getAt(0, tb.addr(0x00400000)));
/**
* Depending on preference for branch or fall-through, the disassembler may or may not
* proceed to the following instructions. I don't really care, since the test is that the
* JMP gets deleted after the update to PC.
* proceed to the following instructions. I don't really care, since the test is that
* the JMP gets deleted after the update to PC.
*/
});
@ -411,12 +420,13 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerTest {
@Test
public void testCurrentDisassembleActionHostArm() throws Throwable {
createLegacyTrace("ARM:LE:32:v8", 0x00400000, () -> tb.buf(0x1e, 0xff, 0x2f, 0xe1));
createTrace("ARM:LE:32:v8", 0x00400000, () -> tb.buf(0x1e, 0xff, 0x2f, 0xe1));
// Fabricate the cpsr so that ARM is used. Otherwise, it will assume Cortex-M, so THUMB
TraceThread thread;
try (Transaction tx = tb.startTransaction()) {
thread = tb.getOrAddThread("Threads[0]", 0);
tb.createObjectsFramesAndRegs(thread, Lifespan.nowOn(0), tb.host, 1);
DBTraceMemorySpace regs =
tb.trace.getMemoryManager().getMemoryRegisterSpace(thread, true);
regs.setValue(0, new RegisterValue(tb.language.getRegister("cpsr"), BigInteger.ZERO));
@ -442,12 +452,13 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerTest {
@Test
public void testCurrentDisassembleActionHostThumb() throws Throwable {
createLegacyTrace("ARM:LE:32:v8", 0x00400000, () -> tb.buf(0x70, 0x47));
createTrace("ARM:LE:32:v8", 0x00400000, () -> tb.buf(0x70, 0x47));
// Fabricate the cpsr so that THUMB is used, even though we could omit as in Cortex-M
TraceThread thread;
try (Transaction tx = tb.startTransaction()) {
thread = tb.getOrAddThread("Threads[0]", 0);
tb.createObjectsFramesAndRegs(thread, Lifespan.nowOn(0), tb.host, 1);
DBTraceMemorySpace regs =
tb.trace.getMemoryManager().getMemoryRegisterSpace(thread, true);
regs.setValue(0,
@ -474,7 +485,7 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerTest {
@Test
public void testCurrentDisassembleActionGuestArm() throws Throwable {
TraceObjectThread thread =
TraceThread thread =
createPolyglotTrace("armv8le", 0x00400000, () -> tb.buf(0x1e, 0xff, 0x2f, 0xe1));
traceManager.activateThread(thread);
waitForSwing();
@ -510,7 +521,7 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerTest {
@Test
public void testCurrentDisassembleActionGuestThumb() throws Throwable {
TraceObjectThread thread =
TraceThread thread =
createPolyglotTrace("armv8le", 0x00400000, () -> tb.buf(0x70, 0x47));
traceManager.activateThread(thread);
waitForSwing();
@ -557,7 +568,7 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerTest {
@Test
public void testFixedDisassembleActionsHostArm() throws Throwable {
createLegacyTrace("ARM:LE:32:v8", 0x00400000, () -> tb.buf(0x1e, 0xff, 0x2f, 0xe1));
createTrace("ARM:LE:32:v8", 0x00400000, () -> tb.buf(0x1e, 0xff, 0x2f, 0xe1));
Address start = tb.addr(0x00400000);
// Ensure the mapper is added to the trace
@ -573,7 +584,7 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerTest {
@Test
public void testFixedDisassembleActionsGuestArm() throws Throwable {
TraceObjectThread thread =
TraceThread thread =
createPolyglotTrace("armv8le", 0x00400000, () -> tb.buf(0x1e, 0xff, 0x2f, 0xe1));
Address start = tb.addr(0x00400000);
@ -590,7 +601,7 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerTest {
@Test
public void testFixedDisassembleActionsGuestThumb() throws Throwable {
TraceObjectThread thread =
TraceThread thread =
createPolyglotTrace("armv8le", 0x00400000, () -> tb.buf(0x70, 0x47));
Address start = tb.addr(0x00400000);
@ -610,7 +621,7 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerTest {
// Assemble actions will think read-only otherwise
DebuggerControlService controlService = addPlugin(tool, DebuggerControlServicePlugin.class);
createLegacyTrace("ARM:LE:32:v8", 0x00400000, () -> tb.buf(0x00, 0x00, 0x00, 0x00));
createTrace("ARM:LE:32:v8", 0x00400000, () -> tb.buf(0x00, 0x00, 0x00, 0x00));
Address start = tb.addr(0x00400000);
controlService.setCurrentMode(tb.trace, ControlMode.RW_TRACE);
@ -638,7 +649,7 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerTest {
DebuggerControlService controlService = addPlugin(tool, DebuggerControlServicePlugin.class);
// Don't cheat here and choose v8T!
createLegacyTrace("ARM:LE:32:v8", 0x00400000, () -> tb.buf(0x00, 0x00));
createTrace("ARM:LE:32:v8", 0x00400000, () -> tb.buf(0x00, 0x00));
Address start = tb.addr(0x00400000);
controlService.setCurrentMode(tb.trace, ControlMode.RW_TRACE);
@ -669,7 +680,7 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerTest {
// Assemble actions will think read-only otherwise
DebuggerControlService controlService = addPlugin(tool, DebuggerControlServicePlugin.class);
TraceObjectThread thread =
TraceThread thread =
createPolyglotTrace("armv8le", 0x00400000, () -> tb.buf(0x00, 0x00, 0x00, 0x00));
Address start = tb.addr(0x00400000);
controlService.setCurrentMode(tb.trace, ControlMode.RW_TRACE);
@ -699,7 +710,7 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerTest {
// Assemble actions will think read-only otherwise
DebuggerControlService controlService = addPlugin(tool, DebuggerControlServicePlugin.class);
TraceObjectThread thread =
TraceThread thread =
createPolyglotTrace("armv8le", 0x00400000, () -> tb.buf(0x00, 0x00));
Address start = tb.addr(0x00400000);
controlService.setCurrentMode(tb.trace, ControlMode.RW_TRACE);
@ -749,7 +760,7 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerTest {
// Assemble actions will think read-only otherwise
DebuggerControlService controlService = addPlugin(tool, DebuggerControlServicePlugin.class);
createLegacyTrace("ARM:LE:32:v8", 0x00400000, () -> tb.buf());
createTrace("ARM:LE:32:v8", 0x00400000, () -> tb.buf());
Address start = tb.addr(0x00400000);
controlService.setCurrentMode(tb.trace, ControlMode.RW_TRACE);
@ -768,7 +779,7 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerTest {
// Assemble actions will think read-only otherwise
DebuggerControlService controlService = addPlugin(tool, DebuggerControlServicePlugin.class);
TraceObjectThread thread = createPolyglotTrace("armv8le", 0x00400000, () -> tb.buf());
TraceThread thread = createPolyglotTrace("armv8le", 0x00400000, () -> tb.buf());
Address start = tb.addr(0x00400000);
controlService.setCurrentMode(tb.trace, ControlMode.RW_TRACE);
@ -787,7 +798,7 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerTest {
// Assemble actions will think read-only otherwise
DebuggerControlService controlService = addPlugin(tool, DebuggerControlServicePlugin.class);
TraceObjectThread thread = createPolyglotTrace("armv8le", 0x00400000, () -> tb.buf());
TraceThread thread = createPolyglotTrace("armv8le", 0x00400000, () -> tb.buf());
Address start = tb.addr(0x00400000);
controlService.setCurrentMode(tb.trace, ControlMode.RW_TRACE);

View file

@ -34,8 +34,6 @@ import ghidra.app.plugin.core.debug.gui.DebuggerResources;
import ghidra.app.plugin.core.debug.gui.copying.DebuggerCopyPlan.AllCopiers;
import ghidra.app.util.viewer.listingpanel.PropertyBasedBackgroundColorModel;
import ghidra.program.database.IntRangeMap;
import ghidra.program.disassemble.Disassembler;
import ghidra.program.disassemble.DisassemblerMessageListener;
import ghidra.program.model.address.*;
import ghidra.program.model.data.*;
import ghidra.program.model.lang.Register;
@ -75,9 +73,10 @@ public class DebuggerCopyPlanTest extends AbstractGhidraHeadedDebuggerTest {
byte src[] = new byte[0x10000];
r.nextBytes(src);
try (Transaction tx = tb.startTransaction()) {
tb.createRootObject("Target");
DBTraceMemoryManager memory = tb.trace.getMemoryManager();
memory.createRegion(".text", 0, tb.range(0x55550000, 0x5555ffff), TraceMemoryFlag.READ,
TraceMemoryFlag.EXECUTE);
memory.createRegion("Memory[.text]", 0, tb.range(0x55550000, 0x5555ffff),
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
memory.putBytes(0, tb.addr(0x55550000), ByteBuffer.wrap(src));
}
@ -107,9 +106,10 @@ public class DebuggerCopyPlanTest extends AbstractGhidraHeadedDebuggerTest {
assertTrue(AllCopiers.STATE.isAvailable(view, program));
try (Transaction tx = tb.startTransaction()) {
tb.createRootObject("Target");
DBTraceMemoryManager memory = tb.trace.getMemoryManager();
memory.createRegion(".text", 0, tb.range(0x55550000, 0x5555ffff), TraceMemoryFlag.READ,
TraceMemoryFlag.EXECUTE);
memory.createRegion("Memory[.text]", 0, tb.range(0x55550000, 0x5555ffff),
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
memory.putBytes(0, tb.addr(0x55550000), ByteBuffer.allocate(4096));
memory.setState(0, tb.addr(0x55551000), TraceMemoryState.ERROR);
}
@ -182,10 +182,14 @@ public class DebuggerCopyPlanTest extends AbstractGhidraHeadedDebuggerTest {
AddressRange trng = tb.range(0x55550000, 0x5555ffff);
Assembler asm = Assemblers.getAssembler(view);
try (Transaction tx = tb.startTransaction()) {
tb.createRootObject("Target");
DBTraceMemoryManager memory = tb.trace.getMemoryManager();
memory.createRegion(".text", 0, trng, TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
InstructionIterator iit =
asm.assemble(tb.addr(0x55550000), "imm r0, #123", "imm r1, #234", "add r0, r1");
memory.createRegion("Memory[.text]", 0, trng,
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
InstructionIterator iit = asm.assemble(tb.addr(0x55550000),
"imm r0, #123",
"imm r1, #234",
"add r0, r1");
assertTrue(iit.hasNext());
}
@ -228,10 +232,14 @@ public class DebuggerCopyPlanTest extends AbstractGhidraHeadedDebuggerTest {
AddressRange trng = tb.range(0x55550000, 0x5555ffff);
Assembler asm = Assemblers.getAssembler(view);
try (Transaction tx = tb.startTransaction()) {
tb.createRootObject("Target");
DBTraceMemoryManager memory = tb.trace.getMemoryManager();
memory.createRegion(".text", 0, trng, TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
InstructionIterator iit =
asm.assemble(tb.addr(0x55550000), "MOV RAX, 1234", "MOV RCX, 2345", "ADD RAX, RCX");
memory.createRegion("Memory[.text]", 0, trng,
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
InstructionIterator iit = asm.assemble(tb.addr(0x55550000),
"MOV RAX, 1234",
"MOV RCX, 2345",
"ADD RAX, RCX");
assertTrue(iit.hasNext());
}
@ -272,7 +280,7 @@ public class DebuggerCopyPlanTest extends AbstractGhidraHeadedDebuggerTest {
assertTrue(AllCopiers.INSTRUCTIONS.isAvailable(view, program));
AddressRange trng = tb.range(0x55550000, 0x5555ffff);
// Assembler asm = Assemblers.getAssembler(view);
Assembler asm = Assemblers.getAssembler(view);
Register contextReg = tb.language.getContextBaseRegister();
Register longMode = tb.language.getRegister("longMode");
@ -281,26 +289,17 @@ public class DebuggerCopyPlanTest extends AbstractGhidraHeadedDebuggerTest {
rv = rv.assign(longMode, BigInteger.ZERO);
Instruction checkCtx;
try (Transaction tx = tb.startTransaction()) {
tb.createRootObject("Target");
DBTraceMemoryManager memory = tb.trace.getMemoryManager();
memory.createRegion(".text", 0, trng, TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
memory.createRegion("Memory[.text]", 0, trng,
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
tb.trace.getRegisterContextManager().setValue(tb.language, rv, Lifespan.nowOn(0), trng);
// TODO: Once GP-1426 is resolved, use the assembler
/*
InstructionIterator iit = asm.assemble(tb.addr(0x55550000),
"MOV EAX, 1234",
"MOV ECX, 2345",
"ADD EAX, ECX");
checkCtx = iit.next();
*/
memory.putBytes(0, tb.addr(0x55550000), tb.buf(0xb8, 0xd2, 0x04, 0x00, 0x00, // MOV EAX,1234
0xb9, 0x29, 0x09, 0x00, 0x00, // MOV ECX,2345
0x01, 0xc8 // ADD EAX,ECX
));
Disassembler
.getDisassembler(view, TaskMonitor.DUMMY, DisassemblerMessageListener.IGNORE)
.disassemble(tb.addr(0x55550000), tb.set(tb.range(0x55550000, 0x5555000b)));
checkCtx = tb.trace.getCodeManager().instructions().getAt(0, tb.addr(0x55550000));
}
// Sanity pre-check
RegisterValue insCtx = checkCtx.getRegisterValue(contextReg);
@ -352,8 +351,10 @@ public class DebuggerCopyPlanTest extends AbstractGhidraHeadedDebuggerTest {
AddressRange trng = tb.range(0x55560000, 0x5556ffff);
try (Transaction tx = tb.startTransaction()) {
tb.createRootObject("Target");
DBTraceMemoryManager memory = tb.trace.getMemoryManager();
memory.createRegion(".data", 0, trng, TraceMemoryFlag.READ, TraceMemoryFlag.WRITE);
memory.createRegion("Memory[.data]", 0, trng,
TraceMemoryFlag.READ, TraceMemoryFlag.WRITE);
tb.addData(0, tb.addr(0x55560000), ByteDataType.dataType, tb.buf(0x12));
tb.addData(0, tb.addr(0x55560001), ShortDataType.dataType, tb.buf(0x12, 0x34));
tb.addData(0, tb.addr(0x55560003), IntegerDataType.dataType,
@ -412,8 +413,10 @@ public class DebuggerCopyPlanTest extends AbstractGhidraHeadedDebuggerTest {
AddressRange trng = tb.range(0x55560000, 0x5556ffff);
try (Transaction tx = tb.startTransaction()) {
tb.createRootObject("Target");
DBTraceMemoryManager memory = tb.trace.getMemoryManager();
memory.createRegion(".data", 0, trng, TraceMemoryFlag.READ, TraceMemoryFlag.WRITE);
memory.createRegion("Memory[.data]", 0, trng,
TraceMemoryFlag.READ, TraceMemoryFlag.WRITE);
tb.addData(0, tb.addr(0x55560000), ByteDataType.dataType, tb.buf(0x12));
tb.addData(0, tb.addr(0x55560001), ShortDataType.dataType, tb.buf(0x12, 0x34));
tb.addData(0, tb.addr(0x55560003), IntegerDataType.dataType,
@ -479,21 +482,20 @@ public class DebuggerCopyPlanTest extends AbstractGhidraHeadedDebuggerTest {
assertTrue(AllCopiers.LABELS.isAvailable(view, program));
try (Transaction tx = tb.startTransaction()) {
tb.createRootObject("Target");
DBTraceMemoryManager memory = tb.trace.getMemoryManager();
memory.createRegion(".text", 0, tb.range(0x55550000, 0x5555ffff), TraceMemoryFlag.READ,
TraceMemoryFlag.EXECUTE);
memory.createRegion("Memory[.text]", 0, tb.range(0x55550000, 0x5555ffff),
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
DBTraceNamespaceSymbol global = tb.trace.getSymbolManager().getGlobalNamespace();
DBTraceLabelSymbolView labels = tb.trace.getSymbolManager().labels();
labels.create(0, null, tb.addr(0x55550000), "test_label1", global, SourceType.IMPORTED);
labels.create(0, null, tb.addr(0x55550005), "test_label2", global,
SourceType.USER_DEFINED);
labels.create(0, tb.addr(0x55550000), "test_label1", global, SourceType.IMPORTED);
labels.create(0, tb.addr(0x55550005), "test_label2", global, SourceType.USER_DEFINED);
DBTraceNamespaceSymbolView namespaces = tb.trace.getSymbolManager().namespaces();
DBTraceNamespaceSymbol testNs = namespaces.add("test_ns", global, SourceType.ANALYSIS);
DBTraceNamespaceSymbol testNsChild =
namespaces.add("test_ns_child", testNs, SourceType.USER_DEFINED);
labels.create(0, null, tb.addr(0x55550800), "test_label3", testNsChild,
SourceType.ANALYSIS);
labels.create(0, tb.addr(0x55550800), "test_label3", testNsChild, SourceType.ANALYSIS);
}
Address paddr = tb.addr(stSpace, 0x00400000);
@ -550,14 +552,15 @@ public class DebuggerCopyPlanTest extends AbstractGhidraHeadedDebuggerTest {
assertTrue(AllCopiers.BREAKPOINTS.isAvailable(view, program));
try (Transaction tx = tb.startTransaction()) {
tb.createRootObject("Target");
DBTraceMemoryManager memory = tb.trace.getMemoryManager();
memory.createRegion(".text", 0, tb.range(0x55550000, 0x5555ffff), TraceMemoryFlag.READ,
TraceMemoryFlag.EXECUTE);
memory.createRegion("Memory[.text]", 0, tb.range(0x55550000, 0x5555ffff),
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
DBTraceBreakpointManager breakpoints = tb.trace.getBreakpointManager();
breakpoints.placeBreakpoint("[1]", 0, tb.addr(0x55550123), List.of(),
breakpoints.placeBreakpoint("Breakpoints[1]", 0, tb.addr(0x55550123), List.of(),
Set.of(TraceBreakpointKind.SW_EXECUTE), true, "Test-1");
breakpoints.placeBreakpoint("[2]", 0, tb.addr(0x55550321), List.of(),
breakpoints.placeBreakpoint("Breakpoints[2]", 0, tb.addr(0x55550321), List.of(),
Set.of(TraceBreakpointKind.SW_EXECUTE), false, "Test-2");
}
@ -603,9 +606,10 @@ public class DebuggerCopyPlanTest extends AbstractGhidraHeadedDebuggerTest {
assertTrue(AllCopiers.BOOKMARKS.isAvailable(view, program));
try (Transaction tx = tb.startTransaction()) {
tb.createRootObject("Target");
DBTraceMemoryManager memory = tb.trace.getMemoryManager();
memory.createRegion(".text", 0, tb.range(0x55550000, 0x5555ffff), TraceMemoryFlag.READ,
TraceMemoryFlag.EXECUTE);
memory.createRegion("Memory[.text]", 0, tb.range(0x55550000, 0x5555ffff),
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
BookmarkManager bookmarks = view.getBookmarkManager();
bookmarks.defineType("TestType", DebuggerResources.ICON_DEBUGGER, Palette.BLUE, 1);
@ -651,11 +655,12 @@ public class DebuggerCopyPlanTest extends AbstractGhidraHeadedDebuggerTest {
assertTrue(AllCopiers.REFERENCES.isAvailable(view, program));
try (Transaction tx = tb.startTransaction()) {
tb.createRootObject("Target");
DBTraceMemoryManager memory = tb.trace.getMemoryManager();
memory.createRegion(".text", 0, tb.range(0x55550000, 0x5555ffff), TraceMemoryFlag.READ,
TraceMemoryFlag.EXECUTE);
memory.createRegion(".data", 0, tb.range(0x55560000, 0x5556ffff), TraceMemoryFlag.READ,
TraceMemoryFlag.WRITE);
memory.createRegion("Memory[.text]", 0, tb.range(0x55550000, 0x5555ffff),
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
memory.createRegion("Memory[.data]", 0, tb.range(0x55560000, 0x5556ffff),
TraceMemoryFlag.READ, TraceMemoryFlag.WRITE);
ReferenceManager references = view.getReferenceManager();
references.addMemoryReference(tb.addr(0x55550123), tb.addr(0x55550321),
@ -702,9 +707,10 @@ public class DebuggerCopyPlanTest extends AbstractGhidraHeadedDebuggerTest {
assertTrue(AllCopiers.COMMENTS.isAvailable(view, program));
try (Transaction tx = tb.startTransaction()) {
tb.createRootObject("Target");
DBTraceMemoryManager memory = tb.trace.getMemoryManager();
memory.createRegion(".text", 0, tb.range(0x55550000, 0x5555ffff), TraceMemoryFlag.READ,
TraceMemoryFlag.EXECUTE);
memory.createRegion("Memory[.text]", 0, tb.range(0x55550000, 0x5555ffff),
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
Listing listing = view.getListing();
listing.setComment(tb.addr(0x55550123), CommentType.EOL, "Test EOL Comment");

View file

@ -129,8 +129,9 @@ public class DebuggerTraceViewDiffPluginTest extends AbstractGhidraHeadedDebugge
public void testColorsDiffBytes() throws Throwable {
createAndOpenTrace();
try (Transaction tx = tb.startTransaction()) {
tb.createRootObject("Target");
DBTraceMemoryManager mm = tb.trace.getMemoryManager();
mm.createRegion(".text", 0, tb.range(0x00400000, 0x0040ffff),
mm.createRegion("Memory[.text]", 0, tb.range(0x00400000, 0x0040ffff),
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
ByteBuffer buf = ByteBuffer.allocate(0x1000); // Yes, smaller than .text
@ -164,8 +165,9 @@ public class DebuggerTraceViewDiffPluginTest extends AbstractGhidraHeadedDebugge
public void testActionPrevDiff() throws Throwable {
createAndOpenTrace();
try (Transaction tx = tb.startTransaction()) {
tb.createRootObject("Target");
DBTraceMemoryManager mm = tb.trace.getMemoryManager();
mm.createRegion(".text", 0, tb.range(0x00400000, 0x0040ffff),
mm.createRegion("Memory[.text]", 0, tb.range(0x00400000, 0x0040ffff),
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
ByteBuffer buf = ByteBuffer.allocate(0x1000); // Yes, smaller than .text
@ -201,8 +203,9 @@ public class DebuggerTraceViewDiffPluginTest extends AbstractGhidraHeadedDebugge
public void testActionNextDiff() throws Throwable {
createAndOpenTrace();
try (Transaction tx = tb.startTransaction()) {
tb.createRootObject("Target");
DBTraceMemoryManager mm = tb.trace.getMemoryManager();
mm.createRegion(".text", 0, tb.range(0x00400000, 0x0040ffff),
mm.createRegion("Memory[.text]", 0, tb.range(0x00400000, 0x0040ffff),
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
ByteBuffer buf = ByteBuffer.allocate(0x1000); // Yes, smaller than .text

View file

@ -45,7 +45,6 @@ import ghidra.program.util.ProgramSelection;
import ghidra.trace.model.Lifespan;
import ghidra.trace.model.Trace;
import ghidra.trace.model.memory.TraceMemoryRegion;
import ghidra.trace.model.memory.TraceObjectMemoryRegion;
import ghidra.trace.model.modules.TraceStaticMapping;
import ghidra.trace.model.target.TraceObject;
import ghidra.trace.model.target.TraceObject.ConflictResolution;
@ -80,10 +79,10 @@ public class DebuggerRegionsProviderTest extends AbstractGhidraHeadedDebuggerTes
DebuggerRegionsProvider provider;
TraceObjectMemoryRegion regionExeText;
TraceObjectMemoryRegion regionExeData;
TraceObjectMemoryRegion regionLibText;
TraceObjectMemoryRegion regionLibData;
TraceMemoryRegion regionExeText;
TraceMemoryRegion regionExeData;
TraceMemoryRegion regionLibText;
TraceMemoryRegion regionLibData;
MemoryBlock blockExeText;
MemoryBlock blockExeData;
@ -109,21 +108,21 @@ public class DebuggerRegionsProviderTest extends AbstractGhidraHeadedDebuggerTes
}
}
protected TraceObjectMemoryRegion addRegion(String name, long loaded, AddressRange range) {
protected TraceMemoryRegion addRegion(String name, long loaded, AddressRange range) {
boolean isData = name.endsWith(".data");
TraceObjectManager om = tb.trace.getObjectManager();
KeyPath memPath = KeyPath.parse("Memory");
Lifespan span = Lifespan.nowOn(loaded);
TraceObjectMemoryRegion region = Objects.requireNonNull(om.createObject(memPath.index(name))
TraceMemoryRegion region = Objects.requireNonNull(om.createObject(memPath.index(name))
.insert(span, ConflictResolution.TRUNCATE)
.getDestination(null)
.queryInterface(TraceObjectMemoryRegion.class));
.queryInterface(TraceMemoryRegion.class));
TraceObject obj = region.getObject();
obj.setAttribute(span, TraceObjectMemoryRegion.KEY_DISPLAY, name);
obj.setAttribute(span, TraceObjectMemoryRegion.KEY_RANGE, range);
obj.setAttribute(span, TraceObjectMemoryRegion.KEY_READABLE, true);
obj.setAttribute(span, TraceObjectMemoryRegion.KEY_WRITABLE, isData);
obj.setAttribute(span, TraceObjectMemoryRegion.KEY_EXECUTABLE, !isData);
obj.setAttribute(span, TraceMemoryRegion.KEY_DISPLAY, name);
obj.setAttribute(span, TraceMemoryRegion.KEY_RANGE, range);
obj.setAttribute(span, TraceMemoryRegion.KEY_READABLE, true);
obj.setAttribute(span, TraceMemoryRegion.KEY_WRITABLE, isData);
obj.setAttribute(span, TraceMemoryRegion.KEY_EXECUTABLE, !isData);
return region;
}
@ -218,7 +217,7 @@ public class DebuggerRegionsProviderTest extends AbstractGhidraHeadedDebuggerTes
public void testAddThenActivateTracePopulates() throws Exception {
createAndOpenTrace();
TraceObjectMemoryRegion region;
TraceMemoryRegion region;
try (Transaction tx = tb.startTransaction()) {
region = addRegion("bin:.text", 0, tb.range(0x00400000, 0x0040ffff));
}
@ -240,7 +239,7 @@ public class DebuggerRegionsProviderTest extends AbstractGhidraHeadedDebuggerTes
waitForPass(() -> assertTableSize(0));
TraceObjectMemoryRegion region;
TraceMemoryRegion region;
try (Transaction tx = tb.startTransaction()) {
region = addRegion("bin:.text", 0, tb.range(0x00400000, 0x0040ffff));
}
@ -257,7 +256,7 @@ public class DebuggerRegionsProviderTest extends AbstractGhidraHeadedDebuggerTes
public void testRemoveRegionRemovesFromTable() throws Exception {
createAndOpenTrace();
TraceObjectMemoryRegion region;
TraceMemoryRegion region;
try (Transaction tx = tb.startTransaction()) {
region = addRegion("bin:.text", 0, tb.range(0x00400000, 0x0040ffff));
}
@ -284,7 +283,7 @@ public class DebuggerRegionsProviderTest extends AbstractGhidraHeadedDebuggerTes
public void testUndoRedo() throws Exception {
createAndOpenTrace();
TraceObjectMemoryRegion region;
TraceMemoryRegion region;
try (Transaction tx = tb.startTransaction()) {
region = addRegion("bin:.text", 0, tb.range(0x00400000, 0x0040ffff));
}
@ -320,7 +319,7 @@ public class DebuggerRegionsProviderTest extends AbstractGhidraHeadedDebuggerTes
createAndOpenTrace();
traceManager.activateTrace(tb.trace);
TraceObjectMemoryRegion region;
TraceMemoryRegion region;
try (Transaction tx = tb.startTransaction()) {
region = addRegion("bin:.text", 0, tb.range(0x00400000, 0x0040ffff));
waitForDomainObject(tb.trace);
@ -346,7 +345,7 @@ public class DebuggerRegionsProviderTest extends AbstractGhidraHeadedDebuggerTes
createAndOpenTrace();
TraceObjectMemoryRegion region;
TraceMemoryRegion region;
try (Transaction tx = tb.startTransaction()) {
region = addRegion("bin:.text", 0, tb.range(0x00400000, 0x0040ffff));
}
@ -465,7 +464,7 @@ public class DebuggerRegionsProviderTest extends AbstractGhidraHeadedDebuggerTes
createAndOpenTrace();
TraceObjectMemoryRegion region;
TraceMemoryRegion region;
try (Transaction tx = tb.startTransaction()) {
region = addRegion("bin:.text", 0, tb.range(0x00400000, 0x0040ffff));
}
@ -514,7 +513,7 @@ public class DebuggerRegionsProviderTest extends AbstractGhidraHeadedDebuggerTes
createAndOpenTrace();
TraceObjectMemoryRegion region;
TraceMemoryRegion region;
try (Transaction tx = tb.startTransaction()) {
region = addRegion("bin:.text", 0, tb.range(0x00400000, 0x0040ffff));
}

View file

@ -43,13 +43,12 @@ import ghidra.trace.database.ToyDBTraceBuilder.EventSuspension;
import ghidra.trace.model.Lifespan;
import ghidra.trace.model.target.*;
import ghidra.trace.model.target.TraceObject.ConflictResolution;
import ghidra.trace.model.target.iface.TraceObjectEventScope;
import ghidra.trace.model.target.iface.TraceEventScope;
import ghidra.trace.model.target.iface.TraceObjectInterface;
import ghidra.trace.model.target.path.KeyPath;
import ghidra.trace.model.target.schema.SchemaContext;
import ghidra.trace.model.target.schema.TraceObjectSchema.SchemaName;
import ghidra.trace.model.target.schema.XmlSchemaContext;
import ghidra.trace.model.thread.TraceObjectThread;
import ghidra.trace.model.thread.TraceThread;
public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerTest {
@ -164,7 +163,7 @@ public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerTest
prevThread.setAttribute(Lifespan.nowOn(i), "_next", thread);
}
objects.getRootObject()
.setAttribute(Lifespan.nowOn(i), TraceObjectEventScope.KEY_EVENT_THREAD,
.setAttribute(Lifespan.nowOn(i), TraceEventScope.KEY_EVENT_THREAD,
thread);
return thread;
}
@ -700,6 +699,8 @@ public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerTest
* sufficient events to overload the queue, the event support with clear them and just issue an
* OBJ_RESTORED event instead. This test ensures we update attributes in the tree when that
* happens.
*
* @throws Throwable because
*/
@Test
public void testTreeTracksChangeAttributeWithEventsSuspended() throws Throwable {
@ -998,7 +999,7 @@ public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerTest
TraceObjectManager objects = tb.trace.getObjectManager();
TraceObject threadObj0 =
objects.getObjectByCanonicalPath(KeyPath.parse("Processes[0].Threads[0]"));
TraceThread thread0 = threadObj0.queryInterface(TraceObjectThread.class);
TraceThread thread0 = threadObj0.queryInterface(TraceThread.class);
createStack(threadObj0);
return thread0;
}

View file

@ -51,12 +51,10 @@ import ghidra.framework.main.DataTreeDialog;
import ghidra.plugin.importer.ImporterPlugin;
import ghidra.program.model.address.*;
import ghidra.program.model.mem.MemoryBlock;
import ghidra.trace.database.module.TraceObjectSection;
import ghidra.trace.model.Lifespan;
import ghidra.trace.model.Trace;
import ghidra.trace.model.memory.TraceObjectMemoryRegion;
import ghidra.trace.model.modules.TraceObjectModule;
import ghidra.trace.model.modules.TraceStaticMapping;
import ghidra.trace.model.memory.TraceMemoryRegion;
import ghidra.trace.model.modules.*;
import ghidra.trace.model.target.TraceObject;
import ghidra.trace.model.target.TraceObject.ConflictResolution;
import ghidra.trace.model.target.TraceObjectManager;
@ -109,13 +107,13 @@ public class DebuggerModulesProviderTest extends AbstractGhidraHeadedDebuggerTes
DebuggerModulesProvider provider;
protected TraceObjectModule modExe;
protected TraceObjectSection secExeText;
protected TraceObjectSection secExeData;
protected TraceModule modExe;
protected TraceSection secExeText;
protected TraceSection secExeData;
protected TraceObjectModule modLib;
protected TraceObjectSection secLibText;
protected TraceObjectSection secLibData;
protected TraceModule modLib;
protected TraceSection secLibText;
protected TraceSection secLibData;
protected SchemaContext ctx;
@ -145,13 +143,13 @@ public class DebuggerModulesProviderTest extends AbstractGhidraHeadedDebuggerTes
try (Transaction tx = tb.startTransaction()) {
TraceObject root = om.getRootObject();
for (TraceObject module : (Iterable<TraceObject>) () -> root
.findSuccessorsInterface(Lifespan.at(0), TraceObjectModule.class, true)
.findSuccessorsInterface(Lifespan.at(0), TraceModule.class, true)
.map(p -> p.getDestination(root))
.iterator()) {
String moduleName = module.getCanonicalPath().index();
Lifespan span = module.getLife().bound();
for (TraceObject section : (Iterable<TraceObject>) () -> module
.findSuccessorsInterface(Lifespan.at(0), TraceObjectSection.class,
.findSuccessorsInterface(Lifespan.at(0), TraceSection.class,
true)
.map(p -> p.getDestination(root))
.iterator()) {
@ -161,42 +159,42 @@ public class DebuggerModulesProviderTest extends AbstractGhidraHeadedDebuggerTes
.getSingletonPath())
.insert(span, ConflictResolution.TRUNCATE)
.getDestination(root);
region.setAttribute(span, TraceObjectMemoryRegion.KEY_RANGE,
section.getAttribute(0, TraceObjectSection.KEY_RANGE).getValue());
region.setAttribute(span, TraceObjectMemoryRegion.KEY_READABLE, true);
region.setAttribute(span, TraceObjectMemoryRegion.KEY_WRITABLE,
region.setAttribute(span, TraceMemoryRegion.KEY_RANGE,
section.getAttribute(0, TraceSection.KEY_RANGE).getValue());
region.setAttribute(span, TraceMemoryRegion.KEY_READABLE, true);
region.setAttribute(span, TraceMemoryRegion.KEY_WRITABLE,
".data".equals(sectionName));
region.setAttribute(span, TraceObjectMemoryRegion.KEY_EXECUTABLE,
region.setAttribute(span, TraceMemoryRegion.KEY_EXECUTABLE,
".text".equals(sectionName));
}
}
}
}
protected TraceObjectModule addModule(String name, AddressRange range, Lifespan span) {
protected TraceModule addModule(String name, AddressRange range, Lifespan span) {
PathPattern modulePattern = PathFilter.parse("Processes[1].Modules[]");
TraceObjectManager om = tb.trace.getObjectManager();
TraceObjectModule module = Objects.requireNonNull(
TraceModule module = Objects.requireNonNull(
om.createObject(modulePattern.applyKeys(name).getSingletonPath())
.insert(span, ConflictResolution.TRUNCATE)
.getDestination(null)
.queryInterface(TraceObjectModule.class));
module.getObject().setAttribute(span, TraceObjectModule.KEY_MODULE_NAME, name);
module.getObject().setAttribute(span, TraceObjectModule.KEY_RANGE, range);
.queryInterface(TraceModule.class));
module.getObject().setAttribute(span, TraceModule.KEY_MODULE_NAME, name);
module.getObject().setAttribute(span, TraceModule.KEY_RANGE, range);
return module;
}
protected TraceObjectSection addSection(TraceObjectModule module, String name,
protected TraceSection addSection(TraceModule module, String name,
AddressRange range) {
TraceObjectManager om = tb.trace.getObjectManager();
Lifespan span = module.getObject().getLife().bound();
TraceObjectSection section = Objects.requireNonNull(om
TraceSection section = Objects.requireNonNull(om
.createObject(
module.getObject().getCanonicalPath().key("Sections").index(name))
.insert(span, ConflictResolution.TRUNCATE)
.getDestination(null)
.queryInterface(TraceObjectSection.class));
section.getObject().setAttribute(span, TraceObjectSection.KEY_RANGE, range);
.queryInterface(TraceSection.class));
section.getObject().setAttribute(span, TraceSection.KEY_RANGE, range);
return section;
}
@ -719,7 +717,7 @@ public class DebuggerModulesProviderTest extends AbstractGhidraHeadedDebuggerTes
for (ValueRow row : visibleSections()) {
assertEquals(modExe.getObject(), row.getValue()
.getChild()
.findCanonicalAncestorsInterface(TraceObjectModule.class)
.findCanonicalAncestorsInterface(TraceModule.class)
.findFirst()
.orElse(null));
}

View file

@ -115,8 +115,9 @@ public class DebuggerStaticMappingProviderTest extends AbstractGhidraHeadedDebug
intoProject(program);
try (Transaction tx = tb.startTransaction()) {
tb.createRootObject("Target");
tb.trace.getMemoryManager()
.addRegion(".text", Lifespan.nowOn(0),
.addRegion("Memory[.text]", Lifespan.nowOn(0),
tb.range(0xdeadbeefL, 0xdeadbeefL + 0xff),
Set.of(TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE));
}

View file

@ -26,7 +26,8 @@ import org.junit.Test;
import db.Transaction;
import generic.Unique;
import generic.theme.*;
import generic.theme.ApplicationThemeManager;
import generic.theme.ThemeManager;
import ghidra.app.plugin.assembler.Assembler;
import ghidra.app.plugin.assembler.Assemblers;
import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerTest;
@ -46,8 +47,10 @@ import ghidra.pcode.exec.trace.TraceSleighUtils;
import ghidra.program.model.address.Address;
import ghidra.program.model.listing.Instruction;
import ghidra.program.model.listing.InstructionIterator;
import ghidra.trace.database.ToyDBTraceBuilder.ToySchemaBuilder;
import ghidra.trace.model.Lifespan;
import ghidra.trace.model.memory.TraceMemoryFlag;
import ghidra.trace.model.target.schema.SchemaContext;
import ghidra.trace.model.thread.TraceThread;
import ghidra.trace.model.time.schedule.TraceSchedule;
@ -79,15 +82,25 @@ public class DebuggerPcodeStepperProviderTest extends AbstractGhidraHeadedDebugg
createTrace();
}
SchemaContext buildContext() {
return new ToySchemaBuilder()
.useRegistersPerFrame()
.noRegisterGroups()
.build();
}
protected void populateTrace() throws Exception {
start = tb.addr(0x00400000);
InstructionIterator iit;
try (Transaction tx = tb.startTransaction()) {
tb.createRootObject(buildContext(), "Target");
tb.trace.getMemoryManager()
.addRegion("echo:.text", Lifespan.nowOn(0), tb.range(0x00400000, 0x0040ffff),
.addRegion("Memory[echo:.text]", Lifespan.nowOn(0),
tb.range(0x00400000, 0x0040ffff),
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
thread = tb.getOrAddThread("1", 0);
thread = tb.getOrAddThread("Threads[1]", 0);
tb.createObjectsFramesAndRegs(thread, Lifespan.nowOn(0), tb.host, 1);
PcodeExecutor<byte[]> init = TraceSleighUtils.buildByteExecutor(tb.trace, 0, thread, 0);
init.executeSleigh("pc = 0x00400000;");
@ -124,7 +137,7 @@ public class DebuggerPcodeStepperProviderTest extends AbstractGhidraHeadedDebugg
public void testCloseCurrentTraceEmpty() throws Exception {
populateTrace();
TraceSchedule schedule1 = TraceSchedule.parse("0:.t0-1");
TraceSchedule schedule1 = TraceSchedule.parse("0:.t%d-1".formatted(thread.getKey()));
traceManager.openTrace(tb.trace);
traceManager.activateThread(thread);
waitForPass(() -> assertDecodeStep());
@ -166,13 +179,13 @@ public class DebuggerPcodeStepperProviderTest extends AbstractGhidraHeadedDebugg
});
// Just one p-code step to load injection (decode step)
TraceSchedule schedule1 = TraceSchedule.parse("0:.t0-1");
TraceSchedule schedule1 = TraceSchedule.parse("0:.t%d-1".formatted(thread.getKey()));
traceManager.openTrace(tb.trace);
traceManager.activateThread(thread);
traceManager.activateTime(schedule1);
waitForPass(() -> assertEquals(schedule1, pcodeProvider.current.getTime()));
waitForPass(() -> assertTrue(pcodeProvider.pcodeTableModel.getModelData()
waitForPass(() -> assertTrue(pcodeProvider.pcodeTableModel.copyModelData()
.stream()
.anyMatch(r -> r.getCode().contains("stepper_test_userop"))));
}

View file

@ -41,9 +41,9 @@ import ghidra.program.model.listing.Function;
import ghidra.program.model.symbol.SourceType;
import ghidra.program.util.ProgramLocation;
import ghidra.trace.model.*;
import ghidra.trace.model.memory.TraceObjectMemoryRegion;
import ghidra.trace.model.stack.TraceObjectStack;
import ghidra.trace.model.stack.TraceObjectStackFrame;
import ghidra.trace.model.memory.TraceMemoryRegion;
import ghidra.trace.model.stack.TraceStack;
import ghidra.trace.model.stack.TraceStackFrame;
import ghidra.trace.model.target.TraceObject;
import ghidra.trace.model.target.TraceObject.ConflictResolution;
import ghidra.trace.model.target.TraceObjectManager;
@ -51,7 +51,7 @@ import ghidra.trace.model.target.path.*;
import ghidra.trace.model.target.schema.SchemaContext;
import ghidra.trace.model.target.schema.TraceObjectSchema.SchemaName;
import ghidra.trace.model.target.schema.XmlSchemaContext;
import ghidra.trace.model.thread.TraceObjectThread;
import ghidra.trace.model.thread.TraceThread;
import ghidra.util.table.GhidraTable;
import ghidra.util.task.TaskMonitor;
@ -167,7 +167,7 @@ public class DebuggerStackProviderTest extends AbstractGhidraHeadedDebuggerTest
}
}
protected TraceObjectThread addThread(int n) {
protected TraceThread addThread(int n) {
PathPattern threadPattern = PathFilter.parse("Processes[1].Threads[]");
KeyPath threadPath = threadPattern.applyIntKeys(n).getSingletonPath();
try (Transaction tx = tb.startTransaction()) {
@ -175,26 +175,26 @@ public class DebuggerStackProviderTest extends AbstractGhidraHeadedDebuggerTest
.createObject(threadPath)
.insert(Lifespan.nowOn(0), ConflictResolution.TRUNCATE)
.getDestination(null)
.queryInterface(TraceObjectThread.class));
.queryInterface(TraceThread.class));
}
}
protected TraceObjectStack addStack(TraceObjectThread thread) {
protected TraceStack addStack(TraceThread thread) {
KeyPath stackPath = thread.getObject().getCanonicalPath().extend("Stack");
try (Transaction tx = tb.startTransaction()) {
return Objects.requireNonNull(tb.trace.getObjectManager()
.createObject(stackPath)
.insert(Lifespan.nowOn(0), ConflictResolution.TRUNCATE)
.getDestination(null)
.queryInterface(TraceObjectStack.class));
.queryInterface(TraceStack.class));
}
}
protected void addStackFrames(TraceObjectStack stack) {
protected void addStackFrames(TraceStack stack) {
addStackFrames(stack, 2);
}
protected void addStackFrames(TraceObjectStack stack, int count) {
protected void addStackFrames(TraceStack stack, int count) {
KeyPath stackPath = stack.getObject().getCanonicalPath();
TraceObjectManager om = tb.trace.getObjectManager();
try (Transaction tx = tb.startTransaction()) {
@ -202,7 +202,7 @@ public class DebuggerStackProviderTest extends AbstractGhidraHeadedDebuggerTest
TraceObject frame = om.createObject(stackPath.index(i))
.insert(Lifespan.nowOn(0), ConflictResolution.TRUNCATE)
.getDestination(null);
frame.setAttribute(Lifespan.nowOn(0), TraceObjectStackFrame.KEY_PC,
frame.setAttribute(Lifespan.nowOn(0), TraceStackFrame.KEY_PC,
tb.addr(0x00400100 + 0x100 * i));
}
}
@ -262,7 +262,7 @@ public class DebuggerStackProviderTest extends AbstractGhidraHeadedDebuggerTest
public void testActivateThreadNoStackEmpty() throws Exception {
createAndOpenTrace();
TraceObjectThread thread = addThread(1);
TraceThread thread = addThread(1);
waitForDomainObject(tb.trace);
traceManager.activateObject(thread.getObject());
@ -275,7 +275,7 @@ public class DebuggerStackProviderTest extends AbstractGhidraHeadedDebuggerTest
public void testActivateThreadThenAddEmptyStackEmpty() throws Exception {
createAndOpenTrace();
TraceObjectThread thread = addThread(1);
TraceThread thread = addThread(1);
addStack(thread);
waitForDomainObject(tb.trace);
@ -289,9 +289,9 @@ public class DebuggerStackProviderTest extends AbstractGhidraHeadedDebuggerTest
public void testActivateThreadThenAddStackPopulatesProvider() throws Exception {
createAndOpenTrace();
TraceObjectThread thread = addThread(1);
TraceThread thread = addThread(1);
traceManager.activateObject(thread.getObject());
TraceObjectStack stack = addStack(thread);
TraceStack stack = addStack(thread);
addStackFrames(stack);
waitForDomainObject(tb.trace);
waitForTasks();
@ -303,8 +303,8 @@ public class DebuggerStackProviderTest extends AbstractGhidraHeadedDebuggerTest
public void testAddStackThenActivateThreadPopulatesProvider() throws Exception {
createAndOpenTrace();
TraceObjectThread thread = addThread(1);
TraceObjectStack stack = addStack(thread);
TraceThread thread = addThread(1);
TraceStack stack = addStack(thread);
addStackFrames(stack);
waitForDomainObject(tb.trace);
@ -316,12 +316,14 @@ public class DebuggerStackProviderTest extends AbstractGhidraHeadedDebuggerTest
/**
* Because keys are strings, we need to ensure they get sorted numerically
*
* @throws Exception because
*/
@Test
public void testTableSortedCorrectly() throws Exception {
createAndOpenTrace();
TraceObjectThread thread = addThread(1);
TraceObjectStack stack = addStack(thread);
TraceThread thread = addThread(1);
TraceStack stack = addStack(thread);
addStackFrames(stack, 15);
waitForDomainObject(tb.trace);
@ -341,8 +343,8 @@ public class DebuggerStackProviderTest extends AbstractGhidraHeadedDebuggerTest
public void testAppendStackUpdatesProvider() throws Exception {
createAndOpenTrace();
TraceObjectThread thread = addThread(1);
TraceObjectStack stack = addStack(thread);
TraceThread thread = addThread(1);
TraceStack stack = addStack(thread);
addStackFrames(stack);
waitForDomainObject(tb.trace);
@ -356,7 +358,7 @@ public class DebuggerStackProviderTest extends AbstractGhidraHeadedDebuggerTest
.createObject(stack.getObject().getCanonicalPath().index(2))
.insert(Lifespan.nowOn(0), ConflictResolution.TRUNCATE)
.getDestination(null);
frame2.setAttribute(Lifespan.nowOn(0), TraceObjectStackFrame.KEY_PC,
frame2.setAttribute(Lifespan.nowOn(0), TraceStackFrame.KEY_PC,
tb.addr(0x00400300));
}
waitForDomainObject(tb.trace);
@ -374,8 +376,8 @@ public class DebuggerStackProviderTest extends AbstractGhidraHeadedDebuggerTest
public void testRemoveFrameUpdatesProvider() throws Exception {
createAndOpenTrace();
TraceObjectThread thread = addThread(1);
TraceObjectStack stack = addStack(thread);
TraceThread thread = addThread(1);
TraceStack stack = addStack(thread);
addStackFrames(stack);
waitForDomainObject(tb.trace);
@ -400,8 +402,8 @@ public class DebuggerStackProviderTest extends AbstractGhidraHeadedDebuggerTest
public void testRemoveStackUpdatesProvider() throws Exception {
createAndOpenTrace();
TraceObjectThread thread = addThread(1);
TraceObjectStack stack = addStack(thread);
TraceThread thread = addThread(1);
TraceStack stack = addStack(thread);
addStackFrames(stack);
waitForDomainObject(tb.trace);
@ -423,9 +425,9 @@ public class DebuggerStackProviderTest extends AbstractGhidraHeadedDebuggerTest
public void testActivateOtherThreadEmptiesProvider() throws Exception {
createAndOpenTrace();
TraceObjectThread thread1 = addThread(1);
TraceObjectThread thread2 = addThread(2);
TraceObjectStack stack1 = addStack(thread1);
TraceThread thread1 = addThread(1);
TraceThread thread2 = addThread(2);
TraceStack stack1 = addStack(thread1);
addStackFrames(stack1);
waitForDomainObject(tb.trace);
@ -444,8 +446,8 @@ public class DebuggerStackProviderTest extends AbstractGhidraHeadedDebuggerTest
public void testActivateSnap() throws Exception {
createAndOpenTrace();
TraceObjectThread thread = addThread(1);
TraceObjectStack stack = addStack(thread);
TraceThread thread = addThread(1);
TraceStack stack = addStack(thread);
addStackFrames(stack);
waitForDomainObject(tb.trace);
@ -477,8 +479,8 @@ public class DebuggerStackProviderTest extends AbstractGhidraHeadedDebuggerTest
public void testCloseCurrentTraceEmpty() throws Exception {
createAndOpenTrace();
TraceObjectThread thread = addThread(1);
TraceObjectStack stack = addStack(thread);
TraceThread thread = addThread(1);
TraceStack stack = addStack(thread);
addStackFrames(stack);
waitForDomainObject(tb.trace);
@ -497,8 +499,8 @@ public class DebuggerStackProviderTest extends AbstractGhidraHeadedDebuggerTest
public void testActivateFrameSelectsRow() throws Exception {
createAndOpenTrace();
TraceObjectThread thread = addThread(1);
TraceObjectStack stack = addStack(thread);
TraceThread thread = addThread(1);
TraceStack stack = addStack(thread);
addStackFrames(stack);
waitForDomainObject(tb.trace);
@ -524,8 +526,8 @@ public class DebuggerStackProviderTest extends AbstractGhidraHeadedDebuggerTest
public void testDoubleClickRowActivateFrame() throws Exception {
createAndOpenTrace();
TraceObjectThread thread = addThread(1);
TraceObjectStack stack = addStack(thread);
TraceThread thread = addThread(1);
TraceStack stack = addStack(thread);
addStackFrames(stack);
waitForDomainObject(tb.trace);
@ -557,8 +559,8 @@ public class DebuggerStackProviderTest extends AbstractGhidraHeadedDebuggerTest
traceManager.openTrace(tb.trace);
programManager.openProgram(program);
TraceObjectThread thread = addThread(1);
TraceObjectStack stack = addStack(thread);
TraceThread thread = addThread(1);
TraceStack stack = addStack(thread);
addStackFrames(stack);
waitForDomainObject(tb.trace);
@ -580,13 +582,13 @@ public class DebuggerStackProviderTest extends AbstractGhidraHeadedDebuggerTest
waitForDomainObject(program);
try (Transaction tx = tb.startTransaction()) {
TraceObjectMemoryRegion region = Objects.requireNonNull(tb.trace.getObjectManager()
TraceMemoryRegion region = Objects.requireNonNull(tb.trace.getObjectManager()
.createObject(KeyPath.parse("Processes[1].Memory[bin:.text]"))
.insert(Lifespan.nowOn(0), ConflictResolution.TRUNCATE)
.getDestination(null)
.queryInterface(TraceObjectMemoryRegion.class));
.queryInterface(TraceMemoryRegion.class));
region.getObject()
.setAttribute(Lifespan.nowOn(0), TraceObjectMemoryRegion.KEY_RANGE,
.setAttribute(Lifespan.nowOn(0), TraceMemoryRegion.KEY_RANGE,
tb.drng(0x00400000, 0x00400fff));
TraceLocation dloc =

View file

@ -34,13 +34,13 @@ import ghidra.debug.api.tracemgr.DebuggerCoordinates;
import ghidra.trace.model.*;
import ghidra.trace.model.target.TraceObject.ConflictResolution;
import ghidra.trace.model.target.TraceObjectManager;
import ghidra.trace.model.target.iface.TraceObjectExecutionStateful;
import ghidra.trace.model.target.iface.TraceExecutionStateful;
import ghidra.trace.model.target.path.PathFilter;
import ghidra.trace.model.target.path.PathPattern;
import ghidra.trace.model.target.schema.SchemaContext;
import ghidra.trace.model.target.schema.TraceObjectSchema.SchemaName;
import ghidra.trace.model.target.schema.XmlSchemaContext;
import ghidra.trace.model.thread.TraceObjectThread;
import ghidra.trace.model.thread.TraceThread;
import ghidra.trace.model.time.TraceTimeManager;
import ghidra.util.table.GhidraTable;
@ -71,8 +71,8 @@ public class DebuggerThreadsProviderTest extends AbstractGhidraHeadedDebuggerTes
DebuggerThreadsProvider provider;
protected TraceObjectThread thread1;
protected TraceObjectThread thread2;
protected TraceThread thread1;
protected TraceThread thread2;
protected SchemaContext ctx;
@ -95,18 +95,18 @@ public class DebuggerThreadsProviderTest extends AbstractGhidraHeadedDebuggerTes
}
}
protected TraceObjectThread addThread(int index, Lifespan lifespan, String comment) {
protected TraceThread addThread(int index, Lifespan lifespan, String comment) {
TraceObjectManager om = tb.trace.getObjectManager();
PathPattern threadPattern = PathFilter.parse("Processes[1].Threads[]");
TraceObjectThread thread = Objects.requireNonNull(om.createObject(
TraceThread thread = Objects.requireNonNull(om.createObject(
threadPattern.applyIntKeys(index).getSingletonPath())
.insert(lifespan, ConflictResolution.TRUNCATE)
.getDestination(null)
.queryInterface(TraceObjectThread.class));
.queryInterface(TraceThread.class));
thread.getObject()
.setAttribute(lifespan, TraceObjectExecutionStateful.KEY_STATE,
.setAttribute(lifespan, TraceExecutionStateful.KEY_STATE,
TraceExecutionState.STOPPED.name());
thread.getObject().setAttribute(lifespan, TraceObjectThread.KEY_COMMENT, comment);
thread.getObject().setAttribute(lifespan, TraceThread.KEY_COMMENT, comment);
return thread;
}
@ -160,7 +160,7 @@ public class DebuggerThreadsProviderTest extends AbstractGhidraHeadedDebuggerTes
assertNull(provider.panel.getSelectedItem());
}
protected void assertThreadSelected(TraceObjectThread thread) {
protected void assertThreadSelected(TraceThread thread) {
ValueRow row = provider.panel.getSelectedItem();
assertNotNull(row);
assertEquals(thread.getObject(), row.getValue().getChild());
@ -329,7 +329,7 @@ public class DebuggerThreadsProviderTest extends AbstractGhidraHeadedDebuggerTes
waitForTasks();
waitForPass(() -> assertEquals("A different comment",
thread1.getObject().getAttribute(0, TraceObjectThread.KEY_COMMENT).getValue()));
thread1.getObject().getAttribute(0, TraceThread.KEY_COMMENT).getValue()));
}
// @Test // Not gonna with write-behind cache

View file

@ -92,7 +92,7 @@ public class DebuggerTimeProviderTest extends AbstractGhidraHeadedDebuggerTest {
// Timestamp is left unchecked, since default is current time
}
@Test // TODO: Technically, this is a plugin action.... Different test case?
@Test // Technically, this is a plugin action.... Different test case?
public void testActionRenameSnapshot() throws Exception {
// More often than not, this action will be used from the dynamic listing
addPlugin(tool, DebuggerListingPlugin.class);
@ -125,7 +125,7 @@ public class DebuggerTimeProviderTest extends AbstractGhidraHeadedDebuggerTest {
DBTraceSnapshot snapshot = tb.trace.getTimeManager().getSnapshot(10, false);
assertEquals("My Snapshot", snapshot.getDescription());
// TODO: Test cancelled has no effect
// LATER?: Test cancelled has no effect
}
@Test
@ -153,7 +153,8 @@ public class DebuggerTimeProviderTest extends AbstractGhidraHeadedDebuggerTest {
createSnaplessTrace();
TraceThread thread;
try (Transaction tx = tb.startTransaction()) {
thread = tb.trace.getThreadManager().createThread("Thread 1", 0);
tb.createRootObject("Target");
thread = tb.trace.getThreadManager().createThread("Threads[1]", 0);
}
traceManager.openTrace(tb.trace);
traceManager.activateThread(thread);

View file

@ -29,8 +29,7 @@ import ghidra.program.model.lang.Register;
import ghidra.program.model.lang.RegisterValue;
import ghidra.trace.model.Trace;
import ghidra.trace.model.TraceExecutionState;
import ghidra.trace.model.breakpoint.TraceBreakpoint;
import ghidra.trace.model.breakpoint.TraceBreakpointKind;
import ghidra.trace.model.breakpoint.*;
import ghidra.trace.model.guest.TracePlatform;
import ghidra.trace.model.stack.TraceStackFrame;
import ghidra.trace.model.target.TraceObject;
@ -233,27 +232,27 @@ public class MockTarget implements Target {
}
@Override
public boolean isBreakpointValid(TraceBreakpoint breakpoint) {
public boolean isBreakpointValid(TraceBreakpointLocation breakpoint) {
return true;
}
@Override
public CompletableFuture<Void> deleteBreakpointAsync(TraceBreakpoint breakpoint) {
public CompletableFuture<Void> deleteBreakpointAsync(TraceBreakpointCommon breakpoint) {
return AsyncUtils.nil();
}
@Override
public void deleteBreakpoint(TraceBreakpoint breakpoint) {
public void deleteBreakpoint(TraceBreakpointCommon breakpoint) {
}
@Override
public CompletableFuture<Void> toggleBreakpointAsync(TraceBreakpoint breakpoint,
public CompletableFuture<Void> toggleBreakpointAsync(TraceBreakpointCommon breakpoint,
boolean enabled) {
return AsyncUtils.nil();
}
@Override
public void toggleBreakpoint(TraceBreakpoint breakpoint, boolean enabled) {
public void toggleBreakpoint(TraceBreakpointCommon breakpoint, boolean enabled) {
}
@Override

View file

@ -52,16 +52,18 @@ import ghidra.program.model.listing.ProgramContext;
import ghidra.program.model.mem.Memory;
import ghidra.program.model.mem.MemoryBlock;
import ghidra.program.util.ProgramLocation;
import ghidra.trace.database.ToyDBTraceBuilder.ToySchemaBuilder;
import ghidra.trace.model.*;
import ghidra.trace.model.breakpoint.TraceBreakpoint;
import ghidra.trace.model.breakpoint.TraceBreakpointKind;
import ghidra.trace.model.breakpoint.TraceBreakpointLocation;
import ghidra.trace.model.guest.TracePlatform;
import ghidra.trace.model.memory.TraceMemoryManager;
import ghidra.trace.model.memory.TraceMemorySpace;
import ghidra.trace.model.stack.TraceObjectStack;
import ghidra.trace.model.stack.TraceObjectStackFrame;
import ghidra.trace.model.stack.TraceStack;
import ghidra.trace.model.stack.TraceStackFrame;
import ghidra.trace.model.target.path.KeyPath;
import ghidra.trace.model.target.path.PathFilter;
import ghidra.trace.model.target.schema.SchemaContext;
import ghidra.trace.model.target.schema.TraceObjectSchema;
import ghidra.trace.model.thread.TraceThread;
import ghidra.trace.model.time.TraceSnapshot;
@ -249,6 +251,13 @@ public class DebuggerEmulationServiceTest extends AbstractGhidraHeadedDebuggerTe
mem.getViewValue(scratch, regW1).getUnsignedValue());
}
protected SchemaContext buildContext() {
return new ToySchemaBuilder()
.noRegisterGroups()
.useRegistersPerFrame()
.build();
}
@Test
public void testPureEmulationRelocated() throws Throwable {
createAndOpenTrace("x86:LE:64:default");
@ -282,7 +291,9 @@ public class DebuggerEmulationServiceTest extends AbstractGhidraHeadedDebuggerTe
TraceThread thread;
TraceMemorySpace regs;
try (Transaction tx = tb.startTransaction()) {
tb.createRootObject(buildContext(), "Target");
thread = tb.getOrAddThread("Threads[0]", 0);
tb.createObjectsFramesAndRegs(thread, Lifespan.nowOn(0), tb.host, 1);
regs = tb.trace.getMemoryManager().getMemoryRegisterSpace(thread, true);
regs.setValue(0, new RegisterValue(program.getLanguage().getProgramCounter(),
BigInteger.valueOf(0x55550000)));
@ -295,8 +306,8 @@ public class DebuggerEmulationServiceTest extends AbstractGhidraHeadedDebuggerTe
waitForSwing();
waitOn(settled);
long scratch =
emulationPlugin.emulate(tb.trace, TraceSchedule.parse("0:t0-1"), TaskMonitor.DUMMY);
long scratch = emulationPlugin.emulate(tb.trace,
TraceSchedule.parse("0:t%d-1".formatted(thread.getKey())), TaskMonitor.DUMMY);
assertEquals("deadbeefcafebabe",
regs.getViewValue(scratch, tb.reg("RAX")).getUnsignedValue().toString(16));
@ -315,7 +326,9 @@ public class DebuggerEmulationServiceTest extends AbstractGhidraHeadedDebuggerTe
TraceMemoryManager mem = tb.trace.getMemoryManager();
TraceThread thread;
try (Transaction tx = tb.startTransaction()) {
tb.createRootObject(buildContext(), "Target");
thread = tb.getOrAddThread("Threads[0]", 0);
tb.createObjectsFramesAndRegs(thread, Lifespan.nowOn(0), tb.host, 1);
buf.assemble("MOV RAX, qword ptr [0x00600800]");
mem.putBytes(0, tb.addr(0x00400000), ByteBuffer.wrap(buf.getBytes()));
mem.putBytes(0, tb.addr(0x00600800),
@ -344,8 +357,8 @@ public class DebuggerEmulationServiceTest extends AbstractGhidraHeadedDebuggerTe
tb.exec(platform, 0, thread, 0, "RIP = 0x00400000;");
}
long scratch =
emulationPlugin.emulate(platform, TraceSchedule.parse("0:t0-1"), TaskMonitor.DUMMY);
long scratch = emulationPlugin.emulate(platform,
TraceSchedule.parse("0:t%d-1".formatted(thread.getKey())), TaskMonitor.DUMMY);
TraceMemorySpace regs = mem.getMemoryRegisterSpace(thread, false);
assertEquals("deadbeefcafebabe",
regs.getViewValue(platform, scratch, tb.reg(platform, "RAX"))
@ -494,7 +507,7 @@ public class DebuggerEmulationServiceTest extends AbstractGhidraHeadedDebuggerTe
trace.getBreakpointManager()
.addBreakpoint("Breakpoints[0]", Lifespan.nowOn(0), addrText, Set.of(thread),
Set.of(TraceBreakpointKind.SW_EXECUTE), true, "test");
TraceBreakpoint tb = trace.getBreakpointManager()
TraceBreakpointLocation tb = trace.getBreakpointManager()
.addBreakpoint("Breakpoints[1]", Lifespan.nowOn(0), addrI1, Set.of(thread),
Set.of(TraceBreakpointKind.SW_EXECUTE), true, "test");
// Force "partial instruction"
@ -568,7 +581,7 @@ public class DebuggerEmulationServiceTest extends AbstractGhidraHeadedDebuggerTe
trace.getBreakpointManager()
.addBreakpoint("Breakpoints[0]", Lifespan.nowOn(0), addrText, Set.of(thread),
Set.of(TraceBreakpointKind.SW_EXECUTE), true, "test");
TraceBreakpoint tb = trace.getBreakpointManager()
TraceBreakpointLocation tb = trace.getBreakpointManager()
.addBreakpoint("Breakpoints[1]", Lifespan.nowOn(0), addrI1, Set.of(thread),
Set.of(TraceBreakpointKind.SW_EXECUTE), true, "test");
// Force "partial instruction"
@ -634,7 +647,7 @@ public class DebuggerEmulationServiceTest extends AbstractGhidraHeadedDebuggerTe
TraceThread thread = Unique.assertOne(trace.getThreadManager().getAllThreads());
try (Transaction tx = trace.openTransaction("Add breakpoint")) {
TraceBreakpoint tb = trace.getBreakpointManager()
TraceBreakpointLocation tb = trace.getBreakpointManager()
.addBreakpoint("Breakpoints[1]", Lifespan.nowOn(0), addrI1, Set.of(thread),
Set.of(TraceBreakpointKind.SW_EXECUTE), true, "test");
// Force "partial instruction"
@ -709,7 +722,7 @@ public class DebuggerEmulationServiceTest extends AbstractGhidraHeadedDebuggerTe
TraceMemorySpace regs = trace.getMemoryManager().getMemoryRegisterSpace(thread, false);
try (Transaction tx = trace.openTransaction("Add breakpoint")) {
TraceBreakpoint tb = trace.getBreakpointManager()
TraceBreakpointLocation tb = trace.getBreakpointManager()
.addBreakpoint("Breakpoints[0]", Lifespan.nowOn(0), addrI2, Set.of(thread),
Set.of(TraceBreakpointKind.SW_EXECUTE), true, "test");
tb.setEmuSleigh(0, """
@ -854,7 +867,7 @@ public class DebuggerEmulationServiceTest extends AbstractGhidraHeadedDebuggerTe
// Inject some logic that would require a cache refresh to materialize
try (Transaction tx = trace.openTransaction("Add breakpoint")) {
TraceBreakpoint tb = trace.getBreakpointManager()
TraceBreakpointLocation tb = trace.getBreakpointManager()
.addBreakpoint("Breakpoints[0]", Lifespan.nowOn(0), addrI2, Set.of(thread),
Set.of(TraceBreakpointKind.SW_EXECUTE), true, "test");
tb.setEmuSleigh(0, """
@ -986,10 +999,10 @@ public class DebuggerEmulationServiceTest extends AbstractGhidraHeadedDebuggerTe
public void testEmuSchemaHasWorkingStackFrames() throws Exception {
TraceObjectSchema rootSchema = ProgramEmulationUtils.EMU_SESSION_SCHEMA;
TraceObjectSchema threadSchema = rootSchema.getSuccessorSchema(KeyPath.parse("Threads[1]"));
KeyPath found = threadSchema.searchForCanonicalContainer(TraceObjectStackFrame.class);
KeyPath found = threadSchema.searchForCanonicalContainer(TraceStackFrame.class);
assertEquals(KeyPath.parse("Stack"), found);
PathFilter stackFilter = threadSchema.searchFor(TraceObjectStack.class, false);
PathFilter stackFilter = threadSchema.searchFor(TraceStack.class, false);
assertNotNull("Non-unique Stack", stackFilter.getSingletonPath());
}
}

View file

@ -635,13 +635,14 @@ public class DebuggerStaticMappingServiceTest extends AbstractGhidraHeadedDebugg
TraceMemoryRegion echoText, echoData, libText, libData;
DBTraceMemoryManager mm = tb.trace.getMemoryManager();
try (Transaction tx = tb.startTransaction()) {
echoText = mm.createRegion("Memory.Regions[/bin/echo (0x00400000)]",
tb.createRootObject("Target");
echoText = mm.createRegion("Memory[/bin/echo (0x00400000)]",
0, tb.range(0x00400000, 0x0040ffff), TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
echoData = mm.createRegion("Memory.Regions[/bin/echo (0x00600000)]",
echoData = mm.createRegion("Memory[/bin/echo (0x00600000)]",
0, tb.range(0x00600000, 0x00600fff), TraceMemoryFlag.READ, TraceMemoryFlag.WRITE);
libText = mm.createRegion("Memory.Regions[/lib/libc.so (0x7ff00000)]",
libText = mm.createRegion("Memory[/lib/libc.so (0x7ff00000)]",
0, tb.range(0x7ff00000, 0x7ff0ffff), TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
libData = mm.createRegion("Memory.Regions[/lib/libc.so (0x7ff20000)]",
libData = mm.createRegion("Memory[/lib/libc.so (0x7ff20000)]",
0, tb.range(0x7ff20000, 0x7ff20fff), TraceMemoryFlag.READ, TraceMemoryFlag.WRITE);
}
@ -688,7 +689,7 @@ public class DebuggerStaticMappingServiceTest extends AbstractGhidraHeadedDebugg
objModBash.insert(Lifespan.nowOn(0), ConflictResolution.DENY);
}
TraceModule modBash = objModBash.queryInterface(TraceObjectModule.class);
TraceModule modBash = objModBash.queryInterface(TraceModule.class);
assertEquals(Map.of(),
mappingService.proposeModuleMaps(List.of(modBash), 0, List.of(program)));
}

View file

@ -80,8 +80,8 @@ import ghidra.program.model.symbol.SourceType;
import ghidra.program.util.*;
import ghidra.trace.model.Lifespan;
import ghidra.trace.model.TraceLocation;
import ghidra.trace.model.breakpoint.TraceBreakpoint;
import ghidra.trace.model.breakpoint.TraceBreakpointKind;
import ghidra.trace.model.breakpoint.TraceBreakpointLocation;
import ghidra.trace.model.listing.TraceData;
import ghidra.trace.model.memory.TraceMemorySpace;
import ghidra.trace.model.thread.TraceThread;
@ -888,7 +888,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest {
waitOn(frameAtSetup.setReturnAddress(editor, tb.addr(0xdeadbeef)));
waitForTasks();
TraceBreakpoint bptUnwind;
TraceBreakpointLocation bptUnwind;
try (Transaction tx = tb.startTransaction()) {
bptUnwind = tb.trace.getBreakpointManager()
.addBreakpoint("Breakpoints[0]", Lifespan.nowOn(0), retInstr, Set.of(),
@ -976,7 +976,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest {
Register sp = program.getCompilerSpec().getStackPointer();
long spAtSetup = regs.getValue(0, sp).getUnsignedValue().longValueExact();
TraceBreakpoint bptUnwind;
TraceBreakpointLocation bptUnwind;
try (Transaction tx = tb.startTransaction()) {
bptUnwind = tb.trace.getBreakpointManager()
.addBreakpoint("Breakpoints[0]", Lifespan.nowOn(0), entry, Set.of(),

View file

@ -300,11 +300,11 @@ public class DBTrace extends DBCachedDomainObjectAdapter implements Trace, Trace
}
@DependentService
protected DBTraceBreakpointManager createBreakpointManager(DBTraceThreadManager threadManager)
protected DBTraceBreakpointManager createBreakpointManager(DBTraceObjectManager objectManager)
throws CancelledException, IOException {
return createTraceManager("Breakpoint Manager",
(openMode, monitor) -> new DBTraceBreakpointManager(dbh, openMode, rwLock, monitor,
baseLanguage, this, threadManager));
this, objectManager));
}
@DependentService
@ -367,10 +367,11 @@ public class DBTrace extends DBCachedDomainObjectAdapter implements Trace, Trace
}
@DependentService
protected DBTraceModuleManager createModuleManager() throws CancelledException, IOException {
protected DBTraceModuleManager createModuleManager(DBTraceObjectManager objectManager)
throws CancelledException, IOException {
return createTraceManager("Module Manager",
(openMode, monitor) -> new DBTraceModuleManager(dbh, openMode, rwLock, monitor,
baseLanguage, this));
(openMode, monitor) -> new DBTraceModuleManager(dbh, openMode, rwLock, monitor, this,
objectManager));
}
@DependentService
@ -670,16 +671,16 @@ public class DBTrace extends DBCachedDomainObjectAdapter implements Trace, Trace
if (recordChanges) {
traceChangeSet.sourceArchiveAdded(sourceArchiveID.getValue());
}
setChanged(
new TraceChangeRecord<>(TraceEvents.SOURCE_TYPE_ARCHIVE_ADDED, null, sourceArchiveID));
setChanged(new TraceChangeRecord<>(TraceEvents.SOURCE_TYPE_ARCHIVE_ADDED, null,
sourceArchiveID));
}
public void dataTypeChanged(long changedID, DataType changedType) {
if (recordChanges) {
traceChangeSet.dataTypeChanged(changedID);
}
setChanged(
new TraceChangeRecord<>(TraceEvents.DATA_TYPE_CHANGED, null, changedID, changedType));
setChanged(new TraceChangeRecord<>(TraceEvents.DATA_TYPE_CHANGED, null, changedID,
changedType));
}
public void dataTypeAdded(long addedID, DataType addedType) {
@ -701,16 +702,16 @@ public class DBTrace extends DBCachedDomainObjectAdapter implements Trace, Trace
if (recordChanges) {
traceChangeSet.dataTypeChanged(movedID);
}
setChanged(
new TraceChangeRecord<>(TraceEvents.DATA_TYPE_MOVED, null, movedID, oldPath, newPath));
setChanged(new TraceChangeRecord<>(TraceEvents.DATA_TYPE_MOVED, null, movedID,
oldPath, newPath));
}
public void dataTypeNameChanged(long renamedID, String oldName, String newName) {
if (recordChanges) {
traceChangeSet.dataTypeChanged(renamedID);
}
setChanged(new TraceChangeRecord<>(TraceEvents.DATA_TYPE_RENAMED, null, renamedID, oldName,
newName));
setChanged(new TraceChangeRecord<>(TraceEvents.DATA_TYPE_RENAMED, null, renamedID,
oldName, newName));
}
public void dataTypeDeleted(long deletedID, DataTypePath deletedPath) {
@ -725,16 +726,16 @@ public class DBTrace extends DBCachedDomainObjectAdapter implements Trace, Trace
if (recordChanges) {
traceChangeSet.categoryAdded(addedID);
}
setChanged(
new TraceChangeRecord<>(TraceEvents.TYPE_CATEGORY_ADDED, null, addedID, addedCategory));
setChanged(new TraceChangeRecord<>(TraceEvents.TYPE_CATEGORY_ADDED, null, addedID,
addedCategory));
}
public void categoryMoved(long movedID, CategoryPath oldPath, CategoryPath newPath) {
if (recordChanges) {
traceChangeSet.categoryChanged(movedID);
}
setChanged(new TraceChangeRecord<>(TraceEvents.TYPE_CATEGORY_MOVED, null, movedID, oldPath,
newPath));
setChanged(new TraceChangeRecord<>(TraceEvents.TYPE_CATEGORY_MOVED, null, movedID,
oldPath, newPath));
}
public void categoryRenamed(long renamedID, String oldName, String newName) {

View file

@ -433,18 +433,9 @@ public enum DBTraceUtils {
*
* @param baseName the base name of the table group
* @param space the address space
* @param threadKey the thread key, -1 usually indicating "no thread"
* @param frameLevel the frame level
* @return the table name
*/
public static String tableName(String baseName, AddressSpace space, long threadKey,
int frameLevel) {
if (space.isRegisterSpace()) {
if (frameLevel == 0) {
return baseName + "_" + space.getName() + "_" + threadKey;
}
return baseName + "_" + space.getName() + "_" + threadKey + "_" + frameLevel;
}
public static String tableName(String baseName, AddressSpace space) {
return baseName + "_" + space.getName();
}

View file

@ -222,7 +222,7 @@ public class DBTraceOverlaySpaceAdapter implements DBTraceManager {
keyToRecordMap.remove(key);
}
// Add any remaing overlay which are missing from factory
// Add any remaining overlays which are missing from factory
for (long key : keyToRecordMap.keySet()) {
DBTraceOverlaySpaceEntry ent = keyToRecordMap.get(key);
String spaceName = ent.name;
@ -268,7 +268,7 @@ public class DBTraceOverlaySpaceAdapter implements DBTraceManager {
ent.set(space.getName(), base.getName());
trace.updateViewsAddSpaceBlock(space);
trace.setChanged(
new TraceChangeRecord<>(TraceEvents.OVERLAY_ADDED, null, trace, null, space));
new TraceChangeRecord<>(TraceEvents.OVERLAY_ADDED, space, trace, null, space));
return space;
}
@ -315,7 +315,7 @@ public class DBTraceOverlaySpaceAdapter implements DBTraceManager {
factory.removeOverlaySpace(name);
trace.updateViewsDeleteSpaceBlock(space);
trace.setChanged(
new TraceChangeRecord<>(TraceEvents.OVERLAY_DELETED, null, trace, space, null));
new TraceChangeRecord<>(TraceEvents.OVERLAY_DELETED, space, trace, space, null));
invalidateCache(true);
}
}

View file

@ -50,8 +50,8 @@ public class DBTraceBookmark extends AbstractDBTraceAddressSnapRangePropertyMapD
@DBAnnotatedColumn(COMMENT_COLUMN_NAME)
static DBObjectColumn COMMENT_COLUMN;
static String tableName(AddressSpace space, long threadKey, int frameLevel) {
return DBTraceUtils.tableName(TABLE_NAME, space, threadKey, frameLevel);
static String tableName(AddressSpace space) {
return DBTraceUtils.tableName(TABLE_NAME, space);
}
@DBAnnotatedField(column = TYPE_COLUMN_NAME, indexed = true)
@ -104,7 +104,7 @@ public class DBTraceBookmark extends AbstractDBTraceAddressSnapRangePropertyMapD
@Override
public long getId() {
return DBTraceBookmarkManager.packId(key, space);
return DBTraceBookmarkManager.packId(key, range.getAddressSpace());
}
@Override
@ -140,14 +140,14 @@ public class DBTraceBookmark extends AbstractDBTraceAddressSnapRangePropertyMapD
update(CATEGORY_COLUMN, COMMENT_COLUMN);
}
space.trace.setChanged(
new TraceChangeRecord<>(TraceEvents.BOOKMARK_CHANGED, space, this));
new TraceChangeRecord<>(TraceEvents.BOOKMARK_CHANGED, space.space, this));
}
@Override
public void delete() {
space.bookmarkMapSpace.deleteData(this);
space.trace.setChanged(
new TraceChangeRecord<>(TraceEvents.BOOKMARK_DELETED, space, this));
new TraceChangeRecord<>(TraceEvents.BOOKMARK_DELETED, space.space, this));
}
@Override

View file

@ -29,7 +29,8 @@ import ghidra.program.model.address.*;
import ghidra.program.model.lang.Language;
import ghidra.trace.database.DBTrace;
import ghidra.trace.database.map.DBTraceAddressSnapRangePropertyMapTree.TraceAddressSnapRangeQuery;
import ghidra.trace.database.space.*;
import ghidra.trace.database.space.AbstractDBTraceSpaceBasedManager;
import ghidra.trace.database.space.DBTraceDelegatingManager;
import ghidra.trace.database.thread.DBTraceThreadManager;
import ghidra.trace.model.Lifespan;
import ghidra.trace.model.bookmark.TraceBookmarkManager;
@ -55,14 +56,6 @@ public class DBTraceBookmarkManager extends AbstractDBTraceSpaceBasedManager<DBT
* | SpaceID | Key |
* +---------+----------+
* }
*
* For register space:
*
* {@code
* +---12----+----32----+----8----+--12--+
* | SpaceID | Thread | Frame | Key |
* +---------+----------+---------+------+
* }
*/
// NOTE: There are few address spaces, but their IDs encode other stuff :/
protected static final int SPACE_ID_MASK = 0x0FFF;
@ -71,23 +64,8 @@ public class DBTraceBookmarkManager extends AbstractDBTraceSpaceBasedManager<DBT
protected static final long MEM_KEY_MASK = 0x000F_FFFF_FFFF_FFFFL;
protected static final int MEM_KEY_SHIFT = 0;
protected static final long REG_THREAD_MASK = 0x0_FFFF_FFFFL;
protected static final int REG_THREAD_SHIFT = 20;
protected static final long REG_FRAME_MASK = 0x00FF;
protected static final int REG_FRAME_SHIFT = 12;
protected static final long REG_KEY_MASK = 0x0FFF;
protected static final int REG_KEY_SHIFT = 0;
protected static long packId(long key, DBTraceSpaceKey spaceKey) {
return spaceKey.getAddressSpace().isRegisterSpace() ? packRegId(key, spaceKey)
: packMemId(key, spaceKey);
}
protected static long packMemId(long key, DBTraceSpaceKey spaceKey) {
long spaceId = spaceKey.getAddressSpace().getSpaceID();
assert spaceKey.getThread() == null;
protected static long packId(long key, AddressSpace space) {
long spaceId = space.getSpaceID();
if ((spaceId & SPACE_ID_MASK) != spaceId) {
throw new AssertionError("Bad assumption");
@ -98,69 +76,17 @@ public class DBTraceBookmarkManager extends AbstractDBTraceSpaceBasedManager<DBT
return (spaceId << SPACE_ID_SHIFT) | (key << MEM_KEY_SHIFT);
}
protected static long packRegId(long key, DBTraceSpaceKey spaceKey) {
long spaceId = spaceKey.getAddressSpace().getSpaceID();
long threadKey = spaceKey.getThread().getKey();
int frameLevel = spaceKey.getFrameLevel();
if ((spaceId & SPACE_ID_MASK) != spaceId) {
throw new AssertionError("Bad assumption");
}
if ((threadKey & REG_THREAD_MASK) != threadKey) {
throw new AssertionError("Bad assumption");
}
if ((frameLevel & REG_FRAME_MASK) != frameLevel) {
throw new AssertionError("Bad assumption");
}
if ((key & REG_KEY_MASK) != key) {
throw new AssertionError("Bad assumption");
}
return (spaceId << SPACE_ID_SHIFT) | (threadKey << REG_THREAD_SHIFT) |
(frameLevel << REG_FRAME_SHIFT) | (key << REG_KEY_SHIFT);
}
protected static int unpackSpaceId(long id) {
return (int) ((id >> SPACE_ID_SHIFT) & SPACE_ID_MASK);
}
protected static long unpackMemKey(long id) {
protected static long unpackKey(long id) {
return (id >> MEM_KEY_SHIFT) & MEM_KEY_MASK;
}
protected static long unpackRegThread(long id) {
return (id >> REG_THREAD_SHIFT) & REG_THREAD_MASK;
}
protected static int unpackRegFrame(long id) {
return (int) ((id >> REG_FRAME_SHIFT) & REG_FRAME_MASK);
}
protected static long unpackRegKey(long id) {
return (id >> REG_KEY_SHIFT) & REG_KEY_MASK;
}
protected static DBTraceSpaceKey unpackSpaceKey(long id, Language baseLanguage,
DBTraceThreadManager threadManager) {
protected static AddressSpace unpackSpace(long id, AddressFactory addressFactory) {
int spaceId = unpackSpaceId(id);
AddressSpace space = baseLanguage.getAddressFactory().getAddressSpace(spaceId);
if (space == null) {
return null;
}
return space.isRegisterSpace() ? unpackRegSpaceKey(space, threadManager, id)
: unpackMemSpaceKey(space, id);
}
protected static DBTraceSpaceKey unpackMemSpaceKey(AddressSpace space, long id) {
return DBTraceSpaceKey.create(space, null, 0);
}
protected static DBTraceSpaceKey unpackRegSpaceKey(AddressSpace space,
DBTraceThreadManager threadManager, long id) {
long threadKey = unpackRegThread(id);
TraceThread thread = threadManager.getThread(threadKey);
assert thread != null;
int frameLevel = unpackRegFrame(id);
return DBTraceSpaceKey.create(space, thread, frameLevel);
return addressFactory.getAddressSpace(spaceId);
}
protected final Map<String, DBTraceBookmarkType> typesByName = new HashMap<>();
@ -178,13 +104,7 @@ public class DBTraceBookmarkManager extends AbstractDBTraceSpaceBasedManager<DBT
@Override
protected DBTraceBookmarkSpace createSpace(AddressSpace space, DBTraceSpaceEntry ent)
throws VersionException, IOException {
return new DBTraceBookmarkSpace(this, space, null, 0);
}
@Override
protected DBTraceBookmarkSpace createRegisterSpace(AddressSpace space, TraceThread thread,
DBTraceSpaceEntry ent) throws VersionException, IOException {
return new DBTraceBookmarkSpace(this, space, thread, ent.getFrameLevel());
return new DBTraceBookmarkSpace(this, space);
}
@Override
@ -267,16 +187,15 @@ public class DBTraceBookmarkManager extends AbstractDBTraceSpaceBasedManager<DBT
@Override
public DBTraceBookmark getBookmark(long id) {
try (LockHold hold = LockHold.lock(lock.readLock())) {
DBTraceSpaceKey spaceKey = unpackSpaceKey(id, baseLanguage, threadManager);
if (spaceKey == null) {
AddressSpace addressSpace = unpackSpace(id, trace.getInternalAddressFactory());
if (addressSpace == null) {
return null;
}
DBTraceBookmarkSpace space = get(spaceKey, false);
DBTraceBookmarkSpace space = get(addressSpace, false);
if (space == null) {
return null;
}
long bookmarkKey =
spaceKey.getAddressSpace().isRegisterSpace() ? unpackRegKey(id) : unpackMemKey(id);
long bookmarkKey = unpackKey(id);
return space.bookmarkMapSpace.getDataByKey(bookmarkKey);
}
}
@ -288,7 +207,7 @@ public class DBTraceBookmarkManager extends AbstractDBTraceSpaceBasedManager<DBT
@Override
public Set<String> getCategoriesForType(TraceBookmarkType type) {
return delegateHashSet(getActiveMemorySpaces(), m -> m.getCategoriesForType(type));
return delegateHashSet(getActiveSpaces(), m -> m.getCategoriesForType(type));
}
@Override
@ -300,7 +219,7 @@ public class DBTraceBookmarkManager extends AbstractDBTraceSpaceBasedManager<DBT
@Override
public Collection<? extends DBTraceBookmark> getAllBookmarks() {
return delegateCollection(getActiveMemorySpaces(), m -> m.getAllBookmarks());
return delegateCollection(getActiveSpaces(), m -> m.getAllBookmarks());
}
@Override
@ -329,7 +248,7 @@ public class DBTraceBookmarkManager extends AbstractDBTraceSpaceBasedManager<DBT
return Collections.emptySet();
}
Collection<DBTraceBookmark> result = new ArrayList<>();
for (DBTraceBookmarkSpace space : memSpaces.values()) {
for (DBTraceBookmarkSpace space : spaces.values()) {
result.addAll(space.bookmarkMapSpace
.reduce(TraceAddressSnapRangeQuery.added(from, to, space.getAddressSpace()))
.values());
@ -343,7 +262,7 @@ public class DBTraceBookmarkManager extends AbstractDBTraceSpaceBasedManager<DBT
return Collections.emptySet();
}
Collection<DBTraceBookmark> result = new ArrayList<>();
for (DBTraceBookmarkSpace space : memSpaces.values()) {
for (DBTraceBookmarkSpace space : spaces.values()) {
result.addAll(space.bookmarkMapSpace
.reduce(TraceAddressSnapRangeQuery.removed(from, to, space.getAddressSpace()))
.values());

View file

@ -25,9 +25,9 @@ import ghidra.trace.database.map.DBTraceAddressSnapRangePropertyMapSpace;
import ghidra.trace.database.map.DBTraceAddressSnapRangePropertyMapTree.TraceAddressSnapRangeQuery;
import ghidra.trace.database.space.DBTraceSpaceBased;
import ghidra.trace.model.Lifespan;
import ghidra.trace.model.Trace;
import ghidra.trace.model.bookmark.TraceBookmarkSpace;
import ghidra.trace.model.bookmark.TraceBookmarkType;
import ghidra.trace.model.thread.TraceThread;
import ghidra.trace.util.TraceChangeRecord;
import ghidra.trace.util.TraceEvents;
import ghidra.util.LockHold;
@ -39,47 +39,37 @@ public class DBTraceBookmarkSpace implements TraceBookmarkSpace, DBTraceSpaceBas
protected final ReadWriteLock lock;
protected final DBTrace trace;
protected final AddressSpace space;
protected final TraceThread thread;
protected final int frameLevel;
protected final DBTraceAddressSnapRangePropertyMapSpace<DBTraceBookmark, DBTraceBookmark> bookmarkMapSpace;
protected final DBCachedObjectIndex<String, DBTraceBookmark> bookmarksByTypeName;
protected final Collection<DBTraceBookmark> bookmarkView;
public DBTraceBookmarkSpace(DBTraceBookmarkManager manager, AddressSpace space,
TraceThread thread, int frameLevel)
public DBTraceBookmarkSpace(DBTraceBookmarkManager manager, AddressSpace space)
throws VersionException, IOException {
this.manager = manager;
this.lock = manager.getLock();
this.trace = manager.getTrace();
this.space = space;
this.thread = thread;
this.frameLevel = frameLevel;
this.bookmarkMapSpace =
new DBTraceAddressSnapRangePropertyMapSpace<>(DBTraceBookmark.tableName(space, -1, 0),
trace.getStoreFactory(), lock, space, null, 0, DBTraceBookmark.class,
new DBTraceAddressSnapRangePropertyMapSpace<>(DBTraceBookmark.tableName(space), trace,
trace.getStoreFactory(), lock, space, DBTraceBookmark.class,
(t, s, r) -> new DBTraceBookmark(this, t, s, r));
this.bookmarksByTypeName =
bookmarkMapSpace.getUserIndex(String.class, DBTraceBookmark.TYPE_COLUMN);
this.bookmarkView = Collections.unmodifiableCollection(bookmarkMapSpace.values());
}
@Override
public Trace getTrace() {
return trace;
}
@Override
public AddressSpace getAddressSpace() {
return space;
}
@Override
public TraceThread getThread() {
return thread;
}
@Override
public int getFrameLevel() {
return frameLevel;
}
protected DBTraceBookmarkType assertInTrace(TraceBookmarkType type) {
if (!(type instanceof DBTraceBookmarkType)) {
throw new IllegalArgumentException("Given type is not part of this trace");
@ -110,7 +100,7 @@ public class DBTraceBookmarkSpace implements TraceBookmarkSpace, DBTraceSpaceBas
try (LockHold hold = LockHold.lock(lock.writeLock())) {
DBTraceBookmark bookmark = bookmarkMapSpace.put(address, lifespan, null);
bookmark.set(type.getTypeString(), category, comment);
trace.setChanged(new TraceChangeRecord<>(TraceEvents.BOOKMARK_ADDED, this, bookmark));
trace.setChanged(new TraceChangeRecord<>(TraceEvents.BOOKMARK_ADDED, space, bookmark));
return bookmark;
}
}

View file

@ -1,460 +0,0 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.trace.database.breakpoint;
import java.io.IOException;
import java.util.*;
import db.DBRecord;
import ghidra.pcode.exec.SleighUtils;
import ghidra.program.model.address.*;
import ghidra.trace.database.DBTrace;
import ghidra.trace.database.DBTraceUtils;
import ghidra.trace.database.map.DBTraceAddressSnapRangePropertyMapTree;
import ghidra.trace.database.map.DBTraceAddressSnapRangePropertyMapTree.AbstractDBTraceAddressSnapRangePropertyMapData;
import ghidra.trace.database.thread.DBTraceThreadManager;
import ghidra.trace.model.Lifespan;
import ghidra.trace.model.breakpoint.TraceBreakpoint;
import ghidra.trace.model.breakpoint.TraceBreakpointKind;
import ghidra.trace.model.thread.TraceThread;
import ghidra.trace.util.TraceChangeRecord;
import ghidra.trace.util.TraceEvents;
import ghidra.util.LockHold;
import ghidra.util.Msg;
import ghidra.util.database.DBCachedObjectStore;
import ghidra.util.database.DBObjectColumn;
import ghidra.util.database.annot.*;
import ghidra.util.exception.DuplicateNameException;
@DBAnnotatedObjectInfo(version = 1)
public class DBTraceBreakpoint
extends AbstractDBTraceAddressSnapRangePropertyMapData<DBTraceBreakpoint>
implements TraceBreakpoint {
protected static final String TABLE_NAME = "Breakpoints";
private static final byte ENABLED_MASK = (byte) (1 << 7);
private static final byte EMU_ENABLED_MASK = (byte) (1 << 6);
static final String PATH_COLUMN_NAME = "Path";
static final String NAME_COLUMN_NAME = "Name";
static final String THREADS_COLUMN_NAME = "Threads";
static final String FLAGS_COLUMN_NAME = "Flags";
static final String COMMENT_COLUMN_NAME = "Comment";
static final String SLEIGH_COLUMN_NAME = "Sleigh";
@DBAnnotatedColumn(PATH_COLUMN_NAME)
static DBObjectColumn PATH_COLUMN;
@DBAnnotatedColumn(NAME_COLUMN_NAME)
static DBObjectColumn NAME_COLUMN;
@DBAnnotatedColumn(THREADS_COLUMN_NAME)
static DBObjectColumn THREADS_COLUMN;
@DBAnnotatedColumn(FLAGS_COLUMN_NAME)
static DBObjectColumn FLAGS_COLUMN;
@DBAnnotatedColumn(COMMENT_COLUMN_NAME)
static DBObjectColumn COMMENT_COLUMN;
@DBAnnotatedColumn(SLEIGH_COLUMN_NAME)
static DBObjectColumn SLEIGH_COLUMN;
protected static String tableName(AddressSpace space, long threadKey) {
return DBTraceUtils.tableName(TABLE_NAME, space, threadKey, 0);
}
@DBAnnotatedField(column = PATH_COLUMN_NAME, indexed = true)
private String path;
@DBAnnotatedField(column = NAME_COLUMN_NAME)
private String name;
@DBAnnotatedField(column = THREADS_COLUMN_NAME)
private long[] threadKeys;
@DBAnnotatedField(column = FLAGS_COLUMN_NAME)
private byte flagsByte;
@DBAnnotatedField(column = COMMENT_COLUMN_NAME)
private String comment;
@DBAnnotatedField(column = SLEIGH_COLUMN_NAME)
private String emuSleigh;
private final Set<TraceBreakpointKind> kinds = EnumSet.noneOf(TraceBreakpointKind.class);
private final Set<TraceBreakpointKind> kindsView = Collections.unmodifiableSet(kinds);
private boolean enabled;
private boolean emuEnabled;
protected final DBTraceBreakpointSpace space;
public DBTraceBreakpoint(DBTraceBreakpointSpace space,
DBTraceAddressSnapRangePropertyMapTree<DBTraceBreakpoint, ?> tree,
DBCachedObjectStore<?> store, DBRecord record) {
super(tree, store, record);
this.space = space;
}
@Override
protected void fresh(boolean created) throws IOException {
super.fresh(created);
if (created) {
return;
}
doFresh();
}
private void doFresh() {
kinds.clear();
for (TraceBreakpointKind k : TraceBreakpointKind.values()) {
if ((flagsByte & k.getBits()) != 0) {
kinds.add(k);
}
}
enabled = (flagsByte & ENABLED_MASK) != 0;
emuEnabled = (flagsByte & EMU_ENABLED_MASK) != 0;
}
@Override
public DBTrace getTrace() {
return space.trace;
}
@Override
protected void setRecordValue(DBTraceBreakpoint value) {
// Nothing: record is the value
}
@Override
protected DBTraceBreakpoint getRecordValue() {
return this;
}
public void set(String path, String name, Collection<TraceThread> threads,
Collection<TraceBreakpointKind> kinds, boolean enabled, boolean emuEnabled,
String comment) {
// TODO: Check that the threads exist and that each's lifespan covers the breakpoint's
// TODO: This would require additional validation any time those are updated
// TODO: For efficiency, would also require index of breakpoints by thread
this.path = path;
this.name = name;
if (!(threads instanceof Set<?>)) {
threads = Set.copyOf(threads);
}
this.threadKeys = new long[threads.size()];
int i = 0;
for (TraceThread t : threads) {
this.threadKeys[i++] = t.getKey();
}
this.flagsByte = 0;
this.kinds.clear();
for (TraceBreakpointKind k : kinds) {
this.flagsByte |= k.getBits();
this.kinds.add(k);
}
if (enabled) {
this.flagsByte |= ENABLED_MASK;
}
if (emuEnabled) {
this.flagsByte |= EMU_ENABLED_MASK;
}
this.comment = comment;
update(PATH_COLUMN, NAME_COLUMN, THREADS_COLUMN, FLAGS_COLUMN, COMMENT_COLUMN);
this.enabled = enabled;
this.emuEnabled = emuEnabled;
// Msg.debug(this, "trace: breakpoint " + this + " enabled=" + enabled + ", because set");
}
public void set(String path, String name, long[] threadKeys,
byte flagsByte, String comment) {
this.path = path;
this.name = name;
this.threadKeys = Arrays.copyOf(threadKeys, threadKeys.length);
this.flagsByte = flagsByte;
this.comment = comment;
update(PATH_COLUMN, NAME_COLUMN, THREADS_COLUMN, FLAGS_COLUMN, COMMENT_COLUMN);
doFresh();
}
@Override
public String getPath() {
try (LockHold hold = LockHold.lock(space.lock.readLock())) {
return path;
}
}
@Override
public void setName(long snap, String name) {
try (LockHold hold = LockHold.lock(space.lock.writeLock())) {
this.name = name;
update(NAME_COLUMN);
}
space.trace
.setChanged(new TraceChangeRecord<>(TraceEvents.BREAKPOINT_CHANGED, space, this));
}
@Override
public String getName(long snap) {
try (LockHold hold = LockHold.lock(space.lock.readLock())) {
return name;
}
}
@Override
public Set<TraceThread> getThreads(long snap) {
try (LockHold hold = LockHold.lock(space.lock.readLock())) {
if (threadKeys.length == 0) {
return Set.of();
}
// NOTE: Caching this result could get hairy if any threads are invalidated....
Set<TraceThread> threads = new LinkedHashSet<>(threadKeys.length);
DBTraceThreadManager threadManager = space.trace.getThreadManager();
for (int i = 0; i < threadKeys.length; i++) {
TraceThread t = threadManager.getThread(threadKeys[i]);
if (t == null) {
Msg.warn(this, "Thread " + threadKeys[i] +
" has been deleted since creating this breakpoint.");
}
threads.add(t);
}
return Collections.unmodifiableSet(threads);
}
}
@Override
public AddressRange getRange(long snap) {
try (LockHold hold = LockHold.lock(space.lock.readLock())) {
return range;
}
}
@Override
public Address getMinAddress(long snap) {
try (LockHold hold = LockHold.lock(space.lock.readLock())) {
return range.getMinAddress();
}
}
@Override
public Address getMaxAddress(long snap) {
try (LockHold hold = LockHold.lock(space.lock.readLock())) {
return range.getMaxAddress();
}
}
@Override
public long getLength(long snap) {
try (LockHold hold = LockHold.lock(space.lock.readLock())) {
return range.getLength();
}
}
protected void setLifespan(Lifespan newLifespan) throws DuplicateNameException {
Lifespan oldLifespan;
try (LockHold hold = LockHold.lock(space.lock.writeLock())) {
space.manager.checkDuplicatePath(this, path, newLifespan);
oldLifespan = lifespan;
doSetLifespan(newLifespan);
}
space.trace.setChanged(new TraceChangeRecord<>(TraceEvents.BREAKPOINT_LIFESPAN_CHANGED,
space, this, oldLifespan, newLifespan));
}
@Override
public Lifespan getLifespan() {
try (LockHold hold = LockHold.lock(space.lock.readLock())) {
return lifespan;
}
}
protected DBTraceBreakpoint doCopy() {
DBTraceBreakpoint breakpoint = space.breakpointMapSpace.put(this, null);
breakpoint.set(path, name, threadKeys, flagsByte, comment);
return breakpoint;
}
protected static byte computeFlagsByte(boolean enabled, Collection<TraceBreakpointKind> kinds) {
byte flags = 0;
for (TraceBreakpointKind k : kinds) {
flags |= k.getBits();
}
if (enabled) {
flags |= ENABLED_MASK;
}
return flags;
}
protected void doSetFlags(boolean enabled, Collection<TraceBreakpointKind> kinds) {
this.flagsByte = computeFlagsByte(enabled, kinds);
this.kinds.clear();
this.kinds.addAll(kinds);
this.enabled = enabled;
// Msg.debug(this,
// "trace: breakpoint " + this + " enabled=" + enabled + ", because doSetFlags");
update(FLAGS_COLUMN);
}
protected void doSetEnabled(boolean enabled) {
this.enabled = enabled;
// Msg.debug(this,
// "trace: breakpoint " + this + " enabled=" + enabled + ", because doSetEnabled");
if (enabled) {
flagsByte |= ENABLED_MASK;
}
else {
flagsByte &= ~ENABLED_MASK;
}
update(FLAGS_COLUMN);
}
protected void doSetEmuEnabled(boolean emuEnabled) {
this.emuEnabled = emuEnabled;
if (emuEnabled) {
flagsByte |= EMU_ENABLED_MASK;
}
else {
flagsByte &= ~EMU_ENABLED_MASK;
}
update(FLAGS_COLUMN);
}
protected void doSetKinds(Collection<TraceBreakpointKind> kinds) {
for (TraceBreakpointKind k : TraceBreakpointKind.values()) {
if (kinds.contains(k)) {
this.flagsByte |= k.getBits();
this.kinds.add(k);
}
else {
this.flagsByte &= ~k.getBits();
this.kinds.remove(k);
}
}
update(FLAGS_COLUMN);
}
@Override
public void setEnabled(long snap, boolean enabled) {
try (LockHold hold = LockHold.lock(space.lock.writeLock())) {
doSetEnabled(enabled);
}
space.trace
.setChanged(new TraceChangeRecord<>(TraceEvents.BREAKPOINT_CHANGED, space, this));
}
@Override
public boolean isEnabled(long snap) {
// NB. Only object mode supports per-snap enablement
try (LockHold hold = LockHold.lock(space.lock.readLock())) {
return enabled;
}
}
@Override
public void setEmuEnabled(long snap, boolean enabled) {
try (LockHold hold = LockHold.lock(space.lock.writeLock())) {
doSetEmuEnabled(enabled);
}
space.trace
.setChanged(new TraceChangeRecord<>(TraceEvents.BREAKPOINT_CHANGED, space, this));
}
@Override
public boolean isEmuEnabled(long snap) {
// NB. Only object mode support per-snap emu-enablement
try (LockHold hold = LockHold.lock(space.lock.readLock())) {
return emuEnabled;
}
}
@Override
public void setKinds(long snap, Collection<TraceBreakpointKind> kinds) {
try (LockHold hold = LockHold.lock(space.lock.writeLock())) {
doSetKinds(kinds);
}
space.trace
.setChanged(new TraceChangeRecord<>(TraceEvents.BREAKPOINT_CHANGED, space, this));
}
@Override
public Set<TraceBreakpointKind> getKinds(long snap) {
try (LockHold hold = LockHold.lock(space.lock.readLock())) {
return kindsView;
}
}
@Override
public void setComment(long snap, String comment) {
try (LockHold hold = LockHold.lock(space.lock.writeLock())) {
this.comment = comment;
update(COMMENT_COLUMN);
}
space.trace
.setChanged(new TraceChangeRecord<>(TraceEvents.BREAKPOINT_CHANGED, space, this));
}
@Override
public String getComment(long snap) {
try (LockHold hold = LockHold.lock(space.lock.readLock())) {
return comment;
}
}
@Override
public void setEmuSleigh(long snap, String emuSleigh) {
try (LockHold hold = LockHold.lock(space.lock.writeLock())) {
if (emuSleigh == null || SleighUtils.UNCONDITIONAL_BREAK.equals(emuSleigh)) {
this.emuSleigh = null;
}
else {
this.emuSleigh = emuSleigh.trim();
}
update(SLEIGH_COLUMN);
}
space.trace
.setChanged(new TraceChangeRecord<>(TraceEvents.BREAKPOINT_CHANGED, space, this));
}
@Override
public String getEmuSleigh(long snap) {
try (LockHold hold = LockHold.lock(space.lock.readLock())) {
return emuSleigh == null || emuSleigh.isBlank() ? SleighUtils.UNCONDITIONAL_BREAK
: emuSleigh;
}
}
@Override
public void delete() {
space.deleteBreakpoint(this);
}
@Override
public void remove(long snap) {
try (LockHold hold = LockHold.lock(space.lock.writeLock())) {
if (snap <= lifespan.lmin()) {
space.deleteBreakpoint(this);
}
else if (snap <= lifespan.lmax()) {
doSetLifespan(lifespan.withMax(snap - 1));
}
}
}
@Override
public boolean isValid(long snap) {
try (LockHold hold = LockHold.lock(space.lock.readLock())) {
return lifespan.contains(snap);
}
}
@Override
public boolean isAlive(Lifespan span) {
try (LockHold hold = LockHold.lock(space.lock.readLock())) {
return lifespan.intersects(span);
}
}
}

View file

@ -19,54 +19,55 @@ import java.util.*;
import java.util.stream.Collectors;
import ghidra.pcode.exec.SleighUtils;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressRange;
import ghidra.program.model.address.*;
import ghidra.trace.database.target.*;
import ghidra.trace.model.Lifespan;
import ghidra.trace.model.Trace;
import ghidra.trace.model.breakpoint.*;
import ghidra.trace.model.breakpoint.TraceBreakpointLocation;
import ghidra.trace.model.breakpoint.TraceBreakpointSpec;
import ghidra.trace.model.target.TraceObject;
import ghidra.trace.model.target.iface.TraceObjectTogglable;
import ghidra.trace.model.target.iface.TraceTogglable;
import ghidra.trace.model.target.info.TraceObjectInterfaceUtils;
import ghidra.trace.model.target.path.PathFilter;
import ghidra.trace.model.target.schema.TraceObjectSchema;
import ghidra.trace.model.thread.*;
import ghidra.trace.model.thread.TraceProcess;
import ghidra.trace.model.thread.TraceThread;
import ghidra.trace.util.*;
import ghidra.util.LockHold;
public class DBTraceObjectBreakpointLocation
implements TraceObjectBreakpointLocation, DBTraceObjectInterface {
public class DBTraceBreakpointLocation
implements TraceBreakpointLocation, DBTraceObjectInterface {
protected static class BreakpointChangeTranslator extends Translator<TraceBreakpoint> {
protected static class BreakpointChangeTranslator extends Translator<TraceBreakpointLocation> {
private static final Map<TraceObjectSchema, Set<String>> KEYS_BY_SCHEMA =
new WeakHashMap<>();
private final Set<String> keys;
protected BreakpointChangeTranslator(DBTraceObject object, TraceBreakpoint iface) {
protected BreakpointChangeTranslator(DBTraceObject object, TraceBreakpointLocation iface) {
super(KEY_RANGE, object, iface);
TraceObjectSchema schema = object.getSchema();
synchronized (KEYS_BY_SCHEMA) {
keys = KEYS_BY_SCHEMA.computeIfAbsent(schema, s -> Set.of(
schema.checkAliasedAttribute(KEY_RANGE),
schema.checkAliasedAttribute(KEY_DISPLAY),
schema.checkAliasedAttribute(TraceObjectTogglable.KEY_ENABLED),
schema.checkAliasedAttribute(TraceTogglable.KEY_ENABLED),
schema.checkAliasedAttribute(KEY_COMMENT)));
}
}
@Override
protected TraceEvent<TraceBreakpoint, Void> getAddedType() {
protected TraceEvent<TraceBreakpointLocation, Void> getAddedType() {
return TraceEvents.BREAKPOINT_ADDED;
}
@Override
protected TraceEvent<TraceBreakpoint, Lifespan> getLifespanChangedType() {
protected TraceEvent<TraceBreakpointLocation, Lifespan> getLifespanChangedType() {
return TraceEvents.BREAKPOINT_LIFESPAN_CHANGED;
}
@Override
protected TraceEvent<TraceBreakpoint, Void> getChangedType() {
protected TraceEvent<TraceBreakpointLocation, Void> getChangedType() {
return TraceEvents.BREAKPOINT_CHANGED;
}
@ -76,7 +77,7 @@ public class DBTraceObjectBreakpointLocation
}
@Override
protected TraceEvent<TraceBreakpoint, Void> getDeletedType() {
protected TraceEvent<TraceBreakpointLocation, Void> getDeletedType() {
return TraceEvents.BREAKPOINT_DELETED;
}
}
@ -84,7 +85,7 @@ public class DBTraceObjectBreakpointLocation
private final DBTraceObject object;
private final BreakpointChangeTranslator translator;
public DBTraceObjectBreakpointLocation(DBTraceObject object) {
public DBTraceBreakpointLocation(DBTraceObject object) {
this.object = object;
translator = new BreakpointChangeTranslator(object, this);
@ -107,9 +108,7 @@ public class DBTraceObjectBreakpointLocation
@Override
public void setName(long snap, String name) {
try (LockHold hold = object.getTrace().lockWrite()) {
setName(Lifespan.nowOn(snap), name);
}
setName(Lifespan.nowOn(snap), name);
}
@Override
@ -121,7 +120,7 @@ public class DBTraceObjectBreakpointLocation
return display;
}
TraceObject spec =
object.findCanonicalAncestorsInterface(TraceObjectBreakpointSpec.class)
object.findCanonicalAncestorsInterface(TraceBreakpointSpec.class)
.findFirst()
.orElse(null);
if (spec == null) {
@ -169,21 +168,19 @@ public class DBTraceObjectBreakpointLocation
@Override
public void setEnabled(Lifespan lifespan, boolean enabled) {
object.setValue(lifespan, TraceObjectTogglable.KEY_ENABLED, enabled);
object.setValue(lifespan, TraceTogglable.KEY_ENABLED, enabled);
}
@Override
public void setEnabled(long snap, boolean enabled) {
try (LockHold hold = object.getTrace().lockWrite()) {
setEnabled(Lifespan.nowOn(snap), enabled);
}
setEnabled(Lifespan.nowOn(snap), enabled);
}
@Override
public boolean isEnabled(long snap) {
try (LockHold hold = object.getTrace().lockRead()) {
Boolean locEn = TraceObjectInterfaceUtils.getValue(object, snap,
TraceObjectTogglable.KEY_ENABLED, Boolean.class, null);
TraceTogglable.KEY_ENABLED, Boolean.class, null);
if (locEn != null) {
return locEn && getSpecification().isEnabled(snap);
}
@ -191,31 +188,6 @@ public class DBTraceObjectBreakpointLocation
}
}
@Override
public void setKinds(Lifespan lifespan, Collection<TraceBreakpointKind> kinds) {
try (LockHold hold = object.getTrace().lockWrite()) {
TraceObjectBreakpointSpec spec = getSpecification();
if (spec.getObject() != this.getObject()) {
throw new UnsupportedOperationException("Set via the specification instead");
}
spec.setKinds(lifespan, kinds);
}
}
@Override
public void setKinds(long snap, Collection<TraceBreakpointKind> kinds) {
try (LockHold hold = object.getTrace().lockWrite()) {
setKinds(Lifespan.nowOn(snap), kinds);
}
}
@Override
public Set<TraceBreakpointKind> getKinds(long snap) {
try (LockHold hold = object.getTrace().lockRead()) {
return getSpecification().getKinds(snap);
}
}
@Override
public Set<TraceThread> getThreads(long snap) {
// TODO: Delete this? It's sort of deprecated out the gate anyway....
@ -223,17 +195,17 @@ public class DBTraceObjectBreakpointLocation
TraceObjectSchema schema = manager.getRootSchema();
try (LockHold hold = object.getTrace().lockRead()) {
Set<TraceThread> threads =
object.queryAncestorsInterface(Lifespan.at(snap), TraceObjectThread.class)
object.queryAncestorsInterface(Lifespan.at(snap), TraceThread.class)
.collect(Collectors.toSet());
if (!threads.isEmpty()) {
return threads;
}
PathFilter procFilter = schema.searchFor(TraceObjectProcess.class, false);
PathFilter procFilter = schema.searchFor(TraceProcess.class, false);
Lifespan lifespan = Lifespan.at(snap);
return object.getAncestorsRoot(lifespan, procFilter)
.flatMap(proc -> proc.getSource(object)
.querySuccessorsInterface(lifespan, TraceObjectThread.class, true))
.querySuccessorsInterface(lifespan, TraceThread.class, true))
.collect(Collectors.toSet());
}
}
@ -245,9 +217,7 @@ public class DBTraceObjectBreakpointLocation
@Override
public void setComment(long snap, String comment) {
try (LockHold hold = object.getTrace().lockWrite()) {
setComment(Lifespan.nowOn(snap), comment);
}
setComment(Lifespan.nowOn(snap), comment);
}
@Override
@ -258,11 +228,11 @@ public class DBTraceObjectBreakpointLocation
if (!comment.isBlank()) {
return comment;
}
TraceObjectBreakpointSpec spec = getSpecification();
TraceBreakpointSpec spec = getSpecification();
if (spec == null) {
return "";
}
return spec.getExpression(snap);
return spec.getComment(snap);
}
}
@ -340,20 +310,20 @@ public class DBTraceObjectBreakpointLocation
return object;
}
public TraceObjectBreakpointSpec getOrCreateSpecification() {
return object.queryOrCreateCanonicalAncestorInterface(TraceObjectBreakpointSpec.class);
public TraceBreakpointSpec getOrCreateSpecification() {
return object.queryOrCreateCanonicalAncestorInterface(TraceBreakpointSpec.class);
}
@Override
public TraceObjectBreakpointSpec getSpecification() {
public TraceBreakpointSpec getSpecification() {
try (LockHold hold = object.getTrace().lockRead()) {
return object.queryCanonicalAncestorsInterface(TraceObjectBreakpointSpec.class)
return object.queryCanonicalAncestorsInterface(TraceBreakpointSpec.class)
.findAny()
.orElseThrow();
}
}
public TraceAddressSpace getTraceAddressSpace(long snap) {
public AddressSpace getAddressSpace(long snap) {
return spaceForValue(snap, KEY_RANGE);
}

View file

@ -17,146 +17,89 @@ package ghidra.trace.database.breakpoint;
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import db.DBHandle;
import ghidra.framework.data.OpenMode;
import ghidra.program.model.address.*;
import ghidra.program.model.lang.Language;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressRange;
import ghidra.trace.database.DBTrace;
import ghidra.trace.database.space.AbstractDBTraceSpaceBasedManager;
import ghidra.trace.database.space.DBTraceDelegatingManager;
import ghidra.trace.database.thread.DBTraceThreadManager;
import ghidra.trace.database.DBTraceManager;
import ghidra.trace.database.target.DBTraceObjectManager;
import ghidra.trace.model.Lifespan;
import ghidra.trace.model.breakpoint.*;
import ghidra.trace.model.thread.TraceThread;
import ghidra.util.LockHold;
import ghidra.util.exception.DuplicateNameException;
import ghidra.util.exception.VersionException;
import ghidra.util.task.TaskMonitor;
public class DBTraceBreakpointManager
extends AbstractDBTraceSpaceBasedManager<DBTraceBreakpointSpace>
implements TraceBreakpointManager, DBTraceDelegatingManager<DBTraceBreakpointSpace> {
protected static final String NAME = "Breakpoint";
public class DBTraceBreakpointManager implements TraceBreakpointManager, DBTraceManager {
protected final ReadWriteLock lock;
protected final DBTrace trace;
protected final DBTraceObjectManager objectManager;
public DBTraceBreakpointManager(DBHandle dbh, OpenMode openMode, ReadWriteLock lock,
TaskMonitor monitor, Language baseLanguage, DBTrace trace,
DBTraceThreadManager threadManager) throws VersionException, IOException {
super(NAME, dbh, openMode, lock, monitor, baseLanguage, trace, threadManager);
loadSpaces();
}
@Override
protected DBTraceBreakpointSpace createSpace(AddressSpace space, DBTraceSpaceEntry ent)
TaskMonitor monitor, DBTrace trace, DBTraceObjectManager objectManager)
throws VersionException, IOException {
return new DBTraceBreakpointSpace(this, dbh, space, ent);
this.lock = lock;
this.trace = trace;
this.objectManager = objectManager;
}
@Override
protected DBTraceBreakpointSpace createRegisterSpace(AddressSpace space, TraceThread thread,
DBTraceSpaceEntry ent) throws VersionException, IOException {
throw new UnsupportedOperationException();
public void dbError(IOException e) {
trace.dbError(e);
}
@Override
public DBTraceBreakpointSpace getForSpace(AddressSpace space, boolean createIfAbsent) {
return super.getForSpace(space, createIfAbsent);
public void invalidateCache(boolean all) {
// NOTE: This is only a wrapper around the object manager
}
@Override
public Lock readLock() {
return lock.readLock();
}
@Override
public Lock writeLock() {
return lock.writeLock();
}
protected void checkDuplicatePath(TraceBreakpoint ignore, String path, Lifespan lifespan)
throws DuplicateNameException {
for (TraceBreakpoint pc : getBreakpointsByPath(path)) {
if (pc == ignore) {
continue;
}
if (!pc.isAlive(lifespan)) {
continue;
}
throw new DuplicateNameException("A breakpoint having path '" + path +
"' already exists within an overlapping snap");
}
}
@Override
public TraceBreakpoint addBreakpoint(String path, Lifespan lifespan, AddressRange range,
public TraceBreakpointLocation addBreakpoint(String path, Lifespan lifespan, AddressRange range,
Collection<TraceThread> threads, Collection<TraceBreakpointKind> kinds, boolean enabled,
String comment) throws DuplicateNameException {
if (trace.getObjectManager().hasSchema()) {
return trace.getObjectManager()
.addBreakpoint(path, lifespan, range, threads, kinds, enabled, comment);
}
checkDuplicatePath(null, path, lifespan);
return delegateWrite(range.getAddressSpace(),
m -> m.addBreakpoint(path, lifespan, range, threads, kinds, enabled, comment));
return objectManager.addBreakpoint(path, lifespan, range, threads, kinds, enabled, comment);
}
@Override
public Collection<? extends TraceBreakpoint> getAllBreakpoints() {
if (trace.getObjectManager().hasSchema()) {
return trace.getObjectManager().getAllObjects(TraceObjectBreakpointLocation.class);
}
return delegateCollection(getActiveMemorySpaces(), m -> m.getAllBreakpoints());
public Collection<? extends TraceBreakpointSpec> getAllBreakpointSpecifications() {
return objectManager.getAllObjects(TraceBreakpointSpec.class);
}
@Override
public Collection<? extends TraceBreakpoint> getBreakpointsByPath(String path) {
if (trace.getObjectManager().hasSchema()) {
return trace.getObjectManager()
.getObjectsByPath(path, TraceObjectBreakpointLocation.class);
}
return delegateCollection(getActiveMemorySpaces(), m -> m.getBreakpointsByPath(path));
public Collection<? extends TraceBreakpointLocation> getAllBreakpointLocations() {
return objectManager.getAllObjects(TraceBreakpointLocation.class);
}
@Override
public TraceBreakpoint getPlacedBreakpointByPath(long snap, String path) {
if (trace.getObjectManager().hasSchema()) {
return trace.getObjectManager()
.getObjectByPath(snap, path, TraceObjectBreakpointLocation.class);
}
try (LockHold hold = LockHold.lock(lock.readLock())) {
return getBreakpointsByPath(path).stream()
.filter(b -> b.isValid(snap))
.findAny()
.orElse(null);
}
public Collection<? extends TraceBreakpointSpec> getBreakpointSpecificationsByPath(
String path) {
return objectManager.getObjectsByPath(path, TraceBreakpointSpec.class);
}
@Override
public Collection<? extends TraceBreakpoint> getBreakpointsAt(long snap, Address address) {
if (trace.getObjectManager().hasSchema()) {
return trace.getObjectManager()
.getObjectsContaining(snap, address,
TraceObjectBreakpointLocation.KEY_RANGE,
TraceObjectBreakpointLocation.class);
}
return delegateRead(address.getAddressSpace(), m -> m.getBreakpointsAt(snap, address),
Collections.emptyList());
public Collection<? extends TraceBreakpointLocation> getBreakpointLocationsByPath(String path) {
return objectManager.getObjectsByPath(path, TraceBreakpointLocation.class);
}
@Override
public Collection<? extends TraceBreakpoint> getBreakpointsIntersecting(Lifespan span,
public TraceBreakpointLocation getPlacedBreakpointByPath(long snap, String path) {
return objectManager.getObjectByPath(snap, path, TraceBreakpointLocation.class);
}
@Override
public Collection<? extends TraceBreakpointLocation> getBreakpointsAt(long snap,
Address address) {
return objectManager.getObjectsContaining(snap, address, TraceBreakpointLocation.KEY_RANGE,
TraceBreakpointLocation.class);
}
@Override
public Collection<? extends TraceBreakpointLocation> getBreakpointsIntersecting(Lifespan span,
AddressRange range) {
if (trace.getObjectManager().hasSchema()) {
return trace.getObjectManager()
.getObjectsIntersecting(span, range,
TraceObjectBreakpointLocation.KEY_RANGE,
TraceObjectBreakpointLocation.class);
}
return delegateRead(range.getAddressSpace(), m -> m.getBreakpointsIntersecting(span, range),
Collections.emptyList());
return objectManager.getObjectsIntersecting(span, range, TraceBreakpointLocation.KEY_RANGE,
TraceBreakpointLocation.class);
}
}

View file

@ -1,138 +0,0 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.trace.database.breakpoint;
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.concurrent.locks.ReadWriteLock;
import db.DBHandle;
import ghidra.program.model.address.*;
import ghidra.trace.database.DBTrace;
import ghidra.trace.database.map.DBTraceAddressSnapRangePropertyMapSpace;
import ghidra.trace.database.map.DBTraceAddressSnapRangePropertyMapTree.TraceAddressSnapRangeQuery;
import ghidra.trace.database.space.AbstractDBTraceSpaceBasedManager.DBTraceSpaceEntry;
import ghidra.trace.database.space.DBTraceSpaceBased;
import ghidra.trace.database.thread.DBTraceThread;
import ghidra.trace.database.thread.DBTraceThreadManager;
import ghidra.trace.model.ImmutableTraceAddressSnapRange;
import ghidra.trace.model.Lifespan;
import ghidra.trace.model.breakpoint.TraceBreakpoint;
import ghidra.trace.model.breakpoint.TraceBreakpointKind;
import ghidra.trace.model.thread.TraceThread;
import ghidra.trace.util.TraceChangeRecord;
import ghidra.trace.util.TraceEvents;
import ghidra.util.LockHold;
import ghidra.util.database.DBCachedObjectIndex;
import ghidra.util.database.DBCachedObjectStoreFactory;
import ghidra.util.exception.VersionException;
public class DBTraceBreakpointSpace implements DBTraceSpaceBased {
protected final DBTraceBreakpointManager manager;
protected final DBHandle dbh;
protected final AddressSpace space;
protected final ReadWriteLock lock;
protected final DBTrace trace;
protected final DBTraceAddressSnapRangePropertyMapSpace<DBTraceBreakpoint, DBTraceBreakpoint> breakpointMapSpace;
protected final DBCachedObjectIndex<String, DBTraceBreakpoint> breakpointsByPath;
protected final Collection<TraceBreakpoint> breakpointView;
public DBTraceBreakpointSpace(DBTraceBreakpointManager manager, DBHandle dbh,
AddressSpace space, DBTraceSpaceEntry ent) throws VersionException, IOException {
this.manager = manager;
this.dbh = dbh;
this.space = space;
this.lock = manager.getLock();
this.trace = manager.getTrace();
DBCachedObjectStoreFactory factory = trace.getStoreFactory();
long threadKey = ent.getThreadKey();
assert threadKey == -1; // No breakpoints on registers
breakpointMapSpace =
new DBTraceAddressSnapRangePropertyMapSpace<DBTraceBreakpoint, DBTraceBreakpoint>(
DBTraceBreakpoint.tableName(space, threadKey), factory, lock, space, null, 0,
DBTraceBreakpoint.class, (t, s, r) -> new DBTraceBreakpoint(this, t, s, r));
breakpointsByPath =
breakpointMapSpace.getUserIndex(String.class, DBTraceBreakpoint.PATH_COLUMN);
breakpointView = Collections.unmodifiableCollection(breakpointMapSpace.values());
}
@Override
public AddressSpace getAddressSpace() {
return space;
}
@Override
public DBTraceThread getThread() {
return null;
}
@Override
public int getFrameLevel() {
return 0;
}
protected DBTraceBreakpoint addBreakpoint(String path, Lifespan lifespan, AddressRange range,
Collection<TraceThread> threads, Collection<TraceBreakpointKind> kinds, boolean enabled,
String comment) {
// NOTE: thread here is not about address/register spaces.
// It's about which thread to trap
try (LockHold hold = LockHold.lock(lock.writeLock())) {
DBTraceThreadManager threadManager = trace.getThreadManager();
for (TraceThread t : threads) {
threadManager.assertIsMine(t);
}
DBTraceBreakpoint breakpoint =
breakpointMapSpace.put(new ImmutableTraceAddressSnapRange(range, lifespan), null);
breakpoint.set(path, path, threads, kinds, enabled, true, comment);
trace.setChanged(
new TraceChangeRecord<>(TraceEvents.BREAKPOINT_ADDED, this, breakpoint));
return breakpoint;
}
}
public Collection<? extends DBTraceBreakpoint> getAllBreakpoints() {
return breakpointMapSpace.values();
}
public Collection<? extends DBTraceBreakpoint> getBreakpointsByPath(String name) {
return Collections.unmodifiableCollection(breakpointsByPath.get(name));
}
public Collection<? extends DBTraceBreakpoint> getBreakpointsAt(long snap, Address address) {
return Collections.unmodifiableCollection(
breakpointMapSpace.reduce(TraceAddressSnapRangeQuery.at(address, snap)).values());
}
public Collection<? extends DBTraceBreakpoint> getBreakpointsIntersecting(Lifespan span,
AddressRange range) {
return Collections.unmodifiableCollection(breakpointMapSpace.reduce(
TraceAddressSnapRangeQuery.intersecting(range, span)).orderedValues());
}
public void deleteBreakpoint(DBTraceBreakpoint breakpoint) {
breakpointMapSpace.deleteData(breakpoint);
trace.setChanged(new TraceChangeRecord<>(TraceEvents.BREAKPOINT_DELETED, this, breakpoint));
}
@Override
public void invalidateCache() {
breakpointMapSpace.invalidateCache();
}
}

View file

@ -18,8 +18,7 @@ package ghidra.trace.database.breakpoint;
import java.util.*;
import java.util.stream.Collectors;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressRange;
import ghidra.program.model.address.AddressSpace;
import ghidra.trace.database.target.DBTraceObject;
import ghidra.trace.database.target.DBTraceObjectInterface;
import ghidra.trace.model.Lifespan;
@ -28,17 +27,15 @@ import ghidra.trace.model.breakpoint.*;
import ghidra.trace.model.breakpoint.TraceBreakpointKind.TraceBreakpointKindSet;
import ghidra.trace.model.target.TraceObject;
import ghidra.trace.model.target.TraceObjectValue;
import ghidra.trace.model.target.iface.TraceObjectInterface;
import ghidra.trace.model.target.iface.TraceObjectTogglable;
import ghidra.trace.model.target.iface.TraceTogglable;
import ghidra.trace.model.target.info.TraceObjectInterfaceUtils;
import ghidra.trace.model.target.schema.TraceObjectSchema;
import ghidra.trace.model.thread.TraceThread;
import ghidra.trace.util.*;
import ghidra.trace.util.TraceChangeRecord;
import ghidra.trace.util.TraceEvents;
import ghidra.util.LockHold;
import ghidra.util.Msg;
public class DBTraceObjectBreakpointSpec
implements TraceObjectBreakpointSpec, DBTraceObjectInterface {
public class DBTraceBreakpointSpec implements TraceBreakpointSpec, DBTraceObjectInterface {
private static final Map<TraceObjectSchema, Set<String>> KEYS_BY_SCHEMA = new WeakHashMap<>();
private final DBTraceObject object;
@ -46,13 +43,13 @@ public class DBTraceObjectBreakpointSpec
private TraceBreakpointKindSet kinds = TraceBreakpointKindSet.of();
public DBTraceObjectBreakpointSpec(DBTraceObject object) {
public DBTraceBreakpointSpec(DBTraceObject object) {
this.object = object;
TraceObjectSchema schema = object.getSchema();
synchronized (KEYS_BY_SCHEMA) {
keys = KEYS_BY_SCHEMA.computeIfAbsent(schema,
s -> Set.of(schema.checkAliasedAttribute(TraceObjectBreakpointSpec.KEY_KINDS),
schema.checkAliasedAttribute(TraceObjectTogglable.KEY_ENABLED)));
s -> Set.of(schema.checkAliasedAttribute(KEY_KINDS),
schema.checkAliasedAttribute(TraceTogglable.KEY_ENABLED)));
}
}
@ -66,51 +63,35 @@ public class DBTraceObjectBreakpointSpec
return object.getCanonicalPath().toString();
}
@Override
public void setName(Lifespan lifespan, String name) {
object.setValue(lifespan, KEY_DISPLAY, name);
}
@Override
public void setName(long snap, String name) {
try (LockHold hold = object.getTrace().lockWrite()) {
object.setValue(Lifespan.nowOn(snap), TraceObjectInterface.KEY_DISPLAY, name);
}
setName(Lifespan.nowOn(snap), name);
}
@Override
public String getName(long snap) {
return TraceObjectInterfaceUtils.getValue(object, snap, TraceObjectInterface.KEY_DISPLAY,
String.class, "");
return TraceObjectInterfaceUtils.getValue(object, snap, KEY_DISPLAY, String.class, "");
}
@Override
public AddressRange getRange(long snap) {
throw new UnsupportedOperationException("Ask a location instead");
}
@Override
public Address getMinAddress(long snap) {
throw new UnsupportedOperationException("Ask a location instead");
}
@Override
public Address getMaxAddress(long snap) {
throw new UnsupportedOperationException("Ask a location instead");
}
@Override
public long getLength(long snap) {
throw new UnsupportedOperationException("Ask a location instead");
public void setEnabled(Lifespan lifespan, boolean enabled) {
object.setValue(lifespan, TraceTogglable.KEY_ENABLED, enabled ? true : null);
}
@Override
public void setEnabled(long snap, boolean enabled) {
try (LockHold hold = object.getTrace().lockWrite()) {
object.setValue(Lifespan.nowOn(snap), TraceObjectTogglable.KEY_ENABLED,
enabled ? true : null);
}
setEnabled(Lifespan.nowOn(snap), enabled);
}
@Override
public boolean isEnabled(long snap) {
return TraceObjectInterfaceUtils.getValue(object, snap,
TraceObjectTogglable.KEY_ENABLED, Boolean.class, false);
TraceTogglable.KEY_ENABLED, Boolean.class, false);
}
@Override
@ -118,8 +99,7 @@ public class DBTraceObjectBreakpointSpec
// TODO: More efficient encoding
// TODO: Target-Trace mapping is implied by encoded name. Seems bad.
try (LockHold hold = object.getTrace().lockWrite()) {
object.setValue(lifespan, TraceObjectBreakpointSpec.KEY_KINDS,
TraceBreakpointKindSet.encode(kinds));
object.setValue(lifespan, KEY_KINDS, TraceBreakpointKindSet.encode(kinds));
this.kinds = TraceBreakpointKindSet.copyOf(kinds);
}
}
@ -133,8 +113,8 @@ public class DBTraceObjectBreakpointSpec
@Override
public Set<TraceBreakpointKind> getKinds(long snap) {
String kindsStr = TraceObjectInterfaceUtils.getValue(object, snap,
TraceObjectBreakpointSpec.KEY_KINDS, String.class, null);
String kindsStr =
TraceObjectInterfaceUtils.getValue(object, snap, KEY_KINDS, String.class, null);
if (kindsStr == null) {
return kinds;
}
@ -149,43 +129,24 @@ public class DBTraceObjectBreakpointSpec
@Override
public String getExpression(long snap) {
return TraceObjectInterfaceUtils.getValue(object, snap,
TraceObjectBreakpointSpec.KEY_EXPRESSION, String.class, null);
return TraceObjectInterfaceUtils.getValue(object, snap, KEY_EXPRESSION, String.class, null);
}
@Override
public Set<TraceThread> getThreads(long snap) {
throw new UnsupportedOperationException("Ask a location instead");
public void setComment(Lifespan lifespan, String comment) {
object.setValue(lifespan, KEY_COMMENT, comment);
}
@Override
public void setComment(long snap, String comment) {
throw new UnsupportedOperationException("Set on a location instead");
setComment(Lifespan.nowOn(snap), comment);
}
@Override
public String getComment(long snap) {
throw new UnsupportedOperationException("Ask a location instead");
}
@Override
public void setEmuEnabled(long snap, boolean enabled) {
throw new UnsupportedOperationException("Set on a location instead");
}
@Override
public boolean isEmuEnabled(long snap) {
throw new UnsupportedOperationException("Ask a location instead");
}
@Override
public void setEmuSleigh(long snap, String sleigh) {
throw new UnsupportedOperationException("Set on a location instead");
}
@Override
public String getEmuSleigh(long snap) {
throw new UnsupportedOperationException("Ask a location instead");
try (LockHold hold = object.getTrace().lockRead()) {
return TraceObjectInterfaceUtils.getValue(object, snap, KEY_COMMENT, String.class, "");
}
}
@Override
@ -217,15 +178,15 @@ public class DBTraceObjectBreakpointSpec
return object;
}
protected Collection<? extends TraceObjectBreakpointLocation> getLocations(Lifespan span) {
protected Collection<? extends TraceBreakpointLocation> getLocations(Lifespan span) {
try (LockHold hold = object.getTrace().lockRead()) {
return object.querySuccessorsInterface(span, TraceObjectBreakpointLocation.class, true)
return object.querySuccessorsInterface(span, TraceBreakpointLocation.class, true)
.collect(Collectors.toSet());
}
}
@Override
public Collection<? extends TraceObjectBreakpointLocation> getLocations(long snap) {
public Collection<? extends TraceBreakpointLocation> getLocations(long snap) {
return getLocations(Lifespan.at(snap));
}
@ -243,9 +204,9 @@ public class DBTraceObjectBreakpointSpec
if (object.getCanonicalParent(affected.getMaxSnap()) == null) {
return null; // Incomplete object
}
for (TraceObjectBreakpointLocation loc : getLocations(affected.getLifespan())) {
DBTraceObjectBreakpointLocation dbLoc = (DBTraceObjectBreakpointLocation) loc;
TraceAddressSpace space = dbLoc.getTraceAddressSpace(affected.getMinSnap());
for (TraceBreakpointLocation loc : getLocations(affected.getLifespan())) {
DBTraceBreakpointLocation dbLoc = (DBTraceBreakpointLocation) loc;
AddressSpace space = dbLoc.getAddressSpace(affected.getMinSnap());
TraceChangeRecord<?, ?> evt =
new TraceChangeRecord<>(TraceEvents.BREAKPOINT_CHANGED, space, loc, null, null);
object.getTrace().setChanged(evt);

View file

@ -101,14 +101,7 @@ public class DBTraceRegisterContextManager
@Override
protected DBTraceRegisterContextSpace createSpace(AddressSpace space, DBTraceSpaceEntry ent)
throws VersionException, IOException {
return new DBTraceRegisterContextSpace(this, dbh, space, ent, null);
}
@Override
protected DBTraceRegisterContextSpace createRegisterSpace(AddressSpace space,
TraceThread thread, DBTraceSpaceEntry ent) throws VersionException, IOException {
// TODO: Should I just forbid this? It doesn't seem sane. Then again, what do I know?
return new DBTraceRegisterContextSpace(this, dbh, space, ent, thread);
return new DBTraceRegisterContextSpace(this, dbh, space, ent);
}
@Override
@ -205,7 +198,7 @@ public class DBTraceRegisterContextManager
@Override
public AddressSetView getRegisterValueAddressRanges(Language language, Register register,
long snap) {
return delegateAddressSet(getActiveMemorySpaces(),
return delegateAddressSet(getActiveSpaces(),
m -> m.getRegisterValueAddressRanges(language, register, snap));
}
@ -218,8 +211,7 @@ public class DBTraceRegisterContextManager
@Override
public boolean hasRegisterValue(Language language, Register register, long snap) {
return delegateAny(getActiveMemorySpaces(),
m -> m.hasRegisterValue(language, register, snap));
return delegateAny(getActiveSpaces(), m -> m.hasRegisterValue(language, register, snap));
}
@Override

View file

@ -39,7 +39,6 @@ import ghidra.trace.database.space.DBTraceSpaceBased;
import ghidra.trace.model.*;
import ghidra.trace.model.context.TraceRegisterContextSpace;
import ghidra.trace.model.guest.TracePlatform;
import ghidra.trace.model.thread.TraceThread;
import ghidra.util.LockHold;
import ghidra.util.database.*;
import ghidra.util.database.annot.*;
@ -79,8 +78,6 @@ public class DBTraceRegisterContextSpace implements TraceRegisterContextSpace, D
protected final DBTraceRegisterContextManager manager;
protected final DBHandle dbh;
protected final AddressSpace space;
protected final TraceThread thread;
protected final int frameLevel;
protected final ReadWriteLock lock;
protected final Language baseLanguage;
protected final DBTrace trace;
@ -91,13 +88,10 @@ public class DBTraceRegisterContextSpace implements TraceRegisterContextSpace, D
new HashMap<>();
public DBTraceRegisterContextSpace(DBTraceRegisterContextManager manager, DBHandle dbh,
AddressSpace space, DBTraceSpaceEntry ent, TraceThread thread)
throws VersionException, IOException {
AddressSpace space, DBTraceSpaceEntry ent) throws VersionException, IOException {
this.manager = manager;
this.dbh = dbh;
this.space = space;
this.thread = thread;
this.frameLevel = ent.getFrameLevel();
this.lock = manager.getLock();
this.baseLanguage = manager.getBaseLanguage();
this.trace = manager.getTrace();
@ -105,8 +99,7 @@ public class DBTraceRegisterContextSpace implements TraceRegisterContextSpace, D
DBCachedObjectStoreFactory factory = trace.getStoreFactory();
registerStore = factory.getOrCreateCachedStore(
DBTraceUtils.tableName(TABLE_NAME, space, ent.getThreadKey(), ent.getFrameLevel()),
registerStore = factory.getOrCreateCachedStore(DBTraceUtils.tableName(TABLE_NAME, space),
DBTraceRegisterEntry.class, DBTraceRegisterEntry::new, true);
loadRegisterValueMaps();
@ -125,28 +118,18 @@ public class DBTraceRegisterContextSpace implements TraceRegisterContextSpace, D
}
}
@Override
public DBTrace getTrace() {
return trace;
}
@Override
public AddressSpace getAddressSpace() {
return space;
}
@Override
public TraceThread getThread() {
return thread;
}
protected long getThreadKey() {
TraceThread thread = getThread();
return thread == null ? -1 : thread.getKey();
}
@Override
public int getFrameLevel() {
return frameLevel;
}
protected String tableName(Language language, Register register) {
return DBTraceUtils.tableName(TABLE_NAME, space, getThreadKey(), getFrameLevel()) + "_" +
return DBTraceUtils.tableName(TABLE_NAME, space) + "_" +
language.getLanguageID().getIdAsString() + "_" + register.getName();
}
@ -154,9 +137,9 @@ public class DBTraceRegisterContextSpace implements TraceRegisterContextSpace, D
Pair<Language, Register> lr) throws VersionException {
String name = tableName(lr.getLeft(), lr.getRight());
try {
return new DBTraceAddressSnapRangePropertyMapSpace<>(name, trace.getStoreFactory(),
lock, space, thread, frameLevel, DBTraceRegisterContextEntry.class,
DBTraceRegisterContextEntry::new);
return new DBTraceAddressSnapRangePropertyMapSpace<>(name, trace,
trace.getStoreFactory(), lock, space,
DBTraceRegisterContextEntry.class, DBTraceRegisterContextEntry::new);
}
catch (IOException e) {
manager.dbError(e);

View file

@ -158,12 +158,12 @@ public class DBTraceDataSettingsAdapter
public class DBTraceDataSettingsSpace extends
DBTraceAddressSnapRangePropertyMapSpace<DBTraceSettingsEntry, DBTraceSettingsEntry>
implements DBTraceDataSettingsOperations {
public DBTraceDataSettingsSpace(String tableName, DBCachedObjectStoreFactory storeFactory,
ReadWriteLock lock, AddressSpace space, TraceThread thread, int frameLevel,
public DBTraceDataSettingsSpace(String tableName, DBTrace trace,
DBCachedObjectStoreFactory storeFactory, ReadWriteLock lock, AddressSpace space,
Class<DBTraceSettingsEntry> dataType,
DBTraceAddressSnapRangePropertyMapDataFactory<DBTraceSettingsEntry, DBTraceSettingsEntry> dataFactory)
throws VersionException, IOException {
super(tableName, storeFactory, lock, space, thread, frameLevel, dataType, dataFactory);
super(tableName, trace, storeFactory, lock, space, dataType, dataFactory);
}
@Override
@ -187,17 +187,8 @@ public class DBTraceDataSettingsAdapter
@Override
protected DBTraceDataSettingsSpace createSpace(AddressSpace space, DBTraceSpaceEntry ent)
throws VersionException, IOException {
return new DBTraceDataSettingsSpace(
tableName(space, ent.getThreadKey(), ent.getFrameLevel()), trace.getStoreFactory(),
lock, space, null, 0, dataType, dataFactory);
}
@Override
protected DBTraceDataSettingsSpace createRegisterSpace(AddressSpace space, TraceThread thread,
DBTraceSpaceEntry ent) throws VersionException, IOException {
return new DBTraceDataSettingsSpace(
tableName(space, ent.getThreadKey(), ent.getFrameLevel()), trace.getStoreFactory(),
lock, space, thread, ent.getFrameLevel(), dataType, dataFactory);
return new DBTraceDataSettingsSpace(tableName(space), trace, trace.getStoreFactory(), lock,
space, dataType, dataFactory);
}
@Override

Some files were not shown because too many files have changed in this diff Show more