mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 10:49:34 +02:00
Different widening strategies
This commit is contained in:
parent
8565f43e06
commit
32793712fe
3 changed files with 173 additions and 64 deletions
|
@ -99,6 +99,7 @@ public:
|
|||
};
|
||||
|
||||
class Partition; // Forward declaration
|
||||
class Widener; // Forward declaration
|
||||
|
||||
/// \brief A range of values attached to a Varnode within a data-flow subsystem
|
||||
///
|
||||
|
@ -139,11 +140,11 @@ private:
|
|||
void setVarnode(Varnode *v,int4 tCode); ///< Attach \b this to given Varnode and set initial values
|
||||
void addEquation(int4 slot,int4 type,const CircleRange &constraint); ///< Insert an equation restricting \b this value set
|
||||
void addLandmark(int4 type,const CircleRange &constraint) { addEquation(numParams,type,constraint); } ///< Add a widening landmark
|
||||
void doWidening(const CircleRange &newRange); ///< Widen the value set so fixed point is reached sooner
|
||||
void looped(void); ///< Mark that iteration has looped back to \b this
|
||||
void computeTypeCode(void); ///< Figure out if \b this value set is absolute or relative
|
||||
bool iterate(void); ///< Regenerate \b this value set from operator inputs
|
||||
bool iterate(Widener &widener); ///< Regenerate \b this value set from operator inputs
|
||||
public:
|
||||
int4 getCount(void) const { return count; } ///< Get the current iteration count
|
||||
const CircleRange *getLandMark(void) const; ///< Get any \e landmark range
|
||||
int4 getTypeCode(void) const { return typeCode; } ///< Return '0' for normal constant, '1' for spacebase relative
|
||||
Varnode *getVarnode(void) const { return vn; } ///< Get the Varnode attached to \b this ValueSet
|
||||
const CircleRange &getRange(void) const { return range; } ///< Get the actual range of values
|
||||
|
@ -185,6 +186,58 @@ public:
|
|||
void printRaw(ostream &s) const; ///< Write a text description of \b to the given stream
|
||||
};
|
||||
|
||||
class Widener {
|
||||
public:
|
||||
virtual ~Widener(void) {} ///< Destructor
|
||||
|
||||
/// \brief Upon entering a fresh partition, determine how the given ValueSet count should be reset
|
||||
///
|
||||
/// \param valueSet is the given value set
|
||||
/// \return the value of the iteration counter to reset to
|
||||
virtual int4 determineIterationReset(const ValueSet &valueSet)=0;
|
||||
|
||||
/// \brief Check if the given value set has been frozen for the remainder of the iteration process
|
||||
///
|
||||
/// \param valueSet is the given value set
|
||||
/// \return \b true if the valueSet will no longer change
|
||||
virtual bool checkFreeze(const ValueSet &valueSet)=0;
|
||||
|
||||
/// \brief For an iteration that isn't stabilizing attempt to widen the given ValueSet
|
||||
///
|
||||
/// Change the given range based on its previous iteration so that it stabilizes more
|
||||
/// rapidly on future iterations.
|
||||
/// \param valueSet is the given value set
|
||||
/// \param range is the previous form of the given range (and storage for the widening result)
|
||||
/// \param newRange is the current iteration of the given range
|
||||
/// \return \b true if widening succeeded
|
||||
virtual bool doWidening(const ValueSet &valueSet,CircleRange &range,const CircleRange &newRange)=0;
|
||||
};
|
||||
|
||||
/// \brief Class for doing normal widening
|
||||
///
|
||||
/// Widening is attempted at a specific iteration. If a landmark is available, it is used
|
||||
/// to do a controlled widening, holding the stable range boundary constant. Otherwise a
|
||||
/// full range is produced. At a later iteration, a full range is produced automatically.
|
||||
class WidenerFull : public Widener {
|
||||
int4 widenIteration; ///< The iteration at which widening is attempted
|
||||
int4 fullIteration; ///< The iteration at which a full range is produced
|
||||
public:
|
||||
WidenerFull(void) { widenIteration = 2; fullIteration = 5; } ///< Constructor with default iterations
|
||||
WidenerFull(int4 wide,int4 full) { widenIteration = wide; fullIteration = full; } ///< Constructor specifying iterations
|
||||
virtual int4 determineIterationReset(const ValueSet &valueSet);
|
||||
virtual bool checkFreeze(const ValueSet &valueSet);
|
||||
virtual bool doWidening(const ValueSet &valueSet,CircleRange &range,const CircleRange &newRange);
|
||||
};
|
||||
|
||||
class WidenerNone : public Widener {
|
||||
int4 freezeIteration; ///< The iteration at which all change ceases
|
||||
public:
|
||||
WidenerNone(void) { freezeIteration = 3; }
|
||||
virtual int4 determineIterationReset(const ValueSet &valueSet);
|
||||
virtual bool checkFreeze(const ValueSet &valueSet);
|
||||
virtual bool doWidening(const ValueSet &valueSet,CircleRange &range,const CircleRange &newRange);
|
||||
};
|
||||
|
||||
/// \brief Class the determines a ValueSet for each Varnode in a data-flow system
|
||||
///
|
||||
/// This class uses \e value \e set \e analysis to calculate (an overestimation of)
|
||||
|
@ -235,7 +288,7 @@ class ValueSetSolver {
|
|||
public:
|
||||
void establishValueSets(const vector<Varnode *> &sinks,const vector<PcodeOp *> &reads,Varnode *stackReg,bool indirectAsCopy);
|
||||
int4 getNumIterations(void) const { return numIterations; } ///< Get the current number of iterations
|
||||
void solve(int4 max); ///< Iterate the ValueSet system until it stabilizes
|
||||
void solve(int4 max,Widener &widener); ///< Iterate the ValueSet system until it stabilizes
|
||||
list<ValueSet>::const_iterator beginValueSets(void) const { return valueNodes.begin(); } ///< Start of all ValueSets in the system
|
||||
list<ValueSet>::const_iterator endValueSets(void) const { return valueNodes.end(); } ///< End of all ValueSets in the system
|
||||
map<SeqNum,ValueSetRead>::const_iterator beginValueSetReads(void) const { return readNodes.begin(); } ///< Start of ValueSetReads
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue