From d5a25fa6a37e3a13ecec5bab440ba355aab2c472 Mon Sep 17 00:00:00 2001 From: Dan <46821332+nsadeveloper789@users.noreply.github.com> Date: Thu, 31 Oct 2024 11:50:38 -0400 Subject: [PATCH] GP-4906: Implement @image-opt. Have local-gdb use it. Fix 'null'. --- .../data/debugger-launchers/kernel-dbgeng.bat | 2 +- .../local-dbgeng-attach.bat | 6 +- .../debugger-launchers/local-dbgeng-ext.bat | 11 +- .../data/debugger-launchers/local-dbgeng.bat | 5 +- .../data/debugger-launchers/local-ttd.bat | 4 +- .../data/debugger-launchers/remote-dbgeng.bat | 5 +- .../Debugger-agent-gdb/certification.manifest | 1 - .../data/debugger-launchers/local-gdb.bat | 46 ++- .../data/debugger-launchers/local-gdb.sh | 80 +++-- .../data/debugger-launchers/qemu-gdb.bat | 3 +- .../data/debugger-launchers/qemu-gdb.sh | 3 +- .../data/debugger-launchers/raw-gdb.bat | 41 --- .../data/debugger-launchers/raw-gdb.sh | 57 ---- .../data/debugger-launchers/remote-gdb.bat | 11 +- .../data/debugger-launchers/remote-gdb.sh | 12 +- .../data/debugger-launchers/ssh-gdb.bat | 47 ++- .../data/debugger-launchers/ssh-gdb.sh | 49 ++- .../data/debugger-launchers/ssh-gdbserver.bat | 3 +- .../data/debugger-launchers/ssh-gdbserver.sh | 5 +- .../data/debugger-launchers/wine-gdb.sh | 31 +- .../data/debugger-launchers/local-lldb.bat | 33 +- .../data/debugger-launchers/local-lldb.sh | 58 ++-- .../data/debugger-launchers/remote-lldb.sh | 30 +- .../main/java/ghidra/debug/api/ValStr.java | 15 + .../api/tracermi/TraceRmiLaunchOffer.java | 21 +- .../data/debugger-launchers/raw-python3.sh | 27 +- .../AbstractScriptTraceRmiLaunchOffer.java | 4 +- .../launcher/AbstractTraceRmiLaunchOffer.java | 27 +- .../launcher/ScriptAttributesParser.java | 311 +++++++++--------- .../gui/AbstractDebuggerParameterDialog.java | 3 + .../launcher/TestTraceRmiLaunchOpinion.java | 8 +- 31 files changed, 497 insertions(+), 462 deletions(-) delete mode 100644 Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/raw-gdb.bat delete mode 100755 Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/raw-gdb.sh diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/data/debugger-launchers/kernel-dbgeng.bat b/Ghidra/Debug/Debugger-agent-dbgeng/data/debugger-launchers/kernel-dbgeng.bat index f34c4d4ba7..3b8fea1998 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/data/debugger-launchers/kernel-dbgeng.bat +++ b/Ghidra/Debug/Debugger-agent-dbgeng/data/debugger-launchers/kernel-dbgeng.bat @@ -9,7 +9,7 @@ ::@menu-group local ::@icon icon.debugger ::@help TraceRmiLauncherServicePlugin#dbgeng_kernel -::@env OPT_PYTHON_EXE:file="python" "Python command" "The path to the Python 3 interpreter. Omit the full path to resolve using the system PATH." +::@env OPT_PYTHON_EXE:file!="python" "Python command" "The path to the Python 3 interpreter. Omit the full path to resolve using the system PATH." :: Use env instead of args, because "all args except first" is terrible to implement in batch ::@env OPT_TARGET_ARGS:str="" "Arguments" "Connection-string arguments (a la .server)" ::@env OPT_USE_DBGMODEL:bool=true "Use dbgmodel" "Load and use dbgmodel.dll if it is available." diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/data/debugger-launchers/local-dbgeng-attach.bat b/Ghidra/Debug/Debugger-agent-dbgeng/data/debugger-launchers/local-dbgeng-attach.bat index 40b8c32d54..eb9e84b023 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/data/debugger-launchers/local-dbgeng-attach.bat +++ b/Ghidra/Debug/Debugger-agent-dbgeng/data/debugger-launchers/local-dbgeng-attach.bat @@ -9,9 +9,9 @@ ::@menu-group local ::@icon icon.debugger ::@help TraceRmiLauncherServicePlugin#dbgeng_attach -::@env OPT_PYTHON_EXE:file="python" "Python command" "The path to the Python 3 interpreter. Omit the full path to resolve using the system PATH." -::@env OPT_TARGET_PID:str="" "Process id" "The target process id" -::@env OPT_ATTACH_FLAGS:str="0" "Attach flags" "Attach flags" +::@env OPT_PYTHON_EXE:file!="python" "Python command" "The path to the Python 3 interpreter. Omit the full path to resolve using the system PATH." +::@env OPT_TARGET_PID:int="" "Process id" "The target process id" +::@env OPT_ATTACH_FLAGS:int="0" "Attach flags" "Attach flags" ::@env OPT_USE_DBGMODEL:bool=true "Use dbgmodel" "Load and use dbgmodel.dll if it is available." ::@env WINDBG_DIR:dir="" "Path to dbgeng.dll directory" "Path containing dbgeng and associated DLLS (if not Windows Kits)." diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/data/debugger-launchers/local-dbgeng-ext.bat b/Ghidra/Debug/Debugger-agent-dbgeng/data/debugger-launchers/local-dbgeng-ext.bat index 4bd01784e3..db407068d1 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/data/debugger-launchers/local-dbgeng-ext.bat +++ b/Ghidra/Debug/Debugger-agent-dbgeng/data/debugger-launchers/local-dbgeng-ext.bat @@ -1,4 +1,5 @@ ::@title dbgeng-ext +::@image-opt env:OPT_TARGET_IMG ::@desc ::@desc

Launch with dbgeng (in a Python interpreter)

::@desc

@@ -9,17 +10,17 @@ ::@menu-group local ::@icon icon.debugger ::@help TraceRmiLauncherServicePlugin#dbgeng_ext -::@env OPT_PYTHON_EXE:file="python" "Python command" "The path to the Python 3 interpreter. Omit the full path to resolve using the system PATH." +::@env OPT_PYTHON_EXE:file!="python" "Python command" "The path to the Python 3 interpreter. Omit the full path to resolve using the system PATH." :: Use env instead of args, because "all args except first" is terrible to implement in batch -::@env OPT_TARGET_IMG:file="" "Image" "The target binary executable image" +::@env OPT_TARGET_IMG:file!="" "Image" "The target binary executable image" ::@env OPT_TARGET_ARGS:str="" "Arguments" "Command-line arguments to pass to the target" ::@env OPT_USE_DBGMODEL:bool=true "Use dbgmodel" "Load and use dbgmodel.dll if it is available." ::@env WINDBG_DIR:dir="" "Path to dbgeng.dll directory" "Path containing dbgeng and associated DLLS (if not Windows Kits)." ::@env OPT_TARGET_DIR:str="" "Dir" "Initial directory" ::@env OPT_TARGET_ENV:str="" "Env" "Environment variables (sep=/0)" -::@env OPT_CREATE_FLAGS:str="1" "Create flags" "Creation flags" -::@env OPT_CREATE_ENGFLAGS:str="0" "Create flags (Engine)" "Engine-specific creation flags" -::@env OPT_VERIFIER_FLAGS:str="0" "Verifier flags" "Verifier flags" +::@env OPT_CREATE_FLAGS:int="1" "Create flags" "Creation flags" +::@env OPT_CREATE_ENGFLAGS:int="0" "Create flags (Engine)" "Engine-specific creation flags" +::@env OPT_VERIFIER_FLAGS:int="0" "Verifier flags" "Verifier flags" @echo off diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/data/debugger-launchers/local-dbgeng.bat b/Ghidra/Debug/Debugger-agent-dbgeng/data/debugger-launchers/local-dbgeng.bat index 328e45d93f..8557a6e9b6 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/data/debugger-launchers/local-dbgeng.bat +++ b/Ghidra/Debug/Debugger-agent-dbgeng/data/debugger-launchers/local-dbgeng.bat @@ -1,4 +1,5 @@ ::@title dbgeng +::@image-opt env:OPT_TARGET_IMG ::@desc ::@desc

Launch with dbgeng (in a Python interpreter)

::@desc

@@ -9,9 +10,9 @@ ::@menu-group local ::@icon icon.debugger ::@help TraceRmiLauncherServicePlugin#dbgeng -::@env OPT_PYTHON_EXE:file="python" "Python command" "The path to the Python 3 interpreter. Omit the full path to resolve using the system PATH." +::@env OPT_PYTHON_EXE:file!="python" "Python command" "The path to the Python 3 interpreter. Omit the full path to resolve using the system PATH." :: Use env instead of args, because "all args except first" is terrible to implement in batch -::@env OPT_TARGET_IMG:file="" "Image" "The target binary executable image" +::@env OPT_TARGET_IMG:file!="" "Image" "The target binary executable image" ::@env OPT_TARGET_ARGS:str="" "Arguments" "Command-line arguments to pass to the target" ::@env OPT_USE_DBGMODEL:bool=true "Use dbgmodel" "Load and use dbgmodel.dll if it is available." ::@env WINDBG_DIR:dir="" "Path to dbgeng.dll directory" "Path containing dbgeng and associated DLLS (if not Windows Kits)." diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/data/debugger-launchers/local-ttd.bat b/Ghidra/Debug/Debugger-agent-dbgeng/data/debugger-launchers/local-ttd.bat index 70a316ad7b..7d6e277819 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/data/debugger-launchers/local-ttd.bat +++ b/Ghidra/Debug/Debugger-agent-dbgeng/data/debugger-launchers/local-ttd.bat @@ -9,9 +9,9 @@ ::@menu-group local ::@icon icon.debugger ::@help TraceRmiLauncherServicePlugin#dbgeng_ttd -::@env OPT_PYTHON_EXE:file="python" "Python command" "The path to the Python 3 interpreter. Omit the full path to resolve using the system PATH." +::@env OPT_PYTHON_EXE:file!="python" "Python command" "The path to the Python 3 interpreter. Omit the full path to resolve using the system PATH." :: Use env instead of args, because "all args except first" is terrible to implement in batch -::@env OPT_TARGET_IMG:file="" "Trace (.run)" "A trace associated with the target binary executable" +::@env OPT_TARGET_IMG:file!="" "Trace (.run)" "A trace associated with the target binary executable" ::@env OPT_TARGET_ARGS:str="" "Arguments" "Command-line arguments to pass to the target" ::@env OPT_USE_DBGMODEL:bool=true "Use dbgmodel" "Load and use dbgmodel.dll if it is available." ::@env OPT_DBGMODEL_PATH:dir="" "Path to dbgeng.dll & \\ttd" "Path containing dbgeng and associated DLLS (if not Windows Kits)." diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/data/debugger-launchers/remote-dbgeng.bat b/Ghidra/Debug/Debugger-agent-dbgeng/data/debugger-launchers/remote-dbgeng.bat index ac6588971d..14d4939504 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/data/debugger-launchers/remote-dbgeng.bat +++ b/Ghidra/Debug/Debugger-agent-dbgeng/data/debugger-launchers/remote-dbgeng.bat @@ -1,4 +1,5 @@ ::@title dbgeng-remote +::@image-opt env:OPT_TARGET_IMG ::@desc ::@desc

Launch with dbgeng remotely (in a Python interpreter)

::@desc

@@ -9,9 +10,9 @@ ::@menu-group local ::@icon icon.debugger ::@help TraceRmiLauncherServicePlugin#dbgeng_remote -::@env OPT_PYTHON_EXE:file="python" "Python command" "The path to the Python 3 interpreter. Omit the full path to resolve using the system PATH." +::@env OPT_PYTHON_EXE:file!="python" "Python command" "The path to the Python 3 interpreter. Omit the full path to resolve using the system PATH." :: Use env instead of args, because "all args except first" is terrible to implement in batch -::@env OPT_TARGET_IMG:file="" "Image" "The target binary executable image" +::@env OPT_TARGET_IMG:str!="" "Image" "The target binary executable image" ::@env OPT_TARGET_ARGS:str="" "Arguments" "Command-line arguments to pass to the target" ::@env OPT_CONNECT_STRING:str="" "Connection" "Connection-string arguments (a la dbgsrv args)" ::@env OPT_USE_DBGMODEL:bool=true "Use dbgmodel" "Load and use dbgmodel.dll if it is available." diff --git a/Ghidra/Debug/Debugger-agent-gdb/certification.manifest b/Ghidra/Debug/Debugger-agent-gdb/certification.manifest index a5d9bacee4..21bc251f6a 100644 --- a/Ghidra/Debug/Debugger-agent-gdb/certification.manifest +++ b/Ghidra/Debug/Debugger-agent-gdb/certification.manifest @@ -3,7 +3,6 @@ Module.manifest||GHIDRA||||END| data/debugger-launchers/local-gdb.bat||GHIDRA||||END| data/debugger-launchers/qemu-gdb.bat||GHIDRA||||END| -data/debugger-launchers/raw-gdb.bat||GHIDRA||||END| data/debugger-launchers/remote-gdb.bat||GHIDRA||||END| data/debugger-launchers/ssh-gdb.bat||GHIDRA||||END| data/debugger-launchers/ssh-gdbserver.bat||GHIDRA||||END| diff --git a/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/local-gdb.bat b/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/local-gdb.bat index 93a6104676..8765033567 100644 --- a/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/local-gdb.bat +++ b/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/local-gdb.bat @@ -1,4 +1,5 @@ ::@title gdb +::@image-opt env:OPT_TARGET_IMG ::@desc ::@desc

Launch with gdb

::@desc

@@ -14,6 +15,8 @@ ::@env OPT_TARGET_ARGS:str="" "Arguments" "Command-line arguments to pass to the target" ::@env OPT_GDB_PATH:file="gdb" "gdb command" "The path to gdb. Omit the full path to resolve using the system PATH." ::@env OPT_START_CMD:StartCmd="starti" "Run command" "The gdb command to actually run the target." +::@env OPT_ARCH:str="i386:x86-64" "Architecture" "Target architecture" + @echo off set PYTHONPATH0=%GHIDRA_HOME%\Ghidra\Debug\Debugger-agent-gdb\pypkg\src @@ -28,18 +31,31 @@ IF EXIST %GHIDRA_HOME%\ghidra\.git ( ) set PYTHONPATH=%PYTHONPATH1%;%PYTHONPATH0%;%PYTHONPATH% -"%OPT_GDB_PATH%" ^ - -q ^ - -ex "set pagination off" ^ - -ex "set confirm off" ^ - -ex "show version" ^ - -ex "python import ghidragdb" ^ - -ex "target exec %OPT_TARGET_IMG%" ^ - -ex "set args %OPT_TARGET_ARGS%" ^ - -ex "set inferior-tty %TTY_TARGET%" ^ - -ex "ghidra trace connect '%GHIDRA_TRACE_RMI_ADDR%'" ^ - -ex "ghidra trace start" ^ - -ex "ghidra trace sync-enable" ^ - -ex "%OPT_START_CMD%" ^ - -ex "set confirm on" ^ - -ex "set pagination on" +IF "%OPT_TARGET_IMG%"=="" ( + "%OPT_GDB_PATH%" ^ + -q ^ + -ex "set pagination off" ^ + -ex "set confirm off" ^ + -ex "show version" ^ + -ex "python import ghidragdb" ^ + -ex "ghidra trace connect '%GHIDRA_TRACE_RMI_ADDR%'" ^ + -ex "ghidra trace start" ^ + -ex "ghidra trace sync-enable" ^ + -ex "set confirm on" ^ + -ex "set pagination on" +) ELSE ( + "%OPT_GDB_PATH%" ^ + -q ^ + -ex "set pagination off" ^ + -ex "set confirm off" ^ + -ex "show version" ^ + -ex "python import ghidragdb" ^ + -ex "target exec %OPT_TARGET_IMG%" ^ + -ex "set args %OPT_TARGET_ARGS%" ^ + -ex "ghidra trace connect '%GHIDRA_TRACE_RMI_ADDR%'" ^ + -ex "ghidra trace start" ^ + -ex "ghidra trace sync-enable" ^ + -ex "%OPT_START_CMD%" ^ + -ex "set confirm on" ^ + -ex "set pagination on" +) diff --git a/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/local-gdb.sh b/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/local-gdb.sh index bb245940bd..2629d0e1ac 100755 --- a/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/local-gdb.sh +++ b/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/local-gdb.sh @@ -1,20 +1,21 @@ #!/usr/bin/bash ## ### -# IP: GHIDRA -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# IP: GHIDRA +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. ## #@title gdb +#@image-opt arg:1 #@desc #@desc

Launch with gdb

#@desc

@@ -26,10 +27,11 @@ #@icon icon.debugger #@help TraceRmiLauncherServicePlugin#gdb #@enum StartCmd:str run start starti -#@arg :file "Image" "The target binary executable image" +#@arg :file "Image" "The target binary executable image, empty for no target" #@args "Arguments" "Command-line arguments to pass to the target" #@env OPT_GDB_PATH:file="gdb" "gdb command" "The path to gdb. Omit the full path to resolve using the system PATH." #@env OPT_START_CMD:StartCmd="starti" "Run command" "The gdb command to actually run the target." +#@env OPT_ARCH:str="i386:x86-64" "Architecture" "Target architecture" #@env OPT_EXTRA_TTY:bool=false "Inferior TTY" "Provide a separate terminal emulator for the target." #@tty TTY_TARGET if env:OPT_EXTRA_TTY @@ -50,20 +52,38 @@ target_image="$1" shift target_args="$@" -# NOTE: Ghidra will leave TTY_TARGET empty, which gdb takes for the same terminal. +# Ghidra will leave TTY_TARGET empty when OPT_EXTRA_TTY is false. Gdb takes empty to mean the same terminal. -"$OPT_GDB_PATH" \ - -q \ - -ex "set pagination off" \ - -ex "set confirm off" \ - -ex "show version" \ - -ex "python import ghidragdb" \ - -ex "file \"$target_image\"" \ - -ex "set args $target_args" \ - -ex "set inferior-tty $TTY_TARGET" \ - -ex "ghidra trace connect \"$GHIDRA_TRACE_RMI_ADDR\"" \ - -ex "ghidra trace start" \ - -ex "ghidra trace sync-enable" \ - -ex "$OPT_START_CMD" \ - -ex "set confirm on" \ - -ex "set pagination on" +if [ -z "$target_image" ] +then + "$OPT_GDB_PATH" \ + -q \ + -ex "set pagination off" \ + -ex "set confirm off" \ + -ex "show version" \ + -ex "python import ghidragdb" \ + -ex "set architecture $OPT_ARCH" \ + -ex "set inferior-tty $TTY_TARGET" \ + -ex "ghidra trace connect \"$GHIDRA_TRACE_RMI_ADDR\"" \ + -ex "ghidra trace start" \ + -ex "ghidra trace sync-enable" \ + -ex "set confirm on" \ + -ex "set pagination on" +else + "$OPT_GDB_PATH" \ + -q \ + -ex "set pagination off" \ + -ex "set confirm off" \ + -ex "show version" \ + -ex "python import ghidragdb" \ + -ex "set architecture $OPT_ARCH" \ + -ex "file \"$target_image\"" \ + -ex "set args $target_args" \ + -ex "set inferior-tty $TTY_TARGET" \ + -ex "ghidra trace connect \"$GHIDRA_TRACE_RMI_ADDR\"" \ + -ex "ghidra trace start" \ + -ex "ghidra trace sync-enable" \ + -ex "$OPT_START_CMD" \ + -ex "set confirm on" \ + -ex "set pagination on" +fi diff --git a/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/qemu-gdb.bat b/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/qemu-gdb.bat index 5f4b132042..65416c29a5 100644 --- a/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/qemu-gdb.bat +++ b/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/qemu-gdb.bat @@ -1,4 +1,5 @@ ::@title qemu + gdb +::@image-opt env:OPT_TARGET_IMG ::@desc ::@desc

Launch with qemu and connect with gdb

::@desc

@@ -10,7 +11,7 @@ ::@menu-group cross ::@icon icon.debugger ::@help TraceRmiLauncherServicePlugin#gdb_qemu -::@env OPT_TARGET_IMG:file="" "Image" "The target binary executable image" +::@env OPT_TARGET_IMG:file!="" "Image" "The target binary executable image" ::@env OPT_TARGET_ARGS:str="" "Arguments" "Command-line arguments to pass to the target" ::@env GHIDRA_LANG_EXTTOOL_qemu:file="" "QEMU command" "The path to qemu for the target architecture." ::@env QEMU_GDB:int=1234 "QEMU Port" "Port for gdb connection to qemu" diff --git a/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/qemu-gdb.sh b/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/qemu-gdb.sh index 917211b024..d9b9b72255 100755 --- a/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/qemu-gdb.sh +++ b/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/qemu-gdb.sh @@ -15,6 +15,7 @@ # limitations under the License. ## #@title qemu + gdb +#@image-opt arg:1 #@desc #@desc

Launch with qemu and connect with gdb

#@desc

@@ -26,7 +27,7 @@ #@menu-group cross #@icon icon.debugger #@help TraceRmiLauncherServicePlugin#gdb_qemu -#@arg :file "Image" "The target binary executable image" +#@arg :file! "Image" "The target binary executable image" #@args "Arguments" "Command-line arguments to pass to the target" #@env GHIDRA_LANG_EXTTOOL_qemu:file="" "QEMU command" "The path to qemu for the target architecture." #@env QEMU_GDB:int=1234 "QEMU Port" "Port for gdb connection to qemu" diff --git a/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/raw-gdb.bat b/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/raw-gdb.bat deleted file mode 100644 index e64f0e96b3..0000000000 --- a/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/raw-gdb.bat +++ /dev/null @@ -1,41 +0,0 @@ -::@title raw gdb -::@no-image -::@desc -::@desc

Start gdb

-::@desc

-::@desc This will start gdb and connect to it. -::@desc It will not launch a target, so you can (must) set up your target manually. -::@desc For setup instructions, press F1. -::@desc

-::@desc -::@menu-group raw -::@icon icon.debugger -::@help TraceRmiLauncherServicePlugin#gdb_raw -::@env OPT_GDB_PATH:file="gdb" "gdb command" "The path to gdb. Omit the full path to resolve using the system PATH." -::@env OPT_ARCH:str="i386:x86-64" "Architecture" "Target architecture" - -@echo off -set PYTHONPATH0=%GHIDRA_HOME%\Ghidra\Debug\Debugger-agent-gdb\pypkg\src -set PYTHONPATH1=%GHIDRA_HOME%\Ghidra\Debug\Debugger-rmi-trace\pypkg\src -IF EXIST %GHIDRA_HOME%\.git ( - set PYTHONPATH0=%GHIDRA_HOME%\Ghidra\Debug\Debugger-agent-gdb\build\pypkg\src - set PYTHONPATH1=%GHIDRA_HOME%\Ghidra\Debug\Debugger-rmi-trace\build\pypkg\src -) -IF EXIST %GHIDRA_HOME%\ghidra\.git ( - set PYTHONPATH0=%GHIDRA_HOME%\ghidra\Ghidra\Debug\Debugger-agent-gdb\build\pypkg\src - set PYTHONPATH1=%GHIDRA_HOME%\ghidra\Ghidra\Debug\Debugger-rmi-trace\build\pypkg\src -) -set PYTHONPATH=%PYTHONPATH1%;%PYTHONPATH0%;%PYTHONPATH% - -"%OPT_GDB_PATH%" ^ - -q ^ - -ex "set pagination off" ^ - -ex "set confirm off" ^ - -ex "show version" ^ - -ex "python import ghidragdb" ^ - -ex "set architecture %OPT_ARCH%" ^ - -ex "ghidra trace connect '%GHIDRA_TRACE_RMI_ADDR%'" ^ - -ex "ghidra trace start" ^ - -ex "ghidra trace sync-enable" ^ - -ex "set confirm on" ^ - -ex "set pagination on" diff --git a/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/raw-gdb.sh b/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/raw-gdb.sh deleted file mode 100755 index 0ed99c1011..0000000000 --- a/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/raw-gdb.sh +++ /dev/null @@ -1,57 +0,0 @@ -#!/usr/bin/env bash -## ### -# IP: GHIDRA -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -## -#@title raw gdb -#@no-image -#@desc -#@desc

Start gdb

-#@desc

-#@desc This will start gdb and connect to it. -#@desc It will not launch a target, so you can (must) set up your target manually. -#@desc For setup instructions, press F1. -#@desc

-#@desc -#@menu-group raw -#@icon icon.debugger -#@help TraceRmiLauncherServicePlugin#gdb_raw -#@env OPT_GDB_PATH:file="gdb" "gdb command" "The path to gdb. Omit the full path to resolve using the system PATH." -#@env OPT_ARCH:str="i386:x86-64" "Architecture" "Target architecture" - -if [ -d ${GHIDRA_HOME}/ghidra/.git ] -then - export PYTHONPATH=$GHIDRA_HOME/ghidra/Ghidra/Debug/Debugger-agent-gdb/build/pypkg/src:$PYTHONPATH - export PYTHONPATH=$GHIDRA_HOME/ghidra/Ghidra/Debug/Debugger-rmi-trace/build/pypkg/src:$PYTHONPATH -elif [ -d ${GHIDRA_HOME}/.git ] -then - export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-agent-gdb/build/pypkg/src:$PYTHONPATH - export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-rmi-trace/build/pypkg/src:$PYTHONPATH -else - export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-agent-gdb/pypkg/src:$PYTHONPATH - export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-rmi-trace/pypkg/src:$PYTHONPATH -fi - -"$OPT_GDB_PATH" \ - -q \ - -ex "set pagination off" \ - -ex "set confirm off" \ - -ex "show version" \ - -ex "python import ghidragdb" \ - -ex "set architecture $OPT_ARCH" \ - -ex "ghidra trace connect \"$GHIDRA_TRACE_RMI_ADDR\"" \ - -ex "ghidra trace start" \ - -ex "ghidra trace sync-enable" \ - -ex "set confirm on" \ - -ex "set pagination on" diff --git a/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/remote-gdb.bat b/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/remote-gdb.bat index faf1f7310a..3fa80e731b 100644 --- a/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/remote-gdb.bat +++ b/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/remote-gdb.bat @@ -1,5 +1,4 @@ ::@title remote gdb -::@no-image ::@desc ::@desc

Launch with local gdb and connect to a stub (e.g., gdbserver)

::@desc

@@ -14,7 +13,7 @@ ::@env OPT_TARGET_TYPE:TargetType="remote" "Target" "The type of remote target" ::@env OPT_HOST:str="localhost" "Host" "The hostname of the target" ::@env OPT_PORT:int=9999 "Port" "The host's listening port" -::@env OPT_ARCH:str="" "Architecture (optional)" "Target architecture override" +::@env OPT_ARCH:str="auto" "Architecture" "Target architecture override" ::@env OPT_GDB_PATH:file="gdb" "gdb command" "The path to gdb on the local system. Omit the full path to resolve using the system PATH." @echo off @@ -30,19 +29,13 @@ IF EXIST %GHIDRA_HOME%\ghidra\.git ( ) set PYTHONPATH=%PYTHONPATH1%;%PYTHONPATH0%;%PYTHONPATH% -IF "%OPT_ARCH%"=="" ( - set archcmd= -) ELSE ( - set archcmd=-ex "set arch %OPT_ARCH%" -) - "%OPT_GDB_PATH%" ^ -q ^ -ex "set pagination off" ^ -ex "set confirm off" ^ -ex "show version" ^ -ex "python import ghidragdb" ^ - %archcmd% ^ + -ex "set arch %OPT_ARCH%" ^ -ex "echo Connecting to %OPT_HOST%:%OPT_PORT%... " ^ -ex "target %OPT_TARGET_TYPE% %OPT_HOST%:%OPT_PORT%" ^ -ex "ghidra trace connect '%GHIDRA_TRACE_RMI_ADDR%'" ^ diff --git a/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/remote-gdb.sh b/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/remote-gdb.sh index 3048e2a217..909c033efd 100755 --- a/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/remote-gdb.sh +++ b/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/remote-gdb.sh @@ -15,7 +15,6 @@ # limitations under the License. ## #@title remote gdb -#@no-image #@desc #@desc

