diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/actions/AbstractFindReferencesDataTypeAction.java b/Ghidra/Features/Base/src/main/java/ghidra/app/actions/AbstractFindReferencesDataTypeAction.java index 3c28dfd29b..fb6c9f9930 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/actions/AbstractFindReferencesDataTypeAction.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/actions/AbstractFindReferencesDataTypeAction.java @@ -27,7 +27,6 @@ import ghidra.app.plugin.core.navigation.FindAppliedDataTypesService; import ghidra.app.plugin.core.navigation.locationreferences.ReferenceUtils; import ghidra.app.util.HelpTopics; import ghidra.framework.plugintool.PluginTool; -import ghidra.program.model.data.Composite; import ghidra.program.model.data.DataType; import ghidra.util.*; @@ -56,7 +55,7 @@ public abstract class AbstractFindReferencesDataTypeAction extends DockingAction protected abstract DataType getDataType(ActionContext context); - protected String getDataTypeField() { + protected String getDataTypeField(DataType baseDataType) { // The base implementation only searches for references to the data type, not specific // fields. Subclasses can change this behavior return null; @@ -89,23 +88,8 @@ public abstract class AbstractFindReferencesDataTypeAction extends DockingAction DataType dataType = getDataType(context); DataType baseDataType = ReferenceUtils.getBaseDataType(dataType); - String field = getDataTypeField(); - - // sanity check - should not happen - if (field != null && !(baseDataType instanceof Composite)) { - Msg.error(this, "Somehow have a field without a Composite parent--searching " + - "only for the parent type '" + dataType + "'; field '" + field + "'"); - Swing.runLater(() -> service.findAndDisplayAppliedDataTypeAddresses(dataType)); - return; - } - - if (field == null) { - Swing.runLater(() -> service.findAndDisplayAppliedDataTypeAddresses(dataType)); - } - else { - Swing.runLater(() -> service.findAndDisplayAppliedDataTypeAddresses( - (Composite) baseDataType, field)); - } + String field = getDataTypeField(baseDataType); + Swing.runLater(() -> service.findAndDisplayAppliedDataTypeAddresses(baseDataType, field)); } } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datamgr/actions/FindReferencesToFieldAction.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datamgr/actions/FindReferencesToFieldAction.java index 31aee84475..f8a6c0e097 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datamgr/actions/FindReferencesToFieldAction.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datamgr/actions/FindReferencesToFieldAction.java @@ -18,7 +18,6 @@ package ghidra.app.plugin.core.datamgr.actions; import java.util.ArrayList; import java.util.List; -import javax.swing.SwingUtilities; import javax.swing.tree.TreePath; import org.apache.commons.lang3.StringUtils; @@ -35,8 +34,8 @@ import ghidra.app.plugin.core.datamgr.tree.DataTypeNode; import ghidra.app.plugin.core.navigation.FindAppliedDataTypesService; import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.data.*; -import ghidra.util.HelpLocation; -import ghidra.util.Msg; +import ghidra.program.model.data.Enum; +import ghidra.util.*; public class FindReferencesToFieldAction extends DockingAction { @@ -72,7 +71,7 @@ public class FindReferencesToFieldAction extends DockingAction { } DataTypeNode dtNode = (DataTypeNode) node; DataType dataType = dtNode.getDataType(); - return dataType instanceof Composite; + return dataType instanceof Composite || dataType instanceof Enum; } @Override @@ -83,7 +82,6 @@ public class FindReferencesToFieldAction extends DockingAction { PluginTool tool = plugin.getTool(); FindAppliedDataTypesService service = tool.getService(FindAppliedDataTypesService.class); - if (service == null) { Msg.showError(this, null, "Missing Plugin", "The FindAppliedDataTypesService is not installed.\n" + @@ -91,7 +89,27 @@ public class FindReferencesToFieldAction extends DockingAction { return; } - Composite composite = (Composite) dataTypeNode.getDataType(); + DataType dt = dataTypeNode.getDataType(); + String[] choices = null; + if (dt instanceof Composite) { + choices = getCompisiteFieldNames((Composite) dt); + } + else if (dt instanceof Enum) { + choices = ((Enum) dt).getNames(); + } + + String userChoice = OptionDialog.showInputChoiceDialog(null, "Choose Field", + "Find uses of '" + dt.getName() + "' field", choices, null, + OptionDialog.QUESTION_MESSAGE); + if (userChoice == null) { + return; + } + + Swing.runLater( + () -> service.findAndDisplayAppliedDataTypeAddresses(dt, userChoice)); + } + + private String[] getCompisiteFieldNames(Composite composite) { DataTypeComponent[] components = composite.getDefinedComponents(); List names = new ArrayList<>(); for (DataTypeComponent dataTypeComponent : components) { @@ -105,17 +123,7 @@ public class FindReferencesToFieldAction extends DockingAction { names.add(fieldName); } - String[] array = names.toArray(new String[names.size()]); - String userChoice = OptionDialog.showInputChoiceDialog(null, "Choose Field", - "Find uses of '" + composite.getName() + "' field", array, null, - OptionDialog.QUESTION_MESSAGE); - - if (userChoice == null) { - return; - } - - SwingUtilities.invokeLater( - () -> service.findAndDisplayAppliedDataTypeAddresses(composite, userChoice)); + return names.toArray(String[]::new); } } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/navigation/FindAppliedDataTypesService.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/navigation/FindAppliedDataTypesService.java index 97338b2114..262dada51b 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/navigation/FindAppliedDataTypesService.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/navigation/FindAppliedDataTypesService.java @@ -15,7 +15,6 @@ */ package ghidra.app.plugin.core.navigation; -import ghidra.program.model.data.Composite; import ghidra.program.model.data.DataType; /** @@ -24,7 +23,7 @@ import ghidra.program.model.data.DataType; public interface FindAppliedDataTypesService { /** - * Tells this service to find all places where the given datatype is defined and will + * Tells this service to find all places where the given datatype is applied and will * display the results of the search. * * @param dataType The datatype which to base the search upon. @@ -32,11 +31,11 @@ public interface FindAppliedDataTypesService { public void findAndDisplayAppliedDataTypeAddresses(DataType dataType); /** - * Tells this service to find all places where the given datatype is defined and will + * Tells this service to find all places where the given datatype is applied and will * display the results of the search. * * @param dataType The datatype which to base the search upon. * @param fieldName the sub-field for which to search */ - public void findAndDisplayAppliedDataTypeAddresses(Composite dataType, String fieldName); + public void findAndDisplayAppliedDataTypeAddresses(DataType dataType, String fieldName); } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/navigation/locationreferences/GenericCompositeDataTypeLocationDescriptor.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/navigation/locationreferences/GenericCompositeDataTypeLocationDescriptor.java index f480c3e5fe..fd4943d99e 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/navigation/locationreferences/GenericCompositeDataTypeLocationDescriptor.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/navigation/locationreferences/GenericCompositeDataTypeLocationDescriptor.java @@ -22,7 +22,6 @@ import org.apache.commons.lang3.StringUtils; import docking.widgets.fieldpanel.support.Highlight; import ghidra.app.util.viewer.field.*; import ghidra.program.model.address.Address; -import ghidra.program.model.data.Composite; import ghidra.program.model.listing.Data; import ghidra.program.model.listing.Program; import ghidra.util.datastruct.Accumulator; @@ -30,8 +29,8 @@ import ghidra.util.exception.CancelledException; import ghidra.util.task.TaskMonitor; /** - * A data type location descriptor that allows you to represent a location for a member field of - * a composite. + * A data type location descriptor that allows you to represent a location for a member field of a + * data type, such as a composite or an enum */ public class GenericCompositeDataTypeLocationDescriptor extends GenericDataTypeLocationDescriptor { @@ -50,9 +49,7 @@ public class GenericCompositeDataTypeLocationDescriptor extends GenericDataTypeL @Override protected void doGetReferences(Accumulator accumulator, TaskMonitor monitor) throws CancelledException { - - Composite currentDataType = (Composite) getDataType(); - ReferenceUtils.findDataTypeReferences(accumulator, currentDataType, fieldName, program, + ReferenceUtils.findDataTypeReferences(accumulator, getDataType(), fieldName, program, useDynamicSearching, monitor); } @@ -102,13 +99,13 @@ public class GenericCompositeDataTypeLocationDescriptor extends GenericDataTypeL // the parent's name and not the field's name. } else if (LabelFieldFactory.class.isAssignableFrom(fieldFactoryClass)) { - // It would be nice to highlight the label that points into data structures. + // It would be nice to highlight the label that points into data structures. // However, the label is on the parent address, which is not in our list of matches - // when we are offcut. Further, using the program to lookup each address that + // when we are offcut. Further, using the program to lookup each address that // comes in to see if it is our paren't address seems too expensive, as highlighting // code is called for every paint operation. // - // We could add the parent match to the list of known addresses and then use that + // We could add the parent match to the list of known addresses and then use that // to lookup in real-time later. To do this we would need the current list of // reference addresses and a new list of parent data addresses. That seems a bit // involved just for highlighting a label. diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/navigation/locationreferences/GenericCompositeDataTypeProgramLocation.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/navigation/locationreferences/GenericCompositeDataTypeProgramLocation.java index f5301b2a70..28420886a6 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/navigation/locationreferences/GenericCompositeDataTypeProgramLocation.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/navigation/locationreferences/GenericCompositeDataTypeProgramLocation.java @@ -18,12 +18,13 @@ package ghidra.app.plugin.core.navigation.locationreferences; import java.util.Objects; import ghidra.program.model.data.Composite; +import ghidra.program.model.data.DataType; import ghidra.program.model.listing.Program; /** - * A class to signal that the ProgramLocation is used for data types and is not really - * connected to the listing. This is a subclass specifically for {@link Composite} types and a - * particular field name of the given composite. + * A class to signal that the ProgramLocation is used for data types and is not really + * connected to the listing. This is a subclass is designed for data types that have fields, such + * as {@link Composite} types and {@link Enum} types. * * @see GenericCompositeDataTypeLocationDescriptor */ @@ -31,7 +32,7 @@ public class GenericCompositeDataTypeProgramLocation extends GenericDataTypeProg private String fieldName; - GenericCompositeDataTypeProgramLocation(Program program, Composite dataType, String fieldName) { + GenericCompositeDataTypeProgramLocation(Program program, DataType dataType, String fieldName) { super(program, dataType); this.fieldName = Objects.requireNonNull(fieldName); } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/navigation/locationreferences/LocationReferencesPlugin.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/navigation/locationreferences/LocationReferencesPlugin.java index 9bda8c8696..f188fb3b8e 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/navigation/locationreferences/LocationReferencesPlugin.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/navigation/locationreferences/LocationReferencesPlugin.java @@ -33,7 +33,6 @@ import ghidra.app.util.query.TableService; import ghidra.framework.options.ToolOptions; import ghidra.framework.plugintool.*; import ghidra.framework.plugintool.util.PluginStatus; -import ghidra.program.model.data.Composite; import ghidra.program.model.data.DataType; import ghidra.program.model.listing.Program; import ghidra.program.model.symbol.Reference; @@ -102,10 +101,10 @@ public class LocationReferencesPlugin extends Plugin tool.addAction(referencesToAddressAction); // - // Unusual Code: This plugin does not use the delete action directly, but our transient - // tables do. We need a way to have keybindings shared for this action. + // Unusual Code: This plugin does not use the delete action directly, but our transient + // tables do. We need a way to have keybindings shared for this action. // Further, we need to register it now, not when the transient - // providers are created, as they would only appear in the options at + // providers are created, as they would only appear in the options at // that point. // DeleteTableRowAction.registerDummy(tool, getName()); @@ -173,7 +172,7 @@ public class LocationReferencesPlugin extends Plugin tool.showComponentProvider(provider, true); -// REFS: is the following statement true???...it seems that the loading is off the swing thread, +// REFS: is the following statement true???...it seems that the loading is off the swing thread, // so it still may not be done at this point! // we add the provider here instead of where it is created above to allow the provider to @@ -311,7 +310,7 @@ public class LocationReferencesPlugin extends Plugin } @Override - public void findAndDisplayAppliedDataTypeAddresses(Composite dataType, String fieldName) { + public void findAndDisplayAppliedDataTypeAddresses(DataType dataType, String fieldName) { ProgramManager programManagerService = tool.getService(ProgramManager.class); GoToService goToService = tool.getService(GoToService.class); Program program = programManagerService.getCurrentProgram(); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/navigation/locationreferences/ReferenceUtils.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/navigation/locationreferences/ReferenceUtils.java index f583e4ae63..08e657958c 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/navigation/locationreferences/ReferenceUtils.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/navigation/locationreferences/ReferenceUtils.java @@ -31,7 +31,6 @@ import ghidra.program.util.*; import ghidra.util.*; import ghidra.util.classfinder.ClassSearcher; import ghidra.util.datastruct.*; -import ghidra.util.exception.AssertException; import ghidra.util.exception.CancelledException; import ghidra.util.task.TaskMonitor; @@ -210,11 +209,6 @@ public final class ReferenceUtils { // Note: none of the params can be null, but this one gets used much later, so check now Objects.requireNonNull(dataType, () -> "Data Type cannot be null"); - // sanity check - if (fieldName != null && !(dataType instanceof Composite)) { - throw new IllegalArgumentException("Can only search for a field with a Composite type"); - } - if (monitor == null) { monitor = TaskMonitor.DUMMY; } @@ -283,12 +277,6 @@ public final class ReferenceUtils { accumulator.add(locationReference); }; - if (fieldName != null && !(dataType instanceof Composite)) { - throw new AssertException( - "Must have a Composite data type to perform a field search. Found " + dataType + - "; field '" + fieldName + "'"); - } - if (finders.isEmpty()) { Msg.debug(ReferenceUtils.class, "Unable to find any implementations of " + DataTypeReferenceFinder.class.getSimpleName()); @@ -300,7 +288,7 @@ public final class ReferenceUtils { finder.findReferences(program, dataType, callback, monitor); } else { - finder.findReferences(program, (Composite) dataType, fieldName, callback, monitor); + finder.findReferences(program, dataType, fieldName, callback, monitor); } } } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/services/DataTypeReference.java b/Ghidra/Features/Base/src/main/java/ghidra/app/services/DataTypeReference.java index 5e40ed861e..764e2ccd2b 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/services/DataTypeReference.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/services/DataTypeReference.java @@ -68,7 +68,7 @@ public class DataTypeReference { fieldNameText + "\tfunction: " + function.getName() + "\n" + "\taddress: " + address + "\n" + - "\tcontext: " + context + "\n" + + "\tcontext: " + context.getPlainText() + "\n" + "}"; //@formatter:on } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/services/DataTypeReferenceFinder.java b/Ghidra/Features/Base/src/main/java/ghidra/app/services/DataTypeReferenceFinder.java index 99cddd394a..d03b54ffaf 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/services/DataTypeReferenceFinder.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/services/DataTypeReferenceFinder.java @@ -33,10 +33,10 @@ import ghidra.util.task.TaskMonitor; public interface DataTypeReferenceFinder extends ExtensionPoint { /** - * Finds references in the current program in a manner appropriate with the given + * Finds references in the current program in a manner appropriate with the given * implementation. *

- * Note that this operation is multi-threaded and that results will be delivered as they + * Note that this operation is multi-threaded and that results will be delivered as they * are found via the callback. * * @param program the program to search @@ -53,16 +53,16 @@ public interface DataTypeReferenceFinder extends ExtensionPoint { * Finds references in the current program to specific field of the given {@link Composite} type * in a manner appropriate with the given implementation. *

- * Note that this operation is multi-threaded and that results will be delivered as they + * Note that this operation is multi-threaded and that results will be delivered as they * are found via the callback. * * @param program the program to search - * @param composite the type containing the field for which to search + * @param dataType the type containing the field for which to search * @param fieldName the name of the composite's field for which to search * @param callback the callback to be called when a reference is found * @param monitor the monitor that allows for progress and cancellation * @throws CancelledException if the operation was cancelled */ - public void findReferences(Program program, Composite composite, String fieldName, + public void findReferences(Program program, DataType dataType, String fieldName, Consumer callback, TaskMonitor monitor) throws CancelledException; } diff --git a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/actions/FindReferencesToDataTypeAction.java b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/actions/FindReferencesToDataTypeAction.java index 2803568a01..2429792bff 100644 --- a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/actions/FindReferencesToDataTypeAction.java +++ b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/actions/FindReferencesToDataTypeAction.java @@ -18,14 +18,14 @@ package ghidra.app.plugin.core.decompile.actions; import docking.ActionContext; import docking.action.MenuData; import ghidra.app.actions.AbstractFindReferencesDataTypeAction; -import ghidra.app.decompiler.ClangFieldToken; -import ghidra.app.decompiler.ClangToken; +import ghidra.app.decompiler.*; import ghidra.app.decompiler.component.*; import ghidra.app.plugin.core.decompile.DecompilerActionContext; import ghidra.app.plugin.core.navigation.locationreferences.LocationReferencesService; import ghidra.app.util.HelpTopics; import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.data.DataType; +import ghidra.program.model.data.Enum; import ghidra.util.HelpLocation; public class FindReferencesToDataTypeAction extends AbstractFindReferencesDataTypeAction { @@ -44,12 +44,11 @@ public class FindReferencesToDataTypeAction extends AbstractFindReferencesDataTy @Override public DataType getDataType(ActionContext context) { - return DecompilerUtils.getDataType((DecompilerActionContext) context); } @Override - protected String getDataTypeField() { + protected String getDataTypeField(DataType dataType) { DecompilerPanel decompilerPanel = controller.getDecompilerPanel(); ClangToken tokenAtCursor = decompilerPanel.getTokenAtCursor(); @@ -57,6 +56,20 @@ public class FindReferencesToDataTypeAction extends AbstractFindReferencesDataTy return tokenAtCursor.getText(); } + if (dataType instanceof Enum) { + + // check for enum field + ClangVariableToken vt = (ClangVariableToken) tokenAtCursor; + String text = vt.getText(); + Enum e = (Enum) dataType; + String[] names = e.getNames(); + for (String name : names) { + if (name.equals(text)) { + return name; + } + } + } + return null; } @@ -93,8 +106,7 @@ public class FindReferencesToDataTypeAction extends AbstractFindReferencesDataTy String typeName = type.getName(); String menuName = "Find Uses of " + typeName; - - String fieldName = getDataTypeField(); + String fieldName = getDataTypeField(type); if (fieldName != null) { menuName += '.' + fieldName; } diff --git a/Ghidra/Features/Decompiler/src/test.slow/java/ghidra/app/plugin/core/decompile/AbstractDecompilerFindReferencesActionTest.java b/Ghidra/Features/Decompiler/src/test.slow/java/ghidra/app/plugin/core/decompile/AbstractDecompilerFindReferencesActionTest.java index 40a376dfd7..d2fc442876 100644 --- a/Ghidra/Features/Decompiler/src/test.slow/java/ghidra/app/plugin/core/decompile/AbstractDecompilerFindReferencesActionTest.java +++ b/Ghidra/Features/Decompiler/src/test.slow/java/ghidra/app/plugin/core/decompile/AbstractDecompilerFindReferencesActionTest.java @@ -33,7 +33,6 @@ import ghidra.app.plugin.core.navigation.locationreferences.LocationReferencesPr import ghidra.app.plugin.core.navigation.locationreferences.LocationReferencesService; import ghidra.app.services.DataTypeReference; import ghidra.app.services.DataTypeReferenceFinder; -import ghidra.program.model.data.Composite; import ghidra.program.model.data.DataType; import ghidra.program.model.listing.Program; import ghidra.program.util.ProgramLocation; @@ -167,7 +166,7 @@ public abstract class AbstractDecompilerFindReferencesActionTest extends Abstrac } @Mock - public void findReferences(Program p, Composite composite, String fieldName, + public void findReferences(Program p, DataType dt, String fieldName, Consumer callback, TaskMonitor monitor) { compositeFieldReferencesCallCount.incrementAndGet(); diff --git a/Ghidra/Features/Decompiler/src/test.slow/java/ghidra/app/plugin/core/decompile/StubDataTypeReferenceFinder.java b/Ghidra/Features/Decompiler/src/test.slow/java/ghidra/app/plugin/core/decompile/StubDataTypeReferenceFinder.java index e9b433d17b..b12f2f4fed 100644 --- a/Ghidra/Features/Decompiler/src/test.slow/java/ghidra/app/plugin/core/decompile/StubDataTypeReferenceFinder.java +++ b/Ghidra/Features/Decompiler/src/test.slow/java/ghidra/app/plugin/core/decompile/StubDataTypeReferenceFinder.java @@ -19,7 +19,6 @@ import java.util.function.Consumer; import ghidra.app.services.DataTypeReference; import ghidra.app.services.DataTypeReferenceFinder; -import ghidra.program.model.data.Composite; import ghidra.program.model.data.DataType; import ghidra.program.model.listing.Program; import ghidra.util.exception.CancelledException; @@ -37,7 +36,7 @@ public class StubDataTypeReferenceFinder implements DataTypeReferenceFinder { } @Override - public void findReferences(Program program, Composite composite, String fieldName, + public void findReferences(Program program, DataType dataType, String fieldName, Consumer callback, TaskMonitor monitor) throws CancelledException { // stub } diff --git a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/extension/datatype/finder/DecompilerDataTypeReferenceFinder.java b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/extension/datatype/finder/DecompilerDataTypeReferenceFinder.java index da8a90c900..8dcaa49b5b 100644 --- a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/extension/datatype/finder/DecompilerDataTypeReferenceFinder.java +++ b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/extension/datatype/finder/DecompilerDataTypeReferenceFinder.java @@ -31,7 +31,8 @@ import ghidra.app.plugin.core.navigation.locationreferences.ReferenceUtils; import ghidra.app.services.DataTypeReference; import ghidra.app.services.DataTypeReferenceFinder; import ghidra.program.model.address.Address; -import ghidra.program.model.data.*; +import ghidra.program.model.data.BuiltInDataType; +import ghidra.program.model.data.DataType; import ghidra.program.model.listing.*; import ghidra.util.Msg; import ghidra.util.StringUtilities; @@ -40,7 +41,7 @@ import ghidra.util.exception.CancelledException; import ghidra.util.task.TaskMonitor; /** - * Implementation of {@link DataTypeReferenceFinder} that uses the Decompiler's output + * Implementation of {@link DataTypeReferenceFinder} that uses the Decompiler's output * to find data type and composite field usage. */ public class DecompilerDataTypeReferenceFinder implements DataTypeReferenceFinder { @@ -52,29 +53,11 @@ public class DecompilerDataTypeReferenceFinder implements DataTypeReferenceFinde @Override public void findReferences(Program program, DataType dataType, Consumer callback, TaskMonitor monitor) throws CancelledException { - - DecompilerDataTypeFinderQCallback qCallback = - new DecompilerDataTypeFinderQCallback(program, dataType, callback); - - Set functions = filterFunctions(program, dataType, monitor); - - try { - ParallelDecompiler.decompileFunctions(qCallback, functions, monitor); - } - catch (InterruptedException e) { - Thread.currentThread().interrupt(); // reset the flag - Msg.trace(this, "Interrupted while decompiling functions"); - } - catch (Exception e) { - Msg.error(this, "Encountered an exception decompiling functions", e); - } - finally { - qCallback.dispose(); - } + findReferences(program, dataType, null, callback, monitor); } @Override - public void findReferences(Program program, Composite dataType, String fieldName, + public void findReferences(Program program, DataType dataType, String fieldName, Consumer callback, TaskMonitor monitor) throws CancelledException { DecompilerDataTypeFinderQCallback qCallback = @@ -175,12 +158,12 @@ public class DecompilerDataTypeReferenceFinder implements DataTypeReferenceFinde // We have a different type, should we search for it? if (baseType instanceof BuiltInDataType) { - // When given a wrapper type (e.g., typedef) , ignore - // built-ins (e.g., int, byte, etc), as + // When given a wrapper type (e.g., typedef) , ignore + // built-ins (e.g., int, byte, etc), as // they will be of little value due to their volume in the program and the - // user *probably* did not intend to search for them. (Below we do not do - // this check, which allows the user to search directly for a - // built-in type, if they wish.) + // user *probably* did not intend to search for them. (Below we do not do + // this check, which allows the user to search directly for a + // built-in type, if they wish.) return; } @@ -227,12 +210,6 @@ public class DecompilerDataTypeReferenceFinder implements DataTypeReferenceFinde private DataType dataType; private String fieldName; - /* Search for Data Type access only--no field usage */ - DecompilerDataTypeFinderQCallback(Program program, DataType dataType, - Consumer callback) { - this(program, dataType, null, callback); - } - /* Search for composite field access */ DecompilerDataTypeFinderQCallback(Program program, DataType dataType, String fieldName, Consumer callback) { @@ -279,7 +256,7 @@ public class DecompilerDataTypeReferenceFinder implements DataTypeReferenceFinde } /** - * Class to do the work of searching through the Decompiler's results for the desired + * Class to do the work of searching through the Decompiler's results for the desired * data type access. */ private static class DecompilerDataTypeFinder { @@ -308,7 +285,7 @@ public class DecompilerDataTypeReferenceFinder implements DataTypeReferenceFinde ClangTokenGroup tokens = decompilation.getCCodeMarkup(); -// TODO delete this when the ticket settles down +// TODO delete this when the ticket settles down // dumpTokens(tokens, 0); // dumpTokenNames(tokens, 0); @@ -339,15 +316,15 @@ public class DecompilerDataTypeReferenceFinder implements DataTypeReferenceFinde } /** - * Uses the given line to find variables (also parameters and return types) and any - * accesses to them in that line. A given variable may be used directly or, as in + * Uses the given line to find variables (also parameters and return types) and any + * accesses to them in that line. A given variable may be used directly or, as in * the case with Composite types, may have one of its fields accessed. Each result * found by this method will be at least a variable access and may also itself have * field accesses. * *

Sometimes a line is structured such that there are anonymous variable accesses. This * is the case where a Composite is being accessed, but the Composite itself is - * not a variable in the current function. See {@link AnonymousVariableAccessDR} for + * not a variable in the current function. See {@link AnonymousVariableAccessDR} for * more details. * * @param line the current line being processed from the Decompiler @@ -396,14 +373,14 @@ public class DecompilerDataTypeReferenceFinder implements DataTypeReferenceFinde else if (token instanceof ClangVariableToken) { // - // Observations: - // 1) 'access' will be null if we are on a C statement that - // is a declaration (parameter or variable). In this case, + // Observations: + // 1) 'access' will be null if we are on a C statement that + // is a declaration (parameter or variable). In this case, // 'declaration' will be an instance of VariableDR. // 2) 'access' will be null the first time a variable is used in // a statement. - // 3) if 'access' is non-null, but already has a variable assigned, - // then this means the current ClangVariableToken represents a new + // 3) if 'access' is non-null, but already has a variable assigned, + // then this means the current ClangVariableToken represents a new // variable access/usage. // if (declaration != null) { @@ -427,7 +404,7 @@ public class DecompilerDataTypeReferenceFinder implements DataTypeReferenceFinde if (access == null) { // Uh-oh. I've only seen this when line-wrapping is happening. In that - // case, try to get the last variable that we've seen and assume that + // case, try to get the last variable that we've seen and assume that // is the variable to which this field belongs. access = getLastAccess(results); if (access == null) { @@ -442,7 +419,7 @@ public class DecompilerDataTypeReferenceFinder implements DataTypeReferenceFinde ClangFieldToken field = (ClangFieldToken) token; if (typesDoNotMatch(access, field)) { - // this can happen when a field is used anonymously, such as directly + // this can happen when a field is used anonymously, such as directly // after a nested array index operation results.add(new AnonymousVariableAccessDR(line, field)); continue; diff --git a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/extension/datatype/finder/DecompilerReference.java b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/extension/datatype/finder/DecompilerReference.java index 44c67b600c..6af5431569 100644 --- a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/extension/datatype/finder/DecompilerReference.java +++ b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/extension/datatype/finder/DecompilerReference.java @@ -174,7 +174,7 @@ public abstract class DecompilerReference { return "{\n" + "\tvariable: " + StringUtilities.toStringWithIndent(variable) + ",\n" + "\tdata type: " + getDataType() + ",\n"+ - "\tline " + getContext() + ",\n" + + "\tline " + StringUtilities.toStringWithIndent(getContext().getPlainText()) + ",\n" + "\tfunction: " + getFunction() + "\n" + "}"; //@formatter:on diff --git a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/extension/datatype/finder/VariableAccessDR.java b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/extension/datatype/finder/VariableAccessDR.java index 344fe9aa03..0d64c2cac5 100644 --- a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/extension/datatype/finder/VariableAccessDR.java +++ b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/extension/datatype/finder/VariableAccessDR.java @@ -120,6 +120,16 @@ public class VariableAccessDR extends DecompilerReference { } if (potentialField == null) { + + // check for the case where we have not been passed a 'potential field', but the given + // 'var' is itself the field we seek, such as in an if statement like this: + // if (color == RED) + // where 'RED' is the variable we are checking + String name = var.getName(); + if (fieldName.equals(name)) { + return var; + } + return null; // we seek a field, but there is none } @@ -268,7 +278,7 @@ public class VariableAccessDR extends DecompilerReference { //@formatter:off return "{\n" + - "\tline " + getContext() + ",\n" + + "\tline " + getContext().getPlainText() + ",\n" + "\tfunction: " + getFunction() + "\n" + "\tvariable: " + StringUtilities.toStringWithIndent(variable) + ",\n" + "\tdata type: " + getDataType() + ",\n"+