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

A prototype model: a model for passing parameters between functions. More...

#include <fspec.hh>

Inheritance diagram for ghidra::ProtoModel:
ghidra::ProtoModelMerged ghidra::UnknownProtoModel

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.
 
ArchitecturegetArch (void) const
 Get the owning Architecture.
 
const ProtoModelgetAliasParent (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 RangeListgetLocalRange (void) const
 Get the range of (possible) local stack variables.
 
const RangeListgetParamRange (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...
 
AddrSpacegetSpacebase (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

Architectureglb
 The Architecture owning this prototype model.
 
string name
 Name of the model.
 
int4 extrapop
 Extra bytes popped from stack.
 
ParamListinput
 Resource model for input parameters.
 
ParamListoutput
 Resource model for output parameters.
 
const ProtoModelcompatModel
 The model this is a copy of.
 
vector< EffectRecordeffectlist
 List of side-effects.
 
vector< VarnodeDatalikelytrash
 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
 

Detailed Description

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.

Member Enumeration Documentation

◆ anonymous enum

anonymous enum
Enumerator
extrapop_unknown 

Reserved extrapop value meaning the function's extrapop is unknown.

Constructor & Destructor Documentation

◆ ProtoModel() [1/2]

ghidra::ProtoModel::ProtoModel ( Architecture g)

Constructor for use with decode()

Parameters
gis the Architecture that will own the new prototype model

◆ ProtoModel() [2/2]

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

Parameters
nmis the new name for this copy
op2is 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.

Member Function Documentation

◆ assignParameterStorage()

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.

Parameters
typelistis the list of data-types from the function prototype
reswill hold the storage locations for each parameter
ignoreOutputErroris true if problems assigning the output parameter are ignored

Referenced by ghidra::ProtoStoreInternal::decode().

◆ assumedInputExtension()

OpCode ghidra::ProtoModel::assumedInputExtension ( const Address addr,
int4  size,
VarnodeData res 
) const
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.

Parameters
addris the starting address of the given storage
sizeis the number of bytes in the given storage
resis the parameter storage to pass back
Returns
the extension operator (INT_ZEXT INT_SEXT) or INT_COPY if there is no extension. INT_PIECE indicates the extension is determined by the specific prototype.

References ghidra::ParamList::assumedExtension().

Referenced by ghidra::FuncProto::assumedInputExtension().

◆ assumedOutputExtension()

OpCode ghidra::ProtoModel::assumedOutputExtension ( const Address addr,
int4  size,
VarnodeData res 
) const
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.

Parameters
addris the starting address of the given storage
sizeis the number of bytes in the given storage
resis the parameter storage to pass back
Returns
the extension operator (INT_ZEXT INT_SEXT) or INT_COPY if there is no extension. INT_PIECE indicates the extension is determined by the specific prototype.

References ghidra::ParamList::assumedExtension().

Referenced by ghidra::FuncProto::assumedOutputExtension().

◆ buildParamList()

void ghidra::ProtoModel::buildParamList ( const string &  strategy)
private

Establish the main resource lists for input and output parameters.

Generate derived ParamList objects based on a given strategy

Parameters
strategyis the resource strategy: currently "standard" or "register"

◆ characterizeAsInputParam()

int4 ghidra::ProtoModel::characterizeAsInputParam ( const Address loc,
int4  size 
) const
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:

  • no_containment - there is no containment between the range and any parameter in this list
  • contains_unjustified - at least one parameter contains the range
  • contains_justified - at least one parameter contains this range as its least significant bytes
  • contained_by - no parameter contains this range, but the range contains at least one parameter
    Parameters
    locis the starting address of the given range
    sizeis the number of bytes in the given range
    Returns
    the characterization code

References ghidra::ParamList::characterizeAsParam().

◆ characterizeAsOutput()

int4 ghidra::ProtoModel::characterizeAsOutput ( const Address loc,
int4  size 
) const
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:

  • no_containment - there is no containment between the range and any parameter in this list
  • contains_unjustified - at least one parameter contains the range
  • contains_justified - at least one parameter contains this range as its least significant bytes
  • contained_by - no parameter contains this range, but the range contains at least one parameter
    Parameters
    locis the starting address of the given range
    sizeis the number of bytes in the given range
    Returns
    the characterization code

References ghidra::ParamList::characterizeAsParam().

◆ checkInputJoin()

bool ghidra::ProtoModel::checkInputJoin ( const Address hiaddr,
int4  hisize,
const Address loaddr,
int4  losize 
) const
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.

Parameters
hiaddris the address of the most significant part of the value
hisizeis the size of the most significant part in bytes
loaddris the address of the least significant part of the value
losizeis the size of the least significant part in bytes
Returns
true if the two pieces can be joined

References ghidra::ParamList::checkJoin().

Referenced by ghidra::FuncProto::checkInputJoin().

◆ checkInputSplit()

bool ghidra::ProtoModel::checkInputSplit ( const Address loc,
int4  size,
int4  splitpoint 
) const
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.

Parameters
locis the starting address of provided storage location
sizeis the size of the location in bytes
splitpointis the number of bytes to consider in the first (in address order) piece
Returns
true if the storage location can be split

References ghidra::ParamList::checkSplit().

Referenced by ghidra::FuncProto::checkInputSplit().

◆ checkOutputJoin()

bool ghidra::ProtoModel::checkOutputJoin ( const Address hiaddr,
int4  hisize,
const Address loaddr,
int4  losize 
) const
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.

Parameters
hiaddris the address of the most significant part of the value
hisizeis the size of the most significant part in bytes
loaddris the address of the least significant part of the value
losizeis the size of the least significant part in bytes
Returns
true if the two pieces can be joined

References ghidra::ParamList::checkJoin().

◆ decode()

void ghidra::ProtoModel::decode ( Decoder decoder)
virtual

◆ deriveInputMap()

void ghidra::ProtoModel::deriveInputMap ( ParamActive active) const
inline

Given a list of input trials, derive the most likely input prototype.

Trials are sorted and marked as used or not.

Parameters
activeis the collection of Varnode input trials

References ghidra::ParamList::fillinMap().

Referenced by ghidra::FuncProto::deriveInputMap().

◆ deriveOutputMap()

void ghidra::ProtoModel::deriveOutputMap ( ParamActive active) const
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

Parameters
activeis the collection of output trials

References ghidra::ParamList::fillinMap().

Referenced by ghidra::FuncProto::deriveOutputMap().

◆ getBiggestContainedInputParam()

bool ghidra::ProtoModel::getBiggestContainedInputParam ( const Address loc,
int4  size,
VarnodeData res 
) const
inline

Pass-back the biggest input parameter contained within the given range.

Parameters
locis the starting address of the given range
sizeis the number of bytes in the range
reswill hold the parameter storage description being passed back
Returns
true if there is at least one parameter contained in the range

References ghidra::ParamList::getBiggestContainedParam().

◆ getBiggestContainedOutput()

bool ghidra::ProtoModel::getBiggestContainedOutput ( const Address loc,
int4  size,
VarnodeData res 
) const
inline

Pass-back the biggest possible output parameter contained within the given range.

Parameters
locis the starting address of the given range
sizeis the number of bytes in the range
reswill hold the storage description being passed back
Returns
true if there is at least one possible output parameter contained in the range

References ghidra::ParamList::getBiggestContainedParam().

◆ getMaxInputDelay()

int4 ghidra::ProtoModel::getMaxInputDelay ( void  ) const
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.

Returns
the maximum number of passes across all input parameters in this model

References ghidra::ParamList::getMaxDelay().

Referenced by ghidra::FuncProto::getMaxInputDelay().

◆ getMaxOutputDelay()

int4 ghidra::ProtoModel::getMaxOutputDelay ( void  ) const
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.

Returns
the maximum number of passes across all output parameters in this model

References ghidra::ParamList::getMaxDelay().

Referenced by ghidra::FuncProto::getMaxOutputDelay().

◆ hasEffect()

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.

Parameters
addris the starting address of the given memory range
sizeis the number of bytes in the given range
Returns
the EffectRecord type

◆ isCompatible()

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.

Parameters
op2is the other ProtoModel to compare with this
Returns
true if the two models are compatible

References compatModel.

◆ lookupEffect()

uint4 ghidra::ProtoModel::lookupEffect ( const vector< EffectRecord > &  efflist,
const Address addr,
int4  size 
)
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

Parameters
efflistis the list of EffectRecords which must be sorted
addris the starting address of the given memory range
sizeis the number of bytes in the memory range
Returns
the EffectRecord type

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().

◆ lookupRecord()

int4 ghidra::ProtoModel::lookupRecord ( const vector< EffectRecord > &  efflist,
int4  listSize,
const Address addr,
int4  size 
)
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.

Parameters
efflistis the given list
listSizeis the number of records in the list to search through
addris the starting Address of the record to find
sizeis the size of the record to find
Returns
the index of the matching record or a negative number

References ghidra::EffectRecord::compareByAddress(), and ghidra::Address::overlap().

Referenced by ghidra::FuncProto::decodeEffect().

◆ possibleInputParam()

bool ghidra::ProtoModel::possibleInputParam ( const Address loc,
int4  size 
) const
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.

Parameters
locis the starting address of the storage location
sizeis the number of bytes in the storage location
Returns
true if the location can be a parameter

References ghidra::ParamList::possibleParam().

◆ possibleInputParamWithSlot()

bool ghidra::ProtoModel::possibleInputParamWithSlot ( const Address loc,
int4  size,
int4 &  slot,
int4 &  slotsize 
) const
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.

Parameters
locis the starting address of the storage location
sizeis the number of bytes in the storage location
slotif the slot number to pass back
slotsizeis the number of consumed slots to pass back
Returns
true if the location can be a parameter

References ghidra::ParamList::possibleParamWithSlot().

◆ possibleOutputParam()

bool ghidra::ProtoModel::possibleOutputParam ( const Address loc,
int4  size 
) const
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.

Parameters
locis the starting address of the storage location
sizeis the number of bytes in the storage location
Returns
true if the location can be a parameter

References ghidra::ParamList::possibleParam().

◆ possibleOutputParamWithSlot()

bool ghidra::ProtoModel::possibleOutputParamWithSlot ( const Address loc,
int4  size,
int4 &  slot,
int4 &  slotsize 
) const
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.

Parameters
locis the starting address of the storage location
sizeis the number of bytes in the storage location
slotif the slot number to pass back
slotsizeis the number of consumed slots to pass back
Returns
true if the location can be a parameter

References ghidra::ParamList::possibleParamWithSlot().

◆ unjustifiedInputParam()

bool ghidra::ProtoModel::unjustifiedInputParam ( const Address loc,
int4  size,
VarnodeData res 
) const
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.

Parameters
locis the starting address of the given storage
sizeis the number of bytes in the given storage
resis the full parameter storage to pass back
Returns
true if the given storage is unjustified within its parameter container

References ghidra::ParamList::unjustifiedContainer().


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