mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-03 09:49:23 +02:00
Merge remote-tracking branch 'origin/GP-5262_AutoKilledByCall'
This commit is contained in:
commit
2589aae3a4
5 changed files with 49 additions and 38 deletions
|
@ -586,6 +586,7 @@ ParamListStandard::ParamListStandard(const ParamListStandard &op2)
|
|||
spacebase = op2.spacebase;
|
||||
maxdelay = op2.maxdelay;
|
||||
thisbeforeret = op2.thisbeforeret;
|
||||
autoKilledByCall = op2.autoKilledByCall;
|
||||
resourceStart = op2.resourceStart;
|
||||
for(list<ModelRule>::const_iterator iter=op2.modelRules.begin();iter!=op2.modelRules.end();++iter) {
|
||||
modelRules.emplace_back(*iter,&op2);
|
||||
|
@ -1198,11 +1199,10 @@ void ParamListStandard::populateResolver(void)
|
|||
/// \param effectlist holds any passed back effect records
|
||||
/// \param groupid is the group to which the new ParamEntry is assigned
|
||||
/// \param normalstack is \b true if the parameters should be allocated from the front of the range
|
||||
/// \param autokill is \b true if parameters are automatically added to the killedbycall list
|
||||
/// \param splitFloat is \b true if floating-point parameters are in their own resource section
|
||||
/// \param grouped is \b true if the new ParamEntry is grouped with other entries
|
||||
void ParamListStandard::parsePentry(Decoder &decoder,vector<EffectRecord> &effectlist,
|
||||
int4 groupid,bool normalstack,bool autokill,bool splitFloat,bool grouped)
|
||||
int4 groupid,bool normalstack,bool splitFloat,bool grouped)
|
||||
{
|
||||
type_class lastClass = TYPECLASS_CLASS4;
|
||||
if (!entry.empty()) {
|
||||
|
@ -1221,7 +1221,7 @@ void ParamListStandard::parsePentry(Decoder &decoder,vector<EffectRecord> &effec
|
|||
AddrSpace *spc = entry.back().getSpace();
|
||||
if (spc->getType() == IPTR_SPACEBASE)
|
||||
spacebase = spc;
|
||||
else if (autokill) // If a register parameter AND we automatically generate killedbycall
|
||||
else if (autoKilledByCall) // If a register parameter AND we automatically generate killedbycall
|
||||
effectlist.push_back(EffectRecord(entry.back(),EffectRecord::killedbycall));
|
||||
|
||||
int4 maxgroup = entry.back().getAllGroups().back() + 1;
|
||||
|
@ -1236,17 +1236,16 @@ void ParamListStandard::parsePentry(Decoder &decoder,vector<EffectRecord> &effec
|
|||
/// \param effectlist holds any passed back effect records
|
||||
/// \param groupid is the group to which all ParamEntry elements are assigned
|
||||
/// \param normalstack is \b true if the parameters should be allocated from the front of the range
|
||||
/// \param autokill is \b true if parameters are automatically added to the killedbycall list
|
||||
/// \param splitFloat is \b true if floating-point parameters are in their own resource section
|
||||
void ParamListStandard::parseGroup(Decoder &decoder,vector<EffectRecord> &effectlist,
|
||||
int4 groupid,bool normalstack,bool autokill,bool splitFloat)
|
||||
int4 groupid,bool normalstack,bool splitFloat)
|
||||
{
|
||||
int4 basegroup = numgroup;
|
||||
ParamEntry *previous1 = (ParamEntry *)0;
|
||||
ParamEntry *previous2 = (ParamEntry *)0;
|
||||
uint4 elemId = decoder.openElement(ELEM_GROUP);
|
||||
while(decoder.peekElement() != 0) {
|
||||
parsePentry(decoder, effectlist, basegroup, normalstack, autokill, splitFloat, true);
|
||||
parsePentry(decoder, effectlist, basegroup, normalstack, splitFloat, true);
|
||||
ParamEntry &pentry( entry.back() );
|
||||
if (pentry.getSpace()->getType() == IPTR_JOIN)
|
||||
throw LowlevelError("<pentry> in the join space not allowed in <group> tag");
|
||||
|
@ -1434,8 +1433,8 @@ void ParamListStandard::decode(Decoder &decoder,vector<EffectRecord> &effectlist
|
|||
spacebase = (AddrSpace *)0;
|
||||
int4 pointermax = 0;
|
||||
thisbeforeret = false;
|
||||
autoKilledByCall = false;
|
||||
bool splitFloat = true; // True if we should split FLOAT entries into their own resource section
|
||||
bool autokilledbycall = false;
|
||||
uint4 elemId = decoder.openElement();
|
||||
for(;;) {
|
||||
uint4 attribId = decoder.getNextAttributeId();
|
||||
|
@ -1447,7 +1446,7 @@ void ParamListStandard::decode(Decoder &decoder,vector<EffectRecord> &effectlist
|
|||
thisbeforeret = decoder.readBool();
|
||||
}
|
||||
else if (attribId == ATTRIB_KILLEDBYCALL) {
|
||||
autokilledbycall = decoder.readBool();
|
||||
autoKilledByCall = decoder.readBool();
|
||||
}
|
||||
else if (attribId == ATTRIB_SEPARATEFLOAT) {
|
||||
splitFloat = decoder.readBool();
|
||||
|
@ -1457,10 +1456,10 @@ void ParamListStandard::decode(Decoder &decoder,vector<EffectRecord> &effectlist
|
|||
uint4 subId = decoder.peekElement();
|
||||
if (subId == 0) break;
|
||||
if (subId == ELEM_PENTRY) {
|
||||
parsePentry(decoder, effectlist, numgroup, normalstack, autokilledbycall, splitFloat, false);
|
||||
parsePentry(decoder, effectlist, numgroup, normalstack, splitFloat, false);
|
||||
}
|
||||
else if (subId == ELEM_GROUP) {
|
||||
parseGroup(decoder, effectlist, numgroup, normalstack, autokilledbycall, splitFloat);
|
||||
parseGroup(decoder, effectlist, numgroup, normalstack, splitFloat);
|
||||
}
|
||||
else if (subId == ELEM_RULE) {
|
||||
break;
|
||||
|
@ -1599,6 +1598,8 @@ void ParamListStandardOut::initialize(void)
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (useFillinFallback)
|
||||
autoKilledByCall = true; // Legacy behavior if there are no rules
|
||||
}
|
||||
|
||||
/// \brief Find the return value storage using the older \e fallback method
|
||||
|
@ -3778,8 +3779,8 @@ void FuncProto::setModel(ProtoModel *m)
|
|||
flags |= has_thisptr;
|
||||
if (m->isConstructor())
|
||||
flags |= is_constructor;
|
||||
if (m->isAutoKillByCall())
|
||||
flags |= auto_killbycall;
|
||||
if (m->isAutoKilledByCall())
|
||||
flags |= auto_killedbycall;
|
||||
model = m;
|
||||
}
|
||||
else {
|
||||
|
@ -4557,13 +4558,13 @@ void FuncProto::printRaw(const string &funcname,ostream &s) const
|
|||
/// This assumes the storage location has already been determined to be contained
|
||||
/// in standard return value location.
|
||||
/// \return \b true if the location should be considered killed by call
|
||||
bool FuncProto::isAutoKillByCall(void) const
|
||||
bool FuncProto::isAutoKilledByCall(void) const
|
||||
|
||||
{
|
||||
if ((flags & auto_killbycall)!=0)
|
||||
return true; // The ProtoModel always does killbycall
|
||||
if ((flags & auto_killedbycall)!=0)
|
||||
return true; // The ProtoModel always does killedbycall
|
||||
if (isOutputLocked())
|
||||
return true; // A locked output location is killbycall by definition
|
||||
return true; // A locked output location is killedbycall by definition
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -560,8 +560,8 @@ public:
|
|||
|
||||
/// \brief Return \b true if ParamEntry locations should automatically be considered killed by call
|
||||
///
|
||||
/// \return \b true if automatically assume killbycall
|
||||
virtual bool isAutoKillByCall(void) const=0;
|
||||
/// \return \b true if automatically assume \e killedbycall
|
||||
virtual bool isAutoKilledByCall(void) const=0;
|
||||
|
||||
/// \brief Restore the model from an \<input> or \<output> element in the stream
|
||||
///
|
||||
|
@ -587,6 +587,7 @@ protected:
|
|||
int4 numgroup; ///< Number of \e groups in this parameter convention
|
||||
int4 maxdelay; ///< Maximum heritage delay across all parameters
|
||||
bool thisbeforeret; ///< Does a \b this parameter come before a hidden return parameter
|
||||
bool autoKilledByCall; ///< Are storage locations in \b this list automatically \e killed \e by \e call
|
||||
vector<int4> resourceStart; ///< The starting group for each resource section
|
||||
list<ParamEntry> entry; ///< The ordered list of parameter entries
|
||||
vector<ParamEntryResolver *> resolverMap; ///< Map from space id to resolver
|
||||
|
@ -605,9 +606,9 @@ protected:
|
|||
void addResolverRange(AddrSpace *spc,uintb first,uintb last,ParamEntry *paramEntry,int4 position);
|
||||
void populateResolver(void); ///< Build the ParamEntry resolver maps
|
||||
void parsePentry(Decoder &decoder,vector<EffectRecord> &effectlist,
|
||||
int4 groupid,bool normalstack,bool autokill,bool splitFloat,bool grouped);
|
||||
int4 groupid,bool normalstack,bool splitFloat,bool grouped);
|
||||
void parseGroup(Decoder &decoder,vector<EffectRecord> &effectlist,
|
||||
int4 groupid,bool normalstack,bool autokill,bool splitFloat);
|
||||
int4 groupid,bool normalstack,bool splitFloat);
|
||||
public:
|
||||
ParamListStandard(void) {} ///< Construct for use with decode()
|
||||
ParamListStandard(const ParamListStandard &op2); ///< Copy constructor
|
||||
|
@ -634,7 +635,7 @@ public:
|
|||
virtual bool isThisBeforeRetPointer(void) const { return thisbeforeret; }
|
||||
virtual void getRangeList(AddrSpace *spc,RangeList &res) const;
|
||||
virtual int4 getMaxDelay(void) const { return maxdelay; }
|
||||
virtual bool isAutoKillByCall(void) const { return false; }
|
||||
virtual bool isAutoKilledByCall(void) const { return autoKilledByCall; }
|
||||
virtual void decode(Decoder &decoder,vector<EffectRecord> &effectlist,bool normalstack);
|
||||
virtual ParamList *clone(void) const;
|
||||
};
|
||||
|
@ -659,7 +660,6 @@ public:
|
|||
virtual void assignMap(const PrototypePieces &proto,TypeFactory &typefactory,vector<ParameterPieces> &res) const;
|
||||
virtual void fillinMap(ParamActive *active) const;
|
||||
virtual bool possibleParam(const Address &loc,int4 size) const;
|
||||
virtual bool isAutoKillByCall(void) const { return useFillinFallback; }
|
||||
virtual void decode(Decoder &decoder,vector<EffectRecord> &effectlist,bool normalstack);
|
||||
virtual ParamList *clone(void) const;
|
||||
};
|
||||
|
@ -995,7 +995,7 @@ public:
|
|||
/// \brief Does \b this model automatically consider potential output locations as killed by call
|
||||
///
|
||||
/// \return \b true if output locations should be considered killed by call
|
||||
bool isAutoKillByCall(void) const { return output->isAutoKillByCall(); }
|
||||
bool isAutoKilledByCall(void) const { return output->isAutoKilledByCall(); }
|
||||
|
||||
/// \brief Is \b this a merged prototype model
|
||||
///
|
||||
|
@ -1350,7 +1350,7 @@ class FuncProto {
|
|||
is_destructor = 0x400, ///< Function is an (object-oriented) destructor
|
||||
has_thisptr= 0x800, ///< Function is a method with a 'this' pointer as an argument
|
||||
is_override = 0x1000, ///< Set if \b this prototype is created to override a single call site
|
||||
auto_killbycall = 0x2000 ///< Potential output storage should always be considered \e killed \e by \e call
|
||||
auto_killedbycall = 0x2000 ///< Potential output storage should always be considered \e killed \e by \e call
|
||||
};
|
||||
ProtoModel *model; ///< Model of for \b this prototype
|
||||
ProtoStore *store; ///< Storage interface for parameters
|
||||
|
@ -1612,7 +1612,7 @@ public:
|
|||
/// \return the active set of flags for \b this prototype
|
||||
uint4 getComparableFlags(void) const { return (flags & (dotdotdot | is_constructor | is_destructor | has_thisptr )); }
|
||||
|
||||
bool isAutoKillByCall(void) const; ///< Is a potential output automatically considered \e killed \e by \e call
|
||||
bool isAutoKilledByCall(void) const; ///< Is a potential output automatically considered \e killed \e by \e call
|
||||
|
||||
void encode(Encoder &encoder) const;
|
||||
void decode(Decoder &decoder,Architecture *glb);
|
||||
|
|
|
@ -1470,7 +1470,7 @@ void Heritage::guardCalls(uint4 fl,const Address &addr,int4 size,vector<Varnode
|
|||
ParamActive *active = fc->getActiveOutput();
|
||||
int4 outputCharacter = fc->characterizeAsOutput(transAddr, size);
|
||||
if (outputCharacter != ParamEntry::no_containment) {
|
||||
if (effecttype != EffectRecord::killedbycall && fc->isAutoKillByCall())
|
||||
if (effecttype != EffectRecord::killedbycall && fc->isAutoKilledByCall())
|
||||
effecttype = EffectRecord::killedbycall;
|
||||
if (outputCharacter == ParamEntry::contained_by) {
|
||||
if (tryOutputOverlapGuard(fc, addr, transAddr, size, write))
|
||||
|
|
|
@ -205,8 +205,8 @@ class VarargsFilter : public QualifierFilter {
|
|||
int4 firstPos; ///< Start of range to match (offset relative to first variable arg)
|
||||
int4 lastPos; ///< End of range to match
|
||||
public:
|
||||
VarargsFilter(void) { firstPos = 0x80000000; lastPos = 0x7fffffff; }
|
||||
VarargsFilter(int4 first,int4 last) { firstPos = first; lastPos = last; }
|
||||
VarargsFilter(void) { firstPos = 0x80000000; lastPos = 0x7fffffff; } ///< Constructor for use with decode
|
||||
VarargsFilter(int4 first,int4 last) { firstPos = first; lastPos = last; } ///< Constructor
|
||||
virtual QualifierFilter *clone(void) const { return new VarargsFilter(firstPos,lastPos); }
|
||||
virtual bool filter(const PrototypePieces &proto,int4 pos) const;
|
||||
virtual void decode(Decoder &decoder);
|
||||
|
|
|
@ -42,6 +42,7 @@ public class ParamListStandard implements ParamList {
|
|||
protected int numgroup; // Number of "groups" in this parameter convention
|
||||
// protected int maxdelay;
|
||||
protected boolean thisbeforeret; // Do hidden return pointers usurp the storage of the this pointer
|
||||
protected boolean autoKilledByCall; // Is storage in this list automatically "killed by call"
|
||||
protected boolean splitMetatype; // Are metatyped entries in separate resource sections
|
||||
// protected int[] resourceStart; // The starting group for each resource section
|
||||
protected ParamEntry[] entry;
|
||||
|
@ -235,6 +236,7 @@ public class ParamListStandard implements ParamList {
|
|||
if (thisbeforeret) {
|
||||
encoder.writeBool(ATTRIB_THISBEFORERETPOINTER, true);
|
||||
}
|
||||
encoder.writeBool(ATTRIB_KILLEDBYCALL, autoKilledByCall);
|
||||
if (isInput && !splitMetatype) {
|
||||
encoder.writeBool(ATTRIB_SEPARATEFLOAT, false);
|
||||
}
|
||||
|
@ -298,7 +300,7 @@ public class ParamListStandard implements ParamList {
|
|||
|
||||
private void parseGroup(XmlPullParser parser, CompilerSpec cspec, ArrayList<ParamEntry> pe,
|
||||
int groupid, boolean splitFloat) throws XmlParseException {
|
||||
XmlElement el = parser.start("group");
|
||||
XmlElement el = parser.start(ELEM_GROUP.name());
|
||||
int basegroup = numgroup;
|
||||
int count = 0;
|
||||
while (parser.peek().isStart()) {
|
||||
|
@ -327,17 +329,22 @@ public class ParamListStandard implements ParamList {
|
|||
spacebase = null;
|
||||
int pointermax = 0;
|
||||
thisbeforeret = false;
|
||||
autoKilledByCall = false;
|
||||
splitMetatype = true;
|
||||
XmlElement mainel = parser.start();
|
||||
String attribute = mainel.getAttribute("pointermax");
|
||||
String attribute = mainel.getAttribute(ATTRIB_POINTERMAX.name());
|
||||
if (attribute != null) {
|
||||
pointermax = SpecXmlUtils.decodeInt(attribute);
|
||||
}
|
||||
attribute = mainel.getAttribute("thisbeforeretpointer");
|
||||
attribute = mainel.getAttribute(ATTRIB_THISBEFORERETPOINTER.name());
|
||||
if (attribute != null) {
|
||||
thisbeforeret = SpecXmlUtils.decodeBoolean(attribute);
|
||||
}
|
||||
attribute = mainel.getAttribute("separatefloat");
|
||||
attribute = mainel.getAttribute(ATTRIB_KILLEDBYCALL.name());
|
||||
if (attribute != null) {
|
||||
autoKilledByCall = SpecXmlUtils.decodeBoolean(attribute);
|
||||
}
|
||||
attribute = mainel.getAttribute(ATTRIB_SEPARATEFLOAT.name());
|
||||
if (attribute != null) {
|
||||
splitMetatype = SpecXmlUtils.decodeBoolean(attribute);
|
||||
}
|
||||
|
@ -347,13 +354,13 @@ public class ParamListStandard implements ParamList {
|
|||
if (!el.isStart()) {
|
||||
break;
|
||||
}
|
||||
if (el.getName().equals("pentry")) {
|
||||
if (el.getName().equals(ELEM_PENTRY.name())) {
|
||||
parsePentry(parser, cspec, pe, numgroup, splitMetatype, false);
|
||||
}
|
||||
else if (el.getName().equals("group")) {
|
||||
else if (el.getName().equals(ELEM_GROUP.name())) {
|
||||
parseGroup(parser, cspec, pe, numgroup, splitMetatype);
|
||||
}
|
||||
else if (el.getName().equals("rule")) {
|
||||
else if (el.getName().equals(ELEM_RULE.name())) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -366,7 +373,7 @@ public class ParamListStandard implements ParamList {
|
|||
if (!subId.isStart()) {
|
||||
break;
|
||||
}
|
||||
if (subId.getName().equals("rule")) {
|
||||
if (subId.getName().equals(ELEM_RULE.name())) {
|
||||
ModelRule rule = new ModelRule();
|
||||
rule.restoreXml(parser, this);
|
||||
rules.add(rule);
|
||||
|
@ -482,6 +489,9 @@ public class ParamListStandard implements ParamList {
|
|||
if (thisbeforeret != op2.thisbeforeret) {
|
||||
return false;
|
||||
}
|
||||
if (autoKilledByCall != op2.autoKilledByCall) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue