decompiler  1.0.0
Public Member Functions | Private Member Functions | Private Attributes | List of all members
ghidra::BlockWhileDo Class Reference

A loop structure where the condition is checked at the top. More...

#include <block.hh>

Inheritance diagram for ghidra::BlockWhileDo:
ghidra::BlockGraph ghidra::FlowBlock

Public Member Functions

 BlockWhileDo (void)
 Constructor.
 
PcodeOpgetInitializeOp (void) const
 Get root of initialize statement or null.
 
PcodeOpgetIterateOp (void) const
 Get root of iterate statement or null.
 
bool hasOverflowSyntax (void) const
 Does this require overflow syntax.
 
void setOverflowSyntax (void)
 Set that this requires overflow syntax.
 
virtual block_type getType (void) const
 Get the FlowBlock type of this.
 
virtual void markLabelBumpUp (bool bump)
 Let hierarchical blocks steal labels of their (first) components. More...
 
virtual void scopeBreak (int4 curexit, int4 curloopexit)
 Mark unstructured edges that should be breaks.
 
virtual void printHeader (ostream &s) const
 Print a simple description of this to stream. More...
 
virtual void emit (PrintLanguage *lng) const
 Emit the instructions in this FlowBlock as structured code. More...
 
virtual FlowBlocknextFlowAfter (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
 
- Public Member Functions inherited from ghidra::BlockGraph
void clear (void)
 Clear all component FlowBlock objects.
 
virtual ~BlockGraph (void)
 Destructor.
 
const vector< FlowBlock * > & getList (void) const
 Get the list of component FlowBlock objects.
 
int4 getSize (void) const
 Get the number of components.
 
FlowBlockgetBlock (int4 i) const
 Get the i-th component.
 
virtual FlowBlocksubBlock (int4 i) const
 Get the i-th component block.
 
virtual void markUnstructured (void)
 Mark target blocks of any unstructured edges.
 
virtual void printTree (ostream &s, int4 level) const
 Print tree structure of any blocks owned by this. More...
 
virtual void printRaw (ostream &s) const
 Print raw instructions contained in this FlowBlock.
 
virtual void encodeBody (Encoder &encoder) const
 Encode detail about components to a stream.
 
virtual void decodeBody (Decoder &decoder)
 Restore details about this FlowBlock from an element stream. More...
 
void decode (Decoder &decoder)
 Decode this BlockGraph from a 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...
 
FlowBlockgetStartBlock (void) const
 Get the entry point FlowBlock. More...
 
FlowBlocknewBlock (void)
 Build a new plain FlowBlock. More...
 
BlockBasicnewBlockBasic (Funcdata *fd)
 Build a new BlockBasic. More...
 
BlockCopynewBlockCopy (FlowBlock *bl)
 Build a new BlockCopy. More...
 
BlockGotonewBlockGoto (FlowBlock *bl)
 Build a new BlockGoto. More...
 
BlockMultiGotonewBlockMultiGoto (FlowBlock *bl, int4 outedge)
 Build a new BlockMultiGoto. More...
 
BlockListnewBlockList (const vector< FlowBlock *> &nodes)
 Build a new BlockList. More...
 
BlockConditionnewBlockCondition (FlowBlock *b1, FlowBlock *b2)
 Build a new BlockCondition. More...
 
BlockIfnewBlockIfGoto (FlowBlock *cond)
 Build a new BlockIfGoto. More...
 
BlockIfnewBlockIf (FlowBlock *cond, FlowBlock *tc)
 Build a new BlockIf. More...
 
BlockIfnewBlockIfElse (FlowBlock *cond, FlowBlock *tc, FlowBlock *fc)
 Build a new BlockIfElse. More...
 
BlockWhileDonewBlockWhileDo (FlowBlock *cond, FlowBlock *cl)
 Build a new BlockWhileDo. More...
 
BlockDoWhilenewBlockDoWhile (FlowBlock *condcl)
 Build a new BlockDoWhile. More...
 
BlockInfLoopnewBlockInfLoop (FlowBlock *body)
 Build a new BlockInfLoop. More...
 
BlockSwitchnewBlockSwitch (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 ghidra::FlowBlock
 FlowBlock (void)
 Construct a block with no edges.
 
virtual ~FlowBlock (void)
 Destructor.
 
int4 getIndex (void) const
 Get the index assigned to this block.
 
FlowBlockgetParent (void)
 Get the parent FlowBlock of this.
 
FlowBlockgetImmedDom (void) const
 Get the immediate dominator FlowBlock.
 
FlowBlockgetCopyMap (void) const
 Get the mapped FlowBlock.
 
const FlowBlockgetParent (void) const
 Get the parent FlowBlock of this.
 
uint4 getFlags (void) const
 Get the block_flags properties.
 
virtual Address getStart (void) const
 Get the starting address of code in this FlowBlock.
 
virtual Address getStop (void) const
 Get the ending address of code in this FlowBlock.
 
virtual const FlowBlockgetExitLeaf (void) const
 Get the FlowBlock to which this block exits.
 
virtual PcodeOplastOp (void) const
 Get the last PcodeOp executed by this FlowBlock.
 
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 FlowBlockgetSplitPoint (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
 Is this too complex to be a condition (BlockCondition)
 
virtual void encodeHeader (Encoder &encoder) const
 Encode basic information as attributes. More...
 
virtual void decodeHeader (Decoder &decoder)
 Decode basic information from element attributes. More...
 
void encodeEdges (Encoder &encoder) const
 Encode edge information to a stream. More...
 
void decodeEdges (Decoder &decoder, BlockMap &resolver)
 Restore edges from an encoded stream. More...
 
void encode (Encoder &encoder) const
 Encode this to a stream. More...
 
void decode (Decoder &decoder, BlockMap &resolver)
 Decode this from a stream. More...
 
const FlowBlocknextInFlow (void) const
 Return next block to be executed in flow. More...
 
void setVisitCount (int4 i)
 Set the number of times this block has been visited.
 
int4 getVisitCount (void) const
 Get the count of visits.
 
void setGotoBranch (int4 i)
 Mark a goto branch. More...
 
void setDefaultSwitch (int4 pos)
 Mark an edge as the switch default. More...
 
bool isMark (void) const
 Return true if this block has been marked.
 
void setMark (void)
 Mark this block.
 
void clearMark (void)
 Clear any mark on this block.
 
void setDonothingLoop (void)
 Label this as a do nothing loop.
 
void setDead (void)
 Label this as dead.
 
bool hasSpecialLabel (void) const
 Return true if this uses a different label.
 
bool isJoined (void) const
 Return true if this is a joined basic block.
 
bool isDuplicated (void) const
 Return true if this is a duplicated block.
 
void setLoopExit (int4 i)
 Label the edge exiting this as a loop.
 
void clearLoopExit (int4 i)
 Clear the loop exit edge.
 
void setBackEdge (int4 i)
 Label the back edge of a loop.
 
bool getFlipPath (void) const
 Have out edges been flipped.
 
bool isJumpTarget (void) const
 Return true if non-fallthru jump flows into this. More...
 
FlowBlockgetFalseOut (void) const
 Get the false output FlowBlock.
 
FlowBlockgetTrueOut (void) const
 Get the true output FlowBlock.
 
FlowBlockgetOut (int4 i)
 Get the i-th output FlowBlock.
 
const FlowBlockgetOut (int4 i) const
 Get i-th output FlowBlock.
 
int4 getOutRevIndex (int4 i) const
 Get the input index of the i-th output FlowBlock.
 
FlowBlockgetIn (int4 i)
 Get the i-th input FlowBlock.
 
const FlowBlockgetIn (int4 i) const
 Get the i-th input FlowBlock.
 
int4 getInRevIndex (int4 i) const
 Get the output index of the i-th input FlowBlock.
 
const FlowBlockgetFrontLeaf (void) const
 Get the first leaf FlowBlock. More...
 
FlowBlockgetFrontLeaf (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...
 
int4 sizeOut (void) const
 Get the number of out edges.
 
int4 sizeIn (void) const
 Get the number of in edges.
 
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...
 
bool isLoopIn (int4 i) const
 Is the i-th incoming edge a loop edge.
 
bool isLoopOut (int4 i) const
 Is the i-th outgoing edge a loop edge.
 
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 isDefaultBranch (int4 i) const
 Is the i-th out edge the switch default edge.
 
bool isLabelBumpUp (void) const
 Are labels for this printed by the parent.
 
bool isUnstructuredTarget (void) const
 Is this the target of an unstructured goto.
 
bool isInteriorGotoTarget (void) const
 Is there an unstructured goto to this block's interior.
 
bool hasInteriorGoto (void) const
 Is there an unstructured goto out of this block's interior.
 
bool isEntryPoint (void) const
 Is the entry point of the function.
 
bool isSwitchOut (void) const
 Is this a switch block.
 
bool isDonothingLoop (void) const
 Is this a do nothing block.
 
bool isDead (void) const
 Is this block dead.
 
bool isTreeEdgeIn (int4 i) const
 Is the i-th incoming edge part of the spanning tree.
 
bool isBackEdgeIn (int4 i) const
 Is the i-th incoming edge a back edge.
 
bool isBackEdgeOut (int4 i) const
 Is the i-th outgoing edge a back edge.
 
bool isIrreducibleOut (int4 i) const
 Is the i-th outgoing edge an irreducible edge.
 
bool isIrreducibleIn (int4 i) const
 Is the i-th incoming edge an irreducible edge.
 
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.
 
bool isGotoIn (int4 i) const
 Is the i-th incoming edge unstructured.
 
bool isGotoOut (int4 i) const
 Is the i-th outgoing edge unstructured.
 
JumpTablegetJumptable (void) const
 Get the JumpTable associated this block. More...
 

Private Member Functions

void findLoopVariable (PcodeOp *cbranch, BlockBasic *head, BlockBasic *tail, PcodeOp *lastOp)
 Find a loop variable. More...
 
PcodeOpfindInitializer (BlockBasic *head, int4 slot) const
 Find the for-loop initializer op. More...
 
PcodeOptestTerminal (Funcdata &data, int4 slot) const
 Test that given statement is terminal and explicit. More...
 
bool testIterateForm (void) const
 Return false if the iterate statement is of an unacceptable form. More...
 

Private Attributes

PcodeOpinitializeOp
 Statement used as for loop initializer.
 
PcodeOpiterateOp
 Statement used as for loop iterator.
 
PcodeOploopDef
 MULTIEQUAL merging loop variable.
 

Additional Inherited Members

- Public Types inherited from ghidra::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 ghidra::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 FlowBlockfindCommonBlock (FlowBlock *bl1, FlowBlock *bl2)
 Find the common dominator of two FlowBlocks. More...
 
static FlowBlockfindCommonBlock (const vector< FlowBlock *> &blockSet)
 Find common dominator of multiple FlowBlocks. More...
 
- Protected Member Functions inherited from ghidra::BlockGraph
void swapBlocks (int4 i, int4 j)
 Swap the positions two component FlowBlocks. More...
 
- Protected Member Functions inherited from ghidra::FlowBlock
void setFlag (uint4 fl)
 Set a boolean property.
 
void clearFlag (uint4 fl)
 Clear a boolean property.
 
- Static Protected Member Functions inherited from ghidra::BlockGraph
static void markCopyBlock (FlowBlock *bl, uint4 fl)
 Set properties on the first leaf FlowBlock. More...
 

Detailed Description

A loop structure where the condition is checked at the top.

This has exactly two components: one conditional block which evaluates when the loop terminates, and one body block. The conditional block has two outgoing edges, one to the body block and one to the exit block. The body block has one outgoing edge back to the conditional block. The BlockWhileDo instance has exactly one outgoing edge.

Overflow syntax refers to the situation where there is a proper BlockWhileDo structure but the conditional block is too long or complicated to emit as a single conditional expression. An alternate while(true) { } form is used instead.

If an iterator op is provided, the block will be printed using for loop syntax, for(i=0;i<10;++i) where an initializer statement and iterator statement are printed alongside the condition statement. Otherwise, while loop syntax is used while(i<10)

Member Function Documentation

◆ emit()

virtual void ghidra::BlockWhileDo::emit ( PrintLanguage lng) const
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.

Parameters
lngis the PrintLanguage that provides details of the high-level language being printed

Reimplemented from ghidra::BlockGraph.

References ghidra::PrintLanguage::emitBlockWhileDo().

◆ finalizePrinting()

void ghidra::BlockWhileDo::finalizePrinting ( Funcdata data) const
virtual

Assume that finalTransform() has run and that all HighVariable merging has occurred. Do any final tests checking that the initialization and iteration statements are good. Extract initialization and iteration statements from their basic blocks.

Parameters
datais the function containing the loop

Reimplemented from ghidra::BlockGraph.

References ghidra::BlockGraph::finalizePrinting(), and ghidra::Funcdata::opMarkNonPrinting().

◆ finalTransform()

void ghidra::BlockWhileDo::finalTransform ( Funcdata data)
virtual

◆ findInitializer()

PcodeOp * ghidra::BlockWhileDo::findInitializer ( BlockBasic head,
int4  slot 
) const
private

Find the for-loop initializer op.

Given a control flow loop, try to find a putative initializer PcodeOp for the loop variable. The initializer must be read by read by loopDef and by in a block that flows only into the loop. If an initializer is found, then initializeOp is set and the lastOp (not including a branch) in the initializer block is returned. Otherwise null is returned.

Parameters
headis the head block of the loop
slotis the block input coming from the loop tail
Returns
the last PcodeOp in the initializer's block

References ghidra::Varnode::getDef(), ghidra::FlowBlock::getIn(), ghidra::PcodeOp::getParent(), ghidra::PcodeOp::isBranch(), ghidra::PcodeOp::isMarker(), ghidra::Varnode::isWritten(), ghidra::FlowBlock::lastOp(), ghidra::PcodeOp::previousOp(), ghidra::FlowBlock::sizeIn(), and ghidra::FlowBlock::sizeOut().

◆ findLoopVariable()

void ghidra::BlockWhileDo::findLoopVariable ( PcodeOp cbranch,
BlockBasic head,
BlockBasic tail,
PcodeOp lastOp 
)
private

Find a loop variable.

Try to find a Varnode that represents the controlling loop variable for this loop. The Varnode must be:

  • tested by the exit condition
  • have a MULTIEQUAL in the head block
  • have a modification coming in from the tail block
  • the modification must be the last op or moveable to the last op

If the loop variable is found, this routine sets the iterateOp and the loopDef.

Parameters
cbranchis the CBRANCH implementing the loop exit
headis the head basic-block of the loop
tailis the tail basic-block of the loop
lastOpis the precomputed last PcodeOp of tail that isn't a BRANCH

References ghidra::PcodeOp::code(), ghidra::CPUI_MULTIEQUAL, ghidra::Varnode::getDef(), ghidra::PcodeOp::getIn(), ghidra::FlowBlock::getOutRevIndex(), ghidra::PcodeOp::getParent(), ghidra::PcodeOp::isCall(), ghidra::PcodeOp::isMarker(), ghidra::PcodeOp::isMoveable(), ghidra::Varnode::isWritten(), ghidra::PcodeOp::numInput(), ghidra::PcodeOpNode::op, and ghidra::PcodeOpNode::slot.

◆ markLabelBumpUp()

void ghidra::BlockWhileDo::markLabelBumpUp ( bool  bump)
virtual

Let hierarchical blocks steal labels of their (first) components.

Parameters
bumpif true, mark that labels for this block are printed by somebody higher in hierarchy

Reimplemented from ghidra::BlockGraph.

References ghidra::BlockGraph::markLabelBumpUp().

◆ nextFlowAfter()

FlowBlock * ghidra::BlockWhileDo::nextFlowAfter ( const FlowBlock bl) const
virtual

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.

Parameters
blis the given FlowBlock
Returns
the next FlowBlock to execute or NULL

Reimplemented from ghidra::BlockGraph.

References ghidra::FlowBlock::getFrontLeaf().

◆ printHeader()

void ghidra::BlockWhileDo::printHeader ( ostream &  s) const
virtual

Print a simple description of this to stream.

Only print a header for this single block

Parameters
sis the output stream

Reimplemented from ghidra::FlowBlock.

References ghidra::FlowBlock::printHeader().

◆ testIterateForm()

bool ghidra::BlockWhileDo::testIterateForm ( void  ) const
private

Return false if the iterate statement is of an unacceptable form.

Make sure the loop variable is involved as input in the iterator statement.

Returns
true if the loop variable is an input to the iterator statement

References ghidra::Varnode::getDef(), ghidra::Varnode::getHigh(), ghidra::Varnode::isAnnotation(), ghidra::Varnode::isExplicit(), and ghidra::Varnode::isWritten().

◆ testTerminal()

PcodeOp * ghidra::BlockWhileDo::testTerminal ( Funcdata data,
int4  slot 
) const
private

Test that given statement is terminal and explicit.

For-loop initializer or iterator statements must be the final statement in their respective basic block. This method tests that iterateOp/initializeOp (specified by slot) is the root of or can be turned into the root of a terminal statement. The root output must be an explicit variable being read by the loopDef MULTIEQUAL at the top of the loop. If the root is not the last PcodeOp in the block, an attempt is made to move it. Return the root PcodeOp if all these conditions are met, otherwise return null.

Parameters
datais the function containing the while loop
slotis the slot read by loopDef from the output of the statement
Returns
an explicit statement or null

References ghidra::PcodeOp::code(), ghidra::CPUI_COPY, ghidra::Varnode::getDef(), ghidra::PcodeOp::getIn(), ghidra::FlowBlock::getIn(), ghidra::PcodeOp::getParent(), ghidra::FlowBlock::getParent(), ghidra::PcodeOp::isBranch(), ghidra::Varnode::isExplicit(), ghidra::Varnode::isWritten(), ghidra::BlockBasic::lastOp(), ghidra::Funcdata::moveRespectingCover(), ghidra::PcodeOp::notPrinted(), and ghidra::PcodeOp::previousOp().


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