decompiler
1.0.0
|
A description of the topological scope of a single variable object. More...
#include <cover.hh>
Public Member Functions | |
void | clear (void) |
Clear this to an empty Cover. | |
int4 | compareTo (const Cover &op2) const |
Give ordering of this and another Cover. More... | |
const CoverBlock & | getCoverBlock (int4 i) const |
Get the CoverBlock corresponding to the i-th block. More... | |
int4 | intersect (const Cover &op2) const |
Characterize the intersection between this and another Cover. More... | |
int4 | intersectByBlock (int4 blk, const Cover &op2) const |
Characterize the intersection on a specific block. More... | |
void | intersectList (vector< int4 > &listout, const Cover &op2, int4 level) const |
Generate a list of blocks that intersect. More... | |
bool | contain (const PcodeOp *op, int4 max) const |
Does this contain the given PcodeOp. More... | |
int4 | containVarnodeDef (const Varnode *vn) const |
Check the definition of a Varnode for containment. More... | |
void | merge (const Cover &op2) |
Merge this with another Cover block by block. More... | |
void | rebuild (const Varnode *vn) |
Reset this based on def-use of a single Varnode. More... | |
void | addDefPoint (const Varnode *vn) |
Reset to the single point where the given Varnode is defined. More... | |
void | addRefPoint (const PcodeOp *ref, const Varnode *vn) |
Add a variable read to this Cover. More... | |
void | print (ostream &s) const |
Dump a description of this cover to stream. More... | |
map< int4, CoverBlock >::const_iterator | begin (void) const |
Get beginning of CoverBlocks. | |
map< int4, CoverBlock >::const_iterator | end (void) const |
Get end of CoverBlocks. | |
Private Member Functions | |
void | addRefRecurse (const FlowBlock *bl) |
Fill-in this recursively from the given block. More... | |
Private Attributes | |
map< int4, CoverBlock > | cover |
block index -> CoverBlock | |
Static Private Attributes | |
static const CoverBlock | emptyBlock |
Global empty CoverBlock for blocks not covered by this. | |
A description of the topological scope of a single variable object.
The topological scope of a variable within a function is the set of locations within the code of the function where that variable holds a variable. For the decompiler, a high-level variable in this sense, HighVariable, is a collection of Varnode objects. In order to merge Varnodes into a HighVariable, the topological scope of each Varnode must not intersect because that would mean the high-level variable holds different values at the same point in the function.
Internally this is implemented as a map from basic block to their non-empty CoverBlock
void ghidra::Cover::addDefPoint | ( | const Varnode * | vn | ) |
Reset to the single point where the given Varnode is defined.
Any previous cover is removed. Calling this with an input Varnode still produces a valid Cover.
vn | is the Varnode |
References ghidra::Varnode::getDef(), ghidra::FlowBlock::getIndex(), ghidra::PcodeOp::getParent(), ghidra::Varnode::isInput(), ghidra::CoverBlock::setBegin(), and ghidra::CoverBlock::setEnd().
Referenced by ghidra::Merge::buildDominantCopy(), ghidra::Merge::checkCopyPair(), and ghidra::Merge::eliminateIntersect().
Add a variable read to this Cover.
Given a Varnode being read and the PcodeOp which reads it, add the point of the read to this and recursively fill in backwards until we run into existing cover.
References ghidra::PcodeOp::code(), ghidra::CPUI_MULTIEQUAL, ghidra::PcodeOp::getIn(), ghidra::FlowBlock::getIn(), ghidra::FlowBlock::getIndex(), ghidra::PcodeOp::getParent(), ghidra::CoverBlock::getUIndex(), ghidra::PcodeOp::numInput(), ghidra::CoverBlock::setEnd(), and ghidra::FlowBlock::sizeIn().
Referenced by ghidra::Merge::buildDominantCopy(), ghidra::Merge::checkCopyPair(), and ghidra::Merge::eliminateIntersect().
|
private |
Fill-in this recursively from the given block.
Add to this Cover recursively, starting at bottom of the given block and filling in backward until we run into existing cover.
bl | is the starting block to add |
References ghidra::PcodeOp::code(), ghidra::CPUI_MULTIEQUAL, ghidra::FlowBlock::getIn(), ghidra::FlowBlock::getIndex(), ghidra::CoverBlock::getUIndex(), ghidra::CoverBlock::setAll(), and ghidra::FlowBlock::sizeIn().
int4 ghidra::Cover::compareTo | ( | const Cover & | op2 | ) | const |
Give ordering of this and another Cover.
Compare this with another Cover by comparing just the indices of the first blocks respectively that are partly covered. Return -1, 0, or 1 if this Cover's first block has a smaller, equal, or bigger index than the other Cover's first block.
op2 | is the other Cover |
References cover.
Referenced by ghidra::Merge::compareHighByBlock().
bool ghidra::Cover::contain | ( | const PcodeOp * | op, |
int4 | max | ||
) | const |
Does this contain the given PcodeOp.
op | is the given PcodeOp |
max | is 1 to test for any containment, 2 to force interior containment |
References ghidra::FlowBlock::getIndex(), and ghidra::PcodeOp::getParent().
Referenced by ghidra::Merge::checkCopyPair(), and ghidra::ActionMarkImplied::checkImpliedCover().
int4 ghidra::Cover::containVarnodeDef | ( | const Varnode * | vn | ) | const |
Check the definition of a Varnode for containment.
If the given Varnode has a defining PcodeOp this is checked for containment. If the Varnode is an input, check if this covers the start of the function.
Return:
vn | is the given Varnode |
References ghidra::Varnode::getDef(), ghidra::FlowBlock::getIndex(), and ghidra::PcodeOp::getParent().
Referenced by ghidra::Merge::eliminateIntersect(), and ghidra::Merge::hideShadows().
const CoverBlock & ghidra::Cover::getCoverBlock | ( | int4 | i | ) | const |
Get the CoverBlock corresponding to the i-th block.
Return a representative CoverBlock describing how much of the given block is covered by this
i | is the index of the given block |
Referenced by ghidra::Merge::collectCorrectable(), and ghidra::Merge::collectCovering().
int4 ghidra::Cover::intersect | ( | const Cover & | op2 | ) | const |
Characterize the intersection between this and another Cover.
Return
op2 | is the other Cover |
References cover.
Referenced by ghidra::Merge::buildDominantCopy(), ghidra::Merge::inflateTest(), ghidra::HighVariable::markExpression(), and ghidra::Merge::shadowedVarnode().
int4 ghidra::Cover::intersectByBlock | ( | int4 | blk, |
const Cover & | op2 | ||
) | const |
Characterize the intersection on a specific block.
Looking only at the given block, Return
blk | is the index of the given block |
op2 | is the other Cover |
References cover.
Referenced by ghidra::HighIntersectTest::gatherBlockVarnodes(), and ghidra::HighIntersectTest::testBlockIntersection().
void ghidra::Cover::intersectList | ( | vector< int4 > & | listout, |
const Cover & | op2, | ||
int4 | level | ||
) | const |
Generate a list of blocks that intersect.
For each block for which this and another Cover intersect, and the block's index to a result list if the type of intersection exceeds a characterization level.
listout | will hold the list of intersecting block indices |
op2 | is the other Cover |
level | is the characterization threshold which must be exceeded |
References cover.
Referenced by ghidra::HighIntersectTest::intersection().
void ghidra::Cover::merge | ( | const Cover & | op2 | ) |
Merge this with another Cover block by block.
op2 | is the other Cover |
References cover.
Referenced by ghidra::Merge::buildDominantCopy(), ghidra::Merge::inflate(), and ghidra::HighVariable::markExpression().
void ghidra::Cover::print | ( | ostream & | s | ) | const |
Dump a description of this cover to stream.
s | is the output stream |
Referenced by ghidra::HighVariable::printCover().
void ghidra::Cover::rebuild | ( | const Varnode * | vn | ) |
Reset this based on def-use of a single Varnode.
The cover is set to all p-code ops between the point where the Varnode is defined and all the points where it is read
vn | is the single Varnode |
References ghidra::Varnode::beginDescend(), and ghidra::Varnode::endDescend().