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;
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue