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;
|
VarnodeLocSet::const_iterator viter;
|
||||||
list<PcodeOp *>::const_iterator oiter;
|
list<PcodeOp *>::const_iterator oiter;
|
||||||
Varnode *vn,*vncur,*defvn,*outvn;
|
Varnode *vn,*vncur,*outvn;
|
||||||
PcodeOp *op;
|
|
||||||
vector<DescTreeElement> varstack; // Depth first varnode traversal stack
|
vector<DescTreeElement> varstack; // Depth first varnode traversal stack
|
||||||
|
|
||||||
for(viter=data.beginLoc();viter!=data.endLoc();++viter) {
|
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
|
if (!checkImpliedCover(data,vncur)) // Can this variable be implied
|
||||||
vncur->setExplicit(); // if not, mark explicit
|
vncur->setExplicit(); // if not, mark explicit
|
||||||
else {
|
else {
|
||||||
vncur->setImplied(); // Mark as implied
|
Merge::markImplied(vncur);
|
||||||
op = vncur->getDef();
|
|
||||||
// setting the implied type is now taken care of by ActionSetCasts
|
// setting the implied type is now taken care of by ActionSetCasts
|
||||||
// vn->updatetype(op->outputtype_token(),false,false); // implied must have parsed type
|
// 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();
|
varstack.pop_back();
|
||||||
}
|
}
|
||||||
|
@ -477,11 +477,22 @@ void Cover::merge(const Cover &op2)
|
|||||||
void Cover::rebuild(const Varnode *vn)
|
void Cover::rebuild(const Varnode *vn)
|
||||||
|
|
||||||
{
|
{
|
||||||
list<PcodeOp *>::const_iterator iter;
|
vector<const Varnode *> path(1,vn);
|
||||||
|
int4 pos = 0;
|
||||||
|
|
||||||
addDefPoint(vn);
|
addDefPoint(vn);
|
||||||
for(iter=vn->beginDescend();iter!=vn->endDescend();++iter)
|
do {
|
||||||
addRefPoint(*iter,vn);
|
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
|
/// Any previous cover is removed. Calling this with an
|
||||||
|
@ -1586,24 +1586,22 @@ void Merge::clear(void)
|
|||||||
stackAffectingOps.clear();
|
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
|
/// The covers of the immediate Varnodes involved in the expression are marked as dirty.
|
||||||
/// output Varnode of the expression if the Varnode Cover can be \b inflated to include the
|
/// This assumes covers for the whole expression are ultimately marked because all its internal Varnodes
|
||||||
/// Cover of the HighVariable, even though the Varnode is not part of the HighVariable.
|
/// are passed to this method.
|
||||||
/// This routine performs the inflation, assuming an intersection test is already performed.
|
/// \param vn is the given Varnode being marked as \e implied
|
||||||
/// \param a is the given Varnode to inflate
|
void Merge::markImplied(Varnode *vn)
|
||||||
/// \param high is the HighVariable to inflate with
|
|
||||||
void Merge::inflate(Varnode *a,HighVariable *high)
|
|
||||||
|
|
||||||
{
|
{
|
||||||
testCache.updateHigh(a->getHigh());
|
vn->setImplied(); // Mark as implied
|
||||||
testCache.updateHigh(high);
|
PcodeOp *op = vn->getDef();
|
||||||
for(int4 i=0;i<high->numInstances();++i) {
|
for(int4 i=0;i<op->numInput();++i) {
|
||||||
Varnode *b = high->getInstance(i);
|
Varnode *defvn = op->getIn(i);
|
||||||
a->cover->merge(*b->cover);
|
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
|
/// \brief Test if we can inflate the Cover of the given Varnode without incurring intersections
|
||||||
|
@ -117,8 +117,8 @@ class Merge {
|
|||||||
public:
|
public:
|
||||||
Merge(Funcdata &fd) : data(fd), stackAffectingOps(fd), testCache(stackAffectingOps) {} ///< Construct given a specific function
|
Merge(Funcdata &fd) : data(fd), stackAffectingOps(fd), testCache(stackAffectingOps) {} ///< Construct given a specific function
|
||||||
void clear(void);
|
void clear(void);
|
||||||
|
static void markImplied(Varnode *vn);
|
||||||
bool inflateTest(Varnode *a,HighVariable *high);
|
bool inflateTest(Varnode *a,HighVariable *high);
|
||||||
void inflate(Varnode *a,HighVariable *high);
|
|
||||||
bool mergeTest(HighVariable *high,vector<HighVariable *> &tmplist);
|
bool mergeTest(HighVariable *high,vector<HighVariable *> &tmplist);
|
||||||
|
|
||||||
void mergeOpcode(OpCode opc);
|
void mergeOpcode(OpCode opc);
|
||||||
|
Loading…
Reference in New Issue
Block a user