Merge remote-tracking branch 'origin/GP-3547_ghidra1_DefaultSettingsFix'

This commit is contained in:
Ryan Kurtz 2025-05-29 14:37:47 -04:00
commit 48b8bc0fcc
9 changed files with 88 additions and 55 deletions

View file

@ -139,8 +139,7 @@ public enum VariableValueUtils {
} }
@Override @Override
protected Boolean evaluateLoad(Program program, PcodeOp op, protected Boolean evaluateLoad(Program program, PcodeOp op, Map<Varnode, Boolean> already) {
Map<Varnode, Boolean> already) {
return evaluateVarnode(program, op.getInput(1), already); return evaluateVarnode(program, op.getInput(1), already);
} }
@ -180,9 +179,14 @@ public enum VariableValueUtils {
this.space = space; this.space = space;
} }
@Override
public boolean isImmutableSettings() {
return true;
}
@Override @Override
public boolean isChangeAllowed(SettingsDefinition settingsDefinition) { public boolean isChangeAllowed(SettingsDefinition settingsDefinition) {
return delegate.isChangeAllowed(settingsDefinition); return false;
} }
@Override @Override
@ -473,9 +477,8 @@ public enum VariableValueUtils {
*/ */
public static boolean hasFreshUnwind(PluginTool tool, DebuggerCoordinates coordinates) { public static boolean hasFreshUnwind(PluginTool tool, DebuggerCoordinates coordinates) {
ListingUnwoundFrame innermost = locateInnermost(tool, coordinates); ListingUnwoundFrame innermost = locateInnermost(tool, coordinates);
if (innermost == null || !Objects.equals(innermost.getProgramCounter(), if (innermost == null || !Objects.equals(innermost.getProgramCounter(), getProgramCounter(
getProgramCounter(coordinates.getPlatform(), coordinates.getThread(), coordinates.getPlatform(), coordinates.getThread(), coordinates.getViewSnap()))) {
coordinates.getViewSnap()))) {
return false; return false;
} }
return true; return true;
@ -866,13 +869,12 @@ public enum VariableValueUtils {
address.isRegisterAddress()) { address.isRegisterAddress()) {
settings = new DefaultSpaceSettings(settings, language.getDefaultSpace()); settings = new DefaultSpaceSettings(settings, language.getDefaultSpace());
} }
ByteMemBufferImpl buf = ByteMemBufferImpl buf = new ByteMemBufferImpl(address, bytes, language.isBigEndian()) {
new ByteMemBufferImpl(address, bytes, language.isBigEndian()) { @Override
@Override public Memory getMemory() {
public Memory getMemory() { return coordinates.getView().getMemory();
return coordinates.getView().getMemory(); }
} };
};
return type.getRepresentation(buf, settings, bytes.length); return type.getRepresentation(buf, settings, bytes.length);
} }

View file

@ -786,12 +786,14 @@
<P>To change the default settings for a given data type:</P> <P>To change the default settings for a given data type:</P>
<OL> <OL>
<LI>Place the cursor on a data item of that type</LI> <LI>Place the cursor on a data item of that type,</LI>
<LI>Press mouse-right to bring up the popup menu</LI> <LI>Press mouse-right to bring up the popup menu,</LI>
<LI>Select <B>Data<IMG src="help/shared/arrow.gif"> Default Settings...</B> to bring up <LI>Select <B>Data<IMG src="help/shared/arrow.gif"> Default Settings...</B> to bring up
the default settings dialog</LI> 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. </LI>
</OL> </OL>
</BLOCKQUOTE> </BLOCKQUOTE>

View file

@ -158,8 +158,7 @@ public class DataPlugin extends Plugin implements DataService {
.buildAndInstall(tool); .buildAndInstall(tool);
// Data instance settings action based upon data selection in listing // Data instance settings action based upon data selection in listing
new ActionBuilder("Data Settings", getName()) new ActionBuilder("Data Settings", getName()).sharedKeyBinding()
.sharedKeyBinding()
.popupMenuPath(DATA_SETTINGS_POPUP_PATH) .popupMenuPath(DATA_SETTINGS_POPUP_PATH)
.popupMenuGroup("Settings") .popupMenuGroup("Settings")
.withContext(ListingActionContext.class) .withContext(ListingActionContext.class)
@ -168,8 +167,7 @@ public class DataPlugin extends Plugin implements DataService {
.buildAndInstall(tool); .buildAndInstall(tool);
// Default settings action based upon data selection in listing // Default settings action based upon data selection in listing
new ActionBuilder("Default Settings", getName()) new ActionBuilder("Default Settings", getName()).sharedKeyBinding()
.sharedKeyBinding()
.popupMenuPath(DEFAULT_SETTINGS_POPUP_PATH) .popupMenuPath(DEFAULT_SETTINGS_POPUP_PATH)
.popupMenuGroup("Settings") .popupMenuGroup("Settings")
.withContext(ListingActionContext.class) .withContext(ListingActionContext.class)
@ -178,8 +176,7 @@ public class DataPlugin extends Plugin implements DataService {
.buildAndInstall(tool); .buildAndInstall(tool);
// Default settings action for selected datatypes from datatype manager // Default settings action for selected datatypes from datatype manager
new ActionBuilder("Default Settings", getName()) new ActionBuilder("Default Settings", getName()).sharedKeyBinding()
.sharedKeyBinding()
.popupMenuPath(DATATYPE_SETTINGS_POPUP_PATH) .popupMenuPath(DATATYPE_SETTINGS_POPUP_PATH)
.popupMenuGroup("Settings") .popupMenuGroup("Settings")
.withContext(DataTypesActionContext.class) .withContext(DataTypesActionContext.class)
@ -197,8 +194,7 @@ public class DataPlugin extends Plugin implements DataService {
.buildAndInstall(tool); .buildAndInstall(tool);
// Default settings action for composite editor components (stand-alone archive) // Default settings action for composite editor components (stand-alone archive)
new ActionBuilder("Default Settings", getName()) new ActionBuilder("Default Settings", getName()).sharedKeyBinding()
.sharedKeyBinding()
.popupMenuPath(DATATYPE_SETTINGS_POPUP_PATH) .popupMenuPath(DATATYPE_SETTINGS_POPUP_PATH)
.popupMenuGroup("Settings") .popupMenuGroup("Settings")
.withContext(ComponentStandAloneActionContext.class) .withContext(ComponentStandAloneActionContext.class)
@ -207,8 +203,7 @@ public class DataPlugin extends Plugin implements DataService {
.buildAndInstall(tool); .buildAndInstall(tool);
editDataTypeAction = editDataTypeAction =
new ActionBuilder("Edit Data Type", getName()) new ActionBuilder("Edit Data Type", getName()).popupMenuPath(EDIT_DATA_TYPE_POPUP_PATH)
.popupMenuPath(EDIT_DATA_TYPE_POPUP_PATH)
.popupMenuGroup("BasicData") .popupMenuGroup("BasicData")
.withContext(ListingActionContext.class) .withContext(ListingActionContext.class)
.enabledWhen(c -> { .enabledWhen(c -> {
@ -717,7 +712,14 @@ public class DataPlugin extends Plugin implements DataService {
if (data == null) { if (data == null) {
return false; 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) { private void editDefaultDataSettings(ListingActionContext context) {

View file

@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 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. * of value and how to interpret the value is done by the SettingsDefinition object.
*/ */
public interface Settings { public interface Settings {
static final String[] EMPTY_STRING_ARRAY = new String[0]; 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 * Determine if a settings change corresponding to the specified
* settingsDefinition is permitted. * settingsDefinition is permitted.
@ -54,14 +59,14 @@ public interface Settings {
* @return the String value for a key * @return the String value for a key
*/ */
String getString(String name); String getString(String name);
/** /**
* Gets the object associated with the given name * Gets the object associated with the given name
* @param name the key used to retrieve a value * @param name the key used to retrieve a value
* @return the object associated with a given key * @return the object associated with a given key
*/ */
Object getValue(String name); Object getValue(String name);
/** /**
* Associates the given long value with the name. * Associates the given long value with the name.
* Note that an attempted setting change may be ignored if prohibited * 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 * @param value the value associated with the key
*/ */
void setString(String name, String value); void setString(String name, String value);
/** /**
* Associates the given object with the name. * Associates the given object with the name.
* Note that an attempted setting change may be ignored if prohibited * 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 * @param value the value to associate with the key
*/ */
void setValue(String name, Object value); void setValue(String name, Object value);
/** /**
* Removes any value associated with the given name * Removes any value associated with the given name
* @param name the key to remove any association * @param name the key to remove any association
*/ */
void clearSetting(String name); void clearSetting(String name);
/** /**
* Removes all name-value pairs from this settings object * Removes all name-value pairs from this settings object
*/ */
void clearAllSettings(); void clearAllSettings();
/** /**
* Get this list of keys that currently have values associated with them * Get this list of keys that currently have values associated with them
* @return an array of string keys. * @return an array of string keys.
*/ */
String[] getNames(); String[] getNames();
/** /**
* Returns true if there are no key-value pairs stored in this settings object. * 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 * 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 * @return true if there are no key-value pairs stored in this settings object
*/ */
boolean isEmpty(); boolean isEmpty();
/** /**
* Returns the underlying default settings for these settings or null if there are none * Returns the underlying default settings for these settings or null if there are none
* @return underlying default settings or null * @return underlying default settings or null

View file

@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -72,8 +72,8 @@ public class SettingsImpl implements Settings, Serializable {
this(); this();
if (settings != null) { if (settings != null) {
String[] names = settings.getNames(); String[] names = settings.getNames();
for (int i = 0; i < names.length; i++) { for (String name : names) {
map.put(names[i], settings.getValue(names[i])); map.put(name, settings.getValue(name));
} }
defaultSettings = settings.getDefaultSettings(); defaultSettings = settings.getDefaultSettings();
} }
@ -100,6 +100,11 @@ public class SettingsImpl implements Settings, Serializable {
this.changeSourceObj = changeSourceObj; this.changeSourceObj = changeSourceObj;
} }
@Override
public boolean isImmutableSettings() {
return immutable;
}
@Override @Override
public boolean isChangeAllowed(SettingsDefinition settingsDefinition) { public boolean isChangeAllowed(SettingsDefinition settingsDefinition) {
if (immutable) { if (immutable) {
@ -147,9 +152,8 @@ public class SettingsImpl implements Settings, Serializable {
if (name == null) { if (name == null) {
nameStr = "s"; nameStr = "s";
} }
Msg.warn(SettingsImpl.class, Msg.warn(SettingsImpl.class, "Ignored invalid attempt to modify immutable " + typeStr +
"Ignored invalid attempt to modify immutable " + typeStr + "component setting" + "component setting" + nameStr);
nameStr);
return false; return false;
} }
return true; return true;
@ -212,10 +216,9 @@ public class SettingsImpl implements Settings, Serializable {
@Override @Override
public String[] getNames() { public String[] getNames() {
String[] names = new String[map.size()]; String[] names = new String[map.size()];
Iterator<String> it = map.keySet().iterator();
int i = 0; int i = 0;
while (it.hasNext()) { for (String element : map.keySet()) {
names[i++] = it.next(); names[i++] = element;
} }
return names; return names;
} }

View file

@ -460,6 +460,11 @@ class DataTypeComponentDB implements InternalDataTypeComponent {
dataMgr.dataTypeChanged(getParent(), false); dataMgr.dataTypeChanged(getParent(), false);
} }
@Override
public boolean isImmutableSettings() {
return false; // NOTE: We could check to see if any editable Settings are defined
}
@Override @Override
public boolean isChangeAllowed(SettingsDefinition settingsDefinition) { public boolean isChangeAllowed(SettingsDefinition settingsDefinition) {
if (settingsDefinition instanceof TypeDefSettingsDefinition) { if (settingsDefinition instanceof TypeDefSettingsDefinition) {

View file

@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -77,6 +77,11 @@ class DataTypeSettingsDB implements Settings {
return wasLocked; return wasLocked;
} }
@Override
public boolean isImmutableSettings() {
return locked;
}
@Override @Override
public boolean isChangeAllowed(SettingsDefinition settingsDefinition) { public boolean isChangeAllowed(SettingsDefinition settingsDefinition) {
if (locked) { if (locked) {
@ -137,9 +142,8 @@ class DataTypeSettingsDB implements Settings {
if (name == null) { if (name == null) {
nameStr = "s"; nameStr = "s";
} }
Msg.warn(SettingsImpl.class, Msg.warn(SettingsImpl.class, "Ignored invalid attempt to modify immutable " + typeStr +
"Ignored invalid attempt to modify immutable " + typeStr + "component setting" + "component setting" + nameStr);
nameStr);
return false; return false;
} }
return true; return true;

View file

@ -46,6 +46,11 @@ public interface Data extends CodeUnit, Settings {
*/ */
public Class<?> getValueClass(); 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 * Returns true if this data corresponds to string data. This is determined
* by the corresponding data type producing a String value. * by the corresponding data type producing a String value.

View file

@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -35,6 +35,11 @@ public class SettingsBuilder implements Settings {
// nada // nada
} }
@Override
public boolean isImmutableSettings() {
return false;
}
@Override @Override
public boolean isChangeAllowed(SettingsDefinition settingsDefinition) { public boolean isChangeAllowed(SettingsDefinition settingsDefinition) {
return settings.isChangeAllowed(settingsDefinition); return settings.isChangeAllowed(settingsDefinition);