mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-11-12 23:23:17 +00:00
relative constraints
This commit is contained in:
parent
e96f39a98f
commit
16fd5df590
@ -170,8 +170,8 @@ bool CircleRange::newDomain(uintb newMask,int4 newStep,uintb &myleft,uintb &myri
|
||||
/// then proceeds by the given \e step up to (but not including) the given
|
||||
/// right boundary. Care should be taken to make sure the remainders of the
|
||||
/// left and right boundaries modulo the step are equal.
|
||||
/// \param mn is the left boundary of the range
|
||||
/// \param mx is the right boundary of the range
|
||||
/// \param lft is the left boundary of the range
|
||||
/// \param rgt is the right boundary of the range
|
||||
/// \param size is the domain size in bytes (1,2,4,8,..)
|
||||
/// \param stp is the desired step (1,2,4,8,..)
|
||||
CircleRange::CircleRange(uintb lft,uintb rgt,int4 size,int4 stp)
|
||||
@ -1373,7 +1373,7 @@ int4 CircleRange::translate2Op(OpCode &opc,uintb &c,int4 &cslot) const
|
||||
return 2; // Cannot represent
|
||||
}
|
||||
|
||||
/// \param is the stream to write to
|
||||
/// \param s is the stream to write to
|
||||
void CircleRange::printRaw(ostream &s) const
|
||||
|
||||
{
|
||||
@ -1440,8 +1440,9 @@ void ValueSet::setVarnode(Varnode *v,int4 tCode)
|
||||
|
||||
/// Equations are stored as an array of (slot,range) pairs, ordered on slot.
|
||||
/// \param slot is the given slot
|
||||
/// \param range is the given range
|
||||
void ValueSet::addEquation(int4 slot,const CircleRange &constraint)
|
||||
/// \param type is the constraint characteristic
|
||||
/// \param constraint is the given range
|
||||
void ValueSet::addEquation(int4 slot,int4 type,const CircleRange &constraint)
|
||||
|
||||
{
|
||||
vector<Equation>::iterator iter;
|
||||
@ -1451,7 +1452,7 @@ void ValueSet::addEquation(int4 slot,const CircleRange &constraint)
|
||||
break;
|
||||
++iter;
|
||||
}
|
||||
equations.insert(iter,Equation(slot,constraint));
|
||||
equations.insert(iter,Equation(slot,type,constraint));
|
||||
}
|
||||
|
||||
/// For an iteration that isn't stabilizing attempt to widen \b this value set
|
||||
@ -1462,7 +1463,6 @@ void ValueSet::addEquation(int4 slot,const CircleRange &constraint)
|
||||
void ValueSet::doWidening(const CircleRange &newRange)
|
||||
|
||||
{
|
||||
count += 1;
|
||||
if (count < 2) {
|
||||
range = newRange;
|
||||
return;
|
||||
@ -1470,7 +1470,7 @@ void ValueSet::doWidening(const CircleRange &newRange)
|
||||
else if (count == 2) {
|
||||
if (!equations.empty()) { // Look for landmark
|
||||
const Equation &landmark(equations.back());
|
||||
if (landmark.slot == numParams) {
|
||||
if (landmark.slot == numParams && typeCode == landmark.typeCode) {
|
||||
bool leftIsStable = range.getMin() == newRange.getMin();
|
||||
if (landmark.range.contains(range)) {
|
||||
range.widen(landmark.range,leftIsStable);
|
||||
@ -1491,7 +1491,7 @@ void ValueSet::doWidening(const CircleRange &newRange)
|
||||
range = newRange;
|
||||
return;
|
||||
}
|
||||
range.setFull(vn->getSize()); // In all other cases expand to everything
|
||||
setFull(); // In all other cases expand to everything
|
||||
}
|
||||
|
||||
/// Give \b this value set a chance to reset its counter do to looping
|
||||
@ -1502,6 +1502,47 @@ void ValueSet::looped(void)
|
||||
count = 2; // Reset to point just after any widening
|
||||
}
|
||||
|
||||
/// Examine the input value sets that determine \b this set and decide if it
|
||||
/// is relative. In general, \b this will be relative if any of its inputs are.
|
||||
/// Certain combinations are indeterminate, which this method flags by calling
|
||||
/// setFull(). The Varnode attached to \b this must have a defining op.
|
||||
void ValueSet::computeTypeCode(void)
|
||||
|
||||
{
|
||||
int4 relCount = 0;
|
||||
int4 lastTypeCode;
|
||||
PcodeOp *op = vn->getDef();
|
||||
for(int4 i=0;i<numParams;++i) {
|
||||
ValueSet *valueSet = op->getIn(i)->getValueSet();
|
||||
if (valueSet->typeCode != 0) {
|
||||
relCount += 1;
|
||||
lastTypeCode = valueSet->typeCode;
|
||||
}
|
||||
}
|
||||
if (relCount == 0) {
|
||||
typeCode = 0;
|
||||
return;
|
||||
}
|
||||
// Only certain operations can propagate a relative value set
|
||||
switch(opCode) {
|
||||
case CPUI_PTRSUB:
|
||||
case CPUI_INT_ADD:
|
||||
if (relCount == 1)
|
||||
typeCode = lastTypeCode;
|
||||
else
|
||||
setFull();
|
||||
break;
|
||||
case CPUI_COPY:
|
||||
case CPUI_INDIRECT:
|
||||
case CPUI_MULTIEQUAL:
|
||||
typeCode = lastTypeCode;
|
||||
break;
|
||||
default:
|
||||
setFull();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// Recalculate \b this value set by grabbing the value sets of the inputs to the
|
||||
/// operator defining the Varnode attached to \b this value set and pushing them
|
||||
/// forward through the operator.
|
||||
@ -1510,6 +1551,10 @@ bool ValueSet::iterate(void)
|
||||
|
||||
{
|
||||
if (!vn->isWritten()) return false;
|
||||
if (typeCode >= 100) return false;
|
||||
if (count == 0)
|
||||
computeTypeCode();
|
||||
count += 1; // Count this iteration
|
||||
CircleRange res;
|
||||
PcodeOp *op = vn->getDef();
|
||||
int4 eqPos = 0;
|
||||
@ -1517,7 +1562,7 @@ bool ValueSet::iterate(void)
|
||||
int4 pieces = 0;
|
||||
for(int4 i=0;i<numParams;++i) {
|
||||
ValueSet *inSet = op->getIn(i)->getValueSet();
|
||||
if (eqPos < equations.size() && equations[eqPos].slot == i) {
|
||||
if (doesEquationApply(eqPos, i)) {
|
||||
CircleRange rangeCopy(inSet->range);
|
||||
if (0 !=rangeCopy.intersect(equations[eqPos].range)) {
|
||||
rangeCopy = equations[eqPos].range;
|
||||
@ -1539,17 +1584,20 @@ bool ValueSet::iterate(void)
|
||||
}
|
||||
else if (numParams == 1) {
|
||||
ValueSet *inSet1 = op->getIn(0)->getValueSet();
|
||||
if (eqPos < equations.size() && equations[eqPos].slot == 0) {
|
||||
if (doesEquationApply(eqPos, 0)) {
|
||||
CircleRange rangeCopy(inSet1->range);
|
||||
if (0 != rangeCopy.intersect(equations[eqPos].range)) {
|
||||
rangeCopy = equations[eqPos].range;
|
||||
}
|
||||
if (!res.pushForwardUnary(opCode, rangeCopy, inSet1->vn->getSize(), vn->getSize()))
|
||||
res.setFull(vn->getSize());
|
||||
if (!res.pushForwardUnary(opCode, rangeCopy, inSet1->vn->getSize(), vn->getSize())) {
|
||||
setFull();
|
||||
return true;
|
||||
}
|
||||
eqPos += 1;
|
||||
}
|
||||
else if (!res.pushForwardUnary(opCode, inSet1->range, inSet1->vn->getSize(), vn->getSize())) {
|
||||
res.setFull(vn->getSize());
|
||||
setFull();
|
||||
return true;
|
||||
}
|
||||
typeCode = inSet1->typeCode;
|
||||
}
|
||||
@ -1562,23 +1610,26 @@ bool ValueSet::iterate(void)
|
||||
res.setFull(vn->getSize());
|
||||
}
|
||||
else if (equations.size() == 0) {
|
||||
if (!res.pushForwardBinary(opCode, inSet1->range, inSet2->range, inSet1->vn->getSize(), vn->getSize(), 32))
|
||||
res.setFull(vn->getSize());
|
||||
if (!res.pushForwardBinary(opCode, inSet1->range, inSet2->range, inSet1->vn->getSize(), vn->getSize(), 32)) {
|
||||
setFull();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
CircleRange range1 = inSet1->range;
|
||||
CircleRange range2 = inSet2->range;
|
||||
if (equations[eqPos].slot == 0) {
|
||||
if (doesEquationApply(eqPos, 0)) {
|
||||
if (0 != range1.intersect(equations[eqPos].range))
|
||||
range1 = equations[eqPos].range;
|
||||
eqPos += 1;
|
||||
}
|
||||
if (eqPos < equations.size() && equations[eqPos].slot == 1) {
|
||||
if (doesEquationApply(eqPos, 1)) {
|
||||
if (0 != range2.intersect(equations[eqPos].range))
|
||||
range2 = equations[eqPos].range;
|
||||
}
|
||||
if (!res.pushForwardBinary(opCode, range1, range2, inSet1->vn->getSize(), vn->getSize(), 32))
|
||||
res.setFull(vn->getSize());
|
||||
if (!res.pushForwardBinary(opCode, range1, range2, inSet1->vn->getSize(), vn->getSize(), 32)) {
|
||||
setFull();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -1778,9 +1829,10 @@ void ValueSetSolver::establishTopologicalOrder(void)
|
||||
/// the Varnode. An equation holding the constraint is added to the ValueSet of the Varnode
|
||||
/// output of the PcodeOp.
|
||||
/// \param vn is the given Varnode
|
||||
/// \param type is the constraint characteristic
|
||||
/// \param range is the known constraint (assuming the \b true branch was taken)
|
||||
/// \param splitPoint is the basic block making the conditional branch
|
||||
void ValueSetSolver::applyConstraints(Varnode *vn,const CircleRange &range,FlowBlock *splitPoint)
|
||||
void ValueSetSolver::applyConstraints(Varnode *vn,int4 type,const CircleRange &range,FlowBlock *splitPoint)
|
||||
|
||||
{
|
||||
list<PcodeOp *>::const_iterator iter;
|
||||
@ -1789,7 +1841,7 @@ void ValueSetSolver::applyConstraints(Varnode *vn,const CircleRange &range,FlowB
|
||||
defBlock = vn->getDef()->getParent();
|
||||
ValueSet *vSet = vn->getValueSet();
|
||||
if (vSet->opCode == CPUI_MULTIEQUAL) {
|
||||
vSet->addLandmark(range); // Leave landmark for widening
|
||||
vSet->addLandmark(type,range); // Leave landmark for widening
|
||||
}
|
||||
}
|
||||
FlowBlock *trueBlock = splitPoint->getTrueOut();
|
||||
@ -1802,13 +1854,13 @@ void ValueSetSolver::applyConstraints(Varnode *vn,const CircleRange &range,FlowB
|
||||
FlowBlock *curBlock = op->getParent();
|
||||
for(;;) {
|
||||
if (curBlock == trueBlock) {
|
||||
outVn->getValueSet()->addEquation(op->getSlot(vn), range);
|
||||
outVn->getValueSet()->addEquation(op->getSlot(vn), type, range);
|
||||
break;
|
||||
}
|
||||
else if (curBlock == falseBlock) {
|
||||
CircleRange falseRange(range);
|
||||
falseRange.invert();
|
||||
outVn->getValueSet()->addEquation(op->getSlot(vn), falseRange);
|
||||
outVn->getValueSet()->addEquation(op->getSlot(vn), type, falseRange);
|
||||
break;
|
||||
}
|
||||
else if (curBlock == splitPoint || curBlock == (FlowBlock *)0
|
||||
@ -1819,31 +1871,33 @@ void ValueSetSolver::applyConstraints(Varnode *vn,const CircleRange &range,FlowB
|
||||
}
|
||||
}
|
||||
|
||||
/// Knowing that there is a lifting path from the given CBRANCH to the given Varnode
|
||||
/// in the system, go ahead and left the \b true value range to a constraint range
|
||||
/// on the Varnode. Then look for reads of the Varnode where the constraint range applies.
|
||||
/// \param vn is the given Varnode in the system
|
||||
/// \param cbranch is the given CBRANCH
|
||||
void ValueSetSolver::constraintsFromPath(Varnode *vn,PcodeOp *cbranch)
|
||||
/// \brief Generate constraints given a Varnode path
|
||||
///
|
||||
/// Knowing that there is a lifting path from the given starting Varnode to an ending Varnode
|
||||
/// in the system, go ahead and lift the given range to a final constraint on the ending
|
||||
/// Varnode. Then look for reads of the Varnode where the constraint applies.
|
||||
/// \param type is the constraint characteristic
|
||||
/// \param lift is the given range that will be lifted
|
||||
/// \param startVn is the starting Varnode
|
||||
/// \param endVn is the given ending Varnode in the system
|
||||
/// \param splitPoint is the point where control-flow splits
|
||||
void ValueSetSolver::constraintsFromPath(int4 type,CircleRange &lift,Varnode *startVn,Varnode *endVn,FlowBlock *splitPoint)
|
||||
|
||||
{
|
||||
CircleRange lift(true);
|
||||
Varnode *curVn = cbranch->getIn(1);
|
||||
while(curVn != vn) {
|
||||
while(startVn != endVn) {
|
||||
Varnode *constVn;
|
||||
curVn = lift.pullBack(curVn->getDef(),&constVn,false);
|
||||
if (curVn == (Varnode *)0) return; // Couldn't pull all the back to our value set
|
||||
startVn = lift.pullBack(startVn->getDef(),&constVn,false);
|
||||
if (startVn == (Varnode *)0) return; // Couldn't pull all the way back to our value set
|
||||
}
|
||||
FlowBlock *splitPoint = cbranch->getParent();
|
||||
for(;;) {
|
||||
Varnode *constVn;
|
||||
applyConstraints(vn,lift,splitPoint);
|
||||
if (!vn->isWritten()) break;
|
||||
PcodeOp *op = vn->getDef();
|
||||
applyConstraints(endVn,type,lift,splitPoint);
|
||||
if (!endVn->isWritten()) break;
|
||||
PcodeOp *op = endVn->getDef();
|
||||
if (op->isCall() || op->isMarker()) break;
|
||||
vn = lift.pullBack(op,&constVn,false);
|
||||
if (vn == (Varnode *)0) break;
|
||||
if (!vn->isMark()) break;
|
||||
endVn = lift.pullBack(op,&constVn,false);
|
||||
if (endVn == (Varnode *)0) break;
|
||||
if (!endVn->isMark()) break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1864,11 +1918,21 @@ void ValueSetSolver::constraintsFromCBranch(PcodeOp *cbranch)
|
||||
int4 num = op->numInput();
|
||||
if (num == 0 || num > 2) break;
|
||||
vn = op->getIn(0);
|
||||
if (vn->isConstant() && num == 2)
|
||||
vn = op->getIn(1);
|
||||
if (num == 2) {
|
||||
if (vn->isConstant())
|
||||
vn = op->getIn(1);
|
||||
else if (!op->getIn(1)->isConstant()) {
|
||||
// If we reach here, both inputs are non-constant
|
||||
generateRelativeConstraint(op, cbranch);
|
||||
return;
|
||||
}
|
||||
// If we reach here, vn is non-constant, other input is constant
|
||||
}
|
||||
}
|
||||
if (vn->isMark()) {
|
||||
constraintsFromPath(vn,cbranch);
|
||||
CircleRange lift(true);
|
||||
Varnode *startVn = cbranch->getIn(1);
|
||||
constraintsFromPath(0,lift,startVn,vn,cbranch->getParent());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1905,6 +1969,98 @@ void ValueSetSolver::generateConstraints(vector<Varnode *> &worklist)
|
||||
blockList[i]->clearMark();
|
||||
}
|
||||
|
||||
/// Verify that the given Varnode is produced by a straight line sequence of
|
||||
/// COPYs, INT_ADDs with a constant, from the base register marked as \e relative
|
||||
/// for our system.
|
||||
/// \param vn is the given Varnode
|
||||
/// \param typeCode will hold the base register code (if found)
|
||||
/// \param value will hold the additive value relative to the base register (if found)
|
||||
/// \return \b true if the Varnode is a \e relative constant
|
||||
bool ValueSetSolver::checkRelativeConstant(Varnode *vn,int4 &typeCode,uintb &value) const
|
||||
|
||||
{
|
||||
value = 0;
|
||||
for(;;) {
|
||||
if (vn->isMark()) {
|
||||
ValueSet *valueSet = vn->getValueSet();
|
||||
if (valueSet->typeCode != 0) {
|
||||
typeCode = valueSet->typeCode;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!vn->isWritten()) return false;
|
||||
PcodeOp *op = vn->getDef();
|
||||
OpCode opc = op->code();
|
||||
if (opc == CPUI_COPY || opc == CPUI_INDIRECT)
|
||||
vn = op->getIn(0);
|
||||
else if (opc == CPUI_INT_ADD || opc == CPUI_PTRSUB) {
|
||||
Varnode *constVn = op->getIn(1);
|
||||
if (!constVn->isConstant())
|
||||
return false;
|
||||
value = (value + constVn->getOffset()) & calc_mask(constVn->getSize());
|
||||
vn = op->getIn(0);
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
return true; // Never reach here
|
||||
}
|
||||
|
||||
/// Given a binary PcodeOp producing a conditional branch, check if it can be interpreted
|
||||
/// as a constraint relative to (the) base register specified for this system. If it can
|
||||
/// be, a \e relative Equation is generated, which will apply to \e relative ValueSets.
|
||||
/// \param compOp is the comparison PcodeOp
|
||||
/// \param cbranch is the conditional branch
|
||||
void ValueSetSolver::generateRelativeConstraint(PcodeOp *compOp,PcodeOp *cbranch)
|
||||
|
||||
{
|
||||
OpCode opc = compOp->code();
|
||||
switch(opc) {
|
||||
case CPUI_INT_LESS:
|
||||
opc = CPUI_INT_SLESS; // Treat unsigned pointer comparisons as signed relative to the base register
|
||||
break;
|
||||
case CPUI_INT_LESSEQUAL:
|
||||
opc = CPUI_INT_SLESSEQUAL;
|
||||
break;
|
||||
case CPUI_INT_SLESS:
|
||||
case CPUI_INT_SLESSEQUAL:
|
||||
case CPUI_INT_EQUAL:
|
||||
case CPUI_INT_NOTEQUAL:
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
int4 typeCode;
|
||||
uintb value;
|
||||
Varnode *vn;
|
||||
Varnode *inVn0 = compOp->getIn(0);
|
||||
Varnode *inVn1 = compOp->getIn(1);
|
||||
CircleRange lift(true);
|
||||
if (checkRelativeConstant(inVn0, typeCode, value)) {
|
||||
vn = inVn1;
|
||||
if (!lift.pullBackBinary(opc, value, 1, vn->getSize(), 1))
|
||||
return;
|
||||
}
|
||||
else if (checkRelativeConstant(inVn1,typeCode,value)) {
|
||||
vn = inVn0;
|
||||
if (!lift.pullBackBinary(opc, value, 0, vn->getSize(), 1))
|
||||
return;
|
||||
}
|
||||
else
|
||||
return; // Neither side looks like a relative constant
|
||||
|
||||
Varnode *endVn = vn;
|
||||
while(!endVn->isMark()) {
|
||||
if (!endVn->isWritten()) return;
|
||||
PcodeOp *op = endVn->getDef();
|
||||
if (op->code() != CPUI_COPY && op->code() != CPUI_INDIRECT)
|
||||
return;
|
||||
endVn = op->getIn(0);
|
||||
}
|
||||
if (endVn != (Varnode *)0)
|
||||
constraintsFromPath(typeCode,lift,endVn,endVn,cbranch->getParent());
|
||||
}
|
||||
|
||||
/// Given a set of sinks, find all the Varnodes that flow directly into them.
|
||||
/// \param sinks is the list terminating Varnodes
|
||||
/// \param stackReg (if non-NULL) gives the stack pointer (for keeping track of relative offsets)
|
||||
|
@ -107,12 +107,18 @@ class Partition; // Forward declaration
|
||||
/// or some other register (if \b typeCode is non-zero).
|
||||
class ValueSet {
|
||||
public:
|
||||
/// \brief An external that can be applied to a ValueSet
|
||||
///
|
||||
/// An Equation is attached to a particular ValueSet and its underlying Varnode
|
||||
/// providing additional restriction on the ValueSet of an input parameter of the
|
||||
/// operation producing the Varnode.
|
||||
class Equation {
|
||||
friend class ValueSet;
|
||||
int4 slot;
|
||||
CircleRange range;
|
||||
int4 slot; ///< The input parameter slot to which the constraint is attached
|
||||
int4 typeCode; ///< The constraint characteristic 0=absolute 1=relative to a spacebase register
|
||||
CircleRange range; ///< The range constraint
|
||||
public:
|
||||
Equation(int4 s,const CircleRange &rng) { slot=s; range = rng; } ///< Constructor
|
||||
Equation(int4 s,int4 tc,const CircleRange &rng) { slot=s; typeCode = tc; range = rng; } ///< Constructor
|
||||
};
|
||||
private:
|
||||
friend class ValueSetSolver;
|
||||
@ -125,12 +131,15 @@ private:
|
||||
vector<Equation> equations; ///< Any equations associated with this value set
|
||||
Partition *partHead; ///< If Varnode is a component head, pointer to corresponding Partition
|
||||
ValueSet *next; ///< Next ValueSet to iterate
|
||||
bool doesEquationApply(int4 num,int4 slot) const; ///< Does the indicated equation apply for the given input slot
|
||||
void setFull(void) { range.setFull(vn->getSize()); typeCode = 100; } ///< Mark value set as possibly containing any value
|
||||
void setVarnode(Varnode *v,int4 tCode); ///< Attach \b this to given Varnode and set initial values
|
||||
void addEquation(int4 slot,const CircleRange &constraint); ///< Insert an equation restricting \b this value set
|
||||
void addLandmark(const CircleRange &constraint) { addEquation(numParams,constraint); } ///< Add a widening landmark
|
||||
void addEquation(int4 slot,int4 type,const CircleRange &constraint); ///< Insert an equation restricting \b this value set
|
||||
void addLandmark(int4 type,const CircleRange &constraint) { addEquation(numParams,type,constraint); } ///< Add a widening landmark
|
||||
void doWidening(const CircleRange &newRange); ///< Widen the value set so fixed point is reached sooner
|
||||
void looped(void); ///< Mark that iteration has looped back to \b this
|
||||
bool iterate(void); ///< Regenerate \b this value set from operator inputs
|
||||
void computeTypeCode(void); ///< Figure out if \b this value set is absolute or relative
|
||||
bool iterate(void); ///< Regenerate \b this value set from operator inputs
|
||||
public:
|
||||
int4 getTypeCode(void) const { return typeCode; } ///< Return '0' for normal constant, '1' for spacebase relative
|
||||
Varnode *getVarnode(void) const { return vn; } ///< Get the Varnode attached to \b this ValueSet
|
||||
@ -190,10 +199,12 @@ class ValueSetSolver {
|
||||
void component(ValueSet *vertex,Partition &part); ///< Generate a partition component given its head
|
||||
int4 visit(ValueSet *vertex,Partition &part); ///< Recursively walk the data-flow graph finding partitions
|
||||
void establishTopologicalOrder(void); ///< Find the optimal order for iterating through the ValueSets
|
||||
void applyConstraints(Varnode *vn,const CircleRange &range,FlowBlock *splitPoint);
|
||||
void constraintsFromPath(Varnode *vn,PcodeOp *cbranch); ///< Generate constraints given a branch and matching Varnode
|
||||
void applyConstraints(Varnode *vn,int4 type,const CircleRange &range,FlowBlock *splitPoint);
|
||||
void constraintsFromPath(int4 type,CircleRange &lift,Varnode *startVn,Varnode *endVn,FlowBlock *splitPoint);
|
||||
void constraintsFromCBranch(PcodeOp *cbranch); ///< Generate constraints arising from the given branch
|
||||
void generateConstraints(vector<Varnode *> &worklist); ///< Generate constraints given a system of Varnodes
|
||||
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
|
||||
public:
|
||||
void establishValueSets(const vector<Varnode *> &sinks,Varnode *stackReg); ///< Build value sets for a data-flow system
|
||||
int4 getNumIterations(void) const { return numIterations; } ///< Get the current number of iterations
|
||||
@ -243,6 +254,23 @@ inline char CircleRange::encodeRangeOverlaps(uintb op1left, uintb op1right, uint
|
||||
return arrange[val];
|
||||
}
|
||||
|
||||
/// Perform basic checks that the selected Equation exists and applies
|
||||
/// to the indicated input slot.
|
||||
/// \param num is the index selecting an Equation
|
||||
/// \param slot is the indicated slot
|
||||
/// \return \b true if the Equation exists and applies
|
||||
inline bool ValueSet::doesEquationApply(int4 num,int4 slot) const
|
||||
|
||||
{
|
||||
if (num < equations.size()) {
|
||||
if (equations[num].slot == slot) {
|
||||
if (equations[num].typeCode == typeCode)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// \param vertex is the node that will be prepended
|
||||
/// \param part is the Partition being modified
|
||||
inline void ValueSetSolver::partitionPrepend(ValueSet *vertex,Partition &part)
|
||||
|
Loading…
Reference in New Issue
Block a user