Merge remote-tracking branch

'origin/GP-520_James_max_unique_varnode_size'
This commit is contained in:
ghidra1 2021-01-26 11:40:21 -05:00
commit a3f223619c
10 changed files with 196 additions and 27 deletions

View file

@ -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)

View file

@ -17,6 +17,8 @@
const int4 SleighBase::SLA_FORMAT_VERSION = 3;
const uintb SleighBase::MAX_UNIQUE_SIZE = 128;
int4 SourceFileIndexer::index(const string filename){
auto it = fileToIndex.find(filename);
if (fileToIndex.end() != it){
@ -57,7 +59,6 @@ void SourceFileIndexer::saveXml(ostream& s) const {
s << "</sourcefiles>\n";
}
SleighBase::SleighBase(void)
{

View file

@ -69,6 +69,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

View file

@ -183,7 +183,7 @@ SubtableSymbol *WithBlock::getCurrentSubtable(const list<WithBlock> &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; ///<Number of constructors using at least one temporary varnode larger than SleighBase::MAX_UNIQUE_SIZE
printextwarning = un;
printdeadwarning = warndead;
printlargetempwarning = warnlargetemp; ///< If true, prints a warning about each constructor using a temporary varnode larger than SleighBase::MAX_UNIQUE_SIZE
}
int4 ConsistencyChecker::recoverSize(const ConstTpl &sizeconst,Constructor *ct)
@ -814,6 +816,33 @@ bool ConsistencyChecker::checkConstructorSection(Constructor *ct,ConstructTpl *c
return testresult;
}
///
/// Returns true if the output or one of the inputs of
/// op is in the unique space and larger than SleighBase::MAX_UNIQUE_SIZE
///
bool ConsistencyChecker::hasLargeTemporary(OpTpl *op){
VarnodeTpl *out = op->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<uintb,Optimi
}
}
///
/// Checks the ops in ct to see whether a varnode larger than
/// SleighBase::MAX_UNIQUE_SIZE is used. Note that this method
/// returns after the first large varnode is found.
///
void ConsistencyChecker::checkLargeTemporaries(Constructor *ct){
vector<OpTpl *> ops = ct->getTempl()->getOpvec();
for (vector<OpTpl *>::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<uintb,int4> &local2Operand,const vector<uintb> &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;
}
@ -2876,7 +2932,7 @@ static void findSlaSpecs(vector<string> &res, const string &dir, const string &s
static void initCompiler(SleighCompile &compiler, map<string,string> &defines, bool enableUnnecessaryPcodeWarning,
bool disableLenientConflict, bool enableAllCollisionWarning,
bool enableAllNopWarning,bool enableDeadTempWarning,bool enforceLocalKeyWord)
bool enableAllNopWarning,bool enableDeadTempWarning,bool enforceLocalKeyWord, bool largeTemporaryWarning)
{
map<string,string>::iterator iter = defines.begin();
@ -2895,6 +2951,8 @@ static void initCompiler(SleighCompile &compiler, map<string,string> &defines, b
compiler.setDeadTempWarning(true);
if (enforceLocalKeyWord)
compiler.setEnforceLocalKeyWord(true);
if (largeTemporaryWarning)
compiler.setLargeTemporaryWarning(true);
}
static void segvHandler(int sig) {
@ -2922,6 +2980,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);
}
@ -2935,6 +2994,7 @@ int main(int argc,char **argv)
bool enableAllNopWarning = false;
bool enableDeadTempWarning = false;
bool enforceLocalKeyWord = false;
bool largeTemporaryWarning = false;
bool compileAll = false;
@ -2966,6 +3026,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
@ -2998,7 +3060,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
@ -3035,7 +3097,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]);

View file

@ -97,8 +97,10 @@ class ConsistencyChecker {
int4 unnecessarypcode;
int4 readnowrite;
int4 writenoread;
int4 largetemp;
bool printextwarning;
bool printdeadwarning;
bool printlargetempwarning;
SubtableSymbol *root_symbol;
vector<SubtableSymbol *> postorder;
map<SubtableSymbol *,int4> 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<uintb,OptimizeRecord> &recs) const;
void applyOptimization(Constructor *ct,const OptimizeRecord &rec);
void checkUnusedTemps(Constructor *ct,const map<uintb,OptimizeRecord> &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<string> 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; }