GP-2859 Clearing symbols from HighVariable must set symboldirty

This commit is contained in:
caheckman 2022-11-17 18:35:48 -05:00
parent 6ade149f4a
commit 9424fdf208
6 changed files with 25 additions and 21 deletions

View file

@ -408,7 +408,6 @@ public:
void clearDeadVarnodes(void); ///< Delete any dead Varnodes void clearDeadVarnodes(void); ///< Delete any dead Varnodes
void calcNZMask(void); ///< Calculate \e non-zero masks for all Varnodes void calcNZMask(void); ///< Calculate \e non-zero masks for all Varnodes
void clearDeadOps(void) { obank.destroyDead(); } ///< Delete any dead PcodeOps void clearDeadOps(void) { obank.destroyDead(); } ///< Delete any dead PcodeOps
void clearSymbolLinks(HighVariable *high); ///< Clear Symbols attached to Varnodes in the given HighVariable
void remapVarnode(Varnode *vn,Symbol *sym,const Address &usepoint); void remapVarnode(Varnode *vn,Symbol *sym,const Address &usepoint);
void remapDynamicVarnode(Varnode *vn,Symbol *sym,const Address &usepoint,uint8 hash); void remapDynamicVarnode(Varnode *vn,Symbol *sym,const Address &usepoint,uint8 hash);
Symbol *linkSymbol(Varnode *vn); ///< Find or create Symbol associated with given Varnode Symbol *linkSymbol(Varnode *vn); ///< Find or create Symbol associated with given Varnode

View file

@ -1002,18 +1002,6 @@ bool Funcdata::syncVarnodesWithSymbol(VarnodeLocSet::const_iterator &iter,uint4
return updateoccurred; return updateoccurred;
} }
/// For each instance Varnode, remove any SymbolEntry reference and associated properties.
/// \param high is the given HighVariable to clear
void Funcdata::clearSymbolLinks(HighVariable *high)
{
for(int4 i=0;i<high->numInstances();++i) {
Varnode *vn = high->getInstance(i);
vn->mapentry = (SymbolEntry *)0;
vn->clearFlags(Varnode::namelock | Varnode::typelock | Varnode::mapped);
}
}
/// \brief Remap a Symbol to a given Varnode using a static mapping /// \brief Remap a Symbol to a given Varnode using a static mapping
/// ///
/// Any previous links between the Symbol, the Varnode, and the associate HighVariable are /// Any previous links between the Symbol, the Varnode, and the associate HighVariable are
@ -1024,7 +1012,7 @@ void Funcdata::clearSymbolLinks(HighVariable *high)
void Funcdata::remapVarnode(Varnode *vn,Symbol *sym,const Address &usepoint) void Funcdata::remapVarnode(Varnode *vn,Symbol *sym,const Address &usepoint)
{ {
clearSymbolLinks(vn->getHigh()); vn->clearSymbolLinks();
SymbolEntry *entry = localmap->remapSymbol(sym, vn->getAddr(), usepoint); SymbolEntry *entry = localmap->remapSymbol(sym, vn->getAddr(), usepoint);
vn->setSymbolEntry(entry); vn->setSymbolEntry(entry);
} }
@ -1040,7 +1028,7 @@ void Funcdata::remapVarnode(Varnode *vn,Symbol *sym,const Address &usepoint)
void Funcdata::remapDynamicVarnode(Varnode *vn,Symbol *sym,const Address &usepoint,uint8 hash) void Funcdata::remapDynamicVarnode(Varnode *vn,Symbol *sym,const Address &usepoint,uint8 hash)
{ {
clearSymbolLinks(vn->getHigh()); vn->clearSymbolLinks();
SymbolEntry *entry = localmap->remapSymbolDynamic(sym, hash, usepoint); SymbolEntry *entry = localmap->remapSymbolDynamic(sym, hash, usepoint);
vn->setSymbolEntry(entry); vn->setSymbolEntry(entry);
} }

View file

@ -175,15 +175,14 @@ void HighVariable::updateSymbol(void) const
highflags &= ~((uint4)symboldirty); highflags &= ~((uint4)symboldirty);
vector<Varnode *>::const_iterator iter; vector<Varnode *>::const_iterator iter;
symbol = (Symbol *)0; symbol = (Symbol *)0;
Varnode *vn = (Varnode *)0;
for(iter=inst.begin();iter!=inst.end();++iter) { for(iter=inst.begin();iter!=inst.end();++iter) {
Varnode *tmpvn = *iter; Varnode *vn = *iter;
if (tmpvn->getSymbolEntry() != (SymbolEntry *)0) if (vn->getSymbolEntry() != (SymbolEntry *)0) {
vn = tmpvn;
}
if (vn != (Varnode *)0)
setSymbol(vn); setSymbol(vn);
return;
}
}
} }
/// Compare two Varnode objects based just on their storage address /// Compare two Varnode objects based just on their storage address

View file

@ -88,6 +88,7 @@ private:
void flagsDirty(void) const { highflags |= flagsdirty | namerepdirty; } ///< Mark the boolean properties as \e dirty void flagsDirty(void) const { highflags |= flagsdirty | namerepdirty; } ///< Mark the boolean properties as \e dirty
void coverDirty(void) const { highflags |= coverdirty; } ///< Mark the cover as \e dirty void coverDirty(void) const { highflags |= coverdirty; } ///< Mark the cover as \e dirty
void typeDirty(void) const { highflags |= typedirty; } ///< Mark the data-type as \e dirty void typeDirty(void) const { highflags |= typedirty; } ///< Mark the data-type as \e dirty
void symbolDirty(void) const { highflags |= symboldirty; } ///< Mark the symbol as \e dirty
void setUnmerged(void) const { highflags |= unmerged; } ///< Mark \b this as having merge problems void setUnmerged(void) const { highflags |= unmerged; } ///< Mark \b this as having merge problems
public: public:
HighVariable(Varnode *vn); ///< Construct a HighVariable with a single member Varnode HighVariable(Varnode *vn); ///< Construct a HighVariable with a single member Varnode

View file

@ -352,6 +352,22 @@ void Varnode::clearFlags(uint4 fl) const
} }
} }
/// For \b this Varnode and any others attached to the same HighVariable,
/// remove any SymbolEntry reference and associated properties.
void Varnode::clearSymbolLinks(void)
{
bool foundEntry = false;
for(int4 i=0;i<high->numInstances();++i) {
Varnode *vn = high->getInstance(i);
foundEntry = foundEntry || (vn->mapentry != (SymbolEntry *)0);
vn->mapentry = (SymbolEntry *)0;
vn->clearFlags(Varnode::namelock | Varnode::typelock | Varnode::mapped);
}
if (foundEntry)
high->symbolDirty();
}
/// Directly change the defining PcodeOp and set appropriate dirty bits /// Directly change the defining PcodeOp and set appropriate dirty bits
/// \param op is the pointer to the new PcodeOp, which can be \b null /// \param op is the pointer to the new PcodeOp, which can be \b null
void Varnode::setDef(PcodeOp *op) void Varnode::setDef(PcodeOp *op)

View file

@ -159,6 +159,7 @@ private:
void clearCover(void) const; ///< Turn off any coverage information void clearCover(void) const; ///< Turn off any coverage information
void setFlags(uint4 fl) const; ///< Internal method for setting boolean attributes void setFlags(uint4 fl) const; ///< Internal method for setting boolean attributes
void clearFlags(uint4 fl) const; ///< Internal method for clearing boolean attributes void clearFlags(uint4 fl) const; ///< Internal method for clearing boolean attributes
void clearSymbolLinks(void); ///< Clear any Symbol attached to \b this Varnode
void setUnaffected(void) { setFlags(Varnode::unaffected); } ///< Mark Varnode as \e unaffected void setUnaffected(void) { setFlags(Varnode::unaffected); } ///< Mark Varnode as \e unaffected
// These functions should be only private things used by VarnodeBank // These functions should be only private things used by VarnodeBank
void setInput(void) { setFlags(Varnode::input|Varnode::coverdirty); } ///< Mark Varnode as \e input void setInput(void) { setFlags(Varnode::input|Varnode::coverdirty); } ///< Mark Varnode as \e input