diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/certification.manifest b/Ghidra/Debug/Debugger-agent-dbgeng/certification.manifest
index 1634305df4..68c406c790 100644
--- a/Ghidra/Debug/Debugger-agent-dbgeng/certification.manifest
+++ b/Ghidra/Debug/Debugger-agent-dbgeng/certification.manifest
@@ -9,7 +9,9 @@ src/main/py/LICENSE||GHIDRA||||END|
src/main/py/MANIFEST.in||GHIDRA||||END|
src/main/py/README.md||GHIDRA||||END|
src/main/py/pyproject.toml||GHIDRA||||END|
+src/main/py/src/ghidradbg/dbgeng_base.xml||GHIDRA||||END|
src/main/py/src/ghidradbg/dbgmodel/DbgModel.idl||GHIDRA||||END|
+src/main/py/src/ghidradbg/exdi/exdi.xml||GHIDRA||||END|
src/main/py/src/ghidradbg/py.typed||GHIDRA||||END|
src/main/py/src/ghidradbg/schema.xml||GHIDRA||||END|
src/main/py/src/ghidradbg/schema_exdi.xml||GHIDRA||||END|
diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/ghidradbg/build_xml.py b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/ghidradbg/build_xml.py
new file mode 100644
index 0000000000..db5edc402f
--- /dev/null
+++ b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/ghidradbg/build_xml.py
@@ -0,0 +1,49 @@
+## ###
+# 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.
+##
+from merge_xml import merge
+import os
+import sys
+rmi_path = os.getcwd() + "/../../../../../../Debugger-rmi-trace/src/main/py/src/ghidratrace/"
+sys.path.append(rmi_path)
+
+
+def main():
+ xml = rmi_path+"xml/"
+ merge(xml_base="dbgeng_base.xml",
+ xml_out="schema.xml",
+ xml_updates=[
+ xml+"sessions.xml",
+ xml+"common.xml",
+ xml+"nesting_adjustments.xml",
+ xml+"available.xml",
+ xml+"events.xml",
+ xml+"breakpointsFlat.xml"
+ ])
+ merge(xml_base="dbgeng_base.xml",
+ xml_out="schema_exdi.xml",
+ xml_updates=[
+ xml+"sessions.xml",
+ xml+"common.xml",
+ xml+"nesting_adjustments.xml",
+ xml+"available.xml",
+ xml+"events.xml",
+ xml+"breakpointsFlat.xml",
+ os.getcwd()+"/exdi/exdi.xml"
+ ])
+
+
+if __name__ == '__main__':
+ main()
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 fc35765358..3d5ca98918 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
@@ -245,10 +245,8 @@ def start_trace(name: str) -> None:
if frame is None:
raise AssertionError("cannot locate schema.xml")
parent = os.path.dirname(inspect.getfile(frame))
- if util.is_exdi():
- schema_fn = os.path.join(parent, 'schema_exdi.xml')
- else:
- schema_fn = os.path.join(parent, 'schema.xml')
+ schema_fn = os.path.join(parent, 'schema_exdi.xml' if util.is_exdi() else 'schema.xml')
+
with open(schema_fn, 'r') as schema_file:
schema_xml = schema_file.read()
using_dbgmodel = os.getenv('OPT_USE_DBGMODEL') == "true"
diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/ghidradbg/dbgeng_base.xml b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/ghidradbg/dbgeng_base.xml
new file mode 100644
index 0000000000..bfb3108502
--- /dev/null
+++ b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/ghidradbg/dbgeng_base.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/ghidradbg/exdi/exdi.xml b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/ghidradbg/exdi/exdi.xml
new file mode 100644
index 0000000000..c6d2961fb5
--- /dev/null
+++ b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/ghidradbg/exdi/exdi.xml
@@ -0,0 +1,93 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/ghidradbg/schema.xml b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/ghidradbg/schema.xml
index e56d789961..e8758f4fd5 100644
--- a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/ghidradbg/schema.xml
+++ b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/ghidradbg/schema.xml
@@ -1,317 +1,327 @@
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/ghidradbg/schema_exdi.xml b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/ghidradbg/schema_exdi.xml
index ba44582d57..4dad14236c 100644
--- a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/ghidradbg/schema_exdi.xml
+++ b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/ghidradbg/schema_exdi.xml
@@ -1,358 +1,412 @@
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Ghidra/Debug/Debugger-agent-drgn/certification.manifest b/Ghidra/Debug/Debugger-agent-drgn/certification.manifest
index 7b4c28f4e0..6aa33e864d 100644
--- a/Ghidra/Debug/Debugger-agent-drgn/certification.manifest
+++ b/Ghidra/Debug/Debugger-agent-drgn/certification.manifest
@@ -10,4 +10,5 @@ src/main/py/LICENSE||GHIDRA||||END|
src/main/py/MANIFEST.in||GHIDRA||||END|
src/main/py/README.md||GHIDRA||||END|
src/main/py/pyproject.toml||GHIDRA||||END|
+src/main/py/src/ghidradrgn/drgn_base.xml||GHIDRA||||END|
src/main/py/src/ghidradrgn/schema.xml||GHIDRA||||END|
diff --git a/Ghidra/Debug/Debugger-agent-drgn/src/main/py/src/ghidradrgn/build_xml.py b/Ghidra/Debug/Debugger-agent-drgn/src/main/py/src/ghidradrgn/build_xml.py
new file mode 100644
index 0000000000..284a24e15e
--- /dev/null
+++ b/Ghidra/Debug/Debugger-agent-drgn/src/main/py/src/ghidradrgn/build_xml.py
@@ -0,0 +1,33 @@
+## ###
+# 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.
+##
+from merge_xml import merge
+import os
+import sys
+rmi_path = os.getcwd() + "/../../../../../../Debugger-rmi-trace/src/main/py/src/ghidratrace/"
+sys.path.append(rmi_path)
+
+
+def main():
+ xml = rmi_path+"xml/"
+ merge(xml_base="drgn_base.xml",
+ xml_out="schema.xml",
+ xml_updates=[
+ xml+"common.xml"
+ ])
+
+
+if __name__ == '__main__':
+ main()
diff --git a/Ghidra/Debug/Debugger-agent-drgn/src/main/py/src/ghidradrgn/drgn_base.xml b/Ghidra/Debug/Debugger-agent-drgn/src/main/py/src/ghidradrgn/drgn_base.xml
new file mode 100644
index 0000000000..10e337fd41
--- /dev/null
+++ b/Ghidra/Debug/Debugger-agent-drgn/src/main/py/src/ghidradrgn/drgn_base.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Ghidra/Debug/Debugger-agent-drgn/src/main/py/src/ghidradrgn/schema.xml b/Ghidra/Debug/Debugger-agent-drgn/src/main/py/src/ghidradrgn/schema.xml
index 28c5bd6191..eb16ff0eff 100644
--- a/Ghidra/Debug/Debugger-agent-drgn/src/main/py/src/ghidradrgn/schema.xml
+++ b/Ghidra/Debug/Debugger-agent-drgn/src/main/py/src/ghidradrgn/schema.xml
@@ -1,183 +1,198 @@
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Ghidra/Debug/Debugger-agent-gdb/certification.manifest b/Ghidra/Debug/Debugger-agent-gdb/certification.manifest
index 5d01f29560..3f474580c9 100644
--- a/Ghidra/Debug/Debugger-agent-gdb/certification.manifest
+++ b/Ghidra/Debug/Debugger-agent-gdb/certification.manifest
@@ -14,6 +14,7 @@ src/main/py/LICENSE||GHIDRA||||END|
src/main/py/MANIFEST.in||GHIDRA||||END|
src/main/py/README.md||GHIDRA||||END|
src/main/py/pyproject.toml||GHIDRA||||END|
+src/main/py/src/ghidragdb/gdb_base.xml||GHIDRA||||END|
src/main/py/src/ghidragdb/py.typed||GHIDRA||||END|
src/main/py/src/ghidragdb/schema.xml||GHIDRA||||END|
src/main/py/tests/EMPTY||GHIDRA||||END|
diff --git a/Ghidra/Debug/Debugger-agent-gdb/src/main/py/src/ghidragdb/build_xml.py b/Ghidra/Debug/Debugger-agent-gdb/src/main/py/src/ghidragdb/build_xml.py
new file mode 100644
index 0000000000..3708443f07
--- /dev/null
+++ b/Ghidra/Debug/Debugger-agent-gdb/src/main/py/src/ghidragdb/build_xml.py
@@ -0,0 +1,35 @@
+## ###
+# 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.
+##
+from merge_xml import merge
+import os
+import sys
+rmi_path = os.getcwd() + "/../../../../../../Debugger-rmi-trace/src/main/py/src/ghidratrace/"
+sys.path.append(rmi_path)
+
+
+def main():
+ xml = rmi_path+"xml/"
+ merge(xml_base="gdb_base.xml",
+ xml_out="schema.xml",
+ xml_updates=[
+ xml+"common.xml",
+ xml+"available.xml",
+ xml+"breakpointsTiered.xml"
+ ])
+
+
+if __name__ == '__main__':
+ main()
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 0eddc70ba9..c14668f920 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
@@ -296,10 +296,12 @@ def start_trace(name: str) -> None:
frame = inspect.currentframe()
if frame is None:
raise AssertionError("cannot locate schema.xml")
+
parent = os.path.dirname(inspect.getfile(frame))
schema_fn = os.path.join(parent, 'schema.xml')
with open(schema_fn, 'r') as schema_file:
schema_xml = schema_file.read()
+
with STATE.trace.open_tx("Create Root Object"):
root = STATE.trace.create_root_object(schema_xml, 'GdbSession')
root.set_value('_display', 'GNU gdb ' + util.GDB_VERSION.full)
diff --git a/Ghidra/Debug/Debugger-agent-gdb/src/main/py/src/ghidragdb/gdb_base.xml b/Ghidra/Debug/Debugger-agent-gdb/src/main/py/src/ghidragdb/gdb_base.xml
new file mode 100644
index 0000000000..98f0984399
--- /dev/null
+++ b/Ghidra/Debug/Debugger-agent-gdb/src/main/py/src/ghidragdb/gdb_base.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Ghidra/Debug/Debugger-agent-gdb/src/main/py/src/ghidragdb/methods.py b/Ghidra/Debug/Debugger-agent-gdb/src/main/py/src/ghidragdb/methods.py
index 73d9fcbeb0..3591ab06e3 100644
--- a/Ghidra/Debug/Debugger-agent-gdb/src/main/py/src/ghidragdb/methods.py
+++ b/Ghidra/Debug/Debugger-agent-gdb/src/main/py/src/ghidragdb/methods.py
@@ -310,11 +310,11 @@ class Environment(TraceObject):
pass
-class Inferior(TraceObject):
+class Process(TraceObject):
pass
-class InferiorContainer(TraceObject):
+class ProcessContainer(TraceObject):
pass
@@ -372,7 +372,7 @@ def refresh_breakpoints(node: BreakpointContainer) -> None:
@REGISTRY.method(action='refresh', display='Refresh Inferiors')
-def refresh_inferiors(node: InferiorContainer) -> None:
+def refresh_inferiors(node: ProcessContainer) -> None:
"""Refresh the list of inferiors."""
with commands.open_tracked_tx('Refresh Inferiors'):
gdb.execute('ghidra trace put-inferiors')
@@ -461,7 +461,7 @@ def refresh_sections(node: Module) -> None:
@REGISTRY.method(action='activate', display="Activate Inferior")
-def activate_inferior(inferior: Inferior) -> None:
+def activate_inferior(inferior: Process) -> None:
"""Switch to the inferior."""
switch_inferior(find_inf_by_obj(inferior))
@@ -481,13 +481,13 @@ def activate_frame(frame: StackFrame) -> None:
@REGISTRY.method(display='Add Inferior')
-def add_inferior(container: InferiorContainer) -> None:
+def add_inferior(container: ProcessContainer) -> None:
"""Add a new inferior."""
gdb.execute('add-inferior')
@REGISTRY.method(action='delete', display="Delete Inferior")
-def delete_inferior(inferior: Inferior) -> None:
+def delete_inferior(inferior: Process) -> None:
"""Remove the inferior."""
inf = find_inf_by_obj(inferior)
gdb.execute(f'remove-inferior {inf.num}')
@@ -495,7 +495,7 @@ def delete_inferior(inferior: Inferior) -> None:
# TODO: Separate method for each of core, exec, remote, etc...?
@REGISTRY.method(display='Connect Target')
-def connect(inferior: Inferior, spec: str) -> None:
+def connect(inferior: Process, spec: str) -> None:
"""Connect to a target machine or process."""
switch_inferior(find_inf_by_obj(inferior))
gdb.execute(f'target {spec}')
@@ -510,21 +510,21 @@ def attach_obj(target: Attachable) -> None:
@REGISTRY.method(action='attach', display='Attach by PID')
-def attach_pid(inferior: Inferior, pid: int) -> None:
+def attach_pid(inferior: Process, pid: int) -> None:
"""Attach the inferior to the given target."""
switch_inferior(find_inf_by_obj(inferior))
gdb.execute(f'attach {pid}')
@REGISTRY.method(display='Detach')
-def detach(inferior: Inferior) -> None:
+def detach(inferior: Process) -> None:
"""Detach the inferior's target."""
switch_inferior(find_inf_by_obj(inferior))
gdb.execute('detach')
@REGISTRY.method(action='launch', display='Launch at main')
-def launch_main(inferior: Inferior,
+def launch_main(inferior: Process,
file: Annotated[str, ParamDesc(display='File')],
args: Annotated[str, ParamDesc(display='Arguments')] = '') -> None:
"""Start a native process with the given command line, stopping at 'main'
@@ -542,7 +542,7 @@ def launch_main(inferior: Inferior,
@REGISTRY.method(action='launch', display='Launch at Loader',
condition=util.GDB_VERSION.major >= 9)
-def launch_loader(inferior: Inferior,
+def launch_loader(inferior: Process,
file: Annotated[str, ParamDesc(display='File')],
args: Annotated[str, ParamDesc(display='Arguments')] = '') -> None:
"""Start a native process with the given command line, stopping at first
@@ -556,7 +556,7 @@ def launch_loader(inferior: Inferior,
@REGISTRY.method(action='launch', display='Launch and Run')
-def launch_run(inferior: Inferior,
+def launch_run(inferior: Process,
file: Annotated[str, ParamDesc(display='File')],
args: Annotated[str, ParamDesc(display='Arguments')] = '') -> None:
"""Run a native process with the given command line (run).
@@ -573,7 +573,7 @@ def launch_run(inferior: Inferior,
@REGISTRY.method()
-def kill(inferior: Inferior) -> None:
+def kill(inferior: Process) -> None:
"""Kill execution of the inferior."""
switch_inferior(find_inf_by_obj(inferior))
with no_confirm():
@@ -581,7 +581,7 @@ def kill(inferior: Inferior) -> None:
@REGISTRY.method()
-def resume(inferior: Inferior) -> None:
+def resume(inferior: Process) -> None:
"""Continue execution of the inferior."""
switch_inferior(find_inf_by_obj(inferior))
gdb.execute('continue')
@@ -589,7 +589,7 @@ def resume(inferior: Inferior) -> None:
@REGISTRY.method(action='step_ext', icon='icon.debugger.resume.back',
condition=util.IS_TRACE)
-def resume_back(inferior: Inferior) -> None:
+def resume_back(inferior: Process) -> None:
"""Continue execution of the inferior backwards."""
gdb.execute('reverse-continue')
@@ -598,7 +598,7 @@ def resume_back(inferior: Inferior) -> None:
# is the current inferior. This in turn queues the UI to enable or disable the
# button appropriately
@REGISTRY.method()
-def interrupt(inferior: Inferior) -> None:
+def interrupt(inferior: Process) -> None:
"""Interrupt the execution of the debugged program."""
gdb.execute('interrupt')
@@ -663,7 +663,7 @@ def step_back_over(thread: Thread,
@REGISTRY.method(action='break_sw_execute')
-def break_sw_execute_address(inferior: Inferior, address: Address) -> None:
+def break_sw_execute_address(inferior: Process, address: Address) -> None:
"""Set a breakpoint (break)."""
inf = find_inf_by_obj(inferior)
offset = inferior.trace.extra.require_mm().map_back(inf, address)
@@ -678,7 +678,7 @@ def break_sw_execute_expression(expression: str) -> None:
@REGISTRY.method(action='break_hw_execute')
-def break_hw_execute_address(inferior: Inferior, address: Address) -> None:
+def break_hw_execute_address(inferior: Process, address: Address) -> None:
"""Set a hardware-assisted breakpoint (hbreak)."""
inf = find_inf_by_obj(inferior)
offset = inferior.trace.extra.require_mm().map_back(inf, address)
@@ -693,7 +693,7 @@ def break_hw_execute_expression(expression: str) -> None:
@REGISTRY.method(action='break_read')
-def break_read_range(inferior: Inferior, range: AddressRange) -> None:
+def break_read_range(inferior: Process, range: AddressRange) -> None:
"""Set a read watchpoint (rwatch)."""
inf = find_inf_by_obj(inferior)
offset_start = inferior.trace.extra.require_mm().map_back(
@@ -709,7 +709,7 @@ def break_read_expression(expression: str) -> None:
@REGISTRY.method(action='break_write')
-def break_write_range(inferior: Inferior, range: AddressRange) -> None:
+def break_write_range(inferior: Process, range: AddressRange) -> None:
"""Set a watchpoint (watch)."""
inf = find_inf_by_obj(inferior)
offset_start = inferior.trace.extra.require_mm().map_back(
@@ -725,7 +725,7 @@ def break_write_expression(expression: str) -> None:
@REGISTRY.method(action='break_access')
-def break_access_range(inferior: Inferior, range: AddressRange) -> None:
+def break_access_range(inferior: Process, range: AddressRange) -> None:
"""Set an access watchpoint (awatch)."""
inf = find_inf_by_obj(inferior)
offset_start = inferior.trace.extra.require_mm().map_back(
@@ -741,7 +741,7 @@ def break_access_expression(expression: str) -> None:
@REGISTRY.method(action='break_ext', display='Catch Event')
-def break_ext_event(inferior: Inferior,
+def break_ext_event(inferior: Process,
spec: Annotated[str, ParamDesc(display='Type')]) -> None:
"""Set a generic catchpoint (catch)."""
gdb.execute(f'catch {spec}')
@@ -756,7 +756,7 @@ def break_event(container: BreakpointContainer,
@REGISTRY.method(action='break_ext', display='Catch Signal')
-def break_ext_signal(inferior: Inferior, signal: Annotated[
+def break_ext_signal(inferior: Process, signal: Annotated[
str, ParamDesc(display='Signal (opt)')]) -> None:
"""Set a signal catchpoint (catch signal)."""
gdb.execute(f'catch signal {signal}')
@@ -770,7 +770,7 @@ def break_signal(container: BreakpointContainer, signal: Annotated[
@REGISTRY.method(action='break_ext', display='Catch Syscall')
-def break_ext_syscall(inferior: Inferior, syscall: Annotated[
+def break_ext_syscall(inferior: Process, syscall: Annotated[
str, ParamDesc(display='Syscall (opt)')]) -> None:
"""Set a syscall catchpoint (catch syscall))."""
gdb.execute(f'catch syscall {syscall}')
@@ -784,7 +784,7 @@ def break_syscall(container: BreakpointContainer, syscall: Annotated[
@REGISTRY.method(action='break_ext', display='Catch Load')
-def break_ext_load(inferior: Inferior, library: Annotated[
+def break_ext_load(inferior: Process, library: Annotated[
str, ParamDesc(display='Library (opt)')]) -> None:
"""Set a load catchpoint (catch load))."""
gdb.execute(f'catch load {library}')
@@ -798,7 +798,7 @@ def break_load(container: BreakpointContainer, library: Annotated[
@REGISTRY.method(action='break_ext', display='Catch Unload')
-def break_ext_unload(inferior: Inferior,
+def break_ext_unload(inferior: Process,
library: Annotated[
str, ParamDesc(display='Library (opt)')]) -> None:
"""Set a unload catchpoint (catch unload))."""
@@ -813,7 +813,7 @@ def break_unload(container: BreakpointContainer, library: Annotated[
@REGISTRY.method(action='break_ext', display='Catch Catch')
-def break_ext_catch(inferior: Inferior, exception: Annotated[
+def break_ext_catch(inferior: Process, exception: Annotated[
str, ParamDesc(display='Exception (opt)')]) -> None:
"""Set a catch catchpoint (catch catch))."""
gdb.execute(f'catch catch {exception}')
@@ -827,7 +827,7 @@ def break_catch(container: BreakpointContainer, exception: Annotated[
@REGISTRY.method(action='break_ext', display='Catch Throw')
-def break_ext_throw(inferior: Inferior, exception: Annotated[
+def break_ext_throw(inferior: Process, exception: Annotated[
str, ParamDesc(display='Exception (opt)')]) -> None:
"""Set a throw catchpoint (catch throw))."""
gdb.execute(f'catch throw {exception}')
@@ -841,7 +841,7 @@ def break_throw(container: BreakpointContainer, exception: Annotated[
@REGISTRY.method(action='break_ext', display='Catch Rethrow')
-def break_ext_rethrow(inferior: Inferior, exception: Annotated[
+def break_ext_rethrow(inferior: Process, exception: Annotated[
str, ParamDesc(display='Exception (opt)')]) -> None:
"""Set a rethrow catchpoint (catch rethrow))."""
gdb.execute(f'catch rethrow {exception}')
@@ -902,7 +902,7 @@ def delete_breakpoint(breakpoint: BreakpointSpec) -> None:
@REGISTRY.method()
-def read_mem(inferior: Inferior, range: AddressRange) -> None:
+def read_mem(inferior: Process, range: AddressRange) -> None:
"""Read memory."""
inf = find_inf_by_obj(inferior)
offset_start = inferior.trace.extra.require_mm().map_back(
@@ -917,7 +917,7 @@ def read_mem(inferior: Inferior, range: AddressRange) -> None:
@REGISTRY.method()
-def write_mem(inferior: Inferior, address: Address, data: bytes) -> None:
+def write_mem(inferior: Process, address: Address, data: bytes) -> None:
"""Write memory."""
inf = find_inf_by_obj(inferior)
offset = inferior.trace.extra.require_mm().map_back(inf, address)
diff --git a/Ghidra/Debug/Debugger-agent-gdb/src/main/py/src/ghidragdb/schema.xml b/Ghidra/Debug/Debugger-agent-gdb/src/main/py/src/ghidragdb/schema.xml
index d1cf8f11b0..79f32d8c00 100644
--- a/Ghidra/Debug/Debugger-agent-gdb/src/main/py/src/ghidragdb/schema.xml
+++ b/Ghidra/Debug/Debugger-agent-gdb/src/main/py/src/ghidragdb/schema.xml
@@ -1,233 +1,243 @@
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Ghidra/Debug/Debugger-agent-lldb/certification.manifest b/Ghidra/Debug/Debugger-agent-lldb/certification.manifest
index 73b81dc24c..1e56bb2724 100644
--- a/Ghidra/Debug/Debugger-agent-lldb/certification.manifest
+++ b/Ghidra/Debug/Debugger-agent-lldb/certification.manifest
@@ -11,5 +11,6 @@ src/main/py/LICENSE||GHIDRA||||END|
src/main/py/MANIFEST.in||GHIDRA||||END|
src/main/py/README.md||GHIDRA||||END|
src/main/py/pyproject.toml||GHIDRA||||END|
+src/main/py/src/ghidralldb/lldb_base.xml||GHIDRA||||END|
src/main/py/src/ghidralldb/py.typed||GHIDRA||||END|
src/main/py/src/ghidralldb/schema.xml||GHIDRA||||END|
diff --git a/Ghidra/Debug/Debugger-agent-lldb/src/main/py/src/ghidralldb/build_xml.py b/Ghidra/Debug/Debugger-agent-lldb/src/main/py/src/ghidralldb/build_xml.py
new file mode 100644
index 0000000000..ced49f6210
--- /dev/null
+++ b/Ghidra/Debug/Debugger-agent-lldb/src/main/py/src/ghidralldb/build_xml.py
@@ -0,0 +1,35 @@
+## ###
+# 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.
+##
+from merge_xml import merge
+import os
+import sys
+rmi_path = os.getcwd() + "/../../../../../../Debugger-rmi-trace/src/main/py/src/ghidratrace/"
+sys.path.append(rmi_path)
+
+
+def main():
+ xml = rmi_path+"xml/"
+ merge(xml_base="lldb_base.xml",
+ xml_out="schema.xml",
+ xml_updates=[
+ xml+"common.xml",
+ xml+"available.xml",
+ xml+"breakpointsTiered.xml"
+ ])
+
+
+if __name__ == '__main__':
+ main()
diff --git a/Ghidra/Debug/Debugger-agent-lldb/src/main/py/src/ghidralldb/lldb_base.xml b/Ghidra/Debug/Debugger-agent-lldb/src/main/py/src/ghidralldb/lldb_base.xml
new file mode 100644
index 0000000000..a62bc71b48
--- /dev/null
+++ b/Ghidra/Debug/Debugger-agent-lldb/src/main/py/src/ghidralldb/lldb_base.xml
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Ghidra/Debug/Debugger-agent-lldb/src/main/py/src/ghidralldb/schema.xml b/Ghidra/Debug/Debugger-agent-lldb/src/main/py/src/ghidralldb/schema.xml
index e45d091fce..bc5b36b27e 100644
--- a/Ghidra/Debug/Debugger-agent-lldb/src/main/py/src/ghidralldb/schema.xml
+++ b/Ghidra/Debug/Debugger-agent-lldb/src/main/py/src/ghidralldb/schema.xml
@@ -1,268 +1,280 @@
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Ghidra/Debug/Debugger-agent-x64dbg/certification.manifest b/Ghidra/Debug/Debugger-agent-x64dbg/certification.manifest
index 49f3984ab1..71c24c832d 100644
--- a/Ghidra/Debug/Debugger-agent-x64dbg/certification.manifest
+++ b/Ghidra/Debug/Debugger-agent-x64dbg/certification.manifest
@@ -11,3 +11,4 @@ src/main/py/README.md||GHIDRA||||END|
src/main/py/pyproject.toml||GHIDRA||||END|
src/main/py/src/ghidraxdbg/py.typed||GHIDRA||||END|
src/main/py/src/ghidraxdbg/schema.xml||GHIDRA||||END|
+src/main/py/src/ghidraxdbg/x64dbg_base.xml||GHIDRA||||END|
diff --git a/Ghidra/Debug/Debugger-agent-x64dbg/src/main/py/src/ghidraxdbg/build_xml.py b/Ghidra/Debug/Debugger-agent-x64dbg/src/main/py/src/ghidraxdbg/build_xml.py
new file mode 100644
index 0000000000..4ffba44482
--- /dev/null
+++ b/Ghidra/Debug/Debugger-agent-x64dbg/src/main/py/src/ghidraxdbg/build_xml.py
@@ -0,0 +1,38 @@
+## ###
+# 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.
+##
+from merge_xml import merge
+import os
+import sys
+rmi_path = os.getcwd() + "/../../../../../../Debugger-rmi-trace/src/main/py/src/ghidratrace/"
+sys.path.append(rmi_path)
+
+
+def main():
+ xml = rmi_path+"xml/"
+ merge(xml_base="x64dbg_base.xml",
+ xml_out="schema.xml",
+ xml_updates=[
+ xml+"sessions.xml",
+ xml+"common.xml",
+ xml+"nesting_adjustments.xml",
+ xml+"available.xml",
+ xml+"events.xml",
+ xml+"breakpointsFlat.xml"
+ ])
+
+
+if __name__ == '__main__':
+ main()
diff --git a/Ghidra/Debug/Debugger-agent-x64dbg/src/main/py/src/ghidraxdbg/schema.xml b/Ghidra/Debug/Debugger-agent-x64dbg/src/main/py/src/ghidraxdbg/schema.xml
index a477772f39..736f2dfe41 100644
--- a/Ghidra/Debug/Debugger-agent-x64dbg/src/main/py/src/ghidraxdbg/schema.xml
+++ b/Ghidra/Debug/Debugger-agent-x64dbg/src/main/py/src/ghidraxdbg/schema.xml
@@ -1,317 +1,331 @@
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Ghidra/Debug/Debugger-agent-x64dbg/src/main/py/src/ghidraxdbg/x64dbg_base.xml b/Ghidra/Debug/Debugger-agent-x64dbg/src/main/py/src/ghidraxdbg/x64dbg_base.xml
new file mode 100644
index 0000000000..0d2350146e
--- /dev/null
+++ b/Ghidra/Debug/Debugger-agent-x64dbg/src/main/py/src/ghidraxdbg/x64dbg_base.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Ghidra/Debug/Debugger-rmi-trace/DEVNOTES.txt b/Ghidra/Debug/Debugger-rmi-trace/DEVNOTES.txt
index 48878e4415..54fc2451e9 100644
--- a/Ghidra/Debug/Debugger-rmi-trace/DEVNOTES.txt
+++ b/Ghidra/Debug/Debugger-rmi-trace/DEVNOTES.txt
@@ -310,3 +310,16 @@ The process parameter, if accepted, is technically redundant.
Because all address spaces among all targets must be unique, the address space encodes the process (or other target object).
If taken, the back end must validate that the address space belongs to the given process.
Otherwise, the back end must figure out the applicable target based on the space name.
+
+
+# Regarding the composition of schema
+
+Schema are now composable, i.e. the schema.xml files used by each debugger-agent may be reconstituted from smaller
+fragments, typically stored in a combination of each agent's python src directory and the common store, "ghidratrace/xml",
+in "Debugger-rmi-trace". The "gradle buildXmlSchema" task will build all of the schema, but individual schema may be
+built by executing "python build_xml.py" from the python src directory. Each build_xml python file calls the "merge_xml"
+python file in the rmi store, which uses either the powershell "merge.ps1" (Windows) or direct calls from "lxml" (Linux).
+Both methods rely on XSLT to transform the base XML (typically agentname_base.xml) by adding new schema from the subpieces
+or replacing attributes in common schema. There is currently no method for subtracting schema, so the entries in build_xml
+must be sequential with later entries overriding earlier ones.
+
diff --git a/Ghidra/Debug/Debugger-rmi-trace/certification.manifest b/Ghidra/Debug/Debugger-rmi-trace/certification.manifest
index 596d5a3829..2c705f4f2a 100644
--- a/Ghidra/Debug/Debugger-rmi-trace/certification.manifest
+++ b/Ghidra/Debug/Debugger-rmi-trace/certification.manifest
@@ -15,4 +15,12 @@ src/main/py/LICENSE||GHIDRA||||END|
src/main/py/README.md||GHIDRA||||END|
src/main/py/pyproject.toml||GHIDRA||||END|
src/main/py/src/ghidratrace/py.typed||GHIDRA||||END|
+src/main/py/src/ghidratrace/xml/available.xml||GHIDRA||||END|
+src/main/py/src/ghidratrace/xml/breakpointsFlat.xml||GHIDRA||||END|
+src/main/py/src/ghidratrace/xml/breakpointsTiered.xml||GHIDRA||||END|
+src/main/py/src/ghidratrace/xml/common.xml||GHIDRA||||END|
+src/main/py/src/ghidratrace/xml/events.xml||GHIDRA||||END|
+src/main/py/src/ghidratrace/xml/merge.xsl||GHIDRA||||END|
+src/main/py/src/ghidratrace/xml/nesting_adjustments.xml||GHIDRA||||END|
+src/main/py/src/ghidratrace/xml/sessions.xml||GHIDRA||||END|
src/main/py/tests/EMPTY||GHIDRA||||END|
diff --git a/Ghidra/Debug/Debugger-rmi-trace/src/main/py/src/ghidratrace/merge.ps1 b/Ghidra/Debug/Debugger-rmi-trace/src/main/py/src/ghidratrace/merge.ps1
new file mode 100644
index 0000000000..313cacae86
--- /dev/null
+++ b/Ghidra/Debug/Debugger-rmi-trace/src/main/py/src/ghidratrace/merge.ps1
@@ -0,0 +1,59 @@
+## ###
+# 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.
+##
+param (
+ [string]$XmlInput,
+ [string]$RmiDir,
+ [string]$XmlOutput,
+ [string]$XmlUpdates
+)
+
+Write-Host "Compositing schema..."
+$warning = $RmiDir+"warning.xml"
+$xslFile = $RmiDir+"merge.xsl"
+$xslt = New-Object System.Xml.Xsl.XslCompiledTransform
+$settings = New-Object System.Xml.Xsl.XsltSettings($true, $false)
+$resolver = New-Object System.Xml.XmlUrlResolver
+$xslt.Load((Resolve-Path $xslFile), $settings, $resolver)
+
+$workingFile = Join-Path $pwd "current.xml"
+Copy-Item $XmlInput $workingFile -Force
+$comment = "`r`n"
+$content = Get-Content $workingFile -Raw
+Set-Content $workingFile -Value ($comment + $content) -NoNewLine
+
+foreach ($fileName in ($XmlUpdates -split " ")) {
+ if (Test-Path $fileName) {
+ $scratch = Join-Path $pwd "temp.xml"
+
+ $xsltArgs = New-Object System.Xml.Xsl.XsltArgumentList
+ $xsltArgs.AddParam("fileName", "", (Resolve-Path $fileName).Path)
+
+ $writer = [System.Xml.XmlWriter]::Create($scratch, $xslt.OutputSettings)
+ try {
+ $xslt.Transform((Resolve-Path $workingFile).Path, $xsltArgs, $writer)
+ $writer.Close()
+ $writer.Dispose()
+
+ Move-Item $scratch $workingFile -Force
+ }
+ catch {
+ $writer.Close()
+ Write-Error "File not found: $fileName"
+ }
+ }
+}
+Move-Item $workingFile $XmlOutput -Force
+Write-Host "Transformation finished"
diff --git a/Ghidra/Debug/Debugger-rmi-trace/src/main/py/src/ghidratrace/merge_xml.py b/Ghidra/Debug/Debugger-rmi-trace/src/main/py/src/ghidratrace/merge_xml.py
new file mode 100644
index 0000000000..d50e98d3dd
--- /dev/null
+++ b/Ghidra/Debug/Debugger-rmi-trace/src/main/py/src/ghidratrace/merge_xml.py
@@ -0,0 +1,64 @@
+## ###
+# 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.
+##
+import os
+import inspect
+from typing import Sequence
+
+
+def merge(xml_base: str, xml_out: str, xml_updates: Sequence[str]) -> None:
+ frame = inspect.currentframe()
+ if frame is None:
+ raise AssertionError("we're cooked")
+ rmi = os.path.dirname(inspect.getfile(frame))
+
+ warning = "This file was autogenerated using build_xml. DO NOT EDIT."
+
+ # This appears to be necessitated by path issue, i.e. merge.xsl uses "document"
+ # and the Windows version of lxml doesn't do the right thing
+ if os.name == 'nt':
+ import subprocess
+
+ ps_script = rmi+'/merge.ps1'
+ updates = " ".join(xml_updates)
+ command = [
+ "powershell.exe",
+ "-ExecutionPolicy", "Bypass",
+ "-File", ps_script,
+ "-XmlInput", xml_base,
+ "-RmiDir", rmi,
+ "-XmlOutput", xml_out,
+ "-XmlUpdates", updates
+ ]
+ try:
+ result = subprocess.run(command, capture_output=True, text=True)
+ print(result.stdout)
+ except subprocess.CalledProcessError as e:
+ print(f"Error: {e.stderror}")
+ else:
+ from lxml import etree
+
+ merge_doc = etree.parse(xml_base)
+ warning_node = etree.Comment(warning)
+ root = merge_doc.getroot()
+ root.insert(0, warning_node)
+
+ xslt_doc = etree.parse(rmi+'/xml/merge.xsl')
+ transform = etree.XSLT(xslt_doc)
+ for xml_update in xml_updates:
+ merge_doc = transform(
+ merge_doc, fileName=etree.XSLT.strparam(xml_update))
+ with open(xml_out, "wb") as f:
+ f.write(merge_doc)
diff --git a/Ghidra/Debug/Debugger-rmi-trace/src/main/py/src/ghidratrace/xml/available.xml b/Ghidra/Debug/Debugger-rmi-trace/src/main/py/src/ghidratrace/xml/available.xml
new file mode 100644
index 0000000000..52b5680374
--- /dev/null
+++ b/Ghidra/Debug/Debugger-rmi-trace/src/main/py/src/ghidratrace/xml/available.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Ghidra/Debug/Debugger-rmi-trace/src/main/py/src/ghidratrace/xml/breakpointsFlat.xml b/Ghidra/Debug/Debugger-rmi-trace/src/main/py/src/ghidratrace/xml/breakpointsFlat.xml
new file mode 100644
index 0000000000..3aa486786a
--- /dev/null
+++ b/Ghidra/Debug/Debugger-rmi-trace/src/main/py/src/ghidratrace/xml/breakpointsFlat.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Ghidra/Debug/Debugger-rmi-trace/src/main/py/src/ghidratrace/xml/breakpointsTiered.xml b/Ghidra/Debug/Debugger-rmi-trace/src/main/py/src/ghidratrace/xml/breakpointsTiered.xml
new file mode 100644
index 0000000000..00f105099f
--- /dev/null
+++ b/Ghidra/Debug/Debugger-rmi-trace/src/main/py/src/ghidratrace/xml/breakpointsTiered.xml
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Ghidra/Debug/Debugger-rmi-trace/src/main/py/src/ghidratrace/xml/common.xml b/Ghidra/Debug/Debugger-rmi-trace/src/main/py/src/ghidratrace/xml/common.xml
new file mode 100644
index 0000000000..0f919d60e6
--- /dev/null
+++ b/Ghidra/Debug/Debugger-rmi-trace/src/main/py/src/ghidratrace/xml/common.xml
@@ -0,0 +1,167 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Ghidra/Debug/Debugger-rmi-trace/src/main/py/src/ghidratrace/xml/events.xml b/Ghidra/Debug/Debugger-rmi-trace/src/main/py/src/ghidratrace/xml/events.xml
new file mode 100644
index 0000000000..cd021bb8ce
--- /dev/null
+++ b/Ghidra/Debug/Debugger-rmi-trace/src/main/py/src/ghidratrace/xml/events.xml
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Ghidra/Debug/Debugger-rmi-trace/src/main/py/src/ghidratrace/xml/merge.xsl b/Ghidra/Debug/Debugger-rmi-trace/src/main/py/src/ghidratrace/xml/merge.xsl
new file mode 100644
index 0000000000..14818bc3e0
--- /dev/null
+++ b/Ghidra/Debug/Debugger-rmi-trace/src/main/py/src/ghidratrace/xml/merge.xsl
@@ -0,0 +1,93 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Ghidra/Debug/Debugger-rmi-trace/src/main/py/src/ghidratrace/xml/nesting_adjustments.xml b/Ghidra/Debug/Debugger-rmi-trace/src/main/py/src/ghidratrace/xml/nesting_adjustments.xml
new file mode 100644
index 0000000000..67f542c5a9
--- /dev/null
+++ b/Ghidra/Debug/Debugger-rmi-trace/src/main/py/src/ghidratrace/xml/nesting_adjustments.xml
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Ghidra/Debug/Debugger-rmi-trace/src/main/py/src/ghidratrace/xml/sessions.xml b/Ghidra/Debug/Debugger-rmi-trace/src/main/py/src/ghidratrace/xml/sessions.xml
new file mode 100644
index 0000000000..0efcd9b358
--- /dev/null
+++ b/Ghidra/Debug/Debugger-rmi-trace/src/main/py/src/ghidratrace/xml/sessions.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/gradle/hasPythonPackage.gradle b/gradle/hasPythonPackage.gradle
index 285fe3aa1f..68aead7f6c 100644
--- a/gradle/hasPythonPackage.gradle
+++ b/gradle/hasPythonPackage.gradle
@@ -124,3 +124,34 @@ ext.distributePyDep = { name ->
}
}
}
+
+// This task composes debugger schema files from their subpieces
+
+def foundFiles = fileTree("src/main/py/src").matching {
+ include "**/build_xml.py"
+}
+
+task buildXmlSchema {
+ doLast {
+ if (rootProject.PYTHON3 == null) {
+ throw new GradleException("A supported version of Python [${PYTHON_SUPPORTED}] was not found!")
+ }
+
+ File buildScript = foundFiles.isEmpty() ? null : foundFiles.singleFile
+ if (buildScript == null || !buildScript.exists()) {
+ println "Warning: Could not find build_xml.py for ${project.name}"
+ return
+ }
+
+ def exec = providers.exec {
+ workingDir { buildScript.parentFile }
+ ignoreExitValue = true
+ commandLine rootProject.PYTHON3
+ args "build_xml.py"
+ }
+ if (exec.result.get().exitValue != 0) {
+ throw new GradleException(exec.standardError.asText.get().strip())
+ }
+ }
+}
+