Skip to content

Commit 687ce7f

Browse files
committed
GT-3531 corrected DomainFile.isVersioned() for checked-out file.
Revised language upgrade support to facilitate optional context reset.
1 parent 560ceb4 commit 687ce7f

File tree

4 files changed

+54
-16
lines changed

4 files changed

+54
-16
lines changed

Ghidra/Framework/Project/src/main/java/ghidra/framework/data/GhidraFileData.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -580,7 +580,7 @@ boolean isReadOnly() {
580580
boolean isVersioned() {
581581
synchronized (fileSystem) {
582582
if (versionedFolderItem == null) {
583-
return false;
583+
return isCheckedOut();
584584
}
585585
return !isHijacked();
586586
}

Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/ProgramDB.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ public ProgramDB(DBHandle dbh, int openMode, TaskMonitor monitor, Object consume
284284
if (monitor == null) {
285285
monitor = TaskMonitorAdapter.DUMMY;
286286
}
287-
287+
288288
boolean success = false;
289289
try {
290290
int id = startTransaction("create program");
@@ -2284,8 +2284,9 @@ public void setLanguage(Language newLanguage, CompilerSpecID newCompilerSpecID,
22842284
* Translate language
22852285
* @param translator language translator, if null only re-disassembly will occur.
22862286
* @param newCompilerSpecID new compiler specification which corresponds to new language, may be null.
2287-
* @param monitor
2288-
* @throws LockException
2287+
* @param forceRedisassembly if true a redisassembly will be forced even if not required
2288+
* @param monitor task monitor
2289+
* @throws LockException if exclusive access is missing
22892290
*/
22902291
public void setLanguage(LanguageTranslator translator, CompilerSpecID newCompilerSpecID,
22912292
boolean forceRedisassembly, TaskMonitor monitor) throws LockException {
@@ -2296,7 +2297,7 @@ public void setLanguage(LanguageTranslator translator, CompilerSpecID newCompile
22962297
try {
22972298
setEventsEnabled(false);
22982299
try {
2299-
boolean notifyCodeManager = true;
2300+
boolean redisassemblyRequired = true;
23002301
int oldLanguageVersion = languageVersion;
23012302
int oldLanguageMinorVersion = languageMinorVersion;
23022303
if (translator != null) {
@@ -2311,7 +2312,7 @@ public void setLanguage(LanguageTranslator translator, CompilerSpecID newCompile
23112312
}
23122313
else if (!forceRedisassembly && language.getVersion() == languageVersion &&
23132314
language.getMinorVersion() == languageMinorVersion) {
2314-
notifyCodeManager = false; // compiler spec change only
2315+
redisassemblyRequired = false; // compiler spec change only
23152316
Msg.info(this, "Setting compiler spec for Program " + getName() + ": " +
23162317
compilerSpecID + " -> " + newCompilerSpecID);
23172318
}
@@ -2350,15 +2351,14 @@ else if (!forceRedisassembly && language.getVersion() == languageVersion &&
23502351
monitor.setProgress(0);
23512352
ProgramRegisterContextDB contextMgr =
23522353
(ProgramRegisterContextDB) getProgramContext();
2353-
if (translator != null) {
2354+
if (redisassemblyRequired) {
23542355
contextMgr.setLanguage(translator, compilerSpec, memoryManager, monitor);
23552356
}
23562357
else {
2357-
// force re-initialization
23582358
contextMgr.initializeDefaultValues(language, compilerSpec);
23592359
}
23602360

2361-
if (notifyCodeManager) {
2361+
if (redisassemblyRequired) {
23622362
Disassembler.clearUnimplementedPcodeWarnings(this, null, monitor);
23632363
repairContext(oldLanguageVersion, oldLanguageMinorVersion, translator, monitor);
23642364
monitor.setMessage("Updating instructions...");

Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/register/ProgramRegisterContextDB.java

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -72,12 +72,12 @@ public ProgramRegisterContextDB(DBHandle dbHandle, ErrorHandler errHandler, Lang
7272
}
7373

7474
if (openMode == DBConstants.UPGRADE && oldContextDataExists) {
75-
// TODO: Make sure upgrade is working correctly before uncommenting
76-
// try {
77-
// OldProgramContextDB.removeOldContextData(dbHandle);
78-
// } catch (IOException e) {
79-
// errorHandler.dbError(e);
80-
// }
75+
try {
76+
OldProgramContextDB.removeOldContextData(dbHandle);
77+
}
78+
catch (IOException e) {
79+
errorHandler.dbError(e);
80+
}
8181
}
8282
}
8383

@@ -161,6 +161,12 @@ private void initializedCurrentValues() {
161161
}
162162
}
163163

164+
/**
165+
* Intialize context with default values defined by pspec and cspec.
166+
* NOTE: cspec values take precedence
167+
* @param lang processor language
168+
* @param compilerSpec compiler specification
169+
*/
164170
public void initializeDefaultValues(Language lang, CompilerSpec compilerSpec) {
165171
defaultRegisterValueMap.clear();
166172
lang.applyContextSettings(this);
@@ -288,9 +294,31 @@ public void setRegisterValue(Address start, Address end, RegisterValue value)
288294
}
289295
}
290296

297+
/**
298+
* Perform context upgrade due to a language change
299+
* @param translator language translator required by major upgrades (may be null)
300+
* @param newCompilerSpec new compiler specification
301+
* @param programMemory program memory
302+
* @param monitor task monitor
303+
* @throws CancelledException thrown if monitor cancelled
304+
*/
291305
public void setLanguage(LanguageTranslator translator, CompilerSpec newCompilerSpec,
292306
AddressSetView programMemory, TaskMonitor monitor) throws CancelledException {
293307

308+
if (translator == null) {
309+
Language lang = program.getLanguage();
310+
boolean clearContext = Boolean.valueOf(
311+
lang.getProperty(GhidraLanguagePropertyKeys.RESET_CONTEXT_ON_UPGRADE));
312+
if (clearContext) {
313+
RegisterValueStore store = registerValueMap.get(baseContextRegister);
314+
if (store != null) {
315+
store.clearAll();
316+
}
317+
}
318+
initializeDefaultValues(lang, newCompilerSpec);
319+
return;
320+
}
321+
294322
Language newLanguage = translator.getNewLanguage();
295323

296324
// Sort the registers by size so that largest come first.
@@ -309,8 +337,11 @@ public void setLanguage(LanguageTranslator translator, CompilerSpec newCompilerS
309337
continue;
310338
}
311339

340+
boolean clearContext = register.isProcessorContext() && Boolean.valueOf(
341+
newLanguage.getProperty(GhidraLanguagePropertyKeys.RESET_CONTEXT_ON_UPGRADE));
342+
312343
// Update storage range map
313-
if (!store.setLanguage(translator, monitor)) {
344+
if (clearContext || !store.setLanguage(translator, monitor)) {
314345
// Clear and remove old register value store
315346
Msg.warn(this,
316347
"WARNING! Discarding all context for register " + register.getName());

Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/GhidraLanguagePropertyKeys.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,4 +112,11 @@ private GhidraLanguagePropertyKeys() {
112112
* following the call. Non-returning functions can be detected in many cases.
113113
*/
114114
public static final String ENABLE_NO_RETURN_ANALYSIS = "enableNoReturnAnalysis";
115+
116+
/**
117+
* Property to indicate that all stored instruction context should be cleared
118+
* during a language upgrade operation which requires redisassembly.
119+
* NOTE: This is an experimental concept which may be removed in the future
120+
*/
121+
public static final String RESET_CONTEXT_ON_UPGRADE = "resetContextOnUpgrade";
115122
}

0 commit comments

Comments
 (0)