Ghidra Decompiler Analysis Engine
|
A class for generating the control-flow structure for a single function. More...
#include <flow.hh>
Public Types | |
enum | { ignore_outofbounds = 1, ignore_unimplemented = 2, error_outofbounds = 4, error_unimplemented = 8, error_reinterpreted = 0x10, error_toomanyinstructions = 0x20, unimplemented_present = 0x40, baddata_present = 0x80, outofbounds_present = 0x100, reinterpreted_present = 0x200, toomanyinstructions_present = 0x400, possible_unreachable = 0x1000, flow_forinline = 0x2000, record_jumploads = 0x4000 } |
Public Member Functions | |
FlowInfo (Funcdata &d, PcodeOpBank &o, BlockGraph &b, vector< FuncCallSpecs * > &q) | |
Constructor. More... | |
FlowInfo (Funcdata &d, PcodeOpBank &o, BlockGraph &b, vector< FuncCallSpecs * > &q, const FlowInfo *op2) | |
Cloning constructor. More... | |
PcodeOp * | target (const Address &addr) const |
Return first p-code op for instruction at given address. More... | |
PcodeOp * | branchTarget (PcodeOp *op) const |
Find the target referred to by a given BRANCH or CBRANCH. More... | |
void | generateOps (void) |
Generate raw control-flow from the function's base address. | |
void | generateBlocks (void) |
Generate basic blocks from the raw control-flow. | |
bool | testHardInlineRestrictions (Funcdata *inlinefd, PcodeOp *op, Address &retaddr) |
For in-lining using the hard model, make sure some restrictions are met. More... | |
bool | checkEZModel (void) const |
Check if this flow matches the EX in-lining model. More... | |
void | injectPcode (void) |
Perform substitution on any op that requires injection. More... | |
void | forwardRecursion (const FlowInfo &op2) |
Pull in-lining recursion information from another flow. More... | |
void | inlineClone (const FlowInfo &inlineflow, const Address &retaddr) |
Clone the given in-line flow into this flow using the hard model. More... | |
void | inlineEZClone (const FlowInfo &inlineflow, const Address &calladdr) |
Clone the given in-line flow into this flow using the EZ model. More... | |
A class for generating the control-flow structure for a single function.
Control-flow for the function is generated in two phases: the method generateOps() produces all the raw p-code ops for the function, and the method generateBlocks() organizes the p-code ops into basic blocks (PcodeBlockBasic). In generateOps(), p-code is generated for every machine instruction that is reachable starting with the entry point address of the function. All possible flow is followed, trimming flow at instructions that end with the formal RETURN p-code operation. CALL and CALLIND are treated as fall-through operations, and flow is not followed into the sub-function.
The class supports various options for handling corner cases during the flow following process, including how to handle:
In generateBlocks(), all previously generated PcodeOp instructions are assigned to a PcodeBlockBasic. These objects define the formal basic block structure of the function. Directed control-flow edges between the blocks are created at this time based on the flow of p-code.
A Funcdata object provided to the constructor holds:
The Translate object (provided by the Architecture owning the function) generates the raw p-code ops for a single instruction. This FlowInfo class also handles p-code injection triggers encountered during flow following, primarily using the architecture's PcodeInjectLibrary to resolve them.
anonymous enum |
FlowInfo::FlowInfo | ( | Funcdata & | d, |
PcodeOpBank & | o, | ||
BlockGraph & | b, | ||
vector< FuncCallSpecs * > & | q | ||
) |
Prepare for tracing flow for a new function. The Funcdata object and references to its internal containers must be explicitly given.
d | is the new function to trace |
o | is the internal p-code container for the function |
b | is the internal basic block container |
q | is the internal container of call sites |
FlowInfo::FlowInfo | ( | Funcdata & | d, |
PcodeOpBank & | o, | ||
BlockGraph & | b, | ||
vector< FuncCallSpecs * > & | q, | ||
const FlowInfo * | op2 | ||
) |
Cloning constructor.
Prepare a new flow cloned from an existing flow. Configuration from the existing flow is copied, but the actual PcodeOps must already be cloned within the new function.
d | is the new function that has been cloned |
o | is the internal p-code container for the function |
b | is the internal basic block container |
q | is the internal container of call sites |
op2 | is the existing flow |
Find the target referred to by a given BRANCH or CBRANCH.
The code reference passed as the first parameter to the branch is examined, and the p-code op it refers to is returned. The reference may be a normal direct address or a relative offset. If no target p-code can be found, an exception is thrown.
op | is the given branch op |
bool FlowInfo::checkEZModel | ( | void | ) | const |
Check if this flow matches the EX in-lining model.
A function is in the EZ model if it is a straight-line leaf function.
void FlowInfo::forwardRecursion | ( | const FlowInfo & | op2 | ) |
Pull in-lining recursion information from another flow.
When preparing p-code for an in-lined function, the generation process needs to be informed of in-lining that has already been performed. This method copies the in-lining information from the parent flow, prior to p-code generation.
op2 | is the parent flow |
void FlowInfo::injectPcode | ( | void | ) |
Perform substitution on any op that requires injection.
Types of substitution include:
Make sure to truncate recursion, and otherwise don't allow a sub-function to be in-lined more than once.
Clone the given in-line flow into this flow using the hard model.
Individual PcodeOps from the Funcdata being in-lined are cloned into the Funcdata for this flow, preserving their original address. Any RETURN op is replaced with jump to first address following the call site.
inlineflow | is the given in-line flow to clone |
retaddr | is the first address after the call site in this flow |
Clone the given in-line flow into this flow using the EZ model.
Individual PcodeOps from the Funcdata being in-lined are cloned into the Funcdata for this flow but are reassigned a new fixed address, and the RETURN op is eliminated.
inlineflow | is the given in-line flow to clone |
calladdr | is the fixed address assigned to the cloned PcodeOps |
Return first p-code op for instruction at given address.
The first p-code op associated with the machine instruction at the given address is returned. If the instruction generated no p-code, an attempt is made to fall-thru to the next instruction. If no p-code op is ultimately found, an exception is thrown.
addr | is the given address of the instruction |
For in-lining using the hard model, make sure some restrictions are met.
Pass back the distinct return address, unless the in-lined function doesn't return.
inlinefd | is the function being in-lined into this flow |
op | is CALL instruction at the site of the in-line |
retaddr | holds the passed back return address |