New indirect_store flag

This commit is contained in:
caheckman 2019-06-28 13:03:26 -04:00
parent b7608adcf2
commit a4856b9af0
6 changed files with 12 additions and 9 deletions

View file

@ -1144,7 +1144,8 @@ int4 ActionDirectWrite::apply(Funcdata &data)
dvn = op->getOut(); dvn = op->getOut();
if (!dvn->isDirectWrite()) { if (!dvn->isDirectWrite()) {
dvn->setDirectWrite(); dvn->setDirectWrite();
if (propagateIndirect || op->code() != CPUI_INDIRECT) // If INDIRECT, output is marked, but does not propagate // For call based INDIRECTs, output is marked, but does not propagate depending on setting
if (propagateIndirect || op->code() != CPUI_INDIRECT || op->isIndirectStore())
worklist.push_back(dvn); worklist.push_back(dvn);
} }
} }

View file

@ -384,7 +384,7 @@ public:
PcodeOp *newOpBefore(PcodeOp *follow,OpCode opc,Varnode *in1,Varnode *in2,Varnode *in3=(Varnode *)0); PcodeOp *newOpBefore(PcodeOp *follow,OpCode opc,Varnode *in1,Varnode *in2,Varnode *in3=(Varnode *)0);
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); PcodeOp *newIndirectOp(PcodeOp *indeffect,const Address &addr,int4 size,uint4 extraFlags);
void setIndirectCreation(PcodeOp *op,PcodeOp *indeffect,Varnode *outvn,bool possibleout); 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 truncateIndirect(PcodeOp *indop); ///< Convert CPUI_INDIRECT into an \e indirect \e creation

View file

@ -608,8 +608,9 @@ PcodeOp *Funcdata::newOpBefore(PcodeOp *follow,OpCode opc,Varnode *in1,Varnode *
/// \param indeffect is the PcodeOp with the indirect effect /// \param indeffect is the PcodeOp with the indirect effect
/// \param addr is the starting address of the storage range to protect /// \param addr is the starting address of the storage range to protect
/// \param size is the number of bytes in the storage range /// \param size is the number of bytes in the storage range
/// \param extraFlags are extra boolean properties to put on the INDIRECT
/// \return the new CPUI_INDIRECT op /// \return the new CPUI_INDIRECT op
PcodeOp *Funcdata::newIndirectOp(PcodeOp *indeffect,const Address &addr,int4 size) PcodeOp *Funcdata::newIndirectOp(PcodeOp *indeffect,const Address &addr,int4 size,uint4 extraFlags)
{ {
Varnode *newin; Varnode *newin;
@ -617,6 +618,7 @@ PcodeOp *Funcdata::newIndirectOp(PcodeOp *indeffect,const Address &addr,int4 siz
newin = newVarnode(size,addr); newin = newVarnode(size,addr);
newop = newOp(2,indeffect->getAddr()); newop = newOp(2,indeffect->getAddr());
newop->flags |= extraFlags;
newVarnodeOut(size,addr,newop); newVarnodeOut(size,addr,newop);
opSetOpcode(newop,CPUI_INDIRECT); opSetOpcode(newop,CPUI_INDIRECT);
opSetInput(newop,newin,0); opSetInput(newop,newin,0);

View file

@ -1402,7 +1402,6 @@ bool AncestorRealistic::checkConditionalExe(State &state)
int4 AncestorRealistic::enterNode(State &state) int4 AncestorRealistic::enterNode(State &state)
{ {
PcodeOp *indop;
// If the node has already been visited, we truncate the traversal to prevent cycles. // If the node has already been visited, we truncate the traversal to prevent cycles.
// We always return success assuming the proper result will get returned along the first path // We always return success assuming the proper result will get returned along the first path
if (state.vn->isMark()) return pop_success; if (state.vn->isMark()) return pop_success;
@ -1424,8 +1423,7 @@ int4 AncestorRealistic::enterNode(State &state)
return pop_failkill; // Truncate this path, indicating killedbycall return pop_failkill; // Truncate this path, indicating killedbycall
return pop_success; // otherwise it could be valid return pop_success; // otherwise it could be valid
} }
indop = PcodeOp::getOpFromConst(op->getIn(1)->getAddr()); if (!op->isIndirectStore()) { // If flow goes THROUGH a call
if (indop->isCall()) { // If flow goes THROUGH a call
if (op->getOut()->isReturnAddress()) return pop_fail; // Storage address location is completely invalid if (op->getOut()->isReturnAddress()) return pop_fail; // Storage address location is completely invalid
if (trial->isKilledByCall()) return pop_fail; // "Likely" killedbycall is invalid if (trial->isKilledByCall()) return pop_fail; // "Likely" killedbycall is invalid
} }

View file

@ -1088,7 +1088,7 @@ void Heritage::guardCalls(uint4 flags,const Address &addr,int4 size,vector<Varno
} }
// We do not guard the call if the effect is "unaffected" or "reload" // We do not guard the call if the effect is "unaffected" or "reload"
if ((effecttype == EffectRecord::unknown_effect)||(effecttype == EffectRecord::return_address)) { if ((effecttype == EffectRecord::unknown_effect)||(effecttype == EffectRecord::return_address)) {
indop = fd->newIndirectOp(fc->getOp(),addr,size); indop = fd->newIndirectOp(fc->getOp(),addr,size,0);
indop->getIn(0)->setActiveHeritage(); indop->getIn(0)->setActiveHeritage();
indop->getOut()->setActiveHeritage(); indop->getOut()->setActiveHeritage();
write.push_back(indop->getOut()); write.push_back(indop->getOut());
@ -1129,7 +1129,7 @@ void Heritage::guardStores(const Address &addr,int4 size,vector<Varnode *> &writ
AddrSpace *storeSpace = Address::getSpaceFromConst(op->getIn(0)->getAddr()); AddrSpace *storeSpace = Address::getSpaceFromConst(op->getIn(0)->getAddr());
if ((container == storeSpace && op->usesSpacebasePtr()) || if ((container == storeSpace && op->usesSpacebasePtr()) ||
(spc == storeSpace)) { (spc == storeSpace)) {
indop = fd->newIndirectOp(op,addr,size); indop = fd->newIndirectOp(op,addr,size,PcodeOp::indirect_store);
indop->getIn(0)->setActiveHeritage(); indop->getIn(0)->setActiveHeritage();
indop->getOut()->setActiveHeritage(); indop->getOut()->setActiveHeritage();
write.push_back(indop->getOut()); write.push_back(indop->getOut());

View file

@ -96,7 +96,8 @@ public:
indirect_creation = 0x8000000, ///< Output varnode is created by indirect effect indirect_creation = 0x8000000, ///< Output varnode is created by indirect effect
calculated_bool = 0x10000000, ///< Output has been determined to be a 1-bit boolean value calculated_bool = 0x10000000, ///< Output has been determined to be a 1-bit boolean value
is_cpool_transformed = 0x20000000, ///< Have we checked for cpool transforms is_cpool_transformed = 0x20000000, ///< Have we checked for cpool transforms
ptrflow = 0x40000000 ///< Op consumes or produces a ptr ptrflow = 0x40000000, ///< Op consumes or produces a ptr
indirect_store = 0x80000000 ///< CPUI_INDIRECT is caused by CPUI_STORE
}; };
enum { enum {
has_thisptr = 0x1, ///< First parameter ( getIn(1) ) is a this pointer has_thisptr = 0x1, ///< First parameter ( getIn(1) ) is a this pointer
@ -163,6 +164,7 @@ public:
bool isCall(void) const { return ((flags&PcodeOp::call)!=0); } ///< Return \b true if this op indicates call semantics bool isCall(void) const { return ((flags&PcodeOp::call)!=0); } ///< Return \b true if this op indicates call semantics
bool isMarker(void) const { return ((flags&PcodeOp::marker)!=0); } ///< Return \b true is a special SSA form op bool isMarker(void) const { return ((flags&PcodeOp::marker)!=0); } ///< Return \b true is a special SSA form op
bool isIndirectCreation(void) const { return ((flags&PcodeOp::indirect_creation)!=0); } ///< Return \b true if op creates a varnode indirectly bool isIndirectCreation(void) const { return ((flags&PcodeOp::indirect_creation)!=0); } ///< Return \b true if op creates a varnode indirectly
bool isIndirectStore(void) const { return ((flags&PcodeOp::indirect_store)!=0); } ///< Return \b true if \b this INDIRECT is caused by STORE
/// \brief Return \b true if this op is not directly represented in C output /// \brief Return \b true if this op is not directly represented in C output
bool notPrinted(void) const { return ((flags&(PcodeOp::marker|PcodeOp::nonprinting|PcodeOp::noreturn))!=0); } bool notPrinted(void) const { return ((flags&(PcodeOp::marker|PcodeOp::nonprinting|PcodeOp::noreturn))!=0); }
/// \brief Return \b true if this op produces a boolean output /// \brief Return \b true if this op produces a boolean output