From 1ea11b20df71c5c54dd2bed718e019479a7caf1a Mon Sep 17 00:00:00 2001 From: ghidra1 Date: Wed, 10 Jun 2026 12:26:44 -0400 Subject: [PATCH 1/2] GP-6891 Improved Debugger Trace import/export support and added packed DBTrace GZT file type. --- .../main/java/ghidra/dbg/isf/IsfServer.java | 43 ++-- .../debug/export/TraceViewAsciiExporter.java | 27 --- .../debug/export/TraceViewBinaryExporter.java | 27 --- .../debug/export/TraceViewHtmlExporter.java | 27 --- .../export/TraceViewIntelHexExporter.java | 27 --- .../debug/export/TraceViewXmlExporter.java | 56 ----- .../debug/gui/export/TraceExportPlugin.java | 197 ++++++++++++++++++ .../DebuggerTraceManagerServicePlugin.java | 6 +- .../plugin/core/debug/utils/GztExporter.java | 122 +++++++++++ .../plugin/core/debug/utils/GztLoader.java | 177 ++++++++++++++++ .../gui/AbstractGhidraHeadedDebuggerTest.java | 2 +- .../trace/database/ToyDBTraceBuilder.java | 6 +- .../help/topics/ExporterPlugin/exporter.htm | 14 +- .../help/help/topics/Glossary/glossary.htm | 14 +- .../help/topics/ImporterPlugin/importer.htm | 14 +- .../plugin/core/exporter/ExporterDialog.java | 2 +- .../plugin/core/exporter/ExporterPlugin.java | 71 ++++--- .../core/progmgr/MultiProgramManager.java | 21 +- .../core/progmgr/ProgramManagerPlugin.java | 3 +- .../SourceFilesTablePlugin.java | 12 +- .../app/util/exporter/AsciiExporter.java | 13 +- .../app/util/exporter/BinaryExporter.java | 32 ++- .../ghidra/app/util/exporter/Exporter.java | 19 +- .../ghidra/app/util/exporter/GdtExporter.java | 5 +- .../ghidra/app/util/exporter/GzfExporter.java | 5 +- .../app/util/exporter/HtmlExporter.java | 13 +- .../app/util/exporter/IntelHexExporter.java | 8 +- .../util/exporter/OriginalFileExporter.java | 21 +- .../app/util/exporter/ProgramExporter.java | 55 +++++ .../ghidra/app/util/exporter/XmlExporter.java | 15 +- .../ghidra/app/util/opinion/GdtLoader.java | 2 +- .../ghidra/app/util/opinion/GzfLoader.java | 3 +- .../plugin/importer/ImporterPlugin.java | 2 +- .../plugin/importer/ImporterUtilities.java | 85 +++++--- .../ghidra/app/util/exporter/CppExporter.java | 11 +- .../main/java/sarif/export/SarifExporter.java | 14 +- .../ghidra/framework/store/FolderItem.java | 8 +- .../store/local/ItemDeserializer.java | 12 +- .../store/local/LocalDataFileItem.java | 11 +- .../store/local/LocalDatabaseItem.java | 13 +- .../store/local/LocalTextDataItem.java | 2 +- .../store/local/LocalUnknownFolderItem.java | 3 +- .../ghidra/framework/model/DomainObject.java | 2 +- .../main/java/skeleton/SkeletonExporter.java | 6 + 44 files changed, 866 insertions(+), 362 deletions(-) delete mode 100644 Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/export/TraceViewAsciiExporter.java delete mode 100644 Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/export/TraceViewBinaryExporter.java delete mode 100644 Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/export/TraceViewHtmlExporter.java delete mode 100644 Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/export/TraceViewIntelHexExporter.java delete mode 100644 Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/export/TraceViewXmlExporter.java create mode 100644 Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/export/TraceExportPlugin.java create mode 100644 Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/utils/GztExporter.java create mode 100644 Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/utils/GztLoader.java create mode 100644 Ghidra/Features/Base/src/main/java/ghidra/app/util/exporter/ProgramExporter.java diff --git a/Ghidra/Debug/Debugger-isf/src/main/java/ghidra/dbg/isf/IsfServer.java b/Ghidra/Debug/Debugger-isf/src/main/java/ghidra/dbg/isf/IsfServer.java index f60cd30bce..ccf8613a3c 100644 --- a/Ghidra/Debug/Debugger-isf/src/main/java/ghidra/dbg/isf/IsfServer.java +++ b/Ghidra/Debug/Debugger-isf/src/main/java/ghidra/dbg/isf/IsfServer.java @@ -37,7 +37,6 @@ import ghidra.program.model.data.DataTypeManager; import ghidra.program.model.data.FileDataTypeManager; import ghidra.program.model.listing.Program; import ghidra.util.Msg; -import ghidra.util.exception.VersionException; import ghidra.util.task.TaskMonitor; public class IsfServer extends Thread { @@ -102,13 +101,13 @@ public class IsfServer extends Thread { try { DataTypeManager dtm; if (ns.endsWith(".gdt")) { - dtm = openAsArchive(ns); + dtm = openAsDataTypeArchive(ns); } else if (ns.endsWith(".gzf")) { - dtm = openAsDatabase(ns); + dtm = openAsProgramDatabase(ns); } else { - dtm = openAsDomainFile(ns); + dtm = openAsProgramFile(ns); } managers.put(ns, dtm); return dtm; @@ -120,43 +119,43 @@ public class IsfServer extends Thread { } } - private DataTypeManager openAsDomainFile(String ns) throws Exception { + private DataTypeManager openAsProgramFile(String ns) throws Exception { ProjectData projectData = project.getProjectData(); DomainFile df = projectData.getFile(ns); + if (!Program.class.isAssignableFrom(df.getDomainObjectClass())) { + throw new IOException("File does not correspond to Program content: " + ns); + } + + // FIXME: Need to track and release Program instance after DTM use is complete (GP-6895) Program program = (Program) df.getDomainObject(this, false, false, TaskMonitor.DUMMY); return program.getDataTypeManager(); } - private DataTypeManager openAsArchive(String ns) throws Exception { + private DataTypeManager openAsDataTypeArchive(String ns) throws Exception { File gdt = new File(ns); return FileDataTypeManager.openFileArchive(gdt, false); } - private DataTypeManager openAsDatabase(String ns) throws Exception { + private DataTypeManager openAsProgramDatabase(String ns) throws Exception { File gzf = new File(ns); TaskMonitor dummy = TaskMonitor.DUMMY; PackedDatabase db = PackedDatabase.getPackedDatabase(gzf, dummy); + DBHandle dbh = db.openForUpdate(dummy); - ProgramDB p = null; + + Program p; + boolean success = false; try { - p = new ProgramDB(dbh, OpenMode.UPDATE, dummy, this); - } - catch (VersionException e) { - if (!e.isUpgradable()) { - throw new RuntimeException(p + " uses an older version and is not upgradable."); - } + p = new ProgramDB(dbh, OpenMode.UPGRADE, dummy, this); + success = true; } finally { - dbh.close(); - } - - dbh = db.openForUpdate(dummy); - p = new ProgramDB(dbh, OpenMode.UPGRADE, dummy, this); - - if (!p.isChanged()) { - throw new RuntimeException(p + " uses an older version and was not upgraded."); + if (!success) { + dbh.close(); + } } + // FIXME: Need to track and release Program instance after DTM use is complete (GP-6895) return p.getListing().getDataTypeManager(); } diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/export/TraceViewAsciiExporter.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/export/TraceViewAsciiExporter.java deleted file mode 100644 index f31c1ffe8a..0000000000 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/export/TraceViewAsciiExporter.java +++ /dev/null @@ -1,27 +0,0 @@ -/* ### - * 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. - */ -package ghidra.app.plugin.core.debug.export; - -import ghidra.app.util.exporter.AsciiExporter; -import ghidra.framework.model.DomainObject; -import ghidra.trace.model.Trace; - -public class TraceViewAsciiExporter extends AsciiExporter { - @Override - public boolean canExportDomainObject(Class domainObjectClass) { - return Trace.class.isAssignableFrom(domainObjectClass); - } -} diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/export/TraceViewBinaryExporter.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/export/TraceViewBinaryExporter.java deleted file mode 100644 index 2949322a91..0000000000 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/export/TraceViewBinaryExporter.java +++ /dev/null @@ -1,27 +0,0 @@ -/* ### - * 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. - */ -package ghidra.app.plugin.core.debug.export; - -import ghidra.app.util.exporter.BinaryExporter; -import ghidra.framework.model.DomainObject; -import ghidra.trace.model.Trace; - -public class TraceViewBinaryExporter extends BinaryExporter { - @Override - public boolean canExportDomainObject(Class domainObjectClass) { - return Trace.class.isAssignableFrom(domainObjectClass); - } -} diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/export/TraceViewHtmlExporter.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/export/TraceViewHtmlExporter.java deleted file mode 100644 index b9c581e2c9..0000000000 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/export/TraceViewHtmlExporter.java +++ /dev/null @@ -1,27 +0,0 @@ -/* ### - * 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. - */ -package ghidra.app.plugin.core.debug.export; - -import ghidra.app.util.exporter.HtmlExporter; -import ghidra.framework.model.DomainObject; -import ghidra.trace.model.Trace; - -public class TraceViewHtmlExporter extends HtmlExporter { - @Override - public boolean canExportDomainObject(Class domainObjectClass) { - return Trace.class.isAssignableFrom(domainObjectClass); - } -} diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/export/TraceViewIntelHexExporter.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/export/TraceViewIntelHexExporter.java deleted file mode 100644 index 96c85d60fd..0000000000 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/export/TraceViewIntelHexExporter.java +++ /dev/null @@ -1,27 +0,0 @@ -/* ### - * 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. - */ -package ghidra.app.plugin.core.debug.export; - -import ghidra.app.util.exporter.IntelHexExporter; -import ghidra.framework.model.DomainObject; -import ghidra.trace.model.Trace; - -public class TraceViewIntelHexExporter extends IntelHexExporter { - @Override - public boolean canExportDomainObject(Class domainObjectClass) { - return Trace.class.isAssignableFrom(domainObjectClass); - } -} diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/export/TraceViewXmlExporter.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/export/TraceViewXmlExporter.java deleted file mode 100644 index 46ab514eb6..0000000000 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/export/TraceViewXmlExporter.java +++ /dev/null @@ -1,56 +0,0 @@ -/* ### - * 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. - */ -package ghidra.app.plugin.core.debug.export; - -import java.util.*; -import java.util.stream.Collectors; - -import ghidra.app.util.*; -import ghidra.app.util.exporter.XmlExporter; -import ghidra.framework.model.DomainObject; -import ghidra.trace.model.Trace; - -// TODO: perhaps getApplicableExporters should use domainObject's class, not file's object class. -// TODO: Where un-supported, be less abrasive, e.g., present empty managers. -public class TraceViewXmlExporter extends XmlExporter { - private final Map hideOpts = Map.of( - "Properties", false, - "Relocation Table", false, - "External Libraries", false); - - @Override - public boolean canExportDomainObject(Class domainObjectClass) { - return Trace.class.isAssignableFrom(domainObjectClass); - } - - @Override - public List