mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 18:29:37 +02:00
Merge remote-tracking branch 'origin/GP-5205_ghidra1_ProgramUserDataIssues' into Ghidra_11.3
This commit is contained in:
commit
afe96c0309
4 changed files with 78 additions and 6 deletions
|
@ -583,12 +583,16 @@ public abstract class DomainObjectAdapterDB extends DomainObjectAdapter implemen
|
|||
}
|
||||
|
||||
DomainObjectAdapterDB userData = getUserData();
|
||||
if (userData != null && userData.isChanged() && (getDomainFile() instanceof GhidraFile)) {
|
||||
if (canSave() && userData != null && userData.isChanged() &&
|
||||
(getDomainFile() instanceof GhidraFile)) {
|
||||
// Only save user data if this domain object was open for update and the
|
||||
// user data was modified.
|
||||
try {
|
||||
userData.prepareToSave();
|
||||
userData.save(null, TaskMonitor.DUMMY);
|
||||
}
|
||||
catch (CancelledException e) {
|
||||
// ignore
|
||||
}
|
||||
catch (IOException e) {
|
||||
Msg.warn(this, "Failed to save user data for: " + getDomainFile().getName());
|
||||
|
|
|
@ -28,6 +28,7 @@ import ghidra.framework.model.ChangeSet;
|
|||
import ghidra.framework.model.DomainObject;
|
||||
import ghidra.framework.store.*;
|
||||
import ghidra.framework.store.local.LocalDatabaseItem;
|
||||
import ghidra.program.model.lang.LanguageNotFoundException;
|
||||
import ghidra.util.InvalidNameException;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
|
@ -232,9 +233,25 @@ public class ProgramContentHandler extends DBWithUserDataContentHandler<ProgramD
|
|||
DBHandle userDbh =
|
||||
openAssociatedUserFile(programItem.getFileID(), PROGRAM_CONTENT_TYPE, userfs, monitor);
|
||||
if (userDbh != null) {
|
||||
return new ProgramUserDataDB(userDbh, program, monitor);
|
||||
boolean success = false;
|
||||
try {
|
||||
ProgramUserDataDB data = new ProgramUserDataDB(userDbh, program, monitor);
|
||||
success = true;
|
||||
return data;
|
||||
}
|
||||
return new ProgramUserDataDB(program);
|
||||
catch (LanguageNotFoundException | IllegalStateException e) {
|
||||
// Ignore - delete to make way for new one
|
||||
}
|
||||
finally {
|
||||
if (!success) {
|
||||
userDbh.close();
|
||||
Msg.debug(this, "Removing incompatible program user data file for " +
|
||||
programItem.getPathName());
|
||||
removeUserDataFile(programItem, userfs);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null; // will be created by ProgramDB when modified
|
||||
}
|
||||
|
||||
private void recoverChangeSet(ProgramDB program, DBHandle dbh) throws IOException {
|
||||
|
|
|
@ -1910,8 +1910,12 @@ public class ProgramDB extends DomainObjectAdapterDB implements Program, ChangeM
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void setChanged(boolean b) {
|
||||
super.setChanged(b);
|
||||
protected void setChanged(boolean state) {
|
||||
super.setChanged(state);
|
||||
if (!state && !dbh.isChanged()) {
|
||||
// language upgrade has already been completed
|
||||
languageUpgradeTranslator = null;
|
||||
}
|
||||
}
|
||||
|
||||
void setChangeSet(ProgramDBChangeSet changeSet) {
|
||||
|
@ -2369,6 +2373,12 @@ public class ProgramDB extends DomainObjectAdapterDB implements Program, ChangeM
|
|||
|
||||
@Override
|
||||
protected void close() {
|
||||
if (changed && languageUpgradeTranslator != null) {
|
||||
// Prevent user data from being saved if program and user data
|
||||
// have gone through a major language upgrade and the program
|
||||
// was not saved.
|
||||
programUserData.setChanged(false);
|
||||
}
|
||||
super.close();
|
||||
intRangePropertyMap.clear();
|
||||
addrSetPropertyMap.clear();
|
||||
|
|
|
@ -119,6 +119,11 @@ class ProgramUserDataDB extends DomainObjectAdapterDB implements ProgramUserData
|
|||
return program.getName() + "_UserData";
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new program user data store.
|
||||
* @param program related program
|
||||
* @throws IOException if an IO error occurs
|
||||
*/
|
||||
public ProgramUserDataDB(ProgramDB program) throws IOException {
|
||||
super(new DBHandle(), getName(program), 500, program);
|
||||
this.program = program;
|
||||
|
@ -157,8 +162,22 @@ class ProgramUserDataDB extends DomainObjectAdapterDB implements ProgramUserData
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Open existing program user data store.
|
||||
* If a major language change is detected the instance will automatically attempt to upgrade
|
||||
* its internal address map.
|
||||
* @param dbh user data storage DB handle
|
||||
* @param program related program
|
||||
* @param monitor task monitor
|
||||
* @throws IOException if an IO error occurs
|
||||
* @throws VersionException if a DB version error occurs
|
||||
* @throws LanguageNotFoundException if language was not found
|
||||
* @throws CancelledException if instantiation was cancelled
|
||||
* @throws IllegalStateException if data store is bad or incmopatible with program
|
||||
*/
|
||||
public ProgramUserDataDB(DBHandle dbh, ProgramDB program, TaskMonitor monitor)
|
||||
throws IOException, VersionException, LanguageNotFoundException, CancelledException {
|
||||
throws IOException, VersionException, LanguageNotFoundException, CancelledException,
|
||||
IllegalStateException {
|
||||
|
||||
super(dbh, getName(program), 500, program);
|
||||
this.program = program;
|
||||
|
@ -200,6 +219,9 @@ class ProgramUserDataDB extends DomainObjectAdapterDB implements ProgramUserData
|
|||
upgradeDatabase();
|
||||
|
||||
if (languageVersionExc != null) {
|
||||
if (languageUpgradeTranslator == null) {
|
||||
throw new LanguageNotFoundException(languageID + ":" + languageVersion);
|
||||
}
|
||||
try {
|
||||
setLanguage(languageUpgradeTranslator, monitor);
|
||||
addressMap.memoryMapChanged(program.getMemory());
|
||||
|
@ -212,6 +234,16 @@ class ProgramUserDataDB extends DomainObjectAdapterDB implements ProgramUserData
|
|||
}
|
||||
}
|
||||
|
||||
if (!program.getLanguageID().equals(languageID)) {
|
||||
throw new IllegalStateException(
|
||||
"User data and program have inconsistent language ID");
|
||||
}
|
||||
|
||||
if (program.getLanguage().getVersion() != languageVersion) {
|
||||
throw new IllegalStateException(
|
||||
"User data language version does not match program's");
|
||||
}
|
||||
|
||||
endTransaction(id, true);
|
||||
changed = false;
|
||||
clearUndo(false);
|
||||
|
@ -431,6 +463,10 @@ class ProgramUserDataDB extends DomainObjectAdapterDB implements ProgramUserData
|
|||
record.setString(VALUE_COL, languageID.getIdAsString());
|
||||
table.putRecord(record);
|
||||
|
||||
record = SCHEMA.createRecord(new StringField(LANGUAGE_VERSION));
|
||||
record.setString(VALUE_COL, Integer.toString(languageVersion));
|
||||
table.putRecord(record);
|
||||
|
||||
setChanged(true);
|
||||
clearCache(true);
|
||||
|
||||
|
@ -451,6 +487,11 @@ class ProgramUserDataDB extends DomainObjectAdapterDB implements ProgramUserData
|
|||
return dbh.canUpdate();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setChanged(boolean b) {
|
||||
super.setChanged(b);
|
||||
}
|
||||
|
||||
private PropertyMap<?> getPropertyMap(String owner, String propertyName, int propertyType,
|
||||
Class<?> saveableClass, boolean create) throws PropertyTypeMismatchException {
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue