Ghidra Decompiler Analysis Engine
|
A basic block for p-code operations. More...
#include <block.hh>
Public Member Functions | |
Address | getEntryAddr (void) const |
Get the address of the (original) first operation to execute. More... | |
virtual Address | getStart (void) const |
virtual Address | getStop (void) const |
virtual block_type | getType (void) const |
virtual FlowBlock * | subBlock (int4 i) 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... | |
virtual void | printHeader (ostream &s) const |
Print a simple description of this to stream. More... | |
virtual void | printRaw (ostream &s) const |
virtual void | emit (PrintLanguage *lng) const |
Emit the instructions in this FlowBlock as structured code. More... | |
virtual const FlowBlock * | getExitLeaf (void) const |
virtual PcodeOp * | lastOp (void) const |
virtual bool | negateCondition (bool toporbottom) |
Flip the condition computed by this. 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 bool | isComplex (void) const |
bool | unblockedMulti (int4 outslot) const |
Check if this block can be removed without introducing inconsistencies. More... | |
bool | hasOnlyMarkers (void) const |
Does this block contain only MULTIEQUAL and INDIRECT ops. More... | |
bool | isDoNothing (void) const |
Should this block should be removed. More... | |
Public Member Functions inherited from FlowBlock | |
FlowBlock (void) | |
Construct a block with no edges. | |
virtual void | markLabelBumpUp (bool bump) |
Let hierarchical blocks steal labels of their (first) components. More... | |
virtual void | printTree (ostream &s, int4 level) const |
Print tree structure of any blocks owned by this. More... | |
virtual bool | preferComplement (Funcdata &data) |
Rearrange this hierarchy to simplify boolean expressions. More... | |
virtual FlowBlock * | nextFlowAfter (const FlowBlock *bl) const |
Get the leaf FlowBlock that will execute after the given FlowBlock. 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... | |
Static Public Member Functions | |
static bool | noInterveningStatement (PcodeOp *first, int4 path, PcodeOp *last) |
Check if there is meaningful activity between two branch instructions. 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... | |
Friends | |
class | Funcdata |
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... | |
A basic block for p-code operations.
A basic block is a maximal sequence of p-code operations (PcodeOp) that, within the context of a function, always execute starting with the first operation in sequence through in order to the last operation. Any decision points in the control flow of a function manifest as branching operations (BRANCH, CBRANCH, BRANCHIND) that necessarily occur as the last operation in a basic block.
Every Funcdata object implements the control-flow graph of the underlying function using BlockBasic objects as the underlying nodes of the graph. The decompiler structures code by making a copy of this graph and then overlaying a hierarchy of structured nodes on top of it.
The block also keeps track of the original range of addresses of instructions constituting the block. As decompiler transformations progress, the set of addresses associated with the current set of PcodeOps my migrate away from this original range.
|
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.
|
virtual |
Perform the flip to normalize conditional branch executed by this block.
This reverses the outgoing edge order in the right basic blocks, but does not modify the instructions directly.
Reimplemented from FlowBlock.
|
virtual |
Test normalizing the conditional branch in this.
Find the set of PcodeOp objects that need to be adjusted to flip the condition this FlowBlock calculates.
Return:
fliplist | will contain the PcodeOps that need to be adjusted |
Reimplemented from FlowBlock.
Address BlockBasic::getEntryAddr | ( | void | ) | const |
Get the address of the (original) first operation to execute.
This relies slightly on normal semantics: when instructions fall-thru during execution, the associated address increases.
|
virtual |
Get the leaf splitting block.
If this block ends with a conditional branch, return the deepest component block that performs the split. This component needs to be able to perform flipInPlaceTest() and flipInPlaceExecute()
Reimplemented from FlowBlock.
bool BlockBasic::hasOnlyMarkers | ( | void | ) | const |
Does this block contain only MULTIEQUAL and INDIRECT ops.
This is a crucial test for whether this block is doing anything substantial or is a candidate for removal. Even blocks that "do nothing" have some kind of branch and placeholder operations (MULTIEQUAL and INDIRECT) for data flowing through the block. This tests if there is any other operation going on.
bool BlockBasic::isDoNothing | ( | void | ) | const |
Should this block should be removed.
Check if this block is doing anything useful.
|
virtual |
Flip the condition computed by this.
Flip the order of outgoing edges (at least). This should also affect the original op causing the condition. Note: we don't have to flip at all levels of the hierarchy only at the top and at the bottom
toporbottom | is true if this is the top outermost block of the hierarchy getting negated |
Reimplemented from FlowBlock.
Check if there is meaningful activity between two branch instructions.
The first branch is assumed to be a CBRANCH one edge of which flows into the other branch. The flow can be through 1 or 2 blocks. If either block performs an operation other than MULTIEQUAL, INDIRECT (or the branch), then return false.
first | is the CBRANCH operation |
path | is the index of the edge to follow to the other branch |
last | is the other branch operation |
|
virtual |
Print a simple description of this to stream.
Only print a header for this single block
s | is the output stream |
Reimplemented from FlowBlock.
|
virtual |
bool BlockBasic::unblockedMulti | ( | int4 | outslot | ) | const |
Check if this block can be removed without introducing inconsistencies.
Does removing this block leads to redundant MULTIEQUAL entries which are inconsistent. A MULTIEQUAL can hide an implied copy, in which case this block is actually doing something and shouldn't be removed.
outslot | is the index of the outblock that this is getting collapsed to |