mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 10:19:23 +02:00
bit based pieces, preserveAddress virtual method
This commit is contained in:
parent
ace956c215
commit
0af94c23c1
2 changed files with 66 additions and 27 deletions
|
@ -29,21 +29,28 @@ void TransformVar::createReplacement(Funcdata *fd)
|
||||||
replacement = vn;
|
replacement = vn;
|
||||||
break;
|
break;
|
||||||
case TransformVar::constant:
|
case TransformVar::constant:
|
||||||
replacement = fd->newConstant(size,val);
|
replacement = fd->newConstant(byteSize,val);
|
||||||
break;
|
break;
|
||||||
case TransformVar::normal_temp:
|
case TransformVar::normal_temp:
|
||||||
if (def == (TransformOp *)0)
|
if (def == (TransformOp *)0)
|
||||||
replacement = fd->newUnique(size);
|
replacement = fd->newUnique(byteSize);
|
||||||
else
|
else
|
||||||
replacement = fd->newUniqueOut(size,def->replacement);
|
replacement = fd->newUniqueOut(byteSize,def->replacement);
|
||||||
break;
|
break;
|
||||||
case TransformVar::piece:
|
case TransformVar::piece:
|
||||||
{
|
{
|
||||||
Address addr = vn->getAddr() + (int4)val;
|
int4 bytePos = (int4)val;
|
||||||
|
if ((bytePos & 7) != 0)
|
||||||
|
throw LowlevelError("Varnode piece is not byte aligned");
|
||||||
|
bytePos >>= 3;
|
||||||
|
if (vn->getSpace()->isBigEndian())
|
||||||
|
bytePos = vn->getSize() - bytePos - byteSize;
|
||||||
|
Address addr = vn->getAddr() + bytePos;
|
||||||
if (def == (TransformOp *)0)
|
if (def == (TransformOp *)0)
|
||||||
replacement = fd->newVarnode(size,addr);
|
replacement = fd->newVarnode(byteSize,addr);
|
||||||
else
|
else
|
||||||
replacement = fd->newVarnodeOut(size, addr, def->replacement);
|
replacement = fd->newVarnodeOut(byteSize, addr, def->replacement);
|
||||||
|
// TODO: fd->preserveProperties(vn,replacement,bytePos);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TransformVar::constant_iop:
|
case TransformVar::constant_iop:
|
||||||
|
@ -97,6 +104,24 @@ bool TransformOp::attemptInsertion(Funcdata *fd)
|
||||||
return true; // Already inserted
|
return true; // Already inserted
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \brief Should the address of the given Varnode be preserved when constructing a piece
|
||||||
|
///
|
||||||
|
/// A new Varnode will be created that represents a logical piece of the given Varnode.
|
||||||
|
/// This routine determines whether the new Varnode should be constructed using
|
||||||
|
/// storage which overlaps the given Varnode. It returns \b true if overlapping storage
|
||||||
|
/// should be used, \b false if the new Varnode should be constructed as a unique temporary.
|
||||||
|
/// \param vn is the given Varnode
|
||||||
|
/// \param bitSize is the logical size of the Varnode piece being constructed
|
||||||
|
/// \param lsbOffset is the least significant bit position of the logical value within the given Varnode
|
||||||
|
/// \return \b true if overlapping storage should be used in construction
|
||||||
|
bool TransformManager::preserveAddress(Varnode *vn,int4 bitSize,int4 lsbOffset) const
|
||||||
|
|
||||||
|
{
|
||||||
|
if ((lsbOffset & 7) != 0) return false; // Logical value not aligned
|
||||||
|
if (vn->getSpace()->getType() == IPTR_INTERNAL) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/// \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)
|
||||||
|
@ -106,7 +131,8 @@ TransformVar *TransformManager::newPreexistingVarnode(Varnode *vn)
|
||||||
TransformVar *res = &newVarnodes.back();
|
TransformVar *res = &newVarnodes.back();
|
||||||
res->vn = vn;
|
res->vn = vn;
|
||||||
res->replacement = (Varnode *)0;
|
res->replacement = (Varnode *)0;
|
||||||
res->size = vn->getSize();
|
res->byteSize = vn->getSize();
|
||||||
|
res->bitSize = res->byteSize * 8;
|
||||||
res->def = (TransformOp *)0;
|
res->def = (TransformOp *)0;
|
||||||
res->type = TransformVar::preexisting;
|
res->type = TransformVar::preexisting;
|
||||||
MapKey key(vn->getCreateIndex(),0);
|
MapKey key(vn->getCreateIndex(),0);
|
||||||
|
@ -122,7 +148,8 @@ TransformVar *TransformManager::newUnique(int4 size)
|
||||||
newVarnodes.push_back(TransformVar());
|
newVarnodes.push_back(TransformVar());
|
||||||
TransformVar *res = &newVarnodes.back();
|
TransformVar *res = &newVarnodes.back();
|
||||||
res->replacement = (Varnode *)0;
|
res->replacement = (Varnode *)0;
|
||||||
res->size = size;
|
res->byteSize = size;
|
||||||
|
res->bitSize = size * 8;
|
||||||
res->def = (TransformOp *)0;
|
res->def = (TransformOp *)0;
|
||||||
res->type = TransformVar::normal_temp;
|
res->type = TransformVar::normal_temp;
|
||||||
return res;
|
return res;
|
||||||
|
@ -137,7 +164,7 @@ TransformVar *TransformManager::newConstant(int4 size,uintb val)
|
||||||
newVarnodes.push_back(TransformVar());
|
newVarnodes.push_back(TransformVar());
|
||||||
TransformVar *res = &newVarnodes.back();
|
TransformVar *res = &newVarnodes.back();
|
||||||
res->replacement = (Varnode *)0;
|
res->replacement = (Varnode *)0;
|
||||||
res->size = size;
|
res->byteSize = size;
|
||||||
res->val = val;
|
res->val = val;
|
||||||
res->def = (TransformOp *)0;
|
res->def = (TransformOp *)0;
|
||||||
res->type = TransformVar::constant;
|
res->type = TransformVar::constant;
|
||||||
|
@ -151,7 +178,8 @@ TransformVar *TransformManager::newIop(Varnode *vn)
|
||||||
TransformVar *res = &newVarnodes.back();
|
TransformVar *res = &newVarnodes.back();
|
||||||
res->vn = (Varnode *)0;
|
res->vn = (Varnode *)0;
|
||||||
res->replacement = (Varnode *)0;
|
res->replacement = (Varnode *)0;
|
||||||
res->size = vn->getSize();
|
res->byteSize = vn->getSize();
|
||||||
|
res->bitSize = res->byteSize * 8;
|
||||||
res->val = vn->getOffset(); // The encoded iop
|
res->val = vn->getOffset(); // The encoded iop
|
||||||
res->def = (TransformOp *)0;
|
res->def = (TransformOp *)0;
|
||||||
res->type = TransformVar::constant_iop;
|
res->type = TransformVar::constant_iop;
|
||||||
|
@ -161,19 +189,24 @@ TransformVar *TransformManager::newIop(Varnode *vn)
|
||||||
/// Given a single logical value within a larger Varnode, create a placeholder for
|
/// Given a single logical value within a larger Varnode, create a placeholder for
|
||||||
/// that logical value.
|
/// that logical value.
|
||||||
/// \param vn is the large Varnode
|
/// \param vn is the large Varnode
|
||||||
/// \param size is the size of the logical value in bytes
|
/// \param bitSize is the size of the logical value in bits
|
||||||
/// \param lsbOffset is the number of least significant bytes of the Varnode dropped from the value
|
/// \param lsbOffset is the number of least significant bits of the Varnode dropped from the value
|
||||||
/// \return the placeholder variable
|
/// \return the placeholder variable
|
||||||
TransformVar *TransformManager::newPiece(Varnode *vn,int4 size,int4 lsbOffset)
|
TransformVar *TransformManager::newPiece(Varnode *vn,int4 bitSize,int4 lsbOffset)
|
||||||
|
|
||||||
{
|
{
|
||||||
newVarnodes.push_back(TransformVar());
|
newVarnodes.push_back(TransformVar());
|
||||||
TransformVar *res = &newVarnodes.back();
|
TransformVar *res = &newVarnodes.back();
|
||||||
res->vn = vn;
|
res->vn = vn;
|
||||||
res->replacement = (Varnode *)0;
|
res->replacement = (Varnode *)0;
|
||||||
res->size = size;
|
res->bitSize = bitSize;
|
||||||
|
res->byteSize = (bitSize + 7) / 8;
|
||||||
res->def = (TransformOp *)0;
|
res->def = (TransformOp *)0;
|
||||||
res->type = TransformVar::piece;
|
if (preserveAddress(vn, bitSize, lsbOffset))
|
||||||
|
res->type = TransformVar::piece;
|
||||||
|
else
|
||||||
|
res->type = TransformVar::normal_temp;
|
||||||
|
res->val = lsbOffset;
|
||||||
MapKey key(vn->getCreateIndex(),lsbOffset);
|
MapKey key(vn->getCreateIndex(),lsbOffset);
|
||||||
pieceMap[key] = res;
|
pieceMap[key] = res;
|
||||||
return res;
|
return res;
|
||||||
|
@ -192,14 +225,17 @@ void TransformManager::newSplit(vector<TransformVar *> &res,Varnode *vn,const La
|
||||||
int4 num = description.getNumLanes();
|
int4 num = description.getNumLanes();
|
||||||
res.resize(num,(TransformVar *)0);
|
res.resize(num,(TransformVar *)0);
|
||||||
for(int4 i=0;i<num;++i) {
|
for(int4 i=0;i<num;++i) {
|
||||||
|
int4 bitpos = description.getPosition(i) * 8;
|
||||||
newVarnodes.push_back(TransformVar());
|
newVarnodes.push_back(TransformVar());
|
||||||
TransformVar *newVar = &newVarnodes.back();
|
TransformVar *newVar = &newVarnodes.back();
|
||||||
newVar->vn = vn;
|
newVar->vn = vn;
|
||||||
newVar->replacement = (Varnode *)0;
|
newVar->replacement = (Varnode *)0;
|
||||||
newVar->size = description.getSize(i);
|
newVar->byteSize = description.getSize(i);
|
||||||
|
newVar->bitSize = newVar->byteSize * 8;
|
||||||
newVar->def = (TransformOp *)0;
|
newVar->def = (TransformOp *)0;
|
||||||
newVar->type = TransformVar::piece;
|
newVar->type = TransformVar::piece;
|
||||||
MapKey key(vn->getCreateIndex(),description.getPosition(i));
|
newVar->val = bitpos;
|
||||||
|
MapKey key(vn->getCreateIndex(),bitpos);
|
||||||
pieceMap[key] = newVar;
|
pieceMap[key] = newVar;
|
||||||
res[i] = newVar;
|
res[i] = newVar;
|
||||||
}
|
}
|
||||||
|
@ -292,10 +328,10 @@ TransformVar *TransformManager::getPreexistingVarnode(Varnode *vn)
|
||||||
/// Given a big Varnode, find the placeholder corresponding to the logical value
|
/// Given a big Varnode, find the placeholder corresponding to the logical value
|
||||||
/// given by a size and significance offset. If it doesn't exist, create it.
|
/// given by a size and significance offset. If it doesn't exist, create it.
|
||||||
/// \param vn is the big Varnode containing the logical value
|
/// \param vn is the big Varnode containing the logical value
|
||||||
/// \param size is the size of the logical value in bytes
|
/// \param bitSize is the size of the logical value in bytes
|
||||||
/// \param lsbOffset is the signficance offset of the logical value within the Varnode
|
/// \param lsbOffset is the signficance offset of the logical value within the Varnode
|
||||||
/// \return the found/created placeholder
|
/// \return the found/created placeholder
|
||||||
TransformVar *TransformManager::getPiece(Varnode *vn,int4 size,int4 lsbOffset)
|
TransformVar *TransformManager::getPiece(Varnode *vn,int4 bitSize,int4 lsbOffset)
|
||||||
|
|
||||||
{
|
{
|
||||||
map<MapKey,TransformVar *>::const_iterator iter;
|
map<MapKey,TransformVar *>::const_iterator iter;
|
||||||
|
@ -304,7 +340,7 @@ TransformVar *TransformManager::getPiece(Varnode *vn,int4 size,int4 lsbOffset)
|
||||||
if (iter != pieceMap.end()) {
|
if (iter != pieceMap.end()) {
|
||||||
return (*iter).second;
|
return (*iter).second;
|
||||||
}
|
}
|
||||||
return newPiece(vn,size,lsbOffset);
|
return newPiece(vn,bitSize,lsbOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Find (or create) placeholder nodes splitting a Varnode into its lanes
|
/// \brief Find (or create) placeholder nodes splitting a Varnode into its lanes
|
||||||
|
|
|
@ -33,12 +33,13 @@ public:
|
||||||
constant_iop = 5, ///< Special iop constant encoding a PcodeOp reference
|
constant_iop = 5, ///< Special iop constant encoding a PcodeOp reference
|
||||||
};
|
};
|
||||||
private:
|
private:
|
||||||
Varnode *vn; ///< Original \b big Varnode of which \b this is a component
|
Varnode *vn; ///< Original \b big Varnode of which \b this is a component
|
||||||
Varnode *replacement; ///< The new explicit lane Varnode
|
Varnode *replacement; ///< The new explicit lane Varnode
|
||||||
int4 size; ///< Size of the lane Varnode in bytes
|
|
||||||
uintb val; ///< Value of constant or position within the original big Varnode
|
|
||||||
TransformOp *def; ///< Defining op for new Varnode
|
|
||||||
uint4 type; ///< Type of new Varnode
|
uint4 type; ///< Type of new Varnode
|
||||||
|
int4 byteSize; ///< Size of the lane Varnode in bytes
|
||||||
|
int4 bitSize; ///< Size of the logical value in bits
|
||||||
|
uintb val; ///< Value of constant or (bit) position within the original big 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
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -110,18 +111,20 @@ class TransformManager {
|
||||||
void placeInputs(void); ///< Set input Varnodes for all new ops
|
void placeInputs(void); ///< Set input Varnodes for all new ops
|
||||||
public:
|
public:
|
||||||
TransformManager(Funcdata *f) { fd = f; } ///< Constructor
|
TransformManager(Funcdata *f) { fd = f; } ///< Constructor
|
||||||
|
virtual ~TransformManager(void) {}
|
||||||
|
virtual bool preserveAddress(Varnode *vn,int4 bitSize,int4 lsbOffset) const;
|
||||||
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,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 size,int4 lsbOffset); ///< Make placeholder for piece of a Varnode
|
TransformVar *newPiece(Varnode *vn,int4 bitSize,int4 lsbOffset); ///< Make placeholder for piece of a Varnode
|
||||||
void newSplit(vector<TransformVar *> &res,Varnode *vn,const LaneDescription &description);
|
void newSplit(vector<TransformVar *> &res,Varnode *vn,const LaneDescription &description);
|
||||||
TransformOp *newOpReplace(int4 numParams,OpCode opc,PcodeOp *replace);
|
TransformOp *newOpReplace(int4 numParams,OpCode opc,PcodeOp *replace);
|
||||||
TransformOp *newOp(int4 numParams,OpCode opc,TransformOp *follow);
|
TransformOp *newOp(int4 numParams,OpCode opc,TransformOp *follow);
|
||||||
TransformOp *newPreexistingOp(int4 numParams,OpCode opc,PcodeOp *originalOp);
|
TransformOp *newPreexistingOp(int4 numParams,OpCode opc,PcodeOp *originalOp);
|
||||||
|
|
||||||
TransformVar *getPreexistingVarnode(Varnode *vn); ///< Get (or create) placeholder for preexisting Varnode
|
TransformVar *getPreexistingVarnode(Varnode *vn); ///< Get (or create) placeholder for preexisting Varnode
|
||||||
TransformVar *getPiece(Varnode *vn,int4 size,int4 lsbOffset); ///< Get (or create) placeholder piece
|
TransformVar *getPiece(Varnode *vn,int4 bitSize,int4 lsbOffset); ///< Get (or create) placeholder piece
|
||||||
void getSplit(vector<TransformVar *> &res,Varnode *vn,const LaneDescription &description);
|
void getSplit(vector<TransformVar *> &res,Varnode *vn,const LaneDescription &description);
|
||||||
void opSetInput(TransformOp *rop,TransformVar *rvn,int4 slot); ///< Mark given variable as input to given op
|
void opSetInput(TransformOp *rop,TransformVar *rvn,int4 slot); ///< Mark given variable as input to given op
|
||||||
void opSetOutput(TransformOp *rop,TransformVar *rvn); ///< Mark given variable as output of given op
|
void opSetOutput(TransformOp *rop,TransformVar *rvn); ///< Mark given variable as output of given op
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue