mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 18:29:37 +02:00
Refactor ParamEntry look-up allowing "contained by" discovery
This commit is contained in:
parent
ef12c20829
commit
12d3da029b
13 changed files with 690 additions and 286 deletions
|
@ -20,6 +20,7 @@
|
|||
#define __CPUI_FSPEC__
|
||||
|
||||
#include "op.hh"
|
||||
#include "rangemap.hh"
|
||||
|
||||
class JoinRecord;
|
||||
|
||||
|
@ -85,6 +86,7 @@ public:
|
|||
bool isExclusion(void) const { return (alignment==0); } ///< Return \b true if this holds a single parameter exclusively
|
||||
bool isReverseStack(void) const { return ((flags & reverse_stack)!=0); } ///< Return \b true if parameters are allocated in reverse order
|
||||
bool contains(const ParamEntry &op2) const; ///< Does \b this contain the indicated entry.
|
||||
bool containedBy(const Address &addr,int4 sz) const; ///< Is this entry contained by the given range
|
||||
int4 justifiedContain(const Address &addr,int4 sz) const; ///< Calculate endian aware containment
|
||||
bool getContainer(const Address &addr,int4 sz,VarnodeData &res) const;
|
||||
OpCode assumedExtension(const Address &addr,int4 sz,VarnodeData &res) const;
|
||||
|
@ -93,11 +95,51 @@ public:
|
|||
uintb getBase(void) const { return addressbase; } ///< Get the starting offset of \b this entry
|
||||
Address getAddrBySlot(int4 &slot,int4 sz) const;
|
||||
void restoreXml(const Element *el,const AddrSpaceManager *manage,bool normalstack);
|
||||
void extraChecks(vector<ParamEntry> &entry);
|
||||
void extraChecks(list<ParamEntry> &entry);
|
||||
bool isParamCheckHigh(void) const { return ((flags & extracheck_high)!=0); } ///< Return \b true if there is a high overlap
|
||||
bool isParamCheckLow(void) const { return ((flags & extracheck_low)!=0); } ///< Return \b true if there is a low overlap
|
||||
};
|
||||
|
||||
/// \brief Class for storing ParamEntry objects in an interval range (rangemap)
|
||||
class ParamEntryRange {
|
||||
uintb first; ///< Starting offset of the ParamEntry's range
|
||||
uintb last; ///< Ending offset of the ParamEntry's range
|
||||
int4 position; ///< Position of the ParamEntry within the entire prototype list
|
||||
ParamEntry *entry; ///< Pointer to the actual ParamEntry
|
||||
|
||||
/// \brief Helper class for initializing ParamEntryRange in a range map
|
||||
class InitData {
|
||||
friend class ParamEntryRange;
|
||||
int4 position; ///< Position (within the full list) being assigned to the ParamEntryRange
|
||||
ParamEntry *entry; ///< Underlying ParamEntry being assigned to the ParamEntryRange
|
||||
public:
|
||||
InitData(int4 pos,ParamEntry *e) { position = pos; entry = e; } ///< Constructor
|
||||
};
|
||||
|
||||
/// \brief Helper class for subsorting on position
|
||||
class SubsortPosition {
|
||||
int4 position; ///< The position value
|
||||
public:
|
||||
SubsortPosition(void) {} ///< Constructor for use with rangemap
|
||||
SubsortPosition(int4 pos) { position = pos; } ///< Construct given position
|
||||
SubsortPosition(bool val) { position = val ? 1000000 : 0; } ///< Constructor minimal/maximal subsort
|
||||
bool operator<(const SubsortPosition &op2) { return position < op2.position; } ///< Compare operation
|
||||
};
|
||||
public:
|
||||
typedef uintb linetype; ///< The linear element for a rangemap
|
||||
typedef SubsortPosition subsorttype; ///< The sub-sort object for a rangemap
|
||||
typedef InitData inittype; ///< Initialization data for a ScopeMapper
|
||||
|
||||
ParamEntryRange(void) {} ///< Constructor for use with rangemap
|
||||
void initialize(const inittype &data,uintb f,uintb l) {
|
||||
first = f; last = l; position = data.position; entry = data.entry; } ///< Initialize the range
|
||||
uintb getFirst(void) const { return first; } ///< Get the first address in the range
|
||||
uintb getLast(void) const { return last; } ///< Get the last address in the range
|
||||
subsorttype getSubsort(void) const { return SubsortPosition(position); } ///< Get the sub-subsort object
|
||||
ParamEntry *getParamEntry(void) const { return entry; } ///< Get pointer to actual ParamEntry
|
||||
};
|
||||
typedef rangemap<ParamEntryRange> ParamEntryResolver; ///< A map from offset to ParamEntry
|
||||
|
||||
/// \brief A register or memory register that may be used to pass a parameter or return value
|
||||
///
|
||||
/// The parameter recovery utilities (see ParamActive) use this to denote a putative
|
||||
|
@ -344,6 +386,18 @@ public:
|
|||
/// \return \b true if the storage location can be split
|
||||
virtual bool checkSplit(const Address &loc,int4 size,int4 splitpoint) const=0;
|
||||
|
||||
/// \brief Characterize whether the given range overlaps parameter storage
|
||||
///
|
||||
/// Does the range naturally fit inside a potential parameter entry from this list or does
|
||||
/// it contain a parameter entry. Return one of three values indicating this characterization:
|
||||
/// - 0 means there is no intersection between the range and any parameter in this list
|
||||
/// - 1 means that at least one parameter contains the range in a properly justified manner
|
||||
/// - 2 means no parameter contains the range, but the range contains at least one ParamEntry
|
||||
/// \param loc is the starting address of the given range
|
||||
/// \param size is the number of bytes in the given range
|
||||
/// \return the characterization code
|
||||
virtual int4 characterizeAsParam(const Address &loc,int4 size) const=0;
|
||||
|
||||
/// \brief Does the given storage location make sense as a parameter
|
||||
///
|
||||
/// Within \b this model, decide if the storage location can be considered a parameter.
|
||||
|
@ -363,6 +417,14 @@ public:
|
|||
/// \return \b true if the location can be a parameter
|
||||
virtual bool possibleParamWithSlot(const Address &loc,int4 size,int4 &slot,int4 &slotsize) const=0;
|
||||
|
||||
/// \brief Pass-back the biggest parameter contained within the given range
|
||||
///
|
||||
/// \param loc is the starting address of the given range
|
||||
/// \param size is the number of bytes in the range
|
||||
/// \param res will hold the parameter storage description being passed back
|
||||
/// \return \b true if there is at least one parameter contained in the range
|
||||
virtual bool getBiggestContainedParam(const Address &loc,int4 size,VarnodeData &res) const=0;
|
||||
|
||||
/// \brief Check if the given storage location looks like an \e unjustified parameter
|
||||
///
|
||||
/// The storage for a value may be contained in a normal parameter location but be
|
||||
|
@ -433,9 +495,10 @@ protected:
|
|||
int4 pointermax; ///< If non-zero, maximum size of a data-type before converting to a pointer
|
||||
bool thisbeforeret; ///< Does a \b this parameter come before a hidden return parameter
|
||||
int4 nonfloatgroup; ///< Group of first entry which is not marked float
|
||||
vector<ParamEntry> entry; ///< The ordered list of parameter entries
|
||||
list<ParamEntry> entry; ///< The ordered list of parameter entries
|
||||
vector<ParamEntryResolver *> resolverMap; ///< Map from space id to resolver
|
||||
AddrSpace *spacebase; ///< Address space containing relative offset parameters
|
||||
int4 findEntry(const Address &loc,int4 size) const; ///< Given storage location find matching ParamEntry
|
||||
const ParamEntry *findEntry(const Address &loc,int4 size) const; ///< Given storage location find matching ParamEntry
|
||||
Address assignAddress(const Datatype *tp,vector<int4> &status) const; ///< Assign storage for given parameter data-type
|
||||
void buildTrialMap(ParamActive *active) const; ///< Build map from parameter trials to model ParamEntrys
|
||||
void separateFloat(ParamActive *active,int4 &floatstart,int4 &floatstop,int4 &start,int4 &stop) const;
|
||||
|
@ -443,18 +506,22 @@ protected:
|
|||
void forceNoUse(ParamActive *active,int4 start,int4 stop) const;
|
||||
void forceInactiveChain(ParamActive *active,int4 maxchain,int4 start,int4 stop) const;
|
||||
void calcDelay(void); ///< Calculate the maximum heritage delay for any potential parameter in this list
|
||||
void populateResolver(void); ///< Build the ParamEntry resolver maps
|
||||
public:
|
||||
ParamListStandard(void) {} ///< Construct for use with restoreXml()
|
||||
ParamListStandard(const ParamListStandard &op2); ///< Copy constructor
|
||||
const vector<ParamEntry> &getEntry(void) const { return entry; } ///< Get the list of parameter entries
|
||||
virtual ~ParamListStandard(void);
|
||||
const list<ParamEntry> &getEntry(void) const { return entry; } ///< Get the list of parameter entries
|
||||
virtual uint4 getType(void) const { return p_standard; }
|
||||
virtual void assignMap(const vector<Datatype *> &proto,bool isinput,
|
||||
TypeFactory &typefactory,vector<ParameterPieces> &res) const;
|
||||
virtual void fillinMap(ParamActive *active) const;
|
||||
virtual bool checkJoin(const Address &hiaddr,int4 hisize,const Address &loaddr,int4 losize) const;
|
||||
virtual bool checkSplit(const Address &loc,int4 size,int4 splitpoint) const;
|
||||
virtual int4 characterizeAsParam(const Address &loc,int4 size) const;
|
||||
virtual bool possibleParam(const Address &loc,int4 size) const;
|
||||
virtual bool possibleParamWithSlot(const Address &loc,int4 size,int4 &slot,int4 &slotsize) const;
|
||||
virtual bool getBiggestContainedParam(const Address &loc,int4 size,VarnodeData &res) const;
|
||||
virtual bool unjustifiedContainer(const Address &loc,int4 size,VarnodeData &res) const;
|
||||
virtual OpCode assumedExtension(const Address &addr,int4 size,VarnodeData &res) const;
|
||||
virtual AddrSpace *getSpacebase(void) const { return spacebase; }
|
||||
|
@ -513,6 +580,7 @@ public:
|
|||
ParamListMerged(void) : ParamListStandard() {} ///< Constructor for use with restoreXml
|
||||
ParamListMerged(const ParamListMerged &op2) : ParamListStandard(op2) {} ///< Copy constructor
|
||||
void foldIn(const ParamListStandard &op2); ///< Add another model to the union
|
||||
void finalize(void) { populateResolver(); } ///< Fold-ins are finished, finalize \b this
|
||||
virtual uint4 getType(void) const { return p_merged; }
|
||||
virtual void assignMap(const vector<Datatype *> &proto,bool isinput,
|
||||
TypeFactory &typefactory,vector<ParameterPieces> &res) const {
|
||||
|
@ -636,6 +704,20 @@ public:
|
|||
int4 numLikelyTrash(void) const { return likelytrash.size(); } ///< Get the number of \e likelytrash locations
|
||||
const VarnodeData &getLikelyTrash(int4 i) const { return likelytrash[i]; } ///< Get the i-th \e likelytrashh location
|
||||
|
||||
/// \brief Characterize whether the given range overlaps parameter storage
|
||||
///
|
||||
/// Does the range naturally fit inside a potential parameter entry from this model or does
|
||||
/// it contain a parameter entry. Return one of three values indicating this characterization:
|
||||
/// - 0 means there is no intersection between the range and any ParamEntry
|
||||
/// - 1 means that at least one ParamEntry contains the range in a properly justified manner
|
||||
/// - 2 means no ParamEntry contains the range, but the range contains at least one ParamEntry
|
||||
/// \param loc is the starting address of the given range
|
||||
/// \param size is the number of bytes in the given range
|
||||
/// \return the characterization code
|
||||
int4 characterizeAsInputParam(const Address &loc,int4 size) const {
|
||||
return input->characterizeAsParam(loc, size);
|
||||
}
|
||||
|
||||
/// \brief Does the given storage location make sense as an input parameter
|
||||
///
|
||||
/// Within \b this model, decide if the storage location can be considered an input parameter.
|
||||
|
@ -716,6 +798,16 @@ public:
|
|||
OpCode assumedOutputExtension(const Address &addr,int4 size,VarnodeData &res) const {
|
||||
return output->assumedExtension(addr,size,res); }
|
||||
|
||||
/// \brief Pass-back the biggest input parameter contained within the given range
|
||||
///
|
||||
/// \param loc is the starting address of the given range
|
||||
/// \param size is the number of bytes in the range
|
||||
/// \param res will hold the parameter storage description being passed back
|
||||
/// \return \b true if there is at least one parameter contained in the range
|
||||
bool getBiggestContainedInputParam(const Address &loc,int4 size,VarnodeData &res) const {
|
||||
return input->getBiggestContainedParam(loc, size, res);
|
||||
}
|
||||
|
||||
AddrSpace *getSpacebase(void) const { return input->getSpacebase(); } ///< Get the stack space associated with \b this model
|
||||
bool isStackGrowsNegative(void) const { return stackgrowsnegative; } ///< Return \b true if the stack \e grows toward smaller addresses
|
||||
bool hasThisPointer(void) const { return hasThis; } ///< Is \b this a model for (non-static) class methods
|
||||
|
@ -1245,6 +1337,7 @@ public:
|
|||
vector<EffectRecord>::const_iterator effectEnd(void) const; ///< Get iterator to end of EffectRecord list
|
||||
int4 numLikelyTrash(void) const; ///< Get the number of \e likely-trash locations
|
||||
const VarnodeData &getLikelyTrash(int4 i) const; ///< Get the i-th \e likely-trash location
|
||||
int4 characterizeAsInputParam(const Address &addr,int4 size) const;
|
||||
bool possibleInputParam(const Address &addr,int4 size) const;
|
||||
bool possibleOutputParam(const Address &addr,int4 size) const;
|
||||
|
||||
|
@ -1292,6 +1385,9 @@ public:
|
|||
OpCode assumedOutputExtension(const Address &addr,int4 size,VarnodeData &res) const {
|
||||
return model->assumedOutputExtension(addr,size,res); }
|
||||
|
||||
/// \brief Pass-back the biggest potential input parameter contained within the given range
|
||||
bool getBiggestContainedInputParam(const Address &loc,int4 size,VarnodeData &res) const;
|
||||
|
||||
bool isCompatible(const FuncProto &op2) const;
|
||||
AddrSpace *getSpacebase(void) const { return model->getSpacebase(); } ///< Get the \e stack address space
|
||||
void printRaw(const string &funcname,ostream &s) const;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue