decompiler
1.0.0
|
A prototype model: a model for passing parameters between functions. More...
#include <fspec.hh>
Public Types | |
enum | { extrapop_unknown = 0x8000 } |
Public Member Functions | |
ProtoModel (Architecture *g) | |
Constructor for use with decode() More... | |
ProtoModel (const string &nm, const ProtoModel &op2) | |
Copy constructor changing the name. More... | |
virtual | ~ProtoModel (void) |
Destructor. | |
const string & | getName (void) const |
Get the name of the prototype model. | |
Architecture * | getArch (void) const |
Get the owning Architecture. | |
const ProtoModel * | getAliasParent (void) const |
Return model this is an alias of (or null) | |
uint4 | hasEffect (const Address &addr, int4 size) const |
Determine side-effect of this on the given memory range. More... | |
int4 | getExtraPop (void) const |
Get the stack-pointer extrapop for this model. | |
void | setExtraPop (int4 ep) |
Set the stack-pointer extrapop. | |
int4 | getInjectUponEntry (void) const |
Get the inject uponentry id. | |
int4 | getInjectUponReturn (void) const |
Get the inject uponreturn id. | |
bool | isCompatible (const ProtoModel *op2) const |
Return true if other given model can be substituted for this. More... | |
void | deriveInputMap (ParamActive *active) const |
Given a list of input trials, derive the most likely input prototype. More... | |
void | deriveOutputMap (ParamActive *active) const |
Given a list of output trials, derive the most likely output prototype. More... | |
void | assignParameterStorage (const vector< Datatype *> &typelist, vector< ParameterPieces > &res, bool ignoreOutputError) |
Calculate input and output storage locations given a function prototype. More... | |
bool | checkInputJoin (const Address &hiaddr, int4 hisize, const Address &loaddr, int4 losize) const |
Check if the given two input storage locations can represent a single logical parameter. More... | |
bool | checkOutputJoin (const Address &hiaddr, int4 hisize, const Address &loaddr, int4 losize) const |
Check if the given two output storage locations can represent a single logical return value. 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... | |
const RangeList & | getLocalRange (void) const |
Get the range of (possible) local stack variables. | |
const RangeList & | getParamRange (void) const |
Get the range of (possible) stack parameters. | |
vector< EffectRecord >::const_iterator | effectBegin (void) const |
Get an iterator to the first EffectRecord. | |
vector< EffectRecord >::const_iterator | effectEnd (void) const |
Get an iterator to the last EffectRecord. | |
vector< VarnodeData >::const_iterator | trashBegin (void) const |
Get an iterator to the first likelytrash. | |
vector< VarnodeData >::const_iterator | trashEnd (void) const |
Get an iterator to the last likelytrash. | |
int4 | characterizeAsInputParam (const Address &loc, int4 size) const |
Characterize whether the given range overlaps parameter storage. More... | |
int4 | characterizeAsOutput (const Address &loc, int4 size) const |
Characterize whether the given range overlaps output storage. More... | |
bool | possibleInputParam (const Address &loc, int4 size) const |
Does the given storage location make sense as an input parameter. More... | |
bool | possibleOutputParam (const Address &loc, int4 size) const |
Does the given storage location make sense as a return value. More... | |
bool | possibleInputParamWithSlot (const Address &loc, int4 size, int4 &slot, int4 &slotsize) const |
Pass-back the slot and slot size for the given storage location as an input parameter. More... | |
bool | possibleOutputParamWithSlot (const Address &loc, int4 size, int4 &slot, int4 &slotsize) const |
Pass-back the slot and slot size for the given storage location as a return value. More... | |
bool | unjustifiedInputParam (const Address &loc, 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 input parameter contained within the given range. More... | |
bool | getBiggestContainedOutput (const Address &loc, int4 size, VarnodeData &res) const |
Pass-back the biggest possible output parameter contained within the given range. More... | |
AddrSpace * | getSpacebase (void) const |
Get the stack space associated with this model. | |
bool | isStackGrowsNegative (void) const |
Return true if the stack grows toward smaller addresses. | |
bool | hasThisPointer (void) const |
Is this a model for (non-static) class methods. | |
bool | isConstructor (void) const |
Is this model for class constructors. | |
bool | printInDecl (void) const |
Return true if name should be printed in function declarations. | |
void | setPrintInDecl (bool val) |
Set whether this name should be printed in function declarations. | |
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... | |
virtual bool | isMerged (void) const |
Is this a merged prototype model. | |
virtual bool | isUnknown (void) const |
Is this an unrecognized prototype model. | |
virtual void | decode (Decoder &decoder) |
Restore this model from a stream. More... | |
Static Public Member Functions | |
static uint4 | lookupEffect (const vector< EffectRecord > &efflist, const Address &addr, int4 size) |
Look up an effect from the given EffectRecord list. More... | |
static int4 | lookupRecord (const vector< EffectRecord > &efflist, int4 listSize, const Address &addr, int4 size) |
Look up a particular EffectRecord from a given list by its Address and size. More... | |
Private Member Functions | |
void | defaultLocalRange (void) |
Set the default stack range used for local variables. | |
void | defaultParamRange (void) |
Set the default stack range used for input parameters. | |
void | buildParamList (const string &strategy) |
Establish the main resource lists for input and output parameters. More... | |
Private Attributes | |
Architecture * | glb |
The Architecture owning this prototype model. | |
string | name |
Name of the model. | |
int4 | extrapop |
Extra bytes popped from stack. | |
ParamList * | input |
Resource model for input parameters. | |
ParamList * | output |
Resource model for output parameters. | |
const ProtoModel * | compatModel |
The model this is a copy of. | |
vector< EffectRecord > | effectlist |
List of side-effects. | |
vector< VarnodeData > | likelytrash |
Storage locations potentially carrying trash values. | |
int4 | injectUponEntry |
Id of injection to perform at beginning of function (-1 means not used) | |
int4 | injectUponReturn |
Id of injection to perform after a call to this function (-1 means not used) | |
RangeList | localrange |
Memory range(s) of space-based locals. | |
RangeList | paramrange |
Memory range(s) of space-based parameters. | |
bool | stackgrowsnegative |
True if stack parameters have (normal) low address to high address ordering. | |
bool | hasThis |
True if this model has a this parameter (auto-parameter) | |
bool | isConstruct |
True if this model is a constructor for a particular object. | |
bool | isPrinted |
True if this model should be printed as part of function declarations. | |
Friends | |
class | ProtoModelMerged |
A prototype model: a model for passing parameters between functions.
This encompasses both input parameters and return values. It attempts to describe the ABI, Application Binary Interface, of the processor or compiler. Any number of function prototypes (FuncProto) can be implemented under a prototype model, which represents a static rule set the compiler uses to decide:
Major analysis concerns are:
A prototype model supports the concept of extrapop, which is defined as the change in value of the stack pointer (or the number of bytes popped from the stack) across a call. This value is calculated starting from the point of the p-code CALL or CALLIND op, when the stack parameters have already been pushed by the calling function. So extrapop only reflects changes made by the callee.
anonymous enum |
ghidra::ProtoModel::ProtoModel | ( | Architecture * | g | ) |
Constructor for use with decode()
g | is the Architecture that will own the new prototype model |
ghidra::ProtoModel::ProtoModel | ( | const string & | nm, |
const ProtoModel & | op2 | ||
) |
Copy constructor changing the name.
Everything is copied from the given prototype model except the name
nm | is the new name for this copy |
op2 | is the prototype model to copy |
References ghidra::ParamList::clone(), effectlist, extrapop, glb, hasThis, injectUponEntry, injectUponReturn, input, isConstruct, likelytrash, localrange, ghidra::AddrSpace::name, output, paramrange, and stackgrowsnegative.
void ghidra::ProtoModel::assignParameterStorage | ( | const vector< Datatype *> & | typelist, |
vector< ParameterPieces > & | res, | ||
bool | ignoreOutputError | ||
) |
Calculate input and output storage locations given a function prototype.
The data-types of the function prototype are passed in as an ordered list, with the first data-type corresponding to the return value and all remaining data-types corresponding to the input parameters. Based on this model, a storage location is selected for each (input and output) parameter and passed back to the caller. The passed back storage locations are ordered similarly, with the output storage as the first entry. The model has the option of inserting a hidden return value pointer in the input storage locations.
A void return type is indicated by the formal TYPE_VOID in the (either) list. If the model can't map the specific output prototype, the caller has the option of whether an exception (ParamUnassignedError) is thrown. If they choose not to throw, the unmapped return value is assumed to be void.
typelist | is the list of data-types from the function prototype |
res | will hold the storage locations for each parameter |
ignoreOutputError | is true if problems assigning the output parameter are ignored |
Referenced by ghidra::ProtoStoreInternal::decode().
|
inline |
Get the type of extension and containing input parameter for the given storage.
If the given storage is properly contained within a normal parameter and the model typically extends a small value into the full container, pass back the full container and the type of extension.
addr | is the starting address of the given storage |
size | is the number of bytes in the given storage |
res | is the parameter storage to pass back |
References ghidra::ParamList::assumedExtension().
Referenced by ghidra::FuncProto::assumedInputExtension().
|
inline |
Get the type of extension and containing return value location for the given storage.
If the given storage is properly contained within a normal return value location and the model typically extends a small value into the full container, pass back the full container and the type of extension.
addr | is the starting address of the given storage |
size | is the number of bytes in the given storage |
res | is the parameter storage to pass back |
References ghidra::ParamList::assumedExtension().
Referenced by ghidra::FuncProto::assumedOutputExtension().
|
private |
Establish the main resource lists for input and output parameters.
Generate derived ParamList objects based on a given strategy
strategy | is the resource strategy: currently "standard" or "register" |
|
inline |
Characterize whether the given range overlaps parameter storage.
Does the range naturally fit inside a potential parameter entry from this model or does it contain a parameter entry. Return one of four values indicating this characterization:
loc | is the starting address of the given range |
size | is the number of bytes in the given range |
References ghidra::ParamList::characterizeAsParam().
|
inline |
Characterize whether the given range overlaps output storage.
Does the range naturally fit inside a potential output entry from this model or does it contain an output entry. Return one of four values indicating this characterization:
loc | is the starting address of the given range |
size | is the number of bytes in the given range |
References ghidra::ParamList::characterizeAsParam().
|
inline |
Check if the given two input storage locations can represent a single logical parameter.
Within the conventions of this model, do the two (hi/lo) locations represent consecutive input parameter locations that can be replaced by a single logical parameter.
hiaddr | is the address of the most significant part of the value |
hisize | is the size of the most significant part in bytes |
loaddr | is the address of the least significant part of the value |
losize | is the size of the least significant part in bytes |
References ghidra::ParamList::checkJoin().
Referenced by ghidra::FuncProto::checkInputJoin().
|
inline |
Check if it makes sense to split a single storage location into two input parameters.
A storage location and split point is provided, implying two new storage locations. Does this model allow these locations to be considered separate parameters.
loc | is the starting address of provided storage location |
size | is the size of the location in bytes |
splitpoint | is the number of bytes to consider in the first (in address order) piece |
References ghidra::ParamList::checkSplit().
Referenced by ghidra::FuncProto::checkInputSplit().
|
inline |
Check if the given two output storage locations can represent a single logical return value.
Within the conventions of this model, do the two (hi/lo) locations represent consecutive locations that can be replaced by a single logical return value.
hiaddr | is the address of the most significant part of the value |
hisize | is the size of the most significant part in bytes |
loaddr | is the address of the least significant part of the value |
losize | is the size of the least significant part in bytes |
References ghidra::ParamList::checkJoin().
|
virtual |
Restore this model from a stream.
Parse details about this model from a <prototype> element
decoder | is the stream decoder |
Reimplemented in ghidra::ProtoModelMerged.
References ghidra::InjectPayload::CALLMECHANISM_TYPE, ghidra::Decoder::closeElement(), ghidra::EffectRecord::compareByAddress(), ghidra::Range::decode(), ghidra::Range::getFirst(), ghidra::Range::getLast(), ghidra::InjectPayload::getName(), ghidra::Decoder::getNextAttributeId(), ghidra::Range::getSpace(), ghidra::EffectRecord::killedbycall, ghidra::AddrSpace::name, ghidra::Decoder::openElement(), ghidra::Decoder::peekElement(), ghidra::Decoder::readBool(), ghidra::Decoder::readSignedIntegerExpectString(), ghidra::Decoder::readString(), ghidra::EffectRecord::return_address, ghidra::AddrSpace::stackGrowsNegative(), and ghidra::EffectRecord::unaffected.
Referenced by ghidra::Architecture::decodeProto().
|
inline |
Given a list of input trials, derive the most likely input prototype.
Trials are sorted and marked as used or not.
active | is the collection of Varnode input trials |
References ghidra::ParamList::fillinMap().
Referenced by ghidra::FuncProto::deriveInputMap().
|
inline |
Given a list of output trials, derive the most likely output prototype.
One trial (at most) is marked used and moved to the front of the list
active | is the collection of output trials |
References ghidra::ParamList::fillinMap().
Referenced by ghidra::FuncProto::deriveOutputMap().
|
inline |
Pass-back the biggest input parameter contained within the given range.
loc | is the starting address of the given range |
size | is the number of bytes in the range |
res | will hold the parameter storage description being passed back |
References ghidra::ParamList::getBiggestContainedParam().
|
inline |
Pass-back the biggest possible output parameter contained within the given range.
loc | is the starting address of the given range |
size | is the number of bytes in the range |
res | will hold the storage description being passed back |
References ghidra::ParamList::getBiggestContainedParam().
|
inline |
Return the maximum heritage delay across all possible input parameters.
Depending on the address space, data-flow for a parameter may not be available until extra transform passes have completed. This method returns the number of passes that must occur before we can guarantee that all parameters have data-flow info.
References ghidra::ParamList::getMaxDelay().
Referenced by ghidra::FuncProto::getMaxInputDelay().
|
inline |
Return the maximum heritage delay across all possible return values.
Depending on the address space, data-flow for a parameter may not be available until extra transform passes have completed. This method returns the number of passes that must occur before we can guarantee that any return value has data-flow info.
References ghidra::ParamList::getMaxDelay().
Referenced by ghidra::FuncProto::getMaxOutputDelay().
uint4 ghidra::ProtoModel::hasEffect | ( | const Address & | addr, |
int4 | size | ||
) | const |
Determine side-effect of this on the given memory range.
The model is searched for an EffectRecord matching the given range and the effect type is returned. If there is no EffectRecord or the effect generally isn't known, EffectRecord::unknown_effect is returned.
addr | is the starting address of the given memory range |
size | is the number of bytes in the given range |
bool ghidra::ProtoModel::isCompatible | ( | const ProtoModel * | op2 | ) | const |
Return true if other given model can be substituted for this.
Test whether one ProtoModel can substituted for another during FuncCallSpecs::deindirect Currently this can only happen if one model is a copy of the other except for the hasThis boolean property.
op2 | is the other ProtoModel to compare with this |
References compatModel.
|
static |
Look up an effect from the given EffectRecord list.
If a given memory range matches an EffectRecord, return the effect type. Otherwise return EffectRecord::unknown_effect
efflist | is the list of EffectRecords which must be sorted |
addr | is the starting address of the given memory range |
size | is the number of bytes in the memory range |
References ghidra::EffectRecord::compareByAddress(), ghidra::Address::getSpace(), ghidra::AddrSpace::getType(), ghidra::IPTR_INTERNAL, ghidra::Address::overlap(), ghidra::EffectRecord::unaffected, and ghidra::EffectRecord::unknown_effect.
Referenced by ghidra::FuncProto::hasEffect().
|
static |
Look up a particular EffectRecord from a given list by its Address and size.
The index of the matching EffectRecord from the given list is returned. Only the first listSize elements are examined, which much be sorted by Address. If no matching range exists, a negative number is returned.
efflist | is the given list |
listSize | is the number of records in the list to search through |
addr | is the starting Address of the record to find |
size | is the size of the record to find |
References ghidra::EffectRecord::compareByAddress(), and ghidra::Address::overlap().
Referenced by ghidra::FuncProto::decodeEffect().
|
inline |
Does the given storage location make sense as an input parameter.
Within this model, decide if the storage location can be considered an input parameter.
loc | is the starting address of the storage location |
size | is the number of bytes in the storage location |
References ghidra::ParamList::possibleParam().
|
inline |
Pass-back the slot and slot size for the given storage location as an input parameter.
This checks if the given storage location acts as an input parameter in this model and passes back the number of slots that it occupies.
loc | is the starting address of the storage location |
size | is the number of bytes in the storage location |
slot | if the slot number to pass back |
slotsize | is the number of consumed slots to pass back |
References ghidra::ParamList::possibleParamWithSlot().
|
inline |
Does the given storage location make sense as a return value.
Within this model, decide if the storage location can be considered an output parameter.
loc | is the starting address of the storage location |
size | is the number of bytes in the storage location |
References ghidra::ParamList::possibleParam().
|
inline |
Pass-back the slot and slot size for the given storage location as a return value.
This checks if the given storage location acts as an output parameter in this model and passes back the number of slots that it occupies.
loc | is the starting address of the storage location |
size | is the number of bytes in the storage location |
slot | if the slot number to pass back |
slotsize | is the number of consumed slots to pass back |
References ghidra::ParamList::possibleParamWithSlot().
|
inline |
Check if the given storage location looks like an unjustified input parameter.
The storage for a value may be contained in a normal parameter location but be unjustified within that container, i.e. the least significant bytes are not being used. If this is the case, pass back the full parameter location and return true.
loc | is the starting address of the given storage |
size | is the number of bytes in the given storage |
res | is the full parameter storage to pass back |
References ghidra::ParamList::unjustifiedContainer().