GP-2037 RuleDoubleStore

This commit is contained in:
caheckman 2022-04-01 13:27:33 -04:00
parent cb4b309942
commit 4448f11cb4
15 changed files with 761 additions and 231 deletions

View file

@ -90,9 +90,6 @@ public:
/// Restore an address and size from parsed XML /// Restore an address and size from parsed XML
static Address restoreXml(const Element *el,const AddrSpaceManager *manage,int4 &size); 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 /// \brief A class for uniquely labelling and comparing PcodeOps
@ -442,17 +439,6 @@ inline void Address::saveXml(ostream &s,int4 size) const {
s << "/>"; 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 /// \param addr is the Address to test for containment
/// \return \b true if addr is in \b this Range /// \return \b true if addr is in \b this Range
inline bool Range::contains(const Address &addr) const { inline bool Range::contains(const Address &addr) const {

View file

@ -963,10 +963,10 @@ AddrSpace *ActionConstantPtr::searchForSpaceAttribute(Varnode *vn,PcodeOp *op)
op = vn->loneDescend(); op = vn->loneDescend();
break; break;
case CPUI_LOAD: case CPUI_LOAD:
return Address::getSpaceFromConst(op->getIn(0)->getAddr()); return op->getIn(0)->getSpaceFromConst();
case CPUI_STORE: case CPUI_STORE:
if (op->getIn(1) == vn) if (op->getIn(1) == vn)
return Address::getSpaceFromConst(op->getIn(0)->getAddr()); return op->getIn(0)->getSpaceFromConst();
return (AddrSpace *)0; return (AddrSpace *)0;
default: default:
return (AddrSpace *)0; return (AddrSpace *)0;
@ -977,9 +977,9 @@ AddrSpace *ActionConstantPtr::searchForSpaceAttribute(Varnode *vn,PcodeOp *op)
op = *iter; op = *iter;
OpCode opc = op->code(); OpCode opc = op->code();
if (opc == CPUI_LOAD) 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) else if (opc == CPUI_STORE && op->getIn(1) == vn)
return Address::getSpaceFromConst(op->getIn(0)->getAddr()); return op->getIn(0)->getSpaceFromConst();
} }
return (AddrSpace *)0; return (AddrSpace *)0;
} }
@ -2203,7 +2203,7 @@ void ActionSetCasts::checkPointerIssues(PcodeOp *op,Varnode *vn,Funcdata &data)
if (ptrtype->getMetatype()==TYPE_PTR) { if (ptrtype->getMetatype()==TYPE_PTR) {
AddrSpace *spc = ((TypePointer *)ptrtype)->getSpace(); AddrSpace *spc = ((TypePointer *)ptrtype)->getSpace();
if (spc != (AddrSpace *)0) { if (spc != (AddrSpace *)0) {
AddrSpace *opSpc = Address::getSpaceFromConst(op->getIn(0)->getAddr()); AddrSpace *opSpc = op->getIn(0)->getSpaceFromConst();
if (opSpc != spc && spc->getContain() != opSpc) { if (opSpc != spc && spc->getContain() != opSpc) {
string name = op->getOpcode()->getName(); string name = op->getOpcode()->getName();
name[0] = toupper( name[0] ); name[0] = toupper( name[0] );
@ -5080,6 +5080,7 @@ void ActionDatabase::universalAction(Architecture *conf)
actprop->addRule( new RulePiecePathology("protorecovery") ); actprop->addRule( new RulePiecePathology("protorecovery") );
actprop->addRule( new RuleDoubleLoad("doubleload") ); actprop->addRule( new RuleDoubleLoad("doubleload") );
actprop->addRule( new RuleDoubleStore("doubleprecis") );
actprop->addRule( new RuleDoubleIn("doubleprecis") ); actprop->addRule( new RuleDoubleIn("doubleprecis") );
for(iter=conf->extra_pool_rules.begin();iter!=conf->extra_pool_rules.end();++iter) for(iter=conf->extra_pool_rules.begin();iter!=conf->extra_pool_rules.end();++iter)
actprop->addRule( *iter ); // Add CPU specific rules actprop->addRule( *iter ); // Add CPU specific rules

File diff suppressed because it is too large Load diff

View file

@ -19,49 +19,57 @@
#include "ruleaction.hh" #include "ruleaction.hh"
#include "funcdata.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 { class SplitVarnode {
Varnode *lo; // Least significant piece of the double precision object Varnode *lo; ///< Least significant piece of the double precision object
Varnode *hi; // Most 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 Varnode *whole; ///< A representative of the whole object
PcodeOp *defpoint; // Operation at which both -lo- and -hi- are defined PcodeOp *defpoint; ///< Operation at which both \b lo and \b hi are defined
BlockBasic *defblock; // Block in which bot -lo- and -hi- are defined BlockBasic *defblock; ///< Block in which both \b lo and \b hi are defined
uintb val; // Value of a double precision constant uintb val; ///< Value of a double precision constant
int4 wholesize; // Size in bytes of the (virtual) whole int4 wholesize; ///< Size in bytes of the (virtual) whole
bool findWholeSplitToPieces(void); bool findWholeSplitToPieces(void); ///< Find whole out of which \b hi and \b lo are split
bool findDefinitionPoint(void); bool findDefinitionPoint(void); ///< Find the earliest PcodeOp where both \b lo and \b hi are defined
bool findWholeBuiltFromPieces(void); bool findWholeBuiltFromPieces(void); ///< Find whole Varnode formed as a CPUI_PIECE of \b hi and \b lo
public: public:
SplitVarnode(void) {} // For use with inHandHi SplitVarnode(void) {} ///< Construct an uninitialized SplitVarnode
SplitVarnode(int4 sz,uintb v); // Initialize a double precision constant SplitVarnode(int4 sz,uintb v); ///< Construct a double precision constant
SplitVarnode(Varnode *l,Varnode *h) { initPartial(l,h); } 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); void initAll(Varnode *w,Varnode *l,Varnode *h); ///< Construct given Varnode pieces and a known \b whole Varnode
void initPartial(int4 sz,uintb v); void initPartial(int4 sz,uintb v); ///< (Re)initialize \b this SplitVarnode as a constant
void initPartial(Varnode *l,Varnode *h); void initPartial(int4 sz,Varnode *l,Varnode *h); ///< (Re)initialize \b this SplitVarnode given Varnode pieces
bool inHandHi(Varnode *h); bool inHandHi(Varnode *h); ///< Try to initialize given just the most significant piece split from whole
bool inHandLo(Varnode *l); bool inHandLo(Varnode *l); ///< Try to initialize given just the least significant piece split from whole
bool inHandLoNoHi(Varnode *l); bool inHandLoNoHi(Varnode *l); ///< Try to initialize given just the least significant piece (other piece may be zero)
bool inHandHiOut(Varnode *h); bool inHandHiOut(Varnode *h); ///< Try to initialize given just the most significant piece concatenated into whole
bool inHandLoOut(Varnode *h); bool inHandLoOut(Varnode *l); ///< Try to initialize given just the least significant piece concatenated into whole
bool isConstant(void) const { return (lo == (Varnode *)0); } 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)); } 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; } int4 getSize(void) const { return wholesize; } ///< Get the size of \b this SplitVarnode as a whole in bytes
Varnode *getLo(void) const { return lo; } Varnode *getLo(void) const { return lo; } ///< Get the least significant Varnode piece
Varnode *getHi(void) const { return hi; } Varnode *getHi(void) const { return hi; } ///< Get the most significant Varnode piece
Varnode *getWhole(void) const { return whole; } Varnode *getWhole(void) const { return whole; } ///< Get the Varnode representing \b this as a whole
PcodeOp *getDefPoint(void) const { return defpoint; } PcodeOp *getDefPoint(void) const { return defpoint; } ///< Get the(final) defining PcodeOp of \b this
BlockBasic *getDefBlock(void) const { return defblock; } BlockBasic *getDefBlock(void) const { return defblock; } ///< Get the defining basic block of \b this
uintb getValue(void) const { return val; } uintb getValue(void) const { return val; } ///< Get the value of \b this, assuming it is a constant
bool isWholeFeasible(PcodeOp *existop); bool isWholeFeasible(PcodeOp *existop); ///< Does a whole Varnode already exist or can it be created before the given PcodeOp
bool isWholePhiFeasible(FlowBlock *bl); bool isWholePhiFeasible(FlowBlock *bl); ///< Does a whole Varnode already exist or can it be created before the given basic block
void findCreateWhole(Funcdata &data); void findCreateWhole(Funcdata &data); ///< Create a \b whole Varnode for \b this, if it doesn't already exist
void findCreateOutputWhole(Funcdata &data); void findCreateOutputWhole(Funcdata &data); ///< Create a \b whole Varnode that will be a PcodeOp output
void createJoinedWhole(Funcdata &data); void createJoinedWhole(Funcdata &data); ///< Create a \b whole Varnode from pieces, respecting piece storage
void buildLoFromWhole(Funcdata &data); void buildLoFromWhole(Funcdata &data); ///< Rebuild the least significant piece as a CPUI_SUBPIECE of the \b whole
void buildHiFromWhole(Funcdata &data); void buildHiFromWhole(Funcdata &data); ///< Rebuild the most significant piece as a CPUI_SUBPIECE of the \b whole
PcodeOp *findEarliestSplitPoint(void); PcodeOp *findEarliestSplitPoint(void); ///< Find the earliest definition point of the \b lo and \b hi pieces
PcodeOp *findOutExist(void); 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 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 bool isAddrTiedContiguous(Varnode *lo,Varnode *hi,Address &res);
static void wholeList(Varnode *w,vector<SplitVarnode> &splitvec); static void wholeList(Varnode *w,vector<SplitVarnode> &splitvec);
static void findCopies(const SplitVarnode &in,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); 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 { class RuleDoubleIn : public Rule {
int4 attemptMarking(Funcdata &data,Varnode *vn,PcodeOp *subpieceOp);
public: 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 { virtual Rule *clone(const ActionGroupList &grouplist) const {
if (!grouplist.contains(getGroup())) return (Rule *)0; if (!grouplist.contains(getGroup())) return (Rule *)0;
return new RuleDoubleIn(getGroup()); return new RuleDoubleIn(getGroup());
@ -309,7 +324,19 @@ public:
} }
virtual void getOpList(vector<uint4> &oplist) const; virtual void getOpList(vector<uint4> &oplist) const;
virtual int4 applyOp(PcodeOp *op,Funcdata &data); 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 #endif

View file

@ -236,7 +236,7 @@ void EmulateMemory::executeLoad(void)
{ {
uintb off = memstate->getValue(currentOp->getInput(1)); 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()); off = AddrSpace::addressToByte(off,spc->getWordSize());
uintb res = memstate->getValue(spc,off,currentOp->getOutput()->size); 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 val = memstate->getValue(currentOp->getInput(2)); // Value being stored
uintb off = memstate->getValue(currentOp->getInput(1)); // Offset to store at 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()); off = AddrSpace::addressToByte(off,spc->getWordSize());
memstate->setValue(spc,off,currentOp->getInput(2)->size,val); memstate->setValue(spc,off,currentOp->getInput(2)->size,val);

View file

@ -66,7 +66,7 @@ void EmulatePcodeOp::executeLoad(void)
{ {
// op will be null, use current_op // op will be null, use current_op
uintb off = getVarnodeValue(currentOp->getIn(1)); 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()); off = AddrSpace::addressToByte(off,spc->getWordSize());
int4 sz = currentOp->getOut()->getSize(); int4 sz = currentOp->getOut()->getSize();
uintb res = getLoadImageValue(spc,off,sz); 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 // There is currently nowhere to store anything since the memstate is null
// uintb val = getVarnodeValue(current_op->getIn(2)); // Value being stored // uintb val = getVarnodeValue(current_op->getIn(2)); // Value being stored
// uintb off = getVarnodeValue(current_op->getIn(1)); // 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) bool EmulatePcodeOp::executeCbranch(void)
@ -120,7 +120,7 @@ void EmulatePcodeOp::executeIndirect(void)
void EmulatePcodeOp::executeSegmentOp(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) if (segdef == (SegmentOp *)0)
throw LowlevelError("Segment operand missing definition"); throw LowlevelError("Segment operand missing definition");
@ -186,7 +186,7 @@ void EmulateSnippet::executeLoad(void)
{ {
// op will be null, use current_op // op will be null, use current_op
uintb off = getVarnodeValue(currentOp->getInput(1)); 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()); off = AddrSpace::addressToByte(off,spc->getWordSize());
int4 sz = currentOp->getOutput()->size; int4 sz = currentOp->getOutput()->size;
uintb res = getLoadImageValue(spc,off,sz); uintb res = getLoadImageValue(spc,off,sz);

View file

@ -1345,7 +1345,7 @@ void Heritage::guardStores(const Address &addr,int4 size,vector<Varnode *> &writ
for(iter=fd->beginOp(CPUI_STORE);iter!=iterend;++iter) { for(iter=fd->beginOp(CPUI_STORE);iter!=iterend;++iter) {
op = *iter; op = *iter;
if (op->isDead()) continue; if (op->isDead()) continue;
AddrSpace *storeSpace = Address::getSpaceFromConst(op->getIn(0)->getAddr()); AddrSpace *storeSpace = op->getIn(0)->getSpaceFromConst();
if ((container == storeSpace && op->usesSpacebasePtr()) || if ((container == storeSpace && op->usesSpacebasePtr()) ||
(spc == storeSpace)) { (spc == storeSpace)) {
indop = fd->newIndirectOp(op,addr,size,PcodeOp::indirect_store); indop = fd->newIndirectOp(op,addr,size,PcodeOp::indirect_store);

View file

@ -79,7 +79,7 @@ void EmulateFunction::executeLoad(void)
{ {
if (collectloads) { if (collectloads) {
uintb off = getVarnodeValue(currentOp->getIn(1)); 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()); off = AddrSpace::addressToByte(off,spc->getWordSize());
int4 sz = currentOp->getOut()->getSize(); int4 sz = currentOp->getOut()->getSize();
loadpoints.push_back(LoadTable(Address(spc,off),sz)); loadpoints.push_back(LoadTable(Address(spc,off),sz));

View file

@ -416,7 +416,7 @@ void PcodeOp::saveXml(ostream &s) const
} }
else if (vn->getSpace()->getType()==IPTR_CONSTANT) { else if (vn->getSpace()->getType()==IPTR_CONSTANT) {
if ((i==0)&&((code()==CPUI_STORE)||(code()==CPUI_LOAD))) { if ((i==0)&&((code()==CPUI_STORE)||(code()==CPUI_LOAD))) {
AddrSpace *spc = Address::getSpaceFromConst(vn->getAddr()); AddrSpace *spc = vn->getSpaceFromConst();
s << "<spaceid"; s << "<spaceid";
a_v(s,"name",spc->getName()); a_v(s,"name",spc->getName());
s << "/>\n"; s << "/>\n";

View file

@ -41,6 +41,9 @@ struct VarnodeData {
/// Get the location of the varnode as an address /// Get the location of the varnode as an address
Address getAddr(void) const; 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 /// Recover this object from an XML tag
void restoreXml(const Element *el,const AddrSpaceManager *manage); void restoreXml(const Element *el,const AddrSpaceManager *manage);
@ -86,6 +89,11 @@ inline Address VarnodeData::getAddr(void) const {
return Address(space,offset); 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 /// \brief A low-level representation of a single pcode operation
/// ///
/// This is just the minimum amount of data to represent a pcode operation /// This is just the minimum amount of data to represent a pcode operation

View file

@ -1,6 +1,5 @@
/* ### /* ###
* IP: GHIDRA * IP: GHIDRA
* REVIEWED: YES
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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(hiop,inst->hi); // Outputs are the pieces of the original
data->opSetOutput(loop,inst->lo); data->opSetOutput(loop,inst->lo);
Varnode *spaceid = op->getIn(0); 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 spaceid = data->newConstant(spaceid->getSize(),spaceid->getOffset()); // Duplicate original spaceid into new LOADs
data->opSetInput(hiop,spaceid,0); data->opSetInput(hiop,spaceid,0);
spaceid = data->newConstant(spaceid->getSize(),spaceid->getOffset()); 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(hiop,inst->hi,2); // Varnodes "being stored" are the pieces of the original
data->opSetInput(loop,inst->lo,2); data->opSetInput(loop,inst->lo,2);
Varnode *spaceid = op->getIn(0); 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 spaceid = data->newConstant(spaceid->getSize(),spaceid->getOffset()); // Duplicate original spaceid into new STOREs
data->opSetInput(hiop,spaceid,0); data->opSetInput(hiop,spaceid,0);
spaceid = data->newConstant(spaceid->getSize(),spaceid->getOffset()); spaceid = data->newConstant(spaceid->getSize(),spaceid->getOffset());

View file

@ -3863,7 +3863,7 @@ AddrSpace *RuleLoadVarnode::checkSpacebase(Architecture *glb,PcodeOp *op,uintb &
AddrSpace *loadspace; AddrSpace *loadspace;
offvn = op->getIn(1); // Address offset 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 // Treat segmentop as part of load/store
if (offvn->isWritten()&&(offvn->getDef()->code()==CPUI_SEGMENTOP)) { if (offvn->isWritten()&&(offvn->getDef()->code()==CPUI_SEGMENTOP)) {
offvn = offvn->getDef()->getIn(2); offvn = offvn->getDef()->getIn(2);
@ -7734,7 +7734,7 @@ void RuleSegment::getOpList(vector<uint4> &oplist) const
int4 RuleSegment::applyOp(PcodeOp *op,Funcdata &data) 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) if (segdef == (SegmentOp *)0)
throw LowlevelError("Segment operand missing definition"); throw LowlevelError("Segment operand missing definition");
@ -8038,7 +8038,7 @@ int4 RulePtrFlow::applyOp(PcodeOp *op,Funcdata &data)
case CPUI_LOAD: case CPUI_LOAD:
case CPUI_STORE: case CPUI_STORE:
vn = op->getIn(1); vn = op->getIn(1);
spc = Address::getSpaceFromConst(op->getIn(0)->getAddr()); spc = op->getIn(0)->getSpaceFromConst();
if (vn->getSize() > spc->getAddrSize()) { if (vn->getSize() > spc->getAddrSize()) {
vn = truncatePointer(spc,op,vn,1,data); vn = truncatePointer(spc,op,vn,1,data);
madeChange = 1; madeChange = 1;

View file

@ -2196,7 +2196,7 @@ bool LaneDivide::buildStore(PcodeOp *op,int4 numLanes,int4 skipLanes)
if (inVars == (TransformVar *)0) return false; if (inVars == (TransformVar *)0) return false;
uintb spaceConst = op->getIn(0)->getOffset(); uintb spaceConst = op->getIn(0)->getOffset();
int4 spaceConstSize = op->getIn(0)->getSize(); 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); Varnode *origPtr = op->getIn(1);
if (origPtr->isFree()) { if (origPtr->isFree()) {
if (!origPtr->isConstant()) return false; 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(); uintb spaceConst = op->getIn(0)->getOffset();
int4 spaceConstSize = op->getIn(0)->getSize(); 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); Varnode *origPtr = op->getIn(1);
if (origPtr->isFree()) { if (origPtr->isFree()) {
if (!origPtr->isConstant()) return false; if (!origPtr->isConstant()) return false;

View file

@ -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 Datatype *reqtype = op->getOut()->getHighTypeDefFacing(); // Cast load pointer to match output
const Varnode *invn = op->getIn(1); const Varnode *invn = op->getIn(1);
Datatype *curtype = invn->getHighTypeReadFacing(op); 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 // 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 // (or even a pointer) due to cycle trimming in the type propagation algorithms
if (curtype->getMetatype() == TYPE_PTR) if (curtype->getMetatype() == TYPE_PTR)
@ -408,7 +408,7 @@ Datatype *TypeOpLoad::propagateType(Datatype *alttype,PcodeOp *op,Varnode *invn,
if (invn->isSpacebase()) return (Datatype *)0; if (invn->isSpacebase()) return (Datatype *)0;
Datatype *newtype; Datatype *newtype;
if (inslot == -1) { // Propagating output to input (value to ptr) 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()); newtype = tlst->getTypePointerNoDepth(outvn->getTempType()->getSize(),alttype,spc->getWordSize());
} }
else if (alttype->getMetatype()==TYPE_PTR) { else if (alttype->getMetatype()==TYPE_PTR) {
@ -426,7 +426,7 @@ void TypeOpLoad::printRaw(ostream &s,const PcodeOp *op)
{ {
Varnode::printRaw(s,op->getOut()); Varnode::printRaw(s,op->getOut());
s << " = *("; s << " = *(";
AddrSpace *spc = Address::getSpaceFromConst(op->getIn(0)->getAddr()); AddrSpace *spc = op->getIn(0)->getSpaceFromConst();
s << spc->getName() << ','; s << spc->getName() << ',';
Varnode::printRaw(s,op->getIn(1)); Varnode::printRaw(s,op->getIn(1));
s << ')'; s << ')';
@ -447,7 +447,7 @@ Datatype *TypeOpStore::getInputCast(const PcodeOp *op,int4 slot,const CastStrate
Datatype *pointerType = pointerVn->getHighTypeReadFacing(op); Datatype *pointerType = pointerVn->getHighTypeReadFacing(op);
Datatype *pointedToType = pointerType; Datatype *pointedToType = pointerType;
Datatype *valueType = op->getIn(2)->getHighTypeReadFacing(op); Datatype *valueType = op->getIn(2)->getHighTypeReadFacing(op);
AddrSpace *spc = Address::getSpaceFromConst(op->getIn(0)->getAddr()); AddrSpace *spc = op->getIn(0)->getSpaceFromConst();
int4 destSize; int4 destSize;
if (pointerType->getMetatype() == TYPE_PTR) { if (pointerType->getMetatype() == TYPE_PTR) {
pointedToType = ((TypePointer *)pointerType)->getPtrTo(); pointedToType = ((TypePointer *)pointerType)->getPtrTo();
@ -483,7 +483,7 @@ Datatype *TypeOpStore::propagateType(Datatype *alttype,PcodeOp *op,Varnode *invn
if (invn->isSpacebase()) return (Datatype *)0; if (invn->isSpacebase()) return (Datatype *)0;
Datatype *newtype; Datatype *newtype;
if (inslot==2) { // Propagating value to ptr 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()); newtype = tlst->getTypePointerNoDepth(outvn->getTempType()->getSize(),alttype,spc->getWordSize());
} }
else if (alttype->getMetatype()==TYPE_PTR) { else if (alttype->getMetatype()==TYPE_PTR) {
@ -500,7 +500,7 @@ void TypeOpStore::printRaw(ostream &s,const PcodeOp *op)
{ {
s << "*("; s << "*(";
AddrSpace *spc = Address::getSpaceFromConst(op->getIn(0)->getAddr()); AddrSpace *spc = op->getIn(0)->getSpaceFromConst();
s << spc->getName() << ','; s << spc->getName() << ',';
Varnode::printRaw(s,op->getIn(1)); Varnode::printRaw(s,op->getIn(1));
s << ") = "; s << ") = ";
@ -2183,7 +2183,7 @@ void TypeOpSegment::printRaw(ostream &s,const PcodeOp *op)
} }
s << getOperatorName(op); s << getOperatorName(op);
s << '('; s << '(';
AddrSpace *spc = Address::getSpaceFromConst(op->getIn(0)->getAddr()); AddrSpace *spc = op->getIn(0)->getSpaceFromConst();
s << spc->getName() << ','; s << spc->getName() << ',';
Varnode::printRaw(s,op->getIn(1)); Varnode::printRaw(s,op->getIn(1));
s << ','; s << ',';

View file

@ -169,6 +169,7 @@ public:
const Address &getAddr(void) const { return (const Address &) loc; } ///< Get the storage Address 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 *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 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 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 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 bool contiguous_test(Varnode *vn1,Varnode *vn2); ///< Test if Varnodes are pieces of a whole
Varnode *findContiguousWhole(Funcdata &data,Varnode *vn1, Varnode *findContiguousWhole(Funcdata &data,Varnode *vn1,
Varnode *vn2); ///< Retrieve the whole Varnode given pieces 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 #endif