mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 02:39:44 +02:00
Merge remote-tracking branch
'origin/GP-520_James_max_unique_varnode_size'
This commit is contained in:
commit
a3f223619c
10 changed files with 196 additions and 27 deletions
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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; }
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue