diff --git a/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerModulesPlugin/images/DebuggerModuleMapProposalDialog.png b/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerModulesPlugin/images/DebuggerModuleMapProposalDialog.png index 5b9873de52..66a259c156 100644 Binary files a/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerModulesPlugin/images/DebuggerModuleMapProposalDialog.png and b/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerModulesPlugin/images/DebuggerModuleMapProposalDialog.png differ diff --git a/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerModulesPlugin/images/DebuggerSectionMapProposalDialog.png b/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerModulesPlugin/images/DebuggerSectionMapProposalDialog.png index 831ea6d4a1..da54d2e0cb 100644 Binary files a/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerModulesPlugin/images/DebuggerSectionMapProposalDialog.png and b/Ghidra/Debug/Debugger/src/main/help/help/topics/DebuggerModulesPlugin/images/DebuggerSectionMapProposalDialog.png differ diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerModuleMapProposalDialog.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerModuleMapProposalDialog.java index 6b201f6226..5a59e66f05 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerModuleMapProposalDialog.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerModuleMapProposalDialog.java @@ -15,6 +15,7 @@ */ package ghidra.app.plugin.core.debug.gui.modules; +import java.util.List; import java.util.function.BiConsumer; import java.util.function.Function; @@ -34,18 +35,17 @@ import ghidra.util.Swing; public class DebuggerModuleMapProposalDialog extends AbstractDebuggerMapProposalDialog { - static final String BLANK = ""; static final int BUTTON_SIZE = 32; protected enum ModuleMapTableColumns implements EnumeratedTableColumn { - REMOVE("Remove", String.class, e -> BLANK, (e, v) -> nop()), + REMOVE("Remove", String.class, e -> "Remove Proposed Entry", (e, v) -> nop()), MODULE_NAME("Module", String.class, e -> e.getModule().getName()), DYNAMIC_BASE("Dynamic Base", Address.class, e -> e.getModule().getBase()), + CHOOSE("Choose", String.class, e -> "Choose Program", (e, v) -> nop()), PROGRAM_NAME("Program", String.class, e -> e.getProgram().getName()), STATIC_BASE("Static Base", Address.class, e -> e.getProgram().getImageBase()), - SIZE("Size", Long.class, e -> e.getModuleRange().getLength()), - CHOOSE("Choose", String.class, e -> BLANK, (e, v) -> nop()); + SIZE("Size", Long.class, e -> e.getModuleRange().getLength()); private final String header; private final Class cls; @@ -94,6 +94,19 @@ public class DebuggerModuleMapProposalDialog } } + protected static class ModuleMapPropsalTableModel extends + DefaultEnumeratedColumnTableModel { + + public ModuleMapPropsalTableModel() { + super("Module Map", ModuleMapTableColumns.class); + } + + @Override + public List defaultSortOrder() { + return List.of(ModuleMapTableColumns.MODULE_NAME); + } + } + private final DebuggerModulesProvider provider; protected DebuggerModuleMapProposalDialog(DebuggerModulesProvider provider) { @@ -102,8 +115,8 @@ public class DebuggerModuleMapProposalDialog } @Override - protected EnumeratedColumnTableModel createTableModel() { - return new DefaultEnumeratedColumnTableModel<>("Module Map", ModuleMapTableColumns.class); + protected ModuleMapPropsalTableModel createTableModel() { + return new ModuleMapPropsalTableModel(); } @Override @@ -117,9 +130,19 @@ public class DebuggerModuleMapProposalDialog CellEditorUtils.installButton(table, filterPanel, removeCol, DebuggerResources.ICON_DELETE, BUTTON_SIZE, this::removeEntry); + TableColumn dynBaseCol = + columnModel.getColumn(ModuleMapTableColumns.DYNAMIC_BASE.ordinal()); + dynBaseCol.setCellRenderer(CustomToStringCellRenderer.MONO_OBJECT); + TableColumn chooseCol = columnModel.getColumn(ModuleMapTableColumns.CHOOSE.ordinal()); CellEditorUtils.installButton(table, filterPanel, chooseCol, DebuggerResources.ICON_PROGRAM, BUTTON_SIZE, this::chooseAndSetProgram); + + TableColumn stBaseCol = columnModel.getColumn(ModuleMapTableColumns.STATIC_BASE.ordinal()); + stBaseCol.setCellRenderer(CustomToStringCellRenderer.MONO_OBJECT); + + TableColumn sizeCol = columnModel.getColumn(ModuleMapTableColumns.SIZE.ordinal()); + sizeCol.setCellRenderer(CustomToStringCellRenderer.MONO_ULONG_HEX); } private void chooseAndSetProgram(ModuleMapEntry entry) { diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerModulesProvider.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerModulesProvider.java index b463b4c270..6688d3c01d 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerModulesProvider.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerModulesProvider.java @@ -972,12 +972,19 @@ public class DebuggerModulesProvider extends ComponentProviderAdapter { } protected void promptModuleProposal(Collection proposal) { + if (proposal.isEmpty()) { + Msg.showInfo(this, getComponent(), "Map Modules", + "Could not formulate a proposal for any selected module." + + " You may need to import and/or open the destination images first."); + return; + } Collection adjusted = moduleProposalDialog.adjustCollection(getTool(), proposal); - if (adjusted != null && staticMappingService != null) { - tool.executeBackgroundCommand( - new MapModulesBackgroundCommand(staticMappingService, adjusted), currentTrace); + if (adjusted == null || staticMappingService == null) { + return; } + tool.executeBackgroundCommand( + new MapModulesBackgroundCommand(staticMappingService, adjusted), currentTrace); } protected void mapModules(Set modules) { @@ -1004,12 +1011,19 @@ public class DebuggerModulesProvider extends ComponentProviderAdapter { } protected void promptSectionProposal(Collection proposal) { + if (proposal.isEmpty()) { + Msg.showInfo(this, getComponent(), "Map Sections", + "Could not formulate a proposal for any selected section." + + " You may need to import and/or open the destination images first."); + return; + } Collection adjusted = sectionProposalDialog.adjustCollection(getTool(), proposal); - if (adjusted != null && staticMappingService != null) { - tool.executeBackgroundCommand( - new MapSectionsBackgroundCommand(staticMappingService, adjusted), currentTrace); + if (adjusted == null || staticMappingService == null) { + return; } + tool.executeBackgroundCommand( + new MapSectionsBackgroundCommand(staticMappingService, adjusted), currentTrace); } protected void mapSections(Set sections) { diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerSectionMapProposalDialog.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerSectionMapProposalDialog.java index 04ee111009..717823c458 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerSectionMapProposalDialog.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerSectionMapProposalDialog.java @@ -15,6 +15,7 @@ */ package ghidra.app.plugin.core.debug.gui.modules; +import java.util.List; import java.util.Map; import java.util.function.BiConsumer; import java.util.function.Function; @@ -35,20 +36,19 @@ import ghidra.util.Swing; public class DebuggerSectionMapProposalDialog extends AbstractDebuggerMapProposalDialog { - static final String BLANK = ""; static final int BUTTON_SIZE = 32; protected enum SectionMapTableColumns implements EnumeratedTableColumn { - REMOVE("Remove", String.class, e -> BLANK, (e, v) -> nop()), + REMOVE("Remove", String.class, e -> "Remove Proposed Entry", (e, v) -> nop()), MODULE_NAME("Module", String.class, e -> e.getModule().getName()), SECTION_NAME("Section", String.class, e -> e.getSection().getName()), DYNAMIC_BASE("Dynamic Base", Address.class, e -> e.getSection().getStart()), + CHOOSE("Choose", String.class, e -> "Choose Block", (e, s) -> nop()), PROGRAM_NAME("Program", String.class, e -> e.getProgram().getName()), BLOCK_NAME("Block", String.class, e -> e.getBlock().getName()), STATIC_BASE("Static Base", Address.class, e -> e.getBlock().getStart()), - SIZE("Size", Long.class, e -> e.getLength()), - CHOOSE("Choose", String.class, e -> BLANK, (e, s) -> nop()); + SIZE("Size", Long.class, e -> e.getLength()); private final String header; private final Class cls; @@ -98,6 +98,19 @@ public class DebuggerSectionMapProposalDialog } } + protected static class SectionMapPropsalTableModel extends + DefaultEnumeratedColumnTableModel { + + public SectionMapPropsalTableModel() { + super("Section Map", SectionMapTableColumns.class); + } + + @Override + public List defaultSortOrder() { + return List.of(SectionMapTableColumns.MODULE_NAME, SectionMapTableColumns.SECTION_NAME); + } + } + private final DebuggerModulesProvider provider; public DebuggerSectionMapProposalDialog(DebuggerModulesProvider provider) { @@ -106,8 +119,8 @@ public class DebuggerSectionMapProposalDialog } @Override - protected EnumeratedColumnTableModel createTableModel() { - return new DefaultEnumeratedColumnTableModel<>("Section Map", SectionMapTableColumns.class); + protected SectionMapPropsalTableModel createTableModel() { + return new SectionMapPropsalTableModel(); } @Override @@ -121,9 +134,19 @@ public class DebuggerSectionMapProposalDialog CellEditorUtils.installButton(table, filterPanel, removeCol, DebuggerResources.ICON_DELETE, BUTTON_SIZE, this::removeEntry); + TableColumn dynBaseCol = + columnModel.getColumn(SectionMapTableColumns.DYNAMIC_BASE.ordinal()); + dynBaseCol.setCellRenderer(CustomToStringCellRenderer.MONO_OBJECT); + TableColumn chooseCol = columnModel.getColumn(SectionMapTableColumns.CHOOSE.ordinal()); CellEditorUtils.installButton(table, filterPanel, chooseCol, DebuggerResources.ICON_PROGRAM, BUTTON_SIZE, this::chooseAndSetBlock); + + TableColumn stBaseCol = columnModel.getColumn(SectionMapTableColumns.STATIC_BASE.ordinal()); + stBaseCol.setCellRenderer(CustomToStringCellRenderer.MONO_OBJECT); + + TableColumn sizeCol = columnModel.getColumn(SectionMapTableColumns.SIZE.ordinal()); + sizeCol.setCellRenderer(CustomToStringCellRenderer.MONO_ULONG_HEX); } private void chooseAndSetBlock(SectionMapEntry entry) { diff --git a/Ghidra/Debug/ProposedUtils/src/main/java/docking/widgets/table/IconButtonTableCellEditor.java b/Ghidra/Debug/ProposedUtils/src/main/java/docking/widgets/table/IconButtonTableCellEditor.java index 1ddcd6de77..983f753c6e 100644 --- a/Ghidra/Debug/ProposedUtils/src/main/java/docking/widgets/table/IconButtonTableCellEditor.java +++ b/Ghidra/Debug/ProposedUtils/src/main/java/docking/widgets/table/IconButtonTableCellEditor.java @@ -51,6 +51,7 @@ public class IconButtonTableCellEditor extends AbstractCellEditor public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { this.row = filterPanel.getRowObject(row); + button.setToolTipText(value.toString()); return button; } diff --git a/Ghidra/Debug/ProposedUtils/src/main/java/docking/widgets/table/IconButtonTableCellRenderer.java b/Ghidra/Debug/ProposedUtils/src/main/java/docking/widgets/table/IconButtonTableCellRenderer.java index bba951ea83..d471463b68 100644 --- a/Ghidra/Debug/ProposedUtils/src/main/java/docking/widgets/table/IconButtonTableCellRenderer.java +++ b/Ghidra/Debug/ProposedUtils/src/main/java/docking/widgets/table/IconButtonTableCellRenderer.java @@ -15,27 +15,31 @@ */ package docking.widgets.table; -import java.awt.Component; -import java.awt.Dimension; +import java.awt.*; -import javax.swing.Icon; -import javax.swing.JButton; +import javax.swing.*; import ghidra.docking.settings.Settings; import ghidra.util.table.column.AbstractGhidraColumnRenderer; public class IconButtonTableCellRenderer extends AbstractGhidraColumnRenderer { + protected final JPanel panel = new JPanel(); protected final JButton button = new JButton(""); public IconButtonTableCellRenderer(Icon icon, int buttonSize) { button.setIcon(icon); button.setMinimumSize(new Dimension(buttonSize, buttonSize)); + panel.setMinimumSize(new Dimension(buttonSize, buttonSize)); + panel.setLayout(new BorderLayout()); + panel.add(button); } @Override public Component getTableCellRendererComponent(GTableCellRenderingData data) { - return button; + super.getTableCellRendererComponent(data); // Waste, but sets background + panel.setBackground(getBackground()); + return panel; } @Override