mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-03 17:59:46 +02:00
Some adjustments to traceForward to CALLs
This commit is contained in:
parent
6beb631e39
commit
762cda04f4
3 changed files with 44 additions and 8 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue