mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 02:39:44 +02:00
GP-787: Refactored Regions,Modules/Sections,Mappings,Threads to use RowWrapped...
This commit is contained in:
parent
84c77bb90c
commit
085daeb39b
17 changed files with 159 additions and 149 deletions
|
@ -18,7 +18,8 @@ package ghidra.app.plugin.core.debug.gui;
|
|||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.event.*;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.function.Function;
|
||||
|
||||
|
@ -1560,11 +1561,11 @@ public interface DebuggerResources {
|
|||
};
|
||||
}
|
||||
|
||||
static <V, R> void setSelectedRows(Set<V> sel, Map<V, R> rowMap, GTable table,
|
||||
static <V, R> void setSelectedRows(Set<V> sel, Function<V, R> rowMapper, GTable table,
|
||||
RowObjectTableModel<R> model, GTableFilterPanel<R> filterPanel) {
|
||||
table.clearSelection();
|
||||
for (V v : sel) {
|
||||
R row = rowMap.get(v);
|
||||
R row = rowMapper.apply(v);
|
||||
if (row == null) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -971,14 +971,12 @@ public class DebuggerBreakpointsProvider extends ComponentProviderAdapter
|
|||
}
|
||||
|
||||
public void setSelectedBreakpoints(Set<LogicalBreakpoint> sel) {
|
||||
DebuggerResources.setSelectedRows(sel, breakpointTableModel.getMap(), breakpointTable,
|
||||
DebuggerResources.setSelectedRows(sel, breakpointTableModel::getRow, breakpointTable,
|
||||
breakpointTableModel, breakpointFilterPanel);
|
||||
}
|
||||
|
||||
public void setSelectedLocations(Set<TraceBreakpoint> sel) {
|
||||
DebuggerResources.setSelectedRows(
|
||||
sel.stream().map(b -> b.getObjectKey()).collect(Collectors.toSet()),
|
||||
locationTableModel.getMap(), locationTable,
|
||||
DebuggerResources.setSelectedRows(sel, locationTableModel::getRow, locationTable,
|
||||
locationTableModel, locationFilterPanel);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,8 +31,9 @@ import com.google.common.collect.Range;
|
|||
import docking.ActionContext;
|
||||
import docking.WindowPosition;
|
||||
import docking.action.*;
|
||||
import docking.widgets.table.*;
|
||||
import docking.widgets.table.CustomToStringCellRenderer;
|
||||
import docking.widgets.table.DefaultEnumeratedColumnTableModel.EnumeratedTableColumn;
|
||||
import docking.widgets.table.RowWrappedEnumeratedColumnTableModel;
|
||||
import ghidra.app.plugin.core.debug.DebuggerPluginPackage;
|
||||
import ghidra.app.plugin.core.debug.gui.DebuggerResources;
|
||||
import ghidra.app.plugin.core.debug.gui.DebuggerResources.AbstractSelectAddressesAction;
|
||||
|
@ -51,6 +52,7 @@ import ghidra.trace.model.Trace.TraceMemoryRegionChangeType;
|
|||
import ghidra.trace.model.TraceDomainObjectListener;
|
||||
import ghidra.trace.model.memory.TraceMemoryManager;
|
||||
import ghidra.trace.model.memory.TraceMemoryRegion;
|
||||
import ghidra.util.database.ObjectKey;
|
||||
import ghidra.util.table.GhidraTable;
|
||||
import ghidra.util.table.GhidraTableFilterPanel;
|
||||
|
||||
|
@ -112,6 +114,16 @@ public class DebuggerRegionsProvider extends ComponentProviderAdapter {
|
|||
}
|
||||
}
|
||||
|
||||
protected static class RegionTableModel
|
||||
extends RowWrappedEnumeratedColumnTableModel< //
|
||||
RegionTableColumns, ObjectKey, RegionRow, TraceMemoryRegion> {
|
||||
|
||||
public RegionTableModel() {
|
||||
super("Regions", RegionTableColumns.class, TraceMemoryRegion::getObjectKey,
|
||||
RegionRow::new);
|
||||
}
|
||||
}
|
||||
|
||||
protected static RegionRow getSelectedRegionRow(ActionContext context) {
|
||||
if (!(context instanceof DebuggerRegionActionContext)) {
|
||||
return null;
|
||||
|
@ -150,26 +162,15 @@ public class DebuggerRegionsProvider extends ComponentProviderAdapter {
|
|||
}
|
||||
|
||||
private void regionAdded(TraceMemoryRegion region) {
|
||||
regionMap.computeIfAbsent(region, r -> {
|
||||
RegionRow rr = new RegionRow(r);
|
||||
regionTableModel.add(rr);
|
||||
return rr;
|
||||
});
|
||||
/**
|
||||
* NOTE: No need to add sections here. A TraceModule is created empty, so when each
|
||||
* section is added, we'll get the call.
|
||||
*/
|
||||
regionTableModel.addItem(region);
|
||||
}
|
||||
|
||||
private void regionChanged(TraceMemoryRegion region) {
|
||||
regionTableModel.notifyUpdated(regionMap.get(region));
|
||||
regionTableModel.updateItem(region);
|
||||
}
|
||||
|
||||
private void regionDeleted(TraceMemoryRegion region) {
|
||||
RegionRow rr = regionMap.remove(region);
|
||||
if (rr != null) {
|
||||
regionTableModel.delete(rr);
|
||||
}
|
||||
regionTableModel.deleteItem(region);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -222,9 +223,7 @@ public class DebuggerRegionsProvider extends ComponentProviderAdapter {
|
|||
|
||||
private final RegionsListener regionsListener = new RegionsListener();
|
||||
|
||||
protected final Map<TraceMemoryRegion, RegionRow> regionMap = new HashMap<>();
|
||||
protected final EnumeratedColumnTableModel<RegionRow> regionTableModel =
|
||||
new DefaultEnumeratedColumnTableModel<>("Regions", RegionTableColumns.class);
|
||||
protected final RegionTableModel regionTableModel = new RegionTableModel();
|
||||
protected GhidraTable regionTable;
|
||||
private GhidraTableFilterPanel<RegionRow> regionFilterPanel;
|
||||
|
||||
|
@ -262,16 +261,13 @@ public class DebuggerRegionsProvider extends ComponentProviderAdapter {
|
|||
}
|
||||
|
||||
private void loadRegions() {
|
||||
regionMap.clear();
|
||||
regionTableModel.clear();
|
||||
|
||||
if (currentTrace == null) {
|
||||
return;
|
||||
}
|
||||
TraceMemoryManager memoryManager = currentTrace.getMemoryManager();
|
||||
for (TraceMemoryRegion region : memoryManager.getAllRegions()) {
|
||||
regionTableModel.add(regionMap.computeIfAbsent(region, RegionRow::new));
|
||||
}
|
||||
regionTableModel.addAllItems(memoryManager.getAllRegions());
|
||||
}
|
||||
|
||||
protected void buildMainPanel() {
|
||||
|
@ -376,8 +372,8 @@ public class DebuggerRegionsProvider extends ComponentProviderAdapter {
|
|||
}
|
||||
|
||||
public void setSelectedRegions(Set<TraceMemoryRegion> sel) {
|
||||
DebuggerResources.setSelectedRows(sel, regionMap, regionTable, regionTableModel,
|
||||
regionFilterPanel);
|
||||
DebuggerResources.setSelectedRows(sel, regionTableModel::getRow, regionTable,
|
||||
regionTableModel, regionFilterPanel);
|
||||
}
|
||||
|
||||
public Collection<RegionRow> getSelectedRows() {
|
||||
|
|
|
@ -64,6 +64,7 @@ import ghidra.trace.model.TraceDomainObjectListener;
|
|||
import ghidra.trace.model.modules.*;
|
||||
import ghidra.util.HelpLocation;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.database.ObjectKey;
|
||||
import ghidra.util.datastruct.CollectionChangeListener;
|
||||
import ghidra.util.table.GhidraTable;
|
||||
import ghidra.util.table.GhidraTableFilterPanel;
|
||||
|
@ -198,6 +199,25 @@ public class DebuggerModulesProvider extends ComponentProviderAdapter {
|
|||
return sections.iterator().next();
|
||||
}
|
||||
|
||||
protected static class ModuleTableModel
|
||||
extends RowWrappedEnumeratedColumnTableModel< //
|
||||
ModuleTableColumns, ObjectKey, ModuleRow, TraceModule> {
|
||||
|
||||
public ModuleTableModel() {
|
||||
super("Modules", ModuleTableColumns.class, TraceModule::getObjectKey, ModuleRow::new);
|
||||
}
|
||||
}
|
||||
|
||||
protected static class SectionTableModel
|
||||
extends RowWrappedEnumeratedColumnTableModel< //
|
||||
SectionTableColumns, ObjectKey, SectionRow, TraceSection> {
|
||||
|
||||
public SectionTableModel() {
|
||||
super("Sections", SectionTableColumns.class, TraceSection::getObjectKey,
|
||||
SectionRow::new);
|
||||
}
|
||||
}
|
||||
|
||||
protected static Set<TraceModule> getSelectedModules(ActionContext context) {
|
||||
if (context instanceof DebuggerModuleActionContext) {
|
||||
DebuggerModuleActionContext ctx = (DebuggerModuleActionContext) context;
|
||||
|
@ -253,54 +273,39 @@ public class DebuggerModulesProvider extends ComponentProviderAdapter {
|
|||
}
|
||||
|
||||
private void moduleAdded(TraceModule module) {
|
||||
moduleMap.computeIfAbsent(module, m -> {
|
||||
ModuleRow mr = new ModuleRow(m);
|
||||
moduleTableModel.add(mr);
|
||||
return mr;
|
||||
});/**
|
||||
moduleTableModel.addItem(module);
|
||||
/**
|
||||
* NOTE: No need to add sections here. A TraceModule is created empty, so when each
|
||||
* section is added, we'll get the call.
|
||||
*/
|
||||
}
|
||||
|
||||
private void moduleChanged(TraceModule module) {
|
||||
moduleTableModel.notifyUpdated(moduleMap.get(module));
|
||||
moduleTableModel.updateItem(module);
|
||||
sectionTableModel.fireTableDataChanged(); // Because module name in section row
|
||||
}
|
||||
|
||||
private void moduleDeleted(TraceModule module) {
|
||||
ModuleRow mr = moduleMap.remove(module);
|
||||
if (mr != null) {
|
||||
moduleTableModel.delete(mr);
|
||||
}
|
||||
moduleTableModel.deleteItem(module);
|
||||
// NOTE: module.getSections() will be empty, now
|
||||
for (Iterator<Entry<TraceSection, SectionRow>> it = sectionMap.entrySet().iterator(); it
|
||||
.hasNext();) {
|
||||
Entry<TraceSection, SectionRow> ent = it.next();
|
||||
if (ent.getKey().getModule() == module) {
|
||||
it.remove();
|
||||
sectionTableModel.delete(ent.getValue());
|
||||
}
|
||||
}
|
||||
sectionTableModel.deleteAllItems(sectionTableModel.getMap()
|
||||
.values()
|
||||
.stream()
|
||||
.filter(r -> r.getModule() == module)
|
||||
.map(r -> r.getSection())
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
private void sectionAdded(TraceSection section) {
|
||||
sectionMap.computeIfAbsent(section, s -> {
|
||||
SectionRow sr = new SectionRow(s);
|
||||
sectionTableModel.add(sr);
|
||||
return sr;
|
||||
});
|
||||
sectionTableModel.addItem(section);
|
||||
}
|
||||
|
||||
private void sectionChanged(TraceSection section) {
|
||||
sectionTableModel.notifyUpdated(sectionMap.get(section));
|
||||
sectionTableModel.updateItem(section);
|
||||
}
|
||||
|
||||
private void sectionDeleted(TraceSection section) {
|
||||
SectionRow sr = sectionMap.remove(section);
|
||||
if (sr != null) {
|
||||
sectionTableModel.delete(sr);
|
||||
}
|
||||
sectionTableModel.deleteItem(section);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -516,15 +521,11 @@ public class DebuggerModulesProvider extends ComponentProviderAdapter {
|
|||
private final RecordersChangedListener recordersChangedListener =
|
||||
new RecordersChangedListener();
|
||||
|
||||
protected final Map<TraceModule, ModuleRow> moduleMap = new HashMap<>();
|
||||
protected final EnumeratedColumnTableModel<ModuleRow> moduleTableModel =
|
||||
new DefaultEnumeratedColumnTableModel<>("Modules", ModuleTableColumns.class);
|
||||
protected final ModuleTableModel moduleTableModel = new ModuleTableModel();
|
||||
protected GhidraTable moduleTable;
|
||||
private GhidraTableFilterPanel<ModuleRow> moduleFilterPanel;
|
||||
|
||||
protected final Map<TraceSection, SectionRow> sectionMap = new HashMap<>();
|
||||
protected final EnumeratedColumnTableModel<SectionRow> sectionTableModel =
|
||||
new DefaultEnumeratedColumnTableModel<>("Sections", SectionTableColumns.class);
|
||||
protected final SectionTableModel sectionTableModel = new SectionTableModel();
|
||||
protected GhidraTable sectionTable;
|
||||
protected GhidraTableFilterPanel<SectionRow> sectionFilterPanel;
|
||||
private final SectionsBySelectedModulesTableFilter filterSectionsBySelectedModules =
|
||||
|
@ -598,22 +599,16 @@ public class DebuggerModulesProvider extends ComponentProviderAdapter {
|
|||
}
|
||||
|
||||
private void loadModules() {
|
||||
moduleMap.clear();
|
||||
moduleTableModel.clear();
|
||||
|
||||
sectionMap.clear();
|
||||
sectionTableModel.clear();
|
||||
|
||||
if (currentTrace == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
TraceModuleManager moduleManager = currentTrace.getModuleManager();
|
||||
for (TraceModule module : moduleManager.getAllModules()) {
|
||||
moduleTableModel.add(moduleMap.computeIfAbsent(module, ModuleRow::new));
|
||||
for (TraceSection section : module.getSections()) {
|
||||
sectionTableModel.add(sectionMap.computeIfAbsent(section, SectionRow::new));
|
||||
}
|
||||
}
|
||||
moduleTableModel.addAllItems(moduleManager.getAllModules());
|
||||
sectionTableModel.addAllItems(moduleManager.getAllSections());
|
||||
}
|
||||
|
||||
protected void buildMainPanel() {
|
||||
|
@ -1092,13 +1087,13 @@ public class DebuggerModulesProvider extends ComponentProviderAdapter {
|
|||
}
|
||||
|
||||
public void setSelectedModules(Set<TraceModule> sel) {
|
||||
DebuggerResources.setSelectedRows(sel, moduleMap, moduleTable, moduleTableModel,
|
||||
moduleFilterPanel);
|
||||
DebuggerResources.setSelectedRows(sel, moduleTableModel::getRow, moduleTable,
|
||||
moduleTableModel, moduleFilterPanel);
|
||||
}
|
||||
|
||||
public void setSelectedSections(Set<TraceSection> sel) {
|
||||
DebuggerResources.setSelectedRows(sel, sectionMap, sectionTable, sectionTableModel,
|
||||
sectionFilterPanel);
|
||||
DebuggerResources.setSelectedRows(sel, sectionTableModel::getRow, sectionTable,
|
||||
sectionTableModel, sectionFilterPanel);
|
||||
}
|
||||
|
||||
private DataTreeDialog getProgramChooserDialog() {
|
||||
|
|
|
@ -19,7 +19,8 @@ import java.awt.BorderLayout;
|
|||
import java.awt.event.MouseEvent;
|
||||
import java.math.BigInteger;
|
||||
import java.net.URL;
|
||||
import java.util.*;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
|
||||
import javax.swing.*;
|
||||
|
@ -54,6 +55,7 @@ import ghidra.trace.model.modules.TraceStaticMappingManager;
|
|||
import ghidra.trace.model.program.TraceProgramView;
|
||||
import ghidra.util.MathUtilities;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.database.ObjectKey;
|
||||
import ghidra.util.database.UndoableTransaction;
|
||||
import ghidra.util.table.GhidraTableFilterPanel;
|
||||
|
||||
|
@ -95,6 +97,16 @@ public class DebuggerStaticMappingProvider extends ComponentProviderAdapter
|
|||
}
|
||||
}
|
||||
|
||||
protected static class MappingTableModel
|
||||
extends RowWrappedEnumeratedColumnTableModel< //
|
||||
StaticMappingTableColumns, ObjectKey, StaticMappingRow, TraceStaticMapping> {
|
||||
|
||||
public MappingTableModel() {
|
||||
super("Mappings", StaticMappingTableColumns.class, TraceStaticMapping::getObjectKey,
|
||||
StaticMappingRow::new);
|
||||
}
|
||||
}
|
||||
|
||||
protected class ListenerForStaticMappingDisplay extends TraceDomainObjectListener {
|
||||
public ListenerForStaticMappingDisplay() {
|
||||
listenForUntyped(DomainObject.DO_OBJECT_RESTORED, e -> objectRestored());
|
||||
|
@ -107,11 +119,11 @@ public class DebuggerStaticMappingProvider extends ComponentProviderAdapter
|
|||
}
|
||||
|
||||
private void staticMappingAdded(TraceStaticMapping mapping) {
|
||||
addMapping(mapping);
|
||||
mappingTableModel.addItem(mapping);
|
||||
}
|
||||
|
||||
private void staticMappingDeleted(TraceStaticMapping mapping) {
|
||||
mappingTableModel.deleteWith(rec -> rec.getMapping() == mapping);
|
||||
mappingTableModel.deleteItem(mapping);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -135,8 +147,7 @@ public class DebuggerStaticMappingProvider extends ComponentProviderAdapter
|
|||
|
||||
private ListenerForStaticMappingDisplay listener = new ListenerForStaticMappingDisplay();
|
||||
|
||||
protected final EnumeratedColumnTableModel<StaticMappingRow> mappingTableModel =
|
||||
new DefaultEnumeratedColumnTableModel<>("Mappings", StaticMappingTableColumns.class);
|
||||
protected final MappingTableModel mappingTableModel = new MappingTableModel();
|
||||
|
||||
private JPanel mainPanel = new JPanel(new BorderLayout());
|
||||
protected GTable mappingTable;
|
||||
|
@ -187,23 +198,13 @@ public class DebuggerStaticMappingProvider extends ComponentProviderAdapter
|
|||
return myActionContext;
|
||||
}
|
||||
|
||||
private void addMapping(TraceStaticMapping mapping) {
|
||||
mappingTableModel.add(new StaticMappingRow(mapping));
|
||||
}
|
||||
|
||||
private void addMappings(Collection<? extends TraceStaticMapping> entries) {
|
||||
for (TraceStaticMapping ent : entries) {
|
||||
addMapping(ent);
|
||||
}
|
||||
}
|
||||
|
||||
private void loadMappings() {
|
||||
mappingTableModel.clear();
|
||||
if (currentTrace == null) {
|
||||
return;
|
||||
}
|
||||
TraceStaticMappingManager manager = currentTrace.getStaticMappingManager();
|
||||
addMappings(manager.getAllEntries());
|
||||
mappingTableModel.addAllItems(manager.getAllEntries());
|
||||
}
|
||||
|
||||
protected void buildMainPanel() {
|
||||
|
|
|
@ -214,11 +214,6 @@ public class ObjectEnumeratedColumnTableModel<C extends ObjectsEnumeratedTableCo
|
|||
fireTableRowsInserted(startIndex, endIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RowIterator<R> rowIterator() {
|
||||
return new TableRowIterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyUpdated(R row) {
|
||||
int rowIndex = modelData.indexOf(row);
|
||||
|
|
|
@ -30,7 +30,8 @@ import docking.action.*;
|
|||
import docking.widgets.EventTrigger;
|
||||
import docking.widgets.HorizontalTabPanel;
|
||||
import docking.widgets.HorizontalTabPanel.TabListCellRenderer;
|
||||
import docking.widgets.table.*;
|
||||
import docking.widgets.table.GTable;
|
||||
import docking.widgets.table.RowWrappedEnumeratedColumnTableModel;
|
||||
import docking.widgets.timeline.TimelineListener;
|
||||
import ghidra.app.plugin.core.debug.DebuggerCoordinates;
|
||||
import ghidra.app.plugin.core.debug.DebuggerPluginPackage;
|
||||
|
@ -55,6 +56,7 @@ import ghidra.trace.model.thread.TraceThreadManager;
|
|||
import ghidra.trace.model.time.TraceSchedule;
|
||||
import ghidra.trace.model.time.TraceSnapshot;
|
||||
import ghidra.util.Swing;
|
||||
import ghidra.util.database.ObjectKey;
|
||||
import ghidra.util.datastruct.CollectionChangeListener;
|
||||
import ghidra.util.table.GhidraTable;
|
||||
import ghidra.util.table.GhidraTableFilterPanel;
|
||||
|
@ -249,6 +251,16 @@ public class DebuggerThreadsProvider extends ComponentProviderAdapter {
|
|||
}
|
||||
}
|
||||
|
||||
protected static class ThreadTableModel
|
||||
extends RowWrappedEnumeratedColumnTableModel< //
|
||||
ThreadTableColumns, ObjectKey, ThreadRow, TraceThread> {
|
||||
|
||||
public ThreadTableModel(DebuggerThreadsProvider provider) {
|
||||
super("Threads", ThreadTableColumns.class, TraceThread::getObjectKey,
|
||||
t -> new ThreadRow(provider.modelService, t));
|
||||
}
|
||||
}
|
||||
|
||||
private class ThreadsListener extends TraceDomainObjectListener {
|
||||
public ThreadsListener() {
|
||||
listenForUntyped(DomainObject.DO_OBJECT_RESTORED, e -> objectRestored());
|
||||
|
@ -267,23 +279,15 @@ public class DebuggerThreadsProvider extends ComponentProviderAdapter {
|
|||
}
|
||||
|
||||
private void threadAdded(TraceThread thread) {
|
||||
threadMap.computeIfAbsent(thread, t -> {
|
||||
ThreadRow tr = new ThreadRow(modelService, t);
|
||||
threadTableModel.add(tr);
|
||||
doSetThread(thread);
|
||||
return tr;
|
||||
});
|
||||
threadTableModel.addItem(thread);
|
||||
}
|
||||
|
||||
private void threadChanged(TraceThread thread) {
|
||||
threadTableModel.notifyUpdatedWith(row -> row.getThread() == thread);
|
||||
threadTableModel.updateItem(thread);
|
||||
}
|
||||
|
||||
private void threadDeleted(TraceThread thread) {
|
||||
ThreadRow tr = threadMap.remove(thread);
|
||||
if (tr != null) {
|
||||
threadTableModel.delete(tr);
|
||||
}
|
||||
threadTableModel.deleteItem(thread);
|
||||
}
|
||||
|
||||
private void snapAdded(TraceSnapshot snapshot) {
|
||||
|
@ -333,9 +337,7 @@ public class DebuggerThreadsProvider extends ComponentProviderAdapter {
|
|||
private final CollectionChangeListener<TraceRecorder> recordersListener =
|
||||
new RecordersChangeListener();
|
||||
|
||||
protected final Map<TraceThread, ThreadRow> threadMap = new HashMap<>();
|
||||
protected final EnumeratedColumnTableModel<ThreadRow> threadTableModel =
|
||||
new DefaultEnumeratedColumnTableModel<>("Threads", ThreadTableColumns.class);
|
||||
protected final ThreadTableModel threadTableModel = new ThreadTableModel(this);
|
||||
|
||||
private JPanel mainPanel;
|
||||
private JSplitPane splitPane;
|
||||
|
@ -453,7 +455,7 @@ public class DebuggerThreadsProvider extends ComponentProviderAdapter {
|
|||
}
|
||||
try (Suppression supp = cbCoordinateActivation.suppress(null)) {
|
||||
if (thread != null) {
|
||||
threadFilterPanel.setSelectedItem(threadMap.get(thread));
|
||||
threadFilterPanel.setSelectedItem(threadTableModel.getRow(thread));
|
||||
}
|
||||
else {
|
||||
threadTable.clearSelection();
|
||||
|
@ -495,20 +497,13 @@ public class DebuggerThreadsProvider extends ComponentProviderAdapter {
|
|||
}
|
||||
|
||||
protected void loadThreads() {
|
||||
threadMap.clear();
|
||||
threadTableModel.clear();
|
||||
Trace curTrace = current.getTrace();
|
||||
if (curTrace == null) {
|
||||
return;
|
||||
}
|
||||
TraceThreadManager manager = curTrace.getThreadManager();
|
||||
for (TraceThread thread : manager.getAllThreads()) {
|
||||
threadMap.computeIfAbsent(thread, t -> {
|
||||
ThreadRow tr = new ThreadRow(modelService, t);
|
||||
threadTableModel.add(tr);
|
||||
return tr;
|
||||
});
|
||||
}
|
||||
threadTableModel.addAllItems(manager.getAllThreads());
|
||||
updateTimelineMax();
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
/* ###
|
||||
* 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.trace.model;
|
||||
|
||||
import ghidra.util.database.ObjectKey;
|
||||
|
||||
public interface TraceObject {
|
||||
/**
|
||||
* Get an opaque unique id for this object, whose hash is immutable
|
||||
*
|
||||
* @return the opaque object id
|
||||
*/
|
||||
ObjectKey getObjectKey();
|
||||
}
|
|
@ -23,29 +23,22 @@ import com.google.common.collect.Range;
|
|||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressRange;
|
||||
import ghidra.trace.model.Trace;
|
||||
import ghidra.trace.model.TraceObject;
|
||||
import ghidra.trace.model.thread.TraceThread;
|
||||
import ghidra.util.database.ObjectKey;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
/**
|
||||
* A breakpoint in a trace
|
||||
*/
|
||||
public interface TraceBreakpoint {
|
||||
public interface TraceBreakpoint extends TraceObject {
|
||||
|
||||
/**
|
||||
* Get the trace containning this breakpoint
|
||||
* Get the trace containing this breakpoint
|
||||
*
|
||||
* @return the trace
|
||||
*/
|
||||
Trace getTrace();
|
||||
|
||||
/**
|
||||
* Get an opaque unique id for this object, whose hash is immutable
|
||||
*
|
||||
* @return the opaque object id
|
||||
*/
|
||||
ObjectKey getObjectKey();
|
||||
|
||||
/**
|
||||
* Get the "full name" of this breakpoint
|
||||
*
|
||||
|
|
|
@ -21,12 +21,13 @@ import com.google.common.collect.Range;
|
|||
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.trace.model.Trace;
|
||||
import ghidra.trace.model.TraceObject;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
/**
|
||||
* A region of mapped target memory in a trace
|
||||
*/
|
||||
public interface TraceMemoryRegion {
|
||||
public interface TraceMemoryRegion extends TraceObject {
|
||||
|
||||
/**
|
||||
* Get the trace containing this region
|
||||
|
@ -105,7 +106,8 @@ public interface TraceMemoryRegion {
|
|||
/**
|
||||
* @see #setLifespan(Range)
|
||||
*
|
||||
* @param destructionSnap the destruction snap, or {@link Long#MAX_VALUE} for "to the end of time"
|
||||
* @param destructionSnap the destruction snap, or {@link Long#MAX_VALUE} for "to the end of
|
||||
* time"
|
||||
*/
|
||||
void setDestructionSnap(long destructionSnap)
|
||||
throws DuplicateNameException, TraceOverlappedRegionException;
|
||||
|
|
|
@ -21,6 +21,7 @@ import com.google.common.collect.Range;
|
|||
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.trace.model.Trace;
|
||||
import ghidra.trace.model.TraceObject;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
/**
|
||||
|
@ -29,7 +30,7 @@ import ghidra.util.exception.DuplicateNameException;
|
|||
* <p>
|
||||
* This also serves as a namespace for storing the module's sections.
|
||||
*/
|
||||
public interface TraceModule {
|
||||
public interface TraceModule extends TraceObject {
|
||||
|
||||
/**
|
||||
* Get the trace containing this module
|
||||
|
|
|
@ -18,12 +18,13 @@ package ghidra.trace.model.modules;
|
|||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressRange;
|
||||
import ghidra.trace.model.Trace;
|
||||
import ghidra.trace.model.TraceObject;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
/**
|
||||
* A section of a module in a trace
|
||||
*/
|
||||
public interface TraceSection {
|
||||
public interface TraceSection extends TraceObject {
|
||||
|
||||
/**
|
||||
* Get the trace containing this section
|
||||
|
|
|
@ -23,11 +23,12 @@ import ghidra.program.model.address.Address;
|
|||
import ghidra.program.model.address.AddressRange;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.trace.model.Trace;
|
||||
import ghidra.trace.model.TraceObject;
|
||||
|
||||
/**
|
||||
* A mapped range from this trace to a Ghidra {@link Program}
|
||||
*/
|
||||
public interface TraceStaticMapping {
|
||||
public interface TraceStaticMapping extends TraceObject {
|
||||
|
||||
/**
|
||||
* Get the "from" trace, i.e., the trace containing this mapping
|
||||
|
|
|
@ -21,12 +21,13 @@ import com.google.common.collect.Range;
|
|||
|
||||
import ghidra.program.model.lang.Register;
|
||||
import ghidra.trace.model.Trace;
|
||||
import ghidra.trace.model.TraceObject;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
/**
|
||||
* A thread in a trace
|
||||
*/
|
||||
public interface TraceThread {
|
||||
public interface TraceThread extends TraceObject {
|
||||
|
||||
/**
|
||||
* Get the trace containing this thread
|
||||
|
|
|
@ -213,11 +213,6 @@ public class DefaultEnumeratedColumnTableModel<C extends Enum<C> & EnumeratedTab
|
|||
fireTableRowsInserted(startIndex, endIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RowIterator<R> rowIterator() {
|
||||
return new TableRowIterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyUpdated(R row) {
|
||||
int rowIndex = modelData.indexOf(row);
|
||||
|
|
|
@ -27,8 +27,6 @@ public interface EnumeratedColumnTableModel<R> extends RowObjectTableModel<R> {
|
|||
|
||||
void addAll(Collection<R> c);
|
||||
|
||||
ListIterator<R> rowIterator();
|
||||
|
||||
void notifyUpdated(R row);
|
||||
|
||||
List<R> notifyUpdatedWith(Predicate<R> predicate);
|
||||
|
|
|
@ -55,6 +55,10 @@ public class RowWrappedEnumeratedColumnTableModel<C extends Enum<C> & Enumerated
|
|||
return c.stream().map(this::rowFor).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public synchronized R getRow(T t) {
|
||||
return map.get(keyFunc.apply(t));
|
||||
}
|
||||
|
||||
public void addItem(T t) {
|
||||
add(rowFor(t));
|
||||
}
|
||||
|
@ -83,4 +87,10 @@ public class RowWrappedEnumeratedColumnTableModel<C extends Enum<C> & Enumerated
|
|||
public synchronized Map<K, R> getMap() {
|
||||
return Map.copyOf(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void clear() {
|
||||
map.clear();
|
||||
super.clear();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue