diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/semantics.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/semantics.cc index 557112c643..f8c1580a8e 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/semantics.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/semantics.cc @@ -37,6 +37,7 @@ ConstTpl::ConstTpl(const_type tp,int4 ht,v_field vf) type = handle; value.handle_index = ht; select = vf; + value_real = 0; } ConstTpl::ConstTpl(const_type tp,int4 ht,v_field vf,uintb plus) diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/sleighbase.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/sleighbase.cc index 59b6fd6445..0d3107fabc 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/sleighbase.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/sleighbase.cc @@ -16,6 +16,7 @@ #include "sleighbase.hh" const int4 SleighBase::SLA_FORMAT_VERSION = 2; +const uintb SleighBase::MAX_UNIQUE_SIZE = 128; SleighBase::SleighBase(void) diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/sleighbase.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/sleighbase.hh index f3c76e2837..f34658b1fe 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/sleighbase.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/sleighbase.hh @@ -40,6 +40,7 @@ protected: void reregisterContext(void); ///< Reregister context fields for a new executable void restoreXml(const Element *el); ///< Read a SLEIGH specification from XML public: + static const uintb MAX_UNIQUE_SIZE; ///< Maximum size of a varnode in the unique space (should match value in SleighBase.java) SleighBase(void); ///< Construct an uninitialized translator bool isInitialized(void) const { return (root != (SubtableSymbol *)0); } ///< Return \b true if \b this is initialized virtual ~SleighBase(void) {} ///< Destructor diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/slgh_compile.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/slgh_compile.cc index 64d30b516a..80ef34d376 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/slgh_compile.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/slgh_compile.cc @@ -183,7 +183,7 @@ SubtableSymbol *WithBlock::getCurrentSubtable(const list &stack) return (SubtableSymbol *)0; } -ConsistencyChecker::ConsistencyChecker(SleighCompile *sleigh,SubtableSymbol *rt,bool un,bool warndead) +ConsistencyChecker::ConsistencyChecker(SleighCompile *sleigh,SubtableSymbol *rt,bool un,bool warndead, bool warnlargetemp) { compiler = sleigh; @@ -191,8 +191,10 @@ ConsistencyChecker::ConsistencyChecker(SleighCompile *sleigh,SubtableSymbol *rt, unnecessarypcode = 0; readnowrite = 0; writenoread = 0; + largetemp = 0; ///getOut(); + if ((out != (VarnodeTpl *) 0x0) && isTemporaryAndTooBig(out)) { + return true; + } + for (int4 i = 0; i < op->numInput(); ++i) { + VarnodeTpl *in = op->getIn(i); + if (isTemporaryAndTooBig(in)) { + return true; + } + } + return false; +} + +/// +/// Returns true precisely when vn is in the unique space and +/// has size larger than SleighBase::MAX_UNIQUE_SIZE +/// +bool ConsistencyChecker::isTemporaryAndTooBig(VarnodeTpl *vn){ + return vn->getSpace().isUniqueSpace() && + (vn->getSize().getReal() > SleighBase::MAX_UNIQUE_SIZE); + } + bool ConsistencyChecker::checkVarnodeTruncation(Constructor *ct,int4 slot, OpTpl *op,VarnodeTpl *vn,bool isbigendian) { @@ -1238,6 +1267,24 @@ void ConsistencyChecker::checkUnusedTemps(Constructor *ct,const map ops = ct->getTempl()->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++; + return; + } + } +} + void ConsistencyChecker::optimize(Constructor *ct) { @@ -1255,6 +1302,7 @@ void ConsistencyChecker::optimize(Constructor *ct) applyOptimization(ct,*currec); } while(currec != (OptimizeRecord *)0); checkUnusedTemps(ct,recs); + checkLargeTemporaries(ct); } bool ConsistencyChecker::test(void) @@ -1640,7 +1688,7 @@ void SleighCompile::buildPatterns(void) void SleighCompile::checkConsistency(void) { - ConsistencyChecker checker(this, root,warnunnecessarypcode,warndeadtemps); + ConsistencyChecker checker(this, root,warnunnecessarypcode,warndeadtemps,largetemporarywarning); if (!checker.test()) { errors += 1; @@ -1669,6 +1717,14 @@ void SleighCompile::checkConsistency(void) msg << "Use -t switch to list each individually"; reportInfo(msg.str()); } + if ((!largetemporarywarning) && (checker.getNumLargeTemporaries() > 0)) { + ostringstream msg; + msg << dec << checker.getNumLargeTemporaries(); + msg << " constructors contain temporaries larger than "; + msg << SleighBase::MAX_UNIQUE_SIZE << " bytes" << endl; + msg << "Use -o switch to list each individually."; + reportInfo(msg.str()); + } } int4 SleighCompile::findCollision(map &local2Operand,const vector &locals,int operand) @@ -1857,7 +1913,7 @@ uintb SleighCompile::getUniqueAddr(void) { uintb base = getUniqueBase(); - setUniqueBase(base + 16); // Should be maximum size of a unique + setUniqueBase(base + SleighBase::MAX_UNIQUE_SIZE); return base; } @@ -2874,7 +2930,7 @@ static void findSlaSpecs(vector &res, const string &dir, const string &s static void initCompiler(SleighCompile &compiler, map &defines, bool enableUnnecessaryPcodeWarning, bool disableLenientConflict, bool enableAllCollisionWarning, - bool enableAllNopWarning,bool enableDeadTempWarning,bool enforceLocalKeyWord) + bool enableAllNopWarning,bool enableDeadTempWarning,bool enforceLocalKeyWord, bool largeTemporaryWarning) { map::iterator iter = defines.begin(); @@ -2893,6 +2949,8 @@ static void initCompiler(SleighCompile &compiler, map &defines, b compiler.setDeadTempWarning(true); if (enforceLocalKeyWord) compiler.setEnforceLocalKeyWord(true); + if (largeTemporaryWarning) + compiler.setLargeTemporaryWarning(true); } static void segvHandler(int sig) { @@ -2920,6 +2978,7 @@ 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 << " -DNAME=VALUE defines a preprocessor macro NAME with value VALUE" << endl; exit(2); } @@ -2933,6 +2992,7 @@ int main(int argc,char **argv) bool enableAllNopWarning = false; bool enableDeadTempWarning = false; bool enforceLocalKeyWord = false; + bool largeTemporaryWarning = false; bool compileAll = false; @@ -2964,6 +3024,8 @@ int main(int argc,char **argv) enableDeadTempWarning = true; else if (argv[i][1] == 'e') enforceLocalKeyWord = true; + else if (argv[i][1] == 'o') + largeTemporaryWarning = true; #ifdef YYDEBUG else if (argv[i][1] == 'x') yydebug = 1; // Debug option @@ -2996,7 +3058,7 @@ int main(int argc,char **argv) SleighCompile compiler; initCompiler(compiler, defines, enableUnnecessaryPcodeWarning, disableLenientConflict, enableAllCollisionWarning, enableAllNopWarning, - enableDeadTempWarning, enforceLocalKeyWord); + enableDeadTempWarning, enforceLocalKeyWord,largeTemporaryWarning); retval = run_compilation(slaspec.c_str(),sla.c_str(),compiler); if (retval != 0) { return retval; // stop on first error @@ -3033,7 +3095,7 @@ int main(int argc,char **argv) SleighCompile compiler; initCompiler(compiler, defines, enableUnnecessaryPcodeWarning, disableLenientConflict, enableAllCollisionWarning, enableAllNopWarning, - enableDeadTempWarning, enforceLocalKeyWord); + enableDeadTempWarning, enforceLocalKeyWord,largeTemporaryWarning); 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 30a7d1c284..29cb777cd2 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/slgh_compile.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/slgh_compile.hh @@ -97,8 +97,10 @@ class ConsistencyChecker { int4 unnecessarypcode; int4 readnowrite; int4 writenoread; + int4 largetemp; bool printextwarning; bool printdeadwarning; + bool printlargetempwarning; SubtableSymbol *root_symbol; vector postorder; map sizemap; // Sizes associated with tables @@ -109,6 +111,8 @@ class ConsistencyChecker { bool checkOpMisuse(OpTpl *op,Constructor *ct); bool sizeRestriction(OpTpl *op,Constructor *ct); bool checkConstructorSection(Constructor *ct,ConstructTpl *cttpl); + bool hasLargeTemporary(OpTpl *op); + bool isTemporaryAndTooBig(VarnodeTpl *vn); bool checkVarnodeTruncation(Constructor *ct,int4 slot,OpTpl *op,VarnodeTpl *vn,bool isbigendian); bool checkSectionTruncations(Constructor *ct,ConstructTpl *cttpl,bool isbigendian); bool checkSubtable(SubtableSymbol *sym); @@ -125,15 +129,17 @@ class ConsistencyChecker { OptimizeRecord *findValidRule(Constructor *ct,map &recs) const; void applyOptimization(Constructor *ct,const OptimizeRecord &rec); void checkUnusedTemps(Constructor *ct,const map &recs); + void checkLargeTemporaries(Constructor *ct); void optimize(Constructor *ct); public: - ConsistencyChecker(SleighCompile *sleigh, SubtableSymbol *rt,bool unnecessary,bool warndead); + ConsistencyChecker(SleighCompile *sleigh, SubtableSymbol *rt,bool unnecessary,bool warndead, bool warnlargetemp); bool test(void); bool testTruncations(bool isbigendian); void optimizeAll(void); int4 getNumUnnecessaryPcode(void) const { return unnecessarypcode; } int4 getNumReadNoWrite(void) const { return readnowrite; } int4 getNumWriteNoRead(void) const { return writenoread; } + int4 getNumLargeTemporaries(void) const {return largetemp;} }; struct FieldContext { @@ -200,6 +206,7 @@ private: bool warnunnecessarypcode; // True if we warn of unnecessary ZEXT or SEXT bool warndeadtemps; // True if we warn of temporaries that are written but not read bool lenientconflicterrors; // True if we ignore most pattern conflict errors + bool largetemporarywarning; // True if we warn about temporaries larger than SleighBase::MAX_UNIQUE_SIZE bool warnalllocalcollisions; // True if local export collisions generate individual warnings bool warnallnops; // True if pcode NOPs generate individual warnings vector noplist; // List of individual NOP warnings @@ -244,6 +251,7 @@ public: void setUnnecessaryPcodeWarning(bool val) { warnunnecessarypcode = val; } void setDeadTempWarning(bool val) { warndeadtemps = val; } void setEnforceLocalKeyWord(bool val) { pcode.setEnforceLocalKey(val); } + void setLargeTemporaryWarning (bool val) {largetemporarywarning = val;} void setLenientConflict(bool val) { lenientconflicterrors = val; } void setLocalCollisionWarning(bool val) { warnalllocalcollisions = val; } void setAllNopWarning(bool val) { warnallnops = val; } 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 7a7cf2e32a..ca99fc6cc2 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 @@ -35,6 +35,8 @@ public abstract class SleighBase extends Translate implements NamedSymbolProvide public static final int SLA_FORMAT_VERSION = 2; // What format of the .sla file this produces // This value should always match SleighLanguage.SLA_FORMAT_VERSION + public static final long MAX_UNIQUE_SIZE = 128; //Maximum size of a varnode in the unique space. + //Should match value in sleighbase.cc private VectorSTL userop = new VectorSTL<>(); private address_set varnode_xref = new address_set(); // Cross-reference registers by address protected SubtableSymbol root; 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 98a3bf1c3f..86a641bf09 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 @@ -23,16 +23,22 @@ import ghidra.pcodeCPort.opcodes.OpCode; import ghidra.pcodeCPort.semantics.*; import ghidra.pcodeCPort.semantics.ConstTpl.const_type; import ghidra.pcodeCPort.semantics.ConstTpl.v_field; +import ghidra.pcodeCPort.sleighbase.SleighBase; import ghidra.pcodeCPort.slghsymbol.*; import ghidra.pcodeCPort.space.AddrSpace; +import ghidra.util.Msg; class ConsistencyChecker { int unnecessarypcode; int readnowrite; int writenoread; + // number of constructors using a temporary varnode larger than SleighBase.MAX_UNIQUE_SIZE + int largetemp; boolean printextwarning; boolean printdeadwarning; + //if true, print information about constructors using temporary varnodes larger than SleighBase.MAX_UNIQUE_SIZE + boolean printlargetempwarning; SleighCompile compiler; SubtableSymbol root_symbol; VectorSTL postorder = new VectorSTL<>(); @@ -98,7 +104,7 @@ class ConsistencyChecker { return true; } printOpError(op, ct, -1, 0, "Input and output sizes must match; " + - op.getIn(0).getSize() + " != " + op.getOut().getSize()); + op.getIn(0).getSize() + " != " + op.getOut().getSize()); return false; case CPUI_INT_ADD: case CPUI_INT_SUB: @@ -493,9 +499,9 @@ class ConsistencyChecker { StringBuilder sb = new StringBuilder(); sb.append("Size restriction error in table '") - .append(sym.getName()) - .append("' in constructor at ").append(ct.location) - .append("\n"); + .append(sym.getName()) + .append("' in constructor at ").append(ct.location) + .append("\n"); sb.append(" Problem"); @@ -637,6 +643,38 @@ class ConsistencyChecker { return testresult; } + /** + * Returns true precisely when {@code opTpl} uses a {@link VarnodeTpl} in + * the unique space whose size is larger than {@link SleighBase#MAX_UNIQUE_SIZE}. + * Note that this method returns as soon as one large {@link VarnodeTpl} is found. + * @param opTpl the op to check + * @return true if {@code opTpl} uses a large temporary varnode + */ + boolean hasLargeTemporary(OpTpl opTpl) { + VarnodeTpl out = opTpl.getOut(); + if (out != null && isTemporaryAndTooBig(out)) { + return true; + } + for (int i = 0; i < opTpl.numInput(); ++i) { + VarnodeTpl in = opTpl.getIn(i); + if (isTemporaryAndTooBig(in)) { + return true; + } + } + return false; + } + + /** + * Returns true precisely when {@code vn} is in the unique space + * and has a size larger than {@link SleighBase#MAX_UNIQUE_SIZE}. + * @param vn varnode template to check + * @return true if it uses a large temporary + */ + boolean isTemporaryAndTooBig(VarnodeTpl vn) { + return vn.getSpace().isUniqueSpace() && + vn.getSize().getReal() > SleighBase.MAX_UNIQUE_SIZE; + } + boolean checkVarnodeTruncation(Constructor ct,int slot,OpTpl op,VarnodeTpl vn,boolean isbigendian) { ConstTpl off = vn.getOffset(); if (off.getType() != const_type.handle) { @@ -1131,6 +1169,25 @@ class ConsistencyChecker { iter.increment(); } } + + /** + * Checks {@code ct} to see whether it contains an {@link OpTpl} which + * uses a varnode in the unique space which is larger than {@link SleighBase#MAX_UNIQUE_SIZE}. + * @param ct constructor to check + */ + void checkLargeTemporaries(Constructor ct) { + ConstructTpl ctTpl = ct.getTempl(); + VectorSTL ops = ctTpl.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++; + return; + } + } + } void optimize(Constructor ct) { OptimizeRecord currec; @@ -1149,16 +1206,21 @@ class ConsistencyChecker { } while (currec != null); checkUnusedTemps(ct, recs); + checkLargeTemporaries(ct); } - ConsistencyChecker(SleighCompile cp, SubtableSymbol rt, boolean unnecessary, boolean warndead) { + ConsistencyChecker(SleighCompile cp, SubtableSymbol rt, boolean unnecessary, boolean warndead, boolean warnlargetemp) { compiler = cp; root_symbol = rt; 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 @@ -1229,4 +1291,13 @@ class ConsistencyChecker { 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 + */ + int getNumLargeTemporaries() { + return largetemp; + } } 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 ad779e50bc..8e23e4ec5d 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 @@ -254,6 +254,7 @@ public class SleighCompile extends SleighBase { boolean warnunusedfields; // True if fields are defined but not used boolean enforcelocalkeyword; // Force slaspec to use 'local' keyword when defining temporary varnodes boolean lenientconflicterrors; // True if we ignore most pattern conflict errors + boolean largetemporarywarning; // True if we warn about temporaries larger than SleighBase.MAX_UNIQUE_SIZE public boolean warnalllocalcollisions; public boolean warnallnops; public VectorSTL noplist = new VectorSTL<>(); @@ -499,7 +500,7 @@ public class SleighCompile extends SleighBase { void checkConsistency() { entry("checkConsistency"); ConsistencyChecker checker = - new ConsistencyChecker(this, root, warnunnecessarypcode, warndeadtemps); + new ConsistencyChecker(this, root, warnunnecessarypcode, warndeadtemps, largetemporarywarning); if (!checker.test()) { errors += 1; @@ -524,6 +525,11 @@ public class SleighCompile extends SleighBase { " operations wrote to temporaries that were not read"); reportWarning(null, "Use -t switch to list each individually"); } + 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."); + } } static int findCollision(Map local2Operand, ArrayList locals, @@ -689,7 +695,7 @@ public class SleighCompile extends SleighBase { long getUniqueAddr() { entry("getUniqueAddr"); long base = getUniqueBase(); - setUniqueBase(base + 16); // Should be maximum size of a unique + setUniqueBase(base + MAX_UNIQUE_SIZE); return base; } @@ -713,6 +719,17 @@ public class SleighCompile extends SleighBase { enforcelocalkeyword = val; 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 + */ + void setLargeTemporaryWarning(boolean val) { + entry("setLargeTemporaryWarning",val); + largetemporarywarning = val; + } void setLenientConflict(boolean val) { entry("setLenientConflict", val); 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 109eabfeb7..5cbd23de59 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 @@ -49,7 +49,7 @@ public class SleighCompileLauncher implements GhidraLaunchable { private static void initCompiler(SleighCompile compiler, Map preprocs, boolean unnecessaryPcodeWarning, boolean lenientConflict, boolean allCollisionWarning, boolean allNopWarning, boolean deadTempWarning, boolean unusedFieldWarning, - boolean enforceLocalKeyWord) { + boolean enforceLocalKeyWord, boolean largeTemporaryWarning) { Set> entrySet = preprocs.entrySet(); for (Entry entry : entrySet) { compiler.setPreprocValue(entry.getKey(), entry.getValue()); @@ -61,6 +61,7 @@ public class SleighCompileLauncher implements GhidraLaunchable { compiler.setDeadTempWarning(deadTempWarning); compiler.setUnusedFieldWarning(unusedFieldWarning); compiler.setEnforceLocalKeyWord(enforceLocalKeyWord); + compiler.setLargeTemporaryWarning(largeTemporaryWarning); } @Override @@ -111,6 +112,7 @@ 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, " -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)"); Msg.info(SleighCompile.class, " -i inject options from specified file"); @@ -125,6 +127,7 @@ public class SleighCompileLauncher implements GhidraLaunchable { boolean deadTempWarning = false; boolean enforceLocalKeyWord = false; boolean unusedFieldWarning = false; + boolean largeTemporaryWarning = false; int i; for (i = 0; i < args.length; ++i) { @@ -185,6 +188,9 @@ 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) == 'x') { SleighCompile.yydebug = true; // Debug option } @@ -219,7 +225,7 @@ public class SleighCompileLauncher implements GhidraLaunchable { SleighCompile compiler = new SleighCompile(); initCompiler(compiler, preprocs, unnecessaryPcodeWarning, lenientConflict, allCollisionWarning, allNopWarning, deadTempWarning, unusedFieldWarning, - enforceLocalKeyWord); + enforceLocalKeyWord, largeTemporaryWarning); String outname = input.getName().replace(".slaspec", ".sla"); File output = new File(input.getParent(), outname); @@ -248,7 +254,7 @@ public class SleighCompileLauncher implements GhidraLaunchable { SleighCompile compiler = new SleighCompile(); initCompiler(compiler, preprocs, unnecessaryPcodeWarning, lenientConflict, allCollisionWarning, allNopWarning, deadTempWarning, unusedFieldWarning, - enforceLocalKeyWord); + enforceLocalKeyWord, largeTemporaryWarning); if (i == args.length) { Msg.error(SleighCompile.class, "Missing input file name"); return 1;