mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 02:09:44 +02:00
GP-2037 RuleDoubleStore
This commit is contained in:
parent
cb4b309942
commit
4448f11cb4
15 changed files with 761 additions and 231 deletions
|
@ -90,9 +90,6 @@ public:
|
|||
|
||||
/// Restore an address and size from parsed XML
|
||||
static Address restoreXml(const Element *el,const AddrSpaceManager *manage,int4 &size);
|
||||
|
||||
/// Recover an encoded address space from an address
|
||||
static AddrSpace *getSpaceFromConst(const Address &addr);
|
||||
};
|
||||
|
||||
/// \brief A class for uniquely labelling and comparing PcodeOps
|
||||
|
@ -442,17 +439,6 @@ inline void Address::saveXml(ostream &s,int4 size) const {
|
|||
s << "/>";
|
||||
}
|
||||
|
||||
/// In \b LOAD and \b STORE instructions, the particular address
|
||||
/// space being read/written is encoded as a constant input parameter
|
||||
/// to the instruction. Internally, this constant is the actual
|
||||
/// pointer to the AddrSpace. This function allows the encoded pointer
|
||||
/// to be recovered from the address it is encoded in.
|
||||
/// \param addr is the Address encoding the pointer
|
||||
/// \return the AddrSpace pointer
|
||||
inline AddrSpace *Address::getSpaceFromConst(const Address &addr) {
|
||||
return (AddrSpace *)(uintp)addr.offset;
|
||||
}
|
||||
|
||||
/// \param addr is the Address to test for containment
|
||||
/// \return \b true if addr is in \b this Range
|
||||
inline bool Range::contains(const Address &addr) const {
|
||||
|
|
|
@ -963,10 +963,10 @@ AddrSpace *ActionConstantPtr::searchForSpaceAttribute(Varnode *vn,PcodeOp *op)
|
|||
op = vn->loneDescend();
|
||||
break;
|
||||
case CPUI_LOAD:
|
||||
return Address::getSpaceFromConst(op->getIn(0)->getAddr());
|
||||
return op->getIn(0)->getSpaceFromConst();
|
||||
case CPUI_STORE:
|
||||
if (op->getIn(1) == vn)
|
||||
return Address::getSpaceFromConst(op->getIn(0)->getAddr());
|
||||
return op->getIn(0)->getSpaceFromConst();
|
||||
return (AddrSpace *)0;
|
||||
default:
|
||||
return (AddrSpace *)0;
|
||||
|
@ -977,9 +977,9 @@ AddrSpace *ActionConstantPtr::searchForSpaceAttribute(Varnode *vn,PcodeOp *op)
|
|||
op = *iter;
|
||||
OpCode opc = op->code();
|
||||
if (opc == CPUI_LOAD)
|
||||
return Address::getSpaceFromConst(op->getIn(0)->getAddr());
|
||||
return op->getIn(0)->getSpaceFromConst();
|
||||
else if (opc == CPUI_STORE && op->getIn(1) == vn)
|
||||
return Address::getSpaceFromConst(op->getIn(0)->getAddr());
|
||||
return op->getIn(0)->getSpaceFromConst();
|
||||
}
|
||||
return (AddrSpace *)0;
|
||||
}
|
||||
|
@ -2203,7 +2203,7 @@ void ActionSetCasts::checkPointerIssues(PcodeOp *op,Varnode *vn,Funcdata &data)
|
|||
if (ptrtype->getMetatype()==TYPE_PTR) {
|
||||
AddrSpace *spc = ((TypePointer *)ptrtype)->getSpace();
|
||||
if (spc != (AddrSpace *)0) {
|
||||
AddrSpace *opSpc = Address::getSpaceFromConst(op->getIn(0)->getAddr());
|
||||
AddrSpace *opSpc = op->getIn(0)->getSpaceFromConst();
|
||||
if (opSpc != spc && spc->getContain() != opSpc) {
|
||||
string name = op->getOpcode()->getName();
|
||||
name[0] = toupper( name[0] );
|
||||
|
@ -5080,6 +5080,7 @@ void ActionDatabase::universalAction(Architecture *conf)
|
|||
actprop->addRule( new RulePiecePathology("protorecovery") );
|
||||
|
||||
actprop->addRule( new RuleDoubleLoad("doubleload") );
|
||||
actprop->addRule( new RuleDoubleStore("doubleprecis") );
|
||||
actprop->addRule( new RuleDoubleIn("doubleprecis") );
|
||||
for(iter=conf->extra_pool_rules.begin();iter!=conf->extra_pool_rules.end();++iter)
|
||||
actprop->addRule( *iter ); // Add CPU specific rules
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -19,49 +19,57 @@
|
|||
#include "ruleaction.hh"
|
||||
#include "funcdata.hh"
|
||||
|
||||
/// \brief A logical value whose storage is split between two Varnodes
|
||||
///
|
||||
/// This is usually a pair of Varnodes \b lo and \b hi holding the least and
|
||||
/// most significant part of the logical value respectively. Its possible for
|
||||
/// the logical value to be a constant, in which case \b lo and \b hi are set to
|
||||
/// null and \b val holds the actual constant.
|
||||
/// Its also possible for \b hi to be null by itself, indicating that most signficant
|
||||
/// part of the variable is zero, and the logical variable is the zero extension of \b lo.
|
||||
class SplitVarnode {
|
||||
Varnode *lo; // Least significant piece of the double precision object
|
||||
Varnode *hi; // Most significant piece of the double precision object
|
||||
Varnode *whole; // A representative of the whole object
|
||||
PcodeOp *defpoint; // Operation at which both -lo- and -hi- are defined
|
||||
BlockBasic *defblock; // Block in which bot -lo- and -hi- are defined
|
||||
uintb val; // Value of a double precision constant
|
||||
int4 wholesize; // Size in bytes of the (virtual) whole
|
||||
bool findWholeSplitToPieces(void);
|
||||
bool findDefinitionPoint(void);
|
||||
bool findWholeBuiltFromPieces(void);
|
||||
Varnode *lo; ///< Least significant piece of the double precision object
|
||||
Varnode *hi; ///< Most significant piece of the double precision object
|
||||
Varnode *whole; ///< A representative of the whole object
|
||||
PcodeOp *defpoint; ///< Operation at which both \b lo and \b hi are defined
|
||||
BlockBasic *defblock; ///< Block in which both \b lo and \b hi are defined
|
||||
uintb val; ///< Value of a double precision constant
|
||||
int4 wholesize; ///< Size in bytes of the (virtual) whole
|
||||
bool findWholeSplitToPieces(void); ///< Find whole out of which \b hi and \b lo are split
|
||||
bool findDefinitionPoint(void); ///< Find the earliest PcodeOp where both \b lo and \b hi are defined
|
||||
bool findWholeBuiltFromPieces(void); ///< Find whole Varnode formed as a CPUI_PIECE of \b hi and \b lo
|
||||
public:
|
||||
SplitVarnode(void) {} // For use with inHandHi
|
||||
SplitVarnode(int4 sz,uintb v); // Initialize a double precision constant
|
||||
SplitVarnode(Varnode *l,Varnode *h) { initPartial(l,h); }
|
||||
void initAll(Varnode *w,Varnode *l,Varnode *h);
|
||||
void initPartial(int4 sz,uintb v);
|
||||
void initPartial(Varnode *l,Varnode *h);
|
||||
bool inHandHi(Varnode *h);
|
||||
bool inHandLo(Varnode *l);
|
||||
bool inHandLoNoHi(Varnode *l);
|
||||
bool inHandHiOut(Varnode *h);
|
||||
bool inHandLoOut(Varnode *h);
|
||||
bool isConstant(void) const { return (lo == (Varnode *)0); }
|
||||
bool hasBothPieces(void) const { return ((hi!=(Varnode *)0)&&(lo!=(Varnode *)0)); }
|
||||
int4 getSize(void) const { return wholesize; }
|
||||
Varnode *getLo(void) const { return lo; }
|
||||
Varnode *getHi(void) const { return hi; }
|
||||
Varnode *getWhole(void) const { return whole; }
|
||||
PcodeOp *getDefPoint(void) const { return defpoint; }
|
||||
BlockBasic *getDefBlock(void) const { return defblock; }
|
||||
uintb getValue(void) const { return val; }
|
||||
bool isWholeFeasible(PcodeOp *existop);
|
||||
bool isWholePhiFeasible(FlowBlock *bl);
|
||||
void findCreateWhole(Funcdata &data);
|
||||
void findCreateOutputWhole(Funcdata &data);
|
||||
void createJoinedWhole(Funcdata &data);
|
||||
void buildLoFromWhole(Funcdata &data);
|
||||
void buildHiFromWhole(Funcdata &data);
|
||||
PcodeOp *findEarliestSplitPoint(void);
|
||||
PcodeOp *findOutExist(void);
|
||||
SplitVarnode(void) {} ///< Construct an uninitialized SplitVarnode
|
||||
SplitVarnode(int4 sz,uintb v); ///< Construct a double precision constant
|
||||
SplitVarnode(Varnode *l,Varnode *h) { initPartial(l->getSize()+h->getSize(),l,h); } ///< Construct from \b lo and \b hi piece
|
||||
void initAll(Varnode *w,Varnode *l,Varnode *h); ///< Construct given Varnode pieces and a known \b whole Varnode
|
||||
void initPartial(int4 sz,uintb v); ///< (Re)initialize \b this SplitVarnode as a constant
|
||||
void initPartial(int4 sz,Varnode *l,Varnode *h); ///< (Re)initialize \b this SplitVarnode given Varnode pieces
|
||||
bool inHandHi(Varnode *h); ///< Try to initialize given just the most significant piece split from whole
|
||||
bool inHandLo(Varnode *l); ///< Try to initialize given just the least significant piece split from whole
|
||||
bool inHandLoNoHi(Varnode *l); ///< Try to initialize given just the least significant piece (other piece may be zero)
|
||||
bool inHandHiOut(Varnode *h); ///< Try to initialize given just the most significant piece concatenated into whole
|
||||
bool inHandLoOut(Varnode *l); ///< Try to initialize given just the least significant piece concatenated into whole
|
||||
bool isConstant(void) const { return (lo == (Varnode *)0); } ///< Return \b true if \b this is a constant
|
||||
bool hasBothPieces(void) const { return ((hi!=(Varnode *)0)&&(lo!=(Varnode *)0)); } ///< Return \b true if both pieces are initialized
|
||||
int4 getSize(void) const { return wholesize; } ///< Get the size of \b this SplitVarnode as a whole in bytes
|
||||
Varnode *getLo(void) const { return lo; } ///< Get the least significant Varnode piece
|
||||
Varnode *getHi(void) const { return hi; } ///< Get the most significant Varnode piece
|
||||
Varnode *getWhole(void) const { return whole; } ///< Get the Varnode representing \b this as a whole
|
||||
PcodeOp *getDefPoint(void) const { return defpoint; } ///< Get the(final) defining PcodeOp of \b this
|
||||
BlockBasic *getDefBlock(void) const { return defblock; } ///< Get the defining basic block of \b this
|
||||
uintb getValue(void) const { return val; } ///< Get the value of \b this, assuming it is a constant
|
||||
bool isWholeFeasible(PcodeOp *existop); ///< Does a whole Varnode already exist or can it be created before the given PcodeOp
|
||||
bool isWholePhiFeasible(FlowBlock *bl); ///< Does a whole Varnode already exist or can it be created before the given basic block
|
||||
void findCreateWhole(Funcdata &data); ///< Create a \b whole Varnode for \b this, if it doesn't already exist
|
||||
void findCreateOutputWhole(Funcdata &data); ///< Create a \b whole Varnode that will be a PcodeOp output
|
||||
void createJoinedWhole(Funcdata &data); ///< Create a \b whole Varnode from pieces, respecting piece storage
|
||||
void buildLoFromWhole(Funcdata &data); ///< Rebuild the least significant piece as a CPUI_SUBPIECE of the \b whole
|
||||
void buildHiFromWhole(Funcdata &data); ///< Rebuild the most significant piece as a CPUI_SUBPIECE of the \b whole
|
||||
PcodeOp *findEarliestSplitPoint(void); ///< Find the earliest definition point of the \b lo and \b hi pieces
|
||||
PcodeOp *findOutExist(void); ///< Find the point at which the output \b whole must exist
|
||||
static bool adjacentOffsets(Varnode *vn1,Varnode *vn2,uintb size1);
|
||||
static bool testContiguousLoad(PcodeOp *most,PcodeOp *least,bool allowfree,PcodeOp *&first,PcodeOp *&second,AddrSpace *&spc,int4 &sizeres);
|
||||
static bool testContiguousPointers(PcodeOp *most,PcodeOp *least,PcodeOp *&first,PcodeOp *&second,AddrSpace *&spc);
|
||||
static bool isAddrTiedContiguous(Varnode *lo,Varnode *hi,Address &res);
|
||||
static void wholeList(Varnode *w,vector<SplitVarnode> &splitvec);
|
||||
static void findCopies(const SplitVarnode &in,vector<SplitVarnode> &splitvec);
|
||||
|
@ -288,9 +296,16 @@ public:
|
|||
bool applyRule(SplitVarnode &i,PcodeOp *ind,bool workishi,Funcdata &data);
|
||||
};
|
||||
|
||||
/// \brief Simply a double precision operation, starting from a marked double precision input.
|
||||
///
|
||||
/// This rule starts by trying to find a pair of Varnodes that are SUBPIECE from a whole,
|
||||
/// are marked as double precision, and that are then used in some double precision operation.
|
||||
/// The various operation \e forms are overlayed on the data-flow until a matching one is found. The
|
||||
/// pieces of the double precision operation are then transformed into a single logical operation on the whole.
|
||||
class RuleDoubleIn : public Rule {
|
||||
int4 attemptMarking(Funcdata &data,Varnode *vn,PcodeOp *subpieceOp);
|
||||
public:
|
||||
RuleDoubleIn(const string &g) : Rule(g, 0, "doublein") {}
|
||||
RuleDoubleIn(const string &g) : Rule(g, 0, "doublein") {} ///< Constructor
|
||||
virtual Rule *clone(const ActionGroupList &grouplist) const {
|
||||
if (!grouplist.contains(getGroup())) return (Rule *)0;
|
||||
return new RuleDoubleIn(getGroup());
|
||||
|
@ -309,7 +324,19 @@ public:
|
|||
}
|
||||
virtual void getOpList(vector<uint4> &oplist) const;
|
||||
virtual int4 applyOp(PcodeOp *op,Funcdata &data);
|
||||
static PcodeOp *noWriteConflict(PcodeOp *op1,PcodeOp *op2,AddrSpace *spc);
|
||||
static PcodeOp *noWriteConflict(PcodeOp *op1,PcodeOp *op2,AddrSpace *spc,vector<PcodeOp *> *indirects);
|
||||
};
|
||||
|
||||
class RuleDoubleStore : public Rule {
|
||||
public:
|
||||
RuleDoubleStore(const string &g) : Rule( g, 0, "doublestore") {}
|
||||
virtual Rule *clone(const ActionGroupList &grouplist) const {
|
||||
if (!grouplist.contains(getGroup())) return (Rule *)0;
|
||||
return new RuleDoubleStore(getGroup());
|
||||
}
|
||||
virtual void getOpList(vector<uint4> &oplist) const;
|
||||
virtual int4 applyOp(PcodeOp *op,Funcdata &data);
|
||||
static bool testIndirectUse(PcodeOp *op1,PcodeOp *op2,const vector<PcodeOp *> &indirects);
|
||||
static void reassignIndirects(Funcdata &data,PcodeOp *newStore,const vector<PcodeOp *> &indirects);
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -236,7 +236,7 @@ void EmulateMemory::executeLoad(void)
|
|||
|
||||
{
|
||||
uintb off = memstate->getValue(currentOp->getInput(1));
|
||||
AddrSpace *spc = Address::getSpaceFromConst(currentOp->getInput(0)->getAddr());
|
||||
AddrSpace *spc = currentOp->getInput(0)->getSpaceFromConst();
|
||||
|
||||
off = AddrSpace::addressToByte(off,spc->getWordSize());
|
||||
uintb res = memstate->getValue(spc,off,currentOp->getOutput()->size);
|
||||
|
@ -248,7 +248,7 @@ void EmulateMemory::executeStore(void)
|
|||
{
|
||||
uintb val = memstate->getValue(currentOp->getInput(2)); // Value being stored
|
||||
uintb off = memstate->getValue(currentOp->getInput(1)); // Offset to store at
|
||||
AddrSpace *spc = Address::getSpaceFromConst(currentOp->getInput(0)->getAddr()); // Space to store in
|
||||
AddrSpace *spc = currentOp->getInput(0)->getSpaceFromConst(); // Space to store in
|
||||
|
||||
off = AddrSpace::addressToByte(off,spc->getWordSize());
|
||||
memstate->setValue(spc,off,currentOp->getInput(2)->size,val);
|
||||
|
|
|
@ -66,7 +66,7 @@ void EmulatePcodeOp::executeLoad(void)
|
|||
{
|
||||
// op will be null, use current_op
|
||||
uintb off = getVarnodeValue(currentOp->getIn(1));
|
||||
AddrSpace *spc = Address::getSpaceFromConst(currentOp->getIn(0)->getAddr());
|
||||
AddrSpace *spc = currentOp->getIn(0)->getSpaceFromConst();
|
||||
off = AddrSpace::addressToByte(off,spc->getWordSize());
|
||||
int4 sz = currentOp->getOut()->getSize();
|
||||
uintb res = getLoadImageValue(spc,off,sz);
|
||||
|
@ -79,7 +79,7 @@ void EmulatePcodeOp::executeStore(void)
|
|||
// There is currently nowhere to store anything since the memstate is null
|
||||
// uintb val = getVarnodeValue(current_op->getIn(2)); // Value being stored
|
||||
// uintb off = getVarnodeValue(current_op->getIn(1));
|
||||
// AddrSpace *spc = Address::getSpaceFromConst(current_op->getIn(0)->getAddr());
|
||||
// AddrSpace *spc = current_op->getIn(0)->getSpaceFromConst();
|
||||
}
|
||||
|
||||
bool EmulatePcodeOp::executeCbranch(void)
|
||||
|
@ -120,7 +120,7 @@ void EmulatePcodeOp::executeIndirect(void)
|
|||
void EmulatePcodeOp::executeSegmentOp(void)
|
||||
|
||||
{
|
||||
SegmentOp *segdef = glb->userops.getSegmentOp(Address::getSpaceFromConst(currentOp->getIn(0)->getAddr())->getIndex());
|
||||
SegmentOp *segdef = glb->userops.getSegmentOp(currentOp->getIn(0)->getSpaceFromConst()->getIndex());
|
||||
if (segdef == (SegmentOp *)0)
|
||||
throw LowlevelError("Segment operand missing definition");
|
||||
|
||||
|
@ -186,7 +186,7 @@ void EmulateSnippet::executeLoad(void)
|
|||
{
|
||||
// op will be null, use current_op
|
||||
uintb off = getVarnodeValue(currentOp->getInput(1));
|
||||
AddrSpace *spc = Address::getSpaceFromConst(currentOp->getInput(0)->getAddr());
|
||||
AddrSpace *spc = currentOp->getInput(0)->getSpaceFromConst();
|
||||
off = AddrSpace::addressToByte(off,spc->getWordSize());
|
||||
int4 sz = currentOp->getOutput()->size;
|
||||
uintb res = getLoadImageValue(spc,off,sz);
|
||||
|
|
|
@ -1345,7 +1345,7 @@ void Heritage::guardStores(const Address &addr,int4 size,vector<Varnode *> &writ
|
|||
for(iter=fd->beginOp(CPUI_STORE);iter!=iterend;++iter) {
|
||||
op = *iter;
|
||||
if (op->isDead()) continue;
|
||||
AddrSpace *storeSpace = Address::getSpaceFromConst(op->getIn(0)->getAddr());
|
||||
AddrSpace *storeSpace = op->getIn(0)->getSpaceFromConst();
|
||||
if ((container == storeSpace && op->usesSpacebasePtr()) ||
|
||||
(spc == storeSpace)) {
|
||||
indop = fd->newIndirectOp(op,addr,size,PcodeOp::indirect_store);
|
||||
|
|
|
@ -79,7 +79,7 @@ void EmulateFunction::executeLoad(void)
|
|||
{
|
||||
if (collectloads) {
|
||||
uintb off = getVarnodeValue(currentOp->getIn(1));
|
||||
AddrSpace *spc = Address::getSpaceFromConst(currentOp->getIn(0)->getAddr());
|
||||
AddrSpace *spc = currentOp->getIn(0)->getSpaceFromConst();
|
||||
off = AddrSpace::addressToByte(off,spc->getWordSize());
|
||||
int4 sz = currentOp->getOut()->getSize();
|
||||
loadpoints.push_back(LoadTable(Address(spc,off),sz));
|
||||
|
|
|
@ -416,7 +416,7 @@ void PcodeOp::saveXml(ostream &s) const
|
|||
}
|
||||
else if (vn->getSpace()->getType()==IPTR_CONSTANT) {
|
||||
if ((i==0)&&((code()==CPUI_STORE)||(code()==CPUI_LOAD))) {
|
||||
AddrSpace *spc = Address::getSpaceFromConst(vn->getAddr());
|
||||
AddrSpace *spc = vn->getSpaceFromConst();
|
||||
s << "<spaceid";
|
||||
a_v(s,"name",spc->getName());
|
||||
s << "/>\n";
|
||||
|
|
|
@ -41,6 +41,9 @@ struct VarnodeData {
|
|||
/// Get the location of the varnode as an address
|
||||
Address getAddr(void) const;
|
||||
|
||||
/// Treat \b this as a constant and recover encoded address space
|
||||
AddrSpace *getSpaceFromConst(void) const;
|
||||
|
||||
/// Recover this object from an XML tag
|
||||
void restoreXml(const Element *el,const AddrSpaceManager *manage);
|
||||
|
||||
|
@ -86,6 +89,11 @@ inline Address VarnodeData::getAddr(void) const {
|
|||
return Address(space,offset);
|
||||
}
|
||||
|
||||
/// \return the encoded AddrSpace
|
||||
inline AddrSpace *VarnodeData::getSpaceFromConst(void) const {
|
||||
return (AddrSpace *)(uintp)offset;
|
||||
}
|
||||
|
||||
/// \brief A low-level representation of a single pcode operation
|
||||
///
|
||||
/// This is just the minimum amount of data to represent a pcode operation
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -292,7 +291,7 @@ void PreferSplitManager::splitLoad(SplitInstance *inst,PcodeOp *op)
|
|||
data->opSetOutput(hiop,inst->hi); // Outputs are the pieces of the original
|
||||
data->opSetOutput(loop,inst->lo);
|
||||
Varnode *spaceid = op->getIn(0);
|
||||
AddrSpace *spc = Address::getSpaceFromConst(spaceid->getAddr());
|
||||
AddrSpace *spc = spaceid->getSpaceFromConst();
|
||||
spaceid = data->newConstant(spaceid->getSize(),spaceid->getOffset()); // Duplicate original spaceid into new LOADs
|
||||
data->opSetInput(hiop,spaceid,0);
|
||||
spaceid = data->newConstant(spaceid->getSize(),spaceid->getOffset());
|
||||
|
@ -343,7 +342,7 @@ void PreferSplitManager::splitStore(SplitInstance *inst,PcodeOp *op)
|
|||
data->opSetInput(hiop,inst->hi,2); // Varnodes "being stored" are the pieces of the original
|
||||
data->opSetInput(loop,inst->lo,2);
|
||||
Varnode *spaceid = op->getIn(0);
|
||||
AddrSpace *spc = Address::getSpaceFromConst(spaceid->getAddr());
|
||||
AddrSpace *spc = spaceid->getSpaceFromConst();
|
||||
spaceid = data->newConstant(spaceid->getSize(),spaceid->getOffset()); // Duplicate original spaceid into new STOREs
|
||||
data->opSetInput(hiop,spaceid,0);
|
||||
spaceid = data->newConstant(spaceid->getSize(),spaceid->getOffset());
|
||||
|
|
|
@ -3863,7 +3863,7 @@ AddrSpace *RuleLoadVarnode::checkSpacebase(Architecture *glb,PcodeOp *op,uintb &
|
|||
AddrSpace *loadspace;
|
||||
|
||||
offvn = op->getIn(1); // Address offset
|
||||
loadspace = Address::getSpaceFromConst(op->getIn(0)->getAddr()); // Space being loaded/stored
|
||||
loadspace = op->getIn(0)->getSpaceFromConst(); // Space being loaded/stored
|
||||
// Treat segmentop as part of load/store
|
||||
if (offvn->isWritten()&&(offvn->getDef()->code()==CPUI_SEGMENTOP)) {
|
||||
offvn = offvn->getDef()->getIn(2);
|
||||
|
@ -7734,7 +7734,7 @@ void RuleSegment::getOpList(vector<uint4> &oplist) const
|
|||
int4 RuleSegment::applyOp(PcodeOp *op,Funcdata &data)
|
||||
|
||||
{
|
||||
SegmentOp *segdef = data.getArch()->userops.getSegmentOp(Address::getSpaceFromConst(op->getIn(0)->getAddr())->getIndex());
|
||||
SegmentOp *segdef = data.getArch()->userops.getSegmentOp(op->getIn(0)->getSpaceFromConst()->getIndex());
|
||||
if (segdef == (SegmentOp *)0)
|
||||
throw LowlevelError("Segment operand missing definition");
|
||||
|
||||
|
@ -8038,7 +8038,7 @@ int4 RulePtrFlow::applyOp(PcodeOp *op,Funcdata &data)
|
|||
case CPUI_LOAD:
|
||||
case CPUI_STORE:
|
||||
vn = op->getIn(1);
|
||||
spc = Address::getSpaceFromConst(op->getIn(0)->getAddr());
|
||||
spc = op->getIn(0)->getSpaceFromConst();
|
||||
if (vn->getSize() > spc->getAddrSize()) {
|
||||
vn = truncatePointer(spc,op,vn,1,data);
|
||||
madeChange = 1;
|
||||
|
|
|
@ -2196,7 +2196,7 @@ bool LaneDivide::buildStore(PcodeOp *op,int4 numLanes,int4 skipLanes)
|
|||
if (inVars == (TransformVar *)0) return false;
|
||||
uintb spaceConst = op->getIn(0)->getOffset();
|
||||
int4 spaceConstSize = op->getIn(0)->getSize();
|
||||
AddrSpace *spc = Address::getSpaceFromConst(op->getIn(0)->getAddr()); // Address space being stored to
|
||||
AddrSpace *spc = op->getIn(0)->getSpaceFromConst(); // Address space being stored to
|
||||
Varnode *origPtr = op->getIn(1);
|
||||
if (origPtr->isFree()) {
|
||||
if (!origPtr->isConstant()) return false;
|
||||
|
@ -2244,7 +2244,7 @@ bool LaneDivide::buildLoad(PcodeOp *op,TransformVar *outVars,int4 numLanes,int4
|
|||
{
|
||||
uintb spaceConst = op->getIn(0)->getOffset();
|
||||
int4 spaceConstSize = op->getIn(0)->getSize();
|
||||
AddrSpace *spc = Address::getSpaceFromConst(op->getIn(0)->getAddr()); // Address space being stored to
|
||||
AddrSpace *spc = op->getIn(0)->getSpaceFromConst(); // Address space being stored to
|
||||
Varnode *origPtr = op->getIn(1);
|
||||
if (origPtr->isFree()) {
|
||||
if (!origPtr->isConstant()) return false;
|
||||
|
|
|
@ -361,7 +361,7 @@ Datatype *TypeOpLoad::getInputCast(const PcodeOp *op,int4 slot,const CastStrateg
|
|||
Datatype *reqtype = op->getOut()->getHighTypeDefFacing(); // Cast load pointer to match output
|
||||
const Varnode *invn = op->getIn(1);
|
||||
Datatype *curtype = invn->getHighTypeReadFacing(op);
|
||||
AddrSpace *spc = Address::getSpaceFromConst(op->getIn(0)->getAddr());
|
||||
AddrSpace *spc = op->getIn(0)->getSpaceFromConst();
|
||||
// Its possible that the input type is not a pointer to the output type
|
||||
// (or even a pointer) due to cycle trimming in the type propagation algorithms
|
||||
if (curtype->getMetatype() == TYPE_PTR)
|
||||
|
@ -408,7 +408,7 @@ Datatype *TypeOpLoad::propagateType(Datatype *alttype,PcodeOp *op,Varnode *invn,
|
|||
if (invn->isSpacebase()) return (Datatype *)0;
|
||||
Datatype *newtype;
|
||||
if (inslot == -1) { // Propagating output to input (value to ptr)
|
||||
AddrSpace *spc = Address::getSpaceFromConst(op->getIn(0)->getAddr());
|
||||
AddrSpace *spc = op->getIn(0)->getSpaceFromConst();
|
||||
newtype = tlst->getTypePointerNoDepth(outvn->getTempType()->getSize(),alttype,spc->getWordSize());
|
||||
}
|
||||
else if (alttype->getMetatype()==TYPE_PTR) {
|
||||
|
@ -426,7 +426,7 @@ void TypeOpLoad::printRaw(ostream &s,const PcodeOp *op)
|
|||
{
|
||||
Varnode::printRaw(s,op->getOut());
|
||||
s << " = *(";
|
||||
AddrSpace *spc = Address::getSpaceFromConst(op->getIn(0)->getAddr());
|
||||
AddrSpace *spc = op->getIn(0)->getSpaceFromConst();
|
||||
s << spc->getName() << ',';
|
||||
Varnode::printRaw(s,op->getIn(1));
|
||||
s << ')';
|
||||
|
@ -447,7 +447,7 @@ Datatype *TypeOpStore::getInputCast(const PcodeOp *op,int4 slot,const CastStrate
|
|||
Datatype *pointerType = pointerVn->getHighTypeReadFacing(op);
|
||||
Datatype *pointedToType = pointerType;
|
||||
Datatype *valueType = op->getIn(2)->getHighTypeReadFacing(op);
|
||||
AddrSpace *spc = Address::getSpaceFromConst(op->getIn(0)->getAddr());
|
||||
AddrSpace *spc = op->getIn(0)->getSpaceFromConst();
|
||||
int4 destSize;
|
||||
if (pointerType->getMetatype() == TYPE_PTR) {
|
||||
pointedToType = ((TypePointer *)pointerType)->getPtrTo();
|
||||
|
@ -483,7 +483,7 @@ Datatype *TypeOpStore::propagateType(Datatype *alttype,PcodeOp *op,Varnode *invn
|
|||
if (invn->isSpacebase()) return (Datatype *)0;
|
||||
Datatype *newtype;
|
||||
if (inslot==2) { // Propagating value to ptr
|
||||
AddrSpace *spc = Address::getSpaceFromConst(op->getIn(0)->getAddr());
|
||||
AddrSpace *spc = op->getIn(0)->getSpaceFromConst();
|
||||
newtype = tlst->getTypePointerNoDepth(outvn->getTempType()->getSize(),alttype,spc->getWordSize());
|
||||
}
|
||||
else if (alttype->getMetatype()==TYPE_PTR) {
|
||||
|
@ -500,7 +500,7 @@ void TypeOpStore::printRaw(ostream &s,const PcodeOp *op)
|
|||
|
||||
{
|
||||
s << "*(";
|
||||
AddrSpace *spc = Address::getSpaceFromConst(op->getIn(0)->getAddr());
|
||||
AddrSpace *spc = op->getIn(0)->getSpaceFromConst();
|
||||
s << spc->getName() << ',';
|
||||
Varnode::printRaw(s,op->getIn(1));
|
||||
s << ") = ";
|
||||
|
@ -2183,7 +2183,7 @@ void TypeOpSegment::printRaw(ostream &s,const PcodeOp *op)
|
|||
}
|
||||
s << getOperatorName(op);
|
||||
s << '(';
|
||||
AddrSpace *spc = Address::getSpaceFromConst(op->getIn(0)->getAddr());
|
||||
AddrSpace *spc = op->getIn(0)->getSpaceFromConst();
|
||||
s << spc->getName() << ',';
|
||||
Varnode::printRaw(s,op->getIn(1));
|
||||
s << ',';
|
||||
|
|
|
@ -169,6 +169,7 @@ public:
|
|||
|
||||
const Address &getAddr(void) const { return (const Address &) loc; } ///< Get the storage Address
|
||||
AddrSpace *getSpace(void) const { return loc.getSpace(); } ///< Get the AddrSpace storing this Varnode
|
||||
AddrSpace *getSpaceFromConst(void) const; ///< Get AddrSpace from \b this encoded constant Varnode
|
||||
uintb getOffset(void) const { return loc.getOffset(); } ///< Get the offset (within its AddrSpace) where this is stored
|
||||
int4 getSize(void) const { return size; } ///< Get the number of bytes this Varnode stores
|
||||
int2 getMergeGroup(void) const { return mergegroup; } ///< Get the \e forced \e merge group of this Varnode
|
||||
|
@ -408,4 +409,12 @@ struct TraverseNode {
|
|||
bool contiguous_test(Varnode *vn1,Varnode *vn2); ///< Test if Varnodes are pieces of a whole
|
||||
Varnode *findContiguousWhole(Funcdata &data,Varnode *vn1,
|
||||
Varnode *vn2); ///< Retrieve the whole Varnode given pieces
|
||||
|
||||
/// In \b LOAD and \b STORE instructions, the particular address space being read/written is encoded
|
||||
/// as a constant Varnode. Internally, this constant is the actual pointer to the AddrSpace.
|
||||
/// \return the AddrSpace pointer
|
||||
inline AddrSpace *Varnode::getSpaceFromConst(void) const {
|
||||
return (AddrSpace *)(uintp)loc.getOffset();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue