decompiler  1.0.0
Public Types | Public Member Functions | Static Public Member Functions | Private Member Functions | Private Attributes | List of all members
ghidra::FuncCallSpecs Class Reference

A class for analyzing parameters to a sub-function call. More...

#include <fspec.hh>

Inheritance diagram for ghidra::FuncCallSpecs:
ghidra::FuncProto

Public Types

enum  { offset_unknown = 0xBADBEEF }
 

Public Member Functions

 FuncCallSpecs (PcodeOp *call_op)
 Construct based on CALL or CALLIND. More...
 
void setAddress (const Address &addr)
 Set (override) the callee's entry address.
 
PcodeOpgetOp (void) const
 Get the CALL or CALLIND corresponding to this.
 
FuncdatagetFuncdata (void) const
 Get the Funcdata object associated with the called function.
 
void setFuncdata (Funcdata *f)
 Set the Funcdata object associated with the called function.
 
FuncCallSpecsclone (PcodeOp *newop) const
 Clone this given the mirrored p-code CALL. More...
 
const string & getName (void) const
 Get the function name associated with the callee.
 
const AddressgetEntryAddress (void) const
 Get the entry address of the callee.
 
void setEffectiveExtraPop (int4 epop)
 Set the specific extrapop associate with this call site.
 
int4 getEffectiveExtraPop (void) const
 Get the specific extrapop associate with this call site.
 
uintb getSpacebaseOffset (void) const
 Get the stack-pointer relative offset at the point of this call site.
 
void setParamshift (int4 val)
 Set a parameter shift for this call site.
 
int4 getParamshift (void) const
 Get the parameter shift for this call site.
 
int4 getMatchCallCount (void) const
 Get the number of calls the caller makes to this sub-function.
 
int4 getStackPlaceholderSlot (void) const
 Get the slot of the stack-pointer placeholder.
 
void initActiveInput (void)
 Turn on analysis recovering input parameters.
 
void clearActiveInput (void)
 Turn off analysis recovering input parameters.
 
void initActiveOutput (void)
 Turn on analysis recovering the return value.
 
void clearActiveOutput (void)
 Turn off analysis recovering the return value.
 
bool isInputActive (void) const
 Return true if input parameter recovery analysis is active.
 
bool isOutputActive (void) const
 Return true if return value recovery analysis is active.
 
void setBadJumpTable (bool val)
 Toggle whether call site looked like an indirect jump.
 
bool isBadJumpTable (void) const
 Return true if this call site looked like an indirect jump.
 
ParamActivegetActiveInput (void)
 Get the analysis object for input parameter recovery.
 
ParamActivegetActiveOutput (void)
 Get the analysis object for return value recovery.
 
bool checkInputJoin (int4 slot1, bool ishislot, Varnode *vn1, Varnode *vn2) const
 Check if adjacent parameter trials can be combined into a single logical parameter. More...
 
void doInputJoin (int4 slot1, bool ishislot)
 Join two parameter trials. More...
 
bool lateRestriction (const FuncProto &restrictedProto, vector< Varnode *> &newinput, Varnode *&newoutput)
 Update this prototype to match a given (more specialized) prototype. More...
 
void deindirect (Funcdata &data, Funcdata *newfd)
 Convert this call site from an indirect to a direct function call. More...
 
void forceSet (Funcdata &data, const FuncProto &fp)
 Force a more restrictive prototype on this call site. More...
 
void insertPcode (Funcdata &data)
 Inject any upon-return p-code at this call site. More...
 
void createPlaceholder (Funcdata &data, AddrSpace *spacebase)
 Add a an input parameter that will resolve to the current stack offset for this call site. More...
 
void resolveSpacebaseRelative (Funcdata &data, Varnode *phvn)
 Calculate the stack offset of this call site. More...
 
void abortSpacebaseRelative (Funcdata &data)
 Abort the attempt to recover the relative stack offset for this function. More...
 
void finalInputCheck (void)
 Make final activity check on trials that might have been affected by conditional execution. More...
 
void checkInputTrialUse (Funcdata &data, AliasChecker &aliascheck)
 Mark if input trials are being actively used. More...
 
void checkOutputTrialUse (Funcdata &data, vector< Varnode *> &trialvn)
 Mark if output trials are being actively used. More...
 
void buildInputFromTrials (Funcdata &data)
 Set the final input Varnodes to this CALL based on ParamActive analysis. More...
 
void buildOutputFromTrials (Funcdata &data, vector< Varnode *> &trialvn)
 Set the final output Varnode of this CALL based on ParamActive analysis of trials. More...
 
int4 getInputBytesConsumed (int4 slot) const
 Get the estimated number of bytes within the given parameter that are consumed. More...
 
bool setInputBytesConsumed (int4 slot, int4 val) const
 Set the estimated number of bytes within the given parameter that are consumed. More...
 
void paramshiftModifyStart (void)
 Prepend any extra parameters if a paramshift is required.
 
bool paramshiftModifyStop (Funcdata &data)
 Throw out any paramshift parameters. More...
 
uint4 hasEffectTranslate (const Address &addr, int4 size) const
 Calculate type of side-effect for a given storage location (with caller translation) More...
 
- Public Member Functions inherited from ghidra::FuncProto
 FuncProto (void)
 Constructor.
 
 ~FuncProto (void)
 Destructor.
 
ArchitecturegetArch (void) const
 Get the Architecture owning this.
 
void copy (const FuncProto &op2)
 Copy another function prototype. More...
 
void copyFlowEffects (const FuncProto &op2)
 Copy properties that affect data-flow.
 
void getPieces (PrototypePieces &pieces) const
 Get the raw pieces of the prototype. More...
 
void setPieces (const PrototypePieces &pieces)
 Set this prototype based on raw pieces. More...
 
void setScope (Scope *s, const Address &startpoint)
 Set a backing symbol Scope for this. More...
 
void setInternal (ProtoModel *m, Datatype *vt)
 Set internal backing storage for this. More...
 
void setModel (ProtoModel *m)
 Set the prototype model for this. More...
 
bool hasModel (void) const
 Does this prototype have a model.
 
bool hasMatchingModel (const ProtoModel *op2) const
 Does this use the given model.
 
const string & getModelName (void) const
 Get the prototype model name.
 
int4 getModelExtraPop (void) const
 Get the extrapop of the prototype model.
 
bool isModelUnknown (void) const
 Return true if the prototype model is unknown.
 
bool printModelInDecl (void) const
 Return true if the name should be printed in declarations.
 
bool isInputLocked (void) const
 Are input data-types locked.
 
bool isOutputLocked (void) const
 Is the output data-type locked.
 
bool isModelLocked (void) const
 Is the prototype model for this locked.
 
bool hasCustomStorage (void) const
 Is this a "custom" function prototype.
 
void setInputLock (bool val)
 Toggle the data-type lock on input parameters. More...
 
void setOutputLock (bool val)
 Toggle the data-type lock on the return value. More...
 
void setModelLock (bool val)
 Toggle the lock on the prototype model for this. More...
 
bool isInline (void) const
 Does this function get in-lined during decompilation.
 
void setInline (bool val)
 Toggle the in-line setting for functions with this prototype. More...
 
int4 getInjectId (void) const
 Get the injection id associated with this. More...
 
int4 getReturnBytesConsumed (void) const
 Get an estimate of the number of bytes consumed by callers of this prototype. More...
 
bool setReturnBytesConsumed (int4 val)
 Set the number of bytes consumed by callers of this. More...
 
bool isNoReturn (void) const
 Does a function with this prototype never return.
 
void setNoReturn (bool val)
 Toggle the no-return setting for functions with this prototype. More...
 
bool hasThisPointer (void) const
 Is this a prototype for a class method, taking a this pointer.
 
bool isConstructor (void) const
 Is this prototype for a class constructor method.
 
void setConstructor (bool val)
 Toggle whether this prototype is a constructor method. More...
 
bool isDestructor (void) const
 Is this prototype for a class destructor method.
 
void setDestructor (bool val)
 Toggle whether this prototype is a destructor method. More...
 
bool hasInputErrors (void) const
 Has this prototype been marked as having an incorrect input parameter descriptions.
 
bool hasOutputErrors (void) const
 Has this prototype been marked as having an incorrect return value description.
 
void setInputErrors (bool val)
 Toggle the input error setting for this prototype. More...
 
void setOutputErrors (bool val)
 Toggle the output error setting for this prototype. More...
 
int4 getExtraPop (void) const
 Get the general extrapop setting for this prototype.
 
void setExtraPop (int4 ep)
 Set the general extrapop for this prototype.
 
int4 getInjectUponEntry (void) const
 Get any upon-entry injection id (or -1)
 
int4 getInjectUponReturn (void) const
 Get any upon-return injection id (or -1)
 
void resolveExtraPop (void)
 Assuming this prototype is locked, calculate the extrapop. More...
 
void clearUnlockedInput (void)
 Clear input parameters that have not been locked.
 
void clearUnlockedOutput (void)
 Clear the return value if it has not been locked.
 
void clearInput (void)
 Clear all input parameters regardless of lock.
 
void setInjectId (int4 id)
 Associate a given injection with this prototype. More...
 
void cancelInjectId (void)
 Turn-off any in-lining for this function.
 
void resolveModel (ParamActive *active)
 If this has a merged model, pick the most likely model (from the merged set) More...
 
void deriveInputMap (ParamActive *active) const
 Given a list of input trials, derive the most likely inputs for this prototype. More...
 
void deriveOutputMap (ParamActive *active) const
 Given a list of output trials, derive the most likely return value for this prototype. More...
 
bool checkInputJoin (const Address &hiaddr, int4 hisz, const Address &loaddr, int4 losz) const
 Check if the given two input storage locations can represent a single logical parameter. More...
 
bool checkInputSplit (const Address &loc, int4 size, int4 splitpoint) const
 Check if it makes sense to split a single storage location into two input parameters. More...
 
void updateInputTypes (Funcdata &data, const vector< Varnode *> &triallist, ParamActive *activeinput)
 Update input parameters based on Varnode trials. More...
 
void updateInputNoTypes (Funcdata &data, const vector< Varnode *> &triallist, ParamActive *activeinput)
 Update input parameters based on Varnode trials, but do not store the data-type. More...
 
void updateOutputTypes (const vector< Varnode *> &triallist)
 Update the return value based on Varnode trials. More...
 
void updateOutputNoTypes (const vector< Varnode *> &triallist, TypeFactory *factory)
 Update the return value based on Varnode trials, but don't store the data-type. More...
 
void updateAllTypes (const vector< string > &namelist, const vector< Datatype *> &typelist, bool dtdtdt)
 Set this entire function prototype based on a list of names and data-types. More...
 
ProtoParametergetParam (int4 i) const
 Get the i-th input parameter.
 
void removeParam (int4 i)
 Remove the i-th input parameter.
 
int4 numParams (void) const
 Get the number of input parameters.
 
ProtoParametergetOutput (void) const
 Get the return value.
 
DatatypegetOutputType (void) const
 Get the return value data-type.
 
const RangeListgetLocalRange (void) const
 Get the range of potential local stack variables.
 
const RangeListgetParamRange (void) const
 Get the range of potential stack parameters.
 
bool isStackGrowsNegative (void) const
 Return true if the stack grows toward smaller addresses.
 
bool isDotdotdot (void) const
 Return true if this takes a variable number of arguments.
 
void setDotdotdot (bool val)
 Toggle whether this takes variable arguments.
 
bool isOverride (void) const
 Return true if this is a call site override.
 
void setOverride (bool val)
 Toggle whether this is a call site override.
 
uint4 hasEffect (const Address &addr, int4 size) const
 Calculate the effect this has an a given storage location. More...
 
vector< EffectRecord >::const_iterator effectBegin (void) const
 Get iterator to front of EffectRecord list.
 
vector< EffectRecord >::const_iterator effectEnd (void) const
 Get iterator to end of EffectRecord list.
 
vector< VarnodeData >::const_iterator trashBegin (void) const
 Get iterator to front of likelytrash list. More...
 
vector< VarnodeData >::const_iterator trashEnd (void) const
 Get iterator to end of likelytrash list. More...
 
int4 characterizeAsInputParam (const Address &addr, int4 size) const
 Decide whether a given storage location could be, or could hold, an input parameter. More...
 
int4 characterizeAsOutput (const Address &addr, int4 size) const
 Decide whether a given storage location could be, or could hold, the return value. More...
 
bool possibleInputParam (const Address &addr, int4 size) const
 Decide whether a given storage location could be an input parameter. More...
 
bool possibleOutputParam (const Address &addr, int4 size) const
 Decide whether a given storage location could be a return value. More...
 
int4 getMaxInputDelay (void) const
 Return the maximum heritage delay across all possible input parameters. More...
 
int4 getMaxOutputDelay (void) const
 Return the maximum heritage delay across all possible return values. More...
 
bool unjustifiedInputParam (const Address &addr, int4 size, VarnodeData &res) const
 Check if the given storage location looks like an unjustified input parameter. More...
 
OpCode assumedInputExtension (const Address &addr, int4 size, VarnodeData &res) const
 Get the type of extension and containing input parameter for the given storage. More...
 
OpCode assumedOutputExtension (const Address &addr, int4 size, VarnodeData &res) const
 Get the type of extension and containing return value location for the given storage. More...
 
bool getBiggestContainedInputParam (const Address &loc, int4 size, VarnodeData &res) const
 Pass-back the biggest potential input parameter contained within the given range. More...
 
bool getBiggestContainedOutput (const Address &loc, int4 size, VarnodeData &res) const
 Pass-back the biggest potential output storage location contained within the given range. More...
 
Address getThisPointerStorage (Datatype *dt)
 Get the storage location associated with the "this" pointer. More...
 
bool isCompatible (const FuncProto &op2) const
 Decide if this can be safely restricted to match another prototype. More...
 
AddrSpacegetSpacebase (void) const
 Get the stack address space.
 
void printRaw (const string &funcname, ostream &s) const
 Print this prototype as a single line of text. More...
 
uint4 getComparableFlags (void) const
 Get the comparable properties of this prototype. More...
 
void encode (Encoder &encoder) const
 Encode this to a stream as a <prototype> element. More...
 
void decode (Decoder &decoder, Architecture *glb)
 Restore this from a <prototype> element in the given stream. More...
 

Static Public Member Functions

static VarnodefindPreexistingWhole (Varnode *vn1, Varnode *vn2)
 Check if given two Varnodes are merged into a whole. More...
 
static FuncCallSpecsgetFspecFromConst (const Address &addr)
 Convert FspecSpace addresses to the underlying FuncCallSpecs object. More...
 
static bool compareByEntryAddress (const FuncCallSpecs *a, const FuncCallSpecs *b)
 Compare FuncCallSpecs by function entry address. More...
 
static void countMatchingCalls (const vector< FuncCallSpecs *> &qlst)
 Calculate the number of times an individual sub-function is called. More...
 

Private Member Functions

VarnodegetSpacebaseRelative (void) const
 Get the active stack-pointer Varnode at this call site. More...
 
VarnodebuildParam (Funcdata &data, Varnode *vn, ProtoParameter *param, Varnode *stackref)
 Build a Varnode representing a specific parameter. More...
 
int4 transferLockedInputParam (ProtoParameter *param)
 Get the index of the CALL input Varnode that matches the given parameter. More...
 
PcodeOptransferLockedOutputParam (ProtoParameter *param)
 
bool transferLockedInput (vector< Varnode *> &newinput, const FuncProto &source)
 List and/or create a Varnode for each input parameter of matching a source prototype. More...
 
bool transferLockedOutput (Varnode *&newoutput, const FuncProto &source)
 Pass back the Varnode needed to match the output parameter (return value) of a source prototype. More...
 
void commitNewInputs (Funcdata &data, vector< Varnode *> &newinput)
 Update input Varnodes to this CALL to reflect the formal input parameters. More...
 
void commitNewOutputs (Funcdata &data, Varnode *newout)
 Update output Varnode to this CALL to reflect the formal return value. More...
 
void collectOutputTrialVarnodes (vector< Varnode *> &trialvn)
 
void setStackPlaceholderSlot (int4 slot)
 Set the slot of the stack-pointer placeholder.
 
void clearStackPlaceholderSlot (void)
 Release the stack-pointer placeholder.
 

Private Attributes

PcodeOpop
 Pointer to CALL or CALLIND instruction.
 