Launch with local gdb and connect to a stub (e.g., gdbserver)

#@desc

@@ -30,7 +29,7 @@ #@env OPT_TARGET_TYPE:TargetType="remote" "Target" "The type of remote target" #@env OPT_HOST:str="localhost" "Host" "The hostname of the target" #@env OPT_PORT:int=9999 "Port" "The host's listening port" -#@env OPT_ARCH:str="" "Architecture (optional)" "Target architecture override" +#@env OPT_ARCH:str="auto" "Architecture" "Target architecture override" #@env OPT_GDB_PATH:file="gdb" "gdb command" "The path to gdb on the local system. Omit the full path to resolve using the system PATH." if [ -d ${GHIDRA_HOME}/ghidra/.git ] @@ -46,20 +45,13 @@ else export PYTHONPATH=$GHIDRA_HOME/Ghidra/Debug/Debugger-rmi-trace/pypkg/src:$PYTHONPATH fi -if [ -z "$OPT_ARCH" ] -then - archcmd= -else - archcmd=-ex "set arch $OPT_ARCH" -fi - "$OPT_GDB_PATH" \ -q \ -ex "set pagination off" \ -ex "set confirm off" \ -ex "show version" \ -ex "python import ghidragdb" \ - $archcmd \ + -ex "set arch $OPT_ARCH" \ -ex "echo Connecting to $OPT_HOST:$OPT_PORT... " \ -ex "target $OPT_TARGET_TYPE $OPT_HOST:$OPT_PORT" \ -ex "ghidra trace connect \"$GHIDRA_TRACE_RMI_ADDR\"" \ diff --git a/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/ssh-gdb.bat b/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/ssh-gdb.bat index ff7820d634..1f4f986fa4 100644 --- a/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/ssh-gdb.bat +++ b/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/ssh-gdb.bat @@ -1,5 +1,6 @@ ::@timeout 60000 ::@title gdb via ssh +::@image-opt env:OPT_TARGET_IMG ::@desc ::@desc

Launch with gdb via ssh

::@desc

@@ -19,21 +20,39 @@ ::@env OPT_EXTRA_SSH_ARGS:str="" "Extra ssh arguments" "Extra arguments to pass to ssh. Use with care." ::@env OPT_GDB_PATH:str="gdb" "gdb command" "The path to gdb on the remote system. Omit the full path to resolve using the system PATH." ::@env OPT_START_CMD:StartCmd="starti" "Run command" "The gdb command to actually run the target." +::@env OPT_ARCH:str="i386:x86-64" "Architecture" "Target architecture" @echo off -set cmd=TERM='%TERM%' '%OPT_GDB_PATH%' ^ - -q ^ - -ex 'set pagination off' ^ - -ex 'set confirm off' ^ - -ex 'show version' ^ - -ex 'python import ghidragdb' ^ - -ex 'file \"%OPT_TARGET_IMG%\"' ^ - -ex 'set args %OPT_TARGET_ARGS%' ^ - -ex 'ghidra trace connect \"localhost:%OPT_REMOTE_PORT%\"' ^ - -ex 'ghidra trace start' ^ - -ex 'ghidra trace sync-enable' ^ - -ex '%OPT_START_CMD%' ^ - -ex 'set confirm on' ^ - -ex 'set pagination on' + +IF "%OPT_TARGET_IMG%" == "" ( + set cmd=TERM='%TERM%' '%OPT_GDB_PATH%' ^ + -q ^ + -ex 'set pagination off' ^ + -ex 'set confirm off' ^ + -ex 'show version' ^ + -ex 'python import ghidragdb' ^ + -ex 'set architecture %OPT_ARCH%' ^ + -ex 'ghidra trace connect \"localhost:%OPT_REMOTE_PORT%\"' ^ + -ex 'ghidra trace start' ^ + -ex 'ghidra trace sync-enable' ^ + -ex 'set confirm on' ^ + -ex 'set pagination on' +) ELSE ( + set cmd=TERM='%TERM%' '%OPT_GDB_PATH%' ^ + -q ^ + -ex 'set pagination off' ^ + -ex 'set confirm off' ^ + -ex 'show version' ^ + -ex 'python import ghidragdb' ^ + -ex 'set architecture %OPT_ARCH%' ^ + -ex 'file \"%OPT_TARGET_IMG%\"' ^ + -ex 'set args %OPT_TARGET_ARGS%' ^ + -ex 'ghidra trace connect \"localhost:%OPT_REMOTE_PORT%\"' ^ + -ex 'ghidra trace start' ^ + -ex 'ghidra trace sync-enable' ^ + -ex '%OPT_START_CMD%' ^ + -ex 'set confirm on' ^ + -ex 'set pagination on' +) "%OPT_SSH_PATH%" "-R%OPT_REMOTE_PORT%:%GHIDRA_TRACE_RMI_ADDR%" -t %OPT_EXTRA_SSH_ARGS% "%OPT_HOST%" "%cmd%" diff --git a/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/ssh-gdb.sh b/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/ssh-gdb.sh index 964fe9cf1b..372460ed00 100755 --- a/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/ssh-gdb.sh +++ b/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/ssh-gdb.sh @@ -16,6 +16,7 @@ ## #@timeout 60000 #@title gdb via ssh +#@image-opt arg:1 #@desc #@desc

Launch with gdb via ssh

#@desc

@@ -29,28 +30,46 @@ #@enum StartCmd:str run start starti #@arg :str "Image" "The target binary executable image on the remote system" #@args "Arguments" "Command-line arguments to pass to the target" -#@env OPT_SSH_PATH:file="ssh" "ssh command" "The path to ssh on the local system. Omit the full path to resolve using the system PATH." +#@env OPT_SSH_PATH:file!="ssh" "ssh command" "The path to ssh on the local system. Omit the full path to resolve using the system PATH." #@env OPT_HOST:str="localhost" "[User@]Host" "The hostname or user@host" #@env OPT_REMOTE_PORT:int=12345 "Remote Trace RMI Port" "A free port on the remote end to receive and forward the Trace RMI connection." #@env OPT_EXTRA_SSH_ARGS:str="" "Extra ssh arguments" "Extra arguments to pass to ssh. Use with care." #@env OPT_GDB_PATH:str="gdb" "gdb command" "The path to gdb on the remote system. Omit the full path to resolve using the system PATH." #@env OPT_START_CMD:StartCmd="starti" "Run command" "The gdb command to actually run the target." +#@env OPT_ARCH:str="i386:x86-64" "Architecture" "Target architecture" target_image="$1" shift target_args="$@" -"$OPT_SSH_PATH" "-R$OPT_REMOTE_PORT:$GHIDRA_TRACE_RMI_ADDR" -t $OPT_EXTRA_SSH_ARGS "$OPT_HOST" "TERM='$TERM' '$OPT_GDB_PATH' \ - -q \ - -ex 'set pagination off' \ - -ex 'set confirm off' \ - -ex 'show version' \ - -ex 'python import ghidragdb' \ - -ex 'file \"$target_image\"' \ - -ex 'set args $target_args' \ - -ex 'ghidra trace connect \"localhost:$OPT_REMOTE_PORT\"' \ - -ex 'ghidra trace start' \ - -ex 'ghidra trace sync-enable' \ - -ex '$OPT_START_CMD' \ - -ex 'set confirm on' \ - -ex 'set pagination on'" +if [ -z "$target_image" ] +then + "$OPT_SSH_PATH" "-R$OPT_REMOTE_PORT:$GHIDRA_TRACE_RMI_ADDR" -t $OPT_EXTRA_SSH_ARGS "$OPT_HOST" "TERM='$TERM' '$OPT_GDB_PATH' \ + -q \ + -ex 'set pagination off' \ + -ex 'set confirm off' \ + -ex 'show version' \ + -ex 'python import ghidragdb' \ + -ex 'set architecture $OPT_ARCH' \ + -ex 'ghidra trace connect \"localhost:$OPT_REMOTE_PORT\"' \ + -ex 'ghidra trace start' \ + -ex 'ghidra trace sync-enable' \ + -ex 'set confirm on' \ + -ex 'set pagination on'" +else + "$OPT_SSH_PATH" "-R$OPT_REMOTE_PORT:$GHIDRA_TRACE_RMI_ADDR" -t $OPT_EXTRA_SSH_ARGS "$OPT_HOST" "TERM='$TERM' '$OPT_GDB_PATH' \ + -q \ + -ex 'set pagination off' \ + -ex 'set confirm off' \ + -ex 'show version' \ + -ex 'python import ghidragdb' \ + -ex 'set architecture $OPT_ARCH' \ + -ex 'file \"$target_image\"' \ + -ex 'set args $target_args' \ + -ex 'ghidra trace connect \"localhost:$OPT_REMOTE_PORT\"' \ + -ex 'ghidra trace start' \ + -ex 'ghidra trace sync-enable' \ + -ex '$OPT_START_CMD' \ + -ex 'set confirm on' \ + -ex 'set pagination on'" +fi diff --git a/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/ssh-gdbserver.bat b/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/ssh-gdbserver.bat index 91c4cc48aa..e0f990455d 100644 --- a/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/ssh-gdbserver.bat +++ b/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/ssh-gdbserver.bat @@ -1,5 +1,6 @@ ::@timeout 60000 ::@title gdb + gdbserver via ssh +::@image-opt env:OPT_TARGET_IMG ::@desc ::@desc

Launch with local gdb and gdbserver via ssh

::@desc

@@ -10,7 +11,7 @@ ::@menu-group remote ::@icon icon.debugger ::@help TraceRmiLauncherServicePlugin#gdb_gdbserver_ssh -::@env OPT_TARGET_IMG:str="" "Image" "The target binary executable image on the remote system" +::@env OPT_TARGET_IMG:str!="" "Image" "The target binary executable image on the remote system" ::@env OPT_TARGET_ARGS:str="" "Arguments" "Command-line arguments to pass to the target" ::@env OPT_SSH_PATH:file="ssh" "ssh command" "The path to ssh on the local system. Omit the full path to resolve using the system PATH." ::@env OPT_HOST:str="localhost" "[User@]Host" "The hostname or user@host" diff --git a/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/ssh-gdbserver.sh b/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/ssh-gdbserver.sh index 4639d1b9d2..23a686a375 100755 --- a/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/ssh-gdbserver.sh +++ b/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/ssh-gdbserver.sh @@ -16,6 +16,7 @@ ## #@timeout 60000 #@title gdb + gdbserver via ssh +#@image-opt arg:1 #@desc #@desc

Launch with local gdb and gdbserver via ssh

#@desc

@@ -26,9 +27,9 @@ #@menu-group remote #@icon icon.debugger #@help TraceRmiLauncherServicePlugin#gdb_gdbserver_ssh -#@arg :str "Image" "The target binary executable image on the remote system" +#@arg :str! "Image" "The target binary executable image on the remote system" #@args "Arguments" "Command-line arguments to pass to the target" -#@env OPT_SSH_PATH:file="ssh" "ssh command" "The path to ssh on the local system. Omit the full path to resolve using the system PATH." +#@env OPT_SSH_PATH:file!="ssh" "ssh command" "The path to ssh on the local system. Omit the full path to resolve using the system PATH." #@env OPT_HOST:str="localhost" "[User@]Host" "The hostname or user@host" #@env OPT_EXTRA_SSH_ARGS:str="" "Extra ssh arguments" "Extra arguments to pass to ssh. Use with care." #@env OPT_GDBSERVER_PATH:str="gdbserver" "gdbserver command (remote)" "The path to gdbserver on the remote system. Omit the full path to resolve using the system PATH." diff --git a/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/wine-gdb.sh b/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/wine-gdb.sh index b8187b81f4..b5ea1cb570 100755 --- a/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/wine-gdb.sh +++ b/Ghidra/Debug/Debugger-agent-gdb/data/debugger-launchers/wine-gdb.sh @@ -1,20 +1,21 @@ #!/usr/bin/bash ## ### -# IP: GHIDRA -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# IP: GHIDRA +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. ## #@title wine + gdb +#@image-opt arg:1 #@desc #@desc

Launch with gdb and wine

#@desc

@@ -25,10 +26,11 @@ #@menu-group cross #@icon icon.debugger #@help TraceRmiLauncherServicePlugin#gdb_wine -#@arg :file "Image" "The target binary executable image" +#@arg :file! "Image" "The target binary executable image" #@args "Arguments" "Command-line arguments to pass to the target" #@env OPT_WINE_PATH:file="/usr/lib/wine/wine64" "Path to wine binary" "The path to the wine executable for your target architecture." #@env OPT_GDB_PATH:file="gdb" "gdb command" "The path to gdb. Omit the full path to resolve using the system PATH." +#@env OPT_ARCH:str="i386:x86-64" "Architecture" "Target architecture" #@env OPT_EXTRA_TTY:bool=false "Inferior TTY" "Provide a separate terminal emulator for the target." #@tty TTY_TARGET if env:OPT_EXTRA_TTY @@ -53,6 +55,7 @@ fi -ex "set confirm off" \ -ex "show version" \ -ex "python import ghidragdb.wine" \ + -ex "set architecture $OPT_ARCH" \ -ex "file \"$OPT_WINE_PATH\"" \ -ex "set args $@" \ -ex "set inferior-tty $TTY_TARGET" \ diff --git a/Ghidra/Debug/Debugger-agent-lldb/data/debugger-launchers/local-lldb.bat b/Ghidra/Debug/Debugger-agent-lldb/data/debugger-launchers/local-lldb.bat index 66c9e5c584..a422bec4df 100644 --- a/Ghidra/Debug/Debugger-agent-lldb/data/debugger-launchers/local-lldb.bat +++ b/Ghidra/Debug/Debugger-agent-lldb/data/debugger-launchers/local-lldb.bat @@ -1,4 +1,5 @@ ::@title lldb +::@image-opt arg:1 ::@desc ::@desc

Launch with lldb

::@desc

@@ -14,8 +15,6 @@ ::@args "Arguments" "Command-line arguments to pass to the target" ::@env OPT_LLDB_PATH:file="lldb" "lldb command" "The path to lldb. Omit the full path to resolve using the system PATH." ::@env OPT_START_CMD:StartCmd="process launch" "Run command" "The lldb command to actually run the target." -::@env OPT_EXTRA_TTY:bool=false "Target TTY" "Provide a separate terminal emulator for the target." -::@tty TTY_TARGET if env:OPT_EXTRA_TTY @echo off set PYTHONPATH0=%GHIDRA_HOME%\Ghidra\Debug\Debugger-agent-gdb\pypkg\src @@ -38,17 +37,21 @@ IF DEFINED target_args ( argspart=-o "settings set target.run-args %target_args%" ) -IF DEFINED TARGET_TTY ( - ttypart=-o "settings set target.output-path %TTY_TARGET%" -o "settings set target.input-path $TTY_TARGET" +IF "%target_image%"=="" ( + "%OPT_LLDB_PATH%" ^ + -o "version" ^ + -o "script import ghidralldb" ^ + -o "ghidra trace connect %GHIDRA_TRACE_RMI_ADDR%" ^ + -o "ghidra trace start" ^ + -o "ghidra trace sync-enable" ^ +) ELSE ( + "%OPT_LLDB_PATH%" ^ + -o "version" ^ + -o "script import ghidralldb" ^ + -o "target create %target_image%" ^ + %argspart% ^ + -o "ghidra trace connect %GHIDRA_TRACE_RMI_ADDR%" ^ + -o "ghidra trace start" ^ + -o "ghidra trace sync-enable" ^ + -o "%OPT_START_CMD%" ) - -"%OPT_LLDB_PATH%" ^ - -o "version" ^ - -o "script import ghidralldb" ^ - -o "target create %target_image%" ^ - %argspart% ^ - %ttypart% ^ - -o "ghidra trace connect %GHIDRA_TRACE_RMI_ADDR%" ^ - -o "ghidra trace start" ^ - -o "ghidra trace sync-enable" ^ - -o "%OPT_START_CMD%" diff --git a/Ghidra/Debug/Debugger-agent-lldb/data/debugger-launchers/local-lldb.sh b/Ghidra/Debug/Debugger-agent-lldb/data/debugger-launchers/local-lldb.sh index 9177b54717..dc896644e9 100755 --- a/Ghidra/Debug/Debugger-agent-lldb/data/debugger-launchers/local-lldb.sh +++ b/Ghidra/Debug/Debugger-agent-lldb/data/debugger-launchers/local-lldb.sh @@ -1,20 +1,21 @@ #!/usr/bin/env bash ## ### -# IP: GHIDRA -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# IP: GHIDRA +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. ## #@title lldb +#@image-opt arg:1 #@desc #@desc

Launch with lldb

#@desc

@@ -64,13 +65,24 @@ else ttypart=-o "settings set target.output-path $TTY_TARGET" -o "settings set target.input-path $TTY_TARGET" fi -"$OPT_LLDB_PATH" \ - -o "version" \ - -o "script import ghidralldb" \ - -o "target create \"$target_image\"" \ - $argspart \ - $ttypart \ - -o "ghidra trace connect \"$GHIDRA_TRACE_RMI_ADDR\"" \ - -o "ghidra trace start" \ - -o "ghidra trace sync-enable" \ - -o "$OPT_START_CMD" +if [ -z "$target_image" ] +then + "$OPT_LLDB_PATH" \ + -o "version" \ + -o "script import ghidralldb" \ + $ttypart \ + -o "ghidra trace connect \"$GHIDRA_TRACE_RMI_ADDR\"" \ + -o "ghidra trace start" \ + -o "ghidra trace sync-enable" +else + "$OPT_LLDB_PATH" \ + -o "version" \ + -o "script import ghidralldb" \ + -o "target create \"$target_image\"" \ + $argspart \ + $ttypart \ + -o "ghidra trace connect \"$GHIDRA_TRACE_RMI_ADDR\"" \ + -o "ghidra trace start" \ + -o "ghidra trace sync-enable" \ + -o "$OPT_START_CMD" +fi diff --git a/Ghidra/Debug/Debugger-agent-lldb/data/debugger-launchers/remote-lldb.sh b/Ghidra/Debug/Debugger-agent-lldb/data/debugger-launchers/remote-lldb.sh index d77a6d981a..170da9afc9 100755 --- a/Ghidra/Debug/Debugger-agent-lldb/data/debugger-launchers/remote-lldb.sh +++ b/Ghidra/Debug/Debugger-agent-lldb/data/debugger-launchers/remote-lldb.sh @@ -1,21 +1,20 @@ #!/usr/bin/env bash ## ### -# IP: GHIDRA -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# IP: GHIDRA +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. ## #@title remote lldb -#@no-image #@desc #@desc

Launch with local lldb and connect to a stub (e.g., gdbserver)

#@desc

@@ -59,5 +58,4 @@ fi -o "ghidra trace connect \"$GHIDRA_TRACE_RMI_ADDR\"" \ -o "ghidra trace start" \ -o "ghidra trace sync-enable" \ - -o "ghidra trace sync-synth-stopped" - + -o "ghidra trace sync-synth-stopped" diff --git a/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/ValStr.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/ValStr.java index d9631d3b91..4b200a7908 100644 --- a/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/ValStr.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/ValStr.java @@ -17,6 +17,7 @@ package ghidra.debug.api; import java.util.Map; import java.util.Map.Entry; +import java.util.Objects; import java.util.stream.Collectors; public record ValStr(T val, String str) { @@ -56,4 +57,18 @@ public record ValStr(T val, String str) { .stream() .collect(Collectors.toMap(Entry::getKey, e -> e.getValue().val())); } + + public static String normStr(ValStr val) { + if (val == null) { + return ""; + } + return val.normStr(); + } + + public String normStr() { + if (val == null) { + return ""; + } + return Objects.toString(val); + } } diff --git a/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/tracermi/TraceRmiLaunchOffer.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/tracermi/TraceRmiLaunchOffer.java index 6351a965c7..5a3497c39a 100644 --- a/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/tracermi/TraceRmiLaunchOffer.java +++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/tracermi/TraceRmiLaunchOffer.java @@ -295,10 +295,29 @@ public interface TraceRmiLaunchOffer { */ Map> getParameters(); + /** + * If present, get the parameter via which this offer expects to receive the current program + * + * @return the parameter, or null + */ + LaunchParameter imageParameter(); + + /** + * Check if this offer presents a parameter for the open program + * + * @return true if present + */ + default boolean supportsImage() { + return imageParameter() != null; + } + /** * Check if this offer requires an open program * * @return true if required */ - boolean requiresImage(); + default boolean requiresImage() { + LaunchParameter param = imageParameter(); + return param != null && param.required(); + } } diff --git a/Ghidra/Debug/Debugger-rmi-trace/data/debugger-launchers/raw-python3.sh b/Ghidra/Debug/Debugger-rmi-trace/data/debugger-launchers/raw-python3.sh index 3827f22cd2..26b0e36d65 100755 --- a/Ghidra/Debug/Debugger-rmi-trace/data/debugger-launchers/raw-python3.sh +++ b/Ghidra/Debug/Debugger-rmi-trace/data/debugger-launchers/raw-python3.sh @@ -1,22 +1,21 @@ #!/usr/bin/env bash ## ### -# IP: GHIDRA -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# IP: GHIDRA +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. ## #@title raw python -#@no-image #@desc #@desc

Start gdb

#@desc

diff --git a/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/AbstractScriptTraceRmiLaunchOffer.java b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/AbstractScriptTraceRmiLaunchOffer.java index 21b1567c2f..64dfc131c2 100644 --- a/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/AbstractScriptTraceRmiLaunchOffer.java +++ b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/AbstractScriptTraceRmiLaunchOffer.java @@ -124,7 +124,7 @@ public abstract class AbstractScriptTraceRmiLaunchOffer extends AbstractTraceRmi } @Override - public boolean requiresImage() { - return !attrs.noImage(); + public LaunchParameter imageParameter() { + return attrs.imageOpt(); } } diff --git a/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/AbstractTraceRmiLaunchOffer.java b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/AbstractTraceRmiLaunchOffer.java index ba882eca4a..b0b2cd275b 100644 --- a/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/AbstractTraceRmiLaunchOffer.java +++ b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/AbstractTraceRmiLaunchOffer.java @@ -57,7 +57,6 @@ import ghidra.util.task.Task; import ghidra.util.task.TaskMonitor; public abstract class AbstractTraceRmiLaunchOffer implements TraceRmiLaunchOffer { - public static final String PARAM_DISPLAY_IMAGE = "Image"; public static final String PREFIX_PARAM_EXTTOOL = "env:GHIDRA_LANG_EXTTOOL_"; public static final int DEFAULT_TIMEOUT_MILLIS = 10000; @@ -299,15 +298,10 @@ public abstract class AbstractTraceRmiLaunchOffer implements TraceRmiLaunchOffer protected Map> generateDefaultLauncherArgs( Map> params) { Map> map = new LinkedHashMap<>(); - ImageParamSetter imageSetter = null; for (Entry> entry : params.entrySet()) { LaunchParameter param = entry.getValue(); map.put(entry.getKey(), ValStr.cast(Object.class, param.defaultValue())); - if (PARAM_DISPLAY_IMAGE.equals(param.display())) { - imageSetter = ImageParamSetter.get(param); - // May still be null if type is not supported - } - else if (param.name().startsWith(PREFIX_PARAM_EXTTOOL)) { + if (param.name().startsWith(PREFIX_PARAM_EXTTOOL)) { String tool = param.name().substring(PREFIX_PARAM_EXTTOOL.length()); List names = program.getLanguage().getLanguageDescription().getExternalNames(tool); @@ -328,7 +322,8 @@ public abstract class AbstractTraceRmiLaunchOffer implements TraceRmiLaunchOffer } } } - if (imageSetter != null && program != null) { + if (supportsImage() && program != null) { + ImageParamSetter imageSetter = ImageParamSetter.get(imageParameter()); imageSetter.setImage(map, program); } return map; @@ -559,9 +554,18 @@ public abstract class AbstractTraceRmiLaunchOffer implements TraceRmiLaunchOffer return auto == null ? ByModuleAutoMapSpec.instance() : auto.getAutoMapSpec(trace); } - protected void initializeMonitor(TaskMonitor monitor) { + protected boolean providesImage(Map> args) { + LaunchParameter param = imageParameter(); + if (param == null) { + return false; + } + return !"".equals(param.get(args).str()); + } + + protected void updateMonitorMax(TaskMonitor monitor, Map> args) { AutoMapSpec spec = getAutoMapSpec(); - if (requiresImage() && spec.hasTask()) { + boolean image = args == null ? supportsImage() : providesImage(args); + if (image && spec.hasTask()) { monitor.setMaximum(6); } else { @@ -621,7 +625,7 @@ public abstract class AbstractTraceRmiLaunchOffer implements TraceRmiLaunchOffer Trace trace = null; Throwable lastExc = null; - initializeMonitor(monitor); + updateMonitorMax(monitor, null); while (true) { try { monitor.setMessage("Gathering arguments"); @@ -633,6 +637,7 @@ public abstract class AbstractTraceRmiLaunchOffer implements TraceRmiLaunchOffer return new LaunchResult(program, sessions, acceptor, connection, trace, lastExc); } + updateMonitorMax(monitor, args); monitor.increment(); acceptor = null; diff --git a/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/ScriptAttributesParser.java b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/ScriptAttributesParser.java index 42fc3af410..98bec883e6 100644 --- a/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/ScriptAttributesParser.java +++ b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/ScriptAttributesParser.java @@ -44,45 +44,46 @@ public abstract class ScriptAttributesParser { public static final String ENV_GHIDRA_TRACE_RMI_HOST = "GHIDRA_TRACE_RMI_HOST"; public static final String ENV_GHIDRA_TRACE_RMI_PORT = "GHIDRA_TRACE_RMI_PORT"; - public static final String AT_TITLE = "@title"; - public static final String AT_DESC = "@desc"; - public static final String AT_MENU_PATH = "@menu-path"; - public static final String AT_MENU_GROUP = "@menu-group"; - public static final String AT_MENU_ORDER = "@menu-order"; - public static final String AT_ICON = "@icon"; - public static final String AT_HELP = "@help"; - public static final String AT_ENUM = "@enum"; - public static final String AT_ENV = "@env"; public static final String AT_ARG = "@arg"; public static final String AT_ARGS = "@args"; - public static final String AT_TTY = "@tty"; + public static final String AT_DESC = "@desc"; + public static final String AT_ENUM = "@enum"; + public static final String AT_ENV = "@env"; + public static final String AT_HELP = "@help"; + public static final String AT_ICON = "@icon"; + public static final String AT_IMAGE_OPT = "@image-opt"; + public static final String AT_MENU_GROUP = "@menu-group"; + public static final String AT_MENU_ORDER = "@menu-order"; + public static final String AT_MENU_PATH = "@menu-path"; + public static final String AT_TITLE = "@title"; public static final String AT_TIMEOUT = "@timeout"; - public static final String AT_NOIMAGE = "@no-image"; + public static final String AT_TTY = "@tty"; - public static final String PREFIX_ENV = "env:"; - public static final String PREFIX_ARG = "arg:"; public static final String KEY_ARGS = "args"; + public static final String PREFIX_ARG = "arg:"; + public static final String PREFIX_ENV = "env:"; - public static final String MSGPAT_INVALID_HELP_SYNTAX = - "%s: Invalid %s syntax. Use Topic#anchor"; - public static final String MSGPAT_INVALID_ENUM_SYNTAX = - "%s: Invalid %s syntax. Use NAME:type Choice1 [ChoiceN...]"; - public static final String MSGPAT_INVALID_ENV_SYNTAX = - "%s: Invalid %s syntax. Use NAME:type=default \"Display\" \"Tool Tip\""; + public static final String MSGPAT_DUPLICATE_TAG = "%s: Duplicate %s"; public static final String MSGPAT_INVALID_ARG_SYNTAX = "%s: Invalid %s syntax. Use :type \"Display\" \"Tool Tip\""; public static final String MSGPAT_INVALID_ARGS_SYNTAX = "%s: Invalid %s syntax. Use \"Display\" \"Tool Tip\""; - public static final String MSGPAT_INVALID_TTY_SYNTAX = - "%s: Invalid %s syntax. Use TTY_TARGET [if env:OPT [== VAL]]"; + public static final String MSGPAT_INVALID_ENUM_SYNTAX = + "%s: Invalid %s syntax. Use NAME:type Choice1 [ChoiceN...]"; + public static final String MSGPAT_INVALID_ENV_SYNTAX = + "%s: Invalid %s syntax. Use NAME:type=default \"Display\" \"Tool Tip\""; + public static final String MSGPAT_INVALID_HELP_SYNTAX = + "%s: Invalid %s syntax. Use Topic#anchor"; + public static final String MSGPAT_INVALID_TIMEOUT_SYNTAX = "" + + "%s: Invalid %s syntax. Use [milliseconds]"; + public static final String MSGPAT_INVALID_TTY_BAD_VAL = + "%s: In %s: Parameter '%s' has type %s, but '%s' cannot be parsed as such"; public static final String MSGPAT_INVALID_TTY_NO_PARAM = "%s: In %s: No such parameter '%s'"; public static final String MSGPAT_INVALID_TTY_NOT_BOOL = "%s: In %s: Parameter '%s' must have bool type"; - public static final String MSGPAT_INVALID_TTY_BAD_VAL = - "%s: In %s: Parameter '%s' has type %s, but '%s' cannot be parsed as such"; - public static final String MSGPAT_INVALID_TIMEOUT_SYNTAX = "" + - "%s: Invalid %s syntax. Use [milliseconds]"; + public static final String MSGPAT_INVALID_TTY_SYNTAX = + "%s: Invalid %s syntax. Use TTY_TARGET [if env:OPT [== VAL]]"; public static class ParseException extends Exception { private Location loc; @@ -289,8 +290,9 @@ public abstract class ScriptAttributesParser { return tac.withCastDefault(new ValStr<>(value, defaultString)); } - public LaunchParameter createParameter(String name, String display, String description) { - return type.createParameter(name, display, description, false, defaultValue); + public LaunchParameter createParameter(String name, String display, String description, + boolean required) { + return type.createParameter(name, display, description, required, defaultValue); } } @@ -340,7 +342,7 @@ public abstract class ScriptAttributesParser { public record ScriptAttributes(String title, String description, List menuPath, String menuGroup, String menuOrder, Icon icon, HelpLocation helpLocation, Map> parameters, Map extraTtys, - int timeoutMillis, boolean noImage) {} + int timeoutMillis, LaunchParameter imageOpt) {} /** * Convert an arguments map into a command line and environment variables @@ -371,7 +373,7 @@ public abstract class ScriptAttributesParser { LaunchParameter param; for (int i = 1; (param = parameters.get("arg:" + i)) != null; i++) { // Don't use ValStr.str here. I'd like the script's input normalized - commandLine.add(Objects.toString(param.get(args).val())); + commandLine.add(param.get(args).normStr()); } param = parameters.get("args"); @@ -384,29 +386,24 @@ public abstract class ScriptAttributesParser { if (key.startsWith(PREFIX_ENV)) { String varName = key.substring(PREFIX_ENV.length()); ValStr val = ent.getValue().get(args); - if (val == null || val.val() == null) { - env.put(varName, ""); - } - else { - env.put(varName, Objects.toString(val.val())); - } + env.put(varName, ValStr.normStr(val)); } } } - private int argc = 0; + private int argc; private String title; private StringBuilder description; - private List menuPath; - private String menuGroup; - private String menuOrder; private String iconId; private HelpLocation helpLocation; + private String menuGroup; + private String menuOrder; + private List menuPath; private final Map> userTypes = new HashMap<>(); private final Map> parameters = new LinkedHashMap<>(); private final Map extraTtys = new LinkedHashMap<>(); private int timeoutMillis = AbstractTraceRmiLaunchOffer.DEFAULT_TIMEOUT_MILLIS; - private boolean noImage = false; + private String imageOptKey; /** * Check if a line should just be ignored, e.g., blank lines, or the "shebang" line on UNIX. @@ -489,36 +486,66 @@ public abstract class ScriptAttributesParser { return; } if (parts.length == 1) { - switch (parts[0].trim()) { - case AT_NOIMAGE -> parseNoImage(loc); - default -> parseUnrecognized(loc, comment); - } + parseUnrecognized(loc, comment); } else { switch (parts[0].trim()) { - case AT_TITLE -> parseTitle(loc, parts[1]); - case AT_DESC -> parseDesc(loc, parts[1]); - case AT_MENU_PATH -> parseMenuPath(loc, parts[1]); - case AT_MENU_GROUP -> parseMenuGroup(loc, parts[1]); - case AT_MENU_ORDER -> parseMenuOrder(loc, parts[1]); - case AT_ICON -> parseIcon(loc, parts[1]); - case AT_HELP -> parseHelp(loc, parts[1]); - case AT_ENUM -> parseEnum(loc, parts[1]); - case AT_ENV -> parseEnv(loc, parts[1]); case AT_ARG -> parseArg(loc, parts[1], ++argc); case AT_ARGS -> parseArgs(loc, parts[1]); - case AT_TTY -> parseTty(loc, parts[1]); + case AT_DESC -> parseDesc(loc, parts[1]); + case AT_ENUM -> parseEnum(loc, parts[1]); + case AT_ENV -> parseEnv(loc, parts[1]); + case AT_HELP -> parseHelp(loc, parts[1]); + case AT_ICON -> parseIcon(loc, parts[1]); + case AT_IMAGE_OPT -> parseImageOpt(loc, parts[1]); + case AT_MENU_GROUP -> parseMenuGroup(loc, parts[1]); + case AT_MENU_ORDER -> parseMenuOrder(loc, parts[1]); + case AT_MENU_PATH -> parseMenuPath(loc, parts[1]); case AT_TIMEOUT -> parseTimeout(loc, parts[1]); + case AT_TITLE -> parseTitle(loc, parts[1]); + case AT_TTY -> parseTty(loc, parts[1]); default -> parseUnrecognized(loc, comment); } } } - protected void parseTitle(Location loc, String str) { - if (title != null) { - reportWarning("%s: Duplicate %s".formatted(loc, AT_TITLE)); + protected void parseArg(Location loc, String str, int argNum) { + List parts = ShellUtils.parseArgs(str); + if (parts.size() != 3) { + reportError(MSGPAT_INVALID_ARG_SYNTAX.formatted(loc, AT_ARG)); + return; + } + String colonType = parts.get(0).trim(); + if (!colonType.startsWith(":")) { + reportError(MSGPAT_INVALID_ARG_SYNTAX.formatted(loc, AT_ARG)); + return; + } + OptType type; + boolean required = colonType.endsWith("!"); + int endType = required ? colonType.length() - 1 : colonType.length(); + try { + type = OptType.parse(loc, colonType.substring(1, endType), userTypes); + String name = PREFIX_ARG + argNum; + parameters.put(name, type.createParameter(name, parts.get(1), parts.get(2), required, + new ValStr<>(null, ""))); + } + catch (ParseException e) { + reportError(e.getMessage()); + } + } + + protected void parseArgs(Location loc, String str) { + List parts = ShellUtils.parseArgs(str); + if (parts.size() != 2) { + reportError(MSGPAT_INVALID_ARGS_SYNTAX.formatted(loc, AT_ARGS)); + return; + } + + LaunchParameter parameter = BaseType.STRING.createParameter( + "args", parts.get(0), parts.get(1), false, ValStr.str("")); + if (parameters.put(KEY_ARGS, parameter) != null) { + reportWarning("%s: Duplicate %s. Replaced".formatted(loc, AT_ARGS)); } - title = str; } protected void parseDesc(Location loc, String str) { @@ -529,54 +556,6 @@ public abstract class ScriptAttributesParser { description.append("\n"); } - protected void parseMenuPath(Location loc, String str) { - if (menuPath != null) { - reportWarning("%s: Duplicate %s".formatted(loc, AT_MENU_PATH)); - } - menuPath = List.of(str.trim().split("\\.")); - if (menuPath.isEmpty()) { - reportError( - "%s: Empty %s. Ignoring.".formatted(loc, AT_MENU_PATH)); - } - } - - protected void parseMenuGroup(Location loc, String str) { - if (menuGroup != null) { - reportWarning("%s: Duplicate %s".formatted(loc, AT_MENU_GROUP)); - } - menuGroup = str; - } - - protected void parseMenuOrder(Location loc, String str) { - if (menuOrder != null) { - reportWarning("%s: Duplicate %s".formatted(loc, AT_MENU_ORDER)); - } - menuOrder = str; - } - - protected void parseIcon(Location loc, String str) { - if (iconId != null) { - reportWarning("%s: Duplicate %s".formatted(loc, AT_ICON)); - } - iconId = str.trim(); - if (!Gui.hasIcon(iconId)) { - reportError( - "%s: Icon id %s not registered in the theme".formatted(loc, iconId)); - } - } - - protected void parseHelp(Location loc, String str) { - if (helpLocation != null) { - reportWarning("%s: Duplicate %s".formatted(loc, AT_HELP)); - } - String[] parts = str.trim().split("#", 2); - if (parts.length != 2) { - reportError(MSGPAT_INVALID_HELP_SYNTAX.formatted(loc, AT_HELP)); - return; - } - helpLocation = new HelpLocation(parts[0].trim(), parts[1].trim()); - } - protected UserType parseEnumChoices(Location loc, BaseType baseType, List choiceParts) { List choices = new ArrayList<>(); @@ -642,10 +621,14 @@ public abstract class ScriptAttributesParser { reportError(MSGPAT_INVALID_ENV_SYNTAX.formatted(loc, AT_ENV)); return; } + String typePart = tadParts[0].trim(); + boolean required = typePart.endsWith("!"); + int endType = required ? typePart.length() - 1 : typePart.length(); try { - TypeAndDefault tad = - TypeAndDefault.parse(loc, tadParts[0].trim(), tadParts[1].trim(), userTypes); - LaunchParameter param = tad.createParameter(name, parts.get(1), parts.get(2)); + TypeAndDefault tad = TypeAndDefault.parse(loc, typePart.substring(0, endType), + tadParts[1].trim(), userTypes); + LaunchParameter param = + tad.createParameter(name, parts.get(1), parts.get(2), required); if (parameters.put(name, param) != null) { reportWarning("%s: Duplicate %s %s. Replaced.".formatted(loc, AT_ENV, trimmed)); } @@ -655,42 +638,75 @@ public abstract class ScriptAttributesParser { } } - protected void parseArg(Location loc, String str, int argNum) { - List parts = ShellUtils.parseArgs(str); - if (parts.size() != 3) { - reportError(MSGPAT_INVALID_ARG_SYNTAX.formatted(loc, AT_ARG)); + protected void parseHelp(Location loc, String str) { + if (helpLocation != null) { + reportWarning(MSGPAT_DUPLICATE_TAG.formatted(loc, AT_HELP)); + } + String[] parts = str.trim().split("#", 2); + if (parts.length != 2) { + reportError(MSGPAT_INVALID_HELP_SYNTAX.formatted(loc, AT_HELP)); return; } - String colonType = parts.get(0).trim(); - if (!colonType.startsWith(":")) { - reportError(MSGPAT_INVALID_ARG_SYNTAX.formatted(loc, AT_ARG)); - return; + helpLocation = new HelpLocation(parts[0].trim(), parts[1].trim()); + } + + protected void parseIcon(Location loc, String str) { + if (iconId != null) { + reportWarning(MSGPAT_DUPLICATE_TAG.formatted(loc, AT_ICON)); } - OptType type; - try { - type = OptType.parse(loc, colonType.substring(1), userTypes); - String name = PREFIX_ARG + argNum; - parameters.put(name, - type.createParameter(name, parts.get(1), parts.get(2), true, - new ValStr<>(null, ""))); - } - catch (ParseException e) { - reportError(e.getMessage()); + iconId = str.trim(); + if (!Gui.hasIcon(iconId)) { + reportError( + "%s: Icon id %s not registered in the theme".formatted(loc, iconId)); } } - protected void parseArgs(Location loc, String str) { - List parts = ShellUtils.parseArgs(str); - if (parts.size() != 2) { - reportError(MSGPAT_INVALID_ARGS_SYNTAX.formatted(loc, AT_ARGS)); - return; + protected void parseImageOpt(Location loc, String str) { + if (imageOptKey != null) { + reportWarning(MSGPAT_DUPLICATE_TAG.formatted(loc, AT_IMAGE_OPT)); } + imageOptKey = str.strip(); + } - LaunchParameter parameter = BaseType.STRING.createParameter( - "args", parts.get(0), parts.get(1), false, ValStr.str("")); - if (parameters.put(KEY_ARGS, parameter) != null) { - reportWarning("%s: Duplicate %s. Replaced".formatted(loc, AT_ARGS)); + protected void parseMenuGroup(Location loc, String str) { + if (menuGroup != null) { + reportWarning(MSGPAT_DUPLICATE_TAG.formatted(loc, AT_MENU_GROUP)); } + menuGroup = str; + } + + protected void parseMenuOrder(Location loc, String str) { + if (menuOrder != null) { + reportWarning(MSGPAT_DUPLICATE_TAG.formatted(loc, AT_MENU_ORDER)); + } + menuOrder = str; + } + + protected void parseMenuPath(Location loc, String str) { + if (menuPath != null) { + reportWarning(MSGPAT_DUPLICATE_TAG.formatted(loc, AT_MENU_PATH)); + } + menuPath = List.of(str.trim().split("\\.")); + if (menuPath.isEmpty()) { + reportError( + "%s: Empty %s. Ignoring.".formatted(loc, AT_MENU_PATH)); + } + } + + protected void parseTimeout(Location loc, String str) { + try { + timeoutMillis = Integer.parseInt(str); + } + catch (NumberFormatException e) { + reportError(MSGPAT_INVALID_TIMEOUT_SYNTAX.formatted(loc, AT_TIMEOUT)); + } + } + + protected void parseTitle(Location loc, String str) { + if (title != null) { + reportWarning(MSGPAT_DUPLICATE_TAG.formatted(loc, AT_TITLE)); + } + title = str; } protected void putTty(Location loc, String name, TtyCondition condition) { @@ -749,19 +765,6 @@ public abstract class ScriptAttributesParser { reportError(MSGPAT_INVALID_TTY_SYNTAX.formatted(loc, AT_TTY)); } - protected void parseTimeout(Location loc, String str) { - try { - timeoutMillis = Integer.parseInt(str); - } - catch (NumberFormatException e) { - reportError(MSGPAT_INVALID_TIMEOUT_SYNTAX.formatted(loc, AT_TIMEOUT)); - } - } - - protected void parseNoImage(Location loc) { - noImage = true; - } - protected void parseUnrecognized(Location loc, String line) { reportWarning("%s: Unrecognized metadata: %s".formatted(loc, line)); } @@ -784,10 +787,18 @@ public abstract class ScriptAttributesParser { if (iconId == null) { iconId = "icon.debugger"; } + LaunchParameter imageOpt = null; + if (imageOptKey != null) { + imageOpt = parameters.get(imageOptKey); + if (imageOpt == null) { + reportError("%s: %s refers to %s, which is not a parameter name".formatted(fileName, + AT_IMAGE_OPT, imageOptKey)); + } + } return new ScriptAttributes(title, getDescription(), List.copyOf(menuPath), menuGroup, menuOrder, new GIcon(iconId), helpLocation, Collections.unmodifiableMap(new LinkedHashMap<>(parameters)), - Collections.unmodifiableMap(new LinkedHashMap<>(extraTtys)), timeoutMillis, noImage); + Collections.unmodifiableMap(new LinkedHashMap<>(extraTtys)), timeoutMillis, imageOpt); } private String getDescription() { diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/AbstractDebuggerParameterDialog.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/AbstractDebuggerParameterDialog.java index d9ab6d9435..6aec34def2 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/AbstractDebuggerParameterDialog.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/AbstractDebuggerParameterDialog.java @@ -637,6 +637,9 @@ public abstract class AbstractDebuggerParameterDialog

extends DialogComponent protected void setEditorValue(PropertyEditor editor, P param, ValStr val) { switch (val.val()) { case null -> { + if (parameterType(param) == String.class) { + editor.setValue(val.str()); + } } case BigInteger bi -> editor.setAsText(val.str()); default -> editor.setValue(val.val()); diff --git a/Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/TestTraceRmiLaunchOpinion.java b/Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/TestTraceRmiLaunchOpinion.java index 51e753a693..550205072d 100644 --- a/Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/TestTraceRmiLaunchOpinion.java +++ b/Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/app/plugin/core/debug/gui/tracermi/launcher/TestTraceRmiLaunchOpinion.java @@ -30,8 +30,8 @@ public class TestTraceRmiLaunchOpinion implements TraceRmiLaunchOpinion { public static class TestTraceRmiLaunchOffer extends AbstractTraceRmiLaunchOffer { private static final LaunchParameter PARAM_IMAGE = - LaunchParameter.create(String.class, "image", PARAM_DISPLAY_IMAGE, "Image to execute", - true, ValStr.str(""), str -> str); + LaunchParameter.create(String.class, "image", "Image", "Image to execute", + false, ValStr.str(""), str -> str); public TestTraceRmiLaunchOffer(TraceRmiLauncherServicePlugin plugin, Program program) { super(plugin, program); @@ -62,8 +62,8 @@ public class TestTraceRmiLaunchOpinion implements TraceRmiLaunchOpinion { } @Override - public boolean requiresImage() { - return false; + public LaunchParameter imageParameter() { + return PARAM_IMAGE; } @Override