From 779ef887e0fd44f36bb72b8bb0a08d622864065f Mon Sep 17 00:00:00 2001 From: dragonmacher <48328597+dragonmacher@users.noreply.github.com> Date: Mon, 2 Dec 2024 19:32:45 -0500 Subject: [PATCH] GP-5157 - Listing Colors - Combined color usage for functions so that they are displayed the same in different parts of the Listing --- .../functionwindow/FunctionTableModel.java | 47 +++++- .../core/references/InstructionPanel.java | 5 +- .../plugin/core/symboltree/SymbolGTree.java | 9 +- .../core/symboltree/SymbolTreeProvider.java | 1 - .../actions/CreateSymbolTableAction.java | 5 +- .../core/symtable/ReferenceProvider.java | 4 +- .../plugin/core/symtable/SymbolProvider.java | 4 +- .../plugin/core/symtable/SymbolRenderer.java | 81 +-------- .../core/symtable/SymbolTablePlugin.java | 6 +- .../java/ghidra/app/util/SymbolInspector.java | 158 +++++++++++++----- .../field/FunctionSignatureFieldFactory.java | 38 ++--- .../util/viewer/field/LabelFieldFactory.java | 5 +- .../util/viewer/field/OperandFieldHelper.java | 41 ++--- .../app/util/viewer/options/OptionsGui.java | 5 +- .../markuptable/VTMarkupItemsTableModel.java | 6 +- .../gui/util/AbstractVTMatchTableModel.java | 8 +- .../feature/vt/gui/util/VTSymbolRenderer.java | 5 +- .../program/model/symbol/ExternalManager.java | 10 +- 18 files changed, 224 insertions(+), 214 deletions(-) diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/functionwindow/FunctionTableModel.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/functionwindow/FunctionTableModel.java index 71ccbf1dbc..e1c3e52a39 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/functionwindow/FunctionTableModel.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/functionwindow/FunctionTableModel.java @@ -4,9 +4,9 @@ * 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. @@ -15,17 +15,23 @@ */ package ghidra.app.plugin.core.functionwindow; -import docking.widgets.table.DiscoverableTableUtils; -import docking.widgets.table.TableColumnDescriptor; +import java.awt.Color; +import java.awt.Component; + +import docking.widgets.table.*; +import ghidra.app.util.SymbolInspector; import ghidra.docking.settings.Settings; import ghidra.framework.plugintool.PluginTool; import ghidra.framework.plugintool.ServiceProvider; import ghidra.program.model.address.Address; import ghidra.program.model.listing.*; +import ghidra.program.model.symbol.Symbol; import ghidra.util.LongIterator; import ghidra.util.datastruct.Accumulator; import ghidra.util.exception.CancelledException; import ghidra.util.table.AddressBasedTableModel; +import ghidra.util.table.column.AbstractGhidraColumnRenderer; +import ghidra.util.table.column.GColumnRenderer; import ghidra.util.table.field.*; import ghidra.util.task.TaskMonitor; @@ -180,6 +186,9 @@ public class FunctionTableModel extends AddressBasedTableModel { + private GColumnRenderer renderer = new FunctionNameRenderer(); + private SymbolInspector inspector = new SymbolInspector(serviceProvider, null); + @Override public String getColumnName() { return "Name"; @@ -196,5 +205,35 @@ public class FunctionTableModel extends AddressBasedTableModel getColumnRenderer() { + return renderer; + } + + // A renderer to paint function name colors using the SymbolInspector + private class FunctionNameRenderer extends AbstractGhidraColumnRenderer { + + @Override + public Component getTableCellRendererComponent(GTableCellRenderingData data) { + Component cellRenderer = super.getTableCellRendererComponent(data); + setBold(); + if (data.isSelected()) { + return cellRenderer; // just let the default foreground color through + } + + FunctionRowObject rowObject = (FunctionRowObject) data.getRowObject(); + Function function = rowObject.getFunction(); + Symbol symbol = function.getSymbol(); + Color color = inspector.getColor(symbol); + cellRenderer.setForeground(color); + return cellRenderer; + } + + @Override + public String getFilterString(String t, Settings settings) { + return t; + } + + } } } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/references/InstructionPanel.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/references/InstructionPanel.java index e9c56d680a..90f45316a1 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/references/InstructionPanel.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/references/InstructionPanel.java @@ -4,9 +4,9 @@ * 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. @@ -353,7 +353,6 @@ class InstructionPanel extends JPanel implements ChangeListener { SymbolTable st = program.getSymbolTable(); Symbol sym = st.getSymbol(ref); if (sym != null) { - symbolInspector.setProgram(program); return symbolInspector.getColor(sym); } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/symboltree/SymbolGTree.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/symboltree/SymbolGTree.java index 6ae4991678..1fd7de32e5 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/symboltree/SymbolGTree.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/symboltree/SymbolGTree.java @@ -4,9 +4,9 @@ * 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. @@ -27,7 +27,6 @@ import generic.theme.GIcon; import ghidra.app.plugin.core.symboltree.nodes.SymbolCategoryNode; import ghidra.app.plugin.core.symboltree.nodes.SymbolNode; import ghidra.app.util.SymbolInspector; -import ghidra.program.model.listing.Program; import ghidra.program.model.symbol.Symbol; import resources.ResourceManager; @@ -120,10 +119,6 @@ public class SymbolGTree extends GTree { } } - public void setProgram(Program program) { - symbolInspector.setProgram(program); - } - @Override public void dispose() { super.dispose(); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/symboltree/SymbolTreeProvider.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/symboltree/SymbolTreeProvider.java index d5be3c4935..734c8e86ac 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/symboltree/SymbolTreeProvider.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/symboltree/SymbolTreeProvider.java @@ -151,7 +151,6 @@ public class SymbolTreeProvider extends ComponentProviderAdapter { private SymbolGTree createTree(SymbolTreeRootNode rootNode) { if (tree != null) { GTreeNode oldRootNode = tree.getModelRoot(); - tree.setProgram(rootNode.getProgram()); tree.setRootNode(rootNode); oldRootNode.removeAll();// assist in cleanup a bit diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/symboltree/actions/CreateSymbolTableAction.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/symboltree/actions/CreateSymbolTableAction.java index 029d32838a..d3f8b3fd68 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/symboltree/actions/CreateSymbolTableAction.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/symboltree/actions/CreateSymbolTableAction.java @@ -4,9 +4,9 @@ * 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. @@ -127,7 +127,6 @@ public class CreateSymbolTableAction extends ProgramSymbolContextAction { new TransientSymbolTableDnDAdapter(table, model); SymbolInspector symbolInspector = new SymbolInspector(tool, table); - symbolInspector.setProgram(program); SymbolRenderer renderer = model.getSymbolRenderer(); renderer.setSymbolInspector(symbolInspector); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/symtable/ReferenceProvider.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/symtable/ReferenceProvider.java index e057207898..b1def0c713 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/symtable/ReferenceProvider.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/symtable/ReferenceProvider.java @@ -4,9 +4,9 @@ * 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. diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/symtable/SymbolProvider.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/symtable/SymbolProvider.java index 9e877a0be4..2a9ed2271e 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/symtable/SymbolProvider.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/symtable/SymbolProvider.java @@ -4,9 +4,9 @@ * 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. diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/symtable/SymbolRenderer.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/symtable/SymbolRenderer.java index 1bf76c16c1..d3c7f33a12 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/symtable/SymbolRenderer.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/symtable/SymbolRenderer.java @@ -4,9 +4,9 @@ * 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. @@ -19,15 +19,8 @@ import java.awt.Color; import java.awt.Component; import docking.widgets.table.GTableCellRenderingData; -import generic.theme.GThemeDefaults.Colors; import ghidra.app.util.SymbolInspector; -import ghidra.program.model.address.Address; -import ghidra.program.model.lang.Register; -import ghidra.program.model.listing.Program; -import ghidra.program.model.listing.Variable; import ghidra.program.model.symbol.Symbol; -import ghidra.program.util.ProgramLocation; -import ghidra.program.util.VariableNameFieldLocation; import ghidra.util.table.GhidraTableCellRenderer; public class SymbolRenderer extends GhidraTableCellRenderer { @@ -44,74 +37,18 @@ public class SymbolRenderer extends GhidraTableCellRenderer { Object value = data.getValue(); int column = data.getColumnModelIndex(); - boolean isSelected = data.isSelected(); - if (value == null && column == AbstractSymbolTableModel.LABEL_COL) { setText("<< REMOVED >>"); } - else if (value instanceof Symbol) { - handleSymbol(value, isSelected); - } - else if (value instanceof Address) { - setText(getAddressString((Address) value)); - } - else if (value instanceof ProgramLocation) { - setText(getLocationString((ProgramLocation) value)); + else if (value instanceof Symbol s) { + setBold(); + Color color = inspector.getColor(s); + + if (!data.isSelected()) { + setForeground(color); + } } return this; } - - private String getLocationString(ProgramLocation location) { - if (location instanceof VariableNameFieldLocation) { - VariableNameFieldLocation varLoc = (VariableNameFieldLocation) location; - Variable variable = varLoc.getVariable(); - return variable.getVariableStorage().toString(); - } - return getAddressString(location.getAddress()); - } - - private void handleSymbol(Object value, boolean isSelected) { - setBold(); - Color color = - (inspector != null) && (value instanceof Symbol) ? inspector.getColor((Symbol) value) - : Colors.FOREGROUND; - - if (!isSelected) { - setForeground(color); - } - } - - private String getAddressString(Address address) { - if (address.isStackAddress()) { - return getStackAddressString(address); - } - else if (address.isRegisterAddress()) { - return getRegisterAddressString(address); - } - else if (address.isExternalAddress() || address == Address.NO_ADDRESS) { - return ""; - } - return address.toString(); - } - - private String getRegisterAddressString(Address address) { - Program program = inspector.getProgram(); - if (program != null) { - Register register = program.getRegister(address); - if (register != null) { - return register.toString(); - } - } - return ""; - } - - private String getStackAddressString(Address address) { - long offset = address.getOffset(); - if (offset < 0) { - return "Stack[-0x" + Long.toHexString(-offset) + "]"; - } - return "Stack[0x" + Long.toHexString(offset) + "]"; - } - } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/symtable/SymbolTablePlugin.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/symtable/SymbolTablePlugin.java index 854a3dc15a..358c1a7fc5 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/symtable/SymbolTablePlugin.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/symtable/SymbolTablePlugin.java @@ -4,9 +4,9 @@ * 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. @@ -179,7 +179,6 @@ public class SymbolTablePlugin extends Plugin { Program newProg = progEvent.getActiveProgram(); if (oldProg != null) { - inspector.setProgram(null); oldProg.removeListener(domainObjectListener); domainObjectWorker.clearAllJobs(); symProvider.setProgram(null, inspector); @@ -189,7 +188,6 @@ public class SymbolTablePlugin extends Plugin { currentProgram = newProg; if (newProg != null) { currentProgram.addListener(domainObjectListener); - inspector.setProgram(currentProgram); symProvider.setProgram(currentProgram, inspector); refProvider.setProgram(currentProgram, inspector); } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/SymbolInspector.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/SymbolInspector.java index 3387726466..754534f27e 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/SymbolInspector.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/SymbolInspector.java @@ -4,9 +4,9 @@ * 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. @@ -40,10 +40,7 @@ import ghidra.program.model.symbol.*; public class SymbolInspector implements OptionsChangeListener { private Component repaintComp; - private Program program; private ToolOptions optionsObject; - private Listing listing; - private Memory memory; private Map cache = new HashMap<>(); /** @@ -81,35 +78,6 @@ public class SymbolInspector implements OptionsChangeListener { } } - /** - * Associates a program with this symbol inspector - * @param p the program for inspecting symbols - */ - public void setProgram(Program p) { - if (program == p) { - return; - } - - if (program != null) { - this.program = null; - this.listing = null; - this.memory = null; - } - if (p != null) { - this.program = p; - this.listing = p.getListing(); - this.memory = p.getMemory(); - } - } - - /** - * Returns the program in use by this inspector; may be null; - * @return the program in use by this inspector; may be null; - */ - public Program getProgram() { - return program; - } - /** * Call this when you are done with this inspector and will not use it again. * Cleans up listeners, etc. @@ -120,7 +88,25 @@ public class SymbolInspector implements OptionsChangeListener { optionsObject = null; } repaintComp = null; - setProgram(null); + } + + /** + * Does nothing + * @param p the program + * @deprecated this method does nothing + */ + @Deprecated(since = "11.3", forRemoval = true) + public void setProgram(Program p) { + // do nothing + } + + /** + * {@return null} + * @deprecated returns null + */ + @Deprecated(since = "11.3", forRemoval = true) + public Program getProgram() { + return null; } /** @@ -129,6 +115,7 @@ public class SymbolInspector implements OptionsChangeListener { * @return boolean true if symbol is bad */ public boolean isBadReferenceSymbol(Symbol s) { + Memory memory = getMemory(s); if (memory == null) { return true; } @@ -149,6 +136,7 @@ public class SymbolInspector implements OptionsChangeListener { return false; } Address addr = s.getAddress(); + Listing listing = getListing(s); Data data = listing.getDataContaining(addr); return (data != null); } @@ -162,6 +150,7 @@ public class SymbolInspector implements OptionsChangeListener { if (isBadReferenceSymbol(s)) { return false; } + Program program = s.getProgram(); ReferenceManager refMgr = program.getReferenceManager(); return !refMgr.hasReferencesTo(s.getAddress()); } @@ -225,6 +214,7 @@ public class SymbolInspector implements OptionsChangeListener { return false; } Address addr = s.getAddress(); + Listing listing = getListing(s); Instruction instr = listing.getInstructionContaining(addr); return (instr != null); } @@ -265,6 +255,7 @@ public class SymbolInspector implements OptionsChangeListener { return false; } Address addr = s.getAddress(); + Listing listing = getListing(s); CodeUnit cu = listing.getCodeUnitContaining(addr); if (cu != null && cu.getLength() > 1) { return cu.getMinAddress().compareTo(addr) < 0; @@ -321,6 +312,25 @@ public class SymbolInspector implements OptionsChangeListener { return new ColorAndStyle(color, style); } + /** + * Gets the color and style used to render the given reference. Calling this method is + * faster than calling {@link #getColor(Symbol)} and {@link #getStyle(Symbol)} + * separately. + * + * @param p the program + * @param r the reference + * @return the color and style + */ + public ColorAndStyle getColorAndStyle(Program p, Reference r) { + ScreenElement se = getScreenElement(p, r); + if (se == null) { + return null; + } + Color color = getColor(se); + int style = getStyle(se); + return new ColorAndStyle(color, style); + } + /** * Get the color used to render the given symbol. * @param s symbol to inspect @@ -341,7 +351,7 @@ public class SymbolInspector implements OptionsChangeListener { /** * Get the ScreenElement corresponding to the type of the symbol - * @param s symbol to inspect + * @param s the symbol to inspect * @return the screen element */ public ScreenElement getScreenElement(Symbol s) { @@ -366,7 +376,8 @@ public class SymbolInspector implements OptionsChangeListener { return OptionsGui.LABELS_UNREFD; } else if (isFunctionSymbol(s)) { - return OptionsGui.FUN_NAME; + Function f = (Function) s.getObject(); + return getFunctionScreenElement(f); } else if (isVariableSymbol(s)) { if (s.getSymbolType() == SymbolType.PARAMETER) { @@ -388,6 +399,21 @@ public class SymbolInspector implements OptionsChangeListener { return null; } + /** + * Get the ScreenElement corresponding to the type of the reference. + * @param p the program + * @param r the reference to inspect + * @return the screen element + */ + public ScreenElement getScreenElement(Program p, Reference r) { + if (r.isExternalReference()) { + ExternalLocation extLoc = ((ExternalReference) r).getExternalLocation(); + String libName = extLoc.getLibraryName(); + return getExternalPathScreenElement(p, libName); + } + return null; + } + public Color getOffcutSymbolColor() { return getColor(OptionsGui.XREF_OFFCUT); } @@ -400,12 +426,60 @@ public class SymbolInspector implements OptionsChangeListener { // Private Methods //================================================================================================== - private ScreenElement getExternalScreenElement(Symbol s) { - String path = program.getExternalManager().getExternalLibraryPath(getExternalName(s)); - if (path != null && path.length() > 0) { - return OptionsGui.EXT_REF_RESOLVED; + private Listing getListing(Symbol s) { + Program p = s.getProgram(); + if (p != null) { + return p.getListing(); } - return OptionsGui.BAD_REF_ADDR; + return null; // not sure if this can happen + } + + private Memory getMemory(Symbol s) { + Program p = s.getProgram(); + if (p != null) { + return p.getMemory(); + } + return null; // not sure if this can happen + } + + private ScreenElement getExternalScreenElement(Symbol s) { + + Program p = s.getProgram(); + String libName = getExternalName(s); + return getExternalPathScreenElement(p, libName); + } + + private ScreenElement getExternalPathScreenElement(Program p, String libName) { + + ExternalManager externalManager = p.getExternalManager(); + if (Library.UNKNOWN.equals(libName)) { + return OptionsGui.EXT_REF_UNRESOLVED; + } + + String path = externalManager.getExternalLibraryPath(libName); + if (path == null || path.length() == 0) { + return OptionsGui.EXT_REF_UNRESOLVED; + } + return OptionsGui.EXT_REF_RESOLVED; + } + + private ScreenElement getFunctionScreenElement(Function function) { + if (!function.isThunk()) { + return OptionsGui.FUN_NAME; + } + + // override function name color for external thunks which are not linked + Function thunkedFunction = function.getThunkedFunction(true); + if (thunkedFunction == null) { + return OptionsGui.EXT_REF_UNRESOLVED; + } + else if (thunkedFunction.isExternal()) { + ExternalLocation location = thunkedFunction.getExternalLocation(); + String libName = location.getLibraryName(); + return getExternalPathScreenElement(function.getProgram(), libName); + } + + return OptionsGui.FUN_NAME; } private String getExternalName(Symbol s) { diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/viewer/field/FunctionSignatureFieldFactory.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/viewer/field/FunctionSignatureFieldFactory.java index 8c31834a13..970295269f 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/viewer/field/FunctionSignatureFieldFactory.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/viewer/field/FunctionSignatureFieldFactory.java @@ -4,9 +4,9 @@ * 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. @@ -25,6 +25,7 @@ import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.RowColLocation; import ghidra.GhidraOptions; import ghidra.app.util.ListingHighlightProvider; +import ghidra.app.util.SymbolInspector; import ghidra.app.util.viewer.field.ListingColors.FunctionColors; import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.proxy.FunctionProxy; @@ -32,7 +33,8 @@ import ghidra.app.util.viewer.proxy.ProxyObj; import ghidra.framework.options.Options; import ghidra.framework.options.ToolOptions; import ghidra.program.model.listing.*; -import ghidra.program.model.symbol.*; +import ghidra.program.model.symbol.SourceType; +import ghidra.program.model.symbol.Symbol; import ghidra.program.util.*; /** @@ -45,6 +47,8 @@ public class FunctionSignatureFieldFactory extends FieldFactory { public final static String DISPLAY_NAMESPACE = GROUP_TITLE + Options.DELIMITER + GhidraOptions.DISPLAY_NAMESPACE; + private SymbolInspector inspector; + private boolean displayFunctionScope; public FunctionSignatureFieldFactory() { @@ -58,13 +62,16 @@ public class FunctionSignatureFieldFactory extends FieldFactory { * @param displayOptions the Options for display properties. * @param fieldOptions the Options for field specific properties. */ - public FunctionSignatureFieldFactory(FieldFormatModel model, ListingHighlightProvider hlProvider, + public FunctionSignatureFieldFactory(FieldFormatModel model, + ListingHighlightProvider hlProvider, ToolOptions displayOptions, ToolOptions fieldOptions) { super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions); fieldOptions.registerOption(DISPLAY_NAMESPACE, false, null, "Prepends namespaces to labels that are not in the global namespace."); + inspector = new SymbolInspector(displayOptions, null); + displayFunctionScope = fieldOptions.getBoolean(DISPLAY_NAMESPACE, false); } @@ -218,27 +225,8 @@ public class FunctionSignatureFieldFactory extends FieldFactory { } private Color getFunctionNameColor(Function function) { - // override function name color for external thunks which are not linked - if (function.isThunk()) { - Function thunkedFunction = function.getThunkedFunction(true); - if (thunkedFunction == null) { - return ListingColors.EXT_REF_UNRESOLVED; - } - else if (thunkedFunction.isExternal()) { - ExternalLocation externalLocation = thunkedFunction.getExternalLocation(); - String libName = externalLocation.getLibraryName(); - if (Library.UNKNOWN.equals(libName)) { - return ListingColors.EXT_REF_UNRESOLVED; - } - ExternalManager externalManager = function.getProgram().getExternalManager(); - String path = externalManager.getExternalLibraryPath(libName); - if (path == null || path.length() == 0) { - return ListingColors.EXT_REF_UNRESOLVED; - } - return ListingColors.EXT_REF_RESOLVED; - } - } - return FunctionColors.NAME; + Symbol s = function.getSymbol(); + return inspector.getColor(s); } @Override diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/viewer/field/LabelFieldFactory.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/viewer/field/LabelFieldFactory.java index a615cfc28c..60ba02be99 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/viewer/field/LabelFieldFactory.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/viewer/field/LabelFieldFactory.java @@ -4,9 +4,9 @@ * 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. @@ -148,7 +148,6 @@ public class LabelFieldFactory extends FieldFactory { Address currAddr = cu.getMinAddress(); Program prog = cu.getProgram(); - inspector.setProgram(prog); Listing list = prog.getListing(); Function func = list.getFunctionAt(currAddr); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/viewer/field/OperandFieldHelper.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/viewer/field/OperandFieldHelper.java index c1bfcc69bf..09f046164d 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/viewer/field/OperandFieldHelper.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/viewer/field/OperandFieldHelper.java @@ -4,9 +4,9 @@ * 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. @@ -67,7 +67,6 @@ abstract class OperandFieldHelper extends FieldFactory { private SymbolInspector inspector; private ColorStyleAttributes addressAttributes = new ColorStyleAttributes(); - private ColorStyleAttributes externalRefAttributes = new ColorStyleAttributes(); private ColorStyleAttributes badRefAttributes = new ColorStyleAttributes(); private ColorStyleAttributes separatorAttributes = new ColorStyleAttributes(); private ColorStyleAttributes scalarAttributes = new ColorStyleAttributes(); @@ -645,21 +644,16 @@ abstract class OperandFieldHelper extends FieldFactory { ReferenceManager refMgr = p.getReferenceManager(); Reference[] refs = refMgr.getReferencesFrom(cu.getMinAddress(), opIndex); - for (Reference element : refs) { - if (element.isExternalReference()) { - ExternalManager extMgr = p.getExternalManager(); - ExternalLocation extLoc = ((ExternalReference) element).getExternalLocation(); + for (Reference ref : refs) { - // has external reference been resolved? - String path = extMgr.getExternalLibraryPath(extLoc.getLibraryName()); - if (path != null && path.length() > 0) { - return externalRefAttributes; - } - return badRefAttributes; + // handle external references + ColorAndStyle c = inspector.getColorAndStyle(p, ref); + if (c != null) { + ColorStyleAttributes newAttributes = new ColorStyleAttributes(); + newAttributes.colorAttribute = c.getColor(); + newAttributes.styleAttribute = c.getStyle(); + return newAttributes; } -// if (refs[i].isVariableReference()) { -// return globalFrameRefAttributes; -// } } Reference mr = refMgr.getPrimaryReferenceFrom(cu.getMinAddress(), opIndex); @@ -686,27 +680,25 @@ abstract class OperandFieldHelper extends FieldFactory { } /** - * Determine the font and color to use to render an operand when that operand - * is a reference. + * Determine the font and color to use to render an operand when that operand is a reference. */ private ColorStyleAttributes getAddressAttributes(CodeUnit cu, Address destAddr, int opIndex, - Program program) { + Program p) { if (destAddr == null) { return separatorAttributes; } - if (destAddr.isMemoryAddress() && !program.getMemory().contains(destAddr)) { + if (destAddr.isMemoryAddress() && !p.getMemory().contains(destAddr)) { return badRefAttributes; } - SymbolTable st = program.getSymbolTable(); - ReferenceManager refMgr = program.getReferenceManager(); + SymbolTable st = p.getSymbolTable(); + ReferenceManager refMgr = p.getReferenceManager(); Reference ref = refMgr.getReference(cu.getMinAddress(), destAddr, opIndex); Symbol sym = st.getSymbol(ref); if (sym != null) { - inspector.setProgram(program); ColorStyleAttributes newAttributes = new ColorStyleAttributes(); ColorAndStyle c = inspector.getColorAndStyle(sym); newAttributes.colorAttribute = c.getColor(); @@ -726,7 +718,6 @@ abstract class OperandFieldHelper extends FieldFactory { scalarAttributes.colorAttribute = ListingColors.CONSTANT; variableRefAttributes.colorAttribute = FunctionColors.VARIABLE; addressAttributes.colorAttribute = ListingColors.ADDRESS; - externalRefAttributes.colorAttribute = ListingColors.EXT_REF_RESOLVED; badRefAttributes.colorAttribute = ListingColors.REF_BAD; registerAttributes.colorAttribute = ListingColors.REGISTER; @@ -738,8 +729,6 @@ abstract class OperandFieldHelper extends FieldFactory { options.getInt(OptionsGui.VARIABLE.getStyleOptionName(), -1); addressAttributes.styleAttribute = options.getInt(OptionsGui.ADDRESS.getStyleOptionName(), -1); - externalRefAttributes.styleAttribute = - options.getInt(OptionsGui.EXT_REF_RESOLVED.getStyleOptionName(), -1); badRefAttributes.styleAttribute = options.getInt(OptionsGui.BAD_REF_ADDR.getStyleOptionName(), -1); registerAttributes.styleAttribute = diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/viewer/options/OptionsGui.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/viewer/options/OptionsGui.java index 8a4ec893c7..677a5819c6 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/viewer/options/OptionsGui.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/viewer/options/OptionsGui.java @@ -4,9 +4,9 @@ * 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. @@ -60,6 +60,7 @@ public class OptionsGui extends JPanel { public static final ScreenElement ENTRY_POINT = new ScreenElement("Entry Point", ListingColors.EXT_ENTRY_POINT); public static final ScreenElement COMMENT_EOL = new ScreenElement("Comment, EOL", "EOL Comment", CommentColors.EOL); public static final ScreenElement EXT_REF_RESOLVED = new ScreenElement("External Reference, Resolved", ListingColors.EXT_REF_RESOLVED); + public static final ScreenElement EXT_REF_UNRESOLVED = new ScreenElement("External Reference, Unresolved", ListingColors.EXT_REF_UNRESOLVED); public static final ScreenElement FIELD_NAME = new ScreenElement("Field Name", ListingColors.FIELD_NAME); public static final ScreenElement FUN_CALL_FIXUP = new ScreenElement("Function Call-Fixup", FunctionColors.CALL_FIXUP); public static final ScreenElement FUN_NAME = new ScreenElement("Function Name", FunctionColors.NAME); diff --git a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/provider/markuptable/VTMarkupItemsTableModel.java b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/provider/markuptable/VTMarkupItemsTableModel.java index ff97d972cd..3b4b9b7bf3 100644 --- a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/provider/markuptable/VTMarkupItemsTableModel.java +++ b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/gui/provider/markuptable/VTMarkupItemsTableModel.java @@ -4,9 +4,9 @@ * 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. @@ -346,7 +346,6 @@ public class VTMarkupItemsTableModel extends AddressBasedTableModel