string name
 Name of function if present.
 
Address entryaddress
 First executing address of function.
 
Funcdatafd
 The Funcdata object for the called functon (if known)
 
int4 effective_extrapop
 Working extrapop for the CALL.
 
uintb stackoffset
 Relative offset of stack-pointer at time of this call.
 
int4 stackPlaceholderSlot
 Slot containing temporary stack tracing placeholder (-1 means unused)
 
int4 paramshift
 Number of input parameters to ignore before prototype.
 
int4 matchCallCount
 Number of calls to this sub-function within the calling function.
 
ParamActive activeinput
 Info for recovering input parameters.
 
ParamActive activeoutput
 Info for recovering output parameters.
 
vector< int4 > inputConsume
 Number of bytes consumed by sub-function, for each input parameter.
 
bool isinputactive
 Are we actively trying to recover input parameters.
 
bool isoutputactive
 Are we actively trying to recover output parameters.
 
bool isbadjumptable
 Was the call originally a jump-table we couldn't recover.
 

Additional Inherited Members

- Protected Member Functions inherited from ghidra::FuncProto
void paramShift (int4 paramshift)
 Add parameters to the front of the input parameter list. More...
 
bool isParamshiftApplied (void) const
 
void setParamshiftApplied (bool val)
 Toggle whether a parameter shift has been applied.
 

Detailed Description

A class for analyzing parameters to a sub-function call.

This can be viewed as a function prototype that evolves over the course of analysis. It derives off of FuncProto and includes facilities for analyzing data-flow for parameter information. This is the high-level object managing the examination of data-flow to recover a working prototype (ParamActive), holding a stack-pointer placeholder to facilitate stack analysis, and deciding on the working extrapop for the CALL.

A stack-pointer placeholder is a temporary Varnode in the input operands of the CALL or CALLIND that is defined by a LOAD from the stack-pointer. By examining the pointer, the exact value of the stack-pointer (relative to its incoming value) can be computed at the point of the CALL. The temporary can arise naturally if stack parameters are a possibility, otherwise a placeholder temporary is artificially inserted into the CALL input. At the time heritage of the stack space is computed, the placeholder is examined to read off the active stack-pointer offset for the CALL and the placeholder is removed.

Member Enumeration Documentation

◆ anonymous enum

anonymous enum
Enumerator
offset_unknown 

"Magic" stack offset indicating the offset is unknown

Constructor & Destructor Documentation

◆ FuncCallSpecs()

ghidra::FuncCallSpecs::FuncCallSpecs ( PcodeOp call_op)

Member Function Documentation

◆ abortSpacebaseRelative()

void ghidra::FuncCallSpecs::abortSpacebaseRelative ( Funcdata data)

Abort the attempt to recover the relative stack offset for this function.

Any stack-pointer placeholder is removed.

Parameters
datais the calling function

References ghidra::Varnode::getDef(), ghidra::Varnode::getSpace(), ghidra::AddrSpace::getType(), ghidra::Varnode::hasNoDescend(), ghidra::IPTR_INTERNAL, ghidra::Varnode::isWritten(), ghidra::Funcdata::opDestroy(), and ghidra::Funcdata::opRemoveInput().

◆ buildInputFromTrials()

void ghidra::FuncCallSpecs::buildInputFromTrials ( Funcdata data)

◆ buildOutputFromTrials()

void ghidra::FuncCallSpecs::buildOutputFromTrials ( Funcdata data,
vector< Varnode *> &  trialvn 
)

◆ buildParam()

Varnode * ghidra::FuncCallSpecs::buildParam ( Funcdata data,
Varnode vn,
ProtoParameter param,
Varnode stackref 
)
private

Build a Varnode representing a specific parameter.

If the Varnode holding the parameter directly as input to the CALL is available, it must be provided to this method. If it is not available, this assumes an (indirect) stack Varnode is needed and builds one. If the holding Varnode is the correct size it is returned, otherwise a truncated Varnode is constructed.

Parameters
datais the calling function
vnis the Varnode holding the parameter (or NULL for a stack parameter)
paramis the actual parameter description
stackrefis the stack-pointer placeholder for this function
Returns
the Varnode that exactly matches the parameter

References ghidra::CPUI_SUBPIECE, ghidra::PcodeOp::getAddr(), ghidra::Varnode::getAddr(), ghidra::ProtoParameter::getAddress(), ghidra::Address::getOffset(), ghidra::Varnode::getSize(), ghidra::ProtoParameter::getSize(), ghidra::Address::getSpace(), ghidra::Varnode::hasNoDescend(), ghidra::Varnode::isConstant(), ghidra::Varnode::isFree(), ghidra::Funcdata::newConstant(), ghidra::Funcdata::newOp(), ghidra::Funcdata::newUniqueOut(), ghidra::Funcdata::newVarnode(), op, ghidra::Funcdata::opInsertBefore(), ghidra::Funcdata::opSetInput(), ghidra::Funcdata::opSetOpcode(), and ghidra::Funcdata::opStackLoad().

Referenced by commitNewInputs().

◆ checkInputJoin()

bool ghidra::FuncCallSpecs::checkInputJoin ( int4  slot1,
bool  ishislot,
Varnode vn1,
Varnode vn2 
) const

Check if adjacent parameter trials can be combined into a single logical parameter.

A slot must be provided indicating the trial and the only following it.

Parameters
slot1is the first trial slot
ishislotis true if the first slot will be the most significant piece
vn1is the Varnode corresponding to the first trial
vn2is the Varnode corresponding to the second trial
Returns
true if the trials can be combined

References activeinput, ghidra::FuncProto::checkInputJoin(), ghidra::ParamTrial::getAddress(), ghidra::ParamActive::getNumTrials(), ghidra::Varnode::getSize(), ghidra::ParamTrial::getSize(), ghidra::ParamActive::getTrialForInputVarnode(), and isInputActive().

Referenced by ghidra::ActionParamDouble::apply().

◆ checkInputTrialUse()

void ghidra::FuncCallSpecs::checkInputTrialUse ( Funcdata data,
AliasChecker aliascheck 
)

◆ checkOutputTrialUse()

void ghidra::FuncCallSpecs::checkOutputTrialUse ( Funcdata data,
vector< Varnode *> &  trialvn 
)

Mark if output trials are being actively used.

Run through each output trial and try to make a determination if the trial is active or not, meaning basically that the first occurrence of a trial after the call is a read.

Parameters
datais the calling function
trialvnwill hold Varnodes corresponding to the trials

References activeoutput, collectOutputTrialVarnodes(), and ghidra::ParamActive::getTrial().

Referenced by ghidra::ActionActiveReturn::apply().

◆ clone()

FuncCallSpecs * ghidra::FuncCallSpecs::clone ( PcodeOp newop) const

Clone this given the mirrored p-code CALL.

Parameters
newopreplaces the CALL or CALLIND op in the clone
Returns
the cloned FuncCallSpecs

References ghidra::FuncProto::copy(), effective_extrapop, fd, FuncCallSpecs(), isbadjumptable, paramshift, setFuncdata(), and stackoffset.

Referenced by ghidra::Funcdata::truncatedFlow().

◆ collectOutputTrialVarnodes()

void ghidra::FuncCallSpecs::collectOutputTrialVarnodes ( vector< Varnode *> &  trialvn)
private

Collect Varnode objects associated with each output trial

Varnodes can be attached to the CALL or CALLIND or one of the preceding INDIRECTs. They are passed back in a list matching the order of the trials.

Parameters
trialvnholds the resulting list of Varnodes

References activeoutput, ghidra::PcodeOp::code(), ghidra::CPUI_INDIRECT, ghidra::Varnode::getAddr(), ghidra::ParamActive::getNumTrials(), ghidra::PcodeOp::getOut(), ghidra::Varnode::getSize(), ghidra::ParamActive::getTrial(), ghidra::PcodeOp::isIndirectCreation(), op, ghidra::PcodeOp::previousOp(), ghidra::ParamTrial::setAddress(), and ghidra::ParamActive::whichTrial().

Referenced by checkOutputTrialUse().

◆ commitNewInputs()

void ghidra::FuncCallSpecs::commitNewInputs ( Funcdata data,
vector< Varnode *> &  newinput 
)
private

Update input Varnodes to this CALL to reflect the formal input parameters.

The current input parameters must be locked and are presumably out of date with the current state of the CALL Varnodes. These existing input Varnodes must already be gathered in a list. Each Varnode is updated to reflect the parameters, which may involve truncating or extending. Any active trials and stack-pointer placeholder is updated, and the new Varnodes are set as the CALL input.

Parameters
datais the calling function
newinputholds old input Varnodes and will hold new input Varnodes

References activeinput, buildParam(), ghidra::ParamActive::clear(), clearActiveInput(), ghidra::ParamActive::finishPass(), ghidra::ProtoParameter::getAddress(), ghidra::PcodeOp::getIn(), ghidra::ParamActive::getNumPasses(), ghidra::FuncProto::getParam(), ghidra::ProtoParameter::getSize(), ghidra::Address::getSpace(), getSpacebaseRelative(), ghidra::ParamActive::getTrial(), ghidra::AddrSpace::getType(), ghidra::IPTR_SPACEBASE, ghidra::FuncProto::isDotdotdot(), ghidra::FuncProto::isInputLocked(), ghidra::ParamTrial::markActive(), ghidra::FuncProto::numParams(), op, ghidra::Funcdata::opSetAllInput(), ghidra::ParamActive::registerTrial(), ghidra::Varnode::setSpacebasePlaceholder(), setStackPlaceholderSlot(), and stackPlaceholderSlot.

Referenced by deindirect(), and forceSet().

◆ commitNewOutputs()

void ghidra::FuncCallSpecs::commitNewOutputs ( Funcdata data,
Varnode newout 
)
private

Update output Varnode to this CALL to reflect the formal return value.

The current return value must be locked and is presumably out of date with the current CALL output. Unless the return value is void, the output Varnode must exist and must be provided. The Varnode is updated to reflect the return value, which may involve truncating or extending. Any active trials are updated, and the new Varnode is set as the CALL output.

Parameters
datais the calling function
newoutis the provided old output Varnode (or NULL)

References activeoutput, ghidra::FuncProto::assumedOutputExtension(), ghidra::ParamActive::clear(), clearActiveOutput(), ghidra::CPUI_COPY, ghidra::CPUI_INT_SEXT, ghidra::CPUI_INT_ZEXT, ghidra::CPUI_PIECE, ghidra::CPUI_SUBPIECE, ghidra::PcodeOp::getAddr(), ghidra::Varnode::getAddr(), ghidra::ProtoParameter::getAddress(), ghidra::Varnode::getDef(), ghidra::Datatype::getMetatype(), ghidra::PcodeOp::getOut(), ghidra::FuncProto::getOutput(), ghidra::Varnode::getSize(), ghidra::ProtoParameter::getSize(), ghidra::Address::getSpace(), ghidra::ProtoParameter::getType(), ghidra::AddrSpace::isBigEndian(), ghidra::FuncProto::isOutputLocked(), ghidra::Funcdata::isTypeRecoveryOn(), ghidra::Funcdata::newConstant(), ghidra::Funcdata::newIndirectCreation(), ghidra::Funcdata::newOp(), ghidra::Funcdata::newVarnodeOut(), op, ghidra::Funcdata::opInsertAfter(), ghidra::Funcdata::opMarkCalculatedBool(), ghidra::Funcdata::opRemoveInput(), ghidra::Funcdata::opSetInput(), ghidra::Funcdata::opSetOpcode(), ghidra::Funcdata::opSetOutput(), ghidra::Funcdata::opUninsert(), ghidra::Funcdata::opUnlink(), ghidra::Funcdata::opUnsetOutput(), ghidra::ParamActive::registerTrial(), ghidra::TYPE_BOOL, and ghidra::TYPE_INT.

Referenced by deindirect(), and forceSet().

◆ compareByEntryAddress()

static bool ghidra::FuncCallSpecs::compareByEntryAddress ( const FuncCallSpecs a,
const FuncCallSpecs b 
)
inlinestatic

Compare FuncCallSpecs by function entry address.

Parameters
ais the first FuncCallSpecs to compare
bis the second to compare
Returns
true if the first should be ordered before the second

References entryaddress.

Referenced by countMatchingCalls().

◆ countMatchingCalls()

void ghidra::FuncCallSpecs::countMatchingCalls ( const vector< FuncCallSpecs *> &  qlst)
static

Calculate the number of times an individual sub-function is called.

Provided a list of all call sites for a calling function, tally the number of calls to the same sub-function. Update the matchCallCount field of each FuncCallSpecs

Parameters
qlstis the list of call sites (FuncCallSpecs) for the calling function

References compareByEntryAddress(), entryaddress, ghidra::Address::isInvalid(), and matchCallCount.

◆ createPlaceholder()

void ghidra::FuncCallSpecs::createPlaceholder ( Funcdata data,
AddrSpace spacebase 
)

Add a an input parameter that will resolve to the current stack offset for this call site.

A LOAD from a free reference to the 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.

Parameters
datais the function where the LOAD is created
spacebaseis the given (stack) AddrSpace

References ghidra::Funcdata::opInsertInput(), ghidra::Funcdata::opStackLoad(), and ghidra::Varnode::setSpacebasePlaceholder().

Referenced by ghidra::ActionFuncLink::funcLinkInput().

◆ deindirect()

void ghidra::FuncCallSpecs::deindirect ( Funcdata data,
Funcdata newfd 
)

Convert this call site from an indirect to a direct function call.

This call site must be a CALLIND, and the function that it is actually calling must be provided. The method makes a determination if the current state of data-flow allows converting to the prototype of the new function without dropping information due to inaccurate dead-code elimination. If conversion is safe, it is performed immediately. Otherwise a restart directive issued to force decompilation to restart from scratch (now with the direct function in hand)

Parameters
datais the calling function
newfdis the Funcdata object that we know is the destination of this CALLIND

References commitNewInputs(), commitNewOutputs(), ghidra::CPUI_CALL, entryaddress, fd, ghidra::PcodeOp::getAddr(), ghidra::Funcdata::getAddress(), ghidra::Funcdata::getDisplayName(), ghidra::Funcdata::getFuncProto(), ghidra::Funcdata::getOverride(), ghidra::Override::insertIndirectOverride(), ghidra::FuncProto::isOverride(), lateRestriction(), name, ghidra::Funcdata::newVarnodeCallSpecs(), op, ghidra::Funcdata::opSetInput(), ghidra::Funcdata::opSetOpcode(), and ghidra::Funcdata::setRestartPending().

Referenced by ghidra::ActionDeindirect::apply().

◆ doInputJoin()

void ghidra::FuncCallSpecs::doInputJoin ( int4  slot1,
bool  ishislot 
)

Join two parameter trials.

We assume checkInputJoin() has returned true. Perform the join, replacing the given adjacent trials with a single merged parameter.

Parameters
slot1is the trial slot of the first trial
ishislotis true if the first slot will be the most significant piece

References activeinput, ghidra::FuncProto::getArch(), ghidra::ParamActive::getTrialForInputVarnode(), ghidra::FuncProto::isInputLocked(), and ghidra::ParamActive::joinTrial().

Referenced by ghidra::ActionParamDouble::apply().

◆ finalInputCheck()

void ghidra::FuncCallSpecs::finalInputCheck ( void  )

Make final activity check on trials that might have been affected by conditional execution.

The activity level a trial may change once conditional execution has been analyzed. This routine (re)checks trials that might be affected by this, which may then be converted to not used.

References activeinput, ghidra::AncestorRealistic::execute(), ghidra::ParamActive::getNumTrials(), ghidra::ParamTrial::getSlot(), ghidra::ParamActive::getTrial(), and op.

Referenced by ghidra::ActionActiveParam::apply().

◆ findPreexistingWhole()

Varnode * ghidra::FuncCallSpecs::findPreexistingWhole ( Varnode vn1,
Varnode vn2 
)
static

Check if given two Varnodes are merged into a whole.

If the Varnodes are merged immediately into a common whole and aren't used for anything else, return the whole Varnode.

Parameters
vn1is the first given Varnode
vn2is the second given Varnode
Returns
the combined Varnode or NULL

References ghidra::PcodeOp::code(), ghidra::CPUI_PIECE, ghidra::PcodeOp::getOut(), and ghidra::Varnode::loneDescend().

Referenced by buildOutputFromTrials().

◆ forceSet()

void ghidra::FuncCallSpecs::forceSet ( Funcdata data,
const FuncProto fp 
)

Force a more restrictive prototype on this call site.

A new prototype must be given, typically recovered from a function pointer data-type that has been propagated to this call site. The method makes a determination if the current state of data-flow allows converting to the new prototype without dropping information due to inaccurate dead-code elimination. If conversion is safe, it is performed immediately. Otherwise a restart directive issued to force decompilation to restart from scratch (now with the new prototype in hand)

Parameters
datais the calling function
fpis the new (more restrictive) function prototype

References commitNewInputs(), commitNewOutputs(), ghidra::FuncProto::copy(), ghidra::FuncProto::FuncProto(), ghidra::PcodeOp::getAddr(), ghidra::Funcdata::getOverride(), ghidra::FuncProto::hasInputErrors(), ghidra::FuncProto::hasOutputErrors(), ghidra::Override::insertProtoOverride(), lateRestriction(), op, ghidra::FuncProto::setInputErrors(), ghidra::FuncProto::setInputLock(), ghidra::FuncProto::setOutputErrors(), and ghidra::Funcdata::setRestartPending().

Referenced by ghidra::ActionDeindirect::apply().

◆ getFspecFromConst()

static FuncCallSpecs* ghidra::FuncCallSpecs::getFspecFromConst ( const Address addr)
inlinestatic

◆ getInputBytesConsumed()

int4 ghidra::FuncCallSpecs::getInputBytesConsumed ( int4  slot) const

Get the estimated number of bytes within the given parameter that are consumed.

As a function is decompiled, there may hints about how many of the bytes, within the storage location used to pass the parameter, are used by this sub-function. A non-zero value means that that many least significant bytes of the storage location are used. A value of zero means all bytes are presumed used.

Parameters
slotis the slot of the given input parameter
Returns
the number of bytes used (or 0)

References inputConsume.

Referenced by ghidra::ActionDeadCode::markConsumedParameters().

◆ getSpacebaseRelative()

Varnode * ghidra::FuncCallSpecs::getSpacebaseRelative ( void  ) const
private

Get the active stack-pointer Varnode at this call site.

Find an instance of the stack-pointer (spacebase register) that is active at the point of this CALL, by examining the stack-pointer placeholder slot.

Returns
the stack-pointer Varnode

References ghidra::PcodeOp::code(), ghidra::CPUI_LOAD, ghidra::Varnode::getDef(), ghidra::PcodeOp::getIn(), ghidra::Varnode::isSpacebasePlaceholder(), ghidra::Varnode::isWritten(), op, and stackPlaceholderSlot.

Referenced by commitNewInputs(), and transferLockedInput().

◆ hasEffectTranslate()

uint4 ghidra::FuncCallSpecs::hasEffectTranslate ( const Address addr,
int4  size 
) const

Calculate type of side-effect for a given storage location (with caller translation)

Stack locations should be provided from the caller's perspective. They are automatically translated to the callee's perspective before making the underlying query.

Parameters
addris the starting address of the storage location
sizeis the number of bytes in the storage
Returns
the effect type

References ghidra::Address::getOffset(), ghidra::Address::getSpace(), ghidra::AddrSpace::getType(), ghidra::FuncProto::hasEffect(), ghidra::IPTR_SPACEBASE, offset_unknown, stackoffset, ghidra::EffectRecord::unknown_effect, and ghidra::AddrSpace::wrapOffset().

Referenced by ghidra::Heritage::callOpIndirectEffect(), and ghidra::Heritage::guardCalls().

◆ insertPcode()

void ghidra::FuncCallSpecs::insertPcode ( Funcdata data)

Inject any upon-return p-code at this call site.

This function prototype may trigger injection of p-code immediately after the CALL or CALLIND to mimic a portion of the callee that decompilation of the caller otherwise wouldn't see.

Parameters
datais the calling function

References ghidra::Funcdata::doLiveInject(), ghidra::PcodeOp::getAddr(), ghidra::Funcdata::getArch(), ghidra::PcodeOp::getBasicIter(), ghidra::FuncProto::getInjectUponReturn(), ghidra::PcodeOp::getParent(), ghidra::PcodeInjectLibrary::getPayload(), op, and ghidra::Architecture::pcodeinjectlib.

Referenced by ghidra::ActionDefaultParams::apply().

◆ lateRestriction()

bool ghidra::FuncCallSpecs::lateRestriction ( const FuncProto restrictedProto,
vector< Varnode *> &  newinput,
Varnode *&  newoutput 
)

Update this prototype to match a given (more specialized) prototype.

This method assumes that this prototype is in some intermediate state during the parameter recovery process and that a new definitive (locked) prototype is discovered for this call site. This method checks to see if this can be updated to match the new prototype without missing any data-flow. If so, this is updated, and new input and output Varnodes for the CALL are passed back.

Parameters
restrictedProtois the new definitive function prototype
newinputwill hold the new list of input Varnodes for the CALL
newoutputwill hold the new output Varnode or NULL
Returns
true if this can be fully converted

References ghidra::FuncProto::copy(), ghidra::FuncProto::hasModel(), ghidra::FuncProto::isCompatible(), ghidra::FuncProto::isDotdotdot(), isinputactive, ghidra::FuncProto::isInputLocked(), ghidra::FuncProto::isOutputLocked(), transferLockedInput(), and transferLockedOutput().

Referenced by deindirect(), and forceSet().

◆ paramshiftModifyStop()

bool ghidra::FuncCallSpecs::paramshiftModifyStop ( Funcdata data)

Throw out any paramshift parameters.

Parameters
datais the calling function
Returns
true if a change was made

References ghidra::FuncProto::isParamshiftApplied(), ghidra::PcodeOp::numInput(), op, ghidra::Funcdata::opRemoveInput(), paramshift, ghidra::FuncProto::removeParam(), and ghidra::FuncProto::setParamshiftApplied().

◆ resolveSpacebaseRelative()

void ghidra::FuncCallSpecs::resolveSpacebaseRelative ( Funcdata data,
Varnode phvn 
)

Calculate the stack offset of this call site.

The given Varnode must be the input to the CALL in the placeholder slot and must be defined by a COPY from a Varnode in the stack space. Calculate the offset of the stack-pointer at the point of this CALL, relative to the incoming stack-pointer value. This can be obtained either be looking at a stack parameter, or if there is no stack parameter, the stack-pointer placeholder can be used. If the placeholder has no other purpose, remove it.

Parameters
datais the calling function
phvnis the Varnode in the placeholder slot for this CALL

References ghidra::ProtoParameter::getAddress(), ghidra::Varnode::getDef(), ghidra::PcodeOp::getIn(), ghidra::Address::getOffset(), ghidra::Varnode::getOffset(), ghidra::Address::getSpace(), ghidra::Varnode::getSpace(), ghidra::AddrSpace::getType(), ghidra::IPTR_SPACEBASE, ghidra::Funcdata::warningHeader(), and ghidra::AddrSpace::wrapOffset().

Referenced by ghidra::RuleLoadVarnode::applyOp().

◆ setInputBytesConsumed()

bool ghidra::FuncCallSpecs::setInputBytesConsumed ( int4  slot,
int4  val 
) const

Set the estimated number of bytes within the given parameter that are consumed.

This provides a hint to the dead code consume algorithm, while examining the calling function, about how the given parameter within the subfunction is used. A non-zero value means that that many least significant bytes of the storage location are used. A value of zero means all bytes are presumed used.

Parameters
slotis the slot of the given input parameter
valis the number of bytes consumed (or 0)
Returns
true if there was a change in the estimate

References inputConsume.

Referenced by ghidra::RulePiecePathology::tracePathologyForward().

◆ transferLockedInput()

bool ghidra::FuncCallSpecs::transferLockedInput ( vector< Varnode *> &  newinput,
const FuncProto source 
)
private

List and/or create a Varnode for each input parameter of matching a source prototype.

Varnodes are taken for current trials associated with 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.

Parameters
newinputwill hold the resulting list of Varnodes
sourceis the source prototype
Returns
false only if the list needs to indicate stack variables and there is no stack-pointer placeholder

References ghidra::PcodeOp::getIn(), ghidra::FuncProto::getParam(), getSpacebaseRelative(), ghidra::FuncProto::numParams(), op, and transferLockedInputParam().

Referenced by lateRestriction().

◆ transferLockedInputParam()

int4 ghidra::FuncCallSpecs::transferLockedInputParam ( ProtoParameter param)
private

Get the index of the CALL input Varnode that matches the given parameter.

This method facilitates the building of a Varnode matching the given parameter from existing data-flow. Return either:

  • 0 if the Varnode can't be built
  • slot# for the input Varnode to reuse
  • -1 if the parameter needs to be built from the stack
    Parameters
    paramis the given parameter to match
    Returns
    the encoded slot

References activeinput, ghidra::ProtoParameter::getAddress(), ghidra::ParamActive::getNumTrials(), ghidra::ProtoParameter::getSize(), ghidra::Address::getSpace(), ghidra::ParamActive::getTrial(), ghidra::AddrSpace::getType(), and ghidra::IPTR_SPACEBASE.

Referenced by transferLockedInput().

◆ transferLockedOutput()

bool ghidra::FuncCallSpecs::transferLockedOutput ( Varnode *&  newoutput,
const FuncProto source 
)
private

Pass back the Varnode needed to match the output parameter (return value) of a source prototype.

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 void, a NULL is passed back.

Parameters
newoutputwill hold the passed back Varnode
sourceis the source prototype
Returns
true if the passed back value is accurate

References ghidra::Datatype::getMetatype(), ghidra::PcodeOp::getOut(), ghidra::FuncProto::getOutput(), ghidra::ProtoParameter::getType(), transferLockedOutputParam(), and ghidra::TYPE_VOID.

Referenced by lateRestriction().

◆ transferLockedOutputParam()

PcodeOp * ghidra::FuncCallSpecs::transferLockedOutputParam ( ProtoParameter param)
private

Return the p-code op whose output Varnode corresponds to the given parameter (return value)

The Varnode may be attached to the base CALL or CALLIND, but it also may be attached to an INDIRECT preceding the CALL. The output Varnode may not exactly match the dimensions of the given parameter. We return non-null if either:

  • The parameter contains the Varnode (the easier case) OR if
  • The Varnode properly contains the parameter
    Parameters
    paramis the given paramter (return value)
    Returns
    the matching PcodeOp or NULL

References ghidra::PcodeOp::code(), ghidra::CPUI_INDIRECT, ghidra::Varnode::getAddr(), ghidra::ProtoParameter::getAddress(), ghidra::PcodeOp::getOut(), ghidra::Varnode::getSize(), ghidra::ProtoParameter::getSize(), ghidra::PcodeOp::isIndirectCreation(), ghidra::Address::justifiedContain(), op, and ghidra::PcodeOp::previousOp().

Referenced by transferLockedOutput().


The documentation for this class was generated from the following files: