mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 18:29:37 +02:00
Prevent Symbol storage conflicts
This commit is contained in:
parent
4f63568bdb
commit
2ea73a65a0
2 changed files with 42 additions and 2 deletions
|
@ -87,6 +87,7 @@ class Funcdata {
|
||||||
// Low level Varnode functions
|
// Low level Varnode functions
|
||||||
void setVarnodeProperties(Varnode *vn) const; ///< Look-up boolean properties and data-type information
|
void setVarnodeProperties(Varnode *vn) const; ///< Look-up boolean properties and data-type information
|
||||||
HighVariable *assignHigh(Varnode *vn); ///< Assign a new HighVariable to a Varnode
|
HighVariable *assignHigh(Varnode *vn); ///< Assign a new HighVariable to a Varnode
|
||||||
|
Symbol *handleSymbolConflict(SymbolEntry *entry,Varnode *vn); ///< Handle two variables with matching storage
|
||||||
bool syncVarnodesWithSymbol(VarnodeLocSet::const_iterator &iter,uint4 flags,Datatype *ct);
|
bool syncVarnodesWithSymbol(VarnodeLocSet::const_iterator &iter,uint4 flags,Datatype *ct);
|
||||||
bool descend2Undef(Varnode *vn); ///< Transform all reads of the given Varnode to a special \b undefined constant
|
bool descend2Undef(Varnode *vn); ///< Transform all reads of the given Varnode to a special \b undefined constant
|
||||||
|
|
||||||
|
|
|
@ -866,6 +866,46 @@ bool Funcdata::syncVarnodesWithSymbols(const ScopeLocal *lm,bool typesyes)
|
||||||
return updateoccurred;
|
return updateoccurred;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A Varnode overlaps the given SymbolEntry. Make sure the Varnode is part of the variable
|
||||||
|
/// underlying the Symbol. If not, remap things so that the Varnode maps to a distinct Symbol.
|
||||||
|
/// In either case, attach the appropriate Symbol to the Varnode
|
||||||
|
/// \param entry is the given SymbolEntry
|
||||||
|
/// \param vn is the overlapping Varnode
|
||||||
|
/// \return the Symbol attached to the Varnode
|
||||||
|
Symbol *Funcdata::handleSymbolConflict(SymbolEntry *entry,Varnode *vn)
|
||||||
|
|
||||||
|
{
|
||||||
|
if (vn->isInput() || vn->isAddrTied() ||
|
||||||
|
vn->isPersist() || vn->isConstant() || entry->isDynamic()) {
|
||||||
|
vn->setSymbolEntry(entry);
|
||||||
|
return entry->getSymbol();
|
||||||
|
}
|
||||||
|
HighVariable *high = vn->getHigh();
|
||||||
|
Varnode *otherVn;
|
||||||
|
HighVariable *otherHigh = (HighVariable *)0;
|
||||||
|
// Look for a conflicting HighVariable
|
||||||
|
VarnodeLocSet::const_iterator iter = beginLoc(entry->getSize(),entry->getAddr());
|
||||||
|
while(iter != endLoc()) {
|
||||||
|
otherVn = *iter;
|
||||||
|
if (otherVn->getSize() != entry->getSize()) break;
|
||||||
|
if (otherVn->getAddr() != entry->getAddr()) break;
|
||||||
|
HighVariable *tmpHigh = otherVn->getHigh();
|
||||||
|
if (tmpHigh != high) {
|
||||||
|
otherHigh = tmpHigh;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++iter;
|
||||||
|
}
|
||||||
|
if (otherHigh == (HighVariable *)0) {
|
||||||
|
vn->setSymbolEntry(entry);
|
||||||
|
return entry->getSymbol();
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we reach here, we have a conflicting variable
|
||||||
|
buildDynamicSymbol(vn);
|
||||||
|
return vn->getSymbolEntry()->getSymbol();
|
||||||
|
}
|
||||||
|
|
||||||
/// \brief Update properties (and the data-type) for a set of Varnodes associated with one Symbol
|
/// \brief Update properties (and the data-type) for a set of Varnodes associated with one Symbol
|
||||||
///
|
///
|
||||||
/// The set of Varnodes with the same size and address all have their boolean properties
|
/// The set of Varnodes with the same size and address all have their boolean properties
|
||||||
|
@ -994,8 +1034,7 @@ Symbol *Funcdata::linkSymbol(Varnode *vn)
|
||||||
// Find any entry overlapping base address
|
// Find any entry overlapping base address
|
||||||
entry = localmap->queryProperties(vn->getAddr(), 1, usepoint, flags);
|
entry = localmap->queryProperties(vn->getAddr(), 1, usepoint, flags);
|
||||||
if (entry != (SymbolEntry *) 0) {
|
if (entry != (SymbolEntry *) 0) {
|
||||||
sym = entry->getSymbol();
|
sym = handleSymbolConflict(entry, vn);
|
||||||
vn->setSymbolEntry(entry);
|
|
||||||
}
|
}
|
||||||
else { // Must create a symbol entry
|
else { // Must create a symbol entry
|
||||||
if (!vn->isPersist()) { // Only create local symbol
|
if (!vn->isPersist()) { // Only create local symbol
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue