GP-4960 Recursively walk implied Varnodes when building a Cover

This commit is contained in:
caheckman 2024-09-30 22:53:40 +00:00
parent a3d0b40f36
commit 4eef52216d
4 changed files with 35 additions and 34 deletions

View File

@ -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();
}

View File

@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -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

View File

@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -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

View File

@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -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);