decompiler
1.0.0
|
A class for analyzing parameters to a sub-function call. More...
#include <fspec.hh>
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. | |
PcodeOp * | getOp (void) const |
Get the CALL or CALLIND corresponding to this. | |
Funcdata * | getFuncdata (void) const |
Get the Funcdata object associated with the called function. | |
void | setFuncdata (Funcdata *f) |
Set the Funcdata object associated with the called function. | |
FuncCallSpecs * | clone (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 Address & | getEntryAddress (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. | |
ParamActive * | getActiveInput (void) |
Get the analysis object for input parameter recovery. | |
ParamActive * | getActiveOutput (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. | |
Architecture * | getArch (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... | |
ProtoParameter * | getParam (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. | |
ProtoParameter * | getOutput (void) const |
Get the return value. | |
Datatype * | getOutputType (void) const |
Get the return value data-type. | |
const RangeList & | getLocalRange (void) const |
Get the range of potential local stack variables. | |
const RangeList & | getParamRange (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... | |
AddrSpace * | getSpacebase (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 Varnode * | findPreexistingWhole (Varnode *vn1, Varnode *vn2) |
Check if given two Varnodes are merged into a whole. More... | |
static FuncCallSpecs * | getFspecFromConst (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 | |
Varnode * | getSpacebaseRelative (void) const |
Get the active stack-pointer Varnode at this call site. More... | |
Varnode * | buildParam (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... | |
PcodeOp * | transferLockedOutputParam (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 | |
PcodeOp * | op |
Pointer to CALL or CALLIND instruction. | |
string | name |
Name of function if present. | |
Address | entryaddress |
First executing address of function. | |
Funcdata * | fd |
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. | |
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.
ghidra::FuncCallSpecs::FuncCallSpecs | ( | PcodeOp * | call_op | ) |
Construct based on CALL or CALLIND.
call_op | is the representative call site within the data-flow |
References ghidra::PcodeOp::code(), ghidra::CPUI_CALL, effective_extrapop, entryaddress, ghidra::ProtoModel::extrapop_unknown, fd, ghidra::Varnode::getAddr(), getFspecFromConst(), ghidra::PcodeOp::getIn(), ghidra::Address::getSpace(), ghidra::AddrSpace::getType(), ghidra::IPTR_FSPEC, isbadjumptable, isinputactive, isoutputactive, offset_unknown, op, paramshift, stackoffset, and stackPlaceholderSlot.
Referenced by clone().
void ghidra::FuncCallSpecs::abortSpacebaseRelative | ( | Funcdata & | data | ) |
Abort the attempt to recover the relative stack offset for this function.
Any stack-pointer placeholder is removed.
data | is 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().
void ghidra::FuncCallSpecs::buildInputFromTrials | ( | Funcdata & | data | ) |
Set the final input Varnodes to this CALL based on ParamActive analysis.
Varnodes that don't look like parameters are removed. Parameters that are unreferenced are filled in. Other Varnode inputs may be truncated or extended. This prototype itself is unchanged.
data | is the calling function |
References activeinput, ghidra::CPUI_SUBPIECE, ghidra::ParamActive::deleteUnusedTrials(), ghidra::PcodeOp::getAddr(), ghidra::Varnode::getAddr(), ghidra::Funcdata::getArch(), ghidra::PcodeOp::getIn(), ghidra::ParamActive::getNumTrials(), ghidra::Funcdata::getScopeLocal(), ghidra::Varnode::getSize(), ghidra::ParamTrial::getSize(), ghidra::ParamActive::getTrial(), ghidra::IPTR_SPACEBASE, ghidra::Translate::isBigEndian(), ghidra::FuncProto::isDotdotdot(), ghidra::FuncProto::isInputLocked(), ghidra::ScopeLocal::markNotMapped(), ghidra::Funcdata::newConstant(), ghidra::Funcdata::newOp(), ghidra::Funcdata::newVarnode(), ghidra::Funcdata::newVarnodeOut(), op, ghidra::Funcdata::opInsertBefore(), ghidra::Funcdata::opSetAllInput(), ghidra::Funcdata::opSetInput(), ghidra::Funcdata::opSetOpcode(), ghidra::ParamActive::sortFixedPosition(), stackoffset, ghidra::Architecture::translate, and ghidra::AddrSpace::wrapOffset().
Referenced by ghidra::ActionActiveParam::apply().
Set the final output Varnode of this CALL based on ParamActive analysis of trials.
If it exists, the active output trial is moved to be the output Varnode of this CALL. If there are two active trials, they are merged as a single output of the CALL. Any INDIRECT ops that were holding the active trials are removed. This prototype itself is unchanged.
data | is the calling function |
trialvn | is the list of Varnodes associated with trials |
References activeoutput, ghidra::AddrSpaceManager::constructJoinAddress(), ghidra::CPUI_SUBPIECE, ghidra::ParamActive::deleteUnusedTrials(), ghidra::Funcdata::deleteVarnode(), findPreexistingWhole(), ghidra::PcodeOp::getAddr(), ghidra::Varnode::getAddr(), ghidra::Funcdata::getArch(), ghidra::Varnode::getDef(), ghidra::PcodeOp::getIn(), ghidra::ParamActive::getNumTrials(), ghidra::Varnode::getSize(), ghidra::ParamActive::getTrial(), ghidra::Funcdata::isDoublePrecisOn(), ghidra::Funcdata::newConstant(), ghidra::Funcdata::newOp(), ghidra::Funcdata::newVarnode(), op, ghidra::Funcdata::opDestroy(), ghidra::Funcdata::opInsertAfter(), ghidra::Funcdata::opSetInput(), ghidra::Funcdata::opSetOpcode(), ghidra::Funcdata::opSetOutput(), ghidra::Varnode::setPrecisHi(), ghidra::Varnode::setPrecisLo(), and ghidra::Architecture::translate.
Referenced by ghidra::ActionActiveReturn::apply().
|
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.
data | is the calling function |
vn | is the Varnode holding the parameter (or NULL for a stack parameter) |
param | is the actual parameter description |
stackref | is the stack-pointer placeholder for this function |
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().
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.
slot1 | is the first trial slot |
ishislot | is true if the first slot will be the most significant piece |
vn1 | is the Varnode corresponding to the first trial |
vn2 | is the Varnode corresponding to the second trial |
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().
void ghidra::FuncCallSpecs::checkInputTrialUse | ( | Funcdata & | data, |
AliasChecker & | aliascheck | ||
) |
Mark if input trials are being actively used.
Run through each input trial and try to make a determination if the trial is active or not, meaning basically that a write has occurred on the trial with no intervening reads between the write and the call.
data | is the calling function |
aliascheck | holds local aliasing information about the function |
References activeinput, ghidra::Funcdata::ancestorOpUse(), ghidra::AncestorRealistic::execute(), ghidra::ProtoModel::extrapop_unknown, ghidra::Varnode::getAddr(), ghidra::Funcdata::getArch(), ghidra::FuncProto::getExtraPop(), ghidra::Funcdata::getFuncProto(), ghidra::PcodeOp::getIn(), ghidra::FuncProto::getLocalRange(), ghidra::FuncProto::getModelExtraPop(), ghidra::ParamActive::getNumTrials(), ghidra::Varnode::getSize(), ghidra::ParamTrial::getSlot(), ghidra::Varnode::getSpace(), ghidra::ParamActive::getTrial(), ghidra::AddrSpace::getType(), ghidra::AliasChecker::hasLocalAlias(), ghidra::FuncProto::hasModel(), ghidra::RangeList::inRange(), ghidra::IPTR_SPACEBASE, ghidra::PcodeOp::isDead(), ghidra::Varnode::isInput(), ghidra::ParamActive::markNeedsFinalCheck(), ghidra::Funcdata::newConstant(), op, ghidra::Funcdata::opSetInput(), and ghidra::Architecture::trim_recurse_max.
Referenced by ghidra::ActionActiveParam::apply().
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.
data | is the calling function |
trialvn | will hold Varnodes corresponding to the trials |
References activeoutput, collectOutputTrialVarnodes(), and ghidra::ParamActive::getTrial().
Referenced by ghidra::ActionActiveReturn::apply().
FuncCallSpecs * ghidra::FuncCallSpecs::clone | ( | PcodeOp * | newop | ) | const |
Clone this given the mirrored p-code CALL.
newop | replaces the CALL or CALLIND op in the clone |
References ghidra::FuncProto::copy(), effective_extrapop, fd, FuncCallSpecs(), isbadjumptable, paramshift, setFuncdata(), and stackoffset.
Referenced by ghidra::Funcdata::truncatedFlow().
|
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.
trialvn | holds 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().
|
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.
data | is the calling function |
newinput | holds 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().
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.
data | is the calling function |
newout | is 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().
|
inlinestatic |
Compare FuncCallSpecs by function entry address.
a | is the first FuncCallSpecs to compare |
b | is the second to compare |
References entryaddress.
Referenced by countMatchingCalls().
|
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
qlst | is the list of call sites (FuncCallSpecs) for the calling function |
References compareByEntryAddress(), entryaddress, ghidra::Address::isInvalid(), and matchCallCount.
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.
data | is the function where the LOAD is created |
spacebase | is the given (stack) AddrSpace |
References ghidra::Funcdata::opInsertInput(), ghidra::Funcdata::opStackLoad(), and ghidra::Varnode::setSpacebasePlaceholder().
Referenced by ghidra::ActionFuncLink::funcLinkInput().
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)
data | is the calling function |
newfd | is 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().
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.
slot1 | is the trial slot of the first trial |
ishislot | is 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().
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().
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.
References ghidra::PcodeOp::code(), ghidra::CPUI_PIECE, ghidra::PcodeOp::getOut(), and ghidra::Varnode::loneDescend().
Referenced by buildOutputFromTrials().
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)
data | is the calling function |
fp | is 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().
|
inlinestatic |
Convert FspecSpace addresses to the underlying FuncCallSpecs object.
addr | is the given fspec address |
References ghidra::Address::getOffset().
Referenced by FuncCallSpecs(), ghidra::Funcdata::getCallSpecs(), ghidra::TypeOpCall::getInputLocal(), ghidra::TypeOpCall::getOutputLocal(), ghidra::FlowInfo::injectPcode(), and ghidra::PrintC::opCall().
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.
slot | is the slot of the given input parameter |
References inputConsume.
Referenced by ghidra::ActionDeadCode::markConsumedParameters().
|
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.
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().
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.
addr | is the starting address of the storage location |
size | is the number of bytes in the storage |
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().
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.
data | is 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().
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.
restrictedProto | is the new definitive function prototype |
newinput | will hold the new list of input Varnodes for the CALL |
newoutput | will hold the new output Varnode or NULL |
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().
bool ghidra::FuncCallSpecs::paramshiftModifyStop | ( | Funcdata & | data | ) |
Throw out any paramshift parameters.
data | is the calling function |
References ghidra::FuncProto::isParamshiftApplied(), ghidra::PcodeOp::numInput(), op, ghidra::Funcdata::opRemoveInput(), paramshift, ghidra::FuncProto::removeParam(), and ghidra::FuncProto::setParamshiftApplied().
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.
data | is the calling function |
phvn | is 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().
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.
slot | is the slot of the given input parameter |
val | is the number of bytes consumed (or 0) |
References inputConsume.
Referenced by ghidra::RulePiecePathology::tracePathologyForward().
|
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.
newinput | will hold the resulting list of Varnodes |
source | is the source prototype |
References ghidra::PcodeOp::getIn(), ghidra::FuncProto::getParam(), getSpacebaseRelative(), ghidra::FuncProto::numParams(), op, and transferLockedInputParam().
Referenced by lateRestriction().
|
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:
param | is the given parameter to match |
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().
|
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.
newoutput | will hold the passed back Varnode |
source | is the source prototype |
References ghidra::Datatype::getMetatype(), ghidra::PcodeOp::getOut(), ghidra::FuncProto::getOutput(), ghidra::ProtoParameter::getType(), transferLockedOutputParam(), and ghidra::TYPE_VOID.
Referenced by lateRestriction().
|
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:
param | is the given paramter (return value) |
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().