My Project
block.hh
Go to the documentation of this file.
1 /* ###
2  * IP: GHIDRA
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
18 
19 #ifndef __CPUI_BLOCK__
20 #define __CPUI_BLOCK__
21 
22 #include "jumptable.hh"
23 
24 class BlockBasic; // Forward declarations
25 class BlockList;
26 class BlockCopy;
27 class BlockGoto;
28 class BlockMultiGoto;
29 class BlockCondition;
30 class BlockIf;
31 class BlockWhileDo;
32 class BlockDoWhile;
33 class BlockInfLoop;
34 class BlockSwitch;
35 class PrintLanguage;
36 class BlockMap;
37 
44 struct BlockEdge {
45  uint4 label;
48  BlockEdge(void) {}
49  BlockEdge(FlowBlock *pt,uint4 lab,int4 rev) { label=lab; point=pt; reverse_index = rev; }
50  void saveXml(ostream &s) const;
51  void restoreXml(const Element *el,BlockMap &resolver);
52 };
53 
60 class FlowBlock {
61  friend class BlockGraph;
62 public:
64  enum block_type {
65  t_plain, t_basic, t_graph, t_copy, t_goto, t_multigoto, t_ls,
66  t_condition, t_if, t_whiledo, t_dowhile, t_switch, t_infloop
67  };
75  enum block_flags {
79  f_switch_out = 0x10,
81  f_mark = 0x80,
82  f_mark2 = 0x100,
83  f_entry_point = 0x200,
86  f_label_bumpup = 0x1000,
87  f_donothing_loop = 0x2000,
88  f_dead = 0x4000,
90  f_flip_path = 0x10000,
91  f_joined_block = 0x20000,
92  f_duplicate_block = 0x40000
93  };
95  enum edge_flags {
100  f_tree_edge = 0x10,
101  f_forward_edge = 0x20,
102  f_cross_edge = 0x40,
103  f_back_edge = 0x80,
105  };
106 private:
107  uint4 flags;
108  FlowBlock *parent;
109  FlowBlock *immed_dom;
110  FlowBlock *copymap;
111  int4 index;
112  int4 visitcount;
113  int4 numdesc;
114  vector<BlockEdge> intothis;
115  vector<BlockEdge> outofthis;
116  // If there are two possible outputs as the
117  // result of a conditional branch
118  // the first block in outofthis should be
119  // the result of the condition being false
120  static void replaceEdgeMap(vector<BlockEdge> &vec);
121  void addInEdge(FlowBlock *b,uint4 lab);
122  void restoreNextInEdge(const Element *el,BlockMap &resolver);
123  void halfDeleteInEdge(int4 slot);
124  void halfDeleteOutEdge(int4 slot);
125  void removeInEdge(int4 slot);
126  void removeOutEdge(int4 slot);
127  void replaceInEdge(int4 num,FlowBlock *b);
128  void replaceOutEdge(int4 num,FlowBlock *b);
129  void replaceEdgesThru(int4 in,int4 out);
130  void swapEdges(void);
131  void setOutEdgeFlag(int4 i,uint4 lab);
132  void clearOutEdgeFlag(int4 i,uint4 lab);
133  void eliminateInDups(FlowBlock *bl);
134  void eliminateOutDups(FlowBlock *bl);
135  static void findDups(const vector<BlockEdge> &ref,vector<FlowBlock *> &duplist);
136  void dedup(void);
137  void replaceUsingMap(void);
138 #ifdef BLOCKCONSISTENT_DEBUG
139  void checkEdges(void);
140 #endif
141 protected:
142  void setFlag(uint4 fl) { flags |= fl; }
143  void clearFlag(uint4 fl) { flags &= ~fl; }
144 public:
145  FlowBlock(void);
146  virtual ~FlowBlock(void) {}
147  int4 getIndex(void) const { return index; }
148  FlowBlock *getParent(void) { return parent; }
149  FlowBlock *getImmedDom(void) const { return immed_dom; }
150  FlowBlock *getCopyMap(void) const { return copymap; }
151  const FlowBlock *getParent(void) const { return (const FlowBlock *) parent; }
152  uint4 getFlags(void) const { return flags; }
153  virtual Address getStart(void) const { return Address(); }
154  virtual Address getStop(void) const { return Address(); }
155  virtual block_type getType(void) const { return t_plain; }
156  virtual FlowBlock *subBlock(int4 i) const { return (FlowBlock *)0; }
157  virtual void markUnstructured(void) {}
158  virtual void markLabelBumpUp(bool bump);
159  virtual void scopeBreak(int4 curexit,int4 curloopexit) {}
160  virtual void printHeader(ostream &s) const;
161  virtual void printTree(ostream &s,int4 level) const;
162  virtual void printRaw(ostream &s) const {}
163  virtual void emit(PrintLanguage *lng) const;
164  virtual const FlowBlock *getExitLeaf(void) const { return (const FlowBlock *)0; }
165  virtual PcodeOp *lastOp(void) const { return (PcodeOp *)0; }
166  virtual bool negateCondition(bool toporbottom);
167  virtual bool preferComplement(Funcdata &data);
168  virtual FlowBlock *getSplitPoint(void);
169  virtual int4 flipInPlaceTest(vector<PcodeOp *> &fliplist) const;
170  virtual void flipInPlaceExecute(void);
171  virtual bool isComplex(void) const { return true; }
172  virtual FlowBlock *nextFlowAfter(const FlowBlock *bl) const;
173  virtual void orderSwitchCases(void) const {}
174  virtual void saveXmlHeader(ostream &s) const;
175  virtual void restoreXmlHeader(const Element *el);
176  virtual void saveXmlBody(ostream &s) const {}
177 
183  virtual void restoreXmlBody(List::const_iterator &iter,List::const_iterator enditer,BlockMap &resolver) {}
184  void saveXmlEdges(ostream &s) const;
185  void restoreXmlEdges(List::const_iterator &iter,List::const_iterator enditer,BlockMap &resolver);
186  void saveXml(ostream &s) const;
187  void restoreXml(const Element *el,BlockMap &resolver);
188  const FlowBlock *nextInFlow(void) const;
189  void setVisitCount(int4 i) { visitcount = i; }
190  int4 getVisitCount(void) const { return visitcount; }
191  void setGotoBranch(int4 i);
192  void setDefaultSwitch(int4 i) { setOutEdgeFlag(i,f_defaultswitch_edge); }
193  bool isMark(void) const { return ((flags&f_mark)!=0); }
194  void setMark(void) { flags |= f_mark; }
195  void clearMark(void) { flags &= ~f_mark; }
196  void setDonothingLoop(void) { flags |= f_donothing_loop; }
197  void setDead(void) { flags |= f_dead; }
198  bool hasSpecialLabel(void) const { return ((flags&(f_joined_block|f_duplicate_block))!=0); }
199  bool isJoined(void) const { return ((flags&f_joined_block)!=0); }
200  bool isDuplicated(void) const { return ((flags&f_duplicate_block)!=0); }
201  void setLoopExit(int4 i) { setOutEdgeFlag(i,f_loop_exit_edge); }
202  void clearLoopExit(int4 i) { clearOutEdgeFlag(i,f_loop_exit_edge); }
203  void setBackEdge(int4 i) { setOutEdgeFlag(i,f_back_edge); }
204  bool getFlipPath(void) const { return ((flags & f_flip_path)!=0); }
205  bool isJumpTarget(void) const;
206  FlowBlock *getFalseOut(void) const { return outofthis[0].point; }
207  FlowBlock *getTrueOut(void) const { return outofthis[1].point; }
208  FlowBlock *getOut(int4 i) { return outofthis[i].point; }
209  const FlowBlock *getOut(int4 i) const { return (const FlowBlock *) outofthis[i].point; }
210  int4 getOutRevIndex(int4 i) const { return outofthis[i].reverse_index; }
211  FlowBlock *getIn(int4 i) { return intothis[i].point; }
212  const FlowBlock *getIn(int4 i) const { return (const FlowBlock *) intothis[i].point; }
213  int4 getInRevIndex(int4 i) const { return intothis[i].reverse_index; }
214  const FlowBlock *getFrontLeaf(void) const;
215  FlowBlock *getFrontLeaf(void);
216  int4 calcDepth(const FlowBlock *leaf) const;
217  bool dominates(const FlowBlock *subBlock) const;
218  bool restrictedByConditional(const FlowBlock *cond) const;
219  int4 sizeOut(void) const { return outofthis.size(); }
220  int4 sizeIn(void) const { return intothis.size(); }
221  bool hasLoopIn(void) const;
222  bool hasLoopOut(void) const;
223  bool isLoopIn(int4 i) const { return ((intothis[i].label & f_loop_edge)!=0); }
224  bool isLoopOut(int4 i) const { return ((outofthis[i].label & f_loop_edge)!=0); }
225  int4 getInIndex(const FlowBlock *bl) const;
226  int4 getOutIndex(const FlowBlock *bl) const;
227  bool isDefaultBranch(int4 i) const { return ((outofthis[i].label & f_defaultswitch_edge)!=0); }
228  bool isLabelBumpUp(void) const { return ((flags & f_label_bumpup)!=0); }
229  bool isUnstructuredTarget(void) const { return ((flags & f_unstructured_targ)!=0); }
230  bool isInteriorGotoTarget(void) const { return ((flags & f_interior_gotoin)!=0); }
231  bool hasInteriorGoto(void) const { return ((flags & f_interior_gotoout)!=0); }
232  bool isEntryPoint(void) const { return ((flags&f_entry_point)!=0); }
233  bool isSwitchOut(void) const { return ((flags&f_switch_out)!=0); }
234  bool isDonothingLoop(void) const { return ((flags&f_donothing_loop)!=0); }
235  bool isDead(void) const { return ((flags & f_dead)!=0); }
236  bool isTreeEdgeIn(int4 i) const { return ((intothis[i].label & f_tree_edge)!=0); }
237  bool isBackEdgeIn(int4 i) const { return ((intothis[i].label & f_back_edge)!=0); }
238  bool isBackEdgeOut(int4 i) const { return ((outofthis[i].label & f_back_edge)!=0); }
239  bool isIrreducibleOut(int4 i) const { return ((outofthis[i].label & f_irreducible)!=0); }
240  bool isIrreducibleIn(int4 i) const { return ((intothis[i].label & f_irreducible)!=0); }
241 
243  bool isDecisionOut(int4 i) const { return ((outofthis[i].label & (f_irreducible|f_back_edge|f_goto_edge))==0); }
244 
246  bool isDecisionIn(int4 i) const { return ((intothis[i].label & (f_irreducible|f_back_edge|f_goto_edge))==0); }
247 
249  bool isLoopDAGOut(int4 i) const { return ((outofthis[i].label & (f_irreducible|f_back_edge|f_loop_exit_edge|f_goto_edge))==0); }
250 
252  bool isLoopDAGIn(int4 i) const { return ((intothis[i].label & (f_irreducible|f_back_edge|f_loop_exit_edge|f_goto_edge))==0); }
253  bool isGotoIn(int4 i) const { return ((intothis[i].label & (f_irreducible|f_goto_edge))!=0); }
254  bool isGotoOut(int4 i) const { return ((outofthis[i].label & (f_irreducible|f_goto_edge))!=0); }
255  JumpTable *getJumptable(void) const;
256  static block_type nameToType(const string &name);
257  static string typeToName(block_type bt);
258  static bool compareBlockIndex(const FlowBlock *bl1,const FlowBlock *bl2);
259  static bool compareFinalOrder(const FlowBlock *bl1,const FlowBlock *bl2);
260  static FlowBlock *findCommonBlock(FlowBlock *bl1,FlowBlock *bl2);
261  static FlowBlock *findCommonBlock(const vector<FlowBlock *> &blockSet);
262 };
263 
270 class BlockGraph : public FlowBlock {
271  vector<FlowBlock *> list;
272  void addBlock(FlowBlock *bl);
273  void forceOutputNum(int4 i);
274  void selfIdentify(void);
275  void identifyInternal(BlockGraph *ident,const vector<FlowBlock *> &nodes);
276  void clearEdgeFlags(uint4 flags);
277  static FlowBlock *createVirtualRoot(const vector<FlowBlock *> &rootlist);
278  void findSpanningTree(vector<FlowBlock *> &preorder,vector<FlowBlock *> &rootlist);
279  bool findIrreducible(const vector<FlowBlock *> &preorder,int4 &irreduciblecount);
280  void forceFalseEdge(const FlowBlock *out0);
281 protected:
282  void swapBlocks(int4 i,int4 j);
283  static void markCopyBlock(FlowBlock *bl,uint4 fl);
284 public:
285  void clear(void);
286  virtual ~BlockGraph(void) { clear(); }
287  const vector<FlowBlock *> &getList(void) const { return list; }
288  int4 getSize(void) const { return list.size(); }
289  FlowBlock *getBlock(int4 i) const { return list[i]; }
290  virtual block_type getType(void) const { return t_graph; }
291  virtual FlowBlock *subBlock(int4 i) const { return list[i]; }
292  virtual void markUnstructured(void);
293  virtual void markLabelBumpUp(bool bump);
294  virtual void scopeBreak(int4 curexit,int4 curloopexit);
295  virtual void printTree(ostream &s,int4 level) const;
296  virtual void printRaw(ostream &s) const;
297  virtual void emit(PrintLanguage *lng) const { lng->emitBlockGraph(this); }
298  virtual FlowBlock *nextFlowAfter(const FlowBlock *bl) const;
299  virtual void orderSwitchCases(void) const;
300  virtual void saveXmlBody(ostream &s) const;
301  virtual void restoreXmlBody(List::const_iterator &iter,List::const_iterator enditer,BlockMap &resolver);
302  void restoreXml(const Element *el,const AddrSpaceManager *m);
303  void addEdge(FlowBlock *begin,FlowBlock *end);
304  void addLoopEdge(FlowBlock *begin,int4 outindex);
305  void removeEdge(FlowBlock *begin,FlowBlock *end);
306  void switchEdge(FlowBlock *in,FlowBlock *outbefore,FlowBlock *outafter);
307  void moveOutEdge(FlowBlock *blold,int4 slot,FlowBlock *blnew);
308  void removeBlock(FlowBlock *bl);
309  void removeFromFlow(FlowBlock *bl);
310  void removeFromFlowSplit(FlowBlock *bl,bool flipflow);
311  void spliceBlock(FlowBlock *bl);
312  void setStartBlock(FlowBlock *bl);
313  FlowBlock *getStartBlock(void) const;
314  // Factory functions
315  FlowBlock *newBlock(void);
316  BlockBasic *newBlockBasic(Funcdata *fd);
317 
318  // Factory (identify) routines
319  BlockCopy *newBlockCopy(FlowBlock *bl);
320  BlockGoto *newBlockGoto(FlowBlock *bl);
321  BlockMultiGoto *newBlockMultiGoto(FlowBlock *bl,int4 outedge);
322  BlockList *newBlockList(const vector<FlowBlock *> &nodes);
323  BlockCondition *newBlockCondition(FlowBlock *b1,FlowBlock *b2);
324  BlockIf *newBlockIfGoto(FlowBlock *cond);
325  BlockIf *newBlockIf(FlowBlock *cond,FlowBlock *tc);
326  BlockIf *newBlockIfElse(FlowBlock *cond,FlowBlock *tc,FlowBlock *fc);
327  BlockWhileDo *newBlockWhileDo(FlowBlock *cond,FlowBlock *cl);
328  BlockDoWhile *newBlockDoWhile(FlowBlock *condcl);
329  BlockInfLoop *newBlockInfLoop(FlowBlock *body);
330  BlockSwitch *newBlockSwitch(const vector<FlowBlock *> &cs,bool hasExit);
331 
332  void orderBlocks(void) {
333  if (list.size()!=1) sort(list.begin(),list.end(),compareFinalOrder); }
334  void buildCopy(const BlockGraph &graph);
335  void clearVisitCount(void);
336  void calcForwardDominator(const vector<FlowBlock *> &rootlist);
337  void buildDomTree(vector<vector<FlowBlock *> > &child) const;
338  int4 buildDomDepth(vector<int4> &depth) const;
339  void buildDomSubTree(vector<FlowBlock *> &res,FlowBlock *root) const;
340  void calcLoop(void);
341  void collectReachable(vector<FlowBlock *> &res,FlowBlock *bl,bool un) const;
342  void structureLoops(vector<FlowBlock *> &rootlist);
343 #ifdef BLOCKCONSISTENT_DEBUG
344  bool isConsistent(void) const;
345 #endif
346 };
347 
363 class BlockBasic: public FlowBlock {
364  friend class Funcdata; // Only uses private functions
365  list<PcodeOp *> op;
366  Funcdata *data;
367  RangeList cover;
368  void insert(list<PcodeOp *>::iterator iter,PcodeOp *inst);
369  void setInitialRange(const Address &beg,const Address &end);
370  void copyRange(const BlockBasic *bb) { cover = bb->cover; }
371  void mergeRange(const BlockBasic *bb) { cover.merge(bb->cover); }
372  void setOrder(void);
373  void removeOp(PcodeOp *inst);
374 public:
375  BlockBasic(Funcdata *fd) { data = fd; }
376  Funcdata *getFuncdata(void) { return data; }
377  const Funcdata *getFuncdata(void) const { return (const Funcdata *)data; }
378  bool contains(const Address &addr) const { return cover.inRange(addr, 1); }
379  Address getEntryAddr(void) const;
380  virtual Address getStart(void) const;
381  virtual Address getStop(void) const;
382  virtual block_type getType(void) const { return t_basic; }
383  virtual FlowBlock *subBlock(int4 i) const { return (FlowBlock *)0; }
384  virtual void saveXmlBody(ostream &s) const;
385  virtual void restoreXmlBody(List::const_iterator &iter,List::const_iterator enditer,BlockMap &resolver);
386  virtual void printHeader(ostream &s) const;
387  virtual void printRaw(ostream &s) const;
388  virtual void emit(PrintLanguage *lng) const { lng->emitBlockBasic(this); }
389  virtual const FlowBlock *getExitLeaf(void) const { return this; }
390  virtual PcodeOp *lastOp(void) const;
391  virtual bool negateCondition(bool toporbottom);
392  virtual FlowBlock *getSplitPoint(void);
393  virtual int4 flipInPlaceTest(vector<PcodeOp *> &fliplist) const;
394  virtual void flipInPlaceExecute(void);
395  virtual bool isComplex(void) const;
396  bool unblockedMulti(int4 outslot) const;
397  bool hasOnlyMarkers(void) const;
398  bool isDoNothing(void) const;
399  list<PcodeOp *>::iterator beginOp(void) { return op.begin(); }
400  list<PcodeOp *>::iterator endOp(void) { return op.end(); }
401  list<PcodeOp *>::const_iterator beginOp(void) const { return op.begin(); }
402  list<PcodeOp *>::const_iterator endOp(void) const { return op.end(); }
403  bool emptyOp(void) const { return op.empty(); }
404  static bool noInterveningStatement(PcodeOp *first,int4 path,PcodeOp *last);
405 };
406 
417 class BlockCopy : public FlowBlock {
418  FlowBlock *copy;
419 public:
420  BlockCopy(FlowBlock *bl) { copy = bl; }
421  virtual FlowBlock *subBlock(int4 i) const { return copy; }
422  virtual block_type getType(void) const { return t_copy; }
423  virtual void printHeader(ostream &s) const;
424  virtual void printTree(ostream &s,int4 level) const;
425  virtual void printRaw(ostream &s) const { copy->printRaw(s); }
426  virtual void emit(PrintLanguage *lng) const { lng->emitBlockCopy(this); }
427  virtual const FlowBlock *getExitLeaf(void) const { return this; }
428  virtual PcodeOp *lastOp(void) const { return copy->lastOp(); }
429  virtual bool negateCondition(bool toporbottom) { bool res = copy->negateCondition(true); FlowBlock::negateCondition(toporbottom); return res; }
430  virtual FlowBlock *getSplitPoint(void) { return copy->getSplitPoint(); }
431  virtual bool isComplex(void) const { return copy->isComplex(); }
432  virtual void saveXmlHeader(ostream &s) const;
433 };
434 
442 class BlockGoto : public BlockGraph {
443  FlowBlock *gototarget;
444  uint4 gototype;
445 public:
446  BlockGoto(FlowBlock *bl) { gototarget = bl; gototype = f_goto_goto; }
447  FlowBlock *getGotoTarget(void) const { return gototarget; }
448  uint4 getGotoType(void) const { return gototype; }
449  bool gotoPrints(void) const;
450  virtual block_type getType(void) const { return t_goto; }
451  virtual void markUnstructured(void);
452  virtual void scopeBreak(int4 curexit,int4 curloopexit);
453  virtual void printHeader(ostream &s) const;
454  virtual void printRaw(ostream &s) const { getBlock(0)->printRaw(s); }
455  virtual void emit(PrintLanguage *lng) const { lng->emitBlockGoto(this); }
456  virtual const FlowBlock *getExitLeaf(void) const { return getBlock(0)->getExitLeaf(); }
457  virtual PcodeOp *lastOp(void) const { return getBlock(0)->lastOp(); }
458  virtual FlowBlock *nextFlowAfter(const FlowBlock *bl) const;
459  virtual void saveXmlBody(ostream &s) const;
460 };
461 
468 class BlockMultiGoto : public BlockGraph {
469  vector<FlowBlock *> gotoedges;
470  bool defaultswitch;
471 public:
472  BlockMultiGoto(FlowBlock *bl) { defaultswitch = false; }
473  void setDefaultGoto(void) { defaultswitch = true; }
474  bool hasDefaultGoto(void) const { return defaultswitch; }
475  void addEdge(FlowBlock *bl) { gotoedges.push_back(bl); }
476  int4 numGotos(void) const { return gotoedges.size(); }
477  FlowBlock *getGoto(int4 i) const { return gotoedges[i]; }
478 
479  virtual block_type getType(void) const { return t_multigoto; }
480  virtual void scopeBreak(int4 curexit,int4 curloopexit);
481  virtual void printHeader(ostream &s) const;
482  virtual void printRaw(ostream &s) const { getBlock(0)->printRaw(s); }
483  virtual void emit(PrintLanguage *lng) const { getBlock(0)->emit(lng); }
484  virtual const FlowBlock *getExitLeaf(void) const { return getBlock(0)->getExitLeaf(); }
485  virtual PcodeOp *lastOp(void) const { return getBlock(0)->lastOp(); }
486  virtual FlowBlock *nextFlowAfter(const FlowBlock *bl) const;
487  virtual void saveXmlBody(ostream &s) const;
488 };
489 
495 class BlockList : public BlockGraph {
496 public:
497  virtual block_type getType(void) const { return t_ls; }
498  virtual void printHeader(ostream &s) const;
499  virtual void emit(PrintLanguage *lng) const { lng->emitBlockLs(this); }
500  virtual const FlowBlock *getExitLeaf(void) const;
501  virtual PcodeOp *lastOp(void) const;
502  virtual bool negateCondition(bool toporbottom);
503  virtual FlowBlock *getSplitPoint(void);
504 };
505 
516 class BlockCondition : public BlockGraph {
517  OpCode opc;
518 public:
519  BlockCondition(OpCode c) { opc = c; }
520  OpCode getOpcode(void) const { return opc; }
521  virtual block_type getType(void) const { return t_condition; }
522  virtual void scopeBreak(int4 curexit,int4 curloopexit);
523  virtual void printHeader(ostream &s) const;
524  virtual void emit(PrintLanguage *lng) const { lng->emitBlockCondition(this); }
525  virtual bool negateCondition(bool toporbottom);
526  virtual FlowBlock *getSplitPoint(void) { return this; }
527  virtual int4 flipInPlaceTest(vector<PcodeOp *> &fliplist) const;
528  virtual void flipInPlaceExecute(void);
529  virtual PcodeOp *lastOp(void) const;
530  virtual bool isComplex(void) const { return getBlock(0)->isComplex(); }
531  virtual FlowBlock *nextFlowAfter(const FlowBlock *bl) const;
532  virtual void saveXmlHeader(ostream &s) const;
533 };
534 
553 class BlockIf : public BlockGraph {
554  uint4 gototype;
555  FlowBlock *gototarget;
556 public:
557  BlockIf(void) { gototype = f_goto_goto; gototarget = (FlowBlock *)0; }
558  void setGotoTarget(FlowBlock *bl) { gototarget = bl; }
559  FlowBlock *getGotoTarget(void) const { return gototarget; }
560  uint4 getGotoType(void) const { return gototype; }
561  virtual block_type getType(void) const { return t_if; }
562  virtual void markUnstructured(void);
563  virtual void scopeBreak(int4 curexit,int4 curloopexit);
564  virtual void printHeader(ostream &s) const;
565  virtual void emit(PrintLanguage *lng) const { lng->emitBlockIf(this); }
566  virtual bool preferComplement(Funcdata &data);
567  virtual const FlowBlock *getExitLeaf(void) const;
568  virtual PcodeOp *lastOp(void) const;
569  virtual FlowBlock *nextFlowAfter(const FlowBlock *bl) const;
570  virtual void saveXmlBody(ostream &s) const;
571 };
572 
583 class BlockWhileDo : public BlockGraph {
584 public:
585  bool hasOverflowSyntax(void) const { return ((getFlags() & f_whiledo_overflow)!=0); }
586  void setOverflowSyntax(void) { setFlag(f_whiledo_overflow); }
587  virtual block_type getType(void) const { return t_whiledo; }
588  virtual void markLabelBumpUp(bool bump);
589  virtual void scopeBreak(int4 curexit,int4 curloopexit);
590  virtual void printHeader(ostream &s) const;
591  virtual void emit(PrintLanguage *lng) const { lng->emitBlockWhileDo(this); }
592  virtual FlowBlock *nextFlowAfter(const FlowBlock *bl) const;
593 };
594 
599 class BlockDoWhile : public BlockGraph {
600 public:
601  virtual block_type getType(void) const { return t_dowhile; }
602  virtual void markLabelBumpUp(bool bump);
603  virtual void scopeBreak(int4 curexit,int4 curloopexit);
604  virtual void printHeader(ostream &s) const;
605  virtual void emit(PrintLanguage *lng) const { lng->emitBlockDoWhile(this); }
606  virtual FlowBlock *nextFlowAfter(const FlowBlock *bl) const;
607 };
608 
613 class BlockInfLoop : public BlockGraph {
614 public:
615  virtual block_type getType(void) const { return t_infloop; }
616  virtual void markLabelBumpUp(bool bump);
617  virtual void scopeBreak(int4 curexit,int4 curloopexit);
618  virtual void printHeader(ostream &s) const;
619  virtual void emit(PrintLanguage *lng) const { lng->emitBlockInfLoop(this); }
620  virtual FlowBlock *nextFlowAfter(const FlowBlock *bl) const;
621 };
622 
630 class BlockSwitch : public BlockGraph {
631  JumpTable *jump;
632  struct CaseOrder {
634  FlowBlock *block;
635  const FlowBlock *basicblock;
636  uintb label;
637  int4 depth;
638  int4 chain;
639  int4 outindex;
640  uint4 gototype;
641  bool isexit;
642  bool isdefault;
643  static bool compare(const CaseOrder &a,const CaseOrder &b);
644  };
645  mutable vector<CaseOrder> caseblocks;
646  void addCase(FlowBlock *switchbl,FlowBlock *bl,uint4 gt);
647 public:
648  BlockSwitch(FlowBlock *ind);
649  void grabCaseBasic(FlowBlock *switchbl,const vector<FlowBlock *> &cs);
650  FlowBlock *getSwitchBlock(void) const { return getBlock(0); }
651  int4 getNumCaseBlocks(void) const { return caseblocks.size(); }
652  FlowBlock *getCaseBlock(int4 i) const { return caseblocks[i].block; }
653 
658  int4 getNumLabels(int4 i) const { return jump->numIndicesByBlock(caseblocks[i].basicblock); }
659 
665  uintb getLabel(int4 i,int4 j) const { return jump->getLabelByIndex(jump->getIndexByBlock(caseblocks[i].basicblock,j)); }
666 
667  bool isDefaultCase(int4 i) const { return caseblocks[i].isdefault; }
668  uint4 getGotoType(int4 i) const { return caseblocks[i].gototype; }
669  bool isExit(int4 i) const { return caseblocks[i].isexit; }
670  const Datatype *getSwitchType(void) const;
671  virtual block_type getType(void) const { return t_switch; }
672  virtual void markUnstructured(void);
673  virtual void scopeBreak(int4 curexit,int4 curloopexit);
674  virtual void printHeader(ostream &s) const;
675  virtual void emit(PrintLanguage *lng) const { lng->emitBlockSwitch(this); }
676  virtual FlowBlock *nextFlowAfter(const FlowBlock *bl) const;
677  virtual void orderSwitchCases(void) const;
678 };
679 
686 class BlockMap {
687  const AddrSpaceManager *manage;
688  vector<FlowBlock *> sortlist;
689  FlowBlock *resolveBlock(FlowBlock::block_type bt);
690  static FlowBlock *findBlock(const vector<FlowBlock *> &list,int4 ind);
691 public:
692  BlockMap(const AddrSpaceManager *m) { manage = m; }
693  BlockMap(const BlockMap &op2);
694  const AddrSpaceManager *getAddressManager(void) const { return manage; }
695  void sortList(void);
696 
701  FlowBlock *findLevelBlock(int4 index) const { return findBlock(sortlist,index); }
702  FlowBlock *createBlock(const string &name);
703 };
704 
707 inline void FlowBlock::emit(PrintLanguage *lng) const
708 
709 {
710 }
711 
717 
718 {
719  return false;
720 }
721 
727 
728 {
729  return (FlowBlock *)0;
730 }
731 
743 inline int4 FlowBlock::flipInPlaceTest(vector<PcodeOp *> &fliplist) const
744 
745 {
746  return 2; // By default a block will not normalize
747 }
748 
754 
755 {
756 }
757 
767 
768 {
769  return (FlowBlock *)0;
770 }
771 
775 inline bool FlowBlock::compareBlockIndex(const FlowBlock *bl1,const FlowBlock *bl2)
776 
777 {
778  return (bl1->getIndex() < bl2->getIndex());
779 }
780 
785 inline bool BlockSwitch::CaseOrder::compare(const CaseOrder &a,const CaseOrder &b)
786 
787 {
788  if (a.label != b.label)
789  return (a.label < b.label);
790  return (a.depth < b.depth);
791 }
792 
793 #endif
BlockMultiGoto(FlowBlock *bl)
Construct given the underlying multi-exit block.
Definition: block.hh:472
virtual FlowBlock * getSplitPoint(void)
Get the leaf splitting block.
Definition: block.hh:430
void setOverflowSyntax(void)
Set that this requires overflow syntax.
Definition: block.hh:586
bool dominates(const FlowBlock *subBlock) const
Does this block dominate the given block.
Definition: block.cc:362
Description of a control-flow block containing PcodeOps.
Definition: block.hh:60
Block ends with a continue;.
Definition: block.hh:78
const vector< FlowBlock * > & getList(void) const
Get the list of component FlowBlock objects.
Definition: block.hh:287
The block has an unstructured jump out of interior.
Definition: block.hh:84
bool hasDefaultGoto(void) const
Does this block hold an unstructured switch default edge.
Definition: block.hh:474
int4 getOutRevIndex(int4 i) const
Get the input index of the i-th output FlowBlock.
Definition: block.hh:210
int4 getIndexByBlock(const FlowBlock *bl, int4 i) const
Get the index of the i-th address table entry that corresponds to the given basic-block.
Definition: jumptable.cc:2311
The base datatype class for the decompiler.
Definition: type.hh:62
Funcdata * getFuncdata(void)
Return the underlying Funcdata object.
Definition: block.hh:376
virtual ~BlockGraph(void)
Destructor.
Definition: block.hh:286
virtual FlowBlock * getSplitPoint(void)
Get the leaf splitting block.
Definition: block.hh:726
bool hasInteriorGoto(void) const
Is there an unstructured goto out of this block&#39;s interior.
Definition: block.hh:231
bool isGotoIn(int4 i) const
Is the i-th incoming edge unstructured.
Definition: block.hh:253
A loop structure where the condition is checked at the bottom.
Definition: block.hh:599
bool isLoopDAGIn(int4 i) const
Is the i-th incoming edge part of the DAG sub-graph.
Definition: block.hh:252
Edge completes a loop, removing these edges gives you a DAG.
Definition: block.hh:97
FlowBlock * getImmedDom(void) const
Get the immediate dominator FlowBlock.
Definition: block.hh:149
OpCode
The op-code defining a specific p-code operation (PcodeOp)
Definition: opcodes.hh:35
A manager for different address spaces.
Definition: translate.hh:218
list< PcodeOp * >::iterator endOp(void)
Return an iterator to the end of the PcodeOps.
Definition: block.hh:400
bool isLoopOut(int4 i) const
Is the i-th outgoing edge a loop edge.
Definition: block.hh:224
list< PcodeOp * >::const_iterator endOp(void) const
Return an iterator to the end of the PcodeOps.
Definition: block.hh:402
bool isIrreducibleIn(int4 i) const
Is the i-th incoming edge an irreducible edge.
Definition: block.hh:240
virtual void emitBlockIf(const BlockIf *bl)=0
Emit an if/else style construct.
FlowBlock * getFalseOut(void) const
Get the false output FlowBlock.
Definition: block.hh:206
void saveXml(ostream &s) const
Save the edge to an XML stream.
Definition: block.cc:22
virtual ~FlowBlock(void)
Destructor.
Definition: block.hh:146
static bool compareFinalOrder(const FlowBlock *bl1, const FlowBlock *bl2)
Final FlowBlock comparison.
Definition: block.cc:665
void setFlag(uint4 fl)
Set a boolean property.
Definition: block.hh:142
void restoreXml(const Element *el, BlockMap &resolver)
Restore this edge from an XML stream.
Definition: block.cc:34
virtual void emitBlockWhileDo(const BlockWhileDo *bl)=0
Emit a loop structure, check at top.
FlowBlock * getCaseBlock(int4 i) const
Get the i-th case FlowBlock.
Definition: block.hh:652
virtual void scopeBreak(int4 curexit, int4 curloopexit)
Mark unstructured edges that should be breaks.
Definition: block.hh:159
void setGotoBranch(int4 i)
Mark a goto branch.
Definition: block.cc:293
const FlowBlock * getIn(int4 i) const
Get the i-th input FlowBlock.
Definition: block.hh:212
bool isJumpTarget(void) const
Return true if non-fallthru jump flows into this.
Definition: block.cc:305
virtual void emitBlockDoWhile(const BlockDoWhile *bl)=0
Emit a loop structure, check at bottom.
bool isBackEdgeIn(int4 i) const
Is the i-th incoming edge a back edge.
Definition: block.hh:237
virtual FlowBlock * subBlock(int4 i) const
Get the i-th component block.
Definition: block.hh:421
virtual void emitBlockInfLoop(const BlockInfLoop *bl)=0
Emit an infinite loop structure.
virtual const FlowBlock * getExitLeaf(void) const
Get the FlowBlock to which this block exits.
Definition: block.hh:164
bool isDefaultCase(int4 i) const
Is the i-th case the default case.
Definition: block.hh:667
Container for data structures associated with a single function.
Definition: funcdata.hh:45
virtual void emit(PrintLanguage *lng) const
Emit the instructions in this FlowBlock as structured code.
Definition: block.hh:524
void setDonothingLoop(void)
Label this as a do nothing loop.
Definition: block.hh:196
Block is a duplicated version of an original basic block.
Definition: block.hh:92
bool isGotoOut(int4 i) const
Is the i-th outgoing edge unstructured.
Definition: block.hh:254
Within (reducible) graph, a back edge defining a loop.
Definition: block.hh:103
bool hasSpecialLabel(void) const
Return true if this uses a different label.
Definition: block.hh:198
virtual bool isComplex(void) const
Is this too complex to be a condition (BlockCondition)
Definition: block.hh:171
bool contains(const Address &addr) const
Determine if the given address is contained in the original range.
Definition: block.hh:378
bool hasLoopOut(void) const
Is there a looping edge going out of this block.
Definition: block.cc:407
virtual const FlowBlock * getExitLeaf(void) const
Get the FlowBlock to which this block exits.
Definition: block.hh:389
Helper class for resolving cross-references while deserializing BlockGraph objects.
Definition: block.hh:686
void setBackEdge(int4 i)
Label the back edge of a loop.
Definition: block.hh:203
A loop structure where the condition is checked at the top.
Definition: block.hh:583
virtual PcodeOp * lastOp(void) const
Get the last PcodeOp executed by this FlowBlock.
Definition: block.hh:457
int4 numIndicesByBlock(const FlowBlock *bl) const
Return the number of address table entries that target the given basic-block.
Definition: jumptable.cc:2264
void setDead(void)
Label this as dead.
Definition: block.hh:197
BlockMap(const AddrSpaceManager *m)
Construct given an address space manager.
Definition: block.hh:692
const FlowBlock * nextInFlow(void) const
Return next block to be executed in flow.
Definition: block.cc:2407
virtual PcodeOp * lastOp(void) const
Get the last PcodeOp executed by this FlowBlock.
Definition: block.hh:485
block_type
The possible block types.
Definition: block.hh:64
int4 sizeOut(void) const
Get the number of out edges.
Definition: block.hh:219
Block is a merged form of original basic blocks.
Definition: block.hh:91
Block is target of unstructured jump to its interior.
Definition: block.hh:85
FlowBlock * findLevelBlock(int4 index) const
Find the FlowBlock matching the given index.
Definition: block.hh:701
bool isSwitchOut(void) const
Is this a switch block.
Definition: block.hh:233
JumpTable * getJumptable(void) const
Get the JumpTable associated this block.
Definition: block.cc:597
Block is in process of being deleted.
Definition: block.hh:88
void printRaw(ostream &s) const
Print raw p-code op descriptions to a stream.
Definition: funcdata.cc:181
int4 getInIndex(const FlowBlock *bl) const
Get the incoming edge index for the given FlowBlock.
Definition: block.cc:549
int4 numGotos(void) const
Get the number of unstructured edges.
Definition: block.hh:476
bool isJoined(void) const
Return true if this is a joined basic block.
Definition: block.hh:199
uint4 label
Label of the edge.
Definition: block.hh:45
virtual void emit(PrintLanguage *lng) const
Emit the instructions in this FlowBlock as structured code.
Definition: block.hh:605
bool isLoopDAGOut(int4 i) const
Is the i-th outgoing edge part of the DAG sub-graph.
Definition: block.hh:249
const FlowBlock * getFrontLeaf(void) const
Get the first leaf FlowBlock.
Definition: block.cc:316
A disjoint set of Ranges, possibly across multiple address spaces.
Definition: address.hh:203
bool emptyOp(void) const
Return true if block contains no operations.
Definition: block.hh:403
int4 getSize(void) const
Get the number of components.
Definition: block.hh:288
virtual void emitBlockLs(const BlockList *bl)=0
Emit a sequence of blocks.
If true, out edges have been flipped since last time path was traced.
Definition: block.hh:90
Block ends with a break;.
Definition: block.hh:77
bool isBackEdgeOut(int4 i) const
Is the i-th outgoing edge a back edge.
Definition: block.hh:238
bool isLabelBumpUp(void) const
Are labels for this printed by the parent.
Definition: block.hh:228
FlowBlock * point
Other end of the edge.
Definition: block.hh:46
const FlowBlock * getOut(int4 i) const
Get i-th output FlowBlock.
Definition: block.hh:209
virtual block_type getType(void) const
Get the FlowBlock type of this.
Definition: block.hh:155
void setDefaultSwitch(int4 i)
Mark an edge as the switch default.
Definition: block.hh:192
bool isDecisionIn(int4 i) const
Can this and the i-th input be merged into a BlockIf or BlockList.
Definition: block.hh:246
void clearLoopExit(int4 i)
Clear the loop exit edge.
Definition: block.hh:202
An infinite loop structure.
Definition: block.hh:613
virtual block_type getType(void) const
Get the FlowBlock type of this.
Definition: block.hh:422
bool getFlipPath(void) const
Have out edges been flipped.
Definition: block.hh:204
Set if the conditional block of a whiledo is too big to print as while(cond) { ...
Definition: block.hh:89
list< PcodeOp * >::iterator beginOp(void)
Return an iterator to the beginning of the PcodeOps.
Definition: block.hh:399
(Block ends in) non-structured branch
Definition: block.hh:76
virtual Address getStart(void) const
Get the starting address of code in this FlowBlock.
Definition: block.hh:153
virtual void saveXmlBody(ostream &s) const
Save detail about components to an XML stream.
Definition: block.hh:176
A secondary mark.
Definition: block.hh:82
virtual void printTree(ostream &s, int4 level) const
Print tree structure of any blocks owned by this.
Definition: block.cc:1216
FlowBlock * getOut(int4 i)
Get the i-th output FlowBlock.
Definition: block.hh:208
virtual void printRaw(ostream &s) const
Print raw instructions contained in this FlowBlock.
Definition: block.hh:162
Generic way to mark a block.
Definition: block.hh:81
bool isMark(void) const
Return true if this block has been marked.
Definition: block.hh:193
Classes to support jump-tables and their recovery.
Any label printed higher up in hierarchy.
Definition: block.hh:86
BlockCopy(FlowBlock *bl)
Construct given the block to copy.
Definition: block.hh:420
int4 reverse_index
Index for edge coming other way.
Definition: block.hh:47
virtual void emit(PrintLanguage *lng) const
Emit the instructions in this FlowBlock as structured code.
Definition: block.hh:499
uintb getLabelByIndex(int4 index) const
Given a case index, get its label.
Definition: jumptable.hh:558
bool isEntryPoint(void) const
Is the entry point of the function.
Definition: block.hh:232
Lowest level operation of the p-code language.
Definition: op.hh:58
FlowBlock * getGoto(int4 i) const
Get the target FlowBlock along the i-th unstructured edge.
Definition: block.hh:477
bool inRange(const Address &addr, int4 size) const
Check containment an address range.
Definition: address.cc:402
A low-level machine address for labelling bytes and data.
Definition: address.hh:46
virtual void emit(PrintLanguage *lng) const
Emit the instructions in this FlowBlock as structured code.
Definition: block.hh:455
uint4 getFlags(void) const
Get the block_flags properties.
Definition: block.hh:152
bool isUnstructuredTarget(void) const
Is this the target of an unstructured goto.
Definition: block.hh:229
uintb getLabel(int4 i, int4 j) const
Get a specific label associated with a case block.
Definition: block.hh:665
An edge in the spanning tree.
Definition: block.hh:100
void clearFlag(uint4 fl)
Clear a boolean property.
Definition: block.hh:143
virtual const FlowBlock * getExitLeaf(void) const
Get the FlowBlock to which this block exits.
Definition: block.hh:484
virtual block_type getType(void) const
Get the FlowBlock type of this.
Definition: block.hh:671
bool isDecisionOut(int4 i) const
Can this and the i-th output be merged into a BlockIf or BlockList.
Definition: block.hh:243
FlowBlock * getGotoTarget(void) const
Get the target block of the goto.
Definition: block.hh:447
A basic "if" block.
Definition: block.hh:553
virtual void emitBlockGoto(const BlockGoto *bl)=0
Emit a block ending with a goto statement.
int4 sizeIn(void) const
Get the number of in edges.
Definition: block.hh:220
virtual void saveXmlHeader(ostream &s) const
Save basic information as XML attributes.
Definition: block.cc:2333
bool isLoopIn(int4 i) const
Is the i-th incoming edge a loop edge.
Definition: block.hh:223
virtual void emit(PrintLanguage *lng) const
Emit the instructions in this FlowBlock as structured code.
Definition: block.hh:297
virtual void emit(PrintLanguage *lng) const
Emit the instructions in this FlowBlock as structured code.
Definition: block.hh:675
virtual void emit(PrintLanguage *lng) const
Emit the instructions in this FlowBlock as structured code.
Definition: block.hh:483
virtual PcodeOp * lastOp(void) const
Get the last PcodeOp executed by this FlowBlock.
Definition: block.hh:428
Output is decided by switch.
Definition: block.hh:79
An edge that crosses subtrees in the spanning tree.
Definition: block.hh:102
int4 getIndex(void) const
Get the index assigned to this block.
Definition: block.hh:147
uint4 getGotoType(int4 i) const
Get the edge type for the i-th case block.
Definition: block.hh:668
This is default edge from switchblock.
Definition: block.hh:98
virtual void emit(PrintLanguage *lng) const
Emit the instructions in this FlowBlock as structured code.
Definition: block.hh:591
static string typeToName(block_type bt)
Get the name string associated with a block_type.
Definition: block.cc:627
FlowBlock * getSwitchBlock(void) const
Get the root switch component.
Definition: block.hh:650
virtual block_type getType(void) const
Get the FlowBlock type of this.
Definition: block.hh:479
BlockBasic(Funcdata *fd)
Construct given the underlying function.
Definition: block.hh:375
virtual void printHeader(ostream &s) const
Print a simple description of this to stream.
Definition: block.cc:574
bool isExit(int4 i) const
Does the i-th case block exit the switch?
Definition: block.hh:669
void setGotoTarget(FlowBlock *bl)
Mark the target of the unstructured edge.
Definition: block.hh:558
An edge that jumps forward in the spanning tree.
Definition: block.hh:101
virtual const FlowBlock * getExitLeaf(void) const
Get the FlowBlock to which this block exits.
Definition: block.hh:456
void setMark(void)
Mark this block.
Definition: block.hh:194
A control-flow block built out of sub-components.
Definition: block.hh:270
int4 getOutIndex(const FlowBlock *bl) const
Get the outgoing edge index for the given FlowBlock.
Definition: block.cc:562
bool isTreeEdgeIn(int4 i) const
Is the i-th incoming edge part of the spanning tree.
Definition: block.hh:236
int4 getInRevIndex(int4 i) const
Get the output index of the i-th input FlowBlock.
Definition: block.hh:213
virtual void emitBlockBasic(const BlockBasic *bb)=0
Emit statements in a basic block.
A block with multiple edges out, at least one of which is an unstructured (goto) branch.
Definition: block.hh:468
virtual void emitBlockSwitch(const BlockSwitch *bl)=0
Emit a switch structure.
bool isDuplicated(void) const
Return true if this is a duplicated block.
Definition: block.hh:200
A basic block for p-code operations.
Definition: block.hh:363
int4 getNumLabels(int4 i) const
Get the number of labels associated with one case block.
Definition: block.hh:658
static block_type nameToType(const string &name)
Get the block_type associated with a name string.
Definition: block.cc:613
A map from values to control-flow targets within a function.
Definition: jumptable.hh:499
An XML element. A node in the DOM tree.
Definition: xml.hh:150
BlockCondition(OpCode c)
Construct given the boolean operation.
Definition: block.hh:519
virtual void printRaw(ostream &s) const
Print raw instructions contained in this FlowBlock.
Definition: block.hh:454
virtual FlowBlock * getSplitPoint(void)
Get the leaf splitting block.
Definition: block.hh:526
virtual block_type getType(void) const
Get the FlowBlock type of this.
Definition: block.hh:615
virtual void emit(PrintLanguage *lng) const
Emit the instructions in this FlowBlock as structured code.
Definition: block.hh:619
FlowBlock * getCopyMap(void) const
Get the mapped FlowBlock.
Definition: block.hh:150
virtual block_type getType(void) const
Get the FlowBlock type of this.
Definition: block.hh:497
virtual block_type getType(void) const
Get the FlowBlock type of this.
Definition: block.hh:290
A series of blocks that execute in sequence.
Definition: block.hh:495
void merge(const RangeList &op2)
Merge another RangeList into this.
Definition: address.cc:385
virtual bool isComplex(void) const
Is this too complex to be a condition (BlockCondition)
Definition: block.hh:530
const FlowBlock * getParent(void) const
Get the parent FlowBlock of this.
Definition: block.hh:151
virtual int4 flipInPlaceTest(vector< PcodeOp *> &fliplist) const
Test normalizing the conditional branch in this.
Definition: block.hh:743
bool isIrreducibleOut(int4 i) const
Is the i-th outgoing edge an irreducible edge.
Definition: block.hh:239
A control-flow edge between blocks (FlowBlock)
Definition: block.hh:44
virtual void emitBlockGraph(const BlockGraph *bl)=0
Emit (an unspecified) list of blocks.
virtual FlowBlock * subBlock(int4 i) const
Get the i-th component block.
Definition: block.hh:383
A block that terminates with an unstructured (goto) branch to another block.
Definition: block.hh:442
virtual block_type getType(void) const
Get the FlowBlock type of this.
Definition: block.hh:521
BlockEdge(FlowBlock *pt, uint4 lab, int4 rev)
Constructor.
Definition: block.hh:49
void saveXmlEdges(ostream &s) const
Save edge information to an XML stream.
Definition: block.cc:2350
void setLoopExit(int4 i)
Label the edge exiting this as a loop.
Definition: block.hh:201
bool hasLoopIn(void) const
Is there a looping edge coming into this block.
Definition: block.cc:398
const Funcdata * getFuncdata(void) const
Return the underlying Funcdata object.
Definition: block.hh:377
virtual void emitBlockCondition(const BlockCondition *bl)=0
Emit a conditional statement.
Edge which must be removed to make graph reducible.
Definition: block.hh:99
A structured switch construction.
Definition: block.hh:630
bool isDefaultBranch(int4 i) const
Is the i-th out edge the switch default edge.
Definition: block.hh:227
static bool compareBlockIndex(const FlowBlock *bl1, const FlowBlock *bl2)
Compare FlowBlock by index.
Definition: block.hh:775
void setDefaultGoto(void)
Mark that this block holds an unstructured switch default.
Definition: block.hh:473
virtual void emit(PrintLanguage *lng) const
Emit the instructions in this FlowBlock as structured code.
Definition: block.hh:565
virtual void emitBlockCopy(const BlockCopy *bl)=0
Emit a basic block (with any labels)
BlockEdge(void)
Constructor for use with restoreXml.
Definition: block.hh:48
const AddrSpaceManager * getAddressManager(void) const
Get the address space manager.
Definition: block.hh:694
list< PcodeOp * >::const_iterator beginOp(void) const
Return an iterator to the beginning of the PcodeOps.
Definition: block.hh:401
virtual bool isComplex(void) const
Is this too complex to be a condition (BlockCondition)
Definition: block.hh:431
BlockGoto(FlowBlock *bl)
Construct given target block.
Definition: block.hh:446
FlowBlock * getIn(int4 i)
Get the i-th input FlowBlock.
Definition: block.hh:211
virtual bool preferComplement(Funcdata &data)
Rearrange this hierarchy to simplify boolean expressions.
Definition: block.hh:716
virtual void printRaw(ostream &s) const
Print raw instructions contained in this FlowBlock.
Definition: block.hh:425
virtual FlowBlock * subBlock(int4 i) const
Get the i-th component block.
Definition: block.hh:291
virtual block_type getType(void) const
Get the FlowBlock type of this.
Definition: block.hh:587
virtual PcodeOp * lastOp(void) const
Get the last PcodeOp executed by this FlowBlock.
Definition: block.hh:165
virtual void emit(PrintLanguage *lng) const
Emit the instructions in this FlowBlock as structured code.
Definition: block.hh:388
FlowBlock * getGotoTarget(void) const
Get the target of the unstructured edge.
Definition: block.hh:559
FlowBlock * getTrueOut(void) const
Get the true output FlowBlock.
Definition: block.hh:207
virtual bool negateCondition(bool toporbottom)
Flip the condition computed by this.
Definition: block.cc:282
virtual FlowBlock * nextFlowAfter(const FlowBlock *bl) const
Get the leaf FlowBlock that will execute after the given FlowBlock.
Definition: block.cc:1237
BlockIf(void)
Constructor.
Definition: block.hh:557
virtual void restoreXmlHeader(const Element *el)
Restore basic information for XML attributes.
Definition: block.cc:2340
void addEdge(FlowBlock *bl)
Mark the edge from this to the given FlowBlock as unstructured.
Definition: block.hh:475
virtual void orderSwitchCases(void) const
Order case components of any contained BlockSwitch.
Definition: block.hh:173
Edge is unstructured.
Definition: block.hh:96
bool restrictedByConditional(const FlowBlock *cond) const
Check if the condition from the given block holds for this block.
Definition: block.cc:381
void clearMark(void)
Clear any mark on this block.
Definition: block.hh:195
block_flags
Boolean properties of blocks.
Definition: block.hh:75
virtual block_type getType(void) const
Get the FlowBlock type of this.
Definition: block.hh:601
int4 calcDepth(const FlowBlock *leaf) const
Get the depth of the given component FlowBlock.
Definition: block.cc:344
int4 getVisitCount(void) const
Get the count of visits.
Definition: block.hh:190
virtual FlowBlock * subBlock(int4 i) const
Get the i-th component block.
Definition: block.hh:156
virtual FlowBlock * nextFlowAfter(const FlowBlock *bl) const
Get the leaf FlowBlock that will execute after the given FlowBlock.
Definition: block.hh:766
virtual void flipInPlaceExecute(void)
Perform the flip to normalize conditional branch executed by this block.
Definition: block.hh:753
Official entry point of the function.
Definition: block.hh:83
Block does nothing in infinite loop (halt)
Definition: block.hh:87
static FlowBlock * findCommonBlock(FlowBlock *bl1, FlowBlock *bl2)
Find the common dominator of two FlowBlocks.
Definition: block.cc:692
void orderBlocks(void)
Definition: block.hh:332
virtual const FlowBlock * getExitLeaf(void) const
Get the FlowBlock to which this block exits.
Definition: block.hh:427
virtual void printRaw(ostream &s) const
Print raw instructions contained in this FlowBlock.
Definition: block.hh:482
virtual bool negateCondition(bool toporbottom)
Flip the condition computed by this.
Definition: block.hh:429
bool isDonothingLoop(void) const
Is this a do nothing block.
Definition: block.hh:234
Two conditional blocks combined into one conditional using BOOL_AND or BOOL_OR.
Definition: block.hh:516
FlowBlock * getParent(void)
Get the parent FlowBlock of this.
Definition: block.hh:148
uint4 getGotoType(void) const
Get the type of unstructured branch.
Definition: block.hh:448
virtual block_type getType(void) const
Get the FlowBlock type of this.
Definition: block.hh:382
bool hasOverflowSyntax(void) const
Does this require overflow syntax.
Definition: block.hh:585
void setVisitCount(int4 i)
Set the number of times this block has been visited.
Definition: block.hh:189
FlowBlock * getBlock(int4 i) const
Get the i-th component.
Definition: block.hh:289
virtual void emit(PrintLanguage *lng) const
Emit the instructions in this FlowBlock as structured code.
Definition: block.hh:426
Block is destination of unstructured goto.
Definition: block.hh:80
virtual void emit(PrintLanguage *lng) const
Emit the instructions in this FlowBlock as structured code.
Definition: block.hh:707
virtual block_type getType(void) const
Get the FlowBlock type of this.
Definition: block.hh:450
The base class API for emitting a high-level language.
Definition: printlanguage.hh:134
edge_flags
Boolean properties on edges.
Definition: block.hh:95
virtual void restoreXmlBody(List::const_iterator &iter, List::const_iterator enditer, BlockMap &resolver)
Restore details about this FlowBlock from an XML stream.
Definition: block.hh:183
bool isInteriorGotoTarget(void) const
Is there an unstructured goto to this block&#39;s interior.
Definition: block.hh:230
Edge exits the body of a loop.
Definition: block.hh:104
This class is used to mirror the BlockBasic objects in the fixed control-flow graph for a function...
Definition: block.hh:417
uint4 getGotoType(void) const
Get the type of unstructured edge.
Definition: block.hh:560
bool isDead(void) const
Is this block dead.
Definition: block.hh:235
virtual void markLabelBumpUp(bool bump)
Let hierarchical blocks steal labels of their (first) components.
Definition: block.cc:1184
virtual Address getStop(void) const
Get the ending address of code in this FlowBlock.
Definition: block.hh:154
OpCode getOpcode(void) const
Get the boolean operation.
Definition: block.hh:520
virtual block_type getType(void) const
Get the FlowBlock type of this.
Definition: block.hh:561
void restoreXmlEdges(List::const_iterator &iter, List::const_iterator enditer, BlockMap &resolver)
Restore edges from an XML stream.
Definition: block.cc:2363
int4 getNumCaseBlocks(void) const
Get the number of cases.
Definition: block.hh:651
FlowBlock(void)
Construct a block with no edges.
Definition: block.cc:50
virtual void markUnstructured(void)
Mark target blocks of any unstructured edges.
Definition: block.hh:157