mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 02:09:44 +02:00
indirection creation refactor
This commit is contained in:
parent
05ee2c14b9
commit
ed335a9af0
4 changed files with 21 additions and 37 deletions
|
@ -1860,8 +1860,11 @@ int4 ActionLikelyTrash::apply(Funcdata &data)
|
||||||
|
|
||||||
for(uint4 i=0;i<indlist.size();++i) {
|
for(uint4 i=0;i<indlist.size();++i) {
|
||||||
PcodeOp *op = indlist[i];
|
PcodeOp *op = indlist[i];
|
||||||
if (op->code() == CPUI_INDIRECT)
|
if (op->code() == CPUI_INDIRECT) {
|
||||||
data.truncateIndirect(indlist[i]);
|
// 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) {
|
else if (op->code() == CPUI_INT_AND) {
|
||||||
data.opSetInput(op,data.newConstant(op->getIn(1)->getSize(),0),1);
|
data.opSetInput(op,data.newConstant(op->getIn(1)->getSize(),0),1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -385,9 +385,8 @@ public:
|
||||||
PcodeOp *cloneOp(const PcodeOp *op,const SeqNum &seq); /// Clone a PcodeOp into \b this function
|
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 *canonicalReturnOp(void) const; /// Find a representative CPUI_RETURN op for \b this function
|
||||||
PcodeOp *newIndirectOp(PcodeOp *indeffect,const Address &addr,int4 size,uint4 extraFlags);
|
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);
|
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
|
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 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
|
void opInsertAfter(PcodeOp *op,PcodeOp *prev); ///< Insert given PcodeOp after a specific op
|
||||||
|
|
|
@ -663,31 +663,6 @@ PcodeOp *Funcdata::newIndirectOp(PcodeOp *indeffect,const Address &addr,int4 siz
|
||||||
return newop;
|
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
|
/// \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
|
/// 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;
|
return newop;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Data-flow through the given CPUI_INDIRECT op is truncated causing the output Varnode
|
/// Data-flow through the given CPUI_INDIRECT op is marked so that the output Varnode
|
||||||
/// to be \e indirectly \e created.
|
/// is considered \e indirectly \e created.
|
||||||
/// An \e indirectly \e created Varnode effectively has no data-flow before the INDIRECT op
|
/// 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.
|
/// that defines it, and the value contained by the Varnode is not explicitly calculable.
|
||||||
/// \param indop is the given CPUI_INDIRECT op
|
/// \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 *outvn = indop->getOut();
|
||||||
Varnode *newin = newConstant(outvn->getSize(),0);
|
Varnode *in0 = indop->getIn(0);
|
||||||
|
|
||||||
indop->flags |= PcodeOp::indirect_creation;
|
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;
|
outvn->flags |= Varnode::indirect_creation;
|
||||||
|
|
||||||
opSetInput(indop,newin,0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Generate raw p-code for the function
|
/// \brief Generate raw p-code for the function
|
||||||
|
|
|
@ -206,7 +206,12 @@ void SubvariableFlow::patchIndirect(PcodeOp *newop,PcodeOp *oldop, ReplaceVarnod
|
||||||
PcodeOp *indop = PcodeOp::getOpFromConst(oldop->getIn(1)->getAddr());
|
PcodeOp *indop = PcodeOp::getOpFromConst(oldop->getIn(1)->getAddr());
|
||||||
bool possibleout = !oldop->getIn(0)->isIndirectZero();
|
bool possibleout = !oldop->getIn(0)->isIndirectZero();
|
||||||
Varnode *outvn = getReplaceVarnode(out);
|
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);
|
FuncCallSpecs *fc = fd->getCallSpecs(indop);
|
||||||
if (fc == (FuncCallSpecs *)0) return;
|
if (fc == (FuncCallSpecs *)0) return;
|
||||||
if (fc->isOutputActive()) {
|
if (fc->isOutputActive()) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue