mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-11-22 04:05:39 +00:00
GP-4960 Recursively walk implied Varnodes when building a Cover
This commit is contained in:
parent
a3d0b40f36
commit
4eef52216d
@ -3402,8 +3402,7 @@ int4 ActionMarkImplied::apply(Funcdata &data)
|
||||
{
|
||||
VarnodeLocSet::const_iterator viter;
|
||||
list<PcodeOp *>::const_iterator oiter;
|
||||
Varnode *vn,*vncur,*defvn,*outvn;
|
||||
PcodeOp *op;
|
||||
Varnode *vn,*vncur,*outvn;
|
||||
vector<DescTreeElement> varstack; // Depth first varnode traversal stack
|
||||
|
||||
for(viter=data.beginLoc();viter!=data.endLoc();++viter) {
|
||||
@ -3420,16 +3419,9 @@ int4 ActionMarkImplied::apply(Funcdata &data)
|
||||
if (!checkImpliedCover(data,vncur)) // Can this variable be implied
|
||||
vncur->setExplicit(); // if not, mark explicit
|
||||
else {
|
||||
vncur->setImplied(); // Mark as implied
|
||||
op = vncur->getDef();
|
||||
Merge::markImplied(vncur);
|
||||
// setting the implied type is now taken care of by ActionSetCasts
|
||||
// vn->updatetype(op->outputtype_token(),false,false); // implied must have parsed type
|
||||
// Back propagate varnode's cover to inputs of defining op
|
||||
for(int4 i=0;i<op->numInput();++i) {
|
||||
defvn = op->getIn(i);
|
||||
if (!defvn->hasCover()) continue;
|
||||
data.getMerge().inflate(defvn,vncur->getHigh());
|
||||
}
|
||||
}
|
||||
varstack.pop_back();
|
||||
}
|
||||
|
@ -477,11 +477,22 @@ void Cover::merge(const Cover &op2)
|
||||
void Cover::rebuild(const Varnode *vn)
|
||||
|
||||
{
|
||||
list<PcodeOp *>::const_iterator iter;
|
||||
vector<const Varnode *> path(1,vn);
|
||||
int4 pos = 0;
|
||||
|
||||
addDefPoint(vn);
|
||||
for(iter=vn->beginDescend();iter!=vn->endDescend();++iter)
|
||||
addRefPoint(*iter,vn);
|
||||
do {
|
||||
const Varnode *curVn = path[pos];
|
||||
pos += 1;
|
||||
list<PcodeOp *>::const_iterator iter;
|
||||
for(iter=curVn->beginDescend();iter!=curVn->endDescend();++iter) {
|
||||
const PcodeOp *op = *iter;
|
||||
addRefPoint(op,vn);
|
||||
const Varnode *outVn = op->getOut();
|
||||
if (outVn != (Varnode *)0 && outVn->isImplied())
|
||||
path.push_back(outVn);
|
||||
}
|
||||
} while(pos < path.size());
|
||||
}
|
||||
|
||||
/// Any previous cover is removed. Calling this with an
|
||||
|
@ -1586,24 +1586,22 @@ void Merge::clear(void)
|
||||
stackAffectingOps.clear();
|
||||
}
|
||||
|
||||
/// \brief Inflate the Cover of a given Varnode with a HighVariable
|
||||
/// \brief Mark the given Varnode as \e implied
|
||||
///
|
||||
/// An expression involving a HighVariable can be propagated to all the read sites of the
|
||||
/// output Varnode of the expression if the Varnode Cover can be \b inflated to include the
|
||||
/// Cover of the HighVariable, even though the Varnode is not part of the HighVariable.
|
||||
/// This routine performs the inflation, assuming an intersection test is already performed.
|
||||
/// \param a is the given Varnode to inflate
|
||||
/// \param high is the HighVariable to inflate with
|
||||
void Merge::inflate(Varnode *a,HighVariable *high)
|
||||
/// The covers of the immediate Varnodes involved in the expression are marked as dirty.
|
||||
/// This assumes covers for the whole expression are ultimately marked because all its internal Varnodes
|
||||
/// are passed to this method.
|
||||
/// \param vn is the given Varnode being marked as \e implied
|
||||
void Merge::markImplied(Varnode *vn)
|
||||
|
||||
{
|
||||
testCache.updateHigh(a->getHigh());
|
||||
testCache.updateHigh(high);
|
||||
for(int4 i=0;i<high->numInstances();++i) {
|
||||
Varnode *b = high->getInstance(i);
|
||||
a->cover->merge(*b->cover);
|
||||
vn->setImplied(); // Mark as implied
|
||||
PcodeOp *op = vn->getDef();
|
||||
for(int4 i=0;i<op->numInput();++i) {
|
||||
Varnode *defvn = op->getIn(i);
|
||||
if (!defvn->hasCover()) continue;
|
||||
defvn->setFlags(Varnode::coverdirty);
|
||||
}
|
||||
a->getHigh()->coverDirty();
|
||||
}
|
||||
|
||||
/// \brief Test if we can inflate the Cover of the given Varnode without incurring intersections
|
||||
|
@ -117,8 +117,8 @@ class Merge {
|
||||
public:
|
||||
Merge(Funcdata &fd) : data(fd), stackAffectingOps(fd), testCache(stackAffectingOps) {} ///< Construct given a specific function
|
||||
void clear(void);
|
||||
static void markImplied(Varnode *vn);
|
||||
bool inflateTest(Varnode *a,HighVariable *high);
|
||||
void inflate(Varnode *a,HighVariable *high);
|
||||
bool mergeTest(HighVariable *high,vector<HighVariable *> &tmplist);
|
||||
|
||||
void mergeOpcode(OpCode opc);
|
||||
|
Loading…
Reference in New Issue
Block a user