basic detection of local collisions

This commit is contained in:
caheckman 2019-08-14 15:17:22 -04:00
parent 0af34a4197
commit 8cce24b334
6 changed files with 94 additions and 0 deletions

View file

@ -797,6 +797,19 @@ int4 ConstructTpl::fillinBuild(vector<int4> &check,AddrSpace *const_space)
return 0;
}
bool ConstructTpl::buildOnly(void) const
{
vector<OpTpl *>::const_iterator iter;
OpTpl *op;
for(iter=vec.begin();iter!=vec.end();++iter) {
op = *iter;
if (op->getOpcode() != BUILD)
return false;
}
return true;
}
void ConstructTpl::changeHandleIndex(const vector<int4> &handmap)
{

View file

@ -178,6 +178,7 @@ public:
bool addOpList(const vector<OpTpl *> &oplist);
void setResult(HandleTpl *t) { result = t; }
int4 fillinBuild(vector<int4> &check,AddrSpace *const_space);
bool buildOnly(void) const;
void changeHandleIndex(const vector<int4> &handmap);
void setInput(VarnodeTpl *vn,int4 index,int4 slot);
void setOutput(VarnodeTpl *vn,int4 index);

View file

@ -788,6 +788,35 @@ void ConsistencyChecker::printOpError(OpTpl *op,Constructor *ct,int4 err1,int4 e
cerr << " operator" << endl << " " << msg << endl;
}
bool ConsistencyChecker::checkLocalExports(Constructor *ct)
{
if (ct->getTempl() == (ConstructTpl *)0)
return true; // No template, collisions impossible
if (ct->getTempl()->buildOnly())
return true; // Operand exports aren't manipulated, so no collision is possible
if (ct->getNumOperands() < 2)
return true; // Collision can only happen with multiple operands
bool noCollisions = true;
set<uintb> collect;
ct->getOperand(0)->collectLocalValues(collect);
for(int4 i=1;i<ct->getNumOperands();++i) {
set<uintb> newCollect;
ct->getOperand(i)->collectLocalValues(newCollect);
if (newCollect.empty()) continue;
int4 newSize = collect.size() + newCollect.size();
collect.insert(newCollect.begin(),newCollect.end());
if (newSize != collect.size()) {
noCollisions = false;
cerr << "Possible local export collision with symbol ";
cerr << ct->getOperand(i)->getName();
cerr << " in constructor starting at line " << dec << ct->getLineno() << endl;
break; // Don't continue
}
}
return noCollisions;
}
bool ConsistencyChecker::checkConstructorSection(Constructor *ct,ConstructTpl *cttpl)
{ // Check all the OpTpl s within the given section for consistency, return true if all tests pass
@ -866,6 +895,7 @@ bool ConsistencyChecker::checkSubtable(SubtableSymbol *sym)
for(int4 i=0;i<numconstruct;++i) {
ct = sym->getConstructor(i);
checkLocalExports(ct);
if (!checkConstructorSection(ct,ct->getTempl()))
testresult = false;
int4 numsection = ct->getNumSections();

View file

@ -105,6 +105,7 @@ class ConsistencyChecker {
int4 recoverSize(const ConstTpl &sizeconst,Constructor *ct);
bool checkOpMisuse(OpTpl *op,Constructor *ct);
bool sizeRestriction(OpTpl *op,Constructor *ct);
bool checkLocalExports(Constructor *ct);
bool checkConstructorSection(Constructor *ct,ConstructTpl *cttpl);
bool checkVarnodeTruncation(Constructor *ct,int4 slot,OpTpl *op,VarnodeTpl *vn,bool isbigendian);
bool checkSectionTruncations(Constructor *ct,ConstructTpl *cttpl,bool isbigendian);

View file

@ -728,6 +728,13 @@ void VarnodeSymbol::getFixedHandle(FixedHandle &hand,ParserWalker &walker) const
hand.size = fix.size;
}
void VarnodeSymbol::collectLocalValues(set<uintb> &results) const
{
if (fix.space->getType() == IPTR_INTERNAL)
results.insert(fix.offset);
}
void VarnodeSymbol::saveXml(ostream &s) const
{
@ -1034,6 +1041,13 @@ void OperandSymbol::print(ostream &s,ParserWalker &walker) const
walker.popOperand();
}
void OperandSymbol::collectLocalValues(set<uintb> &results) const
{
if (triple != (TripleSymbol *)0)
triple->collectLocalValues(results);
}
void OperandSymbol::saveXml(ostream &s) const
{
@ -1542,6 +1556,29 @@ void Constructor::markSubtableOperands(vector<int4> &check) const
}
}
void Constructor::collectLocalExports(set<uintb> &results) const
{
if (templ == (ConstructTpl *)0) return;
HandleTpl *handle = templ->getResult();
if (handle == (HandleTpl *)0) return;
if (handle->getSpace().isConstSpace()) return; // Even if the value is dynamic, the pointed to value won't get used
if (handle->getPtrSpace().getType() != ConstTpl::real) {
if (handle->getTempSpace().isUniqueSpace())
results.insert(handle->getTempOffset().getReal());
return;
}
if (handle->getSpace().isUniqueSpace()) {
results.insert(handle->getPtrOffset().getReal());
return;
}
if (handle->getSpace().getType() == ConstTpl::handle) {
int4 handleIndex = handle->getSpace().getHandleIndex();
OperandSymbol *opSym = getOperand(handleIndex);
opSym->collectLocalValues(results);
}
}
bool Constructor::isRecursive(void) const
{ // Does this constructor cause recursion with its table
@ -1862,6 +1899,13 @@ SubtableSymbol::~SubtableSymbol(void)
delete *iter;
}
void SubtableSymbol::collectLocalValues(set<uintb> &results) const
{
for(int4 i=0;i<construct.size();++i)
construct[i]->collectLocalExports(results);
}
void SubtableSymbol::saveXml(ostream &s) const
{

View file

@ -152,6 +152,7 @@ public:
virtual void getFixedHandle(FixedHandle &hand,ParserWalker &walker) const=0;
virtual int4 getSize(void) const { return 0; } // Size out of context
virtual void print(ostream &s,ParserWalker &walker) const=0;
virtual void collectLocalValues(set<uintb> &results) const {}
};
class FamilySymbol : public TripleSymbol {
@ -254,6 +255,7 @@ public:
virtual int4 getSize(void) const { return fix.size; }
virtual void print(ostream &s,ParserWalker &walker) const {
s << getName(); }
virtual void collectLocalValues(set<uintb> &results) const;
virtual symbol_type getType(void) const { return varnode_symbol; }
virtual void saveXml(ostream &s) const;
virtual void saveXmlHeader(ostream &s) const;
@ -348,6 +350,7 @@ public:
virtual void getFixedHandle(FixedHandle &hnd,ParserWalker &walker) const;
virtual int4 getSize(void) const;
virtual void print(ostream &s,ParserWalker &walker) const;
virtual void collectLocalValues(set<uintb> &results) const;
virtual symbol_type getType(void) const { return operand_symbol; }
virtual void saveXml(ostream &s) const;
virtual void saveXmlHeader(ostream &s) const;
@ -513,6 +516,7 @@ public:
(*iter)->apply(walker);
}
void markSubtableOperands(vector<int4> &check) const;
void collectLocalExports(set<uintb> &results) const;
void setError(bool val) const { inerror = val; }
bool isError(void) const { return inerror; }
bool isRecursive(void) const;
@ -578,6 +582,7 @@ public:
virtual int4 getSize(void) const { return -1; }
virtual void print(ostream &s,ParserWalker &walker) const {
throw SleighError("Cannot use subtable in expression"); }
virtual void collectLocalValues(set<uintb> &results) const;
virtual symbol_type getType(void) const { return subtable_symbol; }
virtual void saveXml(ostream &s) const;
virtual void saveXmlHeader(ostream &s) const;