GP-3014 - Add deduping to DynamicHash gatherFirstLevelVars

This commit is contained in:
caheckman 2023-01-12 19:32:03 -05:00
parent f1dc157f04
commit 4b2a78b1fb
3 changed files with 46 additions and 9 deletions

View file

@ -364,7 +364,7 @@ void DynamicHash::pieceTogetherHash(const Varnode *root,uint4 method)
hash <<= 4;
hash |= method; // 4-bits
hash <<= 7;
hash |= (uint8)op->code(); // 7-bits
hash |= (uint8)transtable[op->code()]; // 7-bits
hash <<= 5;
hash |= (uint8)(slot & 0x1f); // 5-bits
@ -607,6 +607,25 @@ PcodeOp *DynamicHash::findOp(const Funcdata *fd,const Address &addr,uint8 h)
return oplist2[pos];
}
/// Otherwise preserve the order of the list.
/// \param varlist is the given list of Varnodes to check
void DynamicHash::dedupVarnodes(vector<Varnode *> &varlist)
{
if (varlist.size() < 2) return;
vector<Varnode *> resList;
for(int4 i=0;i<varlist.size();++i) {
Varnode *vn = varlist[i];
if (!vn->isMark()) {
vn->setMark();
resList.push_back(vn);
}
}
for(int4 i=0;i<resList.size();++i)
resList[i]->clearMark();
varlist.swap(resList);
}
/// \brief Get the Varnodes immediately attached to PcodeOps at the given address
///
/// Varnodes can be either inputs or outputs to the PcodeOps. The op-code, slot, and
@ -619,7 +638,7 @@ PcodeOp *DynamicHash::findOp(const Funcdata *fd,const Address &addr,uint8 h)
void DynamicHash::gatherFirstLevelVars(vector<Varnode *> &varlist,const Funcdata *fd,const Address &addr,uint8 h)
{
OpCode opc = getOpCodeFromHash(h);
uint4 opcVal = getOpCodeFromHash(h);
int4 slot = getSlotFromHash(h);
bool isnotattached = getIsNotAttached(h);
PcodeOpTree::const_iterator iter = fd->beginOp(addr);
@ -629,7 +648,7 @@ void DynamicHash::gatherFirstLevelVars(vector<Varnode *> &varlist,const Funcdata
PcodeOp *op = (*iter).second;
++iter;
if (op->isDead()) continue;
if (op->code() != opc) continue;
if (transtable[op->code()] != opcVal) continue;
if (slot <0) {
Varnode *vn = op->getOut();
if (vn != (Varnode *)0) {
@ -655,6 +674,7 @@ void DynamicHash::gatherFirstLevelVars(vector<Varnode *> &varlist,const Funcdata
varlist.push_back(vn);
}
}
dedupVarnodes(varlist);
}
/// \brief Place all PcodeOps at the given address in the provided container
@ -697,11 +717,11 @@ uint4 DynamicHash::getMethodFromHash(uint8 h)
/// The hash encodes the op-code of the p-code op attached to the root Varnode
/// \param h is the hash value
/// \return the op-code
OpCode DynamicHash::getOpCodeFromHash(uint8 h)
/// \return the op-code as an integer
uint4 DynamicHash::getOpCodeFromHash(uint8 h)
{
return (OpCode)((h>>37)&0x7f);
return (h>>37)&0x7f;
}
/// The hash encodes the position of the root Varnode within the list of hash collisions