New guardStore

This commit is contained in:
caheckman 2019-06-25 16:53:49 -04:00
parent cb39d39a23
commit 171602e1ce
6 changed files with 42 additions and 16 deletions

View file

@ -234,6 +234,7 @@ public:
const list<LoadGuard> &getLoadGuards(void) const { return heritage.getLoadGuards(); } ///< Get the list of guarded LOADs
const list<LoadGuard> &getStoreGuards(void) const { return heritage.getStoreGuards(); } ///< Get the list of guarded STOREs
const LoadGuard *getStoreGuard(PcodeOp *op) const { return heritage.getStoreGuard(op); } ///< Get LoadGuard associated with STORE op
// Function prototype and call specification routines
int4 numCalls(void) const { return qlst.size(); } ///< Get the number of calls made by \b this function
@ -420,6 +421,7 @@ public:
void opMarkNoCollapse(PcodeOp *op) { op->setFlag(PcodeOp::nocollapse); } ///< Mark PcodeOp as not collapsible
void opMarkCpoolTransformed(PcodeOp *op) { op->setFlag(PcodeOp::is_cpool_transformed); } ///< Mark cpool record was visited
void opMarkCalculatedBool(PcodeOp *op) { op->setFlag(PcodeOp::calculated_bool); } ///< Mark PcodeOp as having boolean output
void opMarkSpacebaseStore(PcodeOp *op) { op->setFlag(PcodeOp::spacebase_ptr); } ///< Mark PcodeOp as STOREing from spacebase ptr
void opFlipCondition(PcodeOp *op) { op->flipFlag(PcodeOp::boolean_flip); } ///< Flip output condition of given CBRANCH
PcodeOp *target(const Address &addr) const { return obank.target(addr); } ///< Look up a PcodeOp by an instruction Address
Varnode *createStackRef(AddrSpace *spc,uintb off,PcodeOp *op,Varnode *stackptr,bool insertafter);

View file

@ -653,6 +653,18 @@ void LoadGuard::finalizeRange(const ValueSetRead &valueSet)
maximumOffset = spc->getHighest();
}
/// Check if the address falls within the range defined by \b this
/// \param addr is the given address
/// \return \b true if the address is contained
bool LoadGuard::isGuarded(const Address &addr) const
{
if (addr.getSpace() != spc) return false;
if (addr.getOffset() < minimumOffset) return false;
if (addr.getOffset() > maximumOffset) return false;
return true;
}
void Heritage::analyzeNewLoadGuards(void)
{
@ -747,6 +759,7 @@ void Heritage::generateStoreGuard(StackNode &node,PcodeOp *op,AddrSpace *spc)
{
storeGuard.push_back(LoadGuard());
storeGuard.back().set(op,spc,node.offset);
fd->opMarkSpacebaseStore(op);
}
/// \brief Trace input stackpointer to any indexed loads
@ -1012,12 +1025,16 @@ void Heritage::guardStores(const Address &addr,int4 size,vector<Varnode *> &writ
{
list<PcodeOp *>::const_iterator iter,iterend;
PcodeOp *op,*indop;
AddrSpace *spc = addr.getSpace();
AddrSpace *container = spc->getContain();
iterend = fd->endOp(CPUI_STORE);
for(iter=fd->beginOp(CPUI_STORE);iter!=iterend;++iter) {
op = *iter;
if (op->isDead()) continue;
if (addr.getSpace()->contain(Address::getSpaceFromConst(op->getIn(0)->getAddr()))) { // Does store affect same space
AddrSpace *storeSpace = Address::getSpaceFromConst(op->getIn(0)->getAddr());
if ((container == storeSpace && op->usesSpacebasePtr()) ||
(spc == storeSpace)) {
indop = fd->newIndirectOp(op,addr,size);
indop->getIn(0)->setActiveHeritage();
indop->getOut()->setActiveHeritage();
@ -2149,6 +2166,19 @@ void Heritage::heritage(void)
pass += 1;
}
/// \param op is the given PcodeOp
/// \return the associated LoadGuard or NULL
const LoadGuard *Heritage::getStoreGuard(PcodeOp *op) const
{
list<LoadGuard>::const_iterator iter;
for(iter=storeGuard.begin();iter!=storeGuard.end();++iter) {
if ((*iter).op == op)
return &(*iter);
}
return (const LoadGuard *)0;
}
/// \brief Get the number times heritage was performed for the given address space
///
/// A negative number indicates the number of passes to be wait before the first

View file

@ -125,6 +125,7 @@ public:
uintb getMinimum(void) const { return minimumOffset; } ///< Get minimum offset of the guarded range
uintb getMaximum(void) const { return maximumOffset; } ///< Get maximum offset of the guarded range
int4 getStep(void) const { return step; } ///< Get the calculated step associated with the range (or 0)
bool isGuarded(const Address &addr) const; ///< Does \b this guard apply to the given address
bool isRangeLocked(void) const { return (analysisState == 2); } ///< Return \b true if the range is fully determined
bool isValid(OpCode opc) const { return (!op->isDead() && op->code() == opc); } ///< Return \b true if the record still describes an active LOAD
};
@ -273,6 +274,7 @@ public:
void heritage(void); ///< Perform one pass of heritage
const list<LoadGuard> &getLoadGuards(void) const { return loadGuard; } ///< Get list of LOAD ops that are guarded
const list<LoadGuard> &getStoreGuards(void) const { return storeGuard; } ///< Get list of STORE ops that are guarded
const LoadGuard *getStoreGuard(PcodeOp *op) const; ///< Get LoadGuard record associated with given PcodeOp
};
#endif

View file

@ -2805,6 +2805,13 @@ int4 RuleIndirectCollapse::applyOp(PcodeOp *op,Funcdata &data)
if (!op->getOut()->hasNoLocalAlias())
return 0;
}
else if (indop->usesSpacebasePtr()) {
const LoadGuard *guard = data.getStoreGuard(indop);
if (guard != (const LoadGuard *)0) {
if (guard->isGuarded(op->getOut()->getAddr()))
return 0;
}
}
else
return 0;
}

View file

@ -112,20 +112,6 @@ void AddrSpace::truncateSpace(uint4 newsize)
calcScaleMask();
}
/// Check if this space contains \b id2.
/// \param id2 is the space to check
/// \return \b true if \b id2 is contained
bool AddrSpace::contain(AddrSpace *id2) const
{
while(this != id2) {
id2 = id2->getContain();
if (id2 == (AddrSpace *)0)
return false; // No containment
}
return true;
}
/// Write the main XML attributes for an address within this space
/// The caller provides only the \e offset, and this routine fills
/// in other details pertaining to this particular space.

View file

@ -121,7 +121,6 @@ public:
uintb getHighest(void) const; ///< Get the highest byte-scaled address
uintb wrapOffset(uintb off) const; ///< Wrap -off- to the offset that fits into this space
char getShortcut(void) const; ///< Get the shortcut character
bool contain(AddrSpace *id2) const; ///< Determine if this space contains another
bool isHeritaged(void) const; ///< Return \b true if dataflow has been traced
bool doesDeadcode(void) const; ///< Return \b true if dead code analysis should be done on this space
bool hasPhysical(void) const; ///< Return \b true if data is physically stored in this