diff --git a/Ghidra/Features/Base/src/test/java/ghidra/program/database/code/CodeManagerTest.java b/Ghidra/Features/Base/src/test/java/ghidra/program/database/code/CodeManagerTest.java index 3c720527e6..81a1da1f66 100644 --- a/Ghidra/Features/Base/src/test/java/ghidra/program/database/code/CodeManagerTest.java +++ b/Ghidra/Features/Base/src/test/java/ghidra/program/database/code/CodeManagerTest.java @@ -39,6 +39,7 @@ import ghidra.test.ToyProgramBuilder; import ghidra.util.Lock; import ghidra.util.SaveableColor; import ghidra.util.exception.NoValueException; +import ghidra.util.task.TaskMonitor; import ghidra.util.task.TaskMonitorAdapter; /** @@ -1008,7 +1009,7 @@ public class CodeManagerTest extends AbstractGenericTest { instructionAt = pdb.getListing().getInstructionAt(addr(0x2000)); assertEquals(FlowOverride.CALL, instructionAt.getFlowOverride()); - pdb.getCodeManager().reDisassembleAllInstructions(0, TaskMonitorAdapter.DUMMY_MONITOR); + pdb.getCodeManager().reDisassembleAllInstructions(TaskMonitor.DUMMY); instructionAt = pdb.getListing().getInstructionAt(addr(0x2000)); assertEquals(FlowOverride.CALL, instructionAt.getFlowOverride()); @@ -1032,7 +1033,7 @@ public class CodeManagerTest extends AbstractGenericTest { Instruction instructionAt = pdb.getListing().getInstructionAt(addr(0x2000)); assertEquals(FlowOverride.NONE, instructionAt.getFlowOverride()); - pdb.getCodeManager().reDisassembleAllInstructions(0, TaskMonitorAdapter.DUMMY_MONITOR); + pdb.getCodeManager().reDisassembleAllInstructions(TaskMonitor.DUMMY); instructionAt = pdb.getListing().getInstructionAt(addr(0x2002)); assertEquals(null, instructionAt); diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/ProgramDB.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/ProgramDB.java index f3b9c9e5b9..fece367ff5 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/ProgramDB.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/ProgramDB.java @@ -44,7 +44,6 @@ import ghidra.program.database.register.ProgramRegisterContextDB; import ghidra.program.database.reloc.RelocationManager; import ghidra.program.database.symbol.*; import ghidra.program.database.util.AddressSetPropertyMapDB; -import ghidra.program.disassemble.Disassembler; import ghidra.program.model.address.*; import ghidra.program.model.lang.*; import ghidra.program.model.listing.*; @@ -488,7 +487,6 @@ public class ProgramDB extends DomainObjectAdapterDB implements Program, ChangeM return ve; } - @Override protected void setDomainFile(DomainFile df) { super.setDomainFile(df); @@ -2210,21 +2208,16 @@ public class ProgramDB extends DomainObjectAdapterDB implements Program, ChangeM monitor.setProgress(0); ProgramRegisterContextDB contextMgr = (ProgramRegisterContextDB) getProgramContext(); + if (redisassemblyRequired) { contextMgr.setLanguage(translator, compilerSpec, memoryManager, monitor); + repairContext(oldLanguageVersion, oldLanguageMinorVersion, translator, monitor); + getCodeManager().reDisassembleAllInstructions(monitor); } else { contextMgr.initializeDefaultValues(language, compilerSpec); } - if (redisassemblyRequired) { - Disassembler.clearUnimplementedPcodeWarnings(this, null, monitor); - repairContext(oldLanguageVersion, oldLanguageMinorVersion, translator, monitor); - monitor.setMessage("Updating instructions..."); - monitor.setProgress(0); - getCodeManager().reDisassembleAllInstructions(500, monitor); - } - // Force function manager to reconcile calling conventions managers[FUNCTION_MGR].setProgram(this); managers[FUNCTION_MGR].programReady(UPDATE, getStoredVersion(), monitor); diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/code/CodeManager.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/code/CodeManager.java index 1a3add9d6b..0d811ba8ac 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/code/CodeManager.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/code/CodeManager.java @@ -3525,13 +3525,13 @@ public class CodeManager implements ErrorHandler, ManagerDB { * be discarded and all instructions redisassembled following flow and adjusting context as needed. * Instructions which fail to redisassemble will be marked - since only one byte will be skipped, such bad * instruction disassembly may cause subsequent errors due to possible instruction shift. - * This method is only intended for use by the ProgramDB setLanguage method. - * @param bookmarkLimit maximum number of errors to bookmark + * This method is only intended for use by the ProgramDB setLanguage method which must ensure that + * the context has been properly initialized. * @param monitor task monitor - * @throws IOException + * @throws IOException if IO error occurs * @throws CancelledException if the operation is canceled. */ - public void reDisassembleAllInstructions(int bookmarkLimit, TaskMonitor monitor) + public void reDisassembleAllInstructions(TaskMonitor monitor) throws IOException, CancelledException { redisassemblyMode = true; @@ -3539,6 +3539,10 @@ public class CodeManager implements ErrorHandler, ManagerDB { if (lock.getOwner() != Thread.currentThread()) { throw new IllegalStateException("Must be invoked by lock owner"); } + + Disassembler.clearUnimplementedPcodeWarnings(program, null, monitor); + Disassembler.clearBadInstructionErrors(program, null, monitor); + int maxCount = instAdapter.getRecordCount(); monitor.initialize(maxCount); monitor.setMessage("Preparing for Re-Disassembly..."); diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/disassemble/Disassembler.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/disassemble/Disassembler.java index a9f2e3853d..b911b80b4b 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/disassemble/Disassembler.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/disassemble/Disassembler.java @@ -1471,6 +1471,24 @@ public class Disassembler implements DisassemblerConflictHandler { } } + /** + * Clear all bookmarks which indicate Bad Instruction within the specified address set. + * @param program program to clear bookmarks + * @param addressSet restricted address set or null for entire program + * @param monitor allow canceling + * @throws CancelledException if monitor canceled + */ + public static void clearBadInstructionErrors(Program program, AddressSetView addressSet, + TaskMonitor monitor) throws CancelledException { + BookmarkManager bmMgr = program.getBookmarkManager(); + if (addressSet == null) { + bmMgr.removeBookmarks(BookmarkType.ERROR, ERROR_BOOKMARK_CATEGORY, monitor); + } + else { + bmMgr.removeBookmarks(addressSet, BookmarkType.ERROR, ERROR_BOOKMARK_CATEGORY, monitor); + } + } + private void reportMessage(final String msg) { if (listener != null) { listener.disassembleMessageReported(msg);