diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/stack/vars/VariableValueUtils.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/stack/vars/VariableValueUtils.java index 7b6698d6c9..d0b7d75573 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/stack/vars/VariableValueUtils.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/stack/vars/VariableValueUtils.java @@ -139,8 +139,7 @@ public enum VariableValueUtils { } @Override - protected Boolean evaluateLoad(Program program, PcodeOp op, - Map already) { + protected Boolean evaluateLoad(Program program, PcodeOp op, Map already) { return evaluateVarnode(program, op.getInput(1), already); } @@ -180,9 +179,14 @@ public enum VariableValueUtils { this.space = space; } + @Override + public boolean isImmutableSettings() { + return true; + } + @Override public boolean isChangeAllowed(SettingsDefinition settingsDefinition) { - return delegate.isChangeAllowed(settingsDefinition); + return false; } @Override @@ -473,9 +477,8 @@ public enum VariableValueUtils { */ public static boolean hasFreshUnwind(PluginTool tool, DebuggerCoordinates coordinates) { ListingUnwoundFrame innermost = locateInnermost(tool, coordinates); - if (innermost == null || !Objects.equals(innermost.getProgramCounter(), - getProgramCounter(coordinates.getPlatform(), coordinates.getThread(), - coordinates.getViewSnap()))) { + if (innermost == null || !Objects.equals(innermost.getProgramCounter(), getProgramCounter( + coordinates.getPlatform(), coordinates.getThread(), coordinates.getViewSnap()))) { return false; } return true; @@ -866,13 +869,12 @@ public enum VariableValueUtils { address.isRegisterAddress()) { settings = new DefaultSpaceSettings(settings, language.getDefaultSpace()); } - ByteMemBufferImpl buf = - new ByteMemBufferImpl(address, bytes, language.isBigEndian()) { - @Override - public Memory getMemory() { - return coordinates.getView().getMemory(); - } - }; + ByteMemBufferImpl buf = new ByteMemBufferImpl(address, bytes, language.isBigEndian()) { + @Override + public Memory getMemory() { + return coordinates.getView().getMemory(); + } + }; return type.getRepresentation(buf, settings, bytes.length); } diff --git a/Ghidra/Features/Base/src/main/help/help/topics/DataPlugin/Data.htm b/Ghidra/Features/Base/src/main/help/help/topics/DataPlugin/Data.htm index 413088eef9..4004bcf5ae 100644 --- a/Ghidra/Features/Base/src/main/help/help/topics/DataPlugin/Data.htm +++ b/Ghidra/Features/Base/src/main/help/help/topics/DataPlugin/Data.htm @@ -786,12 +786,14 @@

To change the default settings for a given data type:

    -
  1. Place the cursor on a data item of that type
  2. +
  3. Place the cursor on a data item of that type,
  4. -
  5. Press mouse-right to bring up the popup menu
  6. +
  7. Press mouse-right to bring up the popup menu,
  8. Select Data Default Settings... to bring up - the default settings dialog
  9. + the default settings dialog. This action may not be available in cases which do not allow + the default settings to be modified such as components of Dynamic Data Types which are + established on-the-fly.
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/data/DataPlugin.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/data/DataPlugin.java index e832c6e6de..80c976c5f5 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/data/DataPlugin.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/data/DataPlugin.java @@ -158,8 +158,7 @@ public class DataPlugin extends Plugin implements DataService { .buildAndInstall(tool); // Data instance settings action based upon data selection in listing - new ActionBuilder("Data Settings", getName()) - .sharedKeyBinding() + new ActionBuilder("Data Settings", getName()).sharedKeyBinding() .popupMenuPath(DATA_SETTINGS_POPUP_PATH) .popupMenuGroup("Settings") .withContext(ListingActionContext.class) @@ -168,8 +167,7 @@ public class DataPlugin extends Plugin implements DataService { .buildAndInstall(tool); // Default settings action based upon data selection in listing - new ActionBuilder("Default Settings", getName()) - .sharedKeyBinding() + new ActionBuilder("Default Settings", getName()).sharedKeyBinding() .popupMenuPath(DEFAULT_SETTINGS_POPUP_PATH) .popupMenuGroup("Settings") .withContext(ListingActionContext.class) @@ -178,8 +176,7 @@ public class DataPlugin extends Plugin implements DataService { .buildAndInstall(tool); // Default settings action for selected datatypes from datatype manager - new ActionBuilder("Default Settings", getName()) - .sharedKeyBinding() + new ActionBuilder("Default Settings", getName()).sharedKeyBinding() .popupMenuPath(DATATYPE_SETTINGS_POPUP_PATH) .popupMenuGroup("Settings") .withContext(DataTypesActionContext.class) @@ -197,8 +194,7 @@ public class DataPlugin extends Plugin implements DataService { .buildAndInstall(tool); // Default settings action for composite editor components (stand-alone archive) - new ActionBuilder("Default Settings", getName()) - .sharedKeyBinding() + new ActionBuilder("Default Settings", getName()).sharedKeyBinding() .popupMenuPath(DATATYPE_SETTINGS_POPUP_PATH) .popupMenuGroup("Settings") .withContext(ComponentStandAloneActionContext.class) @@ -207,8 +203,7 @@ public class DataPlugin extends Plugin implements DataService { .buildAndInstall(tool); editDataTypeAction = - new ActionBuilder("Edit Data Type", getName()) - .popupMenuPath(EDIT_DATA_TYPE_POPUP_PATH) + new ActionBuilder("Edit Data Type", getName()).popupMenuPath(EDIT_DATA_TYPE_POPUP_PATH) .popupMenuGroup("BasicData") .withContext(ListingActionContext.class) .enabledWhen(c -> { @@ -717,7 +712,14 @@ public class DataPlugin extends Plugin implements DataService { if (data == null) { return false; } - return data.getDataType().getSettingsDefinitions().length != 0; + DataType dt = data.getDataType(); + if (dt.getSettingsDefinitions().length == 0) { + return false; + } + if (editDefaults) { + return !dt.getDefaultSettings().isImmutableSettings(); + } + return true; } private void editDefaultDataSettings(ListingActionContext context) { diff --git a/Ghidra/Framework/Docking/src/main/java/ghidra/docking/settings/Settings.java b/Ghidra/Framework/Docking/src/main/java/ghidra/docking/settings/Settings.java index 95226ef346..106e91d1dc 100644 --- a/Ghidra/Framework/Docking/src/main/java/ghidra/docking/settings/Settings.java +++ b/Ghidra/Framework/Docking/src/main/java/ghidra/docking/settings/Settings.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. @@ -21,9 +21,14 @@ package ghidra.docking.settings; * of value and how to interpret the value is done by the SettingsDefinition object. */ public interface Settings { - + static final String[] EMPTY_STRING_ARRAY = new String[0]; + /** + * {@return true if settings may not be modified} + */ + boolean isImmutableSettings(); + /** * Determine if a settings change corresponding to the specified * settingsDefinition is permitted. @@ -54,14 +59,14 @@ public interface Settings { * @return the String value for a key */ String getString(String name); - + /** * Gets the object associated with the given name * @param name the key used to retrieve a value * @return the object associated with a given key */ Object getValue(String name); - + /** * Associates the given long value with the name. * Note that an attempted setting change may be ignored if prohibited @@ -79,7 +84,7 @@ public interface Settings { * @param value the value associated with the key */ void setString(String name, String value); - + /** * Associates the given object with the name. * Note that an attempted setting change may be ignored if prohibited @@ -88,24 +93,24 @@ public interface Settings { * @param value the value to associate with the key */ void setValue(String name, Object value); - + /** * Removes any value associated with the given name * @param name the key to remove any association */ void clearSetting(String name); - + /** * Removes all name-value pairs from this settings object */ void clearAllSettings(); - + /** * Get this list of keys that currently have values associated with them * @return an array of string keys. */ String[] getNames(); - + /** * Returns true if there are no key-value pairs stored in this settings object. * This is not a reflection of the underlying default settings which may still @@ -113,7 +118,7 @@ public interface Settings { * @return true if there are no key-value pairs stored in this settings object */ boolean isEmpty(); - + /** * Returns the underlying default settings for these settings or null if there are none * @return underlying default settings or null diff --git a/Ghidra/Framework/Docking/src/main/java/ghidra/docking/settings/SettingsImpl.java b/Ghidra/Framework/Docking/src/main/java/ghidra/docking/settings/SettingsImpl.java index 9796139f88..cae5e1cd49 100644 --- a/Ghidra/Framework/Docking/src/main/java/ghidra/docking/settings/SettingsImpl.java +++ b/Ghidra/Framework/Docking/src/main/java/ghidra/docking/settings/SettingsImpl.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. @@ -72,8 +72,8 @@ public class SettingsImpl implements Settings, Serializable { this(); if (settings != null) { String[] names = settings.getNames(); - for (int i = 0; i < names.length; i++) { - map.put(names[i], settings.getValue(names[i])); + for (String name : names) { + map.put(name, settings.getValue(name)); } defaultSettings = settings.getDefaultSettings(); } @@ -100,6 +100,11 @@ public class SettingsImpl implements Settings, Serializable { this.changeSourceObj = changeSourceObj; } + @Override + public boolean isImmutableSettings() { + return immutable; + } + @Override public boolean isChangeAllowed(SettingsDefinition settingsDefinition) { if (immutable) { @@ -147,9 +152,8 @@ public class SettingsImpl implements Settings, Serializable { if (name == null) { nameStr = "s"; } - Msg.warn(SettingsImpl.class, - "Ignored invalid attempt to modify immutable " + typeStr + "component setting" + - nameStr); + Msg.warn(SettingsImpl.class, "Ignored invalid attempt to modify immutable " + typeStr + + "component setting" + nameStr); return false; } return true; @@ -212,10 +216,9 @@ public class SettingsImpl implements Settings, Serializable { @Override public String[] getNames() { String[] names = new String[map.size()]; - Iterator it = map.keySet().iterator(); int i = 0; - while (it.hasNext()) { - names[i++] = it.next(); + for (String element : map.keySet()) { + names[i++] = element; } return names; } diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/DataTypeComponentDB.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/DataTypeComponentDB.java index fba32fb942..a3c9c6cbd5 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/DataTypeComponentDB.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/DataTypeComponentDB.java @@ -460,6 +460,11 @@ class DataTypeComponentDB implements InternalDataTypeComponent { dataMgr.dataTypeChanged(getParent(), false); } + @Override + public boolean isImmutableSettings() { + return false; // NOTE: We could check to see if any editable Settings are defined + } + @Override public boolean isChangeAllowed(SettingsDefinition settingsDefinition) { if (settingsDefinition instanceof TypeDefSettingsDefinition) { diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/DataTypeSettingsDB.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/DataTypeSettingsDB.java index 66ec95c242..71626c5149 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/DataTypeSettingsDB.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/DataTypeSettingsDB.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. @@ -77,6 +77,11 @@ class DataTypeSettingsDB implements Settings { return wasLocked; } + @Override + public boolean isImmutableSettings() { + return locked; + } + @Override public boolean isChangeAllowed(SettingsDefinition settingsDefinition) { if (locked) { @@ -137,9 +142,8 @@ class DataTypeSettingsDB implements Settings { if (name == null) { nameStr = "s"; } - Msg.warn(SettingsImpl.class, - "Ignored invalid attempt to modify immutable " + typeStr + "component setting" + - nameStr); + Msg.warn(SettingsImpl.class, "Ignored invalid attempt to modify immutable " + typeStr + + "component setting" + nameStr); return false; } return true; diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/listing/Data.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/listing/Data.java index dd438a82a9..946467823f 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/listing/Data.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/listing/Data.java @@ -46,6 +46,11 @@ public interface Data extends CodeUnit, Settings { */ public Class getValueClass(); + @Override + default boolean isImmutableSettings() { + return true; // NOTE: We could check to see if any editable Settings are defined + } + /** * Returns true if this data corresponds to string data. This is determined * by the corresponding data type producing a String value. diff --git a/Ghidra/Framework/SoftwareModeling/src/test/java/ghidra/program/model/data/SettingsBuilder.java b/Ghidra/Framework/SoftwareModeling/src/test/java/ghidra/program/model/data/SettingsBuilder.java index 4dddbf5291..fbd899611a 100644 --- a/Ghidra/Framework/SoftwareModeling/src/test/java/ghidra/program/model/data/SettingsBuilder.java +++ b/Ghidra/Framework/SoftwareModeling/src/test/java/ghidra/program/model/data/SettingsBuilder.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. @@ -35,6 +35,11 @@ public class SettingsBuilder implements Settings { // nada } + @Override + public boolean isImmutableSettings() { + return false; + } + @Override public boolean isChangeAllowed(SettingsDefinition settingsDefinition) { return settings.isChangeAllowed(settingsDefinition);