mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 02:39:44 +02:00
GP-3429 Intersect tests for stack affecting ops
This commit is contained in:
parent
d932173a25
commit
67b22166af
12 changed files with 432 additions and 15 deletions
|
@ -26,6 +26,44 @@ class PcodeOp;
|
|||
class FlowBlock;
|
||||
class Varnode;
|
||||
|
||||
/// \brief A set of PcodeOps that can be tested for Cover intersections
|
||||
///
|
||||
/// This is a set of PcodeOp objects, designed for quick intersection tests with a Cover. The set is
|
||||
/// lazily constructed via its populate() method at the time the first intersection test is needed.
|
||||
/// Once an intersection has been established between a PcodeOp in \b this set and a Varnode Cover,
|
||||
/// affectsTest() can do secondary testing to determine if the intersection should prevent merging.
|
||||
class PcodeOpSet {
|
||||
friend class Cover;
|
||||
vector<PcodeOp *> opList; // Ops in this set, sorted on block index, then SeqNum::order
|
||||
vector<int4> blockStart; // Index of first op in each non-empty block
|
||||
bool is_pop; // Has the populate() method been called
|
||||
protected:
|
||||
void addOp(PcodeOp *op) { opList.push_back(op); } ///< Add a PcodeOp into the set
|
||||
void finalize(void); // Sort ops in the set into blocks
|
||||
public:
|
||||
PcodeOpSet(void) { is_pop = false; }
|
||||
bool isPopulated(void) const { return is_pop; } /// Return \b true if \b this set is populated
|
||||
virtual ~PcodeOpSet(void) {}
|
||||
|
||||
/// \brief Populate the PcodeOp object in \b this set
|
||||
///
|
||||
/// Call-back to the owner to lazily add PcodeOps to \b this set. The override method calls addOp() for
|
||||
/// each PcodeOp it wants to add, then calls finalize() to make \b this set ready for intersection tests.
|
||||
virtual void populate(void)=0;
|
||||
|
||||
/// \brief (Secondary) test that the given PcodeOp affects the Varnode
|
||||
///
|
||||
/// This method is called after an intersection of a PcodeOp in \b this set with a Varnode Cover has been
|
||||
/// determined. This allows the owner to make a final determination if merging should be prevented.
|
||||
/// \param op is the PcodeOp that intersects with the Varnode Cover
|
||||
/// \param vn is the Varnode whose Cover is intersected
|
||||
/// \return \b true if merging should be prevented
|
||||
virtual bool affectsTest(PcodeOp *op,Varnode *vn) const=0;
|
||||
|
||||
void clear(void) { is_pop = false; opList.clear(); blockStart.clear(); } ///< Clear all PcodeOps in \b this
|
||||
static bool compareByBlock(const PcodeOp *a,const PcodeOp *b); ///< Compare PcodeOps for \b this set
|
||||
};
|
||||
|
||||
/// \brief The topological scope of a variable within a basic block
|
||||
///
|
||||
/// Within a basic block, the topological scope of a variable can be considered
|
||||
|
@ -78,6 +116,7 @@ public:
|
|||
int4 intersect(const Cover &op2) const; ///< Characterize the intersection between \b this and another Cover.
|
||||
int4 intersectByBlock(int4 blk,const Cover &op2) const; ///< Characterize the intersection on a specific block
|
||||
void intersectList(vector<int4> &listout,const Cover &op2,int4 level) const;
|
||||
bool intersect(const PcodeOpSet &opSet,Varnode *rep) const; ///< Does \b this cover any PcodeOp in the given PcodeOpSet
|
||||
bool contain(const PcodeOp *op,int4 max) const;
|
||||
int4 containVarnodeDef(const Varnode *vn) const;
|
||||
void merge(const Cover &op2); ///< Merge \b this with another Cover block by block
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue