mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 18:29:37 +02:00
rearrange LoadGuard class
This commit is contained in:
parent
e1507d05ec
commit
8cad85e36c
3 changed files with 47 additions and 34 deletions
|
@ -232,6 +232,8 @@ public:
|
||||||
/// \return \b true if the Varnode is fully linked
|
/// \return \b true if the Varnode is fully linked
|
||||||
bool isHeritaged(Varnode *vn) { return (heritage.heritagePass(vn->getAddr())>=0); }
|
bool isHeritaged(Varnode *vn) { return (heritage.heritagePass(vn->getAddr())>=0); }
|
||||||
|
|
||||||
|
const list<LoadGuard> &getLoadGuards(void) const { return heritage.getLoadGuards(); }
|
||||||
|
|
||||||
// Function prototype and call specification routines
|
// Function prototype and call specification routines
|
||||||
int4 numCalls(void) const { return qlst.size(); } ///< Get the number of calls made by \b this function
|
int4 numCalls(void) const { return qlst.size(); } ///< Get the number of calls made by \b this function
|
||||||
FuncCallSpecs *getCallSpecs(int4 i) const { return qlst[i]; } ///< Get the i-th call specification
|
FuncCallSpecs *getCallSpecs(int4 i) const { return qlst[i]; } ///< Get the i-th call specification
|
||||||
|
|
|
@ -578,22 +578,20 @@ void Heritage::handleNewLoadCopies(void)
|
||||||
///
|
///
|
||||||
/// isAnalyzed is set to \b true, if full range analysis is not needed
|
/// isAnalyzed is set to \b true, if full range analysis is not needed
|
||||||
/// \param valueSet is the calculated value set as seen by the LOAD operation
|
/// \param valueSet is the calculated value set as seen by the LOAD operation
|
||||||
void Heritage::LoadGuard::establishRange(const ValueSetRead &valueSet)
|
void LoadGuard::establishRange(const ValueSetRead &valueSet)
|
||||||
|
|
||||||
{
|
{
|
||||||
const CircleRange &range( valueSet.getRange() );
|
const CircleRange &range( valueSet.getRange() );
|
||||||
uintb rangeSize = range.getSize();
|
uintb rangeSize = range.getSize();
|
||||||
uintb size;
|
uintb size;
|
||||||
if (range.isEmpty()) {
|
if (range.isEmpty()) {
|
||||||
step = 0;
|
|
||||||
minimumOffset = pointerBase;
|
minimumOffset = pointerBase;
|
||||||
size = 0x1000;
|
size = 0x1000;
|
||||||
}
|
}
|
||||||
else if (range.isFull() || rangeSize > 0xffffff) {
|
else if (range.isFull() || rangeSize > 0xffffff) {
|
||||||
step = 1;
|
|
||||||
minimumOffset = pointerBase;
|
minimumOffset = pointerBase;
|
||||||
size = 0x1000;
|
size = 0x1000;
|
||||||
isAnalyzed = true; // Don't bother doing more analysis
|
analysisState = 1; // Don't bother doing more analysis
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
step = (rangeSize == 3) ? range.getStep() : 0; // Check for consistent step
|
step = (rangeSize == 3) ? range.getStep() : 0; // Check for consistent step
|
||||||
|
@ -627,21 +625,20 @@ void Heritage::LoadGuard::establishRange(const ValueSetRead &valueSet)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Heritage::LoadGuard::finalizeRange(const ValueSetRead &valueSet)
|
void LoadGuard::finalizeRange(const ValueSetRead &valueSet)
|
||||||
|
|
||||||
{
|
{
|
||||||
isAnalyzed = true; // In all cases the settings determined here are final
|
analysisState = 1; // In all cases the settings determined here are final
|
||||||
const CircleRange &range( valueSet.getRange() );
|
const CircleRange &range( valueSet.getRange() );
|
||||||
uintb rangeSize = range.getSize();
|
uintb rangeSize = range.getSize();
|
||||||
if (rangeSize > 1 && rangeSize < 0xffffff) { // Did we converge to something reasonable
|
if (rangeSize > 1 && rangeSize < 0xffffff) { // Did we converge to something reasonable
|
||||||
|
analysisState = 2; // Mark that we got a definitive result
|
||||||
step = range.getStep();
|
step = range.getStep();
|
||||||
minimumOffset = range.getMin();
|
minimumOffset = range.getMin();
|
||||||
maximumOffset = range.getMax();
|
maximumOffset = range.getMax();
|
||||||
if (maximumOffset < minimumOffset) // Values extend into what is usually stack parameters
|
if (maximumOffset < minimumOffset) // Values extend into what is usually stack parameters
|
||||||
maximumOffset = spc->getHighest();
|
maximumOffset = spc->getHighest();
|
||||||
}
|
}
|
||||||
if (step == 0)
|
|
||||||
step = 1;
|
|
||||||
if (minimumOffset > spc->getHighest())
|
if (minimumOffset > spc->getHighest())
|
||||||
minimumOffset = spc->getHighest();
|
minimumOffset = spc->getHighest();
|
||||||
if (maximumOffset > spc->getHighest())
|
if (maximumOffset > spc->getHighest())
|
||||||
|
@ -652,14 +649,14 @@ void Heritage::analyzeNewLoadGuards(void)
|
||||||
|
|
||||||
{
|
{
|
||||||
if (loadGuard.empty()) return;
|
if (loadGuard.empty()) return;
|
||||||
if (loadGuard.back().isAnalyzed) return; // Nothing new
|
if (loadGuard.back().analysisState != 0) return; // Nothing new
|
||||||
list<LoadGuard>::iterator startIter = loadGuard.end();
|
list<LoadGuard>::iterator startIter = loadGuard.end();
|
||||||
vector<Varnode *> sinks;
|
vector<Varnode *> sinks;
|
||||||
vector<PcodeOp *> reads;
|
vector<PcodeOp *> reads;
|
||||||
while(startIter != loadGuard.begin()) {
|
while(startIter != loadGuard.begin()) {
|
||||||
--startIter;
|
--startIter;
|
||||||
LoadGuard &guard( *startIter );
|
LoadGuard &guard( *startIter );
|
||||||
if (guard.isAnalyzed) break;
|
if (guard.analysisState != 0) break;
|
||||||
reads.push_back(guard.op);
|
reads.push_back(guard.op);
|
||||||
sinks.push_back(guard.op->getIn(1)); // The CPUI_LOAD pointer
|
sinks.push_back(guard.op->getIn(1)); // The CPUI_LOAD pointer
|
||||||
}
|
}
|
||||||
|
@ -676,7 +673,7 @@ void Heritage::analyzeNewLoadGuards(void)
|
||||||
for(iter=startIter;iter!=loadGuard.end(); ++iter) {
|
for(iter=startIter;iter!=loadGuard.end(); ++iter) {
|
||||||
LoadGuard &guard( *iter );
|
LoadGuard &guard( *iter );
|
||||||
guard.establishRange(vsSolver.getValueSetRead(guard.op->getSeqNum()));
|
guard.establishRange(vsSolver.getValueSetRead(guard.op->getSeqNum()));
|
||||||
if (!guard.isAnalyzed)
|
if (guard.analysisState == 0)
|
||||||
runFullAnalysis = true;
|
runFullAnalysis = true;
|
||||||
}
|
}
|
||||||
if (runFullAnalysis) {
|
if (runFullAnalysis) {
|
||||||
|
@ -700,13 +697,7 @@ void Heritage::generateLoadGuard(StackNode &node,PcodeOp *op,AddrSpace *spc)
|
||||||
|
|
||||||
{
|
{
|
||||||
loadGuard.push_back(LoadGuard());
|
loadGuard.push_back(LoadGuard());
|
||||||
LoadGuard &guard( loadGuard.back() );
|
loadGuard.back().set(op,spc,node.offset);
|
||||||
guard.op = op;
|
|
||||||
guard.spc = spc;
|
|
||||||
guard.pointerBase = node.offset;
|
|
||||||
guard.minimumOffset = 0; // Initially we guard everything
|
|
||||||
guard.maximumOffset = spc->getHighest();
|
|
||||||
guard.isAnalyzed = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Trace input stackpointer to any indexed loads
|
/// \brief Trace input stackpointer to any indexed loads
|
||||||
|
|
|
@ -95,6 +95,39 @@ class HeritageInfo {
|
||||||
deadremoved = 0; deadcodedelay = delay; warningissued = false; loadGuardSearch = false; } ///< Reset
|
deadremoved = 0; deadcodedelay = delay; warningissued = false; loadGuardSearch = false; } ///< Reset
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// \brief Description of a LOAD operation that needs to be guarded
|
||||||
|
///
|
||||||
|
/// Heritage maintains a list of CPUI_LOAD ops that reference the stack dynamically. These
|
||||||
|
/// can potentially alias stack Varnodes, so we maintain what (possibly limited) information
|
||||||
|
/// we known about the range of stack addresses that can be referenced.
|
||||||
|
class LoadGuard {
|
||||||
|
friend class Heritage;
|
||||||
|
PcodeOp *op; ///< The LOAD op
|
||||||
|
AddrSpace *spc; ///< The stack space being loaded from
|
||||||
|
uintb pointerBase; ///< Base offset of the pointer
|
||||||
|
uintb minimumOffset; ///< Minimum offset of the LOAD
|
||||||
|
uintb maximumOffset; ///< Maximum offset of the LOAD
|
||||||
|
int4 step; ///< Step of any access into this range (0=unknown)
|
||||||
|
int4 analysisState; ///< 0=unanalyzed, 1=analyzed(partial result), 2=analyzed(full result)
|
||||||
|
void establishRange(const ValueSetRead &valueSet); ///< Convert partial value set analysis into guard range
|
||||||
|
void finalizeRange(const ValueSetRead &valueSet); ///< Convert value set analysis to final guard range
|
||||||
|
|
||||||
|
/// \brief Set a new unanalyzed LOAD guard that initially guards everything
|
||||||
|
///
|
||||||
|
/// \param o is the LOAD op
|
||||||
|
/// \param s is the (stack) space it is loading from
|
||||||
|
/// \param off is the base offset that is indexed from
|
||||||
|
void set(PcodeOp *o,AddrSpace *s,uintb off) {
|
||||||
|
op = o; spc = s; pointerBase=off; minimumOffset=0; maximumOffset=s->getHighest(); step=0; analysisState=0;
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
PcodeOp *getOp(void) const { return op; } ///< Get the PcodeOp being guarded
|
||||||
|
uintb getMinimum(void) const { return minimumOffset; } ///< Get minimum offset of the guarded range
|
||||||
|
uintb getMaximum(void) const { return maximumOffset; } ///< Get maximum offset of the guarded range
|
||||||
|
int4 getStep(void) const { return step; } ///< Get the calculated step associated with the range (or 0)
|
||||||
|
bool isRangeLocked(void) const { return (analysisState == 2); } ///< Return \b true if the range is fully determined
|
||||||
|
};
|
||||||
|
|
||||||
/// \brief Manage the construction of Static Single Assignment (SSA) form
|
/// \brief Manage the construction of Static Single Assignment (SSA) form
|
||||||
///
|
///
|
||||||
/// With a specific function (Funcdata), this class links the Varnode and
|
/// With a specific function (Funcdata), this class links the Varnode and
|
||||||
|
@ -156,20 +189,6 @@ class Heritage {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// \brief Description of a LOAD operation that needs to be guarded
|
|
||||||
class LoadGuard {
|
|
||||||
friend class Heritage;
|
|
||||||
PcodeOp *op; ///< The LOAD op
|
|
||||||
AddrSpace *spc; ///< The stack space being loaded from
|
|
||||||
uintb pointerBase; ///< Base offset of the pointer
|
|
||||||
uintb minimumOffset; ///< Minimum offset of the LOAD
|
|
||||||
uintb maximumOffset; ///< Maximum offset of the LOAD
|
|
||||||
int4 step; ///< Step of any access into this range
|
|
||||||
bool isAnalyzed; ///< Has a range analysis been performed on \b this
|
|
||||||
void establishRange(const ValueSetRead &valueSet); ///< Convert partial value set analysis into guard range
|
|
||||||
void finalizeRange(const ValueSetRead &valueSet); ///< Convert value set analysis to final guard range
|
|
||||||
};
|
|
||||||
|
|
||||||
Funcdata *fd; ///< The function \b this is controlling SSA construction
|
Funcdata *fd; ///< The function \b this is controlling SSA construction
|
||||||
LocationMap globaldisjoint; ///< Disjoint cover of every heritaged memory location
|
LocationMap globaldisjoint; ///< Disjoint cover of every heritaged memory location
|
||||||
LocationMap disjoint; ///< Disjoint cover of memory locations currently being heritaged
|
LocationMap disjoint; ///< Disjoint cover of memory locations currently being heritaged
|
||||||
|
@ -229,6 +248,8 @@ class Heritage {
|
||||||
void calcMultiequals(const vector<Varnode *> &write);
|
void calcMultiequals(const vector<Varnode *> &write);
|
||||||
void renameRecurse(BlockBasic *bl,VariableStack &varstack);
|
void renameRecurse(BlockBasic *bl,VariableStack &varstack);
|
||||||
void bumpDeadcodeDelay(Varnode *vn);
|
void bumpDeadcodeDelay(Varnode *vn);
|
||||||
|
void placeMultiequals(void);
|
||||||
|
void rename(void);
|
||||||
public:
|
public:
|
||||||
Heritage(Funcdata *data); ///< Constructor
|
Heritage(Funcdata *data); ///< Constructor
|
||||||
|
|
||||||
|
@ -246,9 +267,8 @@ public:
|
||||||
void buildInfoList(void); ///< Initialize information for each space
|
void buildInfoList(void); ///< Initialize information for each space
|
||||||
void forceRestructure(void) { maxdepth = -1; } ///< Force regeneration of basic block structures
|
void forceRestructure(void) { maxdepth = -1; } ///< Force regeneration of basic block structures
|
||||||
void clear(void); ///< Reset all analysis of heritage
|
void clear(void); ///< Reset all analysis of heritage
|
||||||
void placeMultiequals(void);
|
|
||||||
void rename(void);
|
|
||||||
void heritage(void); ///< Perform one pass of heritage
|
void heritage(void); ///< Perform one pass of heritage
|
||||||
|
const list<LoadGuard> &getLoadGuards(void) const { return loadGuard; } ///< Get list of LOAD ops that are guarded
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue