mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 18:29:37 +02:00
More adjustments to boolean propagation
This commit is contained in:
parent
99367e1139
commit
e6f09b141b
4 changed files with 33 additions and 3 deletions
|
@ -4393,7 +4393,7 @@ void PropagationState::step(void)
|
||||||
inslot = op->getSlot(vn);
|
inslot = op->getSlot(vn);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (op == vn->getDef())
|
if (inslot == -1)
|
||||||
op = (PcodeOp *)0;
|
op = (PcodeOp *)0;
|
||||||
else
|
else
|
||||||
op = vn->getDef();
|
op = vn->getDef();
|
||||||
|
|
|
@ -291,6 +291,15 @@ bool SubvariableFlow::tryReturnPull(PcodeOp *op,ReplaceVarnode *rvn,int4 slot)
|
||||||
return false;
|
return false;
|
||||||
if (inworklist)
|
if (inworklist)
|
||||||
worklist.push_back(rep);
|
worklist.push_back(rep);
|
||||||
|
else if (retvn->isConstant() && retop != op) {
|
||||||
|
// Trace won't revisit this RETURN, so we need to generate patch now
|
||||||
|
patchlist.push_back(PatchRecord());
|
||||||
|
patchlist.back().type = 2;
|
||||||
|
patchlist.back().pullop = retop;
|
||||||
|
patchlist.back().in1 = rep;
|
||||||
|
patchlist.back().slot = slot;
|
||||||
|
pullcount += 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
returnsTraversed = true;
|
returnsTraversed = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,6 +115,7 @@ public:
|
||||||
virtual Datatype *clone(void) const=0; ///< Clone the data-type
|
virtual Datatype *clone(void) const=0; ///< Clone the data-type
|
||||||
virtual void saveXml(ostream &s) const; ///< Serialize the data-type to XML
|
virtual void saveXml(ostream &s) const; ///< Serialize the data-type to XML
|
||||||
int4 typeOrder(const Datatype &op) const { if (this==&op) return 0; return compare(op,10); } ///< Order this with -op- datatype
|
int4 typeOrder(const Datatype &op) const { if (this==&op) return 0; return compare(op,10); } ///< Order this with -op- datatype
|
||||||
|
int4 typeOrderBool(const Datatype &op) const; ///< Order \b this with -op-, treating \e bool data-type as special
|
||||||
void saveXmlBasic(ostream &s) const; ///< Save basic data-type properties
|
void saveXmlBasic(ostream &s) const; ///< Save basic data-type properties
|
||||||
void saveXmlRef(ostream &s) const; ///< Write an XML reference of \b this to stream
|
void saveXmlRef(ostream &s) const; ///< Write an XML reference of \b this to stream
|
||||||
};
|
};
|
||||||
|
@ -447,4 +448,19 @@ public:
|
||||||
void cacheCoreTypes(void); ///< Cache common types
|
void cacheCoreTypes(void); ///< Cache common types
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Order data-types, with special handling of the \e bool data-type. Data-types are compared
|
||||||
|
/// using the normal ordering, but \e bool is ordered after all other data-types. A return value
|
||||||
|
/// of 0 indicates the data-types are the same, -1 indicates that \b this is prefered (ordered earlier),
|
||||||
|
/// and 1 indicates \b this is ordered later.
|
||||||
|
/// \param op is the other data-type to compare with \b this
|
||||||
|
/// \return -1, 0, or 1
|
||||||
|
inline int4 Datatype::typeOrderBool(const Datatype &op) const
|
||||||
|
|
||||||
|
{
|
||||||
|
if (this == &op) return 0;
|
||||||
|
if (metatype == TYPE_BOOL) return 1; // Never prefer bool over other data-types
|
||||||
|
if (op.metatype == TYPE_BOOL) return -1;
|
||||||
|
return compare(op,10);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -112,7 +112,12 @@ void HighVariable::updateFlags(void) const
|
||||||
highflags &= ~flagsdirty; // Clear the dirty flag
|
highflags &= ~flagsdirty; // Clear the dirty flag
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Using Datatype::typeOrder, find the member Varnode with the most specific data-type.
|
/// Find the member Varnode with the most \e specialized data-type, handling \e bool specially.
|
||||||
|
/// Boolean data-types are \e specialized in the data-type lattice, but not all byte values are boolean values.
|
||||||
|
/// Within the Varnode/PcodeOp tree, the \e bool data-type can only propagate to a Varnode if it is verified to
|
||||||
|
/// only take the boolean values 0 and 1. Since the data-type representative represents the type of all
|
||||||
|
/// instances, if any instance is not boolean, then the HighVariable cannot be boolean, even though \e bool
|
||||||
|
/// is more specialized. This method uses Datatype::typeOrderBool() to implement the special handling.
|
||||||
/// \return the representative member
|
/// \return the representative member
|
||||||
Varnode *HighVariable::getTypeRepresentative(void) const
|
Varnode *HighVariable::getTypeRepresentative(void) const
|
||||||
|
|
||||||
|
@ -129,7 +134,7 @@ Varnode *HighVariable::getTypeRepresentative(void) const
|
||||||
if (vn->isTypeLock())
|
if (vn->isTypeLock())
|
||||||
rep = vn;
|
rep = vn;
|
||||||
}
|
}
|
||||||
else if (0>vn->getType()->typeOrder(*rep->getType()))
|
else if (0>vn->getType()->typeOrderBool(*rep->getType()))
|
||||||
rep = vn;
|
rep = vn;
|
||||||
}
|
}
|
||||||
return rep;
|
return rep;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue