INDIRECT toggle and fix spacebase

This commit is contained in:
caheckman 2019-06-04 17:02:29 -04:00
parent 9cdd91a053
commit dadcb20918
2 changed files with 26 additions and 4 deletions

View file

@ -2207,11 +2207,16 @@ void ValueSetSolver::generateRelativeConstraint(PcodeOp *compOp,PcodeOp *cbranch
constraintsFromPath(typeCode,lift,endVn,endVn,cbranch); constraintsFromPath(typeCode,lift,endVn,endVn,cbranch);
} }
/// Given a set of sinks, find all the Varnodes that flow directly into them. /// \brief Build value sets for a data-flow system
///
/// Given a set of sinks, find all the Varnodes that flow directly into them and set up their
/// initial ValueSet objects.
/// \param sinks is the list terminating Varnodes /// \param sinks is the list terminating Varnodes
/// \param reads are add-on PcodeOps where we would like to know input ValueSets at the point of read /// \param reads are add-on PcodeOps where we would like to know input ValueSets at the point of read
/// \param stackReg (if non-NULL) gives the stack pointer (for keeping track of relative offsets) /// \param stackReg (if non-NULL) gives the stack pointer (for keeping track of relative offsets)
void ValueSetSolver::establishValueSets(const vector<Varnode *> &sinks,const vector<PcodeOp *> &reads,Varnode *stackReg) /// \param indirectAsCopy is \b true if solver should treat CPUI_INDIRECT as CPUI_COPY operations
void ValueSetSolver::establishValueSets(const vector<Varnode *> &sinks,const vector<PcodeOp *> &reads,Varnode *stackReg,
bool indirectAsCopy)
{ {
vector<Varnode *> worklist; vector<Varnode *> worklist;
@ -2234,7 +2239,10 @@ void ValueSetSolver::establishValueSets(const vector<Varnode *> &sinks,const vec
workPos += 1; workPos += 1;
if (!vn->isWritten()) { if (!vn->isWritten()) {
if (vn->isConstant()) { if (vn->isConstant()) {
if (vn->loneDescend()->numInput() == 1) // Constant inputs to binary ops should not be treated as root nodes as they
// get picked up during iteration by the other input, except in the case of a
// a PTRSUB from a spacebase constant.
if (vn->isSpacebase() || vn->loneDescend()->numInput() == 1)
rootNodes.push_back(vn->getValueSet()); rootNodes.push_back(vn->getValueSet());
} }
else else
@ -2243,6 +2251,20 @@ void ValueSetSolver::establishValueSets(const vector<Varnode *> &sinks,const vec
} }
PcodeOp *op = vn->getDef(); PcodeOp *op = vn->getDef();
switch(op->code()) { // Distinguish ops where we can never predict an integer range switch(op->code()) { // Distinguish ops where we can never predict an integer range
case CPUI_INDIRECT:
if (indirectAsCopy) {
Varnode *inVn = op->getIn(0);
if (!inVn->isMark()) {
newValueSet(inVn,0);
inVn->setMark();
worklist.push_back(inVn);
}
}
else {
vn->getValueSet()->setFull();
rootNodes.push_back(vn->getValueSet());
}
break;
case CPUI_CALL: case CPUI_CALL:
case CPUI_CALLIND: case CPUI_CALLIND:
case CPUI_CALLOTHER: case CPUI_CALLOTHER:

View file

@ -233,7 +233,7 @@ class ValueSetSolver {
bool checkRelativeConstant(Varnode *vn,int4 &typeCode,uintb &value) const; ///< Check if the given Varnode is a \e relative constant bool checkRelativeConstant(Varnode *vn,int4 &typeCode,uintb &value) const; ///< Check if the given Varnode is a \e relative constant
void generateRelativeConstraint(PcodeOp *compOp,PcodeOp *cbranch); ///< Try to find a \e relative constraint void generateRelativeConstraint(PcodeOp *compOp,PcodeOp *cbranch); ///< Try to find a \e relative constraint
public: public:
void establishValueSets(const vector<Varnode *> &sinks,const vector<PcodeOp *> &reads,Varnode *stackReg); ///< Build value sets for a data-flow system void establishValueSets(const vector<Varnode *> &sinks,const vector<PcodeOp *> &reads,Varnode *stackReg,bool indirectAsCopy);
int4 getNumIterations(void) const { return numIterations; } ///< Get the current number of iterations int4 getNumIterations(void) const { return numIterations; } ///< Get the current number of iterations
void solve(int4 max); ///< Iterate the ValueSet system until it stabilizes void solve(int4 max); ///< Iterate the ValueSet system until it stabilizes
list<ValueSet>::const_iterator beginValueSets(void) const { return valueNodes.begin(); } ///< Start of all ValueSets in the system list<ValueSet>::const_iterator beginValueSets(void) const { return valueNodes.begin(); } ///< Start of all ValueSets in the system