mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 02:39:44 +02:00
Changes in preparation for refactoring SplitFlow
This commit is contained in:
parent
16864aa187
commit
51f3411499
2 changed files with 81 additions and 18 deletions
|
@ -16,6 +16,39 @@
|
||||||
#include "transform.hh"
|
#include "transform.hh"
|
||||||
#include "funcdata.hh"
|
#include "funcdata.hh"
|
||||||
|
|
||||||
|
/// Create lanes that are all the same size
|
||||||
|
/// \param origSize is the size of the whole in bytes
|
||||||
|
/// \param sz is the size of a lane in bytes
|
||||||
|
LaneDescription::LaneDescription(int4 origSize,int4 sz)
|
||||||
|
|
||||||
|
{
|
||||||
|
wholeSize = origSize;
|
||||||
|
int4 numLanes = origSize / sz;
|
||||||
|
laneSize.resize(numLanes);
|
||||||
|
lanePosition.resize(numLanes);
|
||||||
|
int4 pos = 0;
|
||||||
|
for(int4 i=0;i<numLanes;++i) {
|
||||||
|
laneSize[i] = sz;
|
||||||
|
lanePosition[i] = pos;
|
||||||
|
pos += sz;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \param origSize is the size of the whole in bytes
|
||||||
|
/// \param lo is the size of the least significant lane in bytes
|
||||||
|
/// \param hi is the size of the most significant lane in bytes
|
||||||
|
LaneDescription::LaneDescription(int4 origSize,int4 lo,int4 hi)
|
||||||
|
|
||||||
|
{
|
||||||
|
wholeSize = origSize;
|
||||||
|
laneSize.resize(2);
|
||||||
|
lanePosition.resize(2);
|
||||||
|
laneSize[0] = lo;
|
||||||
|
laneSize[1] = hi;
|
||||||
|
lanePosition[0] = 0;
|
||||||
|
lanePosition[1] = lo;
|
||||||
|
}
|
||||||
|
|
||||||
/// Create the Varnode object (constant, unique, vector piece) described by the
|
/// Create the Varnode object (constant, unique, vector piece) described by the
|
||||||
/// given placeholder. If the Varnode is an output, assume the op already exists
|
/// given placeholder. If the Varnode is an output, assume the op already exists
|
||||||
/// and create the Varnode as an output. Set the \b replacement field with the
|
/// and create the Varnode as an output. Set the \b replacement field with the
|
||||||
|
@ -134,6 +167,18 @@ bool TransformManager::preserveAddress(Varnode *vn,int4 bitSize,int4 lsbOffset)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TransformManager::clearVarnodeMarks(void)
|
||||||
|
|
||||||
|
{
|
||||||
|
map<int4,TransformVar *>::const_iterator iter;
|
||||||
|
for(iter=pieceMap.begin();iter!=pieceMap.end();++iter) {
|
||||||
|
Varnode *vn = (*iter).second->vn;
|
||||||
|
if (vn == (Varnode *)0)
|
||||||
|
continue;
|
||||||
|
vn->clearMark();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// \param vn is the preexisting Varnode to create a placeholder for
|
/// \param vn is the preexisting Varnode to create a placeholder for
|
||||||
/// \return the new placeholder node
|
/// \return the new placeholder node
|
||||||
TransformVar *TransformManager::newPreexistingVarnode(Varnode *vn)
|
TransformVar *TransformManager::newPreexistingVarnode(Varnode *vn)
|
||||||
|
@ -158,6 +203,7 @@ TransformVar *TransformManager::newUnique(int4 size)
|
||||||
{
|
{
|
||||||
newVarnodes.push_back(TransformVar());
|
newVarnodes.push_back(TransformVar());
|
||||||
TransformVar *res = &newVarnodes.back();
|
TransformVar *res = &newVarnodes.back();
|
||||||
|
res->vn = (Varnode *)0;
|
||||||
res->replacement = (Varnode *)0;
|
res->replacement = (Varnode *)0;
|
||||||
res->byteSize = size;
|
res->byteSize = size;
|
||||||
res->bitSize = size * 8;
|
res->bitSize = size * 8;
|
||||||
|
@ -167,17 +213,22 @@ TransformVar *TransformManager::newUnique(int4 size)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a new constant in the transform view. A piece of an existing constant
|
||||||
|
/// can be created by giving the existing value and the least significant offset.
|
||||||
/// \param size is the size in bytes of the new constant
|
/// \param size is the size in bytes of the new constant
|
||||||
/// \param val is the value of the new constant
|
/// \param lsbOffset is the number of bits to strip off of the existing value
|
||||||
|
/// \param val is the value of the constant
|
||||||
/// \return the new placeholder node
|
/// \return the new placeholder node
|
||||||
TransformVar *TransformManager::newConstant(int4 size,uintb val)
|
TransformVar *TransformManager::newConstant(int4 size,int4 lsbOffset,uintb val)
|
||||||
|
|
||||||
{
|
{
|
||||||
newVarnodes.push_back(TransformVar());
|
newVarnodes.push_back(TransformVar());
|
||||||
TransformVar *res = &newVarnodes.back();
|
TransformVar *res = &newVarnodes.back();
|
||||||
|
res->vn = (Varnode *)0;
|
||||||
res->replacement = (Varnode *)0;
|
res->replacement = (Varnode *)0;
|
||||||
res->byteSize = size;
|
res->byteSize = size;
|
||||||
res->val = val;
|
res->bitSize = size * 8;
|
||||||
|
res->val = (val >> lsbOffset) & calc_mask(size);
|
||||||
res->def = (TransformOp *)0;
|
res->def = (TransformOp *)0;
|
||||||
res->type = TransformVar::constant;
|
res->type = TransformVar::constant;
|
||||||
res->flags = 0;
|
res->flags = 0;
|
||||||
|
@ -246,9 +297,15 @@ TransformVar *TransformManager::newSplit(Varnode *vn,const LaneDescription &desc
|
||||||
newVar->byteSize = description.getSize(i);
|
newVar->byteSize = description.getSize(i);
|
||||||
newVar->bitSize = newVar->byteSize * 8;
|
newVar->bitSize = newVar->byteSize * 8;
|
||||||
newVar->def = (TransformOp *)0;
|
newVar->def = (TransformOp *)0;
|
||||||
newVar->type = TransformVar::piece;
|
|
||||||
newVar->flags = 0;
|
newVar->flags = 0;
|
||||||
newVar->val = bitpos;
|
if (vn->isConstant()) {
|
||||||
|
newVar->type = TransformVar::constant;
|
||||||
|
newVar->val = (vn->getOffset() >> bitpos) & calc_mask(newVar->byteSize);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
newVar->type = TransformVar::piece;
|
||||||
|
newVar->val = bitpos;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
res[num-1].flags = TransformVar::split_terminator;
|
res[num-1].flags = TransformVar::split_terminator;
|
||||||
return res;
|
return res;
|
||||||
|
@ -375,12 +432,6 @@ TransformVar *TransformManager::getSplit(Varnode *vn,const LaneDescription &desc
|
||||||
return newSplit(vn,description);
|
return newSplit(vn,description);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TransformManager::opSetInput(TransformOp *rop,TransformVar *rvn,int4 slot)
|
|
||||||
|
|
||||||
{
|
|
||||||
rop->input[slot] = rvn;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \brief Handle some special PcodeOp marking
|
/// \brief Handle some special PcodeOp marking
|
||||||
/// If a PcodeOp is an INDIRECT creation, we need to do special marking of the op and Varnodes
|
/// If a PcodeOp is an INDIRECT creation, we need to do special marking of the op and Varnodes
|
||||||
/// \param rop is the placeholder op with the special requirement
|
/// \param rop is the placeholder op with the special requirement
|
||||||
|
|
|
@ -23,6 +23,7 @@ class TransformOp;
|
||||||
/// \brief Placeholder node for Varnode that will exist after a transform is applied to a function
|
/// \brief Placeholder node for Varnode that will exist after a transform is applied to a function
|
||||||
class TransformVar {
|
class TransformVar {
|
||||||
friend class TransformManager;
|
friend class TransformManager;
|
||||||
|
friend class TransformOp;
|
||||||
public:
|
public:
|
||||||
/// \brief Types of replacement Varnodes
|
/// \brief Types of replacement Varnodes
|
||||||
enum {
|
enum {
|
||||||
|
@ -48,11 +49,15 @@ private:
|
||||||
uintb val; ///< Value of constant or (bit) position within the original big Varnode
|
uintb val; ///< Value of constant or (bit) position within the original big Varnode
|
||||||
TransformOp *def; ///< Defining op for new Varnode
|
TransformOp *def; ///< Defining op for new Varnode
|
||||||
void createReplacement(Funcdata *fd); ///< Create the new/modified variable this placeholder represents
|
void createReplacement(Funcdata *fd); ///< Create the new/modified variable this placeholder represents
|
||||||
|
public:
|
||||||
|
Varnode *getOriginal(void) const { return vn; }
|
||||||
|
TransformOp *getDef(void) const { return def; }
|
||||||
};
|
};
|
||||||
|
|
||||||
/// \brief Placeholder node for PcodeOp that will exist after a transform is applied to a function
|
/// \brief Placeholder node for PcodeOp that will exist after a transform is applied to a function
|
||||||
class TransformOp {
|
class TransformOp {
|
||||||
friend class TransformManager;
|
friend class TransformManager;
|
||||||
|
friend class TransformVar;
|
||||||
public:
|
public:
|
||||||
/// Special annotations on new pcode ops
|
/// Special annotations on new pcode ops
|
||||||
enum {
|
enum {
|
||||||
|
@ -71,6 +76,9 @@ private:
|
||||||
TransformOp *follow; ///< The following op after \b this (if not null)
|
TransformOp *follow; ///< The following op after \b this (if not null)
|
||||||
void createReplacement(Funcdata *fd); ///< Create the new/modified op this placeholder represents
|
void createReplacement(Funcdata *fd); ///< Create the new/modified op this placeholder represents
|
||||||
bool attemptInsertion(Funcdata *fd); ///< Try to put the new PcodeOp into its basic block
|
bool attemptInsertion(Funcdata *fd); ///< Try to put the new PcodeOp into its basic block
|
||||||
|
public:
|
||||||
|
TransformVar *getOut(void) const { return output; }
|
||||||
|
TransformVar *getIn(int4 i) const { return input[i]; }
|
||||||
};
|
};
|
||||||
|
|
||||||
/// \brief Description of logical lanes within a \b big Varnode
|
/// \brief Description of logical lanes within a \b big Varnode
|
||||||
|
@ -79,13 +87,16 @@ private:
|
||||||
/// Varnode are disjoint. In general, we expect a Varnode to be tiled with
|
/// Varnode are disjoint. In general, we expect a Varnode to be tiled with
|
||||||
/// lanes all of the same size, but the API allows for possibly non-uniform lanes.
|
/// lanes all of the same size, but the API allows for possibly non-uniform lanes.
|
||||||
class LaneDescription {
|
class LaneDescription {
|
||||||
int4 size; ///< Size of (all) lanes
|
int4 wholeSize; ///< Size of the region being split in bytes
|
||||||
int4 numLanes; ///< Number of distinct lanes
|
vector<int4> laneSize; ///< Size of lanes in bytes
|
||||||
|
vector<int4> lanePosition; ///< Significance positions of lanes in bytes
|
||||||
public:
|
public:
|
||||||
LaneDescription(int4 origSize,int4 sz) { size = sz; numLanes = origSize / sz; } ///< Constructor
|
LaneDescription(int4 origSize,int4 sz); ///< Construct uniform lanes
|
||||||
int4 getNumLanes(void) const { return numLanes; } ///< Get the total number of lanes
|
LaneDescription(int4 origSize,int4 lo,int4 hi); ///< Construct two lanes of arbitrary size
|
||||||
int4 getSize(int4 i) const { return size; } ///< Get the size of the i-th lane
|
int4 getNumLanes(void) const { return laneSize.size(); } ///< Get the total number of lanes
|
||||||
int4 getPosition(int4 i) const { return size * i; } ///< Get the significance offset of the i-th lane
|
int4 getWholeSize(void) const { return wholeSize; } ///< Get the size of the region being split
|
||||||
|
int4 getSize(int4 i) const { return laneSize[i]; } ///< Get the size of the i-th lane
|
||||||
|
int4 getPosition(int4 i) const { return lanePosition[i]; } ///< Get the significance offset of the i-th lane
|
||||||
};
|
};
|
||||||
|
|
||||||
/// \brief Class for splitting larger registers holding smaller logical lanes
|
/// \brief Class for splitting larger registers holding smaller logical lanes
|
||||||
|
@ -110,9 +121,10 @@ public:
|
||||||
TransformManager(Funcdata *f) { fd = f; } ///< Constructor
|
TransformManager(Funcdata *f) { fd = f; } ///< Constructor
|
||||||
virtual ~TransformManager(void); ///< Destructor
|
virtual ~TransformManager(void); ///< Destructor
|
||||||
virtual bool preserveAddress(Varnode *vn,int4 bitSize,int4 lsbOffset) const;
|
virtual bool preserveAddress(Varnode *vn,int4 bitSize,int4 lsbOffset) const;
|
||||||
|
void clearVarnodeMarks(void); ///< Clear mark for all Varnodes in the map
|
||||||
TransformVar *newPreexistingVarnode(Varnode *vn); ///< Make placeholder for preexisting Varnode
|
TransformVar *newPreexistingVarnode(Varnode *vn); ///< Make placeholder for preexisting Varnode
|
||||||
TransformVar *newUnique(int4 size); ///< Make placeholder for new unique space Varnode
|
TransformVar *newUnique(int4 size); ///< Make placeholder for new unique space Varnode
|
||||||
TransformVar *newConstant(int4 size,uintb val); ///< Make placeholder for constant Varnode
|
TransformVar *newConstant(int4 size,int4 lsbOffset,uintb val); ///< Make placeholder for constant Varnode
|
||||||
TransformVar *newIop(Varnode *vn); ///< Make placeholder for special iop constant
|
TransformVar *newIop(Varnode *vn); ///< Make placeholder for special iop constant
|
||||||
TransformVar *newPiece(Varnode *vn,int4 bitSize,int4 lsbOffset); ///< Make placeholder for piece of a Varnode
|
TransformVar *newPiece(Varnode *vn,int4 bitSize,int4 lsbOffset); ///< Make placeholder for piece of a Varnode
|
||||||
TransformVar *newSplit(Varnode *vn,const LaneDescription &description);
|
TransformVar *newSplit(Varnode *vn,const LaneDescription &description);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue