mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 19:42:36 +02:00
GP-3367 Delay full copy of prototype in lateRestriction
This commit is contained in:
parent
1a43822637
commit
bdc6e2202c
2 changed files with 25 additions and 21 deletions
|
@ -4783,21 +4783,23 @@ PcodeOp *FuncCallSpecs::transferLockedOutputParam(ProtoParameter *param)
|
||||||
return (PcodeOp *)0;
|
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
|
/// A NULL Varnode indicates a stack parameter. Varnode dimensions may not match
|
||||||
/// parameter dimensions exactly.
|
/// parameter dimensions exactly.
|
||||||
/// \param newinput will hold the resulting list of Varnodes
|
/// \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
|
/// \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
|
newinput.push_back(op->getIn(0)); // Always keep the call destination address
|
||||||
int4 numparams = numParams();
|
int4 numparams = source.numParams();
|
||||||
Varnode *stackref = (Varnode *)0;
|
Varnode *stackref = (Varnode *)0;
|
||||||
for(int4 i=0;i<numparams;++i) {
|
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) return false;
|
||||||
if (reuse > 0)
|
if (reuse > 0)
|
||||||
newinput.push_back(op->getIn(reuse));
|
newinput.push_back(op->getIn(reuse));
|
||||||
|
@ -4812,17 +4814,18 @@ bool FuncCallSpecs::transferLockedInput(vector<Varnode *> &newinput)
|
||||||
return true;
|
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.
|
/// 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 newoutput will hold the passed back Varnode
|
||||||
|
/// \param source is the source prototype
|
||||||
/// \return \b true if the passed back value is accurate
|
/// \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) {
|
if (param->getType()->getMetatype() == TYPE_VOID) {
|
||||||
newoutput = (Varnode *)0;
|
newoutput = (Varnode *)0;
|
||||||
return true;
|
return true;
|
||||||
|
@ -5078,16 +5081,17 @@ bool FuncCallSpecs::lateRestriction(const FuncProto &restrictedProto,vector<Varn
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isCompatible(restrictedProto)) return false;
|
if (!isCompatible(restrictedProto)) return false;
|
||||||
copy(restrictedProto); // Convert ourselves to restrictedProto
|
if (restrictedProto.isDotdotdot() && (!isinputactive)) return false;
|
||||||
// if (!isInputLocked()) return false;
|
|
||||||
if (isDotdotdot() && (!isinputactive)) return false;
|
|
||||||
|
|
||||||
// Redo all the varnode inputs (if possible)
|
if (restrictedProto.isInputLocked()) {
|
||||||
if (isInputLocked())
|
if (!transferLockedInput(newinput,restrictedProto)) // Redo all the varnode inputs (if possible)
|
||||||
if (!transferLockedInput(newinput)) return false;
|
return false;
|
||||||
// Redo all the varnode outputs (if possible)
|
}
|
||||||
if (isOutputLocked())
|
if (restrictedProto.isOutputLocked()) {
|
||||||
if (!transferLockedOutput(newoutput)) return false;
|
if (!transferLockedOutput(newoutput,restrictedProto)) // Redo all the varnode outputs (if possible)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
copy(restrictedProto); // Convert ourselves to restrictedProto
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1605,8 +1605,8 @@ class FuncCallSpecs : public FuncProto {
|
||||||
Varnode *buildParam(Funcdata &data,Varnode *vn,ProtoParameter *param,Varnode *stackref);
|
Varnode *buildParam(Funcdata &data,Varnode *vn,ProtoParameter *param,Varnode *stackref);
|
||||||
int4 transferLockedInputParam(ProtoParameter *param);
|
int4 transferLockedInputParam(ProtoParameter *param);
|
||||||
PcodeOp *transferLockedOutputParam(ProtoParameter *param);
|
PcodeOp *transferLockedOutputParam(ProtoParameter *param);
|
||||||
bool transferLockedInput(vector<Varnode *> &newinput);
|
bool transferLockedInput(vector<Varnode *> &newinput,const FuncProto &source);
|
||||||
bool transferLockedOutput(Varnode *&newoutput);
|
bool transferLockedOutput(Varnode *&newoutput,const FuncProto &source);
|
||||||
void commitNewInputs(Funcdata &data,vector<Varnode *> &newinput);
|
void commitNewInputs(Funcdata &data,vector<Varnode *> &newinput);
|
||||||
void commitNewOutputs(Funcdata &data,Varnode *newout);
|
void commitNewOutputs(Funcdata &data,Varnode *newout);
|
||||||
void collectOutputTrialVarnodes(vector<Varnode *> &trialvn);
|
void collectOutputTrialVarnodes(vector<Varnode *> &trialvn);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue