GP-4546: Add 'Set breakpoint' multi-action to Breakpoints window.

This commit is contained in:
Dan
2025-02-06 13:15:45 +00:00
parent d23e67a088
commit fb9a7c62a2
44 changed files with 785 additions and 402 deletions

View File

@@ -17,11 +17,11 @@ from concurrent.futures import Future, ThreadPoolExecutor
import re
import sys
import lldb
from ghidratrace import sch
from ghidratrace.client import MethodRegistry, ParamDesc, Address, AddressRange
import lldb
from . import commands, util
@@ -248,7 +248,7 @@ def execute(cmd: str, to_string: bool=False):
return exec_convert_errors(cmd, to_string)
@REGISTRY.method
@REGISTRY.method(display='Evaluate')
def evaluate(expr: str):
"""Evaluate an expression."""
value = util.get_target().EvaluateExpression(expr)
@@ -257,7 +257,7 @@ def evaluate(expr: str):
return commands.convert_value(value)
@REGISTRY.method
@REGISTRY.method(display="Python Evaluate")
def pyeval(expr: str):
return eval(expr)
@@ -345,28 +345,28 @@ def refresh_modules(node: sch.Schema('ModuleContainer')):
exec_convert_errors('ghidra trace put-modules')
@REGISTRY.method(action='activate')
@REGISTRY.method(action='activate', display='Activate Process')
def activate_process(process: sch.Schema('Process')):
"""Switch to the process."""
# TODO
return
@REGISTRY.method(action='activate')
@REGISTRY.method(action='activate', display='Activate Thread')
def activate_thread(thread: sch.Schema('Thread')):
"""Switch to the thread."""
t = find_thread_by_obj(thread)
t.process.SetSelectedThread(t)
@REGISTRY.method(action='activate')
@REGISTRY.method(action='activate', display='Activate Frame')
def activate_frame(frame: sch.Schema('StackFrame')):
"""Select the frame."""
f = find_frame_by_obj(frame)
f.thread.SetSelectedFrame(f.GetFrameID())
@REGISTRY.method(action='delete')
@REGISTRY.method(action='delete', display='Remove Process')
def remove_process(process: sch.Schema('Process')):
"""Remove the process."""
proc = find_proc_by_obj(process)
@@ -442,7 +442,7 @@ def kill(process: sch.Schema('Process')):
exec_convert_errors('process kill')
@REGISTRY.method(name='continue', action='resume')
@REGISTRY.method(name='continue', action='resume', display="Continue")
def _continue(process: sch.Schema('Process')):
"""Continue execution of the process."""
exec_convert_errors('process continue')
@@ -510,7 +510,7 @@ def break_address(process: sch.Schema('Process'), address: Address):
exec_convert_errors(f'breakpoint set -a 0x{offset:x}')
@REGISTRY.method(action='break_sw_execute')
@REGISTRY.method(action='break_ext', display='Set Breakpoint')
def break_expression(expression: str):
"""Set a breakpoint."""
# TODO: Escape?
@@ -525,7 +525,7 @@ def break_hw_address(process: sch.Schema('Process'), address: Address):
exec_convert_errors(f'breakpoint set -H -a 0x{offset:x}')
@REGISTRY.method(action='break_hw_execute')
@REGISTRY.method(action='break_ext', display='Set Hardware Breakpoint')
def break_hw_expression(expression: str):
"""Set a hardware-assisted breakpoint."""
# TODO: Escape?
@@ -543,7 +543,7 @@ def break_read_range(process: sch.Schema('Process'), range: AddressRange):
f'watchpoint set expression -s {sz} -w read -- {offset_start}')
@REGISTRY.method(action='break_read')
@REGISTRY.method(action='break_ext', display='Set Read Watchpoint')
def break_read_expression(expression: str, size=None):
"""Set a read watchpoint."""
size_part = '' if size is None else f'-s {size}'
@@ -562,7 +562,7 @@ def break_write_range(process: sch.Schema('Process'), range: AddressRange):
f'watchpoint set expression -s {sz} -- {offset_start}')
@REGISTRY.method(action='break_write')
@REGISTRY.method(action='break_ext', display='Set Watchpoint')
def break_write_expression(expression: str, size=None):
"""Set a watchpoint."""
size_part = '' if size is None else f'-s {size}'
@@ -572,7 +572,7 @@ def break_write_expression(expression: str, size=None):
@REGISTRY.method(action='break_access')
def break_access_range(process: sch.Schema('Process'), range: AddressRange):
"""Set an access watchpoint."""
"""Set a read/write watchpoint."""
proc = find_proc_by_obj(process)
offset_start = process.trace.memory_mapper.map_back(
proc, Address(range.space, range.min))
@@ -581,9 +581,9 @@ def break_access_range(process: sch.Schema('Process'), range: AddressRange):
f'watchpoint set expression -s {sz} -w read_write -- {offset_start}')
@REGISTRY.method(action='break_access')
@REGISTRY.method(action='break_ext', display='Set Read/Write Watchpoint')
def break_access_expression(expression: str, size=None):
"""Set an access watchpoint."""
"""Set a read/write watchpoint."""
size_part = '' if size is None else f'-s {size}'
exec_convert_errors(
f'watchpoint set expression {size_part} -w read_write -- {expression}')
@@ -595,7 +595,7 @@ def break_exception(lang: str):
exec_convert_errors(f'breakpoint set -E {lang}')
@REGISTRY.method(action='toggle')
@REGISTRY.method(action='toggle', display='Toggle Watchpoint')
def toggle_watchpoint(watchpoint: sch.Schema('WatchpointSpec'), enabled: bool):
"""Toggle a watchpoint."""
wpt = find_wpt_by_obj(watchpoint)
@@ -604,7 +604,7 @@ def toggle_watchpoint(watchpoint: sch.Schema('WatchpointSpec'), enabled: bool):
exec_convert_errors(f'watchpoint {cmd} {wpt.GetID()}')
@REGISTRY.method(action='toggle')
@REGISTRY.method(action='toggle', display='Toggle Breakpoint')
def toggle_breakpoint(breakpoint: sch.Schema('BreakpointSpec'), enabled: bool):
"""Toggle a breakpoint."""
bpt = find_bpt_by_obj(breakpoint)
@@ -612,7 +612,7 @@ def toggle_breakpoint(breakpoint: sch.Schema('BreakpointSpec'), enabled: bool):
exec_convert_errors(f'breakpoint {cmd} {bpt.GetID()}')
@REGISTRY.method(action='toggle')
@REGISTRY.method(action='toggle', display='Toggle Breakpoint Location')
def toggle_breakpoint_location(location: sch.Schema('BreakpointLocation'), enabled: bool):
"""Toggle a breakpoint location."""
bptnum, locnum = find_bptlocnum_by_obj(location)
@@ -620,7 +620,7 @@ def toggle_breakpoint_location(location: sch.Schema('BreakpointLocation'), enabl
exec_convert_errors(f'breakpoint {cmd} {bptnum}.{locnum}')
@REGISTRY.method(action='delete')
@REGISTRY.method(action='delete', display='Delete Watchpoint')
def delete_watchpoint(watchpoint: sch.Schema('WatchpointSpec')):
"""Delete a watchpoint."""
wpt = find_wpt_by_obj(watchpoint)
@@ -628,7 +628,7 @@ def delete_watchpoint(watchpoint: sch.Schema('WatchpointSpec')):
exec_convert_errors(f'watchpoint delete {wptnum}')
@REGISTRY.method(action='delete')
@REGISTRY.method(action='delete', display='Delete Breakpoint')
def delete_breakpoint(breakpoint: sch.Schema('BreakpointSpec')):
"""Delete a breakpoint."""
bpt = find_bpt_by_obj(breakpoint)