GP-3367 Delay full copy of prototype in lateRestriction

This commit is contained in:
caheckman 2023-04-28 13:31:05 -04:00
parent 1a43822637
commit bdc6e2202c
2 changed files with 25 additions and 21 deletions

View file

@ -4783,21 +4783,23 @@ PcodeOp *FuncCallSpecs::transferLockedOutputParam(ProtoParameter *param)
return (PcodeOp *)0;
}
/// \brief List and/or create a Varnode for each input parameter of \b this prototype
/// \brief List and/or create a Varnode for each input parameter of matching a source prototype
///
/// Varnodes will be passed back in order that match current input parameters.
/// Varnodes are taken for current trials associated with \b this call spec.
/// Varnodes will be passed back in the order that they match the source input parameters.
/// A NULL Varnode indicates a stack parameter. Varnode dimensions may not match
/// parameter dimensions exactly.
/// \param newinput will hold the resulting list of Varnodes
/// \param source is the source prototype
/// \return \b false only if the list needs to indicate stack variables and there is no stack-pointer placeholder
bool FuncCallSpecs::transferLockedInput(vector<Varnode *> &newinput)
bool FuncCallSpecs::transferLockedInput(vector<Varnode *> &newinput,const FuncProto &source)
{
newinput.push_back(op->getIn(0)); // Always keep the call destination address
int4 numparams = numParams();
int4 numparams = source.numParams();
Varnode *stackref = (Varnode *)0;
for(int4 i=0;i<numparams;++i) {
int4 reuse = transferLockedInputParam(getParam(i));
int4 reuse = transferLockedInputParam(source.getParam(i));
if (reuse == 0) return false;
if (reuse > 0)
newinput.push_back(op->getIn(reuse));
@ -4812,17 +4814,18 @@ bool FuncCallSpecs::transferLockedInput(vector<Varnode *> &newinput)
return true;
}
/// \brief Pass back the Varnode needed to match the output parameter (return value)
/// \brief Pass back the Varnode needed to match the output parameter (return value) of a source prototype
///
/// Search for the Varnode matching the current output parameter and pass
/// Search for the Varnode matching the output parameter and pass
/// it back. The dimensions of the Varnode may not exactly match the return value.
/// If the return value is e void, a NULL is passed back.
/// If the return value is \e void, a NULL is passed back.
/// \param newoutput will hold the passed back Varnode
/// \param source is the source prototype
/// \return \b true if the passed back value is accurate
bool FuncCallSpecs::transferLockedOutput(Varnode *&newoutput)
bool FuncCallSpecs::transferLockedOutput(Varnode *&newoutput,const FuncProto &source)
{
ProtoParameter *param = getOutput();
ProtoParameter *param = source.getOutput();
if (param->getType()->getMetatype() == TYPE_VOID) {
newoutput = (Varnode *)0;
return true;
@ -5078,16 +5081,17 @@ bool FuncCallSpecs::lateRestriction(const FuncProto &restrictedProto,vector<Varn
}
if (!isCompatible(restrictedProto)) return false;
copy(restrictedProto); // Convert ourselves to restrictedProto
// if (!isInputLocked()) return false;
if (isDotdotdot() && (!isinputactive)) return false;
if (restrictedProto.isDotdotdot() && (!isinputactive)) return false;
// Redo all the varnode inputs (if possible)
if (isInputLocked())
if (!transferLockedInput(newinput)) return false;
// Redo all the varnode outputs (if possible)
if (isOutputLocked())
if (!transferLockedOutput(newoutput)) return false;
if (restrictedProto.isInputLocked()) {
if (!transferLockedInput(newinput,restrictedProto)) // Redo all the varnode inputs (if possible)
return false;
}
if (restrictedProto.isOutputLocked()) {
if (!transferLockedOutput(newoutput,restrictedProto)) // Redo all the varnode outputs (if possible)
return false;
}
copy(restrictedProto); // Convert ourselves to restrictedProto
return true;
}

View file

@ -1605,8 +1605,8 @@ class FuncCallSpecs : public FuncProto {
Varnode *buildParam(Funcdata &data,Varnode *vn,ProtoParameter *param,Varnode *stackref);
int4 transferLockedInputParam(ProtoParameter *param);
PcodeOp *transferLockedOutputParam(ProtoParameter *param);
bool transferLockedInput(vector<Varnode *> &newinput);
bool transferLockedOutput(Varnode *&newoutput);
bool transferLockedInput(vector<Varnode *> &newinput,const FuncProto &source);
bool transferLockedOutput(Varnode *&newoutput,const FuncProto &source);
void commitNewInputs(Funcdata &data,vector<Varnode *> &newinput);
void commitNewOutputs(Funcdata &data,Varnode *newout);
void collectOutputTrialVarnodes(vector<Varnode *> &trialvn);