diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/time/DebuggerSnapshotTablePanel.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/time/DebuggerSnapshotTablePanel.java index 5676a31630..0cec92c03c 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/time/DebuggerSnapshotTablePanel.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/time/DebuggerSnapshotTablePanel.java @@ -228,16 +228,15 @@ public class DebuggerSnapshotTablePanel extends JPanel { } TraceSnapshot snapshot = row.getSnapshot(); - if (snapshot.getSchedule().isSnapOnly() || - snapshot.getVersion() >= current.getTrace().getEmulatorCacheVersion()) { + if (snapshot.isStale(true)) { + setForeground( + data.isSelected() ? COLOR_FOREGROUND_STALE_SEL : COLOR_FOREGROUND_STALE); + } + else { JTable table = data.getTable(); setForeground( data.isSelected() ? table.getSelectionForeground() : table.getForeground()); } - else { - setForeground( - data.isSelected() ? COLOR_FOREGROUND_STALE_SEL : COLOR_FOREGROUND_STALE); - } return this; } diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/DebuggerEmulationServicePlugin.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/DebuggerEmulationServicePlugin.java index 8b7dd85b6a..ca7077b1ea 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/DebuggerEmulationServicePlugin.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/DebuggerEmulationServicePlugin.java @@ -699,7 +699,7 @@ public class DebuggerEmulationServicePlugin extends Plugin implements DebuggerEm TraceSchedule time = key.time; TraceSnapshot tracePrefix = trace.getTimeManager().findSnapshotWithNearestPrefix(time); - if (tracePrefix.getSchedule().isSnapOnly()) { + if (tracePrefix != null && tracePrefix.isSnapOnly(true)) { tracePrefix = null; } Map.Entry cachePrefix = findNearestPrefix(key); diff --git a/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/time/DBTraceSnapshot.java b/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/time/DBTraceSnapshot.java index 809e5cbfda..290087089b 100644 --- a/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/time/DBTraceSnapshot.java +++ b/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/time/DBTraceSnapshot.java @@ -227,6 +227,28 @@ public class DBTraceSnapshot extends DBAnnotatedObject implements TraceSnapshot } } + @Override + public boolean isSnapOnly(boolean whenInconsistent) { + if (schedule == null && key < 0) { + return whenInconsistent; + } + return schedule == null || schedule.isSnapOnly(); + } + + @Override + public boolean isStale(boolean whenInconsistent) { + if (schedule == null) { + if (key < 0) { + return whenInconsistent; + } + return false; // A recorded snapshot + } + if (schedule.isSnapOnly()) { + return false; + } + return version < manager.trace.getEmulatorCacheVersion(); + } + @Override public void delete() { manager.deleteSnapshot(this); diff --git a/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/model/time/TraceSnapshot.java b/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/model/time/TraceSnapshot.java index 5befec010f..d691d4ed06 100644 --- a/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/model/time/TraceSnapshot.java +++ b/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/model/time/TraceSnapshot.java @@ -4,9 +4,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -43,7 +43,7 @@ public interface TraceSnapshot { /** * Get the description of the snapshot * - * @return + * @return the description */ String getDescription(); @@ -131,6 +131,34 @@ public interface TraceSnapshot { */ void setVersion(long version); + /** + * Check if a snapshot involves any steps of emulation + *

+ * A scratch snapshot, i.e., whose key is negative, without a schedule set is considered + * inconsistent. + * + * @param whenInconsistent the value to return for a scratch snapshot without a set schedule + * @return true if no emulation is involved + */ + boolean isSnapOnly(boolean whenInconsistent); + + /** + * For an emulated snapshot, check if re-emulation is necessary to produce an up-to-date + * snapshot. + *

+ * For non-emulated snapshots, this always returns false. A non-emulated snapshot is a snapshot + * whose schedule includes no emulation steps. An emulation snapshot is stale when its version + * is less than the trace's emulator cache version. A scratch snapshot, i.e., whose key is + * negative, without a schedule set is considered inconsistent. + * + * @param whenInconsistent the value to return for a scratch snapshot without a set schedule + * @return true if re-emulation is needed + * @see #getVersion() + * @see #setVersion(long) + * @see Trace#getEmulatorCacheVersion() + */ + boolean isStale(boolean whenInconsistent); + /** * Delete this snapshot * diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/sleighbase.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/sleighbase.cc index 82cd8bcb7f..26805d642e 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/sleighbase.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/sleighbase.cc @@ -17,7 +17,7 @@ namespace ghidra { -const uint4 SleighBase::MAX_UNIQUE_SIZE = 128; +const uint4 SleighBase::MAX_UNIQUE_SIZE = 256; int4 SourceFileIndexer::index(const string filename){ auto it = fileToIndex.find(filename); diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/slgh_compile.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/slgh_compile.cc index d5ca7302c0..75bebffcb0 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/slgh_compile.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/slgh_compile.cc @@ -255,8 +255,7 @@ void ConsistencyChecker::OptimizeRecord::updateCombine(ConsistencyChecker::Optim /// \param rt is the root subtable of the SLEIGH spec /// \param un is \b true to request "Unnecessary extension" warnings /// \param warndead is \b true to request warnings for written but not read temporaries -/// \param warnlargetemp is \b true to request warnings for temporaries that are too large -ConsistencyChecker::ConsistencyChecker(SleighCompile *sleigh,SubtableSymbol *rt,bool un,bool warndead, bool warnlargetemp) +ConsistencyChecker::ConsistencyChecker(SleighCompile *sleigh,SubtableSymbol *rt,bool un,bool warndead) { compiler = sleigh; @@ -264,10 +263,8 @@ ConsistencyChecker::ConsistencyChecker(SleighCompile *sleigh,SubtableSymbol *rt, unnecessarypcode = 0; readnowrite = 0; writenoread = 0; - largetemp = 0; /// ops = ctpl->getOpvec(); for(vector::iterator iter = ops.begin();iter != ops.end();++iter) { if (hasLargeTemporary(*iter)) { - if (printlargetempwarning) { - compiler->reportWarning( - compiler->getLocation(ct), - "Constructor uses temporary varnode larger than " + to_string(SleighBase::MAX_UNIQUE_SIZE) + " bytes."); - } - largetemp++; + compiler->reportError( + compiler->getLocation(ct), + "Constructor uses temporary varnode larger than " + to_string(SleighBase::MAX_UNIQUE_SIZE) + " bytes."); return; } } @@ -1959,7 +1953,6 @@ SleighCompile::SleighCompile(void) warnunnecessarypcode = false; warndeadtemps = false; lenientconflicterrors = true; - largetemporarywarning = false; warnalllocalcollisions = false; warnallnops = false; failinsensitivedups = true; @@ -2141,7 +2134,7 @@ void SleighCompile::buildPatterns(void) void SleighCompile::checkConsistency(void) { - ConsistencyChecker checker(this, root,warnunnecessarypcode,warndeadtemps,largetemporarywarning); + ConsistencyChecker checker(this, root,warnunnecessarypcode,warndeadtemps); if (!checker.testSizeRestrictions()) { errors += 1; @@ -2171,14 +2164,6 @@ void SleighCompile::checkConsistency(void) reportWarning("Use -t switch to list each individually"); } checker.testLargeTemporary(); - if ((!largetemporarywarning) && (checker.getNumLargeTemporaries() > 0)) { - ostringstream msg; - msg << dec << checker.getNumLargeTemporaries(); - msg << " constructors contain temporaries larger than "; - msg << SleighBase::MAX_UNIQUE_SIZE << " bytes"; - reportWarning(msg.str()); - reportWarning("Use -o switch to list each individually."); - } } /// \brief Search for offset matches between a previous set and the given current set @@ -3345,6 +3330,18 @@ vector *SleighCompile::createCrossBuild(VarnodeTpl *addr,SectionSymbol return res; } +/// \brief Prepare for a new section of p-code templates +/// +/// Create the ConstructTpl to hold the templates and reset counters. +/// \return the new ConstructTpl +ConstructTpl *SleighCompile::enterSection(void) + +{ + ConstructTpl *tpl = new ConstructTpl(); + pcode.resetLabelCount(); // Macros have their own labels + return tpl; +} + /// \brief Create a new Constructor under the given subtable /// /// Create the object and initialize parsing for the new definition @@ -3882,13 +3879,12 @@ static void findSlaSpecs(vector &res, const string &dir, const string &s /// \param allNopWarning is \b true for individual warnings about NOP constructors /// \param deadTempWarning is \b true for individual warnings about dead temporary varnodes /// \param enforceLocalKeyWord is \b true to force all local variable definitions to use the \b local keyword -/// \param largeTemporaryWarning is \b true for individual warnings about temporary varnodes that are too large /// \param caseSensitiveRegisterNames is \b true if register names are allowed to be case sensitive /// \param debugOutput is \b true if the output file is written using the debug (XML) form of the .sla format void SleighCompile::setAllOptions(const map &defines, bool unnecessaryPcodeWarning, bool lenientConflict, bool allCollisionWarning, bool allNopWarning,bool deadTempWarning,bool enforceLocalKeyWord, - bool largeTemporaryWarning, bool caseSensitiveRegisterNames,bool debugOutput) + bool caseSensitiveRegisterNames,bool debugOutput) { map::const_iterator iter = defines.begin(); for (iter = defines.begin(); iter != defines.end(); iter++) { @@ -3900,7 +3896,6 @@ void SleighCompile::setAllOptions(const map &defines, bool unnece setAllNopWarning( allNopWarning ); setDeadTempWarning(deadTempWarning); setEnforceLocalKeyWord(enforceLocalKeyWord); - setLargeTemporaryWarning(largeTemporaryWarning); setInsensitiveDuplicateError(!caseSensitiveRegisterNames); setDebugOutput(debugOutput); } @@ -3935,7 +3930,6 @@ int main(int argc,char **argv) cerr << " -t print warnings for dead temporaries" << endl; cerr << " -e enforce use of 'local' keyword for temporaries" << endl; cerr << " -c print warnings for all constructors with colliding operands" << endl; - cerr << " -o print warnings for temporaries which are too large" << endl; cerr << " -s treat register names as case sensitive" << endl; cerr << " -DNAME=VALUE defines a preprocessor macro NAME with value VALUE" << endl; exit(2); @@ -3950,7 +3944,6 @@ int main(int argc,char **argv) bool allNopWarning = false; bool deadTempWarning = false; bool enforceLocalKeyWord = false; - bool largeTemporaryWarning = false; bool caseSensitiveRegisterNames = false; bool debugOutput = false; @@ -3984,8 +3977,6 @@ int main(int argc,char **argv) deadTempWarning = true; else if (argv[i][1] == 'e') enforceLocalKeyWord = true; - else if (argv[i][1] == 'o') - largeTemporaryWarning = true; else if (argv[i][1] == 's') caseSensitiveRegisterNames = true; else if (argv[i][1] == 'y') @@ -4021,8 +4012,7 @@ int main(int argc,char **argv) sla.replace(slaspec.length() - slaspecExtLen, slaspecExtLen, SLAEXT); SleighCompile compiler; compiler.setAllOptions(defines, unnecessaryPcodeWarning, lenientConflict, allCollisionWarning, allNopWarning, - deadTempWarning, enforceLocalKeyWord,largeTemporaryWarning, caseSensitiveRegisterNames, - debugOutput); + deadTempWarning, enforceLocalKeyWord, caseSensitiveRegisterNames, debugOutput); retval = compiler.run_compilation(slaspec,sla); if (retval != 0) { return retval; // stop on first error @@ -4058,8 +4048,7 @@ int main(int argc,char **argv) SleighCompile compiler; compiler.setAllOptions(defines, unnecessaryPcodeWarning, lenientConflict, allCollisionWarning, allNopWarning, - deadTempWarning, enforceLocalKeyWord,largeTemporaryWarning,caseSensitiveRegisterNames, - debugOutput); + deadTempWarning, enforceLocalKeyWord,caseSensitiveRegisterNames,debugOutput); if (i < argc - 1) { string fileoutExamine(argv[i+1]); diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/slgh_compile.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/slgh_compile.hh index 4f55bea0b8..a193c7dbdb 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/slgh_compile.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/slgh_compile.hh @@ -188,10 +188,8 @@ private: int4 unnecessarypcode; ///< Count of unnecessary extension/truncation operations int4 readnowrite; ///< Count of temporary registers that are read but not written int4 writenoread; ///< Count of temporary registers that are written but not read - int4 largetemp; ///< Count of temporary registers that are too large bool printextwarning; ///< Set to \b true if warning emitted for each unnecessary truncation/extension bool printdeadwarning; ///< Set to \b true if warning emitted for each written but not read temporary - bool printlargetempwarning; ///< Set to \b true if warning emitted for each too large temporary SubtableSymbol *root_symbol; ///< The root symbol table for the parsed SLEIGH file vector postorder; ///< Subtables sorted into \e post order (dependent tables listed earlier) map sizemap; ///< Sizes associated with table \e exports @@ -223,7 +221,7 @@ private: void checkLargeTemporaries(Constructor *ct,ConstructTpl *ctpl); void optimize(Constructor *ct); public: - ConsistencyChecker(SleighCompile *sleigh, SubtableSymbol *rt,bool unnecessary,bool warndead, bool warnlargetemp); + ConsistencyChecker(SleighCompile *sleigh, SubtableSymbol *rt,bool unnecessary,bool warndead); bool testSizeRestrictions(void); ///< Test size consistency of all p-code bool testTruncations(void); ///< Test truncation validity of all p-code void testLargeTemporary(void); ///< Test for temporary Varnodes that are too large @@ -231,7 +229,6 @@ public: int4 getNumUnnecessaryPcode(void) const { return unnecessarypcode; } ///< Return the number of unnecessary extensions and truncations int4 getNumReadNoWrite(void) const { return readnowrite; } ///< Return the number of temporaries read but not written int4 getNumWriteNoRead(void) const { return writenoread; } ///< Return the number of temporaries written but not read - int4 getNumLargeTemporaries(void) const {return largetemp;} ///< Return the number of \e too large temporaries }; /// \brief Helper function holding properties of a \e context field prior to calculating the context layout @@ -325,7 +322,6 @@ private: bool warnunnecessarypcode; ///< \b true if we warn of unnecessary ZEXT or SEXT bool warndeadtemps; ///< \b true if we warn of temporaries that are written but not read bool lenientconflicterrors; ///< \b true if we ignore most pattern conflict errors - bool largetemporarywarning; ///< \b true if we warn about temporaries larger than SleighBase::MAX_UNIQUE_SIZE bool warnalllocalcollisions; ///< \b true if local export collisions generate individual warnings bool warnallnops; ///< \b true if pcode NOPs generate individual warnings bool failinsensitivedups; ///< \b true if case insensitive register duplicates cause error @@ -388,11 +384,6 @@ public: /// \param val is \b true if the \b local keyword must always be used. The default is \b false. void setEnforceLocalKeyWord(bool val) { pcode.setEnforceLocalKey(val); } - /// \brief Set whether too large temporary registers generate warnings individually - /// - /// \param val is \b true if warnings are generated individually. The default is \b false. - void setLargeTemporaryWarning (bool val) {largetemporarywarning = val;} - /// \brief Set whether indistinguishable Constructor patterns generate fatal errors /// /// \param val is \b true if no error is generated. The default is \b true. @@ -466,6 +457,7 @@ public: SectionVector *nextNamedSection(SectionVector *vec,ConstructTpl *section,SectionSymbol *sym); SectionVector *finalNamedSection(SectionVector *vec,ConstructTpl *section); vector *createCrossBuild(VarnodeTpl *addr,SectionSymbol *sym); + ConstructTpl *enterSection(void); Constructor *createConstructor(SubtableSymbol *sym); bool isInRoot(Constructor *ct) const { return (root == ct->getParent()); } ///< Is the Constructor in the root table? void resetConstructors(void); @@ -484,7 +476,7 @@ public: void setAllOptions(const map &defines, bool unnecessaryPcodeWarning, bool lenientConflict, bool allCollisionWarning, bool allNopWarning,bool deadTempWarning,bool enforceLocalKeyWord, - bool largeTemporaryWarning, bool caseSensitiveRegisterNames,bool debugOutput); + bool caseSensitiveRegisterNames,bool debugOutput); int4 run_compilation(const string &filein,const string &fileout); }; diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/slghparse.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/slghparse.cc index ec1f76a0e4..741525a324 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/slghparse.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/slghparse.cc @@ -4,9 +4,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -2856,7 +2856,7 @@ yyreduce: break; case 145: - { (yyval.sem) = new ConstructTpl(); } + { (yyval.sem) = slgh->enterSection(); } break; case 146: diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/slghparse.y b/Ghidra/Features/Decompiler/src/decompile/cpp/slghparse.y index fd7f293e7b..cddc09f5cb 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/slghparse.y +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/slghparse.y @@ -4,9 +4,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -350,7 +350,7 @@ rtl: rtlmid { $$ = $1; if ($$->getOpvec().empty() && ($$->getResult() == (Handle | rtlmid EXPORT_KEY STRING { string errmsg="Unknown export varnode: "+*$3; delete $3; slgh->reportError(errmsg); YYERROR; } | rtlmid EXPORT_KEY sizedstar STRING { string errmsg="Unknown pointer varnode: "+*$4; delete $3; delete $4; slgh->reportError(errmsg); YYERROR; } ; -rtlmid: /* EMPTY */ { $$ = new ConstructTpl(); } +rtlmid: /* EMPTY */ { $$ = slgh->enterSection(); } | rtlmid statement { $$ = $1; if (!$$->addOpList(*$2)) { delete $2; slgh->reportError("Multiple delayslot declarations"); YYERROR; } delete $2; } | rtlmid LOCAL_KEY STRING ';' { $$ = $1; slgh->pcode.newLocalDefinition($3); } | rtlmid LOCAL_KEY STRING ':' INTEGER ';' { $$ = $1; slgh->pcode.newLocalDefinition($3,*$5); delete $5; } diff --git a/Ghidra/Framework/FileSystem/src/main/java/ghidra/framework/store/local/IndexedLocalFileSystem.java b/Ghidra/Framework/FileSystem/src/main/java/ghidra/framework/store/local/IndexedLocalFileSystem.java index 3533d45866..33d56875e9 100644 --- a/Ghidra/Framework/FileSystem/src/main/java/ghidra/framework/store/local/IndexedLocalFileSystem.java +++ b/Ghidra/Framework/FileSystem/src/main/java/ghidra/framework/store/local/IndexedLocalFileSystem.java @@ -89,6 +89,7 @@ public class IndexedLocalFileSystem extends LocalFileSystem { * to notify listeners. If false, blocking notification will be performed. * @param create if true a new folder will be created. * @throws FileNotFoundException if specified rootPath does not exist + * @throws IndexReadException failure occured reading index file * @throws IOException if error occurs while reading/writing index files */ IndexedLocalFileSystem(String rootPath, boolean isVersioned, boolean readOnly, @@ -440,11 +441,21 @@ public class IndexedLocalFileSystem extends LocalFileSystem { public static int readIndexVersion(String rootPath) throws IOException { File indexFile = new File(rootPath, INDEX_FILE); + + if (indexFile.exists() && indexFile.length() == 0) { + return 0; // will trigger index rebuild + } + BufferedReader indexReader = null; try { indexReader = new BufferedReader(new InputStreamReader( new BufferedInputStream(new FileInputStream(indexFile)), "UTF8")); - return getIndexVersion(indexReader.readLine()); + int ver = getIndexVersion(indexReader.readLine()); + if (ver >= 0 && ver < LATEST_INDEX_VERSION) { + Msg.warn(LocalFileSystem.class, + "Using deprecated Indexed filesystem (V0): " + rootPath); + } + return ver; } finally { if (indexReader != null) { @@ -463,6 +474,10 @@ public class IndexedLocalFileSystem extends LocalFileSystem { // TODO: current implementation does not attempt to avoid concurrent read/write // access to index/journal files + if (indexFile.length() == 0) { + throw new IndexReadException("empty index: " + indexFile); + } + MessageDigest messageDigest = null; try { messageDigest = MessageDigest.getInstance("MD5"); @@ -485,7 +500,7 @@ public class IndexedLocalFileSystem extends LocalFileSystem { new BufferedInputStream(new FileInputStream(indexFile)), "UTF8")); String line = indexReader.readLine(); if (checkIndexVersion(line)) { - // version line consumed - read next line + // version line consumed - read next line - Version-0 lacked VERSION line line = indexReader.readLine(); } Folder currentFolder = null; @@ -1714,6 +1729,8 @@ public class IndexedLocalFileSystem extends LocalFileSystem { /** * Get the V0 indexed-file-system instance. File system storage should first be * pre-qualified as an having indexed storage using the {@link #isIndexed(String)} method. + *

+ * NOTE: If there is a index read error a forced migration to V1 may occur * @param rootPath * @param isVersioned * @param readOnly @@ -1735,41 +1752,16 @@ public class IndexedLocalFileSystem extends LocalFileSystem { Msg.error(LocalFileSystem.class, "Indexed filesystem error: " + e.getMessage()); Msg.info(LocalFileSystem.class, "Attempting index rebuild: " + rootPath); - if (!IndexedLocalFileSystem.rebuild(new File(rootPath))) { + if (!IndexedV1LocalFileSystem.rebuild(new File(rootPath))) { throw e; } // retry after index rebuild - return new IndexedLocalFileSystem(rootPath, isVersioned, readOnly, + return new IndexedV1LocalFileSystem(rootPath, isVersioned, readOnly, enableAsyncronousDispatching, false); } } - /** - * Completely rebuild filesystem index using item information contained - * within indexed property files. Empty folders will be lost. - * @param rootDir - * @throws IOException - */ - public static boolean rebuild(File rootDir) throws IOException { - - verifyIndexedFileStructure(rootDir); - - IndexedLocalFileSystem fs = new IndexedLocalFileSystem(rootDir.getAbsolutePath()); - fs.rebuildIndex(); - fs.cleanupAfterConstruction(); - fs.dispose(); - - File errorFile = new File(rootDir, REBUILD_ERROR_FILE); - if (errorFile.exists()) { - Msg.error(LocalFileSystem.class, - "Indexed filesystem rebuild failed, see log for details: " + errorFile); - return false; - } - Msg.info(LocalFileSystem.class, "Index rebuild completed: " + rootDir); - return true; - } - static class IndexedItemStorage extends ItemStorage { IndexedItemStorage(File dir, String storageName, String folderPath, String itemName) { diff --git a/Ghidra/Framework/FileSystem/src/main/java/ghidra/framework/store/local/IndexedV1LocalFileSystem.java b/Ghidra/Framework/FileSystem/src/main/java/ghidra/framework/store/local/IndexedV1LocalFileSystem.java index 125f690ae4..1fa6ffe514 100644 --- a/Ghidra/Framework/FileSystem/src/main/java/ghidra/framework/store/local/IndexedV1LocalFileSystem.java +++ b/Ghidra/Framework/FileSystem/src/main/java/ghidra/framework/store/local/IndexedV1LocalFileSystem.java @@ -43,6 +43,7 @@ public class IndexedV1LocalFileSystem extends IndexedLocalFileSystem { * to notify listeners. If false, blocking notification will be performed. * @param create if true a new folder will be created. * @throws FileNotFoundException if specified rootPath does not exist + * @throws IndexReadException failure occured reading index file * @throws IOException if error occurs while reading/writing index files */ protected IndexedV1LocalFileSystem(String rootPath, boolean isVersioned, boolean readOnly, diff --git a/Ghidra/Framework/FileSystem/src/main/java/ghidra/framework/store/local/LocalFileSystem.java b/Ghidra/Framework/FileSystem/src/main/java/ghidra/framework/store/local/LocalFileSystem.java index 4975931845..dd71437d6f 100644 --- a/Ghidra/Framework/FileSystem/src/main/java/ghidra/framework/store/local/LocalFileSystem.java +++ b/Ghidra/Framework/FileSystem/src/main/java/ghidra/framework/store/local/LocalFileSystem.java @@ -130,8 +130,6 @@ public abstract class LocalFileSystem implements FileSystem { return new MangledLocalFileSystem(rootPath, isVersioned, readOnly, enableAsyncronousDispatching); case 0: - Msg.warn(LocalFileSystem.class, - "Using deprecated Indexed filesystem (V0): " + rootPath); return IndexedLocalFileSystem.getFileSystem(rootPath, isVersioned, readOnly, enableAsyncronousDispatching); case 1: diff --git a/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/SleighCompiler.g b/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/SleighCompiler.g index d254d2bd92..39effb8a3d 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/SleighCompiler.g +++ b/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/SleighCompiler.g @@ -1023,7 +1023,7 @@ code_block[Location startingPoint] returns [ConstructTpl rtl] } scope Block; @init { - $Block::ct = new ConstructTpl(startingPoint); + $Block::ct = pcode.enterSection(startingPoint); $code_block::stmtLocation = new Location("", 0); } @after { @@ -1089,7 +1089,7 @@ statement pcode.recordNop(s.first); } $semantic::containsMultipleSections = true; - $Block::ct = new ConstructTpl(s.first); + $Block::ct = pcode.enterSection(s.first); } ; diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/sleighbase/SleighBase.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/sleighbase/SleighBase.java index 5223f6a466..0273875dbb 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/sleighbase/SleighBase.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/sleighbase/SleighBase.java @@ -4,9 +4,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -37,7 +37,7 @@ public abstract class SleighBase extends Translate implements NamedSymbolProvide * Note: The value of {@link #MAX_UNIQUE_SIZE} must match the corresponding value * defined by sleighbase.cc */ - public static final long MAX_UNIQUE_SIZE = 128; //Maximum size of a varnode in the unique space. + public static final long MAX_UNIQUE_SIZE = 256; //Maximum size of a varnode in the unique space. //Should match value in sleighbase.cc private VectorSTL userop = new VectorSTL<>(); diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slgh_compile/ConsistencyChecker.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slgh_compile/ConsistencyChecker.java index dfad7abd0e..baee4e4730 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slgh_compile/ConsistencyChecker.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slgh_compile/ConsistencyChecker.java @@ -35,10 +35,8 @@ class ConsistencyChecker { private int readnowrite; private int writenoread; - private int largetemp; // number of constructors using a temporary varnode larger than SleighBase.MAX_UNIQUE_SIZE private boolean printextwarning; private boolean printdeadwarning; - private boolean printlargetempwarning; // if true, warning about temporary varnodes larger than SleighBase.MAX_UNIQUE_SIZE private SleighCompile compiler; private SubtableSymbol root_symbol; private List postorder = new ArrayList<>(); @@ -1261,12 +1259,9 @@ class ConsistencyChecker { VectorSTL ops = ctpl.getOpvec(); for (IteratorSTL iter = ops.begin(); !iter.isEnd(); iter.increment()) { if (hasLargeTemporary(iter.get())) { - if (printlargetempwarning) { - compiler.reportWarning(ct.location, - "Constructor uses temporary varnode larger than " + - SleighBase.MAX_UNIQUE_SIZE + " bytes."); - } - largetemp++; + compiler.reportError(ct.location, + "Constructor uses temporary varnode larger than " + + SleighBase.MAX_UNIQUE_SIZE + " bytes."); return; } } @@ -1298,12 +1293,8 @@ class ConsistencyChecker { unnecessarypcode = 0; readnowrite = 0; writenoread = 0; - //number of constructors which reference a temporary varnode larger than SleighBase.MAX_UNIQUE_SIZE - largetemp = 0; printextwarning = unnecessary; printdeadwarning = warndead; - //whether to print information about constructors which reference large temporary varnodes - printlargetempwarning = warnlargetemp; } // Main entry point for size consistency check @@ -1401,14 +1392,4 @@ class ConsistencyChecker { public int getNumWriteNoRead() { return writenoread; } - - /** - * Returns the number of constructors which reference a varnode in the unique space with size - * larger than {@link SleighBase#MAX_UNIQUE_SIZE}. - * - * @return num constructors with large temp varnodes - */ - public int getNumLargeTemporaries() { - return largetemp; - } } diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slgh_compile/PcodeCompile.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slgh_compile/PcodeCompile.java index 26bc1c172b..17447b9155 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slgh_compile/PcodeCompile.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slgh_compile/PcodeCompile.java @@ -68,6 +68,8 @@ public abstract class PcodeCompile { public abstract VectorSTL createCrossBuild(Location find, VarnodeTpl v, SectionSymbol second); + public abstract ConstructTpl enterSection(Location where); + public abstract SectionVector standaloneSection(ConstructTpl c); public abstract SectionVector firstNamedSection(ConstructTpl main, SectionSymbol sym); diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slgh_compile/SleighCompile.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slgh_compile/SleighCompile.java index 332f70e6ca..9b63f8172b 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slgh_compile/SleighCompile.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slgh_compile/SleighCompile.java @@ -167,6 +167,11 @@ public class SleighCompile extends SleighBase { return SleighCompile.this.createCrossBuild(find, v, section); } + @Override + public ConstructTpl enterSection(Location where) { + return SleighCompile.this.enterSection(where); + } + @Override public SectionVector standaloneSection(ConstructTpl c) { return SleighCompile.this.standaloneSection(c); @@ -333,6 +338,12 @@ public class SleighCompile extends SleighBase { return res; } + protected ConstructTpl enterSection(Location where) { + entry("enterSection", where); + pcode.resetLabelCount(); + return new ConstructTpl(where); + } + protected SectionVector standaloneSection(ConstructTpl main) { entry("standaloneSection", main); // Create SectionVector for just the main rtl section with no named sections @@ -534,13 +545,6 @@ public class SleighCompile extends SleighBase { reportWarning(null, "Use -t switch to list each individually"); } checker.testLargeTemporary(); - if ((!largetemporarywarning) && checker.getNumLargeTemporaries() > 0) { - reportWarning(null, - checker.getNumLargeTemporaries() + - " constructors contain temporaries larger than " + SleighBase.MAX_UNIQUE_SIZE + - " bytes."); - reportWarning(null, "Use -o switch to list each individually."); - } } private static int findCollision(Map local2Operand, ArrayList locals, @@ -776,17 +780,6 @@ public class SleighCompile extends SleighBase { pcode.setEnforceLocalKey(val); } - /** - * Sets whether or not to print out warning info about - * {@link Constructor}s which reference varnodes in the - * unique space larger than {@link SleighBase#MAX_UNIQUE_SIZE}. - * @param val whether to print info about contructors using large varnodes - */ - public void setLargeTemporaryWarning(boolean val) { - entry("setLargeTemporaryWarning", val); - largetemporarywarning = val; - } - public void setLenientConflict(boolean val) { entry("setLenientConflict", val); lenientconflicterrors = val; @@ -1794,8 +1787,7 @@ public class SleighCompile extends SleighBase { public void setAllOptions(Map preprocs, boolean unnecessaryPcodeWarning, boolean lenientConflict, boolean allCollisionWarning, boolean allNopWarning, boolean deadTempWarning, boolean unusedFieldWarning, boolean enforceLocalKeyWord, - boolean largeTemporaryWarning, boolean caseSensitiveRegisterNames, - boolean debugOutput) { + boolean caseSensitiveRegisterNames, boolean debugOutput) { Set> entrySet = preprocs.entrySet(); for (Entry entry : entrySet) { setPreprocValue(entry.getKey(), entry.getValue()); @@ -1807,7 +1799,6 @@ public class SleighCompile extends SleighBase { setDeadTempWarning(deadTempWarning); setUnusedFieldWarning(unusedFieldWarning); setEnforceLocalKeyWord(enforceLocalKeyWord); - setLargeTemporaryWarning(largeTemporaryWarning); setInsensitiveDuplicateError(!caseSensitiveRegisterNames); setDebugOutput(debugOutput); } diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slgh_compile/SleighCompileLauncher.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slgh_compile/SleighCompileLauncher.java index 7b84727941..be52d69c53 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slgh_compile/SleighCompileLauncher.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slgh_compile/SleighCompileLauncher.java @@ -4,9 +4,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -86,7 +86,6 @@ public class SleighCompileLauncher implements GhidraLaunchable { Msg.info(SleighCompile.class, " -e enforce use of 'local' keyword for temporaries"); Msg.info(SleighCompile.class, " -c print warnings for all constructors with colliding operands"); Msg.info(SleighCompile.class, " -f print warnings for unused token fields"); - Msg.info(SleighCompile.class, " -o print warnings for temporaries which are too large"); Msg.info(SleighCompile.class, " -s treat register names as case sensitive"); Msg.info(SleighCompile.class, " -DNAME=VALUE defines a preprocessor macro NAME with value VALUE (option may be repeated)"); Msg.info(SleighCompile.class, " -dMODULE defines a preprocessor macro MODULE with a value of its module path (option may be repeated)"); @@ -102,7 +101,6 @@ public class SleighCompileLauncher implements GhidraLaunchable { boolean deadTempWarning = false; boolean enforceLocalKeyWord = false; boolean unusedFieldWarning = false; - boolean largeTemporaryWarning = false; boolean caseSensitiveRegisterNames = false; boolean debugOutput = false; @@ -165,9 +163,6 @@ public class SleighCompileLauncher implements GhidraLaunchable { else if (args[i].charAt(1) == 'a') { allMode = true; } - else if (args[i].charAt(1) == 'o') { - largeTemporaryWarning = true; - } else if (args[i].charAt(1) == 's') { caseSensitiveRegisterNames = true; } @@ -208,7 +203,7 @@ public class SleighCompileLauncher implements GhidraLaunchable { SleighCompile compiler = new SleighCompile(); compiler.setAllOptions(preprocs, unnecessaryPcodeWarning, lenientConflict, allCollisionWarning, allNopWarning, deadTempWarning, unusedFieldWarning, - enforceLocalKeyWord, largeTemporaryWarning, caseSensitiveRegisterNames, + enforceLocalKeyWord, caseSensitiveRegisterNames, debugOutput); String outname = input.getName().replace(".slaspec", ".sla"); @@ -238,7 +233,7 @@ public class SleighCompileLauncher implements GhidraLaunchable { SleighCompile compiler = new SleighCompile(); compiler.setAllOptions(preprocs, unnecessaryPcodeWarning, lenientConflict, allCollisionWarning, allNopWarning, deadTempWarning, unusedFieldWarning, - enforceLocalKeyWord, largeTemporaryWarning, caseSensitiveRegisterNames, debugOutput); + enforceLocalKeyWord, caseSensitiveRegisterNames, debugOutput); if (i == args.length) { Msg.error(SleighCompile.class, "Missing input file name"); return 1; diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/PcodeParser.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/PcodeParser.java index 8166b87ef8..0d7c85a56f 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/PcodeParser.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/PcodeParser.java @@ -4,9 +4,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -479,6 +479,12 @@ public class PcodeParser extends PcodeCompile { throw new SleighError("Pcode snippet parsing does not support use of sections", where); } + @Override + public ghidra.pcodeCPort.semantics.ConstructTpl enterSection(Location where) { + resetLabelCount(); + return new ghidra.pcodeCPort.semantics.ConstructTpl(where); + } + @Override public SectionVector standaloneSection(ghidra.pcodeCPort.semantics.ConstructTpl main) { // Create SectionVector for just the main rtl section with no named sections