mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 18:29:37 +02:00
LOAD iterating, reclaim auto_live bit
This commit is contained in:
parent
74d27ecb20
commit
764eec057f
5 changed files with 47 additions and 38 deletions
|
@ -793,7 +793,7 @@ void Funcdata::nodeSplitCloneVarnode(PcodeOp *op,PcodeOp *newop)
|
||||||
uint4 vflags = opvn->getFlags();
|
uint4 vflags = opvn->getFlags();
|
||||||
vflags &= (Varnode::externref | Varnode::volatil | Varnode::incidental_copy |
|
vflags &= (Varnode::externref | Varnode::volatil | Varnode::incidental_copy |
|
||||||
Varnode::readonly | Varnode::persist |
|
Varnode::readonly | Varnode::persist |
|
||||||
Varnode::addrtied | Varnode::addrforce | Varnode::auto_live);
|
Varnode::addrtied | Varnode::addrforce);
|
||||||
newvn->setFlags(vflags);
|
newvn->setFlags(vflags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -257,7 +257,7 @@ Varnode *Funcdata::cloneVarnode(const Varnode *vn)
|
||||||
// These are the flags we allow to be cloned
|
// These are the flags we allow to be cloned
|
||||||
vflags &= (Varnode::annotation | Varnode::externref |
|
vflags &= (Varnode::annotation | Varnode::externref |
|
||||||
Varnode::readonly | Varnode::persist |
|
Varnode::readonly | Varnode::persist |
|
||||||
Varnode::addrtied | Varnode::addrforce | Varnode::auto_live |
|
Varnode::addrtied | Varnode::addrforce |
|
||||||
Varnode::indirect_creation | Varnode::incidental_copy |
|
Varnode::indirect_creation | Varnode::incidental_copy |
|
||||||
Varnode::volatil | Varnode::mapped);
|
Varnode::volatil | Varnode::mapped);
|
||||||
newvn->setFlags(vflags);
|
newvn->setFlags(vflags);
|
||||||
|
@ -503,7 +503,7 @@ void Funcdata::transferVarnodeProperties(Varnode *vn,Varnode *newVn,int4 lsbOffs
|
||||||
{
|
{
|
||||||
uintb newConsume = (vn->getConsume() >> 8*lsbOffset) & calc_mask(newVn->getSize());
|
uintb newConsume = (vn->getConsume() >> 8*lsbOffset) & calc_mask(newVn->getSize());
|
||||||
|
|
||||||
uint4 vnFlags = vn->getFlags() & (Varnode::directwrite|Varnode::addrforce|Varnode::auto_live);
|
uint4 vnFlags = vn->getFlags() & (Varnode::directwrite|Varnode::addrforce);
|
||||||
|
|
||||||
newVn->setFlags(vnFlags); // Preserve addrforce setting
|
newVn->setFlags(vnFlags); // Preserve addrforce setting
|
||||||
newVn->setConsume(newConsume);
|
newVn->setConsume(newConsume);
|
||||||
|
@ -805,7 +805,7 @@ void Funcdata::calcNZMask(void)
|
||||||
|
|
||||||
/// \brief Update Varnode properties based on (new) Symbol information
|
/// \brief Update Varnode properties based on (new) Symbol information
|
||||||
///
|
///
|
||||||
/// Boolean properties \b addrtied, \b addrforce, \b auto_live, and \b nolocalalias
|
/// Boolean properties \b addrtied, \b addrforce, and \b nolocalalias
|
||||||
/// for Varnodes are updated based on new Symbol information they map to.
|
/// for Varnodes are updated based on new Symbol information they map to.
|
||||||
/// The caller can elect to update data-type information as well, where Varnodes
|
/// The caller can elect to update data-type information as well, where Varnodes
|
||||||
/// and their associated HighVariables have their data-type finalized based symbols.
|
/// and their associated HighVariables have their data-type finalized based symbols.
|
||||||
|
@ -874,7 +874,7 @@ bool Funcdata::syncVarnodesWithSymbols(const ScopeLocal *lm,bool typesyes)
|
||||||
/// to point to the first Varnode after the affected set.
|
/// to point to the first Varnode after the affected set.
|
||||||
///
|
///
|
||||||
/// The only properties that can be effectively changed with this
|
/// The only properties that can be effectively changed with this
|
||||||
/// routine are \b mapped, \b addrtied, \b addrforce, \b auto_live, and \b nolocalalias.
|
/// routine are \b mapped, \b addrtied, \b addrforce, and \b nolocalalias.
|
||||||
/// HighVariable splits must occur if \b addrtied is cleared.
|
/// HighVariable splits must occur if \b addrtied is cleared.
|
||||||
///
|
///
|
||||||
/// If the given data-type is non-null, an attempt is made to update all the Varnodes
|
/// If the given data-type is non-null, an attempt is made to update all the Varnodes
|
||||||
|
@ -895,13 +895,13 @@ bool Funcdata::syncVarnodesWithSymbol(VarnodeLocSet::const_iterator &iter,uint4
|
||||||
// We take special care with the addrtied flag
|
// We take special care with the addrtied flag
|
||||||
// as we cannot set it here if it is clear
|
// as we cannot set it here if it is clear
|
||||||
// We can CLEAR but not SET the addrtied flag
|
// We can CLEAR but not SET the addrtied flag
|
||||||
// If addrtied is cleared, so should addrforce and auto_live
|
// If addrtied is cleared, so should addrforce
|
||||||
if ((flags&Varnode::addrtied)==0) // Is the addrtied flags cleared
|
if ((flags&Varnode::addrtied)==0) // Is the addrtied flags cleared
|
||||||
mask |= Varnode::addrtied | Varnode::addrforce | Varnode::auto_live;
|
mask |= Varnode::addrtied | Varnode::addrforce;
|
||||||
// We can set the nolocalalias flag, but not clear it
|
// We can set the nolocalalias flag, but not clear it
|
||||||
// If nolocalalias is set, then addrforce should be cleared
|
// If nolocalalias is set, then addrforce should be cleared
|
||||||
if ((flags&Varnode::nolocalalias)!=0)
|
if ((flags&Varnode::nolocalalias)!=0)
|
||||||
mask |= Varnode::nolocalalias | Varnode::addrforce | Varnode::auto_live;
|
mask |= Varnode::nolocalalias | Varnode::addrforce;
|
||||||
flags &= mask;
|
flags &= mask;
|
||||||
|
|
||||||
vn = *iter;
|
vn = *iter;
|
||||||
|
|
|
@ -627,6 +627,9 @@ void PcodeOpBank::addToCodeList(PcodeOp *op)
|
||||||
case CPUI_STORE:
|
case CPUI_STORE:
|
||||||
op->codeiter = storelist.insert(storelist.end(),op);
|
op->codeiter = storelist.insert(storelist.end(),op);
|
||||||
break;
|
break;
|
||||||
|
case CPUI_LOAD:
|
||||||
|
op->codeiter = loadlist.insert(loadlist.end(), op);
|
||||||
|
break;
|
||||||
case CPUI_RETURN:
|
case CPUI_RETURN:
|
||||||
op->codeiter = returnlist.insert(returnlist.end(),op);
|
op->codeiter = returnlist.insert(returnlist.end(),op);
|
||||||
break;
|
break;
|
||||||
|
@ -648,6 +651,9 @@ void PcodeOpBank::removeFromCodeList(PcodeOp *op)
|
||||||
case CPUI_STORE:
|
case CPUI_STORE:
|
||||||
storelist.erase(op->codeiter);
|
storelist.erase(op->codeiter);
|
||||||
break;
|
break;
|
||||||
|
case CPUI_LOAD:
|
||||||
|
loadlist.erase(op->codeiter);
|
||||||
|
break;
|
||||||
case CPUI_RETURN:
|
case CPUI_RETURN:
|
||||||
returnlist.erase(op->codeiter);
|
returnlist.erase(op->codeiter);
|
||||||
break;
|
break;
|
||||||
|
@ -663,6 +669,7 @@ void PcodeOpBank::clearCodeLists(void)
|
||||||
|
|
||||||
{
|
{
|
||||||
storelist.clear();
|
storelist.clear();
|
||||||
|
loadlist.clear();
|
||||||
returnlist.clear();
|
returnlist.clear();
|
||||||
useroplist.clear();
|
useroplist.clear();
|
||||||
}
|
}
|
||||||
|
@ -896,6 +903,8 @@ list<PcodeOp *>::const_iterator PcodeOpBank::begin(OpCode opc) const
|
||||||
switch(opc) {
|
switch(opc) {
|
||||||
case CPUI_STORE:
|
case CPUI_STORE:
|
||||||
return storelist.begin();
|
return storelist.begin();
|
||||||
|
case CPUI_LOAD:
|
||||||
|
return loadlist.begin();
|
||||||
case CPUI_RETURN:
|
case CPUI_RETURN:
|
||||||
return returnlist.begin();
|
return returnlist.begin();
|
||||||
case CPUI_CALLOTHER:
|
case CPUI_CALLOTHER:
|
||||||
|
@ -912,6 +921,8 @@ list<PcodeOp *>::const_iterator PcodeOpBank::end(OpCode opc) const
|
||||||
switch(opc) {
|
switch(opc) {
|
||||||
case CPUI_STORE:
|
case CPUI_STORE:
|
||||||
return storelist.end();
|
return storelist.end();
|
||||||
|
case CPUI_LOAD:
|
||||||
|
return loadlist.end();
|
||||||
case CPUI_RETURN:
|
case CPUI_RETURN:
|
||||||
return returnlist.end();
|
return returnlist.end();
|
||||||
case CPUI_CALLOTHER:
|
case CPUI_CALLOTHER:
|
||||||
|
|
|
@ -250,6 +250,7 @@ class PcodeOpBank {
|
||||||
list<PcodeOp *> deadlist; ///< List of \e dead PcodeOps
|
list<PcodeOp *> deadlist; ///< List of \e dead PcodeOps
|
||||||
list<PcodeOp *> alivelist; ///< List of \e alive PcodeOps
|
list<PcodeOp *> alivelist; ///< List of \e alive PcodeOps
|
||||||
list<PcodeOp *> storelist; ///< List of STORE PcodeOps
|
list<PcodeOp *> storelist; ///< List of STORE PcodeOps
|
||||||
|
list<PcodeOp *> loadlist; ///< list of LOAD PcodeOps
|
||||||
list<PcodeOp *> returnlist; ///< List of RETURN PcodeOps
|
list<PcodeOp *> returnlist; ///< List of RETURN PcodeOps
|
||||||
list<PcodeOp *> useroplist; ///< List of user-defined PcodeOps
|
list<PcodeOp *> useroplist; ///< List of user-defined PcodeOps
|
||||||
list<PcodeOp *> deadandgone; ///< List of retired PcodeOps
|
list<PcodeOp *> deadandgone; ///< List of retired PcodeOps
|
||||||
|
|
|
@ -83,29 +83,26 @@ public:
|
||||||
namelock = 0x200, ///< The Name of the Varnode is locked
|
namelock = 0x200, ///< The Name of the Varnode is locked
|
||||||
nolocalalias = 0x400, ///< There are no aliases pointing to this varnode
|
nolocalalias = 0x400, ///< There are no aliases pointing to this varnode
|
||||||
volatil = 0x800, ///< This varnode's value is volatile
|
volatil = 0x800, ///< This varnode's value is volatile
|
||||||
spacebase_placeholder = 0x1000, ///< This varnode is inserted artificially to track a register
|
|
||||||
///< value at a specific point in the code
|
|
||||||
|
|
||||||
externref = 0x2000, ///< Varnode address is specially mapped by the loader
|
externref = 0x1000, ///< Varnode address is specially mapped by the loader
|
||||||
readonly = 0x4000, ///< Varnode is stored at a readonly location
|
readonly = 0x2000, ///< Varnode is stored at a readonly location
|
||||||
persist = 0x8000, ///< Persists after (and before) function
|
persist = 0x4000, ///< Persists after (and before) function
|
||||||
addrtied = 0x10000, ///< High-level variable is tied to address
|
addrtied = 0x8000, ///< High-level variable is tied to address
|
||||||
unaffected = 0x20000, ///< Input which is unaffected by the function
|
unaffected = 0x10000, ///< Input which is unaffected by the function
|
||||||
spacebase = 0x40000, ///< This is a base register for an address space
|
spacebase = 0x20000, ///< This is a base register for an address space
|
||||||
indirectonly = 0x80000, ///< If all uses of illegalinput varnode are inputs to INDIRECT
|
indirectonly = 0x40000, ///< If all uses of illegalinput varnode are inputs to INDIRECT
|
||||||
directwrite = 0x100000, ///< (could be) Directly affected by a valid input
|
directwrite = 0x80000, ///< (could be) Directly affected by a valid input
|
||||||
addrforce = 0x200000, ///< Varnode is used to force variable into an address
|
addrforce = 0x100000, ///< Varnode is used to force variable into an address
|
||||||
|
|
||||||
mapped = 0x400000, ///< Varnode has a database entry associated with it
|
mapped = 0x200000, ///< Varnode has a database entry associated with it
|
||||||
indirect_creation = 0x800000, ///< The value in this Varnode is created indirectly
|
indirect_creation = 0x400000, ///< The value in this Varnode is created indirectly
|
||||||
return_address = 0x1000000, ///< Is the varnode storage for a return address
|
return_address = 0x800000, ///< Is the varnode storage for a return address
|
||||||
coverdirty = 0x2000000, ///< Cover is not upto date
|
coverdirty = 0x1000000, ///< Cover is not upto date
|
||||||
precislo = 0x4000000, ///< Is this Varnode the low part of a double precision value
|
precislo = 0x2000000, ///< Is this Varnode the low part of a double precision value
|
||||||
precishi = 0x8000000, ///< Is this Varnode the high part of a double precision value
|
precishi = 0x4000000, ///< Is this Varnode the high part of a double precision value
|
||||||
indirectstorage = 0x10000000, ///< Is this Varnode storing a pointer to the actual symbol
|
indirectstorage = 0x8000000, ///< Is this Varnode storing a pointer to the actual symbol
|
||||||
hiddenretparm = 0x20000000, ///< Does this varnode point to the return value storage location
|
hiddenretparm = 0x10000000, ///< Does this varnode point to the return value storage location
|
||||||
incidental_copy = 0x40000000, ///< Do copies of this varnode happen as a side-effect
|
incidental_copy = 0x20000000 ///< Do copies of this varnode happen as a side-effect
|
||||||
auto_live = 0x80000000 ///< Is this varnode automatically considered live, never removed as dead-code
|
|
||||||
};
|
};
|
||||||
/// Additional boolean properties on a Varnode
|
/// Additional boolean properties on a Varnode
|
||||||
enum addl_flags {
|
enum addl_flags {
|
||||||
|
@ -117,7 +114,9 @@ public:
|
||||||
ptrflow = 0x20, ///< If this varnode flows to or from a pointer
|
ptrflow = 0x20, ///< If this varnode flows to or from a pointer
|
||||||
unsignedprint = 0x40, ///< Constant that must be explicitly printed as unsigned
|
unsignedprint = 0x40, ///< Constant that must be explicitly printed as unsigned
|
||||||
stack_store = 0x80, ///< Created by an explicit STORE
|
stack_store = 0x80, ///< Created by an explicit STORE
|
||||||
locked_input = 0x100 ///< Input that exists even if its unused
|
locked_input = 0x100, ///< Input that exists even if its unused
|
||||||
|
spacebase_placeholder = 0x200 ///< This varnode is inserted artificially to track a register
|
||||||
|
///< value at a specific point in the code
|
||||||
};
|
};
|
||||||
private:
|
private:
|
||||||
mutable uint4 flags; ///< The collection of boolean attributes for this Varnode
|
mutable uint4 flags; ///< The collection of boolean attributes for this Varnode
|
||||||
|
@ -229,14 +228,14 @@ public:
|
||||||
/// Are all Varnodes at this storage location components of the same high-level variable?
|
/// Are all Varnodes at this storage location components of the same high-level variable?
|
||||||
bool isAddrTied(void) const { return ((flags&(Varnode::addrtied|Varnode::insert))==(Varnode::addrtied|Varnode::insert)); }
|
bool isAddrTied(void) const { return ((flags&(Varnode::addrtied|Varnode::insert))==(Varnode::addrtied|Varnode::insert)); }
|
||||||
bool isAddrForce(void) const { return ((flags&Varnode::addrforce)!=0); } ///< Is \b this value forced into a particular storage location?
|
bool isAddrForce(void) const { return ((flags&Varnode::addrforce)!=0); } ///< Is \b this value forced into a particular storage location?
|
||||||
bool isAutoLive(void) const { return ((flags&Varnode::auto_live)!=0); } ///< Is \b this varnode exempt from dead-code removal?
|
bool isAutoLive(void) const { return ((flags&Varnode::addrforce)!=0); } ///< Is \b this varnode exempt from dead-code removal?
|
||||||
bool isMapped(void) const { return ((flags&Varnode::mapped)!=0); } ///< Is there or should be formal symbol information associated with \b this?
|
bool isMapped(void) const { return ((flags&Varnode::mapped)!=0); } ///< Is there or should be formal symbol information associated with \b this?
|
||||||
bool isUnaffected(void) const { return ((flags&Varnode::unaffected)!=0); } ///< Is \b this a value that is supposed to be preserved across the function?
|
bool isUnaffected(void) const { return ((flags&Varnode::unaffected)!=0); } ///< Is \b this a value that is supposed to be preserved across the function?
|
||||||
bool isSpacebase(void) const { return ((flags&Varnode::spacebase)!=0); } ///< Is this location used to store the base point for a virtual address space?
|
bool isSpacebase(void) const { return ((flags&Varnode::spacebase)!=0); } ///< Is this location used to store the base point for a virtual address space?
|
||||||
bool isReturnAddress(void) const { return ((flags&Varnode::return_address)!=0); } ///< Is this storage for a calls return address?
|
bool isReturnAddress(void) const { return ((flags&Varnode::return_address)!=0); } ///< Is this storage for a calls return address?
|
||||||
bool isPtrCheck(void) const { return ((addlflags&Varnode::ptrcheck)!=0); } ///< Has \b this been checked as a constant pointer to a mapped symbol?
|
bool isPtrCheck(void) const { return ((addlflags&Varnode::ptrcheck)!=0); } ///< Has \b this been checked as a constant pointer to a mapped symbol?
|
||||||
bool isPtrFlow(void) const { return ((addlflags&Varnode::ptrflow)!=0); } ///< Does this varnode flow to or from a known pointer
|
bool isPtrFlow(void) const { return ((addlflags&Varnode::ptrflow)!=0); } ///< Does this varnode flow to or from a known pointer
|
||||||
bool isSpacebasePlaceholder(void) const { return ((flags&Varnode::spacebase_placeholder)!=0); } ///< Is \b this used specifically to track stackpointer values?
|
bool isSpacebasePlaceholder(void) const { return ((addlflags&Varnode::spacebase_placeholder)!=0); } ///< Is \b this used specifically to track stackpointer values?
|
||||||
bool hasNoLocalAlias(void) const { return ((flags&Varnode::nolocalalias)!=0); } ///< Are there (not) any local pointers that might affect \b this?
|
bool hasNoLocalAlias(void) const { return ((flags&Varnode::nolocalalias)!=0); } ///< Are there (not) any local pointers that might affect \b this?
|
||||||
bool isMark(void) const { return ((flags&Varnode::mark)!=0); } ///< Has \b this been visited by the current algorithm?
|
bool isMark(void) const { return ((flags&Varnode::mark)!=0); } ///< Has \b this been visited by the current algorithm?
|
||||||
bool isActiveHeritage(void) const { return ((addlflags&Varnode::activeheritage)!=0); } ///< Is \b this currently being traced by the Heritage algorithm?
|
bool isActiveHeritage(void) const { return ((addlflags&Varnode::activeheritage)!=0); } ///< Is \b this currently being traced by the Heritage algorithm?
|
||||||
|
@ -277,10 +276,8 @@ public:
|
||||||
void clearMark(void) const { flags &= ~Varnode::mark; } ///< Clear the mark on this Varnode
|
void clearMark(void) const { flags &= ~Varnode::mark; } ///< Clear the mark on this Varnode
|
||||||
void setDirectWrite(void) { flags |= Varnode::directwrite; } ///< Mark \b this as directly affected by a legal input
|
void setDirectWrite(void) { flags |= Varnode::directwrite; } ///< Mark \b this as directly affected by a legal input
|
||||||
void clearDirectWrite(void) { flags &= ~Varnode::directwrite; } ///< Mark \b this as not directly affected by a legal input
|
void clearDirectWrite(void) { flags &= ~Varnode::directwrite; } ///< Mark \b this as not directly affected by a legal input
|
||||||
void setAddrForce(void) { setFlags(Varnode::addrforce | Varnode::auto_live); } ///< Mark as forcing a value into \b this particular storage location
|
void setAddrForce(void) { setFlags(Varnode::addrforce); } ///< Mark as forcing a value into \b this particular storage location
|
||||||
void clearAddrForce(void) { clearFlags(Varnode::addrforce | Varnode::auto_live); } ///< Clear the forcing attribute
|
void clearAddrForce(void) { clearFlags(Varnode::addrforce); } ///< Clear the forcing attribute
|
||||||
void setAutoLive(void) { flags |= Varnode::auto_live; } ///< Mark varnode as exempt from dead-code removal
|
|
||||||
void clearAutoLive(void) { flags &= ~Varnode::auto_live; } ///< Clear exemption for dead-code removal
|
|
||||||
void setImplied(void) { setFlags(Varnode::implied); } ///< Mark \b this as an \e implied variable in the final C source
|
void setImplied(void) { setFlags(Varnode::implied); } ///< Mark \b this as an \e implied variable in the final C source
|
||||||
void clearImplied(void) { clearFlags(Varnode::implied); } ///< Clear the \e implied mark on this Varnode
|
void clearImplied(void) { clearFlags(Varnode::implied); } ///< Clear the \e implied mark on this Varnode
|
||||||
void setExplicit(void) { setFlags(Varnode::explict); } ///< Mark \b this as an \e explicit variable in the final C source
|
void setExplicit(void) { setFlags(Varnode::explict); } ///< Mark \b this as an \e explicit variable in the final C source
|
||||||
|
@ -291,8 +288,8 @@ public:
|
||||||
void clearPtrCheck(void) { addlflags &= ~Varnode::ptrcheck; } ///< Clear the pointer check mark on this Varnode
|
void clearPtrCheck(void) { addlflags &= ~Varnode::ptrcheck; } ///< Clear the pointer check mark on this Varnode
|
||||||
void setPtrFlow(void) { addlflags |= Varnode::ptrflow; } ///< Set \b this as flowing to or from pointer
|
void setPtrFlow(void) { addlflags |= Varnode::ptrflow; } ///< Set \b this as flowing to or from pointer
|
||||||
void clearPtrFlow(void) { addlflags &= ~Varnode::ptrflow; } ///< Indicate that this varnode is not flowing to or from pointer
|
void clearPtrFlow(void) { addlflags &= ~Varnode::ptrflow; } ///< Indicate that this varnode is not flowing to or from pointer
|
||||||
void setSpacebasePlaceholder(void) { setFlags(Varnode::spacebase_placeholder); } ///< Mark \b this as a special Varnode for tracking stackpointer values
|
void setSpacebasePlaceholder(void) { addlflags |= Varnode::spacebase_placeholder; } ///< Mark \b this as a special Varnode for tracking stackpointer values
|
||||||
void clearSpacebasePlaceholder(void) { clearFlags(Varnode::spacebase_placeholder); } ///< Clear the stackpointer tracking mark
|
void clearSpacebasePlaceholder(void) { addlflags &= ~Varnode::spacebase_placeholder; } ///< Clear the stackpointer tracking mark
|
||||||
void setPrecisLo(void) { setFlags(Varnode::precislo); } ///< Mark \b this as the low portion of a double precision value
|
void setPrecisLo(void) { setFlags(Varnode::precislo); } ///< Mark \b this as the low portion of a double precision value
|
||||||
void clearPrecisLo(void) { clearFlags(Varnode::precislo); } ///< Clear the mark indicating a double precision portion
|
void clearPrecisLo(void) { clearFlags(Varnode::precislo); } ///< Clear the mark indicating a double precision portion
|
||||||
void setPrecisHi(void) { setFlags(Varnode::precishi); } ///< Mark \b this as the high portion of a double precision value
|
void setPrecisHi(void) { setFlags(Varnode::precishi); } ///< Mark \b this as the high portion of a double precision value
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue