GP-6799: Improve display of breakpiont 'kinds' in the UI. Also shorter db/protocol encoding.
@@ -1076,10 +1076,10 @@ def put_single_breakpoint(bp, ibobj, nproc: int, ikeys: List[str]) -> None:
|
||||
if bp.GetType()[0] == DbgEng.DEBUG_BREAKPOINT_DATA:
|
||||
width, prot = bp.GetDataParameters()
|
||||
width = str(width)
|
||||
prot = {4: 'HW_EXECUTE', 2: 'READ', 1: 'WRITE'}[prot]
|
||||
prot = {4: 'X', 2: 'R', 1: 'W'}[prot]
|
||||
else:
|
||||
width = ' '
|
||||
prot = 'SW_EXECUTE'
|
||||
prot = 'x'
|
||||
|
||||
if address is not None: # Implies execution break
|
||||
base, addr = mapper.map(nproc, address)
|
||||
|
||||
@@ -1101,22 +1101,22 @@ def put_single_breakpoint(b: gdb.Breakpoint, ibobj: TraceObject,
|
||||
brkobj.set_value('Enabled', b.enabled)
|
||||
if b.type == gdb.BP_BREAKPOINT:
|
||||
brkobj.set_value('Expression', b.location)
|
||||
brkobj.set_value('Kinds', 'SW_EXECUTE')
|
||||
brkobj.set_value('Kinds', 'x')
|
||||
elif b.type == gdb.BP_HARDWARE_BREAKPOINT:
|
||||
brkobj.set_value('Expression', b.location)
|
||||
brkobj.set_value('Kinds', 'HW_EXECUTE')
|
||||
brkobj.set_value('Kinds', 'X')
|
||||
elif b.type == gdb.BP_WATCHPOINT:
|
||||
brkobj.set_value('Expression', b.expression)
|
||||
brkobj.set_value('Kinds', 'WRITE')
|
||||
brkobj.set_value('Kinds', 'W')
|
||||
elif b.type == gdb.BP_HARDWARE_WATCHPOINT:
|
||||
brkobj.set_value('Expression', b.expression)
|
||||
brkobj.set_value('Kinds', 'WRITE')
|
||||
brkobj.set_value('Kinds', 'W')
|
||||
elif b.type == gdb.BP_READ_WATCHPOINT:
|
||||
brkobj.set_value('Expression', b.expression)
|
||||
brkobj.set_value('Kinds', 'READ')
|
||||
brkobj.set_value('Kinds', 'R')
|
||||
elif b.type == gdb.BP_ACCESS_WATCHPOINT:
|
||||
brkobj.set_value('Expression', b.expression)
|
||||
brkobj.set_value('Kinds', 'READ,WRITE')
|
||||
brkobj.set_value('Kinds', 'RW')
|
||||
else:
|
||||
brkobj.set_value('Expression', '(unknown)')
|
||||
brkobj.set_value('Kinds', '')
|
||||
|
||||
@@ -1536,10 +1536,10 @@ def put_single_breakpoint(b: lldb.SBBreakpoint, proc: lldb.SBProcess) -> None:
|
||||
bpt_obj = trace.create_object(bpt_path)
|
||||
if b.IsHardware():
|
||||
bpt_obj.set_value('Expression', util.get_description(b))
|
||||
bpt_obj.set_value('Kinds', 'HW_EXECUTE')
|
||||
bpt_obj.set_value('Kinds', 'X')
|
||||
else:
|
||||
bpt_obj.set_value('Expression', util.get_description(b))
|
||||
bpt_obj.set_value('Kinds', 'SW_EXECUTE')
|
||||
bpt_obj.set_value('Kinds', 'x')
|
||||
cmdList = lldb.SBStringList()
|
||||
if b.GetCommandLineCommands(cmdList):
|
||||
list = []
|
||||
@@ -1580,11 +1580,11 @@ def put_single_watchpoint(w: lldb.SBWatchpoint, proc: lldb.SBProcess) -> None:
|
||||
wpt_obj = trace.create_object(wpt_path)
|
||||
desc = util.get_description(w, level=0)
|
||||
wpt_obj.set_value('Expression', desc)
|
||||
wpt_obj.set_value('Kinds', 'WRITE')
|
||||
wpt_obj.set_value('Kinds', 'W')
|
||||
if "type = r" in desc:
|
||||
wpt_obj.set_value('Kinds', 'READ')
|
||||
wpt_obj.set_value('Kinds', 'R')
|
||||
if "type = rw" in desc:
|
||||
wpt_obj.set_value('Kinds', 'READ,WRITE')
|
||||
wpt_obj.set_value('Kinds', 'RW')
|
||||
base, addr = mapper.map(proc, w.GetWatchAddress())
|
||||
if base != addr.space:
|
||||
trace.create_overlay_space(base, addr.space)
|
||||
|
||||
@@ -967,12 +967,12 @@ def put_single_breakpoint(bp, bpath, nproc: int, ikeys: List[int]) -> None:
|
||||
brkobj.set_value('Range', addr.extend(bp.hwSize))
|
||||
brkobj.set_value('HitCount', bp.hitCount)
|
||||
if bp.type == BreakpointType.BpNormal:
|
||||
brkobj.set_value('Kinds', 'SW_EXECUTE')
|
||||
brkobj.set_value('Kinds', 'x')
|
||||
if bp.type == BreakpointType.BpHardware:
|
||||
prot = {0: 'READ', 1: 'WRITE', 2: 'HW_EXECUTE'}[bp.typeEx]
|
||||
prot = {0: 'R', 1: 'W', 2: 'X'}[bp.typeEx]
|
||||
brkobj.set_value('Kinds', prot)
|
||||
if bp.type == BreakpointType.BpMemory:
|
||||
prot = {0: 'READ', 1: 'WRITE', 2: 'HW_EXECUTE', 3: 'ACCESS'}[bp.typeEx]
|
||||
prot = {0: 'R', 1: 'W', 2: 'X', 3: 'RW'}[bp.typeEx]
|
||||
brkobj.set_value('Kinds', prot)
|
||||
brkobj.insert()
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ import ghidra.program.model.lang.*;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.util.ProgramLocation;
|
||||
import ghidra.trace.model.*;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind.CommonSet;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind.TraceBreakpointKindSet;
|
||||
import ghidra.trace.model.guest.TracePlatform;
|
||||
import ghidra.trace.model.memory.TraceMemoryOperations;
|
||||
@@ -2174,7 +2175,7 @@ public interface FlatDebuggerAPI {
|
||||
*/
|
||||
default Set<LogicalBreakpoint> breakpointSetSoftwareExecute(ProgramLocation location,
|
||||
String name) {
|
||||
return breakpointSet(location, 1, TraceBreakpointKindSet.SW_EXECUTE, name);
|
||||
return breakpointSet(location, 1, CommonSet.SWX.kinds(), name);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2187,7 +2188,7 @@ public interface FlatDebuggerAPI {
|
||||
*/
|
||||
default Set<LogicalBreakpoint> breakpointSetHardwareExecute(ProgramLocation location,
|
||||
String name) {
|
||||
return breakpointSet(location, 1, TraceBreakpointKindSet.HW_EXECUTE, name);
|
||||
return breakpointSet(location, 1, CommonSet.HWX.kinds(), name);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2204,7 +2205,7 @@ public interface FlatDebuggerAPI {
|
||||
*/
|
||||
default Set<LogicalBreakpoint> breakpointSetRead(ProgramLocation location, int length,
|
||||
String name) {
|
||||
return breakpointSet(location, length, TraceBreakpointKindSet.READ, name);
|
||||
return breakpointSet(location, length, CommonSet.READ.kinds(), name);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2221,7 +2222,7 @@ public interface FlatDebuggerAPI {
|
||||
*/
|
||||
default Set<LogicalBreakpoint> breakpointSetWrite(ProgramLocation location, int length,
|
||||
String name) {
|
||||
return breakpointSet(location, length, TraceBreakpointKindSet.WRITE, name);
|
||||
return breakpointSet(location, length, CommonSet.WRITE.kinds(), name);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2238,7 +2239,7 @@ public interface FlatDebuggerAPI {
|
||||
*/
|
||||
default Set<LogicalBreakpoint> breakpointSetAccess(ProgramLocation location, int length,
|
||||
String name) {
|
||||
return breakpointSet(location, length, TraceBreakpointKindSet.ACCESS, name);
|
||||
return breakpointSet(location, length, CommonSet.ACCESS.kinds(), name);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -48,7 +48,7 @@ import ghidra.program.model.lang.Register;
|
||||
import ghidra.program.model.lang.RegisterValue;
|
||||
import ghidra.trace.model.*;
|
||||
import ghidra.trace.model.breakpoint.*;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind.TraceBreakpointKindSet;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind.CommonSet;
|
||||
import ghidra.trace.model.guest.TracePlatform;
|
||||
import ghidra.trace.model.memory.*;
|
||||
import ghidra.trace.model.stack.TraceStack;
|
||||
@@ -1542,21 +1542,21 @@ public class TraceRmiTarget extends AbstractTarget {
|
||||
public CompletableFuture<Void> placeBreakpointAsync(AddressRange range,
|
||||
Set<TraceBreakpointKind> kinds, String condition, String commands) {
|
||||
Set<TraceBreakpointKind> copyKinds = Set.copyOf(kinds);
|
||||
if (copyKinds.equals(TraceBreakpointKindSet.HW_EXECUTE)) {
|
||||
if (copyKinds.equals(CommonSet.HWX.kinds())) {
|
||||
return placeHwExecBreakAsync(expectSingleAddr(range, TraceBreakpointKind.HW_EXECUTE),
|
||||
condition, commands);
|
||||
}
|
||||
if (copyKinds.equals(TraceBreakpointKindSet.SW_EXECUTE)) {
|
||||
if (copyKinds.equals(CommonSet.SWX.kinds())) {
|
||||
return placeSwExecBreakAsync(expectSingleAddr(range, TraceBreakpointKind.SW_EXECUTE),
|
||||
condition, commands);
|
||||
}
|
||||
if (copyKinds.equals(TraceBreakpointKindSet.READ)) {
|
||||
if (copyKinds.equals(CommonSet.READ.kinds())) {
|
||||
return placeReadBreakAsync(range, condition, commands);
|
||||
}
|
||||
if (copyKinds.equals(TraceBreakpointKindSet.WRITE)) {
|
||||
if (copyKinds.equals(CommonSet.WRITE.kinds())) {
|
||||
return placeWriteBreakAsync(range, condition, commands);
|
||||
}
|
||||
if (copyKinds.equals(TraceBreakpointKindSet.ACCESS)) {
|
||||
if (copyKinds.equals(CommonSet.ACCESS.kinds())) {
|
||||
return placeAccessBreakAsync(range, condition, commands);
|
||||
}
|
||||
Msg.error(this, "Invalid kinds in combination: " + kinds);
|
||||
|
||||
@@ -22,9 +22,8 @@
|
||||
|
||||
<P>The first place to look when you're having trouble is the debugger's terminal. If you do not
|
||||
see one, check the <B>Window → Terminals</B> menu. If there is not one there, then there
|
||||
is no back-end debugger running — unless, perhaps, you are trying to use a Recorder-based
|
||||
target. See <A href="#plugin_conf">Plugin Configuration</A> if you suspect this is the
|
||||
case.</P>
|
||||
is no back-end debugger running. See <A href="#plugin_conf">Plugin Configuration</A> in case
|
||||
your Debugger tool is misconfigured.</P>
|
||||
|
||||
<P>If you already have the correct set of TraceRmi-based plugins enabled, but there is still no
|
||||
terminal after attempting to launch, then the launcher is sorely mis-configured, or your system
|
||||
@@ -52,9 +51,8 @@
|
||||
|
||||
<H2><A name="plugin_conf"></A>Plugin Configuration</H2>
|
||||
|
||||
<P>It is possible you have an old Debugger tool still configured for Recorder-based targets.
|
||||
Recorder-based targets are being replaced by TraceRmi-based targets. Try re-importing the
|
||||
default Debugger tool.</P>
|
||||
<P>It is possible you have an old or misconfigured Debugger tool. Try re-importing the default
|
||||
Debugger tool.</P>
|
||||
|
||||
<P>Alternatively, use <B>File → Configure</B> then click the plug <IMG alt="" src=
|
||||
"icon.extension.configure"> icon near the top right to check your tool configuration. The
|
||||
@@ -70,23 +68,6 @@
|
||||
<LI>DebuggerModelPlugin</LI>
|
||||
</UL>
|
||||
|
||||
<P>The following should be disabled:</P>
|
||||
|
||||
<UL>
|
||||
<LI>DebuggerModelServicePlugin</LI>
|
||||
|
||||
<LI>DebuggerModelServiceProxyPlugin</LI>
|
||||
|
||||
<LI>DebuggerInterpretersPlugin</LI>
|
||||
|
||||
<LI>DebuggerObjectsPlugin</LI>
|
||||
|
||||
<LI>DebuggerTargetsPlugin</LI>
|
||||
</UL>
|
||||
|
||||
<P>It is possible to leave both sets of plugins enabled, but this is by all means <EM>NOT</EM>
|
||||
recommended.</P>
|
||||
|
||||
<H2>Tutorial</H2>
|
||||
|
||||
<P>Additional troubleshooting recommendations are given in the Debugger course materials.</P>
|
||||
|
||||
@@ -88,11 +88,10 @@
|
||||
|
||||
<P>This menu is available on the dynamic listing when the target supports at least one
|
||||
breakpoint kind. This menu is always available on the static listing. It displays set
|
||||
breakpoint actions for each reasonable combination of kinds supported by the target. In the
|
||||
static listing, all reasonable combinations are available, regardless of target support;
|
||||
however, only those kinds supported by the target will be included in the resulting command.
|
||||
Selecting one of the actions will display a prompt allowing adjustments to the parameters
|
||||
before issuing the command.</P>
|
||||
breakpoint actions for each kind supported by the target. In the static listing, all kinds are
|
||||
available, regardless of target support; however, only those kinds supported by the target will
|
||||
be included in the resulting command. Selecting one of the actions will display a prompt
|
||||
allowing adjustments to the parameters before issuing the command.</P>
|
||||
|
||||
<DIV class="image">
|
||||
<IMG alt="" src="images/DebuggerPlaceBreakpointDialog.png">
|
||||
@@ -106,9 +105,9 @@
|
||||
to 1 — often the required value. For access breakpoints, this defaults to the size of
|
||||
the data at the cursor.</LI>
|
||||
|
||||
<LI>Kinds - the kind(s) of breakpoint. Only the reasonable combinations are presented, but
|
||||
the user may type any desired combination. A connected debugger may not support the desired
|
||||
combination.</LI>
|
||||
<LI>Kind - the kind of breakpoint. Only Execute (hw or sw), Read, Write, and Access are
|
||||
presented. A connected debugger may not support the requested kind, in which case it may
|
||||
substitute a similar kind or fail.</LI>
|
||||
|
||||
<LI>Name - the user-defined name of the breakpoint. The name is set on the bookmark at its
|
||||
static location, if applicable.</LI>
|
||||
|
||||
|
Before Width: | Height: | Size: 7.0 KiB After Width: | Height: | Size: 7.0 KiB |
@@ -109,8 +109,8 @@
|
||||
<LI>Length - usually 1. For access breakpoints, this is the length in bytes of the address
|
||||
range.</LI>
|
||||
|
||||
<LI>Kinds - indicates the kind(s) of breakpoint: SW_EXECUTE, HW_EXECUTE, READ, and/or
|
||||
WRITE.</LI>
|
||||
<LI>Kind - indicates the kind(s) of breakpoint: x, X, R, and/or W; respectively for software
|
||||
execute, hardware execute, read, and/or write.</LI>
|
||||
|
||||
<LI>Locations - counts the number of locations included in this logical breakpoint, applying
|
||||
the trace filter if active. Note that a logical breakpoint with 0 locations is
|
||||
|
||||
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
@@ -34,6 +34,11 @@
|
||||
current trace. If the current trace is not in any project, it saves it under "New Traces" of
|
||||
the current project.</P>
|
||||
|
||||
<H3><A name="save_trace_as"></A>Save Trace As</H3>
|
||||
|
||||
<P>This action is available whenever at least one trace is open and active. It prompts for a
|
||||
destination file in the current project and saves the current trace to it.</P>
|
||||
|
||||
<H3><A name="close_trace"></A>Close Trace</H3>
|
||||
|
||||
<P>This action is available whenever at least one trace is open and active. It closes the
|
||||
|
||||
@@ -72,6 +72,8 @@
|
||||
<UL>
|
||||
<LI>Expression - the user-modifiable Sleigh expression defining this watch.</LI>
|
||||
|
||||
<LI>Comment - a user-specified comment to describe or identify this watch.</LI>
|
||||
|
||||
<LI>Address - when evaluation succeeds, the address of the watch's value. This field is
|
||||
really only meaningful when the outermost operator of the expression is a memory dereference.
|
||||
Double-clicking this cell will navigate the primary dynamic listing to this address, if
|
||||
|
||||
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
@@ -16,7 +16,6 @@
|
||||
package ghidra.app.plugin.core.debug.gui.breakpoint;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import db.Transaction;
|
||||
import ghidra.debug.api.breakpoint.LogicalBreakpoint;
|
||||
@@ -95,15 +94,6 @@ public class BreakpointLocationRow {
|
||||
return loc.getTrace().getName();
|
||||
}
|
||||
|
||||
public String getThreads() {
|
||||
long snap = getSnap();
|
||||
return loc.getThreads(snap)
|
||||
.stream()
|
||||
.map(t -> t.getName(snap))
|
||||
.collect(Collectors.toSet())
|
||||
.toString();
|
||||
}
|
||||
|
||||
public String getComment() {
|
||||
return loc.getComment(getSnap());
|
||||
}
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -16,7 +16,8 @@
|
||||
package ghidra.app.plugin.core.debug.gui.breakpoint;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.math.BigInteger;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
@@ -34,7 +35,7 @@ import ghidra.debug.api.breakpoint.LogicalBreakpoint;
|
||||
import ghidra.debug.api.breakpoint.LogicalBreakpoint.State;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.util.ProgramLocation;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind.CommonSet;
|
||||
|
||||
public class BreakpointsDecompilerMarginProvider extends JPanel
|
||||
implements DecompilerMarginProvider, LayoutModelListener {
|
||||
@@ -131,7 +132,7 @@ public class BreakpointsDecompilerMarginProvider extends JPanel
|
||||
Set<LogicalBreakpoint> col = plugin.collectBreakpoints(locs);
|
||||
plugin.breakpointService.toggleBreakpointsAt(col, locs.get(0), () -> {
|
||||
plugin.placeBreakpointDialog.prompt(plugin.getTool(), plugin.breakpointService,
|
||||
"Set breakpoint", locs.get(0), 1, Set.of(TraceBreakpointKind.SW_EXECUTE), "");
|
||||
"Set breakpoint", locs.get(0), 1, CommonSet.SWX, "");
|
||||
// Not great, but I'm not sticking around for the dialog
|
||||
return CompletableFuture.completedFuture(Set.of());
|
||||
});
|
||||
|
||||
@@ -65,7 +65,7 @@ import ghidra.program.util.*;
|
||||
import ghidra.trace.model.Trace;
|
||||
import ghidra.trace.model.TraceLocation;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind.TraceBreakpointKindSet;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind.CommonSet;
|
||||
import ghidra.trace.model.program.TraceProgramView;
|
||||
import ghidra.util.HelpLocation;
|
||||
import ghidra.util.Msg;
|
||||
@@ -85,8 +85,7 @@ import ghidra.util.Msg;
|
||||
servicesRequired = {
|
||||
DebuggerLogicalBreakpointService.class,
|
||||
MarkerService.class,
|
||||
}
|
||||
)
|
||||
})
|
||||
public class DebuggerBreakpointMarkerPlugin extends Plugin {
|
||||
|
||||
private static final Color COLOR_BREAKPOINT_ENABLED_MARKER =
|
||||
@@ -260,20 +259,17 @@ public class DebuggerBreakpointMarkerPlugin extends Plugin {
|
||||
return getTraceFromContext(context) != null;
|
||||
}
|
||||
|
||||
protected static long computeDefaultLength(ActionContext context,
|
||||
Collection<TraceBreakpointKind> selected) {
|
||||
if (selected.isEmpty() ||
|
||||
selected.contains(TraceBreakpointKind.HW_EXECUTE) ||
|
||||
selected.contains(TraceBreakpointKind.SW_EXECUTE)) {
|
||||
protected static long computeDefaultLength(ActionContext context, CommonSet kind) {
|
||||
if (kind == null || kind == CommonSet.SWX || kind == CommonSet.HWX) {
|
||||
return 1;
|
||||
}
|
||||
return computeLengthFromContext(context);
|
||||
}
|
||||
|
||||
protected static Set<TraceBreakpointKind> computeDefaultKinds(ActionContext ctx,
|
||||
protected static CommonSet computeDefaultKind(ActionContext ctx,
|
||||
Collection<TraceBreakpointKind> supported) {
|
||||
if (supported.isEmpty()) {
|
||||
return Set.of();
|
||||
return null;
|
||||
}
|
||||
long length = computeLengthFromContext(ctx);
|
||||
if (length == 1) {
|
||||
@@ -281,27 +277,36 @@ public class DebuggerBreakpointMarkerPlugin extends Plugin {
|
||||
Listing listing = loc.getProgram().getListing();
|
||||
CodeUnit cu = listing.getCodeUnitContaining(loc.getAddress());
|
||||
if (cu instanceof Instruction) {
|
||||
// It may contain both, but prefer SWX
|
||||
if (supported.contains(TraceBreakpointKind.SW_EXECUTE)) {
|
||||
return Set.of(TraceBreakpointKind.SW_EXECUTE);
|
||||
return CommonSet.SWX;
|
||||
}
|
||||
else if (supported.contains(TraceBreakpointKind.HW_EXECUTE)) {
|
||||
return Set.of(TraceBreakpointKind.HW_EXECUTE);
|
||||
return CommonSet.HWX;
|
||||
}
|
||||
return Set.of();
|
||||
return null;
|
||||
}
|
||||
Data data = (Data) cu;
|
||||
if (!data.isDefined()) {
|
||||
if (supported.size() == 1) {
|
||||
return Set.copyOf(supported);
|
||||
for (CommonSet kind : CommonSet.VALUES) {
|
||||
if (kind.kinds().equals(supported)) {
|
||||
return kind;
|
||||
}
|
||||
}
|
||||
return Set.of();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
// TODO: Consider memory protections?
|
||||
Set<TraceBreakpointKind> result =
|
||||
new HashSet<>(Set.of(TraceBreakpointKind.READ, TraceBreakpointKind.WRITE));
|
||||
result.retainAll(supported);
|
||||
return result;
|
||||
// LATER: Consider memory protections?
|
||||
if (supported.containsAll(CommonSet.ACCESS.kinds())) {
|
||||
return CommonSet.ACCESS;
|
||||
}
|
||||
else if (supported.contains(TraceBreakpointKind.READ)) {
|
||||
return CommonSet.READ;
|
||||
}
|
||||
else if (supported.contains(TraceBreakpointKind.WRITE)) {
|
||||
return CommonSet.WRITE;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected Color colorForState(State state) {
|
||||
@@ -576,13 +581,12 @@ public class DebuggerBreakpointMarkerPlugin extends Plugin {
|
||||
protected class SetBreakpointAction extends AbstractSetBreakpointAction {
|
||||
public static final String GROUP = DebuggerResources.GROUP_BREAKPOINTS;
|
||||
|
||||
private final Set<TraceBreakpointKind> kinds;
|
||||
private final CommonSet kind;
|
||||
|
||||
public SetBreakpointAction(Set<TraceBreakpointKind> kinds) {
|
||||
public SetBreakpointAction(CommonSet kind) {
|
||||
super(DebuggerBreakpointMarkerPlugin.this);
|
||||
this.kinds = kinds;
|
||||
setPopupMenuData(new MenuData(
|
||||
new String[] { NAME, TraceBreakpointKindSet.encode(kinds) }, ICON, GROUP));
|
||||
this.kind = kind;
|
||||
setPopupMenuData(new MenuData(new String[] { NAME, kind.toString() }, ICON, GROUP));
|
||||
tool.addAction(this);
|
||||
setEnabled(true);
|
||||
}
|
||||
@@ -593,8 +597,8 @@ public class DebuggerBreakpointMarkerPlugin extends Plugin {
|
||||
return;
|
||||
}
|
||||
ProgramLocation location = getSingleLocationFromContext(context);
|
||||
long length = computeDefaultLength(context, kinds);
|
||||
placeBreakpointDialog.prompt(tool, breakpointService, NAME, location, length, kinds,
|
||||
long length = computeDefaultLength(context, kind);
|
||||
placeBreakpointDialog.prompt(tool, breakpointService, NAME, location, length, kind,
|
||||
"");
|
||||
}
|
||||
|
||||
@@ -608,7 +612,7 @@ public class DebuggerBreakpointMarkerPlugin extends Plugin {
|
||||
return true;
|
||||
}
|
||||
Set<TraceBreakpointKind> supported = getSupportedKindsFromTrace(view.getTrace());
|
||||
return supported.containsAll(kinds);
|
||||
return supported.containsAll(kind.kinds());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -754,32 +758,28 @@ public class DebuggerBreakpointMarkerPlugin extends Plugin {
|
||||
@AutoOptionDefined(
|
||||
name = DebuggerResources.OPTION_NAME_COLORS_ENABLED_BREAKPOINT_COLORING_BACKGROUND,
|
||||
description = "Whether or not to color background for memory at an enabled breakpoint",
|
||||
help = @HelpInfo(anchor = "colors")
|
||||
)
|
||||
help = @HelpInfo(anchor = "colors"))
|
||||
private boolean breakpointEnabledColoringBackground =
|
||||
DebuggerResources.DEFAULT_COLOR_ENABLED_BREAKPOINT_COLORING_BACKGROUND;
|
||||
|
||||
@AutoOptionDefined(
|
||||
name = DebuggerResources.OPTION_NAME_COLORS_DISABLED_BREAKPOINT_COLORING_BACKGROUND,
|
||||
description = "Whether or not to color background for memory at a disabled breakpoint",
|
||||
help = @HelpInfo(anchor = "colors")
|
||||
)
|
||||
help = @HelpInfo(anchor = "colors"))
|
||||
private boolean breakpointDisabledColoringBackground =
|
||||
DebuggerResources.DEFAULT_COLOR_DISABLED_BREAKPOINT_COLORING_BACKGROUND;
|
||||
|
||||
@AutoOptionDefined(
|
||||
name = DebuggerResources.OPTION_NAME_COLORS_INEFF_EN_BREAKPOINT_COLORING_BACKGROUND,
|
||||
description = "Whether or not to color background for memory at an enabled, but ineffective, breakpoint",
|
||||
help = @HelpInfo(anchor = "colors")
|
||||
)
|
||||
help = @HelpInfo(anchor = "colors"))
|
||||
private boolean breakpointIneffEnColoringBackground =
|
||||
DebuggerResources.DEFAULT_COLOR_INEFF_EN_BREAKPOINT_COLORING_BACKGROUND;
|
||||
|
||||
@AutoOptionDefined(
|
||||
name = DebuggerResources.OPTION_NAME_COLORS_INEFF_DIS_BREAKPOINT_COLORING_BACKGROUND,
|
||||
description = "Whether or not to color background for memory at an disabled, but ineffective, breakpoint",
|
||||
help = @HelpInfo(anchor = "colors")
|
||||
)
|
||||
help = @HelpInfo(anchor = "colors"))
|
||||
private boolean breakpointIneffDisColoringBackground =
|
||||
DebuggerResources.DEFAULT_COLOR_INEFF_DIS_BREAKPOINT_COLORING_BACKGROUND;
|
||||
|
||||
@@ -797,11 +797,7 @@ public class DebuggerBreakpointMarkerPlugin extends Plugin {
|
||||
new AsyncDebouncer<>(AsyncTimer.DEFAULT_TIMER, 50);
|
||||
|
||||
// package access for testing
|
||||
SetBreakpointAction actionSetSoftwareBreakpoint;
|
||||
SetBreakpointAction actionSetExecuteBreakpoint;
|
||||
SetBreakpointAction actionSetReadWriteBreakpoint;
|
||||
SetBreakpointAction actionSetReadBreakpoint;
|
||||
SetBreakpointAction actionSetWriteBreakpoint;
|
||||
Map<CommonSet, SetBreakpointAction> actionsSetBreakpoint;
|
||||
ToggleBreakpointAction actionToggleBreakpoint;
|
||||
EnableBreakpointAction actionEnableBreakpoint;
|
||||
DisableBreakpointAction actionDisableBreakpoint;
|
||||
@@ -837,8 +833,7 @@ public class DebuggerBreakpointMarkerPlugin extends Plugin {
|
||||
}
|
||||
|
||||
@AutoOptionConsumed(
|
||||
name = DebuggerResources.OPTION_NAME_COLORS_ENABLED_BREAKPOINT_COLORING_BACKGROUND
|
||||
)
|
||||
name = DebuggerResources.OPTION_NAME_COLORS_ENABLED_BREAKPOINT_COLORING_BACKGROUND)
|
||||
private void setEnabledBreakpointMarkerBackground(boolean breakpointColoringBackground) {
|
||||
for (BreakpointMarkerSets markers : markersByProgram.values()) {
|
||||
markers.setEnabledColoringBackground(breakpointColoringBackground);
|
||||
@@ -846,8 +841,7 @@ public class DebuggerBreakpointMarkerPlugin extends Plugin {
|
||||
}
|
||||
|
||||
@AutoOptionConsumed(
|
||||
name = DebuggerResources.OPTION_NAME_COLORS_DISABLED_BREAKPOINT_COLORING_BACKGROUND
|
||||
)
|
||||
name = DebuggerResources.OPTION_NAME_COLORS_DISABLED_BREAKPOINT_COLORING_BACKGROUND)
|
||||
private void setDisabledBreakpointMarkerBackground(boolean breakpointColoringBackground) {
|
||||
for (BreakpointMarkerSets markers : markersByProgram.values()) {
|
||||
markers.setDisabledColoringBackground(breakpointColoringBackground);
|
||||
@@ -855,8 +849,7 @@ public class DebuggerBreakpointMarkerPlugin extends Plugin {
|
||||
}
|
||||
|
||||
@AutoOptionConsumed(
|
||||
name = DebuggerResources.OPTION_NAME_COLORS_INEFF_EN_BREAKPOINT_COLORING_BACKGROUND
|
||||
)
|
||||
name = DebuggerResources.OPTION_NAME_COLORS_INEFF_EN_BREAKPOINT_COLORING_BACKGROUND)
|
||||
private void setIneffectiveEBreakpointMarkerBackground(boolean breakpointColoringBackground) {
|
||||
for (BreakpointMarkerSets markers : markersByProgram.values()) {
|
||||
markers.setIneffectiveEnabledColoringBackground(breakpointColoringBackground);
|
||||
@@ -864,8 +857,7 @@ public class DebuggerBreakpointMarkerPlugin extends Plugin {
|
||||
}
|
||||
|
||||
@AutoOptionConsumed(
|
||||
name = DebuggerResources.OPTION_NAME_COLORS_INEFF_DIS_BREAKPOINT_COLORING_BACKGROUND
|
||||
)
|
||||
name = DebuggerResources.OPTION_NAME_COLORS_INEFF_DIS_BREAKPOINT_COLORING_BACKGROUND)
|
||||
private void setIneffectiveDBreakpointMarkerBackground(boolean breakpointColoringBackground) {
|
||||
for (BreakpointMarkerSets markers : markersByProgram.values()) {
|
||||
markers.setIneffectiveDisabledColoringBackground(breakpointColoringBackground);
|
||||
@@ -955,7 +947,7 @@ public class DebuggerBreakpointMarkerPlugin extends Plugin {
|
||||
breakpointError(title, "It seems this target does not support breakpoints.");
|
||||
return CompletableFuture.completedFuture(Set.of());
|
||||
}
|
||||
Set<TraceBreakpointKind> kinds = computeDefaultKinds(context, supported);
|
||||
CommonSet kinds = computeDefaultKind(context, supported);
|
||||
long length = computeDefaultLength(context, kinds);
|
||||
placeBreakpointDialog.prompt(tool, breakpointService, title, loc, length, kinds,
|
||||
"");
|
||||
@@ -1085,14 +1077,8 @@ public class DebuggerBreakpointMarkerPlugin extends Plugin {
|
||||
}
|
||||
|
||||
protected void createActions() {
|
||||
actionSetSoftwareBreakpoint =
|
||||
new SetBreakpointAction(Set.of(TraceBreakpointKind.SW_EXECUTE));
|
||||
actionSetExecuteBreakpoint =
|
||||
new SetBreakpointAction(Set.of(TraceBreakpointKind.HW_EXECUTE));
|
||||
actionSetReadWriteBreakpoint =
|
||||
new SetBreakpointAction(Set.of(TraceBreakpointKind.READ, TraceBreakpointKind.WRITE));
|
||||
actionSetReadBreakpoint = new SetBreakpointAction(Set.of(TraceBreakpointKind.READ));
|
||||
actionSetWriteBreakpoint = new SetBreakpointAction(Set.of(TraceBreakpointKind.WRITE));
|
||||
actionsSetBreakpoint =
|
||||
CommonSet.VALUES.stream().collect(Collectors.toMap(s -> s, SetBreakpointAction::new));
|
||||
actionToggleBreakpoint = new ToggleBreakpointAction();
|
||||
actionEnableBreakpoint = new EnableBreakpointAction();
|
||||
actionDisableBreakpoint = new DisableBreakpointAction();
|
||||
|
||||
@@ -149,10 +149,10 @@ public class DebuggerBreakpointsProvider extends ComponentProviderAdapter
|
||||
return 60;
|
||||
}
|
||||
},
|
||||
KINDS("Kinds", String.class, LogicalBreakpointRow::getKinds) {
|
||||
KIND("Kind", String.class, LogicalBreakpointRow::getKind) {
|
||||
@Override
|
||||
public int getPreferredWidth() {
|
||||
return 150;
|
||||
return 50;
|
||||
}
|
||||
},
|
||||
LOCATIONS("Locations", Integer.class, LogicalBreakpointRow::getLocationCount) {
|
||||
@@ -276,12 +276,6 @@ public class DebuggerBreakpointsProvider extends ComponentProviderAdapter
|
||||
}
|
||||
},
|
||||
TRACE("Trace", String.class, BreakpointLocationRow::getTraceName),
|
||||
THREADS("Threads", String.class, BreakpointLocationRow::getThreads) {
|
||||
@Override
|
||||
public boolean isVisible() {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
COMMENT("Comment", String.class, BreakpointLocationRow::getComment,
|
||||
BreakpointLocationRow::setComment),
|
||||
EXPRESSION("Expression", String.class, BreakpointLocationRow::getExpression),
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -15,11 +15,6 @@
|
||||
*/
|
||||
package ghidra.app.plugin.core.debug.gui.breakpoint;
|
||||
|
||||
import static ghidra.trace.model.breakpoint.TraceBreakpointKind.*;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import javax.swing.event.DocumentEvent;
|
||||
@@ -34,8 +29,7 @@ import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.listing.Instruction;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.util.ProgramLocation;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind.TraceBreakpointKindSet;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind.CommonSet;
|
||||
import ghidra.util.MessageType;
|
||||
import ghidra.util.Swing;
|
||||
import ghidra.util.layout.PairLayout;
|
||||
@@ -45,12 +39,12 @@ public class DebuggerPlaceBreakpointDialog extends DialogComponentProvider {
|
||||
private Program program;
|
||||
private Address address;
|
||||
private long length;
|
||||
private Set<TraceBreakpointKind> kinds;
|
||||
private CommonSet kind;
|
||||
private String name;
|
||||
|
||||
private JTextField fieldAddress;
|
||||
private JTextField fieldLength;
|
||||
private JComboBox<String> fieldKinds;
|
||||
private JComboBox<CommonSet> fieldKind;
|
||||
private JTextField fieldName;
|
||||
private PluginTool tool;
|
||||
private String statusText = null;
|
||||
@@ -119,20 +113,15 @@ public class DebuggerPlaceBreakpointDialog extends DialogComponentProvider {
|
||||
panel.add(labelLength);
|
||||
panel.add(fieldLength);
|
||||
|
||||
JLabel labelKinds = new JLabel("Kinds");
|
||||
labelKinds.getAccessibleContext().setAccessibleName("Kinds");
|
||||
DefaultComboBoxModel<String> kindModel = new DefaultComboBoxModel<>();
|
||||
// TODO: Let user select whatever combo?
|
||||
kindModel.addElement(TraceBreakpointKindSet.encode(Set.of(SW_EXECUTE)));
|
||||
kindModel.addElement(TraceBreakpointKindSet.encode(Set.of(HW_EXECUTE)));
|
||||
kindModel.addElement(TraceBreakpointKindSet.encode(Set.of(READ)));
|
||||
kindModel.addElement(TraceBreakpointKindSet.encode(Set.of(WRITE)));
|
||||
kindModel.addElement(TraceBreakpointKindSet.encode(Set.of(READ, WRITE)));
|
||||
fieldKinds = new JComboBox<String>(kindModel);
|
||||
fieldKinds.setEditable(true);
|
||||
fieldKinds.getAccessibleContext().setAccessibleName("Kinds");
|
||||
panel.add(labelKinds);
|
||||
panel.add(fieldKinds);
|
||||
JLabel labelKind = new JLabel("Kind");
|
||||
labelKind.getAccessibleContext().setAccessibleName("Kind");
|
||||
DefaultComboBoxModel<CommonSet> kindModel = new DefaultComboBoxModel<>();
|
||||
kindModel.addAll(CommonSet.VALUES);
|
||||
fieldKind = new JComboBox<CommonSet>(kindModel);
|
||||
fieldKind.setEditable(false);
|
||||
fieldKind.getAccessibleContext().setAccessibleName("Kind");
|
||||
panel.add(labelKind);
|
||||
panel.add(fieldKind);
|
||||
|
||||
JLabel labelName = new JLabel("Name");
|
||||
fieldName = new JTextField();
|
||||
@@ -148,17 +137,17 @@ public class DebuggerPlaceBreakpointDialog extends DialogComponentProvider {
|
||||
}
|
||||
|
||||
public void prompt(PluginTool tool, DebuggerLogicalBreakpointService service, String title,
|
||||
ProgramLocation loc, long length, Collection<TraceBreakpointKind> kinds, String name) {
|
||||
ProgramLocation loc, long length, CommonSet kind, String name) {
|
||||
this.service = service;
|
||||
this.program = loc.getProgram();
|
||||
this.address = DebuggerLogicalBreakpointService.addressFromLocation(loc);
|
||||
this.length = length;
|
||||
this.kinds = Set.copyOf(kinds);
|
||||
this.kind = kind;
|
||||
this.name = name;
|
||||
|
||||
this.fieldAddress.setText(address.toString());
|
||||
this.fieldLength.setText(Long.toUnsignedString(length));
|
||||
this.fieldKinds.setSelectedItem(TraceBreakpointKindSet.encode(kinds));
|
||||
this.fieldKind.setSelectedItem(kind);
|
||||
this.fieldName.setText("");
|
||||
this.tool = tool;
|
||||
|
||||
@@ -182,18 +171,11 @@ public class DebuggerPlaceBreakpointDialog extends DialogComponentProvider {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
kinds = TraceBreakpointKindSet.decode((String) fieldKinds.getSelectedItem(), true);
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
setStatusText("Invalid kinds: " + e);
|
||||
return;
|
||||
}
|
||||
|
||||
kind = ((CommonSet) fieldKind.getSelectedItem());
|
||||
name = fieldName.getText();
|
||||
|
||||
ProgramLocation loc = new ProgramLocation(program, address);
|
||||
service.placeBreakpointAt(loc, length, kinds, name).exceptionally(ex -> {
|
||||
service.placeBreakpointAt(loc, length, kind.kinds(), name).exceptionally(ex -> {
|
||||
ex = AsyncUtils.unwrapThrowable(ex);
|
||||
statusText = ex.getMessage(); // will be set when dialog is shown later
|
||||
tool.showDialog(this);
|
||||
|
||||
@@ -125,7 +125,7 @@ public class LogicalBreakpointRow {
|
||||
return lb.getDomainObject();
|
||||
}
|
||||
|
||||
public String getKinds() {
|
||||
public String getKind() {
|
||||
return TraceBreakpointKindSet.encode(lb.getKinds());
|
||||
}
|
||||
|
||||
|
||||
@@ -100,21 +100,21 @@ class BreakpointTimelinePanel extends JPanel {
|
||||
private static boolean singleColumn = false;
|
||||
private static boolean showGridOutline = true;
|
||||
|
||||
private static GColor BG_COLOR = Colors.BACKGROUND;
|
||||
private static GColor GRID_COLOR = Colors.FOREGROUND_DISABLED;
|
||||
private static GColor SELECTION_COLOR =
|
||||
private static final GColor BG_COLOR = Colors.BACKGROUND;
|
||||
private static final GColor GRID_COLOR = Colors.FOREGROUND_DISABLED;
|
||||
private static final GColor SELECTION_COLOR =
|
||||
new GColor("color.debugger.plugin.breakpoint.timeline.selection");
|
||||
private static GColor HOVER_COLOR =
|
||||
private static final GColor HOVER_COLOR =
|
||||
new GColor("color.debugger.plugin.breakpoint.timeline.hover");
|
||||
private static GColor CURRENT_SNAP_COLOR =
|
||||
private static final GColor CURRENT_SNAP_COLOR =
|
||||
new GColor("color.debugger.plugin.breakpoint.timeline.current");
|
||||
private static GColor INSTRUCTION_HIT_COLOR =
|
||||
private static final GColor INSTRUCTION_HIT_COLOR =
|
||||
new GColor("color.debugger.plugin.breakpoint.timeline.type.instructions");
|
||||
private static GColor MEMORY_READ_COLOR =
|
||||
private static final GColor MEMORY_READ_COLOR =
|
||||
new GColor("color.debugger.plugin.breakpoint.timeline.type.read.memory");
|
||||
private static GColor MEMORY_WRITE_COLOR =
|
||||
private static final GColor MEMORY_WRITE_COLOR =
|
||||
new GColor("color.debugger.plugin.breakpoint.timeline.type.write.memory");
|
||||
private static Map<TraceBreakpointKind, GColor> BREAKTYPE_TO_COLOR = Map.ofEntries(
|
||||
private static final Map<TraceBreakpointKind, GColor> BREAKTYPE_TO_COLOR = Map.ofEntries(
|
||||
Map.entry(TraceBreakpointKind.HW_EXECUTE, BreakpointTimelinePanel.INSTRUCTION_HIT_COLOR),
|
||||
Map.entry(TraceBreakpointKind.SW_EXECUTE, BreakpointTimelinePanel.INSTRUCTION_HIT_COLOR),
|
||||
Map.entry(TraceBreakpointKind.READ, BreakpointTimelinePanel.MEMORY_READ_COLOR),
|
||||
|
||||
@@ -44,8 +44,7 @@ public class MappedLogicalBreakpoint implements LogicalBreakpointInternal {
|
||||
private final Map<Trace, TraceBreakpointSet> traceBreaks = new HashMap<>();
|
||||
|
||||
protected MappedLogicalBreakpoint(PluginTool tool, Program program, Address progAddr,
|
||||
long length,
|
||||
Collection<TraceBreakpointKind> kinds) {
|
||||
long length, Collection<TraceBreakpointKind> kinds) {
|
||||
this.tool = tool;
|
||||
this.kinds = Set.copyOf(kinds);
|
||||
this.length = length;
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -16,6 +16,7 @@
|
||||
package ghidra.app.plugin.core.debug.service.breakpoint;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.google.gson.*;
|
||||
|
||||
@@ -27,6 +28,7 @@ import ghidra.program.model.address.AddressSet;
|
||||
import ghidra.program.model.listing.*;
|
||||
import ghidra.program.util.ProgramLocation;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind.CommonSet;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind.TraceBreakpointKindSet;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
@@ -69,8 +71,8 @@ public class ProgramBreakpoint {
|
||||
Set<TraceBreakpointKind> result = TraceBreakpointKindSet.decode(parts[0], false);
|
||||
if (result.isEmpty()) {
|
||||
Msg.warn(TraceBreakpointKind.class,
|
||||
"Decoded empty set of kinds from bookmark. Assuming SW_EXECUTE");
|
||||
return Set.of(TraceBreakpointKind.SW_EXECUTE);
|
||||
"Decoded empty set of kinds from bookmark. Assuming %s".formatted(CommonSet.SWX));
|
||||
return CommonSet.SWX.kinds();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -435,6 +437,21 @@ public class ProgramBreakpoint {
|
||||
return TraceBreakpointKindSet.encode(kinds) + ";" + Long.toUnsignedString(length);
|
||||
}
|
||||
|
||||
/**
|
||||
* In case a program database with pre-Ghidra-12.2 breakpoint bookmarks comes along (this will
|
||||
* happen for a while), we want to ensure the old encodings are deleted when the breakpoint is
|
||||
* toggled. While we'd normally strive for perfect backward compatibility, it's not as important
|
||||
* for breakpoints here. If this function is to be removed later (it probably should be), we can
|
||||
* either: 1) ensure there's some upgrade process, on import or via a script; or 2) just
|
||||
* instruct users on a case-by-case basis to delete the old breakpoints.
|
||||
*
|
||||
* @return the bookmark category for encoding the breakpoint kinds in versions prior to 12.2.
|
||||
*/
|
||||
protected String computeCategory_Pre12Dot2() {
|
||||
return kinds.stream().map(k -> k.name()).collect(Collectors.joining(",")) + ";" +
|
||||
Long.toUnsignedString(length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the state of this breakpoint by manipulating bookmarks
|
||||
*
|
||||
@@ -458,9 +475,12 @@ public class ProgramBreakpoint {
|
||||
try (Transaction tx = program.openTransaction("Toggle breakpoint")) {
|
||||
BookmarkManager manager = program.getBookmarkManager();
|
||||
String catStr = computeCategory();
|
||||
String catStr_Pre12Dot2 = computeCategory_Pre12Dot2();
|
||||
manager.setBookmark(address, addType, catStr, comment);
|
||||
manager.removeBookmarks(new AddressSet(address), delType, catStr,
|
||||
TaskMonitor.DUMMY);
|
||||
manager.removeBookmarks(new AddressSet(address), delType, catStr_Pre12Dot2,
|
||||
TaskMonitor.DUMMY);
|
||||
}
|
||||
catch (CancelledException e) {
|
||||
throw new AssertionError(e);
|
||||
|
||||
@@ -66,6 +66,7 @@ import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.util.ProgramLocation;
|
||||
import ghidra.trace.model.*;
|
||||
import ghidra.trace.model.breakpoint.*;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind.CommonSet;
|
||||
import ghidra.trace.model.guest.TracePlatform;
|
||||
import ghidra.trace.model.program.TraceProgramView;
|
||||
import ghidra.trace.model.thread.TraceThread;
|
||||
@@ -664,12 +665,8 @@ public class DebuggerEmulationServicePlugin extends Plugin implements DebuggerEm
|
||||
continue;
|
||||
}
|
||||
Set<TraceBreakpointKind> kinds = bpt.getKinds(snap);
|
||||
boolean isExecute =
|
||||
kinds.contains(TraceBreakpointKind.HW_EXECUTE) ||
|
||||
kinds.contains(TraceBreakpointKind.SW_EXECUTE);
|
||||
boolean isRead = kinds.contains(TraceBreakpointKind.READ);
|
||||
boolean isWrite = kinds.contains(TraceBreakpointKind.WRITE);
|
||||
if (isExecute) {
|
||||
if (kinds.contains(TraceBreakpointKind.HW_EXECUTE) ||
|
||||
kinds.contains(TraceBreakpointKind.SW_EXECUTE)) {
|
||||
Address minAddress = bpt.getMinAddress(snap);
|
||||
try {
|
||||
emu.inject(minAddress, bpt.getEmuSleigh(snap));
|
||||
@@ -679,13 +676,13 @@ public class DebuggerEmulationServicePlugin extends Plugin implements DebuggerEm
|
||||
emu.inject(minAddress, "emu_injection_err();");
|
||||
}
|
||||
}
|
||||
if (isRead && isWrite) {
|
||||
if (kinds.equals(CommonSet.ACCESS.kinds())) {
|
||||
emu.addAccessBreakpoint(bpt.getRange(snap), AccessKind.RW);
|
||||
}
|
||||
else if (isRead) {
|
||||
else if (kinds.equals(CommonSet.READ.kinds())) {
|
||||
emu.addAccessBreakpoint(bpt.getRange(snap), AccessKind.R);
|
||||
}
|
||||
else if (isWrite) {
|
||||
else if (kinds.equals(CommonSet.WRITE.kinds())) {
|
||||
emu.addAccessBreakpoint(bpt.getRange(snap), AccessKind.W);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ import ghidra.program.model.pcode.*;
|
||||
import ghidra.program.util.*;
|
||||
import ghidra.trace.model.Lifespan;
|
||||
import ghidra.trace.model.TraceAddressSnapRange;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind.CommonSet;
|
||||
import ghidra.trace.model.property.*;
|
||||
import ghidra.util.HelpLocation;
|
||||
import ghidra.util.Msg;
|
||||
@@ -55,8 +55,8 @@ import sarif.export.WrappedLogicalLocation;
|
||||
import sarif.managers.SarifMgr;
|
||||
|
||||
/**
|
||||
* Container for all the decompiler elements the users "selects" via the menu.
|
||||
* This data is used to build queries.
|
||||
* Container for all the decompiler elements the users "selects" via the menu. This data is used to
|
||||
* build queries.
|
||||
*/
|
||||
public class EmulatorTaintState extends AbstractTaintState {
|
||||
|
||||
@@ -164,8 +164,8 @@ public class EmulatorTaintState extends AbstractTaintState {
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the query string, save it to a file the users selects, and run the
|
||||
* engine using the index and the query that is saved to the file.
|
||||
* Build the query string, save it to a file the users selects, and run the engine using the
|
||||
* index and the query that is saved to the file.
|
||||
*/
|
||||
@Override
|
||||
public boolean queryIndex(Program program, PluginTool tool, QueryType queryType) {
|
||||
@@ -219,8 +219,7 @@ public class EmulatorTaintState extends AbstractTaintState {
|
||||
|
||||
private void injectTaint(Address target, String sleigh) {
|
||||
PlaceEmuBreakpointActionItem item = new PlaceEmuBreakpointActionItem(current.getTrace(),
|
||||
current.getSnap(), target, 1, Set.of(TraceBreakpointKind.SW_EXECUTE),
|
||||
sleigh);
|
||||
current.getSnap(), target, 1, CommonSet.SWX.kinds(), sleigh);
|
||||
item.execute();
|
||||
}
|
||||
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package ghidra.app.plugin.core.debug.gui.memview;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.*;
|
||||
@@ -29,7 +28,7 @@ import ghidra.program.model.listing.Program;
|
||||
import ghidra.test.ToyProgramBuilder;
|
||||
import ghidra.trace.database.ToyDBTraceBuilder;
|
||||
import ghidra.trace.model.Lifespan;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind.CommonSet;
|
||||
import ghidra.trace.model.memory.TraceMemoryFlag;
|
||||
import ghidra.trace.model.thread.TraceThread;
|
||||
import help.screenshot.GhidraScreenShotGenerator;
|
||||
@@ -109,13 +108,9 @@ public class DebuggerMemviewPluginScreenShots extends GhidraScreenShotGenerator
|
||||
}
|
||||
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
Set<TraceThread> threads = new HashSet<TraceThread>();
|
||||
Set<TraceBreakpointKind> kinds = new HashSet<TraceBreakpointKind>();
|
||||
threads.add(thread1);
|
||||
kinds.add(TraceBreakpointKind.HW_EXECUTE);
|
||||
tb.trace.getBreakpointManager()
|
||||
.addBreakpoint("bpt1", Lifespan.span(17, 25), tb.range(0x7fac1234, 0x7fc1238),
|
||||
threads, kinds, true, "break here");
|
||||
Set.of(thread1), CommonSet.HWX.kinds(), true, "break here");
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -22,11 +22,12 @@ import org.junit.*;
|
||||
import db.Transaction;
|
||||
import ghidra.app.plugin.core.debug.service.tracemgr.DebuggerTraceManagerServicePlugin;
|
||||
import ghidra.app.services.DebuggerTraceManagerService;
|
||||
import ghidra.program.model.data.PointerDataType;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.lang.Language;
|
||||
import ghidra.program.model.lang.RegisterValue;
|
||||
import ghidra.test.ToyProgramBuilder;
|
||||
import ghidra.trace.database.ToyDBTraceBuilder;
|
||||
import ghidra.trace.database.ToyDBTraceBuilder.ToySchemaBuilder;
|
||||
import ghidra.trace.model.Lifespan;
|
||||
import ghidra.trace.model.memory.TraceMemorySpace;
|
||||
import ghidra.trace.model.thread.TraceThread;
|
||||
@@ -57,10 +58,15 @@ public class DebuggerRegistersPluginScreenShots extends GhidraScreenShotGenerato
|
||||
@Test
|
||||
public void testCaptureDebuggerRegistersPlugin() throws Throwable {
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.createRootObject(new ToySchemaBuilder()
|
||||
.useRegistersPerThread()
|
||||
.noRegisterGroups()
|
||||
.build());
|
||||
long snap0 = tb.trace.getTimeManager().createSnapshot("First").getKey();
|
||||
long snap1 = tb.trace.getTimeManager().createSnapshot("Second").getKey();
|
||||
|
||||
TraceThread thread = tb.getOrAddThread("[1]", snap0);
|
||||
TraceThread thread = tb.getOrAddThread("Targets[1].Threads[1]", snap0);
|
||||
tb.createObjectsRegsForThread(thread, Lifespan.nowOn(snap0), tb.host);
|
||||
TraceMemorySpace regs =
|
||||
tb.trace.getMemoryManager().getMemoryRegisterSpace(thread, true);
|
||||
Language lang = tb.trace.getBaseLanguage();
|
||||
@@ -90,11 +96,16 @@ public class DebuggerRegistersPluginScreenShots extends GhidraScreenShotGenerato
|
||||
regs.setValue(snap1,
|
||||
new RegisterValue(lang.getRegister("RDX"), BigInteger.valueOf(0x80)));
|
||||
|
||||
TypeDef pointerRam = tb.trace.getBaseDataTypeManager()
|
||||
.resolveType(PointerDataType.dataType.typedefBuilder()
|
||||
.addressSpace(tb.language.getDefaultDataSpace())
|
||||
.build(),
|
||||
DataTypeConflictHandler.DEFAULT_HANDLER);
|
||||
|
||||
tb.trace.getCodeManager()
|
||||
.getCodeRegisterSpace(thread, true)
|
||||
.definedData()
|
||||
.create(Lifespan.nowOn(snap0), lang.getRegister("RIP"),
|
||||
PointerDataType.dataType);
|
||||
.create(Lifespan.nowOn(snap0), lang.getRegister("RIP"), pointerRam);
|
||||
|
||||
traceManager.openTrace(tb.trace);
|
||||
traceManager.activateThread(thread);
|
||||
|
||||
@@ -60,7 +60,7 @@ import ghidra.trace.database.ToyDBTraceBuilder;
|
||||
import ghidra.trace.database.target.DBTraceObjectManager;
|
||||
import ghidra.trace.model.DefaultTraceLocation;
|
||||
import ghidra.trace.model.Lifespan;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind.CommonSet;
|
||||
import ghidra.trace.model.stack.TraceStack;
|
||||
import ghidra.trace.model.stack.TraceStackFrame;
|
||||
import ghidra.trace.model.target.schema.SchemaContext;
|
||||
@@ -125,11 +125,11 @@ public class DebuggerStackPluginScreenShots extends GhidraScreenShotGenerator
|
||||
.createInitializedBlock(".text", addr(program, 0x00400000), 0x10000, (byte) 0,
|
||||
TaskMonitor.DUMMY, false);
|
||||
FunctionManager fMan = program.getFunctionManager();
|
||||
fMan.createFunction("FUN_00401000", addr(0x00401000),
|
||||
fMan.createFunction("FUN_00401000", addr(program, 0x00401000),
|
||||
set(program, 0x00401000, 0x00401100), SourceType.USER_DEFINED);
|
||||
fMan.createFunction("FUN_00401200", addr(0x00401200),
|
||||
fMan.createFunction("FUN_00401200", addr(program, 0x00401200),
|
||||
set(program, 0x00401200, 0x00401300), SourceType.USER_DEFINED);
|
||||
fMan.createFunction("FUN_00404300", addr(0x00404300),
|
||||
fMan.createFunction("FUN_00404300", addr(program, 0x00404300),
|
||||
set(program, 0x00404300, 0x00404400), SourceType.USER_DEFINED);
|
||||
}
|
||||
|
||||
@@ -328,8 +328,7 @@ public class DebuggerStackPluginScreenShots extends GhidraScreenShotGenerator
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.trace.getBreakpointManager()
|
||||
.addBreakpoint("Breakpoints[0]", Lifespan.nowOn(0), retInstr,
|
||||
Set.of(),
|
||||
Set.of(TraceBreakpointKind.SW_EXECUTE), true, "unwind stack");
|
||||
Set.of(), CommonSet.SWX.kinds(), true, "unwind stack");
|
||||
}
|
||||
|
||||
EmulationResult result = emuService.run(atSetup.getPlatform(), atSetup.getTime(), monitor,
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -67,7 +67,7 @@ import ghidra.program.model.symbol.SourceType;
|
||||
import ghidra.program.util.GhidraProgramUtilities;
|
||||
import ghidra.trace.database.ToyDBTraceBuilder;
|
||||
import ghidra.trace.model.Lifespan;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind.CommonSet;
|
||||
import ghidra.trace.model.thread.TraceThread;
|
||||
import ghidra.trace.model.time.schedule.Scheduler;
|
||||
import ghidra.util.InvalidNameException;
|
||||
@@ -276,8 +276,7 @@ public class VariableValueHoverPluginScreenShots extends GhidraScreenShotGenerat
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.trace.getBreakpointManager()
|
||||
.addBreakpoint("Breakpoints[0]", Lifespan.nowOn(0), retInstr,
|
||||
Set.of(),
|
||||
Set.of(TraceBreakpointKind.SW_EXECUTE), true, "unwind stack");
|
||||
Set.of(), CommonSet.SWX.kinds(), true, "unwind stack");
|
||||
}
|
||||
|
||||
EmulationResult result = emuService.run(atSetup.getPlatform(), atSetup.getTime(), monitor,
|
||||
|
||||
@@ -27,6 +27,8 @@ import ghidra.program.model.data.LongDataType;
|
||||
import ghidra.program.model.symbol.SourceType;
|
||||
import ghidra.test.ToyProgramBuilder;
|
||||
import ghidra.trace.database.ToyDBTraceBuilder;
|
||||
import ghidra.trace.database.ToyDBTraceBuilder.ToySchemaBuilder;
|
||||
import ghidra.trace.model.Lifespan;
|
||||
import ghidra.trace.model.thread.TraceThread;
|
||||
import help.screenshot.GhidraScreenShotGenerator;
|
||||
|
||||
@@ -57,6 +59,10 @@ public class DebuggerWatchesPluginScreenShots extends GhidraScreenShotGenerator
|
||||
TraceThread thread;
|
||||
long snap0, snap1;
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.createRootObject(new ToySchemaBuilder()
|
||||
.useRegistersPerThread()
|
||||
.noRegisterGroups()
|
||||
.build());
|
||||
snap0 = tb.trace.getTimeManager().createSnapshot("First").getKey();
|
||||
snap1 = tb.trace.getTimeManager().createSnapshot("Second").getKey();
|
||||
|
||||
@@ -65,7 +71,8 @@ public class DebuggerWatchesPluginScreenShots extends GhidraScreenShotGenerator
|
||||
.create(snap1, tb.addr(0x7fff0004), "fiveUp",
|
||||
tb.trace.getSymbolManager().getGlobalNamespace(), SourceType.USER_DEFINED);
|
||||
|
||||
thread = tb.getOrAddThread("[1]", snap0);
|
||||
thread = tb.getOrAddThread("Targets[1].Threads[1]", snap0);
|
||||
tb.createObjectsRegsForThread(thread, Lifespan.nowOn(snap0), tb.host);
|
||||
|
||||
PcodeExecutor<byte[]> executor0 =
|
||||
TraceSleighUtils.buildByteExecutor(tb.trace, snap0, thread, 0);
|
||||
|
||||
@@ -45,7 +45,7 @@ import ghidra.trace.database.memory.DBTraceMemoryManager;
|
||||
import ghidra.trace.database.program.DBTraceVariableSnapProgramView;
|
||||
import ghidra.trace.database.symbol.*;
|
||||
import ghidra.trace.model.Lifespan;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind.CommonSet;
|
||||
import ghidra.trace.model.memory.TraceMemoryFlag;
|
||||
import ghidra.trace.model.memory.TraceMemoryState;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
@@ -559,9 +559,9 @@ public class DebuggerCopyPlanTest extends AbstractGhidraHeadedDebuggerTest {
|
||||
|
||||
DBTraceBreakpointManager breakpoints = tb.trace.getBreakpointManager();
|
||||
breakpoints.placeBreakpoint("Breakpoints[1]", 0, tb.addr(0x55550123), List.of(),
|
||||
Set.of(TraceBreakpointKind.SW_EXECUTE), true, "Test-1");
|
||||
CommonSet.SWX.kinds(), true, "Test-1");
|
||||
breakpoints.placeBreakpoint("Breakpoints[2]", 0, tb.addr(0x55550321), List.of(),
|
||||
Set.of(TraceBreakpointKind.SW_EXECUTE), false, "Test-2");
|
||||
CommonSet.SWX.kinds(), false, "Test-2");
|
||||
}
|
||||
|
||||
Address paddr = tb.addr(stSpace, 0x55550000);
|
||||
@@ -571,8 +571,7 @@ public class DebuggerCopyPlanTest extends AbstractGhidraHeadedDebuggerTest {
|
||||
false);
|
||||
// Set up a collision. This is normal with relocations
|
||||
program.getBookmarkManager()
|
||||
.setBookmark(tb.addr(stSpace, 0x55550123), "BreakpointDisabled", "SW_EXECUTE;1",
|
||||
"");
|
||||
.setBookmark(tb.addr(stSpace, 0x55550123), "BreakpointDisabled", "x;1", "");
|
||||
|
||||
AllCopiers.BREAKPOINTS.copy(view, tb.range(0x55550000, 0x5555ffff), program, paddr,
|
||||
TaskMonitor.DUMMY);
|
||||
@@ -588,12 +587,12 @@ public class DebuggerCopyPlanTest extends AbstractGhidraHeadedDebuggerTest {
|
||||
bm = bookmarks.get(0);
|
||||
assertEquals(tb.addr(stSpace, 0x55550123), bm.getAddress());
|
||||
assertEquals("BreakpointEnabled", bm.getTypeString());
|
||||
assertEquals("SW_EXECUTE;1", bm.getCategory());
|
||||
assertEquals("x;1", bm.getCategory());
|
||||
|
||||
bm = bookmarks.get(1);
|
||||
assertEquals(tb.addr(stSpace, 0x55550321), bm.getAddress());
|
||||
assertEquals("BreakpointDisabled", bm.getTypeString());
|
||||
assertEquals("SW_EXECUTE;1", bm.getCategory());
|
||||
assertEquals("x;1", bm.getCategory());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -54,7 +54,7 @@ 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.TraceBreakpointKind;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind.CommonSet;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointLocation;
|
||||
import ghidra.trace.model.guest.TracePlatform;
|
||||
import ghidra.trace.model.memory.TraceMemoryManager;
|
||||
@@ -448,7 +448,7 @@ public class DebuggerEmulationServiceTest extends AbstractGhidraHeadedDebuggerTe
|
||||
try (Transaction tx = trace.openTransaction("Add breakpoint")) {
|
||||
trace.getBreakpointManager()
|
||||
.addBreakpoint("Breakpoints[0]", Lifespan.nowOn(0), addrI2, Set.of(thread),
|
||||
Set.of(TraceBreakpointKind.SW_EXECUTE), true, "test");
|
||||
CommonSet.SWX.kinds(), true, "test");
|
||||
}
|
||||
|
||||
EmulationResult result = emulationPlugin.run(trace.getPlatformManager().getHostPlatform(),
|
||||
@@ -506,10 +506,10 @@ public class DebuggerEmulationServiceTest extends AbstractGhidraHeadedDebuggerTe
|
||||
try (Transaction tx = trace.openTransaction("Add breakpoint")) {
|
||||
trace.getBreakpointManager()
|
||||
.addBreakpoint("Breakpoints[0]", Lifespan.nowOn(0), addrText, Set.of(thread),
|
||||
Set.of(TraceBreakpointKind.SW_EXECUTE), true, "test");
|
||||
CommonSet.SWX.kinds(), true, "test");
|
||||
TraceBreakpointLocation tb = trace.getBreakpointManager()
|
||||
.addBreakpoint("Breakpoints[1]", Lifespan.nowOn(0), addrI1, Set.of(thread),
|
||||
Set.of(TraceBreakpointKind.SW_EXECUTE), true, "test");
|
||||
CommonSet.SWX.kinds(), true, "test");
|
||||
// Force "partial instruction"
|
||||
tb.setEmuSleigh(0, """
|
||||
r1 = 0xbeef;
|
||||
@@ -518,7 +518,7 @@ public class DebuggerEmulationServiceTest extends AbstractGhidraHeadedDebuggerTe
|
||||
""");
|
||||
trace.getBreakpointManager()
|
||||
.addBreakpoint("Breakpoints[2]", Lifespan.nowOn(0), addrI2, Set.of(thread),
|
||||
Set.of(TraceBreakpointKind.SW_EXECUTE), true, "test");
|
||||
CommonSet.SWX.kinds(), true, "test");
|
||||
}
|
||||
|
||||
assertEquals(0, emulationPlugin.cache.size());
|
||||
@@ -580,10 +580,10 @@ public class DebuggerEmulationServiceTest extends AbstractGhidraHeadedDebuggerTe
|
||||
try (Transaction tx = trace.openTransaction("Add breakpoint")) {
|
||||
trace.getBreakpointManager()
|
||||
.addBreakpoint("Breakpoints[0]", Lifespan.nowOn(0), addrText, Set.of(thread),
|
||||
Set.of(TraceBreakpointKind.SW_EXECUTE), true, "test");
|
||||
CommonSet.SWX.kinds(), true, "test");
|
||||
TraceBreakpointLocation tb = trace.getBreakpointManager()
|
||||
.addBreakpoint("Breakpoints[1]", Lifespan.nowOn(0), addrI1, Set.of(thread),
|
||||
Set.of(TraceBreakpointKind.SW_EXECUTE), true, "test");
|
||||
CommonSet.SWX.kinds(), true, "test");
|
||||
// Force "partial instruction"
|
||||
tb.setEmuSleigh(0, """
|
||||
r1 = 0xbeef;
|
||||
@@ -649,7 +649,7 @@ public class DebuggerEmulationServiceTest extends AbstractGhidraHeadedDebuggerTe
|
||||
try (Transaction tx = trace.openTransaction("Add breakpoint")) {
|
||||
TraceBreakpointLocation tb = trace.getBreakpointManager()
|
||||
.addBreakpoint("Breakpoints[1]", Lifespan.nowOn(0), addrI1, Set.of(thread),
|
||||
Set.of(TraceBreakpointKind.SW_EXECUTE), true, "test");
|
||||
CommonSet.SWX.kinds(), true, "test");
|
||||
// Force "partial instruction"
|
||||
tb.setEmuSleigh(0, """
|
||||
r1 = 0xbeef;
|
||||
@@ -724,7 +724,7 @@ public class DebuggerEmulationServiceTest extends AbstractGhidraHeadedDebuggerTe
|
||||
try (Transaction tx = trace.openTransaction("Add breakpoint")) {
|
||||
TraceBreakpointLocation tb = trace.getBreakpointManager()
|
||||
.addBreakpoint("Breakpoints[0]", Lifespan.nowOn(0), addrI2, Set.of(thread),
|
||||
Set.of(TraceBreakpointKind.SW_EXECUTE), true, "test");
|
||||
CommonSet.SWX.kinds(), true, "test");
|
||||
tb.setEmuSleigh(0, """
|
||||
r1 = 0x5678;
|
||||
emu_swi();
|
||||
@@ -791,7 +791,7 @@ public class DebuggerEmulationServiceTest extends AbstractGhidraHeadedDebuggerTe
|
||||
try (Transaction tx = trace.openTransaction("Add breakpoint")) {
|
||||
trace.getBreakpointManager()
|
||||
.addBreakpoint("Breakpoints[0]", Lifespan.nowOn(0), addr(trace, 0x1234),
|
||||
Set.of(thread), Set.of(TraceBreakpointKind.READ), true, "test");
|
||||
Set.of(thread), CommonSet.READ.kinds(), true, "test");
|
||||
}
|
||||
|
||||
EmulationResult result = emulationPlugin.run(trace.getPlatformManager().getHostPlatform(),
|
||||
@@ -869,7 +869,7 @@ public class DebuggerEmulationServiceTest extends AbstractGhidraHeadedDebuggerTe
|
||||
try (Transaction tx = trace.openTransaction("Add breakpoint")) {
|
||||
TraceBreakpointLocation tb = trace.getBreakpointManager()
|
||||
.addBreakpoint("Breakpoints[0]", Lifespan.nowOn(0), addrI2, Set.of(thread),
|
||||
Set.of(TraceBreakpointKind.SW_EXECUTE), true, "test");
|
||||
CommonSet.SWX.kinds(), true, "test");
|
||||
tb.setEmuSleigh(0, """
|
||||
r1 = 0x5678;
|
||||
emu_exec_decoded();
|
||||
|
||||
@@ -80,7 +80,7 @@ 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.TraceBreakpointKind;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind.CommonSet;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointLocation;
|
||||
import ghidra.trace.model.listing.TraceData;
|
||||
import ghidra.trace.model.memory.TraceMemorySpace;
|
||||
@@ -831,7 +831,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest {
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.trace.getBreakpointManager()
|
||||
.addBreakpoint("Breakpoints[0]", Lifespan.nowOn(0), retInstr, Set.of(),
|
||||
Set.of(TraceBreakpointKind.SW_EXECUTE), true, "capture return value");
|
||||
CommonSet.SWX.kinds(), true, "capture return value");
|
||||
}
|
||||
|
||||
EmulationResult result = emuService.run(atSetup.getPlatform(), atSetup.getTime(), monitor,
|
||||
@@ -892,10 +892,10 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest {
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
bptUnwind = tb.trace.getBreakpointManager()
|
||||
.addBreakpoint("Breakpoints[0]", Lifespan.nowOn(0), retInstr, Set.of(),
|
||||
Set.of(TraceBreakpointKind.SW_EXECUTE), true, "unwind stack");
|
||||
CommonSet.SWX.kinds(), true, "unwind stack");
|
||||
tb.trace.getBreakpointManager()
|
||||
.addBreakpoint("Breakpoints[1]", Lifespan.nowOn(0), tb.addr(0xdeadbeef),
|
||||
Set.of(), Set.of(TraceBreakpointKind.SW_EXECUTE), true,
|
||||
Set.of(), CommonSet.SWX.kinds(), true,
|
||||
"capture return value");
|
||||
}
|
||||
|
||||
@@ -980,7 +980,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest {
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
bptUnwind = tb.trace.getBreakpointManager()
|
||||
.addBreakpoint("Breakpoints[0]", Lifespan.nowOn(0), entry, Set.of(),
|
||||
Set.of(TraceBreakpointKind.SW_EXECUTE), true, "unwind stack");
|
||||
CommonSet.SWX.kinds(), true, "unwind stack");
|
||||
bptUnwind.setEmuSleigh(0, """
|
||||
if (%s >= 0x%x) goto <skip>;
|
||||
emu_swi();
|
||||
@@ -1121,7 +1121,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest {
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.trace.getBreakpointManager()
|
||||
.addBreakpoint("Breakpoints[0]", Lifespan.nowOn(0), retInstr, Set.of(),
|
||||
Set.of(TraceBreakpointKind.SW_EXECUTE), true, "unwind stack");
|
||||
CommonSet.SWX.kinds(), true, "unwind stack");
|
||||
}
|
||||
|
||||
EmulationResult result = emuService.run(atSetup.getPlatform(), atSetup.getTime(), monitor,
|
||||
@@ -1161,7 +1161,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest {
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.trace.getBreakpointManager()
|
||||
.addBreakpoint("Breakpoints[0]", Lifespan.nowOn(0), retInstr, Set.of(),
|
||||
Set.of(TraceBreakpointKind.SW_EXECUTE), true, "unwind stack");
|
||||
CommonSet.SWX.kinds(), true, "unwind stack");
|
||||
}
|
||||
|
||||
DebuggerCoordinates atSetup = traceManager.getCurrent();
|
||||
@@ -1202,7 +1202,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest {
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.trace.getBreakpointManager()
|
||||
.addBreakpoint("Breakpoints[0]", Lifespan.nowOn(0), retInstr, Set.of(),
|
||||
Set.of(TraceBreakpointKind.SW_EXECUTE), true, "unwind stack");
|
||||
CommonSet.SWX.kinds(), true, "unwind stack");
|
||||
}
|
||||
|
||||
DebuggerCoordinates atSetup = traceManager.getCurrent();
|
||||
@@ -1243,7 +1243,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest {
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.trace.getBreakpointManager()
|
||||
.addBreakpoint("Breakpoints[0]", Lifespan.nowOn(0), retInstr, Set.of(),
|
||||
Set.of(TraceBreakpointKind.SW_EXECUTE), true, "unwind stack");
|
||||
CommonSet.SWX.kinds(), true, "unwind stack");
|
||||
}
|
||||
|
||||
DebuggerCoordinates atSetup = traceManager.getCurrent();
|
||||
|
||||
@@ -96,8 +96,6 @@ public class DBTraceBreakpointSpec implements TraceBreakpointSpec, DBTraceObject
|
||||
|
||||
@Override
|
||||
public void setKinds(Lifespan lifespan, Collection<TraceBreakpointKind> kinds) {
|
||||
// TODO: More efficient encoding
|
||||
// TODO: Target-Trace mapping is implied by encoded name. Seems bad.
|
||||
try (LockHold hold = object.getTrace().lockWrite()) {
|
||||
object.setValue(lifespan, KEY_KINDS, TraceBreakpointKindSet.encode(kinds));
|
||||
this.kinds = TraceBreakpointKindSet.copyOf(kinds);
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -32,20 +32,16 @@ import org.apache.commons.collections4.set.AbstractSetDecorator;
|
||||
* open us up to database breaks if the common enum changes.
|
||||
*/
|
||||
public enum TraceBreakpointKind {
|
||||
READ(1 << 0),
|
||||
WRITE(1 << 1),
|
||||
HW_EXECUTE(1 << 2),
|
||||
SW_EXECUTE(1 << 3);
|
||||
READ('R'),
|
||||
WRITE('W'),
|
||||
HW_EXECUTE('X'),
|
||||
SW_EXECUTE('x');
|
||||
|
||||
public static final int COUNT = values().length;
|
||||
public static final List<TraceBreakpointKind> VALUES = List.of(values());
|
||||
public static final int COUNT = VALUES.size();
|
||||
|
||||
public static class TraceBreakpointKindSet extends AbstractSetDecorator<TraceBreakpointKind> {
|
||||
public static final TraceBreakpointKindSet SW_EXECUTE = of(TraceBreakpointKind.SW_EXECUTE);
|
||||
public static final TraceBreakpointKindSet HW_EXECUTE = of(TraceBreakpointKind.HW_EXECUTE);
|
||||
public static final TraceBreakpointKindSet READ = of(TraceBreakpointKind.READ);
|
||||
public static final TraceBreakpointKindSet WRITE = of(TraceBreakpointKind.WRITE);
|
||||
public static final TraceBreakpointKindSet ACCESS =
|
||||
of(TraceBreakpointKind.READ, TraceBreakpointKind.WRITE);
|
||||
public static final TraceBreakpointKindSet EMPTY = TraceBreakpointKindSet.of();
|
||||
|
||||
public static TraceBreakpointKindSet of(TraceBreakpointKind... kinds) {
|
||||
return new TraceBreakpointKindSet(Set.of(kinds));
|
||||
@@ -56,29 +52,60 @@ public enum TraceBreakpointKind {
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a comma-separated list of kind names to a set of kinds.
|
||||
* Convert a string of flags to a set of kinds.
|
||||
* <p>
|
||||
* For backwards compatibility, this can also accept a comma-separated list of kind names.
|
||||
* The backwards compatibility will eventually be removed. In the meantime, no string can
|
||||
* exceed 3 flags, as this has to be able to distinguish which encoding to decode, and the
|
||||
* shortest name is {@link #READ}.
|
||||
*
|
||||
* @param encoded the encoded list
|
||||
* @param strict true to report unrecognized kinds, false to ignore
|
||||
* @return the decoded set
|
||||
*/
|
||||
public static TraceBreakpointKindSet decode(String encoded, boolean strict) {
|
||||
Set<TraceBreakpointKind> result = EnumSet.noneOf(TraceBreakpointKind.class);
|
||||
Set<String> names = new HashSet<>(Set.of(encoded.toUpperCase().split(",")));
|
||||
for (TraceBreakpointKind k : values()) {
|
||||
if (names.remove(k.name())) {
|
||||
result.add(k);
|
||||
}
|
||||
TraceBreakpointKindSet simple = switch (encoded) {
|
||||
case "" -> EMPTY;
|
||||
case "x", "SW_EXECUTE" -> CommonSet.SWX.kinds();
|
||||
case "X", "HW_EXECUTE" -> CommonSet.HWX.kinds();
|
||||
case "R", "READ" -> CommonSet.READ.kinds();
|
||||
case "W", "WRITE" -> CommonSet.WRITE.kinds();
|
||||
case "RW", "READ,WRITE", "WRITE,READ" -> CommonSet.ACCESS.kinds();
|
||||
default -> null;
|
||||
};
|
||||
if (simple != null) {
|
||||
return simple;
|
||||
}
|
||||
if (strict && !names.isEmpty()) {
|
||||
throw new IllegalArgumentException(names.toString());
|
||||
/**
|
||||
* Distinguishes 3-flag encoding from shortest comma-names encoding. No sane system
|
||||
* should apply all 4 flags, which would confuse this check.
|
||||
*/
|
||||
Set<TraceBreakpointKind> result = EnumSet.noneOf(TraceBreakpointKind.class);
|
||||
if (encoded.length() < 4) {
|
||||
for (TraceBreakpointKind k : VALUES) {
|
||||
if (encoded.contains(k.flagStr)) {
|
||||
result.add(k);
|
||||
}
|
||||
}
|
||||
// I kind of don't care about "strict" anymore
|
||||
}
|
||||
else {
|
||||
Set<String> names = new HashSet<>(Set.of(encoded.toUpperCase().split(",")));
|
||||
for (TraceBreakpointKind k : VALUES) {
|
||||
if (names.remove(k.name())) {
|
||||
result.add(k);
|
||||
}
|
||||
}
|
||||
if (strict && !names.isEmpty()) {
|
||||
throw new IllegalArgumentException(names.toString());
|
||||
}
|
||||
}
|
||||
return new TraceBreakpointKindSet(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a set (or collection) of kinds to a comma-separated list of names.
|
||||
*
|
||||
* Convert a set (or collection) of kinds to a string of flags
|
||||
* <p>
|
||||
* The list is always encoded in order of the declaration of kinds (enum order).
|
||||
*
|
||||
* @param col the set
|
||||
@@ -86,14 +113,9 @@ public enum TraceBreakpointKind {
|
||||
*/
|
||||
public static String encode(Collection<TraceBreakpointKind> col) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
boolean first = true;
|
||||
for (TraceBreakpointKind k : values()) {
|
||||
for (TraceBreakpointKind k : VALUES) {
|
||||
if (col.contains(k)) {
|
||||
if (!first) {
|
||||
sb.append(',');
|
||||
}
|
||||
first = false;
|
||||
sb.append(k.name());
|
||||
sb.append(k.flag);
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
@@ -109,13 +131,39 @@ public enum TraceBreakpointKind {
|
||||
}
|
||||
}
|
||||
|
||||
private final byte bits;
|
||||
public enum CommonSet {
|
||||
SWX("Execute (sw)", TraceBreakpointKindSet.of(TraceBreakpointKind.SW_EXECUTE)),
|
||||
HWX("Execute (hw)", TraceBreakpointKindSet.of(TraceBreakpointKind.HW_EXECUTE)),
|
||||
READ("Read (hw)", TraceBreakpointKindSet.of(TraceBreakpointKind.READ)),
|
||||
WRITE("Write (hw)", TraceBreakpointKindSet.of(TraceBreakpointKind.WRITE)),
|
||||
ACCESS("Access (hw)", TraceBreakpointKindSet.of(
|
||||
TraceBreakpointKind.READ, TraceBreakpointKind.WRITE));
|
||||
|
||||
TraceBreakpointKind(int mask) {
|
||||
this.bits = (byte) mask;
|
||||
public static final List<CommonSet> VALUES = List.of(values());
|
||||
|
||||
private final String display;
|
||||
private final TraceBreakpointKindSet kinds;
|
||||
|
||||
private CommonSet(String display, TraceBreakpointKindSet kinds) {
|
||||
this.display = display;
|
||||
this.kinds = kinds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return display;
|
||||
}
|
||||
|
||||
public TraceBreakpointKindSet kinds() {
|
||||
return kinds;
|
||||
}
|
||||
}
|
||||
|
||||
public byte getBits() {
|
||||
return bits;
|
||||
private final char flag;
|
||||
private final String flagStr;
|
||||
|
||||
TraceBreakpointKind(char flag) {
|
||||
this.flag = flag;
|
||||
this.flagStr = "" + flag;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ import db.Transaction;
|
||||
import ghidra.test.AbstractGhidraHeadlessIntegrationTest;
|
||||
import ghidra.trace.database.ToyDBTraceBuilder;
|
||||
import ghidra.trace.model.Lifespan;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind.CommonSet;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointLocation;
|
||||
import ghidra.trace.model.target.schema.TraceObjectSchema.SchemaName;
|
||||
import ghidra.trace.model.target.schema.XmlSchemaContext;
|
||||
@@ -93,7 +93,7 @@ public class DBTraceBreakpointManagerTest extends AbstractGhidraHeadlessIntegrat
|
||||
try (Transaction tx = b.startTransaction()) {
|
||||
breakpointManager.addBreakpoint("Breakpoints[0]", Lifespan.span(0, 10),
|
||||
b.addr(0x00400000),
|
||||
Set.of(), Set.of(TraceBreakpointKind.SW_EXECUTE), true, "main");
|
||||
Set.of(), CommonSet.SWX.kinds(), true, "main");
|
||||
}
|
||||
|
||||
try (Transaction tx = b.startTransaction()) {
|
||||
@@ -114,13 +114,13 @@ public class DBTraceBreakpointManagerTest extends AbstractGhidraHeadlessIntegrat
|
||||
// For table mode, ensure the answer is the same as object mode
|
||||
breakMain = breakpointManager.addBreakpoint("Breakpoints[0]", Lifespan.span(0, 10),
|
||||
b.addr(0x00400000),
|
||||
Set.of(thread), Set.of(TraceBreakpointKind.SW_EXECUTE), true, "main");
|
||||
Set.of(thread), CommonSet.SWX.kinds(), true, "main");
|
||||
breakVarA = breakpointManager.addBreakpoint("Breakpoints[1]", Lifespan.span(0, 10),
|
||||
b.range(0x00600010, 0x00600013),
|
||||
Set.of(thread), Set.of(TraceBreakpointKind.WRITE), false, "varA");
|
||||
Set.of(thread), CommonSet.WRITE.kinds(), false, "varA");
|
||||
breakVarB = breakpointManager.addBreakpoint("Breakpoints[1]", Lifespan.span(11, 20),
|
||||
b.range(0x00600020, 0x00600023),
|
||||
Set.of(thread), Set.of(TraceBreakpointKind.WRITE), false, "varB");
|
||||
Set.of(thread), CommonSet.WRITE.kinds(), false, "varB");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -231,12 +231,12 @@ public class DBTraceBreakpointManagerTest extends AbstractGhidraHeadlessIntegrat
|
||||
@Test
|
||||
public void testSetGetKinds() throws Exception {
|
||||
addBreakpoints();
|
||||
assertEquals(Set.of(TraceBreakpointKind.SW_EXECUTE), Set.copyOf(breakMain.getKinds(0)));
|
||||
assertEquals(CommonSet.SWX.kinds(), Set.copyOf(breakMain.getKinds(0)));
|
||||
try (Transaction tx = b.startTransaction()) {
|
||||
breakMain.getSpecification().setKinds(0, Set.of(TraceBreakpointKind.HW_EXECUTE));
|
||||
assertEquals(Set.of(TraceBreakpointKind.HW_EXECUTE), Set.copyOf(breakMain.getKinds(0)));
|
||||
breakMain.getSpecification().setKinds(0, CommonSet.HWX.kinds());
|
||||
assertEquals(CommonSet.HWX.kinds(), Set.copyOf(breakMain.getKinds(0)));
|
||||
}
|
||||
assertEquals(Set.of(TraceBreakpointKind.HW_EXECUTE), Set.copyOf(breakMain.getKinds(0)));
|
||||
assertEquals(CommonSet.HWX.kinds(), Set.copyOf(breakMain.getKinds(0)));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -20,7 +20,6 @@ import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.*;
|
||||
|
||||
@@ -59,7 +58,7 @@ import ghidra.trace.database.ToyDBTraceBuilder;
|
||||
import ghidra.trace.database.target.DBTraceObject;
|
||||
import ghidra.trace.model.DefaultTraceLocation;
|
||||
import ghidra.trace.model.Lifespan;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind.CommonSet;
|
||||
import ghidra.trace.model.target.TraceObject.ConflictResolution;
|
||||
import ghidra.trace.model.target.path.KeyPath;
|
||||
import ghidra.util.Msg;
|
||||
@@ -115,7 +114,7 @@ public class DebuggerBreakpointMarkerPluginScreenShots extends GhidraScreenShotG
|
||||
DBTraceObject objBptLoc = tb.trace.getObjectManager().createObject(pathSpec.index(1));
|
||||
objBptLoc.setAttribute(Lifespan.nowOn(0), "Range",
|
||||
new AddressRangeImpl(dynAddr, dynAddr));
|
||||
objBptSpec.setAttribute(Lifespan.nowOn(0), "Kinds", "SW_EXECUTE");
|
||||
objBptSpec.setAttribute(Lifespan.nowOn(0), "Kinds", "x");
|
||||
objBptSpec.setAttribute(Lifespan.nowOn(0), "Enabled", enabled);
|
||||
objBptLoc.insert(Lifespan.nowOn(0), ConflictResolution.DENY);
|
||||
}
|
||||
@@ -150,7 +149,7 @@ public class DebuggerBreakpointMarkerPluginScreenShots extends GhidraScreenShotG
|
||||
|
||||
Msg.debug(this, "Placing disabled breakpoint");
|
||||
breakpointService.placeBreakpointAt(program, addr(program, 0x00401c60), 1,
|
||||
Set.of(TraceBreakpointKind.SW_EXECUTE), "");
|
||||
CommonSet.SWX.kinds(), "");
|
||||
LogicalBreakpoint lbDis = waitForValue(() -> Unique.assertAtMostOne(
|
||||
breakpointService.getBreakpointsAt(program, addr(program, 0x00401c60))));
|
||||
placeBreakpoint(1, lbDis.getTraceAddress(tb.trace), false);
|
||||
@@ -158,7 +157,7 @@ public class DebuggerBreakpointMarkerPluginScreenShots extends GhidraScreenShotG
|
||||
|
||||
Msg.debug(this, "Placing enabled breakpoint");
|
||||
breakpointService.placeBreakpointAt(program, addr(program, 0x00401c63), 1,
|
||||
Set.of(TraceBreakpointKind.SW_EXECUTE), "");
|
||||
CommonSet.SWX.kinds(), "");
|
||||
LogicalBreakpoint lbEn = waitForValue(() -> Unique.assertAtMostOne(
|
||||
breakpointService.getBreakpointsAt(program, addr(program, 0x00401c63))));
|
||||
placeBreakpoint(2, lbEn.getTraceAddress(tb.trace), true);
|
||||
@@ -296,7 +295,7 @@ public class DebuggerBreakpointMarkerPluginScreenShots extends GhidraScreenShotG
|
||||
|
||||
Msg.debug(this, "Placing breakpoint");
|
||||
breakpointService.placeBreakpointAt(program, addr(program, 0x00401070), 1,
|
||||
Set.of(TraceBreakpointKind.SW_EXECUTE), "");
|
||||
CommonSet.SWX.kinds(), "");
|
||||
LogicalBreakpoint lbEn = waitForValue(() -> Unique.assertAtMostOne(
|
||||
breakpointService.getBreakpointsAt(program, addr(program, 0x00401070))));
|
||||
placeBreakpoint(1, lbEn.getTraceAddress(tb.trace), true);
|
||||
@@ -337,7 +336,7 @@ public class DebuggerBreakpointMarkerPluginScreenShots extends GhidraScreenShotG
|
||||
|
||||
Msg.debug(this, "Placing breakpoint");
|
||||
breakpointService.placeBreakpointAt(program, addr(program, 0x00401070), 1,
|
||||
Set.of(TraceBreakpointKind.SW_EXECUTE), "");
|
||||
CommonSet.SWX.kinds(), "");
|
||||
LogicalBreakpoint lbEn = waitForValue(() -> Unique.assertAtMostOne(
|
||||
breakpointService.getBreakpointsAt(program, addr(program, 0x00401070))));
|
||||
placeBreakpoint(1, lbEn.getTraceAddress(tb.trace), true);
|
||||
@@ -357,11 +356,12 @@ public class DebuggerBreakpointMarkerPluginScreenShots extends GhidraScreenShotG
|
||||
public void testCaptureDebuggerPlaceBreakpointDialog() throws Throwable {
|
||||
runSwing(
|
||||
() -> listing.goTo(program, new ProgramLocation(program, addr(program, 0x00401c63))));
|
||||
performAction(breakpointMarkerPlugin.actionSetSoftwareBreakpoint, false);
|
||||
performAction(breakpointMarkerPlugin.actionsSetBreakpoint.get(CommonSet.SWX), false);
|
||||
DebuggerPlaceBreakpointDialog dialog =
|
||||
waitForDialogComponent(DebuggerPlaceBreakpointDialog.class);
|
||||
|
||||
dialog.setName("After setup");
|
||||
dialog.getComponent().grabFocus();
|
||||
captureDialog(dialog);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@ import ghidra.trace.database.ToyDBTraceBuilder;
|
||||
import ghidra.trace.database.breakpoint.DBTraceBreakpointManager;
|
||||
import ghidra.trace.model.*;
|
||||
import ghidra.trace.model.breakpoint.*;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind.CommonSet;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
import help.screenshot.GhidraScreenShotGenerator;
|
||||
@@ -137,12 +138,10 @@ public class DebuggerBreakpointsPluginScreenShots extends GhidraScreenShotGenera
|
||||
try (Transaction tx = program.openTransaction("Add breakpoint")) {
|
||||
program.getBookmarkManager()
|
||||
.setBookmark(addr(program, 0x00401234),
|
||||
LogicalBreakpoint.ENABLED_BOOKMARK_TYPE,
|
||||
"SW_EXECUTE;1", "before connect");
|
||||
LogicalBreakpoint.ENABLED_BOOKMARK_TYPE, "x;1", "before connect");
|
||||
program.getBookmarkManager()
|
||||
.setBookmark(addr(program, 0x00604321),
|
||||
LogicalBreakpoint.ENABLED_BOOKMARK_TYPE,
|
||||
"WRITE;4", "write version");
|
||||
LogicalBreakpoint.ENABLED_BOOKMARK_TYPE, "W;4", "write version");
|
||||
}
|
||||
|
||||
try (Transaction tx = tb1.startTransaction()) {
|
||||
@@ -153,14 +152,14 @@ public class DebuggerBreakpointsPluginScreenShots extends GhidraScreenShotGenera
|
||||
DBTraceBreakpointManager bm = tb1.trace.getBreakpointManager();
|
||||
TraceBreakpointLocation locCx =
|
||||
bm.placeBreakpoint("Breakpoints[1]", snap, tb1.addr(0x00401234), List.of(),
|
||||
Set.of(TraceBreakpointKind.SW_EXECUTE), true, "");
|
||||
CommonSet.SWX.kinds(), true, "");
|
||||
locCx.getSpecification()
|
||||
.getObject()
|
||||
.setAttribute(Lifespan.nowOn(snap), TraceBreakpointSpec.KEY_EXPRESSION,
|
||||
"*0x00401234");
|
||||
TraceBreakpointLocation locWr =
|
||||
bm.placeBreakpoint("Breakpoints[2]", snap, tb1.range(0x00604321, 0x00604324),
|
||||
List.of(), Set.of(TraceBreakpointKind.WRITE), true, "");
|
||||
List.of(), CommonSet.WRITE.kinds(), true, "");
|
||||
locWr.getSpecification()
|
||||
.getObject()
|
||||
.setAttribute(Lifespan.nowOn(snap), TraceBreakpointSpec.KEY_EXPRESSION,
|
||||
@@ -175,11 +174,11 @@ public class DebuggerBreakpointsPluginScreenShots extends GhidraScreenShotGenera
|
||||
DBTraceBreakpointManager bm = tb2.trace.getBreakpointManager();
|
||||
TraceBreakpointLocation locCx =
|
||||
bm.placeBreakpoint("Breakpoints[1]", snap, tb2.addr(0x7fac1234), List.of(),
|
||||
Set.of(TraceBreakpointKind.SW_EXECUTE), false, "");
|
||||
CommonSet.SWX.kinds(), false, "");
|
||||
locCx.getSpecification()
|
||||
.getObject()
|
||||
.setAttribute(Lifespan.nowOn(snap), TraceBreakpointSpec.KEY_EXPRESSION,
|
||||
"*0x7fac1234");
|
||||
.getObject()
|
||||
.setAttribute(Lifespan.nowOn(snap), TraceBreakpointSpec.KEY_EXPRESSION,
|
||||
"*0x7fac1234");
|
||||
}
|
||||
|
||||
programManager.openProgram(program);
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package agent.dbgeng.rmi;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
@@ -41,7 +42,7 @@ import ghidra.program.model.lang.RegisterValue;
|
||||
import ghidra.program.model.listing.CodeUnit;
|
||||
import ghidra.trace.database.ToyDBTraceBuilder;
|
||||
import ghidra.trace.model.*;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind.CommonSet;
|
||||
import ghidra.trace.model.listing.TraceCodeSpace;
|
||||
import ghidra.trace.model.listing.TraceData;
|
||||
import ghidra.trace.model.memory.*;
|
||||
@@ -989,9 +990,9 @@ public class DbgEngCommandsTest extends AbstractDbgEngTraceRmiTest {
|
||||
Address bp1 = rangeMain.getMinAddress();
|
||||
|
||||
assertBreakLoc(procBreakLocVals.get(0), "[0]", bp1, 1,
|
||||
Set.of(TraceBreakpointKind.SW_EXECUTE), "ntdll!Ldr");
|
||||
CommonSet.SWX.kinds(), "ntdll!Ldr");
|
||||
assertBreakLoc(procBreakLocVals.get(1), "[1]", bp1.add(4), 1,
|
||||
Set.of(TraceBreakpointKind.HW_EXECUTE), "ntdll!Ldr");
|
||||
CommonSet.HWX.kinds(), "ntdll!Ldr");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1031,11 +1032,11 @@ public class DbgEngCommandsTest extends AbstractDbgEngTraceRmiTest {
|
||||
Address main2 = rangeMain2.getMinAddress();
|
||||
|
||||
assertWatchLoc(procBreakVals.get(0), "[0]", main0, (int) rangeMain0.getLength(),
|
||||
Set.of(TraceBreakpointKind.HW_EXECUTE), "ntdll!LdrInit");
|
||||
CommonSet.HWX.kinds(), "ntdll!LdrInit");
|
||||
assertWatchLoc(procBreakVals.get(1), "[1]", main1, (int) rangeMain1.getLength(),
|
||||
Set.of(TraceBreakpointKind.WRITE), "ntdll!LdrInit");
|
||||
CommonSet.WRITE.kinds(), "ntdll!LdrInit");
|
||||
assertWatchLoc(procBreakVals.get(2), "[2]", main2, (int) rangeMain2.getLength(),
|
||||
Set.of(TraceBreakpointKind.READ), "ntdll!LdrInit");
|
||||
CommonSet.READ.kinds(), "ntdll!LdrInit");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
*/
|
||||
package agent.dbgeng.rmi;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.greaterThan;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.File;
|
||||
@@ -38,7 +39,7 @@ import ghidra.pty.testutil.DummyProc;
|
||||
import ghidra.trace.database.ToyDBTraceBuilder;
|
||||
import ghidra.trace.model.Lifespan;
|
||||
import ghidra.trace.model.Trace;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind.CommonSet;
|
||||
import ghidra.trace.model.memory.TraceMemoryRegion;
|
||||
import ghidra.trace.model.memory.TraceMemorySpace;
|
||||
import ghidra.trace.model.modules.TraceModule;
|
||||
@@ -142,9 +143,9 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest {
|
||||
Address main = rangeMain.getMinAddress();
|
||||
|
||||
assertBreakLoc(procBreakLocVals.get(0), "[0]", main, 1,
|
||||
Set.of(TraceBreakpointKind.SW_EXECUTE), "ntdll!Ldr");
|
||||
CommonSet.SWX.kinds(), "ntdll!Ldr");
|
||||
assertBreakLoc(procBreakLocVals.get(1), "[1]", main.add(4), 1,
|
||||
Set.of(TraceBreakpointKind.HW_EXECUTE), "ntdll!Ldr");
|
||||
CommonSet.HWX.kinds(), "ntdll!Ldr");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -185,14 +186,11 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest {
|
||||
Address main2 = rangeMain2.getMinAddress();
|
||||
|
||||
assertWatchLoc(procBreakVals.get(0), "[0]", main0, (int) rangeMain0.getLength(),
|
||||
Set.of(TraceBreakpointKind.HW_EXECUTE),
|
||||
"main");
|
||||
CommonSet.HWX.kinds(), "main");
|
||||
assertWatchLoc(procBreakVals.get(1), "[1]", main1, (int) rangeMain1.getLength(),
|
||||
Set.of(TraceBreakpointKind.WRITE),
|
||||
"main+4");
|
||||
CommonSet.WRITE.kinds(), "main+4");
|
||||
assertWatchLoc(procBreakVals.get(2), "[2]", main2, (int) rangeMain1.getLength(),
|
||||
Set.of(TraceBreakpointKind.READ),
|
||||
"main+8");
|
||||
CommonSet.READ.kinds(), "main+8");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ import ghidra.program.model.lang.RegisterValue;
|
||||
import ghidra.program.model.listing.CodeUnit;
|
||||
import ghidra.trace.database.ToyDBTraceBuilder;
|
||||
import ghidra.trace.model.*;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind.CommonSet;
|
||||
import ghidra.trace.model.listing.TraceCodeSpace;
|
||||
import ghidra.trace.model.listing.TraceData;
|
||||
import ghidra.trace.model.memory.*;
|
||||
@@ -1071,20 +1071,15 @@ public class GdbCommandsTest extends AbstractGdbTraceRmiTest {
|
||||
|
||||
// NB. starti avoid use of temporary main breakpoint
|
||||
assertBreakLoc(infBreakLocVals.get(0), "[1.1]", main, 1,
|
||||
Set.of(TraceBreakpointKind.SW_EXECUTE),
|
||||
"*main");
|
||||
CommonSet.SWX.kinds(), "*main");
|
||||
assertBreakLoc(infBreakLocVals.get(1), "[2.1]", main.add(10), 1,
|
||||
Set.of(TraceBreakpointKind.HW_EXECUTE),
|
||||
"*main+10");
|
||||
CommonSet.HWX.kinds(), "*main+10");
|
||||
assertBreakLoc(infBreakLocVals.get(2), "[3.1]", main.add(20), 1,
|
||||
Set.of(TraceBreakpointKind.WRITE),
|
||||
"-location *((char*)(&main+20))");
|
||||
CommonSet.WRITE.kinds(), "-location *((char*)(&main+20))");
|
||||
assertBreakLoc(infBreakLocVals.get(3), "[4.1]", main.add(30), 8,
|
||||
Set.of(TraceBreakpointKind.READ),
|
||||
"-location *((char(*)[8])(&main+30))");
|
||||
CommonSet.READ.kinds(), "-location *((char(*)[8])(&main+30))");
|
||||
assertBreakLoc(infBreakLocVals.get(4), "[5.1]", main.add(40), 5,
|
||||
Set.of(TraceBreakpointKind.READ, TraceBreakpointKind.WRITE),
|
||||
"-location *((char(*)[5])(&main+40))");
|
||||
CommonSet.ACCESS.kinds(), "-location *((char(*)[5])(&main+40))");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ import ghidra.pty.testutil.DummyProc;
|
||||
import ghidra.trace.database.ToyDBTraceBuilder;
|
||||
import ghidra.trace.model.Lifespan;
|
||||
import ghidra.trace.model.Trace;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind.CommonSet;
|
||||
import ghidra.trace.model.listing.TraceCodeSpace;
|
||||
import ghidra.trace.model.listing.TraceData;
|
||||
import ghidra.trace.model.memory.TraceMemoryRegion;
|
||||
@@ -146,20 +146,15 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest {
|
||||
|
||||
// NB. starti avoid use of temporary main breakpoint
|
||||
assertBreakLoc(infBreakLocVals.get(0), "[1.1]", main, 1,
|
||||
Set.of(TraceBreakpointKind.SW_EXECUTE),
|
||||
"*main");
|
||||
CommonSet.SWX.kinds(), "*main");
|
||||
assertBreakLoc(infBreakLocVals.get(1), "[2.1]", main.add(10), 1,
|
||||
Set.of(TraceBreakpointKind.HW_EXECUTE),
|
||||
"*main+10");
|
||||
CommonSet.HWX.kinds(), "*main+10");
|
||||
assertBreakLoc(infBreakLocVals.get(2), "[3.1]", main.add(20), 1,
|
||||
Set.of(TraceBreakpointKind.WRITE),
|
||||
"-location *((char*)(&main+20))");
|
||||
CommonSet.WRITE.kinds(), "-location *((char*)(&main+20))");
|
||||
assertBreakLoc(infBreakLocVals.get(3), "[4.1]", main.add(30), 8,
|
||||
Set.of(TraceBreakpointKind.READ),
|
||||
"-location *((char(*)[8])(&main+30))");
|
||||
CommonSet.READ.kinds(), "-location *((char(*)[8])(&main+30))");
|
||||
assertBreakLoc(infBreakLocVals.get(4), "[5.1]", main.add(40), 5,
|
||||
Set.of(TraceBreakpointKind.READ, TraceBreakpointKind.WRITE),
|
||||
"-location *((char(*)[5])(&main+40))");
|
||||
CommonSet.ACCESS.kinds(), "-location *((char(*)[5])(&main+40))");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -202,20 +197,15 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest {
|
||||
|
||||
// NB. starti avoid use of temporary main breakpoint
|
||||
assertBreakLoc(infBreakLocVals.get(0), "[1.1]", main, 1,
|
||||
Set.of(TraceBreakpointKind.SW_EXECUTE),
|
||||
"*main");
|
||||
CommonSet.SWX.kinds(), "*main");
|
||||
assertBreakLoc(infBreakLocVals.get(1), "[2.1]", main.add(10), 1,
|
||||
Set.of(TraceBreakpointKind.HW_EXECUTE),
|
||||
"*main+10");
|
||||
CommonSet.HWX.kinds(), "*main+10");
|
||||
assertBreakLoc(infBreakLocVals.get(2), "[3.1]", main.add(20), 1,
|
||||
Set.of(TraceBreakpointKind.WRITE),
|
||||
"-location *((char*)(&main+20))");
|
||||
CommonSet.WRITE.kinds(), "-location *((char*)(&main+20))");
|
||||
assertBreakLoc(infBreakLocVals.get(3), "[4.1]", main.add(30), 8,
|
||||
Set.of(TraceBreakpointKind.READ),
|
||||
"-location *((char(*)[8])(&main+30))");
|
||||
CommonSet.READ.kinds(), "-location *((char(*)[8])(&main+30))");
|
||||
assertBreakLoc(infBreakLocVals.get(4), "[5.1]", main.add(40), 5,
|
||||
Set.of(TraceBreakpointKind.READ, TraceBreakpointKind.WRITE),
|
||||
"-location *((char(*)[5])(&main+40))");
|
||||
CommonSet.ACCESS.kinds(), "-location *((char(*)[5])(&main+40))");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package agent.lldb.rmi;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assume.assumeFalse;
|
||||
@@ -45,7 +46,7 @@ import ghidra.program.model.lang.RegisterValue;
|
||||
import ghidra.program.model.listing.CodeUnit;
|
||||
import ghidra.trace.database.ToyDBTraceBuilder;
|
||||
import ghidra.trace.model.*;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind.CommonSet;
|
||||
import ghidra.trace.model.listing.TraceCodeSpace;
|
||||
import ghidra.trace.model.listing.TraceData;
|
||||
import ghidra.trace.model.memory.*;
|
||||
@@ -1075,11 +1076,9 @@ public class LldbCommandsTest extends AbstractLldbTraceRmiTest {
|
||||
Address main = rangeMain.getMinAddress();
|
||||
|
||||
assertBreakLoc(procBreakLocVals.get(0), "[1]", main, 1,
|
||||
Set.of(TraceBreakpointKind.SW_EXECUTE),
|
||||
"main");
|
||||
CommonSet.SWX.kinds(), "main");
|
||||
assertBreakLoc(procBreakLocVals.get(1), "[1]", main, 1,
|
||||
Set.of(TraceBreakpointKind.HW_EXECUTE),
|
||||
"main");
|
||||
CommonSet.HWX.kinds(), "main");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1121,11 +1120,11 @@ public class LldbCommandsTest extends AbstractLldbTraceRmiTest {
|
||||
Address main2 = rangeMain2.getMinAddress();
|
||||
|
||||
assertWatchLoc(procWatchLocVals.get(0), "[1]", main0, (int) rangeMain0.getLength(),
|
||||
Set.of(TraceBreakpointKind.WRITE), "main");
|
||||
CommonSet.WRITE.kinds(), "main");
|
||||
assertWatchLoc(procWatchLocVals.get(1), "[2]", main1, (int) rangeMain1.getLength(),
|
||||
Set.of(TraceBreakpointKind.READ), "main");
|
||||
CommonSet.READ.kinds(), "main");
|
||||
assertWatchLoc(procWatchLocVals.get(2), "[3]", main2, (int) rangeMain2.getLength(),
|
||||
Set.of(TraceBreakpointKind.READ, TraceBreakpointKind.WRITE), "main");
|
||||
CommonSet.ACCESS.kinds(), "main");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ package agent.lldb.rmi;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assume.*;
|
||||
import static org.junit.Assume.assumeTrue;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -37,7 +37,7 @@ import ghidra.pty.testutil.DummyProc;
|
||||
import ghidra.trace.database.ToyDBTraceBuilder;
|
||||
import ghidra.trace.model.Lifespan;
|
||||
import ghidra.trace.model.Trace;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind.CommonSet;
|
||||
import ghidra.trace.model.memory.TraceMemoryRegion;
|
||||
import ghidra.trace.model.memory.TraceMemorySpace;
|
||||
import ghidra.trace.model.modules.TraceModule;
|
||||
@@ -129,11 +129,9 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
|
||||
Address main = rangeMain.getMinAddress();
|
||||
|
||||
assertBreakLoc(procBreakLocVals.get(0), "[1]", main, 1,
|
||||
Set.of(TraceBreakpointKind.SW_EXECUTE),
|
||||
"main");
|
||||
CommonSet.SWX.kinds(), "main");
|
||||
assertBreakLoc(procBreakLocVals.get(1), "[1]", main, 1,
|
||||
Set.of(TraceBreakpointKind.HW_EXECUTE),
|
||||
"main");
|
||||
CommonSet.HWX.kinds(), "main");
|
||||
}
|
||||
conn.success();
|
||||
}
|
||||
@@ -176,14 +174,11 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
|
||||
Address main2 = rangeMain2.getMinAddress();
|
||||
|
||||
assertWatchLoc(procWatchLocVals.get(0), "[1]", main0, (int) rangeMain0.getLength(),
|
||||
Set.of(TraceBreakpointKind.WRITE),
|
||||
"main");
|
||||
CommonSet.WRITE.kinds(), "main");
|
||||
assertWatchLoc(procWatchLocVals.get(1), "[2]", main1, (int) rangeMain1.getLength(),
|
||||
Set.of(TraceBreakpointKind.READ),
|
||||
"main+0x20");
|
||||
CommonSet.READ.kinds(), "main+0x20");
|
||||
assertWatchLoc(procWatchLocVals.get(2), "[3]", main2, (int) rangeMain1.getLength(),
|
||||
Set.of(TraceBreakpointKind.READ, TraceBreakpointKind.WRITE),
|
||||
"main+0x30");
|
||||
CommonSet.ACCESS.kinds(), "main+0x30");
|
||||
}
|
||||
conn.success();
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ import ghidra.program.model.symbol.SourceType;
|
||||
import ghidra.program.util.ProgramLocation;
|
||||
import ghidra.trace.model.*;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind.TraceBreakpointKindSet;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind.CommonSet;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointLocation;
|
||||
import ghidra.trace.model.program.TraceProgramView;
|
||||
import ghidra.util.SystemUtilities;
|
||||
@@ -83,7 +83,7 @@ public abstract class AbstractDebuggerBreakpointMarkerPluginTest<T>
|
||||
AbstractDisableBreakpointAction.NAME, AbstractClearBreakpointAction.NAME);
|
||||
|
||||
protected static final Set<String> SET_ACTIONS =
|
||||
Set.of("SW_EXECUTE", "HW_EXECUTE", "READ,WRITE", "READ", "WRITE");
|
||||
Set.of("Execute (sw)", "Execute (hw)", "Access (hw)", "Read (hw)", "Write (hw)");
|
||||
|
||||
protected DebuggerBreakpointMarkerPlugin breakpointMarkerPlugin;
|
||||
protected DebuggerListingPlugin listingPlugin;
|
||||
@@ -201,7 +201,7 @@ public abstract class AbstractDebuggerBreakpointMarkerPluginTest<T>
|
||||
TaskMonitor.DUMMY, false);
|
||||
program.getBookmarkManager()
|
||||
.setBookmark(addr(program, 0x00400123), LogicalBreakpoint.ENABLED_BOOKMARK_TYPE,
|
||||
"SW_EXECUTE;1", "");
|
||||
"x;1", "");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -505,7 +505,7 @@ public abstract class AbstractDebuggerBreakpointMarkerPluginTest<T>
|
||||
DebuggerPlaceBreakpointDialog dialog =
|
||||
waitForDialogComponent(DebuggerPlaceBreakpointDialog.class);
|
||||
runSwing(() -> dialog.okCallback());
|
||||
handleSetBreakpointInvocation(TraceBreakpointKindSet.SW_EXECUTE, 0x55550123);
|
||||
handleSetBreakpointInvocation(CommonSet.SWX.kinds(), 0x55550123);
|
||||
waitForDomainObject(program);
|
||||
waitForDomainObject(tb.trace);
|
||||
waitOn(breakpointService.changesSettled());
|
||||
@@ -514,7 +514,7 @@ public abstract class AbstractDebuggerBreakpointMarkerPluginTest<T>
|
||||
LogicalBreakpoint lb = Unique.assertOne(breakpointService.getAllBreakpoints());
|
||||
assertEquals(State.ENABLED, lb.computeState());
|
||||
// TODO: Different cases for different expected default kinds?
|
||||
assertEquals(Set.of(TraceBreakpointKind.SW_EXECUTE), lb.getKinds());
|
||||
assertEquals(CommonSet.SWX.kinds(), lb.getKinds());
|
||||
});
|
||||
}
|
||||
|
||||
@@ -543,7 +543,7 @@ public abstract class AbstractDebuggerBreakpointMarkerPluginTest<T>
|
||||
DebuggerPlaceBreakpointDialog dialog =
|
||||
waitForDialogComponent(DebuggerPlaceBreakpointDialog.class);
|
||||
runSwing(() -> dialog.okCallback());
|
||||
handleSetBreakpointInvocation(TraceBreakpointKindSet.ACCESS, 0x55550123);
|
||||
handleSetBreakpointInvocation(CommonSet.ACCESS.kinds(), 0x55550123);
|
||||
waitForDomainObject(program);
|
||||
waitForDomainObject(tb.trace);
|
||||
waitOn(breakpointService.changesSettled());
|
||||
@@ -552,7 +552,7 @@ public abstract class AbstractDebuggerBreakpointMarkerPluginTest<T>
|
||||
LogicalBreakpoint lb = Unique.assertOne(breakpointService.getAllBreakpoints());
|
||||
assertEquals(State.ENABLED, lb.computeState());
|
||||
// TODO: Different cases for different expected default kinds?
|
||||
assertEquals(TraceBreakpointKindSet.ACCESS, lb.getKinds());
|
||||
assertEquals(CommonSet.ACCESS.kinds(), lb.getKinds());
|
||||
});
|
||||
}
|
||||
|
||||
@@ -621,8 +621,8 @@ public abstract class AbstractDebuggerBreakpointMarkerPluginTest<T>
|
||||
waitForPass(() -> assertEquals(State.ENABLED, lb.computeStateForTrace(trace)));
|
||||
}
|
||||
|
||||
protected void testActionSetBreakpointProgram(DockingAction action,
|
||||
Set<TraceBreakpointKind> expectedKinds) throws Throwable {
|
||||
protected void testActionSetBreakpointProgram(CommonSet kind) throws Throwable {
|
||||
DockingAction action = breakpointMarkerPlugin.actionsSetBreakpoint.get(kind);
|
||||
addMappedBreakpointOpenAndWait(); // Adds an unneeded breakpoint. Aw well.
|
||||
|
||||
ProgramLocationActionContext ctx = staticCtx(addr(program, 0x0400321));
|
||||
@@ -635,19 +635,19 @@ public abstract class AbstractDebuggerBreakpointMarkerPluginTest<T>
|
||||
dialog.okCallback();
|
||||
});
|
||||
|
||||
handleSetBreakpointInvocation(expectedKinds, 0x55550321);
|
||||
handleSetBreakpointInvocation(kind.kinds(), 0x55550321);
|
||||
|
||||
waitForPass(() -> {
|
||||
LogicalBreakpoint lb = Unique.assertOne(
|
||||
breakpointService.getBreakpointsAt(program, addr(program, 0x00400321)));
|
||||
assertEquals(expectedKinds, lb.getKinds());
|
||||
assertEquals(kind.kinds(), lb.getKinds());
|
||||
assertEquals(State.ENABLED, lb.computeState());
|
||||
assertEquals("Test name", lb.getName());
|
||||
});
|
||||
}
|
||||
|
||||
protected void testActionSetBreakpointTrace(DockingAction action,
|
||||
Set<TraceBreakpointKind> expectedKinds) throws Throwable {
|
||||
protected void testActionSetBreakpointTrace(CommonSet kind) throws Throwable {
|
||||
DockingAction action = breakpointMarkerPlugin.actionsSetBreakpoint.get(kind);
|
||||
T t = addMappedBreakpointOpenAndWait(); // Adds an unneeded breakpoint. Aw well.
|
||||
Trace trace = getTrace(t);
|
||||
|
||||
@@ -657,12 +657,12 @@ public abstract class AbstractDebuggerBreakpointMarkerPluginTest<T>
|
||||
DebuggerPlaceBreakpointDialog dialog =
|
||||
waitForDialogComponent(DebuggerPlaceBreakpointDialog.class);
|
||||
runSwing(() -> dialog.okCallback());
|
||||
handleSetBreakpointInvocation(expectedKinds, 0x55550321);
|
||||
handleSetBreakpointInvocation(kind.kinds(), 0x55550321);
|
||||
|
||||
waitForPass(() -> {
|
||||
LogicalBreakpoint lb = Unique
|
||||
.assertOne(breakpointService.getBreakpointsAt(trace, addr(trace, 0x55550321)));
|
||||
assertEquals(expectedKinds, lb.getKinds());
|
||||
assertEquals(kind.kinds(), lb.getKinds());
|
||||
assertEquals(State.ENABLED, lb.computeStateForTrace(trace));
|
||||
});
|
||||
/**
|
||||
@@ -672,63 +672,53 @@ public abstract class AbstractDebuggerBreakpointMarkerPluginTest<T>
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testActionSetSoftwareBreakpointProgram() throws Throwable {
|
||||
testActionSetBreakpointProgram(breakpointMarkerPlugin.actionSetSoftwareBreakpoint,
|
||||
Set.of(TraceBreakpointKind.SW_EXECUTE));
|
||||
public void testActionSetSwExecuteBreakpointProgram() throws Throwable {
|
||||
testActionSetBreakpointProgram(CommonSet.SWX);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testActionSetSoftwareBreakpointTrace() throws Throwable {
|
||||
testActionSetBreakpointTrace(breakpointMarkerPlugin.actionSetSoftwareBreakpoint,
|
||||
Set.of(TraceBreakpointKind.SW_EXECUTE));
|
||||
public void testActionSetSwExecuteBreakpointTrace() throws Throwable {
|
||||
testActionSetBreakpointTrace(CommonSet.SWX);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testActionSetExecuteBreakpointProgram() throws Throwable {
|
||||
testActionSetBreakpointProgram(breakpointMarkerPlugin.actionSetExecuteBreakpoint,
|
||||
Set.of(TraceBreakpointKind.HW_EXECUTE));
|
||||
public void testActionSetHwExecuteBreakpointProgram() throws Throwable {
|
||||
testActionSetBreakpointProgram(CommonSet.HWX);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testActionSetExecuteBreakpointTrace() throws Throwable {
|
||||
testActionSetBreakpointTrace(breakpointMarkerPlugin.actionSetExecuteBreakpoint,
|
||||
Set.of(TraceBreakpointKind.HW_EXECUTE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testActionSetReadWriteBreakpointProgram() throws Throwable {
|
||||
testActionSetBreakpointProgram(breakpointMarkerPlugin.actionSetReadWriteBreakpoint,
|
||||
Set.of(TraceBreakpointKind.READ, TraceBreakpointKind.WRITE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testActionSetReadWriteBreakpointTrace() throws Throwable {
|
||||
testActionSetBreakpointTrace(breakpointMarkerPlugin.actionSetReadWriteBreakpoint,
|
||||
Set.of(TraceBreakpointKind.READ, TraceBreakpointKind.WRITE));
|
||||
public void testActionSetHwExecuteBreakpointTrace() throws Throwable {
|
||||
testActionSetBreakpointTrace(CommonSet.HWX);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testActionSetReadBreakpointProgram() throws Throwable {
|
||||
testActionSetBreakpointProgram(breakpointMarkerPlugin.actionSetReadBreakpoint,
|
||||
Set.of(TraceBreakpointKind.READ));
|
||||
testActionSetBreakpointProgram(CommonSet.READ);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testActionSetReadBreakpointTrace() throws Throwable {
|
||||
testActionSetBreakpointTrace(breakpointMarkerPlugin.actionSetReadBreakpoint,
|
||||
Set.of(TraceBreakpointKind.READ));
|
||||
testActionSetBreakpointTrace(CommonSet.READ);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testActionSetWriteBreakpointProgram() throws Throwable {
|
||||
testActionSetBreakpointProgram(breakpointMarkerPlugin.actionSetWriteBreakpoint,
|
||||
Set.of(TraceBreakpointKind.WRITE));
|
||||
testActionSetBreakpointProgram(CommonSet.WRITE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testActionSetWriteBreakpointTrace() throws Throwable {
|
||||
testActionSetBreakpointTrace(breakpointMarkerPlugin.actionSetWriteBreakpoint,
|
||||
Set.of(TraceBreakpointKind.WRITE));
|
||||
testActionSetBreakpointTrace(CommonSet.WRITE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testActionSetAccessBreakpointProgram() throws Throwable {
|
||||
testActionSetBreakpointProgram(CommonSet.ACCESS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testActionSetAccessBreakpointTrace() throws Throwable {
|
||||
testActionSetBreakpointTrace(CommonSet.ACCESS);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -867,7 +857,7 @@ public abstract class AbstractDebuggerBreakpointMarkerPluginTest<T>
|
||||
waitForPass(() -> {
|
||||
LogicalBreakpoint lb = Unique.assertOne(breakpointService.getAllBreakpoints());
|
||||
assertEquals(State.INEFFECTIVE_ENABLED, lb.computeState());
|
||||
assertEquals(Set.of(TraceBreakpointKind.SW_EXECUTE), lb.getKinds());
|
||||
assertEquals(CommonSet.SWX.kinds(), lb.getKinds());
|
||||
});
|
||||
|
||||
performEnabledAction(decompilerProvider, breakpointMarkerPlugin.actionToggleBreakpoint,
|
||||
@@ -875,7 +865,7 @@ public abstract class AbstractDebuggerBreakpointMarkerPluginTest<T>
|
||||
waitForPass(() -> {
|
||||
LogicalBreakpoint lb = Unique.assertOne(breakpointService.getAllBreakpoints());
|
||||
assertEquals(State.INEFFECTIVE_DISABLED, lb.computeState());
|
||||
assertEquals(Set.of(TraceBreakpointKind.SW_EXECUTE), lb.getKinds());
|
||||
assertEquals(CommonSet.SWX.kinds(), lb.getKinds());
|
||||
});
|
||||
}
|
||||
|
||||
@@ -891,9 +881,9 @@ public abstract class AbstractDebuggerBreakpointMarkerPluginTest<T>
|
||||
runSwing(() -> decompilerProvider.getController().setDecompileData(mockData(results)));
|
||||
|
||||
waitOn(breakpointService.placeBreakpointAt(program, entry, 1,
|
||||
Set.of(TraceBreakpointKind.SW_EXECUTE), ""));
|
||||
CommonSet.SWX.kinds(), ""));
|
||||
waitOn(breakpointService.placeBreakpointAt(program, entry.add(2), 1,
|
||||
Set.of(TraceBreakpointKind.SW_EXECUTE), ""));
|
||||
CommonSet.SWX.kinds(), ""));
|
||||
waitForPass(() -> {
|
||||
assertEquals(2, breakpointService.getAllBreakpoints().size());
|
||||
});
|
||||
|
||||
@@ -50,7 +50,7 @@ import ghidra.program.model.mem.MemoryConflictException;
|
||||
import ghidra.program.util.ProgramLocation;
|
||||
import ghidra.trace.model.*;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind.TraceBreakpointKindSet;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind.CommonSet;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointLocation;
|
||||
import ghidra.trace.model.time.TraceSnapshot;
|
||||
import ghidra.util.SystemUtilities;
|
||||
@@ -107,7 +107,7 @@ public abstract class AbstractDebuggerBreakpointsProviderTest<T, P>
|
||||
TaskMonitor.DUMMY, false);
|
||||
program.getBookmarkManager()
|
||||
.setBookmark(addr(program, 0x00400123), LogicalBreakpoint.ENABLED_BOOKMARK_TYPE,
|
||||
"SW_EXECUTE;1", "");
|
||||
"x;1", "");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,7 +153,7 @@ public abstract class AbstractDebuggerBreakpointsProviderTest<T, P>
|
||||
Unique.assertOne(breakpointsProvider.breakpointTableModel.getModelData());
|
||||
assertEquals("55550123", row.getAddress().toString());
|
||||
assertEquals(trace, row.getDomainObject());
|
||||
assertEquals("SW_EXECUTE", row.getKinds());
|
||||
assertEquals("x", row.getKind());
|
||||
assertEquals(State.INCONSISTENT_ENABLED, row.getState());
|
||||
}
|
||||
|
||||
@@ -197,7 +197,7 @@ public abstract class AbstractDebuggerBreakpointsProviderTest<T, P>
|
||||
Unique.assertOne(breakpointsProvider.breakpointTableModel.getModelData());
|
||||
assertEquals("00400123", row.getAddress().toString());
|
||||
assertEquals(program, row.getDomainObject());
|
||||
assertEquals("SW_EXECUTE", row.getKinds());
|
||||
assertEquals("x", row.getKind());
|
||||
assertEquals(State.INEFFECTIVE_ENABLED, row.getState());
|
||||
}
|
||||
|
||||
@@ -534,7 +534,7 @@ public abstract class AbstractDebuggerBreakpointsProviderTest<T, P>
|
||||
});
|
||||
|
||||
performAction(breakpointsProvider.actionMakeBreakpointsEffective);
|
||||
handleSetBreakpointInvocation(TraceBreakpointKindSet.SW_EXECUTE, 0x55550123);
|
||||
handleSetBreakpointInvocation(CommonSet.SWX.kinds(), 0x55550123);
|
||||
|
||||
waitForPass(() -> {
|
||||
assertFalse(breakpointsProvider.actionMakeBreakpointsEffective.isEnabled());
|
||||
|
||||
@@ -29,7 +29,7 @@ import ghidra.trace.database.target.DBTraceObjectManager;
|
||||
import ghidra.trace.model.Lifespan;
|
||||
import ghidra.trace.model.Trace;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind.TraceBreakpointKindSet;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind.CommonSet;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointLocation;
|
||||
|
||||
@Category(NightlyCategory.class)
|
||||
@@ -76,8 +76,7 @@ public class DebuggerRmiBreakpointMarkerPluginTest
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
DBTraceObjectManager objs = tb.trace.getObjectManager();
|
||||
addMemoryRegion(objs, zeroOn, tb.range(0x55550000, 0x55550fff), "bin:.text", "rx");
|
||||
addBreakpointAndLoc(objs, zeroOn, tb.range(0x55550123),
|
||||
Set.of(TraceBreakpointKind.SW_EXECUTE));
|
||||
addBreakpointAndLoc(objs, zeroOn, tb.range(0x55550123), CommonSet.SWX.kinds());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,46 +84,46 @@ public class DebuggerRmiBreakpointMarkerPluginTest
|
||||
protected void handleSetBreakpointInvocation(Set<TraceBreakpointKind> expectedKinds,
|
||||
long dynOffset) throws Throwable {
|
||||
Lifespan zeroOn = Lifespan.nowOn(0);
|
||||
if (TraceBreakpointKindSet.READ.equals(expectedKinds)) {
|
||||
if (CommonSet.READ.kinds().equals(expectedKinds)) {
|
||||
Map<String, Object> args = rmiMethodSetReadBreak.expect();
|
||||
addBreakpointAndLoc(tb.trace.getObjectManager(), zeroOn, tb.range(dynOffset),
|
||||
TraceBreakpointKindSet.READ);
|
||||
CommonSet.READ.kinds());
|
||||
rmiMethodSetReadBreak.result(null);
|
||||
assertEquals(Map.ofEntries(
|
||||
Map.entry("process", tb.obj("Processes[1]")),
|
||||
Map.entry("range", tb.range(dynOffset))), args);
|
||||
}
|
||||
else if (TraceBreakpointKindSet.WRITE.equals(expectedKinds)) {
|
||||
else if (CommonSet.WRITE.kinds().equals(expectedKinds)) {
|
||||
Map<String, Object> args = rmiMethodSetWriteBreak.expect();
|
||||
addBreakpointAndLoc(tb.trace.getObjectManager(), zeroOn, tb.range(dynOffset),
|
||||
TraceBreakpointKindSet.WRITE);
|
||||
CommonSet.WRITE.kinds());
|
||||
rmiMethodSetWriteBreak.result(null);
|
||||
assertEquals(Map.ofEntries(
|
||||
Map.entry("process", tb.obj("Processes[1]")),
|
||||
Map.entry("range", tb.range(dynOffset))), args);
|
||||
}
|
||||
else if (TraceBreakpointKindSet.ACCESS.equals(expectedKinds)) {
|
||||
else if (CommonSet.ACCESS.kinds().equals(expectedKinds)) {
|
||||
Map<String, Object> args = rmiMethodSetAccessBreak.expect();
|
||||
addBreakpointAndLoc(tb.trace.getObjectManager(), zeroOn, tb.range(dynOffset),
|
||||
TraceBreakpointKindSet.ACCESS);
|
||||
CommonSet.ACCESS.kinds());
|
||||
rmiMethodSetAccessBreak.result(null);
|
||||
assertEquals(Map.ofEntries(
|
||||
Map.entry("process", tb.obj("Processes[1]")),
|
||||
Map.entry("range", tb.range(dynOffset))), args);
|
||||
}
|
||||
else if (TraceBreakpointKindSet.SW_EXECUTE.equals(expectedKinds)) {
|
||||
else if (CommonSet.SWX.kinds().equals(expectedKinds)) {
|
||||
Map<String, Object> args = rmiMethodSetSwBreak.expect();
|
||||
addBreakpointAndLoc(tb.trace.getObjectManager(), zeroOn, tb.range(dynOffset),
|
||||
TraceBreakpointKindSet.SW_EXECUTE);
|
||||
CommonSet.SWX.kinds());
|
||||
rmiMethodSetSwBreak.result(null);
|
||||
assertEquals(Map.ofEntries(
|
||||
Map.entry("process", tb.obj("Processes[1]")),
|
||||
Map.entry("address", tb.addr(dynOffset))), args);
|
||||
}
|
||||
else if (TraceBreakpointKindSet.HW_EXECUTE.equals(expectedKinds)) {
|
||||
else if (CommonSet.HWX.kinds().equals(expectedKinds)) {
|
||||
Map<String, Object> args = rmiMethodSetHwBreak.expect();
|
||||
addBreakpointAndLoc(tb.trace.getObjectManager(), zeroOn, tb.range(dynOffset),
|
||||
TraceBreakpointKindSet.HW_EXECUTE);
|
||||
CommonSet.HWX.kinds());
|
||||
rmiMethodSetHwBreak.result(null);
|
||||
assertEquals(Map.ofEntries(
|
||||
Map.entry("process", tb.obj("Processes[1]")),
|
||||
|
||||