GP-3378 Remove op when clearing placeholder

This commit is contained in:
caheckman 2023-05-01 19:39:08 -04:00
parent 89e18fa536
commit 68747248f3
3 changed files with 29 additions and 14 deletions

View file

@ -1466,14 +1466,8 @@ void ActionFuncLink::funcLinkInput(FuncCallSpecs *fc,Funcdata &data)
data.opInsertInput(op,data.newVarnode(param->getSize(),param->getAddress()),op->numInput());
}
}
if (spacebase != (AddrSpace *)0) { // If we need it, create the stackplaceholder
PcodeOp *op = fc->getOp();
int4 slot = op->numInput();
Varnode *loadval = data.opStackLoad(spacebase,0,1,op,(Varnode *)0,false);
data.opInsertInput(op,loadval,slot);
fc->setStackPlaceholderSlot(slot);
loadval->setSpacebasePlaceholder();
}
if (spacebase != (AddrSpace *)0) // If we need it, create the stackplaceholder
fc->createPlaceholder(data, spacebase);
}
/// \brief Set up the return value recovery process for a single sub-function call

View file

@ -4554,6 +4554,23 @@ void FuncProto::decode(Decoder &decoder,Architecture *glb)
updateThisPointer();
}
/// \brief Add a an input parameter that will resolve to the current stack offset for \b this call site
///
/// A LOAD from a free reference to the \e spacebase pointer of the given AddrSpace is created and
/// its output is added as a parameter to the call. Later the LOAD should resolve to a COPY from
/// a Varnode in the AddrSpace, whose offset is then the current offset.
/// \param data is the function where the LOAD is created
/// \param spacebase is the given (stack) AddrSpace
void FuncCallSpecs::createPlaceholder(Funcdata &data,AddrSpace *spacebase)
{
int4 slot = op->numInput();
Varnode *loadval = data.opStackLoad(spacebase,0,1,op,(Varnode *)0,false);
data.opInsertInput(op,loadval,slot);
setStackPlaceholderSlot(slot);
loadval->setSpacebasePlaceholder();
}
/// \brief Calculate the stack offset of \b this call site
///
/// The given Varnode must be the input to the CALL in the \e placeholder slot
@ -4577,8 +4594,7 @@ void FuncCallSpecs::resolveSpacebaseRelative(Funcdata &data,Varnode *phvn)
if (stackPlaceholderSlot >= 0) {
if (op->getIn(stackPlaceholderSlot) == phvn) {
data.opRemoveInput(op,stackPlaceholderSlot);
clearStackPlaceholderSlot();
abortSpacebaseRelative(data);
return;
}
}
@ -4610,8 +4626,12 @@ void FuncCallSpecs::abortSpacebaseRelative(Funcdata &data)
{
if (stackPlaceholderSlot >= 0) {
Varnode *vn = op->getIn(stackPlaceholderSlot);
data.opRemoveInput(op,stackPlaceholderSlot);
clearStackPlaceholderSlot();
// Remove the op producing the placeholder as well
if (vn->hasNoDescend() && vn->getSpace()->getType() == IPTR_INTERNAL && vn->isWritten())
data.opDestroy(vn->getDef());
}
}

View file

@ -1610,6 +1610,10 @@ class FuncCallSpecs : public FuncProto {
void commitNewInputs(Funcdata &data,vector<Varnode *> &newinput);
void commitNewOutputs(Funcdata &data,Varnode *newout);
void collectOutputTrialVarnodes(vector<Varnode *> &trialvn);
void setStackPlaceholderSlot(int4 slot) { stackPlaceholderSlot = slot;
if (isinputactive) activeinput.setPlaceholderSlot(); } ///< Set the slot of the stack-pointer placeholder
void clearStackPlaceholderSlot(void) {
stackPlaceholderSlot = -1; if (isinputactive) activeinput.freePlaceholderSlot(); } ///< Release the stack-pointer placeholder
public:
enum {
offset_unknown = 0xBADBEEF ///< "Magic" stack offset indicating the offset is unknown
@ -1629,10 +1633,6 @@ public:
int4 getParamshift(void) const { return paramshift; } ///< Get the parameter shift for this call site
int4 getMatchCallCount(void) const { return matchCallCount; } ///< Get the number of calls the caller makes to \b this sub-function
int4 getStackPlaceholderSlot(void) const { return stackPlaceholderSlot; } ///< Get the slot of the stack-pointer placeholder
void setStackPlaceholderSlot(int4 slot) { stackPlaceholderSlot = slot;
if (isinputactive) activeinput.setPlaceholderSlot(); } ///< Set the slot of the stack-pointer placeholder
void clearStackPlaceholderSlot(void) {
stackPlaceholderSlot = -1; if (isinputactive) activeinput.freePlaceholderSlot(); } ///< Release the stack-pointer placeholder
void initActiveInput(void); ///< Turn on analysis recovering input parameters
void clearActiveInput(void) { isinputactive = false; } ///< Turn off analysis recovering input parameters
@ -1651,6 +1651,7 @@ public:
void deindirect(Funcdata &data,Funcdata *newfd);
void forceSet(Funcdata &data,const FuncProto &fp);
void insertPcode(Funcdata &data);
void createPlaceholder(Funcdata &data,AddrSpace *spacebase);
void resolveSpacebaseRelative(Funcdata &data,Varnode *phvn);
void abortSpacebaseRelative(Funcdata &data);
void finalInputCheck(void);