diff --git a/Ghidra/Features/Base/src/main/help/help/topics/DataTypeManagerPlugin/data_type_manager_description.htm b/Ghidra/Features/Base/src/main/help/help/topics/DataTypeManagerPlugin/data_type_manager_description.htm index 4b328fccd8..f072007660 100644 --- a/Ghidra/Features/Base/src/main/help/help/topics/DataTypeManagerPlugin/data_type_manager_description.htm +++ b/Ghidra/Features/Base/src/main/help/help/topics/DataTypeManagerPlugin/data_type_manager_description.htm @@ -69,7 +69,7 @@
- The source archive must be editable in order to commit File archives must be open for editing and project
archives that are under version control must be checked-out.
Any data type dependencies for a comitted
+ data type, which do not already have a source archive, will become associated to the same
+ source archive.
@@ -55,28 +51,28 @@- - Built-in archive data types +- Built-in archive data types - - Program data types +- Program data types - - Project Archive +- Project Archive @@ -91,7 +87,7 @@ - - File Archive +- File Archive - - Indicates the archive is modifiable by you and possibly by + - Indicates the archive is modifiable by you and possibly by others in your shared project @@ -99,14 +95,14 @@- - Indicates the archive is currently modifiable only by you +- Indicates the archive is currently modifiable only by you @@ -114,7 +110,7 @@ - - Indicates the archive is out of date (someone has checked + - Indicates the archive is out of date (someone has checked changes for this archive into the repository) - - Indicates the archive is hijacked (modified without being + - Indicates the archive is hijacked (modified without being checked out) @@ -153,7 +149,7 @@- - Indicates the archive has datatypes that need updating and + - Indicates the archive has datatypes that need updating and datatypes that need to be committed. @@ -170,63 +166,63 @@- - Category +- Category - - Built-in data type +- Built-in data type - - Structure +- Structure - - Union +- Union - - Typedef +- Typedef - - Function Definition +- Function Definition - - Enum +- Enum - - Pointer +- Pointer @@ -241,7 +237,7 @@ - - Favorite +- Favorite - - Indicates the data type has changes that need to be committed + - Indicates the data type has changes that need to be committed to the source archive @@ -249,7 +245,7 @@- - Indicates the data type has been updated in the source archive + - Indicates the data type has been updated in the source archive and needs to be updated locally. @@ -257,7 +253,7 @@- - Indicates the data type has changed both in this archive and + - Indicates the data type has changed both in this archive and in the source archive. (conflict) @@ -266,7 +262,9 @@
- - Indicates the data type is missing in the source archive. +- Indicates the data type is missing in the source archive. It is important to + note that this determination ibased upon a matching Universal ID and not just + its pathname. @@ -409,7 +407,7 @@ Archive...
-This action will launch a project data type archive chooser that can be + This action will launch a project data type archive chooser that can be used to open an existing project archive. Project data type archives live in the project and can be seen in the Ghidra Project Window. Project data type @@ -432,7 +430,7 @@ Archive... -
This action is used to create a new project data type archive. A project + This action is used to create a new project data type archive. A project window browser will be launched for choosing a location in the project and a name for the new project archive. @@ -501,7 +499,7 @@ Paths...
-This action will launch a dialog that + This action will launch a dialog that can be used to add, remove, or reorder the directories used for searching for a file archive. Ghidra programs only store the name of the archive. Each directory in the archive path is searched in order, looking for a file diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datamgr/DataTypeSynchronizer.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datamgr/DataTypeSynchronizer.java index 97f6561be6..e513dfc3d9 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datamgr/DataTypeSynchronizer.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datamgr/DataTypeSynchronizer.java @@ -116,6 +116,15 @@ public class DataTypeSynchronizer { } public static void commitAssumingTransactionsOpen(DataTypeManager sourceDTM, DataType refDT) { + + // Must refresh associations of refDt and its dependencies to ensure that any + // non-sourced datatype is properly associated to the sourceDTM + DataTypeManager refDTM = refDT.getDataTypeManager(); + SourceArchive sourceArchive = refDTM.getSourceArchive(sourceDTM.getUniversalID()); + refDTM.associateDataTypeWithArchive(refDT, sourceArchive); + + // Perform commit of changes by re-resolving and performing additional updates + // not handled by resolve. long lastChangeTime = refDT.getLastChangeTime(); DataType sourceDT = sourceDTM.resolve(refDT, DataTypeConflictHandler.REPLACE_HANDLER); if (!namesAreEquivalent(refDT, sourceDT)) { diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/DataTypeManagerDB.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/DataTypeManagerDB.java index db16c2b1d4..c252500981 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/DataTypeManagerDB.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/DataTypeManagerDB.java @@ -445,9 +445,8 @@ abstract public class DataTypeManagerDB implements DataTypeManager { versionExc = e.combine(versionExc); } try { - functionDefAdapter = - FunctionDefinitionDBAdapter.getAdapter(dbHandle, openMode, tablePrefix, - callingConventionAdapter, monitor); + functionDefAdapter = FunctionDefinitionDBAdapter.getAdapter(dbHandle, openMode, + tablePrefix, callingConventionAdapter, monitor); } catch (VersionException e) { versionExc = e.combine(versionExc); @@ -460,9 +459,8 @@ abstract public class DataTypeManagerDB implements DataTypeManager { versionExc = e.combine(versionExc); } try { - settingsAdapter = - SettingsDBAdapter.getAdapter(tablePrefix + SETTINGS_TABLE_NAME, dbHandle, openMode, - null, monitor); + settingsAdapter = SettingsDBAdapter.getAdapter(tablePrefix + SETTINGS_TABLE_NAME, + dbHandle, openMode, null, monitor); } catch (VersionException e) { versionExc = e.combine(versionExc); @@ -499,7 +497,7 @@ abstract public class DataTypeManagerDB implements DataTypeManager { catch (VersionException e) { versionExc = e.combine(versionExc); } - + try { initializeOtherAdapters(openMode, monitor); } @@ -513,7 +511,7 @@ abstract public class DataTypeManagerDB implements DataTypeManager { updateManagerAndAppVersion(openMode); } - + /** * Initialize other DB adapters after base implementation adapters has been * initialized. @@ -548,9 +546,7 @@ abstract public class DataTypeManagerDB implements DataTypeManager { */ private void initializedParentChildTable() { buildSortedDataTypeList(); - Iterator it = sortedDataTypes.iterator(); - while (it.hasNext()) { - DataType dt = it.next(); + for (DataType dt : sortedDataTypes) { if (dt instanceof Array) { ((Array) dt).getDataType().addParent(dt); } @@ -765,9 +761,8 @@ abstract public class DataTypeManagerDB implements DataTypeManager { } lock.acquire(); try { - Set previouslyUsedSet = previouslyUsedSettingsValuesMap - .computeIfAbsent(settingsDefinition.getStorageKey(), - n -> generateSuggestions(settingsDefinition)); + Set previouslyUsedSet = previouslyUsedSettingsValuesMap.computeIfAbsent( + settingsDefinition.getStorageKey(), n -> generateSuggestions(settingsDefinition)); // Last-minute additions are not cached since suggested values may change Set set = new TreeSet<>(previouslyUsedSet); // copy before updating settingsDefinition.addPreferredValues(this, set); @@ -1866,8 +1861,8 @@ abstract public class DataTypeManagerDB implements DataTypeManager { replacementDt.setLastChangeTime(lastChangeTime); } catch (Exception e) { - Msg.error(this, "Unable to set the name to " + existingDt.getName() + - "on " + replacementDt + " while replacing the original datatype", e); + Msg.error(this, "Unable to set the name to " + existingDt.getName() + "on " + + replacementDt + " while replacing the original datatype", e); } } CategoryPath path = existingDt.getCategoryPath(); @@ -1878,8 +1873,8 @@ abstract public class DataTypeManagerDB implements DataTypeManager { } catch (Exception e) { // not sure what to do here - Msg.error(this, "Unable to set the CatagoryPath to " + path + - "on " + replacementDt + " while replacing the original datatype", e); + Msg.error(this, "Unable to set the CatagoryPath to " + path + "on " + + replacementDt + " while replacing the original datatype", e); } } return replacementDt; @@ -1929,11 +1924,7 @@ abstract public class DataTypeManagerDB implements DataTypeManager { } else { buildSortedDataTypeList(); - // make copy of sortedDataTypes list before iterating as dt.dataTypeReplaced may - // call back into this class and cause a modification to the sortedDataTypes list. - Iterator it = new ArrayList<>(sortedDataTypes).iterator(); - while (it.hasNext()) { - DataType dt = it.next(); + for (DataType dt : new ArrayList<>(sortedDataTypes)) { dt.dataTypeReplaced(existingDt, newDt); } } @@ -2229,9 +2220,7 @@ abstract public class DataTypeManagerDB implements DataTypeManager { deletedIds.addFirst(l); } - Iterator it = deletedIds.iterator(); - while (it.hasNext()) { - Long l = it.next(); + for (Long l : deletedIds) { deleteDataType(l.longValue()); } @@ -2280,10 +2269,8 @@ abstract public class DataTypeManagerDB implements DataTypeManager { throw new IllegalArgumentException( "The given datatype must exist in this DataTypeManager"); } - if (!datatype.getSourceArchive().equals(getLocalSourceArchive())) { - return; - } - if (datatype.getSourceArchive().equals(archive)) { + SourceArchive currentSource = datatype.getSourceArchive(); + if (!currentSource.equals(getLocalSourceArchive()) && !currentSource.equals(archive)) { return; } resolveSourceArchive(archive); @@ -2557,8 +2544,7 @@ abstract public class DataTypeManagerDB implements DataTypeManager { @Override public DataType getDataType(CategoryPath path, String name) { - if (CategoryPath.ROOT.equals(path) && - name.equals(DataType.DEFAULT.getName())) { + if (CategoryPath.ROOT.equals(path) && name.equals(DataType.DEFAULT.getName())) { return DataType.DEFAULT; } Category category = getCategory(path); @@ -2960,16 +2946,15 @@ abstract public class DataTypeManagerDB implements DataTypeManager { newDataType = createBuiltIn(builtInDataType, cat); } else if (dt instanceof StructureInternal structure) { - newDataType = createStructure(structure, name, cat, sourceArchiveIdValue, - id.getValue()); + newDataType = + createStructure(structure, name, cat, sourceArchiveIdValue, id.getValue()); } else if (dt instanceof TypeDef typedef) { newDataType = createTypeDef(typedef, name, cat, sourceArchiveIdValue, id.getValue()); } else if (dt instanceof UnionInternal union) { - newDataType = - createUnion(union, name, cat, sourceArchiveIdValue, id.getValue()); + newDataType = createUnion(union, name, cat, sourceArchiveIdValue, id.getValue()); } else if (dt instanceof Enum enumm) { newDataType = createEnum(enumm, name, cat, sourceArchiveIdValue, id.getValue()); @@ -2995,8 +2980,7 @@ abstract public class DataTypeManagerDB implements DataTypeManager { } private Structure createStructure(StructureInternal struct, String name, CategoryDB category, - long sourceArchiveIdValue, long universalIdValue) - throws IOException { + long sourceArchiveIdValue, long universalIdValue) throws IOException { try { if (name == null || name.length() == 0) { throw new IllegalArgumentException("Data type must have a valid name"); @@ -3007,9 +2991,9 @@ abstract public class DataTypeManagerDB implements DataTypeManager { len = 0; } DBRecord record = compositeAdapter.createRecord(name, struct.getDescription(), false, - category.getID(), len, -1, sourceArchiveIdValue, - universalIdValue, struct.getLastChangeTime(), - struct.getStoredPackingValue(), struct.getStoredMinimumAlignment()); + category.getID(), len, -1, sourceArchiveIdValue, universalIdValue, + struct.getLastChangeTime(), struct.getStoredPackingValue(), + struct.getStoredMinimumAlignment()); StructureDB structDB = new StructureDB(this, dtCache, compositeAdapter, componentAdapter, record); @@ -3038,8 +3022,7 @@ abstract public class DataTypeManagerDB implements DataTypeManager { } private TypeDef createTypeDef(TypeDef typedef, String name, Category cat, - long sourceArchiveIdValue, long universalIdValue) - throws IOException { + long sourceArchiveIdValue, long universalIdValue) throws IOException { if (name == null || name.length() == 0) { throw new IllegalArgumentException("Data type must have a valid name"); } @@ -3067,16 +3050,15 @@ abstract public class DataTypeManagerDB implements DataTypeManager { } private Union createUnion(UnionInternal union, String name, CategoryDB category, - long sourceArchiveIdValue, long universalIdValue) - throws IOException { + long sourceArchiveIdValue, long universalIdValue) throws IOException { if (name == null || name.length() == 0) { throw new IllegalArgumentException("Data type must have a valid name"); } try { creatingDataType++; DBRecord record = compositeAdapter.createRecord(name, null, true, category.getID(), 0, - -1, sourceArchiveIdValue, universalIdValue, - union.getLastChangeTime(), union.getStoredPackingValue(), union.getStoredMinimumAlignment()); + -1, sourceArchiveIdValue, universalIdValue, union.getLastChangeTime(), + union.getStoredPackingValue(), union.getStoredMinimumAlignment()); UnionDB unionDB = new UnionDB(this, dtCache, compositeAdapter, componentAdapter, record); @@ -3110,7 +3092,8 @@ abstract public class DataTypeManagerDB implements DataTypeManager { long enumID = record.getKey(); String[] enumNames = enumm.getNames(); for (String enumName : enumNames) { - enumValueAdapter.createRecord(enumID, enumName, enumm.getValue(enumName), enumm.getComment(enumName)); + enumValueAdapter.createRecord(enumID, enumName, enumm.getValue(enumName), + enumm.getComment(enumName)); } EnumDB enumDB = new EnumDB(this, dtCache, enumAdapter, enumValueAdapter, record); return enumDB; @@ -3318,14 +3301,12 @@ abstract public class DataTypeManagerDB implements DataTypeManager { } try { creatingDataType++; - byte callingConventionId = - callingConventionAdapter.getCallingConventionId(funDef.getCallingConventionName(), - cc -> callingConventionNameAdded(cc)); - DBRecord record = - functionDefAdapter.createRecord(name, funDef.getComment(), cat.getID(), - DEFAULT_DATATYPE_ID, funDef.hasNoReturn(), funDef.hasVarArgs(), - callingConventionId, sourceArchiveIdValue, universalIdValue, - funDef.getLastChangeTime()); + byte callingConventionId = callingConventionAdapter.getCallingConventionId( + funDef.getCallingConventionName(), cc -> callingConventionNameAdded(cc)); + DBRecord record = functionDefAdapter.createRecord(name, funDef.getComment(), + cat.getID(), DEFAULT_DATATYPE_ID, funDef.hasNoReturn(), funDef.hasVarArgs(), + callingConventionId, sourceArchiveIdValue, universalIdValue, + funDef.getLastChangeTime()); FunctionDefinitionDB funDefDb = new FunctionDefinitionDB(this, dtCache, functionDefAdapter, paramAdapter, record); @@ -3344,7 +3325,7 @@ abstract public class DataTypeManagerDB implements DataTypeManager { creatingDataType--; } } - + class DataTypeIterator implements Iterator { private RecordIterator it; private T nextDataType; @@ -4192,12 +4173,10 @@ abstract public class DataTypeManagerDB implements DataTypeManager { * @param monitor task monitor * @throws CancelledException if task cancelled */ - protected void doSourceArchiveUpdates(TaskMonitor monitor) - throws CancelledException { + protected void doSourceArchiveUpdates(TaskMonitor monitor) throws CancelledException { SourceArchiveUpgradeMap upgradeMap = new SourceArchiveUpgradeMap(); for (SourceArchive sourceArchive : getSourceArchives()) { - SourceArchive mappedSourceArchive = - upgradeMap.getMappedSourceArchive(sourceArchive); + SourceArchive mappedSourceArchive = upgradeMap.getMappedSourceArchive(sourceArchive); if (mappedSourceArchive != null) { replaceSourceArchive(sourceArchive, mappedSourceArchive); } @@ -4241,7 +4220,7 @@ abstract public class DataTypeManagerDB implements DataTypeManager { lock.release(); } } - + private void doCompositeFixup(TaskMonitor monitor) throws CancelledException, IOException { // NOTE: Any composite could be indirectly affected by a component size change diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/BuiltInDataTypeManager.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/BuiltInDataTypeManager.java index 094939e06a..49e38f97c5 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/BuiltInDataTypeManager.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/BuiltInDataTypeManager.java @@ -69,6 +69,7 @@ public final class BuiltInDataTypeManager extends StandAloneDataTypeManager { initialize(); } + @Override protected final void setProgramArchitecture(ProgramArchitecture programArchitecture, VariableStorageManager variableStorageMgr, boolean force, TaskMonitor monitor) throws IOException, CancelledException { @@ -168,9 +169,8 @@ public final class BuiltInDataTypeManager extends StandAloneDataTypeManager { if (dataType instanceof BuiltInDataType) { return DataTypeManager.BUILT_IN_ARCHIVE_UNIVERSAL_ID; } - throw new IllegalArgumentException( - "Only Built-in data types can be resolved by the " + getClass().getSimpleName() + - " manager."); + throw new IllegalArgumentException("Only Built-in data types can be resolved by the " + + getClass().getSimpleName() + " manager."); } @Override diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/DataTypeManager.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/DataTypeManager.java index 3d806e962c..6e3d7811f6 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/DataTypeManager.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/DataTypeManager.java @@ -509,7 +509,9 @@ public interface DataTypeManager { public SourceArchive getLocalSourceArchive(); /** - * Change the given data type so that its source archive is the given archive + * Change the given data type and its dependencies so thier source archive is set to + * given archive. Only those data types not already associated with a source archive + * will be changed. * * @param datatype the type * @param archive the archive