From f54bd20d40f50b95c3dd8309d79bb88415d501ad Mon Sep 17 00:00:00 2001
From: ghidragon <106987263+ghidragon@users.noreply.github.com>
Date: Wed, 2 Jul 2025 13:20:47 -0400
Subject: [PATCH] GP-5481 Created prototype data graph feature
---
Ghidra/Debug/Debugger/build.gradle | 1 +
.../graph/data/DebuggerDataGraphPlugin.java | 76 ++
.../CircleWithLabelVertexShapeProvider.java | 8 +-
.../program/database/ProgramBuilder.java | 44 +
Ghidra/Features/DataGraph/Module.manifest | 1 +
Ghidra/Features/DataGraph/build.gradle | 34 +
.../Features/DataGraph/certification.manifest | 8 +
.../DataGraph/data/datagraph.theme.properties | 4 +
.../src/main/help/help/TOC_Source.xml | 64 ++
.../topics/DataGraphPlugin/Data_Graph.html | 250 ++++++
.../DataGraphPlugin/images/CodeVertex.png | Bin 0 -> 20126 bytes
.../DataGraphPlugin/images/DataGraph.png | Bin 0 -> 49444 bytes
.../datagraph/AbstractDataGraphPlugin.java | 84 ++
.../main/java/datagraph/DataGraphPlugin.java | 75 ++
.../java/datagraph/DataGraphProvider.java | 296 +++++++
.../src/main/java/datagraph/DegContext.java | 54 ++
.../java/datagraph/DegSatelliteContext.java | 32 +
.../datagraph/data/graph/CodeDegVertex.java | 181 +++++
.../datagraph/data/graph/DataDegVertex.java | 390 +++++++++
.../data/graph/DataExplorationGraph.java | 61 ++
.../datagraph/data/graph/DegController.java | 749 ++++++++++++++++++
.../java/datagraph/data/graph/DegEdge.java | 35 +
.../datagraph/data/graph/DegGraphView.java | 60 ++
.../java/datagraph/data/graph/DegLayout.java | 71 ++
.../data/graph/DegLayoutProvider.java | 46 ++
.../java/datagraph/data/graph/DegVertex.java | 116 +++
.../data/graph/panel/DataVertexPanel.java | 656 +++++++++++++++
.../panel/DtComponentPathComparator.java | 43 +
.../model/column/CompactDataColumnModel.java | 132 +++
.../model/column/ExpandedDataColumnModel.java | 122 +++
.../model/column/PointerColumnRenderer.java | 44 +
.../model/column/ValueColumnRenderer.java | 41 +
.../model/row/ArrayGroupDataRowObject.java | 61 ++
.../model/row/ComponentDataRowObject.java | 65 ++
.../graph/panel/model/row/DataRowObject.java | 85 ++
.../panel/model/row/DataRowObjectCache.java | 59 ++
.../panel/model/row/DataTrableRowModel.java | 141 ++++
.../panel/model/row/OpenDataChildren.java | 469 +++++++++++
.../explore/AbstractExplorationGraph.java | 143 ++++
.../java/datagraph/graph/explore/EgEdge.java | 30 +
.../graph/explore/EgEdgeRenderer.java | 49 ++
.../graph/explore/EgEdgeTransformer.java | 88 ++
.../graph/explore/EgGraphLayout.java | 268 +++++++
.../datagraph/graph/explore/EgVertex.java | 129 +++
.../graph/explore/GraphLocationMap.java | 130 +++
.../resources/images/view_detailed_16.png | Bin 0 -> 961 bytes
.../graph/DataGraphProviderTest.java | 531 +++++++++++++
.../datagraph/graph/EgGraphLayoutTest.java | 304 +++++++
.../datagraph/graph/GraphLocationMapTest.java | 91 +++
.../src/main/help/help/TOC_Source.xml | 2 +-
.../FunctionGraphPlugin/Function_Graph.html | 157 +---
.../functiongraph/graph/FunctionGraph.java | 2 +-
.../graph/layout/EmptyLayout.java | 8 +-
.../flowchart/AbstractFlowChartLayout.java | 2 +-
.../layout/flowchart/FlowChartLayoutTest.java | 4 +-
.../layout/flowchart/EdgeSegmentTest.java | 2 -
.../graph/FcgVertexShapeProvider.java | 2 +-
.../main/java/docking/DockableComponent.java | 1 +
.../java/docking/DockableToolBarManager.java | 3 +-
.../src/main/java/docking/GenericHeader.java | 12 +-
.../tabbedpane/DockingTabRenderer.java | 5 +-
.../trable/AbstractGTrableRowModel.java | 45 ++
.../trable/DefaultGTrableCellRenderer.java | 51 ++
.../trable/DefaultGTrableRowModel.java | 98 +++
.../java/docking/widgets/trable/GTrable.java | 646 +++++++++++++++
.../trable/GTrableCellClickedListener.java | 32 +
.../widgets/trable/GTrableCellRenderer.java | 40 +
.../docking/widgets/trable/GTrableColumn.java | 76 ++
.../widgets/trable/GTrableColumnModel.java | 252 ++++++
.../trable/GTrableModeRowlListener.java | 27 +
.../docking/widgets/trable/GTrableRow.java | 66 ++
.../widgets/trable/GTrableRowModel.java | 84 ++
.../docking/widgets/trable/OpenCloseIcon.java | 105 +++
.../docking/widgets/trable/GTrableTest.java | 338 ++++++++
Ghidra/Framework/Graph/build.gradle | 5 +-
Ghidra/Framework/Graph/certification.manifest | 2 +
.../Graph/src/main/help/help/TOC_Source.xml | 54 ++
.../help/topics/VisualGraph/Visual_Graph.html | 149 ++++
.../graph/VisualGraphComponentProvider.java | 12 +-
.../featurette/VgSatelliteFeaturette.java | 53 +-
.../job/RelayoutAndCenterVertexGraphJob.java | 78 ++
.../graph/job/RelayoutAndEnsureVisible.java | 166 ++++
.../graph/job/RelayoutFunctionGraphJob.java | 27 +-
.../ghidra/graph/viewer/GraphComponent.java | 19 +-
.../ghidra/graph/viewer/GraphViewerUtils.java | 44 +-
.../viewer/event/mouse/VertexMouseInfo.java | 36 +-
...lGraphEventForwardingGraphMousePlugin.java | 5 +-
.../VisualGraphPickingGraphMousePlugin.java | 25 +-
.../mouse/VisualGraphPluggableGraphMouse.java | 110 ++-
.../layout/AbstractVisualGraphLayout.java | 10 +-
.../graph/viewer/layout/GridBounds.java | 10 +
.../graph/viewer/layout/GridLocationMap.java | 49 +-
.../ghidra/graph/viewer/layout/GridPoint.java | 6 +
.../JungWrappingVisualGraphLayoutAdapter.java | 10 +-
.../graph/viewer/layout/LayoutListener.java | 13 +-
.../graph/viewer/layout/LayoutPositions.java | 9 +-
.../viewer/layout/VisualGraphLayout.java | 12 +-
.../shape/ArticulatedEdgeTransformer.java | 81 +-
.../shape/VisualGraphShapePickSupport.java | 5 +-
.../main/java/generic/theme}/CloseIcon.java | 11 +-
.../Gui/src/main/java/resources/Icons.java | 6 +-
.../DataGraphPluginScreenShots.java | 145 ++++
102 files changed, 9267 insertions(+), 366 deletions(-)
create mode 100644 Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/graph/data/DebuggerDataGraphPlugin.java
create mode 100644 Ghidra/Features/DataGraph/Module.manifest
create mode 100644 Ghidra/Features/DataGraph/build.gradle
create mode 100644 Ghidra/Features/DataGraph/certification.manifest
create mode 100644 Ghidra/Features/DataGraph/data/datagraph.theme.properties
create mode 100644 Ghidra/Features/DataGraph/src/main/help/help/TOC_Source.xml
create mode 100644 Ghidra/Features/DataGraph/src/main/help/help/topics/DataGraphPlugin/Data_Graph.html
create mode 100644 Ghidra/Features/DataGraph/src/main/help/help/topics/DataGraphPlugin/images/CodeVertex.png
create mode 100644 Ghidra/Features/DataGraph/src/main/help/help/topics/DataGraphPlugin/images/DataGraph.png
create mode 100644 Ghidra/Features/DataGraph/src/main/java/datagraph/AbstractDataGraphPlugin.java
create mode 100644 Ghidra/Features/DataGraph/src/main/java/datagraph/DataGraphPlugin.java
create mode 100644 Ghidra/Features/DataGraph/src/main/java/datagraph/DataGraphProvider.java
create mode 100644 Ghidra/Features/DataGraph/src/main/java/datagraph/DegContext.java
create mode 100644 Ghidra/Features/DataGraph/src/main/java/datagraph/DegSatelliteContext.java
create mode 100644 Ghidra/Features/DataGraph/src/main/java/datagraph/data/graph/CodeDegVertex.java
create mode 100644 Ghidra/Features/DataGraph/src/main/java/datagraph/data/graph/DataDegVertex.java
create mode 100644 Ghidra/Features/DataGraph/src/main/java/datagraph/data/graph/DataExplorationGraph.java
create mode 100644 Ghidra/Features/DataGraph/src/main/java/datagraph/data/graph/DegController.java
create mode 100644 Ghidra/Features/DataGraph/src/main/java/datagraph/data/graph/DegEdge.java
create mode 100644 Ghidra/Features/DataGraph/src/main/java/datagraph/data/graph/DegGraphView.java
create mode 100644 Ghidra/Features/DataGraph/src/main/java/datagraph/data/graph/DegLayout.java
create mode 100644 Ghidra/Features/DataGraph/src/main/java/datagraph/data/graph/DegLayoutProvider.java
create mode 100644 Ghidra/Features/DataGraph/src/main/java/datagraph/data/graph/DegVertex.java
create mode 100644 Ghidra/Features/DataGraph/src/main/java/datagraph/data/graph/panel/DataVertexPanel.java
create mode 100644 Ghidra/Features/DataGraph/src/main/java/datagraph/data/graph/panel/DtComponentPathComparator.java
create mode 100644 Ghidra/Features/DataGraph/src/main/java/datagraph/data/graph/panel/model/column/CompactDataColumnModel.java
create mode 100644 Ghidra/Features/DataGraph/src/main/java/datagraph/data/graph/panel/model/column/ExpandedDataColumnModel.java
create mode 100644 Ghidra/Features/DataGraph/src/main/java/datagraph/data/graph/panel/model/column/PointerColumnRenderer.java
create mode 100644 Ghidra/Features/DataGraph/src/main/java/datagraph/data/graph/panel/model/column/ValueColumnRenderer.java
create mode 100644 Ghidra/Features/DataGraph/src/main/java/datagraph/data/graph/panel/model/row/ArrayGroupDataRowObject.java
create mode 100644 Ghidra/Features/DataGraph/src/main/java/datagraph/data/graph/panel/model/row/ComponentDataRowObject.java
create mode 100644 Ghidra/Features/DataGraph/src/main/java/datagraph/data/graph/panel/model/row/DataRowObject.java
create mode 100644 Ghidra/Features/DataGraph/src/main/java/datagraph/data/graph/panel/model/row/DataRowObjectCache.java
create mode 100644 Ghidra/Features/DataGraph/src/main/java/datagraph/data/graph/panel/model/row/DataTrableRowModel.java
create mode 100644 Ghidra/Features/DataGraph/src/main/java/datagraph/data/graph/panel/model/row/OpenDataChildren.java
create mode 100644 Ghidra/Features/DataGraph/src/main/java/datagraph/graph/explore/AbstractExplorationGraph.java
create mode 100644 Ghidra/Features/DataGraph/src/main/java/datagraph/graph/explore/EgEdge.java
create mode 100644 Ghidra/Features/DataGraph/src/main/java/datagraph/graph/explore/EgEdgeRenderer.java
create mode 100644 Ghidra/Features/DataGraph/src/main/java/datagraph/graph/explore/EgEdgeTransformer.java
create mode 100644 Ghidra/Features/DataGraph/src/main/java/datagraph/graph/explore/EgGraphLayout.java
create mode 100644 Ghidra/Features/DataGraph/src/main/java/datagraph/graph/explore/EgVertex.java
create mode 100644 Ghidra/Features/DataGraph/src/main/java/datagraph/graph/explore/GraphLocationMap.java
create mode 100644 Ghidra/Features/DataGraph/src/main/resources/images/view_detailed_16.png
create mode 100644 Ghidra/Features/DataGraph/src/test/java/datagraph/graph/DataGraphProviderTest.java
create mode 100644 Ghidra/Features/DataGraph/src/test/java/datagraph/graph/EgGraphLayoutTest.java
create mode 100644 Ghidra/Features/DataGraph/src/test/java/datagraph/graph/GraphLocationMapTest.java
rename Ghidra/Features/FunctionGraph/src/test/{java => }/ghidra/app/plugin/core/functiongraph/graph/layout/flowchart/EdgeSegmentTest.java (99%)
create mode 100644 Ghidra/Framework/Docking/src/main/java/docking/widgets/trable/AbstractGTrableRowModel.java
create mode 100644 Ghidra/Framework/Docking/src/main/java/docking/widgets/trable/DefaultGTrableCellRenderer.java
create mode 100644 Ghidra/Framework/Docking/src/main/java/docking/widgets/trable/DefaultGTrableRowModel.java
create mode 100644 Ghidra/Framework/Docking/src/main/java/docking/widgets/trable/GTrable.java
create mode 100644 Ghidra/Framework/Docking/src/main/java/docking/widgets/trable/GTrableCellClickedListener.java
create mode 100644 Ghidra/Framework/Docking/src/main/java/docking/widgets/trable/GTrableCellRenderer.java
create mode 100644 Ghidra/Framework/Docking/src/main/java/docking/widgets/trable/GTrableColumn.java
create mode 100644 Ghidra/Framework/Docking/src/main/java/docking/widgets/trable/GTrableColumnModel.java
create mode 100644 Ghidra/Framework/Docking/src/main/java/docking/widgets/trable/GTrableModeRowlListener.java
create mode 100644 Ghidra/Framework/Docking/src/main/java/docking/widgets/trable/GTrableRow.java
create mode 100644 Ghidra/Framework/Docking/src/main/java/docking/widgets/trable/GTrableRowModel.java
create mode 100644 Ghidra/Framework/Docking/src/main/java/docking/widgets/trable/OpenCloseIcon.java
create mode 100644 Ghidra/Framework/Docking/src/test/java/docking/widgets/trable/GTrableTest.java
create mode 100644 Ghidra/Framework/Graph/src/main/help/help/TOC_Source.xml
create mode 100644 Ghidra/Framework/Graph/src/main/help/help/topics/VisualGraph/Visual_Graph.html
create mode 100644 Ghidra/Framework/Graph/src/main/java/ghidra/graph/job/RelayoutAndCenterVertexGraphJob.java
create mode 100644 Ghidra/Framework/Graph/src/main/java/ghidra/graph/job/RelayoutAndEnsureVisible.java
rename Ghidra/Framework/{Docking/src/main/java/docking => Gui/src/main/java/generic/theme}/CloseIcon.java (95%)
create mode 100644 Ghidra/Test/IntegrationTest/src/screen/java/help/screenshot/DataGraphPluginScreenShots.java
diff --git a/Ghidra/Debug/Debugger/build.gradle b/Ghidra/Debug/Debugger/build.gradle
index 5bb9a15cbc..2cd52327a8 100644
--- a/Ghidra/Debug/Debugger/build.gradle
+++ b/Ghidra/Debug/Debugger/build.gradle
@@ -31,6 +31,7 @@ dependencies {
api project(':DecompilerDependent')
api project(':FunctionGraph')
api project(':ProposedUtils')
+ api project(':DataGraph')
testImplementation project(path: ':Generic', configuration: 'testArtifacts')
testImplementation project(path: ':Base', configuration: 'testArtifacts')
diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/graph/data/DebuggerDataGraphPlugin.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/graph/data/DebuggerDataGraphPlugin.java
new file mode 100644
index 0000000000..e1846e08be
--- /dev/null
+++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/graph/data/DebuggerDataGraphPlugin.java
@@ -0,0 +1,76 @@
+/* ###
+ * 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.gui.graph.data;
+
+import datagraph.AbstractDataGraphPlugin;
+import ghidra.app.context.ListingActionContext;
+import ghidra.app.plugin.PluginCategoryNames;
+import ghidra.app.plugin.core.debug.DebuggerPluginPackage;
+import ghidra.app.plugin.core.debug.event.TraceLocationPluginEvent;
+import ghidra.framework.plugintool.*;
+import ghidra.framework.plugintool.util.PluginStatus;
+import ghidra.program.util.ProgramLocation;
+
+/**
+ * Plugin for showing a graph of data from the listing.
+ */
+//@formatter:off
+@PluginInfo(
+ status = PluginStatus.RELEASED,
+ packageName = DebuggerPluginPackage.NAME,
+ category = PluginCategoryNames.DEBUGGER,
+ shortDescription = "Debugger Data Graph",
+ description = """
+ Plugin for displaying graphs of data objects in memory. From any data object in the
+ listing, the user can display a graph of that data object. Initially, a graph will be shown
+ with one vertex that has a scrollable view of the values in memory associated with that data.
+ Also, any pointers or references from or to that data can be explored by following the
+ references and creating additional vertices for the referenced code or data.
+ """,
+ eventsConsumed = {
+ TraceLocationPluginEvent.class,
+ },
+ eventsProduced = {
+ TraceLocationPluginEvent.class,
+ }
+)
+//@formatter:on
+public class DebuggerDataGraphPlugin extends AbstractDataGraphPlugin {
+ public DebuggerDataGraphPlugin(PluginTool plugintool) {
+ super(plugintool);
+ }
+
+ @Override
+ public void processEvent(PluginEvent event) {
+ if (event instanceof TraceLocationPluginEvent ev) {
+ ProgramLocation location = ev.getLocation();
+ goTo(location);
+ }
+ }
+
+ @Override
+ public void fireLocationEvent(ProgramLocation location) {
+ firePluginEvent(new TraceLocationPluginEvent(getName(), location));
+ }
+
+ @Override
+ protected boolean isGraphActionEnabled(ListingActionContext context) {
+ if (!context.getNavigatable().isDynamic()) {
+ return false;
+ }
+ return super.isGraphActionEnabled(context);
+ }
+}
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/base/graph/CircleWithLabelVertexShapeProvider.java b/Ghidra/Features/Base/src/main/java/ghidra/base/graph/CircleWithLabelVertexShapeProvider.java
index 743f039f7d..9a042bf216 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/base/graph/CircleWithLabelVertexShapeProvider.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/base/graph/CircleWithLabelVertexShapeProvider.java
@@ -73,6 +73,7 @@ public class CircleWithLabelVertexShapeProvider implements VertexShapeProvider {
protected boolean useDebugBorders = false;
private String fullLabelText;
+ private int circleCenterYOffset;
public CircleWithLabelVertexShapeProvider(String label) {
this.fullLabelText = label;
@@ -85,6 +86,10 @@ public class CircleWithLabelVertexShapeProvider implements VertexShapeProvider {
buildUi();
}
+ public int getCircleCenterYOffset() {
+ return circleCenterYOffset;
+ }
+
protected void buildUi() {
String name = generateLabelText();
@@ -201,6 +206,7 @@ public class CircleWithLabelVertexShapeProvider implements VertexShapeProvider {
vertexImageLabel.setBounds(x, y, size.width, size.height);
Dimension shapeSize = vertexShape.getBounds().getSize();
+ circleCenterYOffset = shapeSize.height / 2 - parentSize.height / 2;
// setFrame() will make sure the shape's x,y values are where they need to be
// for the later 'full shape' creation
@@ -332,7 +338,7 @@ public class CircleWithLabelVertexShapeProvider implements VertexShapeProvider {
return false;
}
- protected void setTogglesVisible(boolean visible) {
+ public void setTogglesVisible(boolean visible) {
toggleInsButton.setVisible(visible);
toggleOutsButton.setVisible(visible);
}
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/program/database/ProgramBuilder.java b/Ghidra/Features/Base/src/main/java/ghidra/program/database/ProgramBuilder.java
index 13fda9b7cd..23add48ab5 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/program/database/ProgramBuilder.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/program/database/ProgramBuilder.java
@@ -397,6 +397,50 @@ public class ProgramBuilder {
}
}
+ public void setString(String address, String string) throws Exception {
+ byte[] bytes = string.getBytes();
+ setBytes(address, bytes);
+ }
+
+ public void setShort(String address, short value) throws Exception {
+ DataConverter converter = getDataConverter();
+ byte[] bytes = converter.getBytes(value);
+ setBytes(address, bytes);
+ }
+
+ public void setInt(String address, int value) throws Exception {
+ DataConverter converter = getDataConverter();
+ byte[] bytes = converter.getBytes(value);
+ setBytes(address, bytes);
+ }
+
+ public void setLong(String address, long value) throws Exception {
+ DataConverter converter = getDataConverter();
+ byte[] bytes = converter.getBytes(value);
+ setBytes(address, bytes);
+ }
+
+ public void putAddress(String address, String pointerAddress) throws Exception {
+ Address pointer = addr(pointerAddress);
+ long offset = pointer.getOffset();
+ int pointerSize = pointer.getAddressSpace().getPointerSize();
+ switch (pointerSize) {
+ case 2:
+ setShort(address, (short) offset);
+ break;
+ case 4:
+ setInt(address, (int) offset);
+ break;
+ default:
+ setLong(address, offset);
+ }
+ }
+
+ private DataConverter getDataConverter() {
+ boolean bigEndian = program.getMemory().isBigEndian();
+ return bigEndian ? BigEndianDataConverter.INSTANCE : LittleEndianDataConverter.INSTANCE;
+ }
+
public void setRead(MemoryBlock block, boolean r) {
tx(() -> block.setRead(r));
}
diff --git a/Ghidra/Features/DataGraph/Module.manifest b/Ghidra/Features/DataGraph/Module.manifest
new file mode 100644
index 0000000000..5f6a55051e
--- /dev/null
+++ b/Ghidra/Features/DataGraph/Module.manifest
@@ -0,0 +1 @@
+EXCLUDE FROM GHIDRA JAR: true
diff --git a/Ghidra/Features/DataGraph/build.gradle b/Ghidra/Features/DataGraph/build.gradle
new file mode 100644
index 0000000000..1ecb5f3f26
--- /dev/null
+++ b/Ghidra/Features/DataGraph/build.gradle
@@ -0,0 +1,34 @@
+/* ###
+ * 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.
+ */
+apply from: "$rootProject.projectDir/gradle/distributableGhidraModule.gradle"
+apply from: "$rootProject.projectDir/gradle/javaProject.gradle"
+apply from: "$rootProject.projectDir/gradle/helpProject.gradle"
+apply from: "$rootProject.projectDir/gradle/jacocoProject.gradle"
+apply from: "$rootProject.projectDir/gradle/javaTestProject.gradle"
+apply plugin: 'eclipse'
+
+eclipse.project.name = 'Features Data Graph'
+
+
+// Note: this module's name is 'Data Graph'
+dependencies {
+ api project(":Base")
+
+ // These have abstract test classes and stubs needed by this module
+ testImplementation project(path: ':Project', configuration: 'testArtifacts')
+ testImplementation project(path: ':SoftwareModeling', configuration: 'testArtifacts')
+
+}
diff --git a/Ghidra/Features/DataGraph/certification.manifest b/Ghidra/Features/DataGraph/certification.manifest
new file mode 100644
index 0000000000..4a79ed6350
--- /dev/null
+++ b/Ghidra/Features/DataGraph/certification.manifest
@@ -0,0 +1,8 @@
+##VERSION: 2.0
+Module.manifest||GHIDRA||||END|
+data/datagraph.theme.properties||GHIDRA||||END|
+src/main/help/help/TOC_Source.xml||GHIDRA||||END|
+src/main/help/help/topics/DataGraphPlugin/Data_Graph.html||GHIDRA||||END|
+src/main/help/help/topics/DataGraphPlugin/images/CodeVertex.png||GHIDRA||||END|
+src/main/help/help/topics/DataGraphPlugin/images/DataGraph.png||GHIDRA||||END|
+src/main/resources/images/view_detailed_16.png||Nuvola Icons - LGPL 2.1|||Nuvola icon set|END|
diff --git a/Ghidra/Features/DataGraph/data/datagraph.theme.properties b/Ghidra/Features/DataGraph/data/datagraph.theme.properties
new file mode 100644
index 0000000000..6278ada3f1
--- /dev/null
+++ b/Ghidra/Features/DataGraph/data/datagraph.theme.properties
@@ -0,0 +1,4 @@
+[Defaults]
+color.fg.datagraph.value = color.palette.blue
+icon.plugin.datagraph.action.viewer.vertex.format = view_detailed_16.png
+icon.plugin.datagraph.action.viewer.reset = icon.refresh
diff --git a/Ghidra/Features/DataGraph/src/main/help/help/TOC_Source.xml b/Ghidra/Features/DataGraph/src/main/help/help/TOC_Source.xml
new file mode 100644
index 0000000000..ba6629ee26
--- /dev/null
+++ b/Ghidra/Features/DataGraph/src/main/help/help/TOC_Source.xml
@@ -0,0 +1,64 @@
+
+
+
+
+
![]() |
+
++ +The data graph is a graph display that shows data objects in memory. Each data vertex + displays a scrollable view of a data object and its contents.
+ +Initially, a data graph is generated from a specific data program location. The graph + will be populated with one data vertex showing the data for that location. From this original + source vertex, the references to and from this vertex can be explored to add additional + vertices to the graph. In the data vertex display, any data elements that have an outgoing + reference will have an
+ +icon that can be clicked + to quickly explore that reference.
If a reference leads from/to code, a simple code vertex is generated + that simply shows the function and offset of the reference from the function's entry point. + For the purposes of the data graph, code vertices are end points and cannot be explored + further.
+ +The display consists of the Primary View and an optional Satellite View.
+
++ +The primary view shows an initial data object that was used to create the graph. This + data vertex can be used to explore references and pointers. As you explore, new vertices + will be added to the graph. All vertices in the graph can trace a reference relationship + back to the original source data object.
+ ++++
The original source data vertex + has a
icon in its header to indicate it is the original source vertex.
++ +Data Vertices
+ +++Data vertices show information about the data and values they contain. If the vertex + datatype is a primitive, such as an int, the vertex contains only one row that shows its name + and value. If the data is more complex such as a structure or array, the vertex will display + multiple rows showing the name and value of each field in the structure. If the structure + contains other structures or arrays of data, those data items can be expanded in a tree/table + structure showing the names and values of that internal data.
+ +Any elements that are pointers (or have attached outgoing references) will display a +
+ +icon that can be clicked to explore those + references to add new vertices.
Data vertices can be resized by dragging the bottom right corner. Also, the interior column + sizes can be adjusted by hovering the mouse on a column boundary and dragging left or + right.
+ +The header of a vertex contains the name of the label and/or address of the data object. + The header also contains buttons that allow you to perform some common operations on the + vertex.
+ +As long as you are within the interaction threshold, + you may interact with the vertex to expand/collapse sub-data elements and to click on any + pointer references to add vertices to the graph.
+ +Code Vertices
+++ +Generally vertices in the graph show data objects, but a vertex can also represent a + reference from or to code. In the data graph, code vertices are terminal vertices, simply + showing the function name and offset into or out of that function.
+ ++ +
+ ++ + ++ In the image above, the graph is showing two references to the same string.
+Vertex Layout
+++The data graph uses a special layout to attempt to maintain a logical structure as + more vertices are added to the graph. This layout uses the exploration order + to layout the vertices.
+ +Starting with the original data vertex. All vertices that were + added to the graph by following outgoing references are displayed in a column to the right of + the vertex. Within this column, the vertices are ordered by the order they are first referenced + from the source vertex.
+ +Similarly, vertices added to the graph by following incoming references are shown in a + column to the left of the source vertex. Within this column, the vertices are ordered by + address.
+ +Additional layers of vertices can be added by further exploring the child vertices and their + descendants. These additional vertices are ordered in the same way relative to their immediate + source vertex.
+ +Whenever a vertex is removed from the graph, all vertices that were discovered by exploring + from that vertex are also removed.
+ +Vertex Actions
+ +++The following toolbar actions are available on a data vertex.
+ ++
+ + + +- + +
  Expand All - + Expands all expandable sub-data elements recursively contained in the data object. Note + that this action is not available if the data has no sub-data elements.
- + +
 Collapse All + - Collapses all expanded sub-data elements. Note that this action is not available if the + data has no sub-data elements.
- +
 Delete Vertex - Removes this vertex and all vertices + that descend from this vertex.
+
+- Add All Outgoing References - All outgoing references + from this data element or its sub-elements will generate a new vertex in the graph, if + not already present.
+ +- Add All Incoming References - The program will be + searched for any references to this data element or its sub-elents and a new vertex be + created each discovered reference, if not already present.
+ +- Expand Fully - If the mouse is over an + expandable row in data vertex, the vertex and all it's child elements will be fully + expanded.
+ +- Set Original Source - Makes this the original source + root vertex. All other vertices are reorganized and laid out as if they were discovered + by following references from this vertex.See Vertex + Layout.
+ +- Delete Selected Vertices - Deletes the selected + vertices and any descendants vertices (vertices that were discovered via exploring from + that vertex.)
+Selecting Vertices
+ +++ +Left-clicking a vertex will select that vertex. To select multiple vertices, hold down + the Ctrl key while clicking. To deselect + a block, hold the Ctrl key while clicking the block. To clear all selected + blocks, click in an empty area of the primary view. When selected, a block is adorned + with a halo.
+ +You may also select multiple vertices in one action by holding the Ctrl key + while performing a drag operation. Press the Ctrl key and start the drag in an + empty area of the primary view (not over a vertex). This will create a bounding rectangle + on the screen that will select any vertices contained therein when the action is + finished.
+Navigating Vertices
+ +++By default the data graph can be used to navigate the main views of the tool. Clicking + on a vertex or a row within a vertex will generate a goto event for that address, causing + the main tool to navigate to that location. See the actions below to turn off this + behavior.
+ +Also, the data graph can listen for tool location changes and select the appropriate + vertex in the graph if any vertices contain the tool location address. This behavior is + off by default, but can be turn on via a popup action.
+
+Standard Graph Features and Actions +Toolbar Actions
+ ++
+- + +
 Refresh Layout - All manually positioned + vertices will be reset and the graph will relayout to its automated locations.
- + +
 Go To Source Vertex - The original source vertex will be selected + and centered in the graph.
- + +
 Navigate In - If selected, the graph will + listen for tool location events and select the vertex that contains the location address, + is one exists.
- + +
 Navigate Out - If selected, the graph will + generate tool location events when vertices are selected or rows within a vertex are + selected.
- +
 Expanded Format - If selected, + vertices will show more information for each row in the display. In compact mode, a data + row will generally show the field name and its value. In expanded mode, a data row will + generally show the datatype, field name, and its value.
++ +The data graph is a type of Ghidra Visual Graph and has some standard concepts, features + and actions. +
+++
+- Satellite View
+- Panning
+- Zooming
+- Interaction Threshold
+
Provided by: Data Graph Plugin
+