indirection creation refactor

This commit is contained in:
caheckman 2019-09-28 16:11:18 -04:00
parent 05ee2c14b9
commit ed335a9af0
4 changed files with 21 additions and 37 deletions

View file

@ -1860,8 +1860,11 @@ int4 ActionLikelyTrash::apply(Funcdata &data)
for(uint4 i=0;i<indlist.size();++i) {
PcodeOp *op = indlist[i];
if (op->code() == CPUI_INDIRECT)
data.truncateIndirect(indlist[i]);
if (op->code() == CPUI_INDIRECT) {
// Trucate data-flow through INDIRECT, turning it into indirect creation
data.opSetInput(op,data.newConstant(op->getOut()->getSize(), 0),0);
data.markIndirectCreation(op,false);
}
else if (op->code() == CPUI_INT_AND) {
data.opSetInput(op,data.newConstant(op->getIn(1)->getSize(),0),1);
}

View file

@ -385,9 +385,8 @@ public:
PcodeOp *cloneOp(const PcodeOp *op,const SeqNum &seq); /// Clone a PcodeOp into \b this function
PcodeOp *canonicalReturnOp(void) const; /// Find a representative CPUI_RETURN op for \b this function
PcodeOp *newIndirectOp(PcodeOp *indeffect,const Address &addr,int4 size,uint4 extraFlags);
void setIndirectCreation(PcodeOp *op,PcodeOp *indeffect,Varnode *outvn,bool possibleout);
PcodeOp *newIndirectCreation(PcodeOp *indeffect,const Address &addr,int4 size,bool possibleout);
void truncateIndirect(PcodeOp *indop); ///< Convert CPUI_INDIRECT into an \e indirect \e creation
void markIndirectCreation(PcodeOp *indop,bool possibleOutput); ///< Convert CPUI_INDIRECT into an \e indirect \e creation
PcodeOp *findOp(const SeqNum &sq) { return obank.findOp(sq); } ///< Find PcodeOp with given sequence number
void opInsertBefore(PcodeOp *op,PcodeOp *follow); ///< Insert given PcodeOp before a specific op
void opInsertAfter(PcodeOp *op,PcodeOp *prev); ///< Insert given PcodeOp after a specific op

View file

@ -663,31 +663,6 @@ PcodeOp *Funcdata::newIndirectOp(PcodeOp *indeffect,const Address &addr,int4 siz
return newop;
}
/// \brief Turn given PcodeOp into a CPUI_INDIRECT that \e indirectly \e creates a Varnode
///
/// An \e indirectly \e created Varnode effectively has no data-flow before the INDIRECT op
/// that defines it, and the value contained by the Varnode is not explicitly calculable.
/// \param op is the given PcodeOp to convert to a CPUI_INDIRECT
/// \param indeffect is the p-code causing the indirect effect
/// \param outvn is the (preexisting) Varnode that will be marked as \e created by the INDIRECT
/// \param possibleout is \b true if the output should be treated as a \e directwrite.
void Funcdata::setIndirectCreation(PcodeOp *op,PcodeOp *indeffect,Varnode *outvn,bool possibleout)
{
Varnode *newin;
newin = newConstant(outvn->getSize(),0);
op->flags |= PcodeOp::indirect_creation;
opSetOutput(op,outvn);
if (!possibleout)
newin->flags |= Varnode::indirect_creation;
outvn->flags |= Varnode::indirect_creation;
opSetOpcode(op,CPUI_INDIRECT);
opSetInput(op,newin,0);
opSetInput(op,newVarnodeIop(indeffect),1);
opInsertBefore(op,indeffect);
}
/// \brief Build a CPUI_INDIRECT op that \e indirectly \e creates a Varnode
///
/// An \e indirectly \e created Varnode effectively has no data-flow before the INDIRECT op
@ -718,22 +693,24 @@ PcodeOp *Funcdata::newIndirectCreation(PcodeOp *indeffect,const Address &addr,in
return newop;
}
/// Data-flow through the given CPUI_INDIRECT op is truncated causing the output Varnode
/// to be \e indirectly \e created.
/// Data-flow through the given CPUI_INDIRECT op is marked so that the output Varnode
/// is considered \e indirectly \e created.
/// An \e indirectly \e created Varnode effectively has no data-flow before the INDIRECT op
/// that defines it, and the value contained by the Varnode is not explicitly calculable.
/// \param indop is the given CPUI_INDIRECT op
void Funcdata::truncateIndirect(PcodeOp *indop)
/// \param possibleOutput is \b true if INDIRECT should be marked as a possible call output
void Funcdata::markIndirectCreation(PcodeOp *indop,bool possibleOutput)
{
Varnode *outvn = indop->getOut();
Varnode *newin = newConstant(outvn->getSize(),0);
Varnode *in0 = indop->getIn(0);
indop->flags |= PcodeOp::indirect_creation;
newin->flags |= Varnode::indirect_creation;
if (!in0->isConstant())
throw LowlevelError("Indirect creation not properly formed");
if (!possibleOutput)
in0->flags |= Varnode::indirect_creation;
outvn->flags |= Varnode::indirect_creation;
opSetInput(indop,newin,0);
}
/// \brief Generate raw p-code for the function

View file

@ -206,7 +206,12 @@ void SubvariableFlow::patchIndirect(PcodeOp *newop,PcodeOp *oldop, ReplaceVarnod
PcodeOp *indop = PcodeOp::getOpFromConst(oldop->getIn(1)->getAddr());
bool possibleout = !oldop->getIn(0)->isIndirectZero();
Varnode *outvn = getReplaceVarnode(out);
fd->setIndirectCreation(newop,indop,outvn,possibleout);
fd->opSetOutput(newop,outvn);
fd->opSetOpcode(newop, CPUI_INDIRECT);
fd->opSetInput(newop,fd->newConstant(outvn->getSize(),0),0);
fd->opSetInput(newop,fd->newVarnodeIop(indop),1);
fd->markIndirectCreation(newop,possibleout);
fd->opInsertBefore(newop, indop);
FuncCallSpecs *fc = fd->getCallSpecs(indop);
if (fc == (FuncCallSpecs *)0) return;
if (fc->isOutputActive()) {