diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/ghidradbg/commands.py b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/ghidradbg/commands.py index 3d5ca98918..ae0dcad242 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/ghidradbg/commands.py +++ b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/ghidradbg/commands.py @@ -1074,10 +1074,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) diff --git a/Ghidra/Debug/Debugger-agent-gdb/src/main/py/src/ghidragdb/commands.py b/Ghidra/Debug/Debugger-agent-gdb/src/main/py/src/ghidragdb/commands.py index c14668f920..376db6d4c5 100644 --- a/Ghidra/Debug/Debugger-agent-gdb/src/main/py/src/ghidragdb/commands.py +++ b/Ghidra/Debug/Debugger-agent-gdb/src/main/py/src/ghidragdb/commands.py @@ -1103,22 +1103,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', '') diff --git a/Ghidra/Debug/Debugger-agent-lldb/src/main/py/src/ghidralldb/commands.py b/Ghidra/Debug/Debugger-agent-lldb/src/main/py/src/ghidralldb/commands.py index 49868e3930..9b8dbd5faf 100644 --- a/Ghidra/Debug/Debugger-agent-lldb/src/main/py/src/ghidralldb/commands.py +++ b/Ghidra/Debug/Debugger-agent-lldb/src/main/py/src/ghidralldb/commands.py @@ -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) diff --git a/Ghidra/Debug/Debugger-agent-x64dbg/src/main/py/src/ghidraxdbg/commands.py b/Ghidra/Debug/Debugger-agent-x64dbg/src/main/py/src/ghidraxdbg/commands.py index 441909881f..51e82b542d 100644 --- a/Ghidra/Debug/Debugger-agent-x64dbg/src/main/py/src/ghidraxdbg/commands.py +++ b/Ghidra/Debug/Debugger-agent-x64dbg/src/main/py/src/ghidraxdbg/commands.py @@ -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() diff --git a/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/flatapi/FlatDebuggerAPI.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/flatapi/FlatDebuggerAPI.java index 40b0183c2d..e4f1e4e8e8 100644 --- a/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/flatapi/FlatDebuggerAPI.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/flatapi/FlatDebuggerAPI.java @@ -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 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 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 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 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 breakpointSetAccess(ProgramLocation location, int length, String name) { - return breakpointSet(location, length, TraceBreakpointKindSet.ACCESS, name); + return breakpointSet(location, length, CommonSet.ACCESS.kinds(), name); } /** diff --git a/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/tracermi/TraceRmiTarget.java b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/tracermi/TraceRmiTarget.java index 60c48eb119..467ec4f139 100644 --- a/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/tracermi/TraceRmiTarget.java +++ b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/tracermi/TraceRmiTarget.java @@ -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 placeBreakpointAsync(AddressRange range, Set kinds, String condition, String commands) { Set 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); diff --git a/Ghidra/Debug/Debugger/src/main/help/help/topics/Debugger/Troubleshooting.html b/Ghidra/Debug/Debugger/src/main/help/help/topics/Debugger/Troubleshooting.html index c646dfda9c..14cb545859 100644 --- a/Ghidra/Debug/Debugger/src/main/help/help/topics/Debugger/Troubleshooting.html +++ b/Ghidra/Debug/Debugger/src/main/help/help/topics/Debugger/Troubleshooting.html @@ -22,9 +22,8 @@

The first place to look when you're having trouble is the debugger's terminal. If you do not see one, check the Window → Terminals 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 Plugin Configuration if you suspect this is the - case.

+ is no back-end debugger running. See Plugin Configuration in case + your Debugger tool is misconfigured.

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 @@

Plugin Configuration

-

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.

+

It is possible you have an old or misconfigured Debugger tool. Try re-importing the default + Debugger tool.

Alternatively, use File → Configure then click the plug icon near the top right to check your tool configuration. The @@ -70,23 +68,6 @@

  • DebuggerModelPlugin
  • -

    The following should be disabled:

    - -
      -
    • DebuggerModelServicePlugin
    • - -
    • DebuggerModelServiceProxyPlugin
    • - -
    • DebuggerInterpretersPlugin
    • - -
    • DebuggerObjectsPlugin
    • - -
    • DebuggerTargetsPlugin
    • -
    - -

    It is possible to leave both sets of plugins enabled, but this is by all means NOT - recommended.

    -

    Tutorial

    Additional troubleshooting recommendations are given in the Debugger course materials.

    diff --git a/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerBreakpointMarkerPlugin/DebuggerBreakpointMarkerPlugin.html b/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerBreakpointMarkerPlugin/DebuggerBreakpointMarkerPlugin.html index 13b8fd7d2e..7160e660ae 100644 --- a/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerBreakpointMarkerPlugin/DebuggerBreakpointMarkerPlugin.html +++ b/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerBreakpointMarkerPlugin/DebuggerBreakpointMarkerPlugin.html @@ -88,11 +88,10 @@

    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.

    + 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.

    @@ -106,9 +105,9 @@ to 1 — often the required value. For access breakpoints, this defaults to the size of the data at the cursor. -
  • 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.
  • +
  • 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.
  • Name - the user-defined name of the breakpoint. The name is set on the bookmark at its static location, if applicable.
  • diff --git a/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerBreakpointMarkerPlugin/images/DebuggerPlaceBreakpointDialog.png b/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerBreakpointMarkerPlugin/images/DebuggerPlaceBreakpointDialog.png index f50f8b2fc2..07304adb8b 100644 Binary files a/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerBreakpointMarkerPlugin/images/DebuggerPlaceBreakpointDialog.png and b/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerBreakpointMarkerPlugin/images/DebuggerPlaceBreakpointDialog.png differ diff --git a/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerBreakpointsPlugin/DebuggerBreakpointsPlugin.html b/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerBreakpointsPlugin/DebuggerBreakpointsPlugin.html index 813e16dbd2..87b7d015e4 100644 --- a/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerBreakpointsPlugin/DebuggerBreakpointsPlugin.html +++ b/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerBreakpointsPlugin/DebuggerBreakpointsPlugin.html @@ -109,8 +109,8 @@
  • Length - usually 1. For access breakpoints, this is the length in bytes of the address range.
  • -
  • Kinds - indicates the kind(s) of breakpoint: SW_EXECUTE, HW_EXECUTE, READ, and/or - WRITE.
  • +
  • Kind - indicates the kind(s) of breakpoint: x, X, R, and/or W; respectively for software + execute, hardware execute, read, and/or write.
  • 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 diff --git a/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerBreakpointsPlugin/images/DebuggerBreakpointsPlugin.png b/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerBreakpointsPlugin/images/DebuggerBreakpointsPlugin.png index 5615abc9f6..7db6cdd19d 100644 Binary files a/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerBreakpointsPlugin/images/DebuggerBreakpointsPlugin.png and b/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerBreakpointsPlugin/images/DebuggerBreakpointsPlugin.png differ diff --git a/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerRegistersPlugin/images/DebuggerRegistersPlugin.png b/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerRegistersPlugin/images/DebuggerRegistersPlugin.png index a9ada72fbc..0d763e82d6 100644 Binary files a/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerRegistersPlugin/images/DebuggerRegistersPlugin.png and b/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerRegistersPlugin/images/DebuggerRegistersPlugin.png differ diff --git a/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerStackPlugin/images/DebuggerStackPlugin.png b/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerStackPlugin/images/DebuggerStackPlugin.png index b9f506af45..c6d919fc48 100644 Binary files a/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerStackPlugin/images/DebuggerStackPlugin.png and b/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerStackPlugin/images/DebuggerStackPlugin.png differ diff --git a/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerTimePlugin/images/DebuggerTimePlugin.png b/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerTimePlugin/images/DebuggerTimePlugin.png index 3b584931fa..230215b41d 100644 Binary files a/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerTimePlugin/images/DebuggerTimePlugin.png and b/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerTimePlugin/images/DebuggerTimePlugin.png differ diff --git a/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerTraceManagerServicePlugin/DebuggerTraceManagerServicePlugin.html b/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerTraceManagerServicePlugin/DebuggerTraceManagerServicePlugin.html index a8afd58c51..0e814b02f3 100644 --- a/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerTraceManagerServicePlugin/DebuggerTraceManagerServicePlugin.html +++ b/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerTraceManagerServicePlugin/DebuggerTraceManagerServicePlugin.html @@ -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.

    +

    Save Trace As

    + +

    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.

    +

    Close Trace

    This action is available whenever at least one trace is open and active. It closes the diff --git a/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerWatchesPlugin/DebuggerWatchesPlugin.html b/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerWatchesPlugin/DebuggerWatchesPlugin.html index b5906deb9d..6b060f478e 100644 --- a/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerWatchesPlugin/DebuggerWatchesPlugin.html +++ b/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerWatchesPlugin/DebuggerWatchesPlugin.html @@ -72,6 +72,8 @@

    • Expression - the user-modifiable Sleigh expression defining this watch.
    • +
    • Comment - a user-specified comment to describe or identify this watch.
    • +
    • 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 diff --git a/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerWatchesPlugin/images/DebuggerWatchesPlugin.png b/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerWatchesPlugin/images/DebuggerWatchesPlugin.png index 85692bc897..167adc8987 100644 Binary files a/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerWatchesPlugin/images/DebuggerWatchesPlugin.png and b/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerWatchesPlugin/images/DebuggerWatchesPlugin.png differ diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/BreakpointLocationRow.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/BreakpointLocationRow.java index 543972d6ea..fa62c67b82 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/BreakpointLocationRow.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/BreakpointLocationRow.java @@ -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()); } diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/BreakpointsDecompilerMarginProvider.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/BreakpointsDecompilerMarginProvider.java index 4335ad352d..7730c6fb8d 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/BreakpointsDecompilerMarginProvider.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/BreakpointsDecompilerMarginProvider.java @@ -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 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()); }); diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerBreakpointMarkerPlugin.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerBreakpointMarkerPlugin.java index 87dc1d831e..26ab4df201 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerBreakpointMarkerPlugin.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerBreakpointMarkerPlugin.java @@ -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 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 computeDefaultKinds(ActionContext ctx, + protected static CommonSet computeDefaultKind(ActionContext ctx, Collection 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 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 kinds; + private final CommonSet kind; - public SetBreakpointAction(Set 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 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 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 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(); diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerBreakpointsProvider.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerBreakpointsProvider.java index a4d22ca548..426f75fac7 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerBreakpointsProvider.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerBreakpointsProvider.java @@ -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), diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerPlaceBreakpointDialog.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerPlaceBreakpointDialog.java index 82af120089..7c70d7c984 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerPlaceBreakpointDialog.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerPlaceBreakpointDialog.java @@ -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 kinds; + private CommonSet kind; private String name; private JTextField fieldAddress; private JTextField fieldLength; - private JComboBox fieldKinds; + private JComboBox 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 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(kindModel); - fieldKinds.setEditable(true); - fieldKinds.getAccessibleContext().setAccessibleName("Kinds"); - panel.add(labelKinds); - panel.add(fieldKinds); + JLabel labelKind = new JLabel("Kind"); + labelKind.getAccessibleContext().setAccessibleName("Kind"); + DefaultComboBoxModel kindModel = new DefaultComboBoxModel<>(); + kindModel.addAll(CommonSet.VALUES); + fieldKind = new JComboBox(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 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); diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/LogicalBreakpointRow.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/LogicalBreakpointRow.java index edede8cb39..079a9b821a 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/LogicalBreakpointRow.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/LogicalBreakpointRow.java @@ -125,7 +125,7 @@ public class LogicalBreakpointRow { return lb.getDomainObject(); } - public String getKinds() { + public String getKind() { return TraceBreakpointKindSet.encode(lb.getKinds()); } diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/timeline/BreakpointTimelinePanel.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/timeline/BreakpointTimelinePanel.java index 672489271c..bf16963a13 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/timeline/BreakpointTimelinePanel.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/timeline/BreakpointTimelinePanel.java @@ -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 BREAKTYPE_TO_COLOR = Map.ofEntries( + private static final Map 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), diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/breakpoint/MappedLogicalBreakpoint.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/breakpoint/MappedLogicalBreakpoint.java index 3de1052ca1..63982ca362 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/breakpoint/MappedLogicalBreakpoint.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/breakpoint/MappedLogicalBreakpoint.java @@ -44,8 +44,7 @@ public class MappedLogicalBreakpoint implements LogicalBreakpointInternal { private final Map traceBreaks = new HashMap<>(); protected MappedLogicalBreakpoint(PluginTool tool, Program program, Address progAddr, - long length, - Collection kinds) { + long length, Collection kinds) { this.tool = tool; this.kinds = Set.copyOf(kinds); this.length = length; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/breakpoint/ProgramBreakpoint.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/breakpoint/ProgramBreakpoint.java index 2557d78e07..809e7af3d6 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/breakpoint/ProgramBreakpoint.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/breakpoint/ProgramBreakpoint.java @@ -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 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); diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/DebuggerEmulationServicePlugin.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/DebuggerEmulationServicePlugin.java index 480b7e6c7c..028826d517 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/DebuggerEmulationServicePlugin.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/DebuggerEmulationServicePlugin.java @@ -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; @@ -668,12 +669,8 @@ public class DebuggerEmulationServicePlugin extends Plugin implements DebuggerEm continue; } Set 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)); @@ -683,13 +680,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); } } diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/taint/EmulatorTaintState.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/taint/EmulatorTaintState.java index 2980aaf491..97c0988308 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/taint/EmulatorTaintState.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/taint/EmulatorTaintState.java @@ -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(); } diff --git a/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/memview/DebuggerMemviewPluginScreenShots.java b/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/memview/DebuggerMemviewPluginScreenShots.java index 32009c30aa..29f9529216 100644 --- a/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/memview/DebuggerMemviewPluginScreenShots.java +++ b/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/memview/DebuggerMemviewPluginScreenShots.java @@ -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 threads = new HashSet(); - Set kinds = new HashSet(); - 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"); } /* diff --git a/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/register/DebuggerRegistersPluginScreenShots.java b/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/register/DebuggerRegistersPluginScreenShots.java index de3541ae25..a1c0aba747 100644 --- a/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/register/DebuggerRegistersPluginScreenShots.java +++ b/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/register/DebuggerRegistersPluginScreenShots.java @@ -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); diff --git a/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/stack/DebuggerStackPluginScreenShots.java b/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/stack/DebuggerStackPluginScreenShots.java index f13d5a48f1..8c0b500065 100644 --- a/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/stack/DebuggerStackPluginScreenShots.java +++ b/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/stack/DebuggerStackPluginScreenShots.java @@ -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, diff --git a/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/stack/vars/VariableValueHoverPluginScreenShots.java b/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/stack/vars/VariableValueHoverPluginScreenShots.java index 0db2ced92a..6ee6a10b43 100644 --- a/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/stack/vars/VariableValueHoverPluginScreenShots.java +++ b/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/stack/vars/VariableValueHoverPluginScreenShots.java @@ -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, diff --git a/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/watch/DebuggerWatchesPluginScreenShots.java b/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/watch/DebuggerWatchesPluginScreenShots.java index a6bf3e56a3..e0876340da 100644 --- a/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/watch/DebuggerWatchesPluginScreenShots.java +++ b/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/watch/DebuggerWatchesPluginScreenShots.java @@ -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 executor0 = TraceSleighUtils.buildByteExecutor(tb.trace, snap0, thread, 0); diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/copying/DebuggerCopyPlanTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/copying/DebuggerCopyPlanTest.java index e0dd857e87..ea374a0873 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/copying/DebuggerCopyPlanTest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/copying/DebuggerCopyPlanTest.java @@ -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 diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/emulation/DebuggerEmulationServiceTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/emulation/DebuggerEmulationServiceTest.java index c3b01344ae..af0c8bf635 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/emulation/DebuggerEmulationServiceTest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/emulation/DebuggerEmulationServiceTest.java @@ -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(); diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/stack/StackUnwinderTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/stack/StackUnwinderTest.java index ef58704c3b..6dd0bc56f0 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/stack/StackUnwinderTest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/stack/StackUnwinderTest.java @@ -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 ; 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(); diff --git a/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/breakpoint/DBTraceBreakpointSpec.java b/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/breakpoint/DBTraceBreakpointSpec.java index b32d06961c..30b47867a6 100644 --- a/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/breakpoint/DBTraceBreakpointSpec.java +++ b/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/breakpoint/DBTraceBreakpointSpec.java @@ -96,8 +96,6 @@ public class DBTraceBreakpointSpec implements TraceBreakpointSpec, DBTraceObject @Override public void setKinds(Lifespan lifespan, Collection 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); diff --git a/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/model/breakpoint/TraceBreakpointKind.java b/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/model/breakpoint/TraceBreakpointKind.java index 4d6d0543f4..9e1bd40065 100644 --- a/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/model/breakpoint/TraceBreakpointKind.java +++ b/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/model/breakpoint/TraceBreakpointKind.java @@ -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 VALUES = List.of(values()); + public static final int COUNT = VALUES.size(); public static class TraceBreakpointKindSet extends AbstractSetDecorator { - 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. + *

      + * 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 result = EnumSet.noneOf(TraceBreakpointKind.class); - Set 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 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 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 + *

      * 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 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 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; } } diff --git a/Ghidra/Debug/Framework-TraceModeling/src/test/java/ghidra/trace/database/breakpoint/DBTraceBreakpointManagerTest.java b/Ghidra/Debug/Framework-TraceModeling/src/test/java/ghidra/trace/database/breakpoint/DBTraceBreakpointManagerTest.java index 7d6f428ff6..39371292cf 100644 --- a/Ghidra/Debug/Framework-TraceModeling/src/test/java/ghidra/trace/database/breakpoint/DBTraceBreakpointManagerTest.java +++ b/Ghidra/Debug/Framework-TraceModeling/src/test/java/ghidra/trace/database/breakpoint/DBTraceBreakpointManagerTest.java @@ -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 diff --git a/Ghidra/Test/DebuggerIntegrationTest/src/screen/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerBreakpointMarkerPluginScreenShots.java b/Ghidra/Test/DebuggerIntegrationTest/src/screen/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerBreakpointMarkerPluginScreenShots.java index 2dae502c33..6b95355dbb 100644 --- a/Ghidra/Test/DebuggerIntegrationTest/src/screen/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerBreakpointMarkerPluginScreenShots.java +++ b/Ghidra/Test/DebuggerIntegrationTest/src/screen/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerBreakpointMarkerPluginScreenShots.java @@ -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); } } diff --git a/Ghidra/Test/DebuggerIntegrationTest/src/screen/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerBreakpointsPluginScreenShots.java b/Ghidra/Test/DebuggerIntegrationTest/src/screen/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerBreakpointsPluginScreenShots.java index 3618e91f62..0ab812ebba 100644 --- a/Ghidra/Test/DebuggerIntegrationTest/src/screen/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerBreakpointsPluginScreenShots.java +++ b/Ghidra/Test/DebuggerIntegrationTest/src/screen/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerBreakpointsPluginScreenShots.java @@ -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); diff --git a/Ghidra/Test/DebuggerIntegrationTest/src/test.slow/java/agent/dbgeng/rmi/DbgEngCommandsTest.java b/Ghidra/Test/DebuggerIntegrationTest/src/test.slow/java/agent/dbgeng/rmi/DbgEngCommandsTest.java index 5fec3bdfa1..213ca5b3c0 100644 --- a/Ghidra/Test/DebuggerIntegrationTest/src/test.slow/java/agent/dbgeng/rmi/DbgEngCommandsTest.java +++ b/Ghidra/Test/DebuggerIntegrationTest/src/test.slow/java/agent/dbgeng/rmi/DbgEngCommandsTest.java @@ -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"); } } diff --git a/Ghidra/Test/DebuggerIntegrationTest/src/test.slow/java/agent/dbgeng/rmi/DbgEngMethodsTest.java b/Ghidra/Test/DebuggerIntegrationTest/src/test.slow/java/agent/dbgeng/rmi/DbgEngMethodsTest.java index dd7d636e98..5a6110108d 100644 --- a/Ghidra/Test/DebuggerIntegrationTest/src/test.slow/java/agent/dbgeng/rmi/DbgEngMethodsTest.java +++ b/Ghidra/Test/DebuggerIntegrationTest/src/test.slow/java/agent/dbgeng/rmi/DbgEngMethodsTest.java @@ -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"); } } } diff --git a/Ghidra/Test/DebuggerIntegrationTest/src/test.slow/java/agent/gdb/rmi/GdbCommandsTest.java b/Ghidra/Test/DebuggerIntegrationTest/src/test.slow/java/agent/gdb/rmi/GdbCommandsTest.java index 14f8f850dd..0115cc5c71 100644 --- a/Ghidra/Test/DebuggerIntegrationTest/src/test.slow/java/agent/gdb/rmi/GdbCommandsTest.java +++ b/Ghidra/Test/DebuggerIntegrationTest/src/test.slow/java/agent/gdb/rmi/GdbCommandsTest.java @@ -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))"); } } diff --git a/Ghidra/Test/DebuggerIntegrationTest/src/test.slow/java/agent/gdb/rmi/GdbMethodsTest.java b/Ghidra/Test/DebuggerIntegrationTest/src/test.slow/java/agent/gdb/rmi/GdbMethodsTest.java index 99dc9064c2..09925c7f4f 100644 --- a/Ghidra/Test/DebuggerIntegrationTest/src/test.slow/java/agent/gdb/rmi/GdbMethodsTest.java +++ b/Ghidra/Test/DebuggerIntegrationTest/src/test.slow/java/agent/gdb/rmi/GdbMethodsTest.java @@ -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))"); } } } diff --git a/Ghidra/Test/DebuggerIntegrationTest/src/test.slow/java/agent/lldb/rmi/LldbCommandsTest.java b/Ghidra/Test/DebuggerIntegrationTest/src/test.slow/java/agent/lldb/rmi/LldbCommandsTest.java index b2fd8285ea..0767f7084d 100644 --- a/Ghidra/Test/DebuggerIntegrationTest/src/test.slow/java/agent/lldb/rmi/LldbCommandsTest.java +++ b/Ghidra/Test/DebuggerIntegrationTest/src/test.slow/java/agent/lldb/rmi/LldbCommandsTest.java @@ -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"); } } diff --git a/Ghidra/Test/DebuggerIntegrationTest/src/test.slow/java/agent/lldb/rmi/LldbMethodsTest.java b/Ghidra/Test/DebuggerIntegrationTest/src/test.slow/java/agent/lldb/rmi/LldbMethodsTest.java index a8f27a9166..af42d81888 100644 --- a/Ghidra/Test/DebuggerIntegrationTest/src/test.slow/java/agent/lldb/rmi/LldbMethodsTest.java +++ b/Ghidra/Test/DebuggerIntegrationTest/src/test.slow/java/agent/lldb/rmi/LldbMethodsTest.java @@ -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(); } diff --git a/Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/app/plugin/core/debug/gui/breakpoint/AbstractDebuggerBreakpointMarkerPluginTest.java b/Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/app/plugin/core/debug/gui/breakpoint/AbstractDebuggerBreakpointMarkerPluginTest.java index 55c7f0cbd5..0a19fdfe0f 100644 --- a/Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/app/plugin/core/debug/gui/breakpoint/AbstractDebuggerBreakpointMarkerPluginTest.java +++ b/Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/app/plugin/core/debug/gui/breakpoint/AbstractDebuggerBreakpointMarkerPluginTest.java @@ -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 AbstractDisableBreakpointAction.NAME, AbstractClearBreakpointAction.NAME); protected static final Set 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 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 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 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 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 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 waitForPass(() -> assertEquals(State.ENABLED, lb.computeStateForTrace(trace))); } - protected void testActionSetBreakpointProgram(DockingAction action, - Set 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 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 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 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 } @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 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 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 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()); }); diff --git a/Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/app/plugin/core/debug/gui/breakpoint/AbstractDebuggerBreakpointsProviderTest.java b/Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/app/plugin/core/debug/gui/breakpoint/AbstractDebuggerBreakpointsProviderTest.java index b1abe437d6..020e43a58c 100644 --- a/Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/app/plugin/core/debug/gui/breakpoint/AbstractDebuggerBreakpointsProviderTest.java +++ b/Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/app/plugin/core/debug/gui/breakpoint/AbstractDebuggerBreakpointsProviderTest.java @@ -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 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 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 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 }); performAction(breakpointsProvider.actionMakeBreakpointsEffective); - handleSetBreakpointInvocation(TraceBreakpointKindSet.SW_EXECUTE, 0x55550123); + handleSetBreakpointInvocation(CommonSet.SWX.kinds(), 0x55550123); waitForPass(() -> { assertFalse(breakpointsProvider.actionMakeBreakpointsEffective.isEnabled()); diff --git a/Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerRmiBreakpointMarkerPluginTest.java b/Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerRmiBreakpointMarkerPluginTest.java index a152aa39c1..66f5a74d49 100644 --- a/Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerRmiBreakpointMarkerPluginTest.java +++ b/Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerRmiBreakpointMarkerPluginTest.java @@ -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 expectedKinds, long dynOffset) throws Throwable { Lifespan zeroOn = Lifespan.nowOn(0); - if (TraceBreakpointKindSet.READ.equals(expectedKinds)) { + if (CommonSet.READ.kinds().equals(expectedKinds)) { Map 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 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 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 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 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]")), diff --git a/Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerRmiBreakpointsProviderTest.java b/Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerRmiBreakpointsProviderTest.java index d780394a7a..cccf32b73b 100644 --- a/Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerRmiBreakpointsProviderTest.java +++ b/Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerRmiBreakpointsProviderTest.java @@ -28,7 +28,7 @@ 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.TraceBreakpointKindSet; +import ghidra.trace.model.breakpoint.TraceBreakpointKind.CommonSet; import ghidra.trace.model.breakpoint.TraceBreakpointLocation; import ghidra.trace.model.memory.TraceMemoryRegion; @@ -117,7 +117,7 @@ public class DebuggerRmiBreakpointsProviderTest Trace trace = target.getTrace(); try (Transaction tx = trace.openTransaction("Add breakpoint")) { addBreakpointAndLoc(trace.getObjectManager(), Lifespan.nowOn(0), tb.range(offset), - TraceBreakpointKindSet.SW_EXECUTE); + CommonSet.SWX.kinds()); } } @@ -125,10 +125,10 @@ public class DebuggerRmiBreakpointsProviderTest protected void handleSetBreakpointInvocation(Set expectedKinds, long dynOffset) throws Throwable { Lifespan zeroOn = Lifespan.nowOn(0); - if (TraceBreakpointKindSet.SW_EXECUTE.equals(expectedKinds)) { + if (CommonSet.SWX.kinds().equals(expectedKinds)) { Map 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]")), diff --git a/Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/app/plugin/core/debug/service/breakpoint/AbstractDebuggerLogicalBreakpointServiceTest.java b/Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/app/plugin/core/debug/service/breakpoint/AbstractDebuggerLogicalBreakpointServiceTest.java index cc993ecf7a..4489004c9a 100644 --- a/Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/app/plugin/core/debug/service/breakpoint/AbstractDebuggerLogicalBreakpointServiceTest.java +++ b/Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/app/plugin/core/debug/service/breakpoint/AbstractDebuggerLogicalBreakpointServiceTest.java @@ -42,6 +42,7 @@ import ghidra.program.util.ProgramLocation; import ghidra.trace.database.ToyDBTraceBuilder; import ghidra.trace.model.*; import ghidra.trace.model.breakpoint.*; +import ghidra.trace.model.breakpoint.TraceBreakpointKind.CommonSet; import ghidra.trace.model.memory.TraceMemoryFlag; import ghidra.trace.model.memory.TraceMemoryRegion; import ghidra.trace.model.target.TraceObject.ConflictResolution; @@ -263,10 +264,10 @@ public abstract class AbstractDebuggerLogicalBreakpointServiceTest try (Transaction tx = p.openTransaction("Create bookmarks")) { enBm = p.getBookmarkManager() .setBookmark(addr(p, 0x00400123), LogicalBreakpoint.ENABLED_BOOKMARK_TYPE, - "SW_EXECUTE;1", ""); + "x;1", ""); disBm = p.getBookmarkManager() .setBookmark(addr(p, 0x00400321), LogicalBreakpoint.DISABLED_BOOKMARK_TYPE, - "SW_EXECUTE;1", ""); + "x;1", ""); } waitForDomainObject(p); } @@ -274,11 +275,9 @@ public abstract class AbstractDebuggerLogicalBreakpointServiceTest protected void refetchProgramBreakpoints(Program p) throws Throwable { // After a redo enBm = p.getBookmarkManager() - .getBookmark(addr(p, 0x00400123), LogicalBreakpoint.ENABLED_BOOKMARK_TYPE, - "SW_EXECUTE;1"); + .getBookmark(addr(p, 0x00400123), LogicalBreakpoint.ENABLED_BOOKMARK_TYPE, "x;1"); disBm = p.getBookmarkManager() - .getBookmark(addr(p, 0x00400321), LogicalBreakpoint.DISABLED_BOOKMARK_TYPE, - "SW_EXECUTE;1"); + .getBookmark(addr(p, 0x00400321), LogicalBreakpoint.DISABLED_BOOKMARK_TYPE, "x;1"); } protected void removeProgramBreakpoints(Program p) throws Throwable { @@ -292,7 +291,7 @@ public abstract class AbstractDebuggerLogicalBreakpointServiceTest protected void assertLogicalBreakpointForLoneAccessBreakpoint(Trace trace) { LogicalBreakpoint enLb = Unique.assertOne(breakpointService.getAllBreakpoints()); assertNull(enLb.getProgramLocation()); - assertEquals(Set.of(TraceBreakpointKind.READ, TraceBreakpointKind.WRITE), enLb.getKinds()); + assertEquals(CommonSet.ACCESS.kinds(), enLb.getKinds()); TraceBreakpointLocation bpt = Unique.assertOne(trace.getBreakpointManager().getAllBreakpointLocations()); @@ -314,7 +313,7 @@ public abstract class AbstractDebuggerLogicalBreakpointServiceTest LogicalBreakpoint enLb = Unique.assertOne(breakpointService.getBreakpointsAt(trace, addr(trace, offset))); assertNull(enLb.getProgramLocation()); - assertEquals(Set.of(TraceBreakpointKind.SW_EXECUTE), enLb.getKinds()); + assertEquals(CommonSet.SWX.kinds(), enLb.getKinds()); TraceBreakpointLocation bpt = Unique.assertOne(trace.getBreakpointManager().getAllBreakpointLocations()); @@ -332,7 +331,7 @@ public abstract class AbstractDebuggerLogicalBreakpointServiceTest .assertOne(breakpointService.getBreakpointsAt(program, addr(program, 0x00400123))); assertNotNull(enLb.getProgramBookmark()); // Created automatically when trace breakpoint set. assertEquals(State.ENABLED, enLb.computeStateForProgram(program)); - assertEquals(Set.of(TraceBreakpointKind.SW_EXECUTE), enLb.getKinds()); + assertEquals(CommonSet.SWX.kinds(), enLb.getKinds()); TraceBreakpointLocation bpt = Unique.assertOne(trace.getBreakpointManager().getAllBreakpointLocations()); @@ -353,7 +352,7 @@ public abstract class AbstractDebuggerLogicalBreakpointServiceTest assertEquals(enBm, enLb.getProgramBookmark()); assertTrue(enLb.getMappedTraces().isEmpty()); assertEquals(State.INEFFECTIVE_ENABLED, enLb.computeStateForProgram(program)); - assertEquals(Set.of(TraceBreakpointKind.SW_EXECUTE), enLb.getKinds()); + assertEquals(CommonSet.SWX.kinds(), enLb.getKinds()); LogicalBreakpoint disLb = Unique .assertOne(breakpointService.getBreakpointsAt(program, addr(program, 0x00400321))); @@ -362,7 +361,7 @@ public abstract class AbstractDebuggerLogicalBreakpointServiceTest assertEquals(disBm, disLb.getProgramBookmark()); assertTrue(disLb.getMappedTraces().isEmpty()); assertEquals(State.INEFFECTIVE_DISABLED, disLb.computeStateForProgram(program)); - assertEquals(Set.of(TraceBreakpointKind.SW_EXECUTE), disLb.getKinds()); + assertEquals(CommonSet.SWX.kinds(), disLb.getKinds()); } protected void assertLogicalBreakpointsForMappedBookmarks(Trace trace) { @@ -1509,7 +1508,7 @@ public abstract class AbstractDebuggerLogicalBreakpointServiceTest try (Transaction tid = p.openTransaction("Create bookmark bp with sleigh")) { enBm = p.getBookmarkManager() .setBookmark(addr(p, 0x00400123), LogicalBreakpoint.ENABLED_BOOKMARK_TYPE, - "SW_EXECUTE;1", "{sleigh: 'r0=0xbeef;'}"); + "x;1", "{sleigh: 'r0=0xbeef;'}"); } waitForDomainObject(p); } @@ -1606,7 +1605,7 @@ public abstract class AbstractDebuggerLogicalBreakpointServiceTest tb.createRootObject(SCHEMA_CTX); TraceBreakpointLocation bpt = tb.trace.getBreakpointManager() .addBreakpoint("Processes[1].Breakpoints[0][0]", Lifespan.nowOn(0), - tb.addr(0x55550123), Set.of(), Set.of(TraceBreakpointKind.SW_EXECUTE), + tb.addr(0x55550123), Set.of(), CommonSet.SWX.kinds(), false /* emuEnabled defaults to true */, ""); bpt.setEmuSleigh(0, "r0=0xbeef;"); } @@ -1661,7 +1660,7 @@ public abstract class AbstractDebuggerLogicalBreakpointServiceTest TraceBreakpointLocation bpt = tb.trace.getBreakpointManager() .addBreakpoint("Processes[1].Breakpoints[0]", Lifespan.nowOn(0), tb.addr(0x55550123), - Set.of(), Set.of(TraceBreakpointKind.SW_EXECUTE), + Set.of(), CommonSet.SWX.kinds(), false /* emuEnabled defaults to true */, ""); bpt.setEmuSleigh(0, "r0=0xbeef;"); waitForValue(() -> Unique.assertAtMostOne( diff --git a/Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/app/plugin/core/debug/service/breakpoint/DebuggerRmiLogicalBreakpointServiceTest.java b/Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/app/plugin/core/debug/service/breakpoint/DebuggerRmiLogicalBreakpointServiceTest.java index b13e36a531..0254e2b91e 100644 --- a/Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/app/plugin/core/debug/service/breakpoint/DebuggerRmiLogicalBreakpointServiceTest.java +++ b/Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/app/plugin/core/debug/service/breakpoint/DebuggerRmiLogicalBreakpointServiceTest.java @@ -40,7 +40,7 @@ import ghidra.program.util.ProgramLocation; import ghidra.trace.database.ToyDBTraceBuilder; 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.memory.TraceMemoryRegion; import ghidra.trace.model.modules.TraceStaticMapping; import ghidra.trace.model.target.TraceObject; @@ -178,7 +178,7 @@ public class DebuggerRmiLogicalBreakpointServiceTest extends Trace trace = target.getTrace(); try (Transaction tx = trace.openTransaction("Add access breakpoint")) { addBreakpointAndLoc(trace.getObjectManager(), Lifespan.nowOn(target.getSnap()), - tb.range(min, min), TraceBreakpointKindSet.ACCESS); + tb.range(min, min), CommonSet.ACCESS.kinds()); } waitForDomainObject(trace); } @@ -190,7 +190,7 @@ public class DebuggerRmiLogicalBreakpointServiceTest extends Trace trace = target.getTrace(); try (Transaction tx = trace.openTransaction("Add software breakpoint")) { addBreakpointAndLoc(trace.getObjectManager(), Lifespan.nowOn(target.getSnap()), - tb.range(min, min), TraceBreakpointKindSet.SW_EXECUTE, id); + tb.range(min, min), CommonSet.SWX.kinds(), id); } waitForDomainObject(trace); } @@ -203,7 +203,7 @@ public class DebuggerRmiLogicalBreakpointServiceTest extends List locsToDel = trace.getBreakpointManager() .getAllBreakpointLocations() .stream() - .filter(loc -> loc.getKinds(snap).equals(TraceBreakpointKindSet.SW_EXECUTE)) + .filter(loc -> loc.getKinds(snap).equals(CommonSet.SWX.kinds())) .toList(); List specsToDel = locsToDel.stream().map(bp -> bp.getSpecification()).distinct().toList(); @@ -279,7 +279,7 @@ public class DebuggerRmiLogicalBreakpointServiceTest extends tb.createRootObject(SCHEMA_CTX); bpt = tb.trace.getBreakpointManager() .addBreakpoint("Processes[1].Breakpoints[0][0]", Lifespan.nowOn(0), - tb.addr(0x55550123), Set.of(), Set.of(TraceBreakpointKind.SW_EXECUTE), + tb.addr(0x55550123), Set.of(), CommonSet.SWX.kinds(), false, ""); } waitForDomainObject(tb.trace); @@ -323,7 +323,7 @@ public class DebuggerRmiLogicalBreakpointServiceTest extends tb.createRootObject(SCHEMA_CTX); bpt = tb.trace.getBreakpointManager() .addBreakpoint("Processes[1].Breakpoints[0][0]", Lifespan.nowOn(0), - tb.addr(0x55550123), Set.of(), Set.of(TraceBreakpointKind.SW_EXECUTE), + tb.addr(0x55550123), Set.of(), CommonSet.SWX.kinds(), false, ""); } waitForDomainObject(tb.trace); @@ -379,7 +379,7 @@ public class DebuggerRmiLogicalBreakpointServiceTest extends tb.createRootObject(SCHEMA_CTX); bpt = tb.trace.getBreakpointManager() .addBreakpoint("Processes[1].Breakpoints[0][0]", Lifespan.nowOn(0), - tb.addr(0x55550123), Set.of(), Set.of(TraceBreakpointKind.SW_EXECUTE), + tb.addr(0x55550123), Set.of(), CommonSet.SWX.kinds(), false, ""); addTextMappingDead(0, program, tb); } @@ -431,7 +431,7 @@ public class DebuggerRmiLogicalBreakpointServiceTest extends tb.createRootObject(SCHEMA_CTX); bpt = tb.trace.getBreakpointManager() .addBreakpoint("Processes[1].Breakpoints[0][0]", Lifespan.nowOn(0), - tb.addr(0x55550123), Set.of(), Set.of(TraceBreakpointKind.SW_EXECUTE), + tb.addr(0x55550123), Set.of(), CommonSet.SWX.kinds(), false, ""); addTextMappingDead(0, program, tb); } diff --git a/Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/debug/flatapi/AbstractFlatDebuggerAPITest.java b/Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/debug/flatapi/AbstractFlatDebuggerAPITest.java index 9e53b6ad3e..ee97b43919 100644 --- a/Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/debug/flatapi/AbstractFlatDebuggerAPITest.java +++ b/Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/debug/flatapi/AbstractFlatDebuggerAPITest.java @@ -44,7 +44,7 @@ import ghidra.trace.database.ToyDBTraceBuilder.ToySchemaBuilder; import ghidra.trace.database.memory.DBTraceMemoryManager; import ghidra.trace.database.memory.DBTraceMemorySpace; 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.target.schema.SchemaContext; import ghidra.trace.model.thread.TraceThread; @@ -296,7 +296,7 @@ public abstract class AbstractFlatDebuggerAPITest CompletableFuture changesSettled = breakpointService.changesSettled(); waitOn(breakpointService.placeBreakpointAt(program, addr(program, 0x00400000), 1, - Set.of(TraceBreakpointKind.SW_EXECUTE), "name")); + CommonSet.SWX.kinds(), "name")); waitForSwing(); waitOn(changesSettled); } diff --git a/Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/debug/flatapi/DeadFlatDebuggerAPITest.java b/Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/debug/flatapi/DeadFlatDebuggerAPITest.java index 3cb1c63c9a..e1d3541d07 100644 --- a/Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/debug/flatapi/DeadFlatDebuggerAPITest.java +++ b/Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/debug/flatapi/DeadFlatDebuggerAPITest.java @@ -32,7 +32,7 @@ import ghidra.debug.api.breakpoint.LogicalBreakpoint.State; import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.program.model.address.Address; import ghidra.trace.model.Trace; -import ghidra.trace.model.breakpoint.TraceBreakpointKind.TraceBreakpointKindSet; +import ghidra.trace.model.breakpoint.TraceBreakpointKind.CommonSet; import ghidra.trace.model.stack.TraceStack; import ghidra.trace.model.thread.TraceThread; import ghidra.trace.model.time.schedule.TraceSchedule; @@ -460,7 +460,7 @@ public class DeadFlatDebuggerAPITest extends AbstractFlatDebuggerAPITest

    • The next column Length gives the length of the breakpoint. In GDB, this generally applies to watchpoints only.
    • -
    • The next column Kinds gives the kinds of +
    • The next column Kind gives the kind(s) of breakpoint. Most breakpoints are software execution breakpoints, -indicated by “SW_EXECUTE.” That is, they are implemented by patching the -target’s memory with a special instruction that traps execution — -INT3 on x86. There are also hardware execution breakpoints -indicated by “HW_EXECUTE,” and access breakpoints indicated by “HW_READ” -and/or “HW_WRITE”. NOTE: GDB would call access -breakpoints watchpoints. An advantage to software breakpoints -is that you can have a practically unlimited number of them. Some -disadvantages are they can be detected easily, and they are limited to -execution breakpoints.
    • +indicated by (lower case) x. That is, they are implemented +by patching the target’s memory with a special instruction that traps +execution — INT3 on x86. There are also hardware execution +breakpoints indicated by (upper case) X and access +breakpoints indicated by R and/or W. +NOTE: GDB would call access breakpoints +watchpoints. An advantage to software breakpoints is that you +can have a practically unlimited number of them. Some disadvantages are +they can be detected easily, and they are limited to execution +breakpoints.
    • The next column Locations counts the number of locations for the breakpoint. For a single-target session, this is most likely 1.
    • diff --git a/GhidraDocs/GhidraClass/Debugger/A3-Breakpoints.md b/GhidraDocs/GhidraClass/Debugger/A3-Breakpoints.md index 3e4149b703..575f650178 100644 --- a/GhidraDocs/GhidraClass/Debugger/A3-Breakpoints.md +++ b/GhidraDocs/GhidraClass/Debugger/A3-Breakpoints.md @@ -68,10 +68,10 @@ This lists the *logical* breakpoints, preferring static addresses. Again, because the module has not been imported yet, this column is blank. * The next column **Length** gives the length of the breakpoint. In GDB, this generally applies to watchpoints only. -* The next column **Kinds** gives the kinds of breakpoint. - Most breakpoints are software execution breakpoints, indicated by "SW_EXECUTE." +* The next column **Kind** gives the kind(s) of breakpoint. + Most breakpoints are software execution breakpoints, indicated by (lower case) `x`. That is, they are implemented by patching the target's memory with a special instruction that traps execution — `INT3` on x86. - There are also hardware execution breakpoints indicated by "HW_EXECUTE," and access breakpoints indicated by "HW_READ" and/or "HW_WRITE". + There are also hardware execution breakpoints indicated by (upper case) `X` and access breakpoints indicated by `R` and/or `W`. **NOTE**: GDB would call access breakpoints *watchpoints*. An advantage to software breakpoints is that you can have a practically unlimited number of them. Some disadvantages are they can be detected easily, and they are limited to execution breakpoints. * The next column **Locations** counts the number of locations for the breakpoint. diff --git a/GhidraDocs/GhidraClass/Debugger/images/Breakpoints_EmptyAfterLaunch.png b/GhidraDocs/GhidraClass/Debugger/images/Breakpoints_EmptyAfterLaunch.png index f6a0e1bac2..a4f4aba8c6 100644 Binary files a/GhidraDocs/GhidraClass/Debugger/images/Breakpoints_EmptyAfterLaunch.png and b/GhidraDocs/GhidraClass/Debugger/images/Breakpoints_EmptyAfterLaunch.png differ diff --git a/GhidraDocs/GhidraClass/Debugger/images/Breakpoints_PopAfterSRandRand.png b/GhidraDocs/GhidraClass/Debugger/images/Breakpoints_PopAfterSRandRand.png index 7efe94e1d6..1bd4e7bc41 100644 Binary files a/GhidraDocs/GhidraClass/Debugger/images/Breakpoints_PopAfterSRandRand.png and b/GhidraDocs/GhidraClass/Debugger/images/Breakpoints_PopAfterSRandRand.png differ diff --git a/GhidraDocs/GhidraClass/Debugger/images/Breakpoints_SyncedAfterImportLibC.png b/GhidraDocs/GhidraClass/Debugger/images/Breakpoints_SyncedAfterImportLibC.png index adc879a90a..276f4f3c30 100644 Binary files a/GhidraDocs/GhidraClass/Debugger/images/Breakpoints_SyncedAfterImportLibC.png and b/GhidraDocs/GhidraClass/Debugger/images/Breakpoints_SyncedAfterImportLibC.png differ diff --git a/GhidraDocs/GhidraClass/Debugger/images/GettingStarted_DisassemblyAfterLaunch.png b/GhidraDocs/GhidraClass/Debugger/images/GettingStarted_DisassemblyAfterLaunch.png index 040063f276..7452c8006e 100644 Binary files a/GhidraDocs/GhidraClass/Debugger/images/GettingStarted_DisassemblyAfterLaunch.png and b/GhidraDocs/GhidraClass/Debugger/images/GettingStarted_DisassemblyAfterLaunch.png differ diff --git a/GhidraDocs/GhidraClass/Debugger/images/GettingStarted_ToolWSpecimen.png b/GhidraDocs/GhidraClass/Debugger/images/GettingStarted_ToolWSpecimen.png index ee759c57d5..d8d4549bb9 100644 Binary files a/GhidraDocs/GhidraClass/Debugger/images/GettingStarted_ToolWSpecimen.png and b/GhidraDocs/GhidraClass/Debugger/images/GettingStarted_ToolWSpecimen.png differ