mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 18:29:37 +02:00
basic detection of local collisions
This commit is contained in:
parent
0af34a4197
commit
8cce24b334
6 changed files with 94 additions and 0 deletions
|
@ -797,6 +797,19 @@ int4 ConstructTpl::fillinBuild(vector<int4> &check,AddrSpace *const_space)
|
||||||
return 0;
|
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)
|
void ConstructTpl::changeHandleIndex(const vector<int4> &handmap)
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
@ -178,6 +178,7 @@ public:
|
||||||
bool addOpList(const vector<OpTpl *> &oplist);
|
bool addOpList(const vector<OpTpl *> &oplist);
|
||||||
void setResult(HandleTpl *t) { result = t; }
|
void setResult(HandleTpl *t) { result = t; }
|
||||||
int4 fillinBuild(vector<int4> &check,AddrSpace *const_space);
|
int4 fillinBuild(vector<int4> &check,AddrSpace *const_space);
|
||||||
|
bool buildOnly(void) const;
|
||||||
void changeHandleIndex(const vector<int4> &handmap);
|
void changeHandleIndex(const vector<int4> &handmap);
|
||||||
void setInput(VarnodeTpl *vn,int4 index,int4 slot);
|
void setInput(VarnodeTpl *vn,int4 index,int4 slot);
|
||||||
void setOutput(VarnodeTpl *vn,int4 index);
|
void setOutput(VarnodeTpl *vn,int4 index);
|
||||||
|
|
|
@ -788,6 +788,35 @@ void ConsistencyChecker::printOpError(OpTpl *op,Constructor *ct,int4 err1,int4 e
|
||||||
cerr << " operator" << endl << " " << msg << endl;
|
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)
|
bool ConsistencyChecker::checkConstructorSection(Constructor *ct,ConstructTpl *cttpl)
|
||||||
|
|
||||||
{ // Check all the OpTpl s within the given section for consistency, return true if all tests pass
|
{ // 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) {
|
for(int4 i=0;i<numconstruct;++i) {
|
||||||
ct = sym->getConstructor(i);
|
ct = sym->getConstructor(i);
|
||||||
|
checkLocalExports(ct);
|
||||||
if (!checkConstructorSection(ct,ct->getTempl()))
|
if (!checkConstructorSection(ct,ct->getTempl()))
|
||||||
testresult = false;
|
testresult = false;
|
||||||
int4 numsection = ct->getNumSections();
|
int4 numsection = ct->getNumSections();
|
||||||
|
|
|
@ -105,6 +105,7 @@ class ConsistencyChecker {
|
||||||
int4 recoverSize(const ConstTpl &sizeconst,Constructor *ct);
|
int4 recoverSize(const ConstTpl &sizeconst,Constructor *ct);
|
||||||
bool checkOpMisuse(OpTpl *op,Constructor *ct);
|
bool checkOpMisuse(OpTpl *op,Constructor *ct);
|
||||||
bool sizeRestriction(OpTpl *op,Constructor *ct);
|
bool sizeRestriction(OpTpl *op,Constructor *ct);
|
||||||
|
bool checkLocalExports(Constructor *ct);
|
||||||
bool checkConstructorSection(Constructor *ct,ConstructTpl *cttpl);
|
bool checkConstructorSection(Constructor *ct,ConstructTpl *cttpl);
|
||||||
bool checkVarnodeTruncation(Constructor *ct,int4 slot,OpTpl *op,VarnodeTpl *vn,bool isbigendian);
|
bool checkVarnodeTruncation(Constructor *ct,int4 slot,OpTpl *op,VarnodeTpl *vn,bool isbigendian);
|
||||||
bool checkSectionTruncations(Constructor *ct,ConstructTpl *cttpl,bool isbigendian);
|
bool checkSectionTruncations(Constructor *ct,ConstructTpl *cttpl,bool isbigendian);
|
||||||
|
|
|
@ -728,6 +728,13 @@ void VarnodeSymbol::getFixedHandle(FixedHandle &hand,ParserWalker &walker) const
|
||||||
hand.size = fix.size;
|
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
|
void VarnodeSymbol::saveXml(ostream &s) const
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -1034,6 +1041,13 @@ void OperandSymbol::print(ostream &s,ParserWalker &walker) const
|
||||||
walker.popOperand();
|
walker.popOperand();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OperandSymbol::collectLocalValues(set<uintb> &results) const
|
||||||
|
|
||||||
|
{
|
||||||
|
if (triple != (TripleSymbol *)0)
|
||||||
|
triple->collectLocalValues(results);
|
||||||
|
}
|
||||||
|
|
||||||
void OperandSymbol::saveXml(ostream &s) const
|
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
|
bool Constructor::isRecursive(void) const
|
||||||
|
|
||||||
{ // Does this constructor cause recursion with its table
|
{ // Does this constructor cause recursion with its table
|
||||||
|
@ -1862,6 +1899,13 @@ SubtableSymbol::~SubtableSymbol(void)
|
||||||
delete *iter;
|
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
|
void SubtableSymbol::saveXml(ostream &s) const
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
@ -152,6 +152,7 @@ public:
|
||||||
virtual void getFixedHandle(FixedHandle &hand,ParserWalker &walker) const=0;
|
virtual void getFixedHandle(FixedHandle &hand,ParserWalker &walker) const=0;
|
||||||
virtual int4 getSize(void) const { return 0; } // Size out of context
|
virtual int4 getSize(void) const { return 0; } // Size out of context
|
||||||
virtual void print(ostream &s,ParserWalker &walker) const=0;
|
virtual void print(ostream &s,ParserWalker &walker) const=0;
|
||||||
|
virtual void collectLocalValues(set<uintb> &results) const {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class FamilySymbol : public TripleSymbol {
|
class FamilySymbol : public TripleSymbol {
|
||||||
|
@ -254,6 +255,7 @@ public:
|
||||||
virtual int4 getSize(void) const { return fix.size; }
|
virtual int4 getSize(void) const { return fix.size; }
|
||||||
virtual void print(ostream &s,ParserWalker &walker) const {
|
virtual void print(ostream &s,ParserWalker &walker) const {
|
||||||
s << getName(); }
|
s << getName(); }
|
||||||
|
virtual void collectLocalValues(set<uintb> &results) const;
|
||||||
virtual symbol_type getType(void) const { return varnode_symbol; }
|
virtual symbol_type getType(void) const { return varnode_symbol; }
|
||||||
virtual void saveXml(ostream &s) const;
|
virtual void saveXml(ostream &s) const;
|
||||||
virtual void saveXmlHeader(ostream &s) const;
|
virtual void saveXmlHeader(ostream &s) const;
|
||||||
|
@ -348,6 +350,7 @@ public:
|
||||||
virtual void getFixedHandle(FixedHandle &hnd,ParserWalker &walker) const;
|
virtual void getFixedHandle(FixedHandle &hnd,ParserWalker &walker) const;
|
||||||
virtual int4 getSize(void) const;
|
virtual int4 getSize(void) const;
|
||||||
virtual void print(ostream &s,ParserWalker &walker) 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 symbol_type getType(void) const { return operand_symbol; }
|
||||||
virtual void saveXml(ostream &s) const;
|
virtual void saveXml(ostream &s) const;
|
||||||
virtual void saveXmlHeader(ostream &s) const;
|
virtual void saveXmlHeader(ostream &s) const;
|
||||||
|
@ -513,6 +516,7 @@ public:
|
||||||
(*iter)->apply(walker);
|
(*iter)->apply(walker);
|
||||||
}
|
}
|
||||||
void markSubtableOperands(vector<int4> &check) const;
|
void markSubtableOperands(vector<int4> &check) const;
|
||||||
|
void collectLocalExports(set<uintb> &results) const;
|
||||||
void setError(bool val) const { inerror = val; }
|
void setError(bool val) const { inerror = val; }
|
||||||
bool isError(void) const { return inerror; }
|
bool isError(void) const { return inerror; }
|
||||||
bool isRecursive(void) const;
|
bool isRecursive(void) const;
|
||||||
|
@ -578,6 +582,7 @@ public:
|
||||||
virtual int4 getSize(void) const { return -1; }
|
virtual int4 getSize(void) const { return -1; }
|
||||||
virtual void print(ostream &s,ParserWalker &walker) const {
|
virtual void print(ostream &s,ParserWalker &walker) const {
|
||||||
throw SleighError("Cannot use subtable in expression"); }
|
throw SleighError("Cannot use subtable in expression"); }
|
||||||
|
virtual void collectLocalValues(set<uintb> &results) const;
|
||||||
virtual symbol_type getType(void) const { return subtable_symbol; }
|
virtual symbol_type getType(void) const { return subtable_symbol; }
|
||||||
virtual void saveXml(ostream &s) const;
|
virtual void saveXml(ostream &s) const;
|
||||||
virtual void saveXmlHeader(ostream &s) const;
|
virtual void saveXmlHeader(ostream &s) const;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue