mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 18:29:37 +02:00
Basic multi-entry merge capability
This commit is contained in:
parent
76d0f12bd3
commit
b99772a784
8 changed files with 123 additions and 6 deletions
|
@ -102,6 +102,15 @@ bool Merge::mergeTestRequired(HighVariable *high_out,HighVariable *high_in)
|
|||
}
|
||||
else if (high_out->isExtraOut())
|
||||
return false;
|
||||
if (high_in->isMapped() && high_out->isMapped()) {
|
||||
Symbol *symbolIn = high_in->getSymbol();
|
||||
Symbol *symbolOut = high_out->getSymbol();
|
||||
if (symbolIn != (Symbol *)0 && symbolOut != (Symbol *)0) {
|
||||
if (symbolIn != symbolOut) return false; // Map to different symbols
|
||||
if (high_in->getSymbolOffset() != high_out->getSymbolOffset())
|
||||
return false; // Map to different parts of same symbol
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -151,9 +160,6 @@ bool Merge::mergeTestSpeculative(HighVariable *high_out,HighVariable *high_in)
|
|||
{
|
||||
if (!mergeTestAdjacent(high_out,high_in)) return false;
|
||||
|
||||
// Don't merge a mapped variable speculatively
|
||||
if (high_out->isMapped()) return false;
|
||||
if (high_in->isMapped()) return false;
|
||||
// Don't merge anything with a global speculatively
|
||||
if (high_out->isPersist()) return false;
|
||||
if (high_in->isPersist()) return false;
|
||||
|
@ -268,7 +274,7 @@ void Merge::mergeOpcode(OpCode opc)
|
|||
vn2 = op->getIn(j);
|
||||
if (!mergeTestBasic(vn2)) continue;
|
||||
if (mergeTestRequired(vn1->getHigh(),vn2->getHigh()))
|
||||
merge(vn1->getHigh(),vn2->getHigh(),false);
|
||||
merge(vn1->getHigh(),vn2->getHigh(),true); // Treat as speculative
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -798,6 +804,61 @@ void Merge::mergeMarker(void)
|
|||
}
|
||||
}
|
||||
|
||||
/// \brief Merge together Varnodes mapped to SymbolEntrys from the same Symbol
|
||||
///
|
||||
/// Symbols that have more than one SymbolEntry may attach to more than one Varnode.
|
||||
/// These Varnodes need to be merged to properly represent a single variable.
|
||||
void Merge::mergeMultiEntry(void)
|
||||
|
||||
{
|
||||
SymbolNameTree::const_iterator iter = data.getScopeLocal()->beginMultiEntry();
|
||||
SymbolNameTree::const_iterator enditer = data.getScopeLocal()->endMultiEntry();
|
||||
for(;iter!=enditer;++iter) {
|
||||
vector<Varnode *> mergeList;
|
||||
Symbol *symbol = *iter;
|
||||
int4 numEntries = symbol->numEntries();
|
||||
int4 mergeCount = 0;
|
||||
int4 skipCount = 0;
|
||||
int4 conflictCount = 0;
|
||||
for(int4 i=0;i<numEntries;++i) {
|
||||
int4 prevSize = mergeList.size();
|
||||
data.findLinkedVarnodes(symbol->getMapEntry(i), mergeList);
|
||||
if (mergeList.size() == prevSize)
|
||||
skipCount += 1; // Did not discover any Varnodes corresponding to a particular SymbolEntry
|
||||
}
|
||||
if (mergeList.empty()) continue;
|
||||
HighVariable *high = mergeList[0]->getHigh();
|
||||
Datatype *ct = high->getType();
|
||||
updateHigh(high);
|
||||
for(int4 i=0;i<mergeList.size();++i) {
|
||||
HighVariable *newHigh = mergeList[i]->getHigh();
|
||||
if (newHigh == high) continue; // Varnodes already merged
|
||||
updateHigh(newHigh);
|
||||
if (!mergeTestRequired(high, newHigh)) {
|
||||
conflictCount += 1;
|
||||
continue;
|
||||
}
|
||||
if (!merge(high,newHigh,false)) { // Attempt the merge
|
||||
conflictCount += 1;
|
||||
continue;
|
||||
}
|
||||
mergeCount += 1;
|
||||
}
|
||||
if (skipCount != 0 || conflictCount !=0) {
|
||||
ostringstream s;
|
||||
s << "Unable to";
|
||||
if (mergeCount != 0)
|
||||
s << " fully";
|
||||
s << " merge symbol: " << symbol->getName();
|
||||
if (skipCount > 0)
|
||||
s << " -- Some instance varnodes not found.";
|
||||
if (conflictCount > 0)
|
||||
s << " -- Some merges are forbidden";
|
||||
data.warningHeader(s.str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// \brief Speculatively merge Varnodes that are input/output to the same p-code op
|
||||
///
|
||||
/// If a single p-code op has an input and output HighVariable that share the same data-type,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue