decompiler
1.0.0
|
A standard model for parameters as an ordered list of storage resources. More...
#include <fspec.hh>
Public Member Functions | |
ParamListStandard (void) | |
Construct for use with decode() | |
ParamListStandard (const ParamListStandard &op2) | |
Copy constructor. | |
const list< ParamEntry > & | getEntry (void) const |
Get the list of parameter entries. | |
virtual uint4 | getType (void) const |
Get the type of parameter list. | |
virtual void | assignMap (const vector< Datatype *> &proto, TypeFactory &typefactory, vector< ParameterPieces > &res) const |
Given list of data-types, map the list positions to storage locations. More... | |
virtual void | fillinMap (ParamActive *active) const |
Given an unordered list of storage locations, calculate a function prototype. More... | |
virtual bool | checkJoin (const Address &hiaddr, int4 hisize, const Address &loaddr, int4 losize) const |
Check if the given two storage locations can represent a single logical parameter. More... | |
virtual bool | checkSplit (const Address &loc, int4 size, int4 splitpoint) const |
Check if it makes sense to split a single storage location into two parameters. More... | |
virtual int4 | characterizeAsParam (const Address &loc, int4 size) const |
Characterize whether the given range overlaps parameter storage. More... | |
virtual bool | possibleParam (const Address &loc, int4 size) const |
Does the given storage location make sense as a parameter. More... | |
virtual bool | possibleParamWithSlot (const Address &loc, int4 size, int4 &slot, int4 &slotsize) const |
Pass-back the slot and slot size for the given storage location as a parameter. More... | |
virtual bool | getBiggestContainedParam (const Address &loc, int4 size, VarnodeData &res) const |
Pass-back the biggest parameter contained within the given range. More... | |
virtual bool | unjustifiedContainer (const Address &loc, int4 size, VarnodeData &res) const |
Check if the given storage location looks like an unjustified parameter. More... | |
virtual OpCode | assumedExtension (const Address &addr, int4 size, VarnodeData &res) const |
Get the type of extension and containing parameter for the given storage. More... | |
virtual AddrSpace * | getSpacebase (void) const |
Get the address space associated with any stack based parameters in this list. More... | |
virtual void | getRangeList (AddrSpace *spc, RangeList &res) const |
For a given address space, collect all the parameter locations within that space. More... | |
virtual int4 | getMaxDelay (void) const |
Return the maximum heritage delay across all possible parameters. More... | |
virtual void | decode (Decoder &decoder, vector< EffectRecord > &effectlist, bool normalstack) |
Restore the model from an <input> or <output> element in the stream. More... | |
virtual ParamList * | clone (void) const |
Clone this parameter list model. | |
Public Member Functions inherited from ghidra::ParamList | |
virtual | ~ParamList (void) |
Destructor. | |
Protected Member Functions | |
const ParamEntry * | findEntry (const Address &loc, int4 size) const |
Given storage location find matching ParamEntry. More... | |
Address | assignAddress (const Datatype *tp, vector< int4 > &status) const |
Assign storage for given parameter data-type. More... | |
const ParamEntry * | selectUnreferenceEntry (int4 grp, type_metatype prefType) const |
Select entry to fill an unreferenced param. More... | |
void | buildTrialMap (ParamActive *active) const |
Build map from parameter trials to model ParamEntrys. More... | |
void | separateSections (ParamActive *active, vector< int4 > &trialStart) const |
Calculate the range of trials in each resource sections. More... | |
void | calcDelay (void) |
Calculate the maximum heritage delay for any potential parameter in this list. | |
void | addResolverRange (AddrSpace *spc, uintb first, uintb last, ParamEntry *paramEntry, int4 position) |
Internal method for adding a single address range to the ParamEntryResolvers. More... | |
void | populateResolver (void) |
Build the ParamEntry resolver maps. More... | |
void | parsePentry (Decoder &decoder, vector< EffectRecord > &effectlist, int4 groupid, bool normalstack, bool autokill, bool splitFloat, bool grouped) |
Parse a <pentry> element and add it to this list. More... | |
void | parseGroup (Decoder &decoder, vector< EffectRecord > &effectlist, int4 groupid, bool normalstack, bool autokill, bool splitFloat) |
Parse a sequence of <pentry> elements that are allocated as a group. More... | |
Static Protected Member Functions | |
static void | markGroupNoUse (ParamActive *active, int4 activeTrial, int4 trialStart) |
Mark all the trials within the indicated groups as not used, except for one specified index. More... | |
static void | markBestInactive (ParamActive *active, int4 group, int4 groupStart, type_metatype prefType) |
From among multiple inactive trials, select the most likely to be active and mark others as not used. More... | |
static void | forceExclusionGroup (ParamActive *active) |
Enforce exclusion rules for the given set of parameter trials. More... | |
static void | forceNoUse (ParamActive *active, int4 start, int4 stop) |
Mark every trial above the first "definitely not used" as inactive. More... | |
static void | forceInactiveChain (ParamActive *active, int4 maxchain, int4 start, int4 stop, int4 groupstart) |
Enforce rules about chains of inactive slots. More... | |
Protected Attributes | |
int4 | numgroup |
Number of groups in this parameter convention. | |
int4 | maxdelay |
Maximum heritage delay across all parameters. | |
int4 | pointermax |
If non-zero, maximum size of a data-type before converting to a pointer. | |
bool | thisbeforeret |
Does a this parameter come before a hidden return parameter. | |
vector< int4 > | resourceStart |
The starting group for each resource section. | |
list< ParamEntry > | entry |
The ordered list of parameter entries. | |
vector< ParamEntryResolver * > | resolverMap |
Map from space id to resolver. | |
AddrSpace * | spacebase |
Address space containing relative offset parameters. | |
Additional Inherited Members | |
Public Types inherited from ghidra::ParamList | |
enum | { p_standard, p_standard_out, p_register, p_register_out, p_merged } |
A standard model for parameters as an ordered list of storage resources.
This is a configurable model for passing (input) parameters as a list to a function. The model allows 1 or more resource lists based on data-type, either TYPE_UNKNOWN for general purpose or TYPE_FLOAT for floating-point registers. Within a resource list, any number of parameters can be used but they must come starting at the beginning of the list with no holes (skipped resources). A resource list can include (at the end) stack parameters that are allocated based on an alignment. Optionally, the model supports converting data-types larger than a specified size to pointers within the parameter list.
|
protected |
Internal method for adding a single address range to the ParamEntryResolvers.
Specify the contiguous address range, the ParamEntry to map to it, and a position recording the order in which ranges are added.
spc | is address space of the memory range |
first | is the starting offset of the memory range |
last | is the ending offset of the memory range |
paramEntry | is the ParamEntry to associate with the memory range |
position | is the ordering position |
References ghidra::AddrSpace::getIndex(), and ghidra::rangemap< _recordtype >::insert().
|
protected |
Assign storage for given parameter data-type.
Given the next data-type and the status of previously allocated slots, select the storage location for the parameter. The status array is indexed by group: a positive value indicates how many slots have been allocated from that group, and a -1 indicates the group/resource is fully consumed.
tp | is the data-type of the next parameter |
status | is an array marking how many slots have already been consumed in a group |
References ghidra::ParamEntry::getAddrBySlot(), ghidra::ParamEntry::getAllGroups(), ghidra::ParamEntry::getGroup(), ghidra::Datatype::getMetatype(), ghidra::Datatype::getSize(), ghidra::ParamEntry::getType(), ghidra::ParamEntry::groupSet, ghidra::ParamEntry::isExclusion(), ghidra::Address::isInvalid(), and ghidra::TYPE_UNKNOWN.
|
virtual |
Given list of data-types, map the list positions to storage locations.
If we know the function prototype, recover how parameters are actually stored using the model.
proto | is the ordered list of data-types |
typefactory | is the TypeFactory (for constructing pointers) |
res | will contain the storage locations corresponding to the datatypes |
Implements ghidra::ParamList.
Reimplemented in ghidra::ParamListMerged, ghidra::ParamListStandardOut, and ghidra::ParamListRegisterOut.
References ghidra::AddrSpace::getAddrSize(), ghidra::TypeFactory::getArch(), ghidra::AddrSpaceManager::getDefaultDataSpace(), ghidra::ParamEntry::getSize(), ghidra::TypeFactory::getTypePointer(), ghidra::AddrSpace::getWordSize(), ghidra::ParameterPieces::hiddenretparm, and ghidra::ParameterPieces::indirectstorage.
|
virtual |
Get the type of extension and containing 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 |
Implements ghidra::ParamList.
References ghidra::CPUI_COPY, and ghidra::ParamEntry::size.
|
protected |
Build map from parameter trials to model ParamEntrys.
Given a set of trials (putative Varnode parameters) as ParamTrial objects, associate each trial with a model ParamEntry within this list. Trials for for which there are no matching entries are marked as unused. Any holes in the resource list are filled with unreferenced trials. The trial list is sorted.
active | is the set of trials to map and organize |
References ghidra::ParamEntry::getAddrBySlot(), ghidra::ParamEntry::getAlign(), ghidra::ParamEntry::getGroup(), ghidra::ParamActive::getNumTrials(), ghidra::ParamEntry::getSize(), ghidra::ParamEntry::getSlot(), ghidra::ParamActive::getTrial(), ghidra::ParamEntry::isExclusion(), ghidra::ParamTrial::markUnref(), ghidra::ParamActive::registerTrial(), ghidra::ParamActive::sortTrials(), ghidra::TYPE_FLOAT, and ghidra::TYPE_UNKNOWN.
|
virtual |
Characterize whether the given range overlaps parameter storage.
Does the range naturally fit inside a potential parameter entry from this list or does it contain a parameter entry. Return one of four enumerations indicating this characterization:
loc | is the starting address of the given range |
size | is the number of bytes in the given range |
Implements ghidra::ParamList.
References ghidra::ParamEntry::contained_by, ghidra::ParamEntry::containedBy(), ghidra::ParamEntry::contains_justified, ghidra::ParamEntry::contains_unjustified, ghidra::rangemap< _recordtype >::end(), ghidra::rangemap< _recordtype >::find(), ghidra::rangemap< _recordtype >::find_end(), ghidra::AddrSpace::getIndex(), ghidra::Address::getOffset(), ghidra::Address::getSpace(), ghidra::ParamEntry::isExclusion(), ghidra::ParamEntry::justifiedContain(), and ghidra::ParamEntry::no_containment.
|
virtual |
Check if the given two storage locations can represent a single logical parameter.
Within the conventions of this model, do the two (hi/lo) locations represent consecutive 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 |
Implements ghidra::ParamList.
References ghidra::ParamEntry::getAlign(), ghidra::ParamEntry::getBase(), ghidra::ParamEntry::getGroup(), ghidra::Address::getOffset(), ghidra::Address::isContiguous(), and ghidra::ParamEntry::isExclusion().
|
virtual |
Check if it makes sense to split a single storage location into two parameters.
A storage location and split point is provided, implying two new storage locations. Does this model allow these locations to be considered 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 |
Implements ghidra::ParamList.
|
virtual |
Restore the model from an <input> or <output> element in the stream.
decoder | is the stream decoder |
effectlist | is a container collecting EffectRecords across all parameters |
normalstack | is true if parameters are pushed on the stack in the normal order |
Implements ghidra::ParamList.
Reimplemented in ghidra::ParamListStandardOut.
References ghidra::Decoder::closeElement(), ghidra::Decoder::getNextAttributeId(), ghidra::Decoder::openElement(), ghidra::Decoder::peekElement(), ghidra::Decoder::readBool(), and ghidra::Decoder::readSignedInteger().
Referenced by ghidra::ParamListStandardOut::decode().
|
virtual |
Given an unordered list of storage locations, calculate a function prototype.
A list of input (or output) trials is given, which may have holes, invalid inputs etc. Decide on the formal ordered parameter list. Trials within the ParamActive are added, removed, or reordered as needed.
active | is the given list of trials |
Implements ghidra::ParamList.
Reimplemented in ghidra::ParamListMerged, ghidra::ParamListRegister, and ghidra::ParamListRegisterOut.
References ghidra::ParamActive::getNumTrials(), ghidra::ParamActive::getTrial(), and ghidra::ParamTrial::markUsed().
|
protected |
Given storage location find matching ParamEntry.
Find the (first) entry containing the given memory range
loc | is the starting address of the range |
size | is the number of bytes in the range |
References ghidra::rangemap< _recordtype >::find(), ghidra::AddrSpace::getIndex(), ghidra::ParamEntry::getMinSize(), ghidra::Address::getOffset(), ghidra::Address::getSpace(), ghidra::ParamEntry::justifiedContain(), and ghidra::ParamEntry::size.
|
staticprotected |
Enforce exclusion rules for the given set of parameter trials.
If there are more than one active trials in a single group, and if that group is an exclusion group, mark all but the first trial to defnouse.
active | is the set of trials |
References ghidra::ParamTrial::getEntry(), ghidra::ParamEntry::getGroup(), ghidra::ParamActive::getNumTrials(), ghidra::ParamActive::getTrial(), and ghidra::TYPE_UNKNOWN.
|
staticprotected |
Enforce rules about chains of inactive slots.
If there is a chain of slots whose length is greater than maxchain, where all trials are inactive, mark trials in any later slot as inactive. Mark any inactive trials before this (that aren't in a maximal chain) as active. The parameter entries in the model may be split up into different resource sections, as in floating-point vs general purpose. This method must be called on a single section at a time. The start and stop indices describe the range of trials in the particular section.
active | is the set of trials, which must be sorted |
maxchain | is the maximum number of inactive trials to allow in a chain |
start | is the first index in the range of trials to consider |
stop | is the last index (+1) in the range of trials to consider |
groupstart | is the smallest group id in the particular section |
References ghidra::ParamActive::getTrial(), ghidra::IPTR_SPACEBASE, ghidra::ParamActive::isRecoverSubcall(), ghidra::ParamTrial::markActive(), and ghidra::ParamTrial::slotGroup().
|
staticprotected |
Mark every trial above the first "definitely not used" as inactive.
Inspection and marking only occurs within an indicated range of trials, allowing floating-point and general purpose resources to be treated separately.
active | is the set of trials, which must already be ordered |
start | is the index of the first trial in the range to consider |
stop | is the index (+1) of the last trial in the range to consider |
References ghidra::ParamTrial::getEntry(), ghidra::ParamEntry::getGroup(), and ghidra::ParamActive::getTrial().
|
virtual |
Pass-back the biggest 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 |
Implements ghidra::ParamList.
References ghidra::ParamEntry::containedBy(), ghidra::rangemap< _recordtype >::find_begin(), ghidra::rangemap< _recordtype >::find_end(), ghidra::ParamEntry::getBase(), ghidra::AddrSpace::getIndex(), ghidra::Address::getOffset(), ghidra::ParamEntry::getSize(), ghidra::Address::getSpace(), ghidra::ParamEntry::getSpace(), ghidra::ParamEntry::isExclusion(), ghidra::VarnodeData::offset, ghidra::VarnodeData::size, and ghidra::VarnodeData::space.
|
inlinevirtual |
Return the maximum heritage delay across all possible 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.
Implements ghidra::ParamList.
For a given address space, collect all the parameter locations within that space.
Pass back the memory ranges for any parameter that is stored in the given address space.
spc | is the given address space |
res | will hold the set of matching memory ranges |
Implements ghidra::ParamList.
References ghidra::RangeList::insertRange().
|
inlinevirtual |
Get the address space associated with any stack based parameters in this list.
Implements ghidra::ParamList.
Referenced by ghidra::ParamListMerged::foldIn().
|
staticprotected |
From among multiple inactive trials, select the most likely to be active and mark others as not used.
There can be at most one inactive trial in an exclusion group for the fill algorithms to work. Score all the trials and pick the one that is the most likely to actually be an active param. Mark all the others as definitely not used.
active | is the sorted set of trials |
group | is the group number |
groupStart | is the index of the first trial in the group |
prefType | is a preferred entry to type to use in scoring |
References ghidra::ParamEntry::getAllGroups(), ghidra::ParamEntry::getGroup(), ghidra::ParamActive::getNumTrials(), ghidra::ParamActive::getTrial(), and ghidra::ParamEntry::getType().
|
staticprotected |
Mark all the trials within the indicated groups as not used, except for one specified index.
Only one trial within an exclusion group can have active use, mark all others as unused.
active | is the set of trials, which must be sorted on group |
activeTrial | is the index of the trial whose groups are to be considered active |
trialStart | is the index of the first trial to mark |
References ghidra::ParamTrial::getEntry(), ghidra::ParamActive::getNumTrials(), ghidra::ParamActive::getTrial(), and ghidra::ParamTrial::markNoUse().
|
protected |
Parse a sequence of <pentry> elements that are allocated as a group.
All ParamEntry objects will share the same group id.
decoder | is the stream decoder |
effectlist | holds any passed back effect records |
groupid | is the group to which all ParamEntry elements are assigned |
normalstack | is true if the parameters should be allocated from the front of the range |
autokill | is true if parameters are automatically added to the killedbycall list |
splitFloat | is true if floating-point parameters are in their own resource section |
References ghidra::Decoder::closeElement(), ghidra::IPTR_JOIN, ghidra::Decoder::openElement(), ghidra::ParamEntry::orderWithinGroup(), and ghidra::Decoder::peekElement().
|
protected |
Parse a <pentry> element and add it to this list.
decoder | is the stream decoder |
effectlist | holds any passed back effect records |
groupid | is the group to which the new ParamEntry is assigned |
normalstack | is true if the parameters should be allocated from the front of the range |
autokill | is true if parameters are automatically added to the killedbycall list |
splitFloat | is true if floating-point parameters are in their own resource section |
grouped | is true if the new ParamEntry is grouped with other entries |
References ghidra::AddrSpace::getType(), ghidra::IPTR_SPACEBASE, ghidra::EffectRecord::killedbycall, ghidra::TYPE_UNION, and ghidra::TYPE_UNKNOWN.
|
protected |
Build the ParamEntry resolver maps.
Enter all the ParamEntry objects into an interval map (based on address space)
References ghidra::ParamEntry::getBase(), ghidra::ParamEntry::getJoinRecord(), ghidra::JoinRecord::getPiece(), ghidra::ParamEntry::getSize(), ghidra::ParamEntry::getSpace(), ghidra::AddrSpace::getType(), ghidra::IPTR_JOIN, ghidra::JoinRecord::numPieces(), and ghidra::VarnodeData::offset.
|
virtual |
Does the given storage location make sense as a parameter.
Within this model, decide if the storage location can be considered a parameter.
loc | is the starting address of the storage location |
size | is the number of bytes in the storage location |
Implements ghidra::ParamList.
Reimplemented in ghidra::ParamListRegisterOut.
|
virtual |
Pass-back the slot and slot size for the given storage location as a parameter.
This checks if the given storage location acts as a 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 |
Implements ghidra::ParamList.
References ghidra::ParamEntry::getAlign(), ghidra::ParamEntry::getAllGroups(), ghidra::ParamEntry::getSlot(), and ghidra::ParamEntry::isExclusion().
|
protected |
Select entry to fill an unreferenced param.
From among the ParamEntrys matching the given group, return the one that best matches the given metatype attribute. If there are no ParamEntrys in the group, null is returned.
grp | is the given group number |
prefType | is the preferred metatype attribute to match |
References ghidra::ParamEntry::getGroup(), ghidra::ParamEntry::getType(), and ghidra::TYPE_UNKNOWN.
|
protected |
Calculate the range of trials in each resource sections.
The trials must already be mapped, which should put them in group order. The sections split at the groups given by resourceStart. We pass back the starting index for each range of trials.
active | is the given set of parameter trials |
trialStart | will hold the starting index for each range of trials |
References ghidra::ParamActive::getNumTrials(), and ghidra::ParamActive::getTrial().
|
virtual |
Check if the given storage location looks like an unjustified 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 |
Implements ghidra::ParamList.
References ghidra::ParamEntry::size.