Some adjustments to traceForward to CALLs

This commit is contained in:
caheckman 2020-02-24 17:10:34 -05:00
parent 6beb631e39
commit 762cda04f4
3 changed files with 44 additions and 8 deletions

View file

@ -81,6 +81,35 @@ PcodeOp::PcodeOp(int4 s,const SeqNum &sq) : start(sq),inrefs(s)
inrefs[i] = (Varnode *)0;
}
/// \brief Find the slot for a given Varnode, which may be take up multiple input slots
///
/// In the rare case that \b this PcodeOp takes the same Varnode as input multiple times,
/// use the specific descendant iterator producing \b this PcodeOp to work out the corresponding slot.
/// Every slot containing the given Varnode will be produced exactly once over the course of iteration.
/// \param vn is the given Varnode
/// \param firstSlot is the first instance of the Varnode in \b this input list
/// \param iter is the specific descendant iterator producing \b this
/// \return the slot corresponding to the iterator
int4 PcodeOp::getRepeatSlot(const Varnode *vn,int4 firstSlot,list<PcodeOp *>::const_iterator iter) const
{
int4 count = 1;
for(list<PcodeOp *>::const_iterator oiter=vn->beginDescend();oiter != iter;++oiter) {
if ((*oiter) == this)
count += 1;
}
if (count == 1) return firstSlot;
int4 recount = 1;
for(int4 i=firstSlot+1;i<inrefs.size();++i) {
if (inrefs[i] == vn) {
recount += 1;
if (recount == count)
return i;
}
}
return -1;
}
/// Can this be collapsed to a copy op, i.e. are all inputs constants
/// \return \b true if this op can be callapsed
bool PcodeOp::isCollapsible(void) const

View file

@ -155,6 +155,7 @@ public:
list<PcodeOp *>::iterator getBasicIter(void) const { return basiciter; } ///< Get position within basic block
/// \brief Get the slot number of the indicated input varnode
int4 getSlot(const Varnode *vn) const { int4 i,n; n=inrefs.size(); for(i=0;i<n;++i) if (inrefs[i]==vn) break; return i; }
int4 getRepeatSlot(const Varnode *vn,int4 firstSlot,list<PcodeOp *>::const_iterator iter) const;
/// \brief Get the evaluation type of this op
uint4 getEvalType(void) const { return (flags&(PcodeOp::unary|PcodeOp::binary|PcodeOp::special)); }
/// \brief Get type which indicates unusual halt in control-flow

View file

@ -347,14 +347,14 @@ bool SubvariableFlow::traceForward(ReplaceVarnode *rvn)
bool booldir;
int4 dcount = 0;
int4 hcount = 0;
int4 callcount = 0;
list<PcodeOp *>::const_iterator iter,enditer;
iter = rvn->vn->beginDescend();
enditer = rvn->vn->endDescend();
while(iter != enditer) {
op = *iter++;
for(iter = rvn->vn->beginDescend();iter != enditer;++iter) {
op = *iter;
outvn = op->getOut();
if ((outvn!=(Varnode *)0)&&(outvn->isMark()))
if ((outvn!=(Varnode *)0)&&outvn->isMark()&&!op->isCall())
continue;
dcount += 1; // Count this descendant
slot = op->getSlot(rvn->vn);
@ -557,6 +557,9 @@ bool SubvariableFlow::traceForward(ReplaceVarnode *rvn)
break;
case CPUI_CALL:
case CPUI_CALLIND:
callcount += 1;
if (callcount > 1)
slot = op->getRepeatSlot(rvn->vn, slot, iter);
if (!tryCallPull(op,rvn,slot)) return false;
hcount += 1; // Dealt with this descendant
break;
@ -781,14 +784,14 @@ bool SubvariableFlow::traceForwardSext(ReplaceVarnode *rvn)
int4 slot;
int4 dcount = 0;
int4 hcount = 0;
int4 callcount = 0;
list<PcodeOp *>::const_iterator iter,enditer;
iter = rvn->vn->beginDescend();
enditer = rvn->vn->endDescend();
while(iter != enditer) {
op = *iter++;
for(iter=rvn->vn->beginDescend();iter != enditer;++iter) {
op = *iter;
outvn = op->getOut();
if ((outvn!=(Varnode *)0)&&(outvn->isMark()))
if ((outvn!=(Varnode *)0)&&outvn->isMark()&&!op->isCall())
continue;
dcount += 1; // Count this descendant
slot = op->getSlot(rvn->vn);
@ -836,6 +839,9 @@ bool SubvariableFlow::traceForwardSext(ReplaceVarnode *rvn)
break;
case CPUI_CALL:
case CPUI_CALLIND:
callcount += 1;
if (callcount > 1)
slot = op->getRepeatSlot(rvn->vn, slot, iter);
if (!tryCallPull(op,rvn,slot)) return false;
hcount += 1; // Dealt with this descendant
break;