Ghidra Decompiler Analysis Engine
|
A control-flow block built out of sub-components. More...
#include <block.hh>
Public Member Functions | |
void | clear (void) |
Clear all component FlowBlock objects. | |
virtual block_type | getType (void) const |
virtual FlowBlock * | subBlock (int4 i) const |
virtual void | markUnstructured (void) |
virtual void | markLabelBumpUp (bool bump) |
Let hierarchical blocks steal labels of their (first) components. More... | |
virtual void | scopeBreak (int4 curexit, int4 curloopexit) |
virtual void | printTree (ostream &s, int4 level) const |
Print tree structure of any blocks owned by this. More... | |
virtual void | printRaw (ostream &s) const |
virtual void | emit (PrintLanguage *lng) const |
Emit the instructions in this FlowBlock as structured code. More... | |
virtual FlowBlock * | nextFlowAfter (const FlowBlock *bl) const |
Get the leaf FlowBlock that will execute after the given FlowBlock. More... | |
virtual void | finalTransform (Funcdata &data) |
virtual void | finalizePrinting (Funcdata &data) const |
virtual void | saveXmlBody (ostream &s) const |
virtual void | restoreXmlBody (List::const_iterator &iter, List::const_iterator enditer, BlockMap &resolver) |
Restore details about this FlowBlock from an XML stream. More... | |
void | restoreXml (const Element *el, const AddrSpaceManager *m) |
Restore this BlockGraph from an XML stream. More... | |
void | addEdge (FlowBlock *begin, FlowBlock *end) |
Add a directed edge between component FlowBlocks. More... | |
void | addLoopEdge (FlowBlock *begin, int4 outindex) |
Mark a given edge as a loop edge. More... | |
void | removeEdge (FlowBlock *begin, FlowBlock *end) |
Remove an edge between component FlowBlocks. More... | |
void | switchEdge (FlowBlock *in, FlowBlock *outbefore, FlowBlock *outafter) |
Move an edge from one out FlowBlock to another. More... | |
void | moveOutEdge (FlowBlock *blold, int4 slot, FlowBlock *blnew) |
Move indicated out edge to a new FlowBlock. More... | |
void | removeBlock (FlowBlock *bl) |
Remove a FlowBlock from this BlockGraph. More... | |
void | removeFromFlow (FlowBlock *bl) |
Remove given FlowBlock preserving flow in this. More... | |
void | removeFromFlowSplit (FlowBlock *bl, bool flipflow) |
Remove FlowBlock splitting flow between input and output edges. More... | |
void | spliceBlock (FlowBlock *bl) |
Splice given FlowBlock together with its output. More... | |
void | setStartBlock (FlowBlock *bl) |
Set the entry point FlowBlock for this graph. More... | |
FlowBlock * | getStartBlock (void) const |
Get the entry point FlowBlock. More... | |
FlowBlock * | newBlock (void) |
Build a new plain FlowBlock. More... | |
BlockBasic * | newBlockBasic (Funcdata *fd) |
Build a new BlockBasic. More... | |
BlockCopy * | newBlockCopy (FlowBlock *bl) |
Build a new BlockCopy. More... | |
BlockGoto * | newBlockGoto (FlowBlock *bl) |
Build a new BlockGoto. More... | |
BlockMultiGoto * | newBlockMultiGoto (FlowBlock *bl, int4 outedge) |
Build a new BlockMultiGoto. More... | |
BlockList * | newBlockList (const vector< FlowBlock * > &nodes) |
Build a new BlockList. More... | |
BlockCondition * | newBlockCondition (FlowBlock *b1, FlowBlock *b2) |
Build a new BlockCondition. More... | |
BlockIf * | newBlockIfGoto (FlowBlock *cond) |
Build a new BlockIfGoto. More... | |
BlockIf * | newBlockIf (FlowBlock *cond, FlowBlock *tc) |
Build a new BlockIf. More... | |
BlockIf * | newBlockIfElse (FlowBlock *cond, FlowBlock *tc, FlowBlock *fc) |
Build a new BlockIfElse. More... | |
BlockWhileDo * | newBlockWhileDo (FlowBlock *cond, FlowBlock *cl) |
Build a new BlockWhileDo. More... | |
BlockDoWhile * | newBlockDoWhile (FlowBlock *condcl) |
Build a new BlockDoWhile. More... | |
BlockInfLoop * | newBlockInfLoop (FlowBlock *body) |
Build a new BlockInfLoop. More... | |
BlockSwitch * | newBlockSwitch (const vector< FlowBlock * > &cs, bool hasExit) |
Build a new BlockSwitch. More... | |
void | orderBlocks (void) |
void | buildCopy (const BlockGraph &graph) |
Build a copy of a BlockGraph. More... | |
void | clearVisitCount (void) |
Clear the visit count in all node FlowBlocks. | |
void | calcForwardDominator (const vector< FlowBlock * > &rootlist) |
Calculate forward dominators. More... | |
void | buildDomTree (vector< vector< FlowBlock * > > &child) const |
Build the dominator tree. More... | |
int4 | buildDomDepth (vector< int4 > &depth) const |
Calculate dominator depths. More... | |
void | buildDomSubTree (vector< FlowBlock * > &res, FlowBlock *root) const |
Collect nodes from a dominator sub-tree. More... | |
void | calcLoop (void) |
Calculate loop edges. More... | |
void | collectReachable (vector< FlowBlock * > &res, FlowBlock *bl, bool un) const |
Collect reachable/unreachable FlowBlocks from a given start FlowBlock. More... | |
void | structureLoops (vector< FlowBlock * > &rootlist) |
Label loop edges. More... | |
Public Member Functions inherited from FlowBlock | |
FlowBlock (void) | |
Construct a block with no edges. | |
virtual void | printHeader (ostream &s) const |
Print a simple description of this to stream. More... | |
virtual bool | negateCondition (bool toporbottom) |
Flip the condition computed by this. More... | |
virtual bool | preferComplement (Funcdata &data) |
Rearrange this hierarchy to simplify boolean expressions. More... | |
virtual FlowBlock * | getSplitPoint (void) |
Get the leaf splitting block. More... | |
virtual int4 | flipInPlaceTest (vector< PcodeOp * > &fliplist) const |
Test normalizing the conditional branch in this. More... | |
virtual void | flipInPlaceExecute (void) |
Perform the flip to normalize conditional branch executed by this block. More... | |
virtual void | saveXmlHeader (ostream &s) const |
Save basic information as XML attributes. More... | |
virtual void | restoreXmlHeader (const Element *el) |
Restore basic information for XML attributes. More... | |
void | saveXmlEdges (ostream &s) const |
Save edge information to an XML stream. More... | |
void | restoreXmlEdges (List::const_iterator &iter, List::const_iterator enditer, BlockMap &resolver) |
Restore edges from an XML stream. More... | |
void | saveXml (ostream &s) const |
Write out this to an XML stream. More... | |
void | restoreXml (const Element *el, BlockMap &resolver) |
Restore this from an XML stream. More... | |
const FlowBlock * | nextInFlow (void) const |
Return next block to be executed in flow. More... | |
void | setGotoBranch (int4 i) |
Mark a goto branch. More... | |
bool | isJumpTarget (void) const |
Return true if non-fallthru jump flows into this. More... | |
const FlowBlock * | getFrontLeaf (void) const |
Get the first leaf FlowBlock. More... | |
FlowBlock * | getFrontLeaf (void) |
Get the first leaf FlowBlock. More... | |
int4 | calcDepth (const FlowBlock *leaf) const |
Get the depth of the given component FlowBlock. More... | |
bool | dominates (const FlowBlock *subBlock) const |
Does this block dominate the given block. More... | |
bool | restrictedByConditional (const FlowBlock *cond) const |
Check if the condition from the given block holds for this block. More... | |
bool | hasLoopIn (void) const |
Is there a looping edge coming into this block. More... | |
bool | hasLoopOut (void) const |
Is there a looping edge going out of this block. More... | |
int4 | getInIndex (const FlowBlock *bl) const |
Get the incoming edge index for the given FlowBlock. More... | |
int4 | getOutIndex (const FlowBlock *bl) const |
Get the outgoing edge index for the given FlowBlock. More... | |
bool | isDecisionOut (int4 i) const |
Can this and the i-th output be merged into a BlockIf or BlockList. | |
bool | isDecisionIn (int4 i) const |
Can this and the i-th input be merged into a BlockIf or BlockList. | |
bool | isLoopDAGOut (int4 i) const |
Is the i-th outgoing edge part of the DAG sub-graph. | |
bool | isLoopDAGIn (int4 i) const |
Is the i-th incoming edge part of the DAG sub-graph. | |
JumpTable * | getJumptable (void) const |
Get the JumpTable associated this block. More... | |
Protected Member Functions | |
void | swapBlocks (int4 i, int4 j) |
Swap the positions two component FlowBlocks. More... | |
Static Protected Member Functions | |
static void | markCopyBlock (FlowBlock *bl, uint4 fl) |
Set properties on the first leaf FlowBlock. More... | |
Additional Inherited Members | |
Public Types inherited from FlowBlock | |
enum | block_type { t_plain, t_basic, t_graph, t_copy, t_goto, t_multigoto, t_ls, t_condition, t_if, t_whiledo, t_dowhile, t_switch, t_infloop } |
The possible block types. | |
enum | block_flags { f_goto_goto = 1, f_break_goto = 2, f_continue_goto = 4, f_switch_out = 0x10, f_unstructured_targ = 0x20, f_mark = 0x80, f_mark2 = 0x100, f_entry_point = 0x200, f_interior_gotoout = 0x400, f_interior_gotoin = 0x800, f_label_bumpup = 0x1000, f_donothing_loop = 0x2000, f_dead = 0x4000, f_whiledo_overflow = 0x8000, f_flip_path = 0x10000, f_joined_block = 0x20000, f_duplicate_block = 0x40000 } |
Boolean properties of blocks. More... | |
enum | edge_flags { f_goto_edge = 1, f_loop_edge = 2, f_defaultswitch_edge = 4, f_irreducible = 8, f_tree_edge = 0x10, f_forward_edge = 0x20, f_cross_edge = 0x40, f_back_edge = 0x80, f_loop_exit_edge = 0x100 } |
Boolean properties on edges. More... | |
Static Public Member Functions inherited from FlowBlock | |
static block_type | nameToType (const string &name) |
Get the block_type associated with a name string. More... | |
static string | typeToName (block_type bt) |
Get the name string associated with a block_type. More... | |
static bool | compareBlockIndex (const FlowBlock *bl1, const FlowBlock *bl2) |
Compare FlowBlock by index. More... | |
static bool | compareFinalOrder (const FlowBlock *bl1, const FlowBlock *bl2) |
Final FlowBlock comparison. More... | |
static FlowBlock * | findCommonBlock (FlowBlock *bl1, FlowBlock *bl2) |
Find the common dominator of two FlowBlocks. More... | |
static FlowBlock * | findCommonBlock (const vector< FlowBlock * > &blockSet) |
Find common dominator of multiple FlowBlocks. More... | |
A control-flow block built out of sub-components.
This is the core class for building a hierarchy of control-flow blocks. A set of control-flow blocks can be grouped together and viewed as a single block, with its own input and output blocks. All the code structuring elements (BlockList, BlockIf, BlockWhileDo, etc.) derive from this.
void BlockGraph::addLoopEdge | ( | FlowBlock * | begin, |
int4 | outindex | ||
) |
Mark a given edge as a loop edge.
begin | is a given component FlowBlock |
outindex | is the index of the out edge to mark as a loop |
void BlockGraph::buildCopy | ( | const BlockGraph & | graph | ) |
Build a copy of a BlockGraph.
Construct a copy of the given BlockGraph in this. The nodes of the copy will be official BlockCopy objects which will contain a reference to their corresponding FlowBlock in the given graph. All edges will be duplicated.
graph | is the given BlockGraph to copy |
int4 BlockGraph::buildDomDepth | ( | vector< int4 > & | depth | ) | const |
Calculate dominator depths.
Associate every FlowBlock node in this graph with its depth in the dominator tree. The dominator root has depth 1, the nodes it immediately dominates have depth 2, etc.
depth | is array that will be populated with depths |
void BlockGraph::buildDomTree | ( | vector< vector< FlowBlock * > > & | child | ) | const |
Build the dominator tree.
Associate dominator children with each node via a list (of lists) indexed by the FlowBlock index.
child | is the initially empty list of lists |
void BlockGraph::calcForwardDominator | ( | const vector< FlowBlock * > & | rootlist | ) |
Calculate forward dominators.
Calculate the immediate dominator for each FlowBlock node in this BlockGraph, for forward control-flow. The algorithm must be provided a list of entry points for the graph. We assume the blocks are in reverse post-order and this is reflected in the index field. Using an algorithm by Cooper, Harvey, and Kennedy. Softw. Pract. Exper. 2001; 4: 1-10
rootlist | is the list of entry point FlowBlocks |
void BlockGraph::calcLoop | ( | void | ) |
Calculate loop edges.
This algorithm identifies a set of edges such that, if the edges are removed, the remaining graph has NO directed cycles The algorithm works as follows: Starting from the start block, do a depth first search through the "out" edges of the block. If the outblock is already on the current path from root to node, we have found a cycle, we add the last edge to the list and continue pretending that edge didn't exist. If the outblock is not on the current path but has been visited before, we can truncate the search. This is now only applied as a failsafe if the graph has irreducible edges.
|
inlinevirtual |
Emit the instructions in this FlowBlock as structured code.
This is the main entry point, at the control-flow level, for printing structured code.
lng | is the PrintLanguage that provides details of the high-level language being printed |
Reimplemented from FlowBlock.
Reimplemented in BlockSwitch, BlockInfLoop, BlockDoWhile, BlockWhileDo, BlockIf, BlockCondition, BlockList, BlockMultiGoto, and BlockGoto.
FlowBlock * BlockGraph::getStartBlock | ( | void | ) | const |
|
staticprotected |
Set properties on the first leaf FlowBlock.
For the given BlockGraph find the first component leaf FlowBlock and set its properties
bl | is the given BlockGraph |
fl | is the property to set |
|
virtual |
Let hierarchical blocks steal labels of their (first) components.
bump | if true, mark that labels for this block are printed by somebody higher in hierarchy |
Reimplemented from FlowBlock.
Reimplemented in BlockInfLoop, BlockDoWhile, and BlockWhileDo.
FlowBlock * BlockGraph::newBlock | ( | void | ) |
BlockBasic * BlockGraph::newBlockBasic | ( | Funcdata * | fd | ) |
Build a new BlockBasic.
Add the new BlockBasic to this
fd | is the function underlying the basic block |
BlockCondition * BlockGraph::newBlockCondition | ( | FlowBlock * | b1, |
FlowBlock * | b2 | ||
) |
Build a new BlockCondition.
Add the new BlockCondition to this, collapsing its pieces into it.
BlockDoWhile * BlockGraph::newBlockDoWhile | ( | FlowBlock * | condcl | ) |
Build a new BlockDoWhile.
Add the new BlockDoWhile to this, collapsing the condition clause FlowBlock into it.
condcl | is the condition clause FlowBlock |
BlockInfLoop * BlockGraph::newBlockInfLoop | ( | FlowBlock * | body | ) |
Build a new BlockInfLoop.
Add the new BlockInfLoop to this, collapsing the body FlowBlock into it.
body | is the body FlowBlock |
BlockMultiGoto * BlockGraph::newBlockMultiGoto | ( | FlowBlock * | bl, |
int4 | outedge | ||
) |
Build a new BlockMultiGoto.
The given FlowBlock may already be a BlockMultiGoto, otherwise we add the new BlockMultiGoto to this.
bl | is the given FlowBlock with the new goto edge |
outedge | is the index of the outgoing edge to make into a goto |
BlockSwitch * BlockGraph::newBlockSwitch | ( | const vector< FlowBlock * > & | cs, |
bool | hasExit | ||
) |
Build a new BlockSwitch.
Add the new BlockSwitch to this, collapsing all the case FlowBlocks into it.
cs | is the list of case FlowBlocks |
hasExit | is true if the switch has a formal exit |
BlockWhileDo * BlockGraph::newBlockWhileDo | ( | FlowBlock * | cond, |
FlowBlock * | cl | ||
) |
Build a new BlockWhileDo.
Add the new BlockWhileDo to this, collapsing the condition and clause into it.
Get the leaf FlowBlock that will execute after the given FlowBlock.
Within the hierarchy of this FlowBlock, assume the given FlowBlock will fall-thru in its execution at some point. Return the first leaf block (BlockBasic or BlockCopy) that will execute after the given FlowBlock completes, assuming this is a unique block.
bl | is the given FlowBlock |
Reimplemented from FlowBlock.
Reimplemented in BlockSwitch, BlockInfLoop, BlockDoWhile, BlockWhileDo, BlockIf, BlockCondition, BlockMultiGoto, and BlockGoto.
|
inline |
< Sort blocks using the final ordering
|
virtual |
void BlockGraph::removeBlock | ( | FlowBlock * | bl | ) |
Remove a FlowBlock from this BlockGraph.
The indicated block is pulled out of the component list and deleted. Any edges between it and the rest of the BlockGraph are simply removed.
bl | is the indicated block |
void BlockGraph::removeFromFlow | ( | FlowBlock * | bl | ) |
Remove given FlowBlock preserving flow in this.
This should be applied only if the given FlowBlock has 0 or 1 outputs. If there is an output FlowBlock, all incoming edges to the given FlowBlock are moved so they flow into the output FlowBlock, then all remaining edges into or out of the given FlowBlock are removed. The given FlowBlock is not removed from this. This routine doesn't preserve loopedge information
bl | is the given FlowBlock component |
void BlockGraph::removeFromFlowSplit | ( | FlowBlock * | bl, |
bool | flipflow | ||
) |
Remove FlowBlock splitting flow between input and output edges.
Remove the given FlowBlock from the flow of the graph. It must have 2 inputs, and 2 outputs. The edges will be remapped so that
Or if flipflow is true:
bl | is the given FlowBlock |
flipflow | indicates how the edges are remapped |
void BlockGraph::restoreXml | ( | const Element * | el, |
const AddrSpaceManager * | m | ||
) |
Restore this BlockGraph from an XML stream.
This is currently just a wrapper around the FlowBlock::restoreXml() that sets of the BlockMap resolver
el | is the root <block> tag |
m | is the address space manager |
|
virtual |
void BlockGraph::setStartBlock | ( | FlowBlock * | bl | ) |
void BlockGraph::spliceBlock | ( | FlowBlock * | bl | ) |
Splice given FlowBlock together with its output.
The given FlowBlock must have exactly one output. That output must have exactly one input. The output FlowBlock is removed and any outgoing edges it has become outgoing edge of the given FlowBlock. The output FlowBlock is permanently removed. It is viewed as being spliced together with the given FlowBlock.
bl | is the given FlowBlock |
void BlockGraph::structureLoops | ( | vector< FlowBlock * > & | rootlist | ) |
Label loop edges.
rootlist | will contain the entry points for the graph |
|
protected |
Swap the positions two component FlowBlocks.
i | is the position of the first FlowBlock to swap |
j | is the position of the second |
Move an edge from one out FlowBlock to another.
The edge from in to outbefore must already exist. It will get removed and replaced with an edge from in to outafter. The new edge index will be the same as the removed edge, and all other edge ordering will be preserved.