mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 10:49:34 +02:00
Rearrange MULTIEQUAL equation generation
This commit is contained in:
parent
3433400d76
commit
e506f27b31
2 changed files with 62 additions and 24 deletions
|
@ -2035,6 +2035,44 @@ void ValueSetSolver::establishTopologicalOrder(void)
|
||||||
orderPartition.startNode = orderPartition.startNode->next; // Remove simulated root
|
orderPartition.startNode = orderPartition.startNode->next; // Remove simulated root
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \brief Generate an equation given a \b true constraint and the input/output Varnodes it affects
|
||||||
|
///
|
||||||
|
/// The equation is expressed as: only \b true values can reach the indicated input to a specific PcodeOp.
|
||||||
|
/// The equation is attached to the output of the PcodeOp.
|
||||||
|
/// \param vn is the output Varnode the equation will be attached to
|
||||||
|
/// \param op is the specific PcodeOp
|
||||||
|
/// \param slot is the input slot of the constrained input Varnode
|
||||||
|
/// \param type is the type of values
|
||||||
|
/// \param range is the range of \b true values
|
||||||
|
void ValueSetSolver::generateTrueEquation(Varnode *vn,PcodeOp *op,int4 slot,int4 type,const CircleRange &range)
|
||||||
|
|
||||||
|
{
|
||||||
|
if (vn != (Varnode *) 0)
|
||||||
|
vn->getValueSet()->addEquation(slot, type, range);
|
||||||
|
else
|
||||||
|
readNodes[op->getSeqNum()].addEquation(slot, type, range);// Special read site
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Generate the complementary equation given a \b true constraint and the input/output Varnodes it affects
|
||||||
|
///
|
||||||
|
/// The equation is expressed as: only \b false values can reach the indicated input to a specific PcodeOp.
|
||||||
|
/// The equation is attached to the output of the PcodeOp.
|
||||||
|
/// \param vn is the output Varnode the equation will be attached to
|
||||||
|
/// \param op is the specific PcodeOp
|
||||||
|
/// \param slot is the input slot of the constrained input Varnode
|
||||||
|
/// \param type is the type of values
|
||||||
|
/// \param range is the range of \b true values, which must be complemented
|
||||||
|
void ValueSetSolver::generateFalseEquation(Varnode *vn,PcodeOp *op,int4 slot,int4 type,const CircleRange &range)
|
||||||
|
|
||||||
|
{
|
||||||
|
CircleRange falseRange(range);
|
||||||
|
falseRange.invert();
|
||||||
|
if (vn != (Varnode *) 0)
|
||||||
|
vn->getValueSet()->addEquation(slot, type, falseRange);
|
||||||
|
else
|
||||||
|
readNodes[op->getSeqNum()].addEquation(slot, type, falseRange);// Special read site
|
||||||
|
}
|
||||||
|
|
||||||
/// \brief Look for PcodeOps where the given constraint range applies and instantiate an equation
|
/// \brief Look for PcodeOps where the given constraint range applies and instantiate an equation
|
||||||
///
|
///
|
||||||
/// If a read of the given Varnode is in a basic block dominated by the condition producing the
|
/// If a read of the given Varnode is in a basic block dominated by the condition producing the
|
||||||
|
@ -2079,35 +2117,33 @@ void ValueSetSolver::applyConstraints(Varnode *vn,int4 type,const CircleRange &r
|
||||||
}
|
}
|
||||||
FlowBlock *curBlock = op->getParent();
|
FlowBlock *curBlock = op->getParent();
|
||||||
int4 slot = op->getSlot(vn);
|
int4 slot = op->getSlot(vn);
|
||||||
for(;;) {
|
if (op->code() == CPUI_MULTIEQUAL) {
|
||||||
if (curBlock == trueBlock) {
|
if (curBlock == trueBlock) {
|
||||||
if (!trueIsRestricted) {
|
|
||||||
// If its possible that both the true and false edges can reach trueBlock
|
// If its possible that both the true and false edges can reach trueBlock
|
||||||
// then the only input we can restrict is a MULTIEQUAL input along the exact true edge
|
// then the only input we can restrict is a MULTIEQUAL input along the exact true edge
|
||||||
if (op->code() != CPUI_MULTIEQUAL) break;
|
if (trueIsRestricted || trueBlock->getIn(slot) == splitPoint)
|
||||||
if (op->getParent() != trueBlock) break;
|
generateTrueEquation(outVn, op, slot, type, range);
|
||||||
if (trueBlock->getIn(slot) != splitPoint) break;
|
continue;
|
||||||
}
|
}
|
||||||
if (outVn != (Varnode *)0)
|
else if (curBlock == falseBlock) {
|
||||||
outVn->getValueSet()->addEquation(slot, type, range);
|
// If its possible that both the true and false edges can reach falseBlock
|
||||||
else
|
// then the only input we can restrict is a MULTIEQUAL input along the exact false edge
|
||||||
readNodes[op->getSeqNum()].addEquation(slot, type, range); // Special read site
|
if (falseIsRestricted || falseBlock->getIn(slot) == splitPoint)
|
||||||
|
generateFalseEquation(outVn, op, slot, type, range);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// else
|
||||||
|
// curBlock = curBlock->getIn(slot); // MULTIEQUAL input is really only from one in-block
|
||||||
|
}
|
||||||
|
for(;;) {
|
||||||
|
if (curBlock == trueBlock) {
|
||||||
|
if (trueIsRestricted)
|
||||||
|
generateTrueEquation(outVn, op, slot, type, range);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (curBlock == falseBlock) {
|
else if (curBlock == falseBlock) {
|
||||||
if (!falseIsRestricted) {
|
if (falseIsRestricted)
|
||||||
// If its possible that both the true and false edges can reach falseBlock
|
generateFalseEquation(outVn, op, slot, type, range);
|
||||||
// then the only input we can restrict is a MULTIEQUAL input along the exact false edge
|
|
||||||
if (op->code() != CPUI_MULTIEQUAL) break;
|
|
||||||
if (op->getParent() != falseBlock) break;
|
|
||||||
if (falseBlock->getIn(slot) != splitPoint) break;
|
|
||||||
}
|
|
||||||
CircleRange falseRange(range);
|
|
||||||
falseRange.invert();
|
|
||||||
if (outVn != (Varnode *)0)
|
|
||||||
outVn->getValueSet()->addEquation(slot, type, falseRange);
|
|
||||||
else
|
|
||||||
readNodes[op->getSeqNum()].addEquation(slot, type, falseRange); // Special read site
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (curBlock == splitPoint || curBlock == (FlowBlock *)0)
|
else if (curBlock == splitPoint || curBlock == (FlowBlock *)0)
|
||||||
|
|
|
@ -287,6 +287,8 @@ class ValueSetSolver {
|
||||||
void component(ValueSet *vertex,Partition &part); ///< Generate a partition component given its head
|
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
|
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 establishTopologicalOrder(void); ///< Find the optimal order for iterating through the ValueSets
|
||||||
|
void generateTrueEquation(Varnode *vn,PcodeOp *op,int4 slot,int4 type,const CircleRange &range);
|
||||||
|
void generateFalseEquation(Varnode *vn,PcodeOp *op,int4 slot,int4 type,const CircleRange &range);
|
||||||
void applyConstraints(Varnode *vn,int4 type,const CircleRange &range,PcodeOp *cbranch);
|
void applyConstraints(Varnode *vn,int4 type,const CircleRange &range,PcodeOp *cbranch);
|
||||||
void constraintsFromPath(int4 type,CircleRange &lift,Varnode *startVn,Varnode *endVn,PcodeOp *cbranch);
|
void constraintsFromPath(int4 type,CircleRange &lift,Varnode *startVn,Varnode *endVn,PcodeOp *cbranch);
|
||||||
void constraintsFromCBranch(PcodeOp *cbranch); ///< Generate constraints arising from the given branch
|
void constraintsFromCBranch(PcodeOp *cbranch); ///< Generate constraints arising from the given branch
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue