GP-3783 Check for same VariableGroup before assigning partial Symbol

This commit is contained in:
caheckman 2023-08-25 15:33:47 +00:00
parent cb3d780fb8
commit 17eb87ebf7
3 changed files with 18 additions and 6 deletions

View file

@ -285,7 +285,8 @@ bool SplitVarnode::findWholeSplitToPieces(void)
} }
if (subhi->code() != CPUI_SUBPIECE) return false; if (subhi->code() != CPUI_SUBPIECE) return false;
if (subhi->getIn(1)->getOffset() != wholesize - hi->getSize()) return false; if (subhi->getIn(1)->getOffset() != wholesize - hi->getSize()) return false;
whole = subhi->getIn(0); Varnode *putativeWhole = subhi->getIn(0);
if (putativeWhole->getSize() != wholesize) return false;
if (!lo->isWritten()) return false; if (!lo->isWritten()) return false;
PcodeOp *sublo = lo->getDef(); PcodeOp *sublo = lo->getDef();
if (sublo->code() == CPUI_COPY) { // Go thru one level of copy, if the piece is addrtied if (sublo->code() == CPUI_COPY) { // Go thru one level of copy, if the piece is addrtied
@ -294,14 +295,11 @@ bool SplitVarnode::findWholeSplitToPieces(void)
sublo = otherlo->getDef(); sublo = otherlo->getDef();
} }
if (sublo->code() != CPUI_SUBPIECE) return false; if (sublo->code() != CPUI_SUBPIECE) return false;
Varnode *res = sublo->getIn(0); if (putativeWhole != sublo->getIn(0))
if (whole == (Varnode*)0)
whole = res;
else if (whole != res)
return false; // Doesn't match between pieces return false; // Doesn't match between pieces
if (sublo->getIn(1)->getOffset() != 0) if (sublo->getIn(1)->getOffset() != 0)
return false; return false;
if (whole == (Varnode*)0) return false; whole = putativeWhole;
} }
if (whole->isWritten()) { if (whole->isWritten()) {

View file

@ -1022,6 +1022,8 @@ void Funcdata::linkProtoPartial(Varnode *vn)
if (rootVn == vn) return; if (rootVn == vn) return;
HighVariable *rootHigh = rootVn->getHigh(); HighVariable *rootHigh = rootVn->getHigh();
if (!rootHigh->isSameGroup(high))
return;
Varnode *nameRep = rootHigh->getNameRepresentative(); Varnode *nameRep = rootHigh->getNameRepresentative();
Symbol *sym = linkSymbol(nameRep); Symbol *sym = linkSymbol(nameRep);
if (sym == (Symbol *)0) return; if (sym == (Symbol *)0) return;

View file

@ -207,6 +207,7 @@ public:
void clearMark(void) const { flags &= ~Varnode::mark; } ///< Clear the mark on this variable void clearMark(void) const { flags &= ~Varnode::mark; } ///< Clear the mark on this variable
bool isMark(void) const { return ((flags&Varnode::mark)!=0); } ///< Return \b true if \b this is marked bool isMark(void) const { return ((flags&Varnode::mark)!=0); } ///< Return \b true if \b this is marked
bool isUnmerged(void) const { return ((highflags&unmerged)!=0); } ///< Return \b true if \b this has merge problems bool isUnmerged(void) const { return ((highflags&unmerged)!=0); } ///< Return \b true if \b this has merge problems
bool isSameGroup(const HighVariable *op2) const; ///< Is \b this part of the same VariableGroup as \b op2
/// \brief Determine if \b this HighVariable has an associated cover. /// \brief Determine if \b this HighVariable has an associated cover.
/// ///
@ -294,5 +295,16 @@ inline const Cover &HighVariable::getCover(void) const
return piece->getCover(); return piece->getCover();
} }
/// Test if the two HighVariables should be pieces of the same symbol.
/// \param op2 is the other HighVariable to compare with \b this
/// \return \b true if they share the same underlying VariableGroup
inline bool HighVariable::isSameGroup(const HighVariable *op2) const
{
if (piece == (VariablePiece *)0 || op2->piece == (VariablePiece *)0)
return false;
return piece->getGroup() == op2->piece->getGroup();
}
} // End namespace ghidra } // End namespace ghidra
#endif #endif