Ghidra Decompiler Analysis Engine
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 finalTransform(Funcdata &data) {}
174  virtual void finalizePrinting(Funcdata &data) const {}
175  virtual void saveXmlHeader(ostream &s) const;
176  virtual void restoreXmlHeader(const Element *el);
177  virtual void saveXmlBody(ostream &s) const {}
178 
184  virtual void restoreXmlBody(List::const_iterator &iter,List::const_iterator enditer,BlockMap &resolver) {}
185  void saveXmlEdges(ostream &s) const;
186  void restoreXmlEdges(List::const_iterator &iter,List::const_iterator enditer,BlockMap &resolver);
187  void saveXml(ostream &s) const;
188  void restoreXml(const Element *el,BlockMap &resolver);
189  const FlowBlock *nextInFlow(void) const;
190  void setVisitCount(int4 i) { visitcount = i; }
191  int4 getVisitCount(void) const { return visitcount; }
192  void setGotoBranch(int4 i);
193  void setDefaultSwitch(int4 i) { setOutEdgeFlag(i,f_defaultswitch_edge); }
194  bool isMark(void) const { return ((flags&f_mark)!=0); }
195  void setMark(void) { flags |= f_mark; }
196  void clearMark(void) { flags &= ~f_mark; }
197  void setDonothingLoop(void) { flags |= f_donothing_loop; }
198  void setDead(void) { flags |= f_dead; }
199  bool hasSpecialLabel(void) const { return ((flags&(f_joined_block|f_duplicate_block))!=0); }
200  bool isJoined(void) const { return ((flags&f_joined_block)!=0); }
201  bool isDuplicated(void) const { return ((flags&f_duplicate_block)!=0); }
202  void setLoopExit(int4 i) { setOutEdgeFlag(i,f_loop_exit_edge); }
203  void clearLoopExit(int4 i) { clearOutEdgeFlag(i,f_loop_exit_edge); }
204  void setBackEdge(int4 i) { setOutEdgeFlag(i,f_back_edge); }
205  bool getFlipPath(void) const { return ((flags & f_flip_path)!=0); }
206  bool isJumpTarget(void) const;
207  FlowBlock *getFalseOut(void) const { return outofthis[0].point; }
208  FlowBlock *getTrueOut(void) const { return outofthis[1].point; }
209  FlowBlock *getOut(int4 i) { return outofthis[i].point; }
210  const FlowBlock *getOut(int4 i) const { return (const FlowBlock *) outofthis[i].point; }
211  int4 getOutRevIndex(int4 i) const { return outofthis[i].reverse_index; }
212  FlowBlock *getIn(int4 i) { return intothis[i].point; }
213  const FlowBlock *getIn(int4 i) const { return (const FlowBlock *) intothis[i].point; }
214  int4 getInRevIndex(int4 i) const { return intothis[i].reverse_index; }
215  const FlowBlock *getFrontLeaf(void) const;
216  FlowBlock *getFrontLeaf(void);
217  int4 calcDepth(const FlowBlock *leaf) const;
218  bool dominates(const FlowBlock *subBlock) const;
219  bool restrictedByConditional(const FlowBlock *cond) const;
220  int4 sizeOut(void) const { return outofthis.size(); }
221  int4 sizeIn(void) const { return intothis.size(); }
222  bool hasLoopIn(void) const;
223  bool hasLoopOut(void) const;
224  bool isLoopIn(int4 i) const { return ((intothis[i].label & f_loop_edge)!=0); }
225  bool isLoopOut(int4 i) const { return ((outofthis[i].label & f_loop_edge)!=0); }
226  int4 getInIndex(const FlowBlock *bl) const;
227  int4 getOutIndex(const FlowBlock *bl) const;
228  bool isDefaultBranch(int4 i) const { return ((outofthis[i].label & f_defaultswitch_edge)!=0); }
229  bool isLabelBumpUp(void) const { return ((flags & f_label_bumpup)!=0); }
230  bool isUnstructuredTarget(void) const { return ((flags & f_unstructured_targ)!=0); }
231  bool isInteriorGotoTarget(void) const { return ((flags & f_interior_gotoin)!=0); }
232  bool hasInteriorGoto(void) const { return ((flags & f_interior_gotoout)!=0); }
233  bool isEntryPoint(void) const { return ((flags&f_entry_point)!=0); }
234  bool isSwitchOut(void) const { return ((flags&f_switch_out)!=0); }
235  bool isDonothingLoop(void) const { return ((flags&f_donothing_loop)!=0); }
236  bool isDead(void) const { return ((flags & f_dead)!=0); }
237  bool isTreeEdgeIn(int4 i) const { return ((intothis[i].label & f_tree_edge)!=0); }
238  bool isBackEdgeIn(int4 i) const { return ((intothis[i].label & f_back_edge)!=0); }
239  bool isBackEdgeOut(int4 i) const { return ((outofthis[i].label & f_back_edge)!=0); }
240  bool isIrreducibleOut(int4 i) const { return ((outofthis[i].label & f_irreducible)!=0); }
241  bool isIrreducibleIn(int4 i) const { return ((intothis[i].label & f_irreducible)!=0); }
242 
244  bool isDecisionOut(int4 i) const { return ((outofthis[i].label & (f_irreducible|f_back_edge|f_goto_edge))==0); }
245 
247  bool isDecisionIn(int4 i) const { return ((intothis[i].label & (f_irreducible|f_back_edge|f_goto_edge))==0); }
248 
250  bool isLoopDAGOut(int4 i) const { return ((outofthis[i].label & (f_irreducible|f_back_edge|f_loop_exit_edge|f_goto_edge))==0); }
251 
253  bool isLoopDAGIn(int4 i) const { return ((intothis[i].label & (f_irreducible|f_back_edge|f_loop_exit_edge|f_goto_edge))==0); }
254  bool isGotoIn(int4 i) const { return ((intothis[i].label & (f_irreducible|f_goto_edge))!=0); }
255  bool isGotoOut(int4 i) const { return ((outofthis[i].label & (f_irreducible|f_goto_edge))!=0); }
256  JumpTable *getJumptable(void) const;
257  static block_type nameToType(const string &name);
258  static string typeToName(block_type bt);
259  static bool compareBlockIndex(const FlowBlock *bl1,const FlowBlock *bl2);
260  static bool compareFinalOrder(const FlowBlock *bl1,const FlowBlock *bl2);
261  static FlowBlock *findCommonBlock(FlowBlock *bl1,FlowBlock *bl2);
262  static FlowBlock *findCommonBlock(const vector<FlowBlock *> &blockSet);
263 };
264 
271 class BlockGraph : public FlowBlock {
272  vector<FlowBlock *> list;
273  void addBlock(FlowBlock *bl);
274  void forceOutputNum(int4 i);
275  void selfIdentify(void);
276  void identifyInternal(BlockGraph *ident,const vector<FlowBlock *> &nodes);
277  void clearEdgeFlags(uint4 flags);
278  static FlowBlock *createVirtualRoot(const vector<FlowBlock *> &rootlist);
279  void findSpanningTree(vector<FlowBlock *> &preorder,vector<FlowBlock *> &rootlist);
280  bool findIrreducible(const vector<FlowBlock *> &preorder,int4 &irreduciblecount);
281  void forceFalseEdge(const FlowBlock *out0);
282 protected:
283  void swapBlocks(int4 i,int4 j);
284  static void markCopyBlock(FlowBlock *bl,uint4 fl);
285 public:
286  void clear(void);
287  virtual ~BlockGraph(void) { clear(); }
288  const vector<FlowBlock *> &getList(void) const { return list; }
289  int4 getSize(void) const { return list.size(); }
290  FlowBlock *getBlock(int4 i) const { return list[i]; }
291  virtual block_type getType(void) const { return t_graph; }
292  virtual FlowBlock *subBlock(int4 i) const { return list[i]; }
293  virtual void markUnstructured(void);
294  virtual void markLabelBumpUp(bool bump);
295  virtual void scopeBreak(int4 curexit,int4 curloopexit);
296  virtual void printTree(ostream &s,int4 level) const;
297  virtual void printRaw(ostream &s) const;
298  virtual void emit(PrintLanguage *lng) const { lng->emitBlockGraph(this); }
299  virtual FlowBlock *nextFlowAfter(const FlowBlock *bl) const;
300  virtual void finalTransform(Funcdata &data);
301  virtual void finalizePrinting(Funcdata &data) const;
302  virtual void saveXmlBody(ostream &s) const;
303  virtual void restoreXmlBody(List::const_iterator &iter,List::const_iterator enditer,BlockMap &resolver);
304  void restoreXml(const Element *el,const AddrSpaceManager *m);
305  void addEdge(FlowBlock *begin,FlowBlock *end);
306  void addLoopEdge(FlowBlock *begin,int4 outindex);
307  void removeEdge(FlowBlock *begin,FlowBlock *end);
308  void switchEdge(FlowBlock *in,FlowBlock *outbefore,FlowBlock *outafter);
309  void moveOutEdge(FlowBlock *blold,int4 slot,FlowBlock *blnew);
310  void removeBlock(FlowBlock *bl);
311  void removeFromFlow(FlowBlock *bl);
312  void removeFromFlowSplit(FlowBlock *bl,bool flipflow);
313  void spliceBlock(FlowBlock *bl);
314  void setStartBlock(FlowBlock *bl);
315  FlowBlock *getStartBlock(void) const;
316  // Factory functions
317  FlowBlock *newBlock(void);
319 
320  // Factory (identify) routines
323  BlockMultiGoto *newBlockMultiGoto(FlowBlock *bl,int4 outedge);
324  BlockList *newBlockList(const vector<FlowBlock *> &nodes);
327  BlockIf *newBlockIf(FlowBlock *cond,FlowBlock *tc);
332  BlockSwitch *newBlockSwitch(const vector<FlowBlock *> &cs,bool hasExit);
333 
334  void orderBlocks(void) {
335  if (list.size()!=1) sort(list.begin(),list.end(),compareFinalOrder); }
336  void buildCopy(const BlockGraph &graph);
337  void clearVisitCount(void);
338  void calcForwardDominator(const vector<FlowBlock *> &rootlist);
339  void buildDomTree(vector<vector<FlowBlock *> > &child) const;
340  int4 buildDomDepth(vector<int4> &depth) const;
341  void buildDomSubTree(vector<FlowBlock *> &res,FlowBlock *root) const;
342  void calcLoop(void);
343  void collectReachable(vector<FlowBlock *> &res,FlowBlock *bl,bool un) const;
344  void structureLoops(vector<FlowBlock *> &rootlist);
345 #ifdef BLOCKCONSISTENT_DEBUG
346  bool isConsistent(void) const;
347 #endif
348 };
349 
365 class BlockBasic: public FlowBlock {
366  friend class Funcdata; // Only uses private functions
367  list<PcodeOp *> op;
368  Funcdata *data;
369  RangeList cover;
370  void insert(list<PcodeOp *>::iterator iter,PcodeOp *inst);
371  void setInitialRange(const Address &beg,const Address &end);
372  void copyRange(const BlockBasic *bb) { cover = bb->cover; }
373  void mergeRange(const BlockBasic *bb) { cover.merge(bb->cover); }
374  void setOrder(void);
375  void removeOp(PcodeOp *inst);
376 public:
377  BlockBasic(Funcdata *fd) { data = fd; }
378  Funcdata *getFuncdata(void) { return data; }
379  const Funcdata *getFuncdata(void) const { return (const Funcdata *)data; }
380  bool contains(const Address &addr) const { return cover.inRange(addr, 1); }
381  Address getEntryAddr(void) const;
382  virtual Address getStart(void) const;
383  virtual Address getStop(void) const;
384  virtual block_type getType(void) const { return t_basic; }
385  virtual FlowBlock *subBlock(int4 i) const { return (FlowBlock *)0; }
386  virtual void saveXmlBody(ostream &s) const;
387  virtual void restoreXmlBody(List::const_iterator &iter,List::const_iterator enditer,BlockMap &resolver);
388  virtual void printHeader(ostream &s) const;
389  virtual void printRaw(ostream &s) const;
390  virtual void emit(PrintLanguage *lng) const { lng->emitBlockBasic(this); }
391  virtual const FlowBlock *getExitLeaf(void) const { return this; }
392  virtual PcodeOp *lastOp(void) const;
393  virtual bool negateCondition(bool toporbottom);
394  virtual FlowBlock *getSplitPoint(void);
395  virtual int4 flipInPlaceTest(vector<PcodeOp *> &fliplist) const;
396  virtual void flipInPlaceExecute(void);
397  virtual bool isComplex(void) const;
398  bool unblockedMulti(int4 outslot) const;
399  bool hasOnlyMarkers(void) const;
400  bool isDoNothing(void) const;
401  list<PcodeOp *>::iterator beginOp(void) { return op.begin(); }
402  list<PcodeOp *>::iterator endOp(void) { return op.end(); }
403  list<PcodeOp *>::const_iterator beginOp(void) const { return op.begin(); }
404  list<PcodeOp *>::const_iterator endOp(void) const { return op.end(); }
405  bool emptyOp(void) const { return op.empty(); }
406  static bool noInterveningStatement(PcodeOp *first,int4 path,PcodeOp *last);
407 };
408 
419 class BlockCopy : public FlowBlock {
420  FlowBlock *copy;
421 public:
422  BlockCopy(FlowBlock *bl) { copy = bl; }
423  virtual FlowBlock *subBlock(int4 i) const { return copy; }
424  virtual block_type getType(void) const { return t_copy; }
425  virtual void printHeader(ostream &s) const;
426  virtual void printTree(ostream &s,int4 level) const;
427  virtual void printRaw(ostream &s) const { copy->printRaw(s); }
428  virtual void emit(PrintLanguage *lng) const { lng->emitBlockCopy(this); }
429  virtual const FlowBlock *getExitLeaf(void) const { return this; }
430  virtual PcodeOp *lastOp(void) const { return copy->lastOp(); }
431  virtual bool negateCondition(bool toporbottom) { bool res = copy->negateCondition(true); FlowBlock::negateCondition(toporbottom); return res; }
432  virtual FlowBlock *getSplitPoint(void) { return copy->getSplitPoint(); }
433  virtual bool isComplex(void) const { return copy->isComplex(); }
434  virtual void saveXmlHeader(ostream &s) const;
435 };
436 
444 class BlockGoto : public BlockGraph {
445  FlowBlock *gototarget;
446  uint4 gototype;
447 public:
448  BlockGoto(FlowBlock *bl) { gototarget = bl; gototype = f_goto_goto; }
449  FlowBlock *getGotoTarget(void) const { return gototarget; }
450  uint4 getGotoType(void) const { return gototype; }
451  bool gotoPrints(void) const;
452  virtual block_type getType(void) const { return t_goto; }
453  virtual void markUnstructured(void);
454  virtual void scopeBreak(int4 curexit,int4 curloopexit);
455  virtual void printHeader(ostream &s) const;
456  virtual void printRaw(ostream &s) const { getBlock(0)->printRaw(s); }
457  virtual void emit(PrintLanguage *lng) const { lng->emitBlockGoto(this); }
458  virtual const FlowBlock *getExitLeaf(void) const { return getBlock(0)->getExitLeaf(); }
459  virtual PcodeOp *lastOp(void) const { return getBlock(0)->lastOp(); }
460  virtual FlowBlock *nextFlowAfter(const FlowBlock *bl) const;
461  virtual void saveXmlBody(ostream &s) const;
462 };
463 
470 class BlockMultiGoto : public BlockGraph {
471  vector<FlowBlock *> gotoedges;
472  bool defaultswitch;
473 public:
474  BlockMultiGoto(FlowBlock *bl) { defaultswitch = false; }
475  void setDefaultGoto(void) { defaultswitch = true; }
476  bool hasDefaultGoto(void) const { return defaultswitch; }
477  void addEdge(FlowBlock *bl) { gotoedges.push_back(bl); }
478  int4 numGotos(void) const { return gotoedges.size(); }
479  FlowBlock *getGoto(int4 i) const { return gotoedges[i]; }
480 
481  virtual block_type getType(void) const { return t_multigoto; }
482  virtual void scopeBreak(int4 curexit,int4 curloopexit);
483  virtual void printHeader(ostream &s) const;
484  virtual void printRaw(ostream &s) const { getBlock(0)->printRaw(s); }
485  virtual void emit(PrintLanguage *lng) const { getBlock(0)->emit(lng); }
486  virtual const FlowBlock *getExitLeaf(void) const { return getBlock(0)->getExitLeaf(); }
487  virtual PcodeOp *lastOp(void) const { return getBlock(0)->lastOp(); }
488  virtual FlowBlock *nextFlowAfter(const FlowBlock *bl) const;
489  virtual void saveXmlBody(ostream &s) const;
490 };
491 
497 class BlockList : public BlockGraph {
498 public:
499  virtual block_type getType(void) const { return t_ls; }
500  virtual void printHeader(ostream &s) const;
501  virtual void emit(PrintLanguage *lng) const { lng->emitBlockLs(this); }
502  virtual const FlowBlock *getExitLeaf(void) const;
503  virtual PcodeOp *lastOp(void) const;
504  virtual bool negateCondition(bool toporbottom);
505  virtual FlowBlock *getSplitPoint(void);
506 };
507 
518 class BlockCondition : public BlockGraph {
519  OpCode opc;
520 public:
521  BlockCondition(OpCode c) { opc = c; }
522  OpCode getOpcode(void) const { return opc; }
523  virtual block_type getType(void) const { return t_condition; }
524  virtual void scopeBreak(int4 curexit,int4 curloopexit);
525  virtual void printHeader(ostream &s) const;
526  virtual void emit(PrintLanguage *lng) const { lng->emitBlockCondition(this); }
527  virtual bool negateCondition(bool toporbottom);
528  virtual FlowBlock *getSplitPoint(void) { return this; }
529  virtual int4 flipInPlaceTest(vector<PcodeOp *> &fliplist) const;
530  virtual void flipInPlaceExecute(void);
531  virtual PcodeOp *lastOp(void) const;
532  virtual bool isComplex(void) const { return getBlock(0)->isComplex(); }
533  virtual FlowBlock *nextFlowAfter(const FlowBlock *bl) const;
534  virtual void saveXmlHeader(ostream &s) const;
535 };
536 
555 class BlockIf : public BlockGraph {
556  uint4 gototype;
557  FlowBlock *gototarget;
558 public:
559  BlockIf(void) { gototype = f_goto_goto; gototarget = (FlowBlock *)0; }
560  void setGotoTarget(FlowBlock *bl) { gototarget = bl; }
561  FlowBlock *getGotoTarget(void) const { return gototarget; }
562  uint4 getGotoType(void) const { return gototype; }
563  virtual block_type getType(void) const { return t_if; }
564  virtual void markUnstructured(void);
565  virtual void scopeBreak(int4 curexit,int4 curloopexit);
566  virtual void printHeader(ostream &s) const;
567  virtual void emit(PrintLanguage *lng) const { lng->emitBlockIf(this); }
568  virtual bool preferComplement(Funcdata &data);
569  virtual const FlowBlock *getExitLeaf(void) const;
570  virtual PcodeOp *lastOp(void) const;
571  virtual FlowBlock *nextFlowAfter(const FlowBlock *bl) const;
572  virtual void saveXmlBody(ostream &s) const;
573 };
574 
590 class BlockWhileDo : public BlockGraph {
591  mutable PcodeOp *initializeOp;
592  mutable PcodeOp *iterateOp;
593  mutable PcodeOp *loopDef;
594  void findLoopVariable(PcodeOp *cbranch,BlockBasic *head,BlockBasic *tail,PcodeOp *lastOp);
595  PcodeOp *findInitializer(BlockBasic *head,int4 slot) const;
596  PcodeOp *testTerminal(Funcdata &data,int4 slot) const;
597  bool testIterateForm(void) const;
598 public:
599  BlockWhileDo(void) { initializeOp = (PcodeOp *)0; iterateOp = (PcodeOp *)0; loopDef = (PcodeOp *)0; }
600  PcodeOp *getInitializeOp(void) const { return initializeOp; }
601  PcodeOp *getIterateOp(void) const { return iterateOp; }
602  bool hasOverflowSyntax(void) const { return ((getFlags() & f_whiledo_overflow)!=0); }
603  void setOverflowSyntax(void) { setFlag(f_whiledo_overflow); }
604  virtual block_type getType(void) const { return t_whiledo; }
605  virtual void markLabelBumpUp(bool bump);
606  virtual void scopeBreak(int4 curexit,int4 curloopexit);
607  virtual void printHeader(ostream &s) const;
608  virtual void emit(PrintLanguage *lng) const { lng->emitBlockWhileDo(this); }
609  virtual FlowBlock *nextFlowAfter(const FlowBlock *bl) const;
610  virtual void finalTransform(Funcdata &data);
611  virtual void finalizePrinting(Funcdata &data) const;
612 };
613 
618 class BlockDoWhile : public BlockGraph {
619 public:
620  virtual block_type getType(void) const { return t_dowhile; }
621  virtual void markLabelBumpUp(bool bump);
622  virtual void scopeBreak(int4 curexit,int4 curloopexit);
623  virtual void printHeader(ostream &s) const;
624  virtual void emit(PrintLanguage *lng) const { lng->emitBlockDoWhile(this); }
625  virtual FlowBlock *nextFlowAfter(const FlowBlock *bl) const;
626 };
627 
632 class BlockInfLoop : public BlockGraph {
633 public:
634  virtual block_type getType(void) const { return t_infloop; }
635  virtual void markLabelBumpUp(bool bump);
636  virtual void scopeBreak(int4 curexit,int4 curloopexit);
637  virtual void printHeader(ostream &s) const;
638  virtual void emit(PrintLanguage *lng) const { lng->emitBlockInfLoop(this); }
639  virtual FlowBlock *nextFlowAfter(const FlowBlock *bl) const;
640 };
641 
649 class BlockSwitch : public BlockGraph {
650  JumpTable *jump;
651  struct CaseOrder {
653  FlowBlock *block;
654  const FlowBlock *basicblock;
655  uintb label;
656  int4 depth;
657  int4 chain;
658  int4 outindex;
659  uint4 gototype;
660  bool isexit;
661  bool isdefault;
662  static bool compare(const CaseOrder &a,const CaseOrder &b);
663  };
664  mutable vector<CaseOrder> caseblocks;
665  void addCase(FlowBlock *switchbl,FlowBlock *bl,uint4 gt);
666 public:
667  BlockSwitch(FlowBlock *ind);
668  void grabCaseBasic(FlowBlock *switchbl,const vector<FlowBlock *> &cs);
669  FlowBlock *getSwitchBlock(void) const { return getBlock(0); }
670  int4 getNumCaseBlocks(void) const { return caseblocks.size(); }
671  FlowBlock *getCaseBlock(int4 i) const { return caseblocks[i].block; }
672 
677  int4 getNumLabels(int4 i) const { return jump->numIndicesByBlock(caseblocks[i].basicblock); }
678 
684  uintb getLabel(int4 i,int4 j) const { return jump->getLabelByIndex(jump->getIndexByBlock(caseblocks[i].basicblock,j)); }
685 
686  bool isDefaultCase(int4 i) const { return caseblocks[i].isdefault; }
687  uint4 getGotoType(int4 i) const { return caseblocks[i].gototype; }
688  bool isExit(int4 i) const { return caseblocks[i].isexit; }
689  const Datatype *getSwitchType(void) const;
690  virtual block_type getType(void) const { return t_switch; }
691  virtual void markUnstructured(void);
692  virtual void scopeBreak(int4 curexit,int4 curloopexit);
693  virtual void printHeader(ostream &s) const;
694  virtual void emit(PrintLanguage *lng) const { lng->emitBlockSwitch(this); }
695  virtual FlowBlock *nextFlowAfter(const FlowBlock *bl) const;
696  virtual void finalizePrinting(Funcdata &data) const;
697 };
698 
705 class BlockMap {
706  const AddrSpaceManager *manage;
707  vector<FlowBlock *> sortlist;
708  FlowBlock *resolveBlock(FlowBlock::block_type bt);
709  static FlowBlock *findBlock(const vector<FlowBlock *> &list,int4 ind);
710 public:
711  BlockMap(const AddrSpaceManager *m) { manage = m; }
712  BlockMap(const BlockMap &op2);
713  const AddrSpaceManager *getAddressManager(void) const { return manage; }
714  void sortList(void);
715 
720  FlowBlock *findLevelBlock(int4 index) const { return findBlock(sortlist,index); }
721  FlowBlock *createBlock(const string &name);
722 };
723 
726 inline void FlowBlock::emit(PrintLanguage *lng) const
727 
728 {
729 }
730 
736 
737 {
738  return false;
739 }
740 
746 
747 {
748  return (FlowBlock *)0;
749 }
750 
762 inline int4 FlowBlock::flipInPlaceTest(vector<PcodeOp *> &fliplist) const
763 
764 {
765  return 2; // By default a block will not normalize
766 }
767 
773 
774 {
775 }
776 
786 
787 {
788  return (FlowBlock *)0;
789 }
790 
794 inline bool FlowBlock::compareBlockIndex(const FlowBlock *bl1,const FlowBlock *bl2)
795 
796 {
797  return (bl1->getIndex() < bl2->getIndex());
798 }
799 
804 inline bool BlockSwitch::CaseOrder::compare(const CaseOrder &a,const CaseOrder &b)
805 
806 {
807  if (a.label != b.label)
808  return (a.label < b.label);
809  return (a.depth < b.depth);
810 }
811 
812 #endif
BlockGraph::spliceBlock
void spliceBlock(FlowBlock *bl)
Splice given FlowBlock together with its output.
Definition: block.cc:1510
BlockGraph::orderBlocks
void orderBlocks(void)
Definition: block.hh:334
FlowBlock::FlowBlock
FlowBlock(void)
Construct a block with no edges.
Definition: block.cc:50
BlockGraph::newBlock
FlowBlock * newBlock(void)
Build a new plain FlowBlock.
Definition: block.cc:1572
PrintLanguage
The base class API for emitting a high-level language.
Definition: printlanguage.hh:134
BlockSwitch::getSwitchType
const Datatype * getSwitchType(void) const
Get the data-type of the switch variable.
Definition: block.cc:3375
BlockGraph::buildDomSubTree
void buildDomSubTree(vector< FlowBlock * > &res, FlowBlock *root) const
Collect nodes from a dominator sub-tree.
Definition: block.cc:1986
BlockGraph
A control-flow block built out of sub-components.
Definition: block.hh:271
BlockBasic::flipInPlaceTest
virtual int4 flipInPlaceTest(vector< PcodeOp * > &fliplist) const
Test normalizing the conditional branch in this.
Definition: block.cc:2267
FlowBlock::f_whiledo_overflow
@ f_whiledo_overflow
Set if the conditional block of a whiledo is too big to print as while(cond) { ...
Definition: block.hh:89
FlowBlock
Description of a control-flow block containing PcodeOps.
Definition: block.hh:60
BlockWhileDo::finalTransform
virtual void finalTransform(Funcdata &data)
Definition: block.cc:3135
FlowBlock::f_goto_goto
@ f_goto_goto
(Block ends in) non-structured branch
Definition: block.hh:76
BlockDoWhile::emit
virtual void emit(PrintLanguage *lng) const
Emit the instructions in this FlowBlock as structured code.
Definition: block.hh:624
PrintLanguage::emitBlockCopy
virtual void emitBlockCopy(const BlockCopy *bl)=0
Emit a basic block (with any labels)
BlockGraph::newBlockMultiGoto
BlockMultiGoto * newBlockMultiGoto(FlowBlock *bl, int4 outedge)
Build a new BlockMultiGoto.
Definition: block.cc:1633
FlowBlock::restrictedByConditional
bool restrictedByConditional(const FlowBlock *cond) const
Check if the condition from the given block holds for this block.
Definition: block.cc:381
FlowBlock::isLoopDAGIn
bool isLoopDAGIn(int4 i) const
Is the i-th incoming edge part of the DAG sub-graph.
Definition: block.hh:253
FlowBlock::getInIndex
int4 getInIndex(const FlowBlock *bl) const
Get the incoming edge index for the given FlowBlock.
Definition: block.cc:549
BlockCopy::printHeader
virtual void printHeader(ostream &s) const
Print a simple description of this to stream.
Definition: block.cc:2614
FlowBlock::calcDepth
int4 calcDepth(const FlowBlock *leaf) const
Get the depth of the given component FlowBlock.
Definition: block.cc:344
FlowBlock::emit
virtual void emit(PrintLanguage *lng) const
Emit the instructions in this FlowBlock as structured code.
Definition: block.hh:726
BlockDoWhile::markLabelBumpUp
virtual void markLabelBumpUp(bool bump)
Let hierarchical blocks steal labels of their (first) components.
Definition: block.cc:3205
BlockGraph::clearVisitCount
void clearVisitCount(void)
Clear the visit count in all node FlowBlocks.
Definition: block.cc:1846
PrintLanguage::emitBlockLs
virtual void emitBlockLs(const BlockList *bl)=0
Emit a sequence of blocks.
BlockGraph::calcLoop
void calcLoop(void)
Calculate loop edges.
Definition: block.cc:2010
FlowBlock::restoreXmlBody
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:184
FlowBlock::f_mark2
@ f_mark2
A secondary mark.
Definition: block.hh:82
FlowBlock::compareFinalOrder
static bool compareFinalOrder(const FlowBlock *bl1, const FlowBlock *bl2)
Final FlowBlock comparison.
Definition: block.cc:668
BlockWhileDo::markLabelBumpUp
virtual void markLabelBumpUp(bool bump)
Let hierarchical blocks steal labels of their (first) components.
Definition: block.cc:3095
FlowBlock::f_entry_point
@ f_entry_point
Official entry point of the function.
Definition: block.hh:83
FlowBlock::findCommonBlock
static FlowBlock * findCommonBlock(FlowBlock *bl1, FlowBlock *bl2)
Find the common dominator of two FlowBlocks.
Definition: block.cc:695
BlockDoWhile
A loop structure where the condition is checked at the bottom.
Definition: block.hh:618
BlockEdge
A control-flow edge between blocks (FlowBlock)
Definition: block.hh:44
PrintLanguage::emitBlockGoto
virtual void emitBlockGoto(const BlockGoto *bl)=0
Emit a block ending with a goto statement.
FlowBlock::nameToType
static block_type nameToType(const string &name)
Get the block_type associated with a name string.
Definition: block.cc:616
BlockGraph::emit
virtual void emit(PrintLanguage *lng) const
Emit the instructions in this FlowBlock as structured code.
Definition: block.hh:298
JumpTable
A map from values to control-flow targets within a function.
Definition: jumptable.hh:499
FlowBlock::f_label_bumpup
@ f_label_bumpup
Any label printed higher up in hierarchy.
Definition: block.hh:86
FlowBlock::restoreXmlEdges
void restoreXmlEdges(List::const_iterator &iter, List::const_iterator enditer, BlockMap &resolver)
Restore edges from an XML stream.
Definition: block.cc:2376
BlockGraph::nextFlowAfter
virtual FlowBlock * nextFlowAfter(const FlowBlock *bl) const
Get the leaf FlowBlock that will execute after the given FlowBlock.
Definition: block.cc:1240
FlowBlock::hasLoopOut
bool hasLoopOut(void) const
Is there a looping edge going out of this block.
Definition: block.cc:407
BlockSwitch::printHeader
virtual void printHeader(ostream &s) const
Print a simple description of this to stream.
Definition: block.cc:3411
BlockGraph::structureLoops
void structureLoops(vector< FlowBlock * > &rootlist)
Label loop edges.
Definition: block.cc:2100
BlockGraph::removeFromFlowSplit
void removeFromFlowSplit(FlowBlock *bl, bool flipflow)
Remove FlowBlock splitting flow between input and output edges.
Definition: block.cc:1488
RangeList::inRange
bool inRange(const Address &addr, int4 size) const
Check containment an address range.
Definition: address.cc:402
FlowBlock::f_unstructured_targ
@ f_unstructured_targ
Block is destination of unstructured goto.
Definition: block.hh:80
BlockInfLoop::nextFlowAfter
virtual FlowBlock * nextFlowAfter(const FlowBlock *bl) const
Get the leaf FlowBlock that will execute after the given FlowBlock.
Definition: block.cc:3255
BlockGraph::swapBlocks
void swapBlocks(int4 i, int4 j)
Swap the positions two component FlowBlocks.
Definition: block.cc:1150
BlockCondition::flipInPlaceExecute
virtual void flipInPlaceExecute(void)
Perform the flip to normalize conditional branch executed by this block.
Definition: block.cc:2787
BlockWhileDo::finalizePrinting
virtual void finalizePrinting(Funcdata &data) const
Definition: block.cc:3182
FlowBlock::nextInFlow
const FlowBlock * nextInFlow(void) const
Return next block to be executed in flow.
Definition: block.cc:2420
FlowBlock::getSplitPoint
virtual FlowBlock * getSplitPoint(void)
Get the leaf splitting block.
Definition: block.hh:745
FlowBlock::f_forward_edge
@ f_forward_edge
An edge that jumps forward in the spanning tree.
Definition: block.hh:101
FlowBlock::f_break_goto
@ f_break_goto
Block ends with a break;.
Definition: block.hh:77
PrintLanguage::emitBlockIf
virtual void emitBlockIf(const BlockIf *bl)=0
Emit an if/else style construct.
PrintLanguage::emitBlockWhileDo
virtual void emitBlockWhileDo(const BlockWhileDo *bl)=0
Emit a loop structure, check at top.
BlockGraph::newBlockList
BlockList * newBlockList(const vector< FlowBlock * > &nodes)
Build a new BlockList.
Definition: block.cc:1664
FlowBlock::typeToName
static string typeToName(block_type bt)
Get the name string associated with a block_type.
Definition: block.cc:630
jumptable.hh
Classes to support jump-tables and their recovery.
PrintLanguage::emitBlockDoWhile
virtual void emitBlockDoWhile(const BlockDoWhile *bl)=0
Emit a loop structure, check at bottom.
BlockGraph::newBlockInfLoop
BlockInfLoop * newBlockInfLoop(FlowBlock *body)
Build a new BlockInfLoop.
Definition: block.cc:1795
FlowBlock::printTree
virtual void printTree(ostream &s, int4 level) const
Print tree structure of any blocks owned by this.
Definition: block.cc:586
FlowBlock::f_flip_path
@ f_flip_path
If true, out edges have been flipped since last time path was traced.
Definition: block.hh:90
Funcdata::endOp
list< PcodeOp * >::const_iterator endOp(OpCode opc) const
End of PcodeOp objects with the given op-code.
Definition: funcdata.hh:458
BlockGraph::newBlockCondition
BlockCondition * newBlockCondition(FlowBlock *b1, FlowBlock *b2)
Build a new BlockCondition.
Definition: block.cc:1686
FlowBlock::f_mark
@ f_mark
Generic way to mark a block.
Definition: block.hh:81
BlockGraph::newBlockWhileDo
BlockWhileDo * newBlockWhileDo(FlowBlock *cond, FlowBlock *cl)
Build a new BlockWhileDo.
Definition: block.cc:1764
FlowBlock::getOutIndex
int4 getOutIndex(const FlowBlock *bl) const
Get the outgoing edge index for the given FlowBlock.
Definition: block.cc:562
BlockInfLoop::markLabelBumpUp
virtual void markLabelBumpUp(bool bump)
Let hierarchical blocks steal labels of their (first) components.
Definition: block.cc:3233
BlockSwitch::grabCaseBasic
void grabCaseBasic(FlowBlock *switchbl, const vector< FlowBlock * > &cs)
Build annotated CaseOrder objects.
Definition: block.cc:3303
BlockBasic::isDoNothing
bool isDoNothing(void) const
Should this block should be removed.
Definition: block.cc:2502
BlockGraph::newBlockDoWhile
BlockDoWhile * newBlockDoWhile(FlowBlock *condcl)
Build a new BlockDoWhile.
Definition: block.cc:1780
BlockMultiGoto::printHeader
virtual void printHeader(ostream &s) const
Print a simple description of this to stream.
Definition: block.cc:2703
FlowBlock::f_loop_edge
@ f_loop_edge
Edge completes a loop, removing these edges gives you a DAG.
Definition: block.hh:97
BlockCondition::flipInPlaceTest
virtual int4 flipInPlaceTest(vector< PcodeOp * > &fliplist) const
Test normalizing the conditional branch in this.
Definition: block.cc:2769
BlockGraph::getStartBlock
FlowBlock * getStartBlock(void) const
Get the entry point FlowBlock.
Definition: block.cc:1562
BlockSwitch::getLabel
uintb getLabel(int4 i, int4 j) const
Get a specific label associated with a case block.
Definition: block.hh:684
BlockCondition::nextFlowAfter
virtual FlowBlock * nextFlowAfter(const FlowBlock *bl) const
Get the leaf FlowBlock that will execute after the given FlowBlock.
Definition: block.cc:2832
FlowBlock::f_interior_gotoout
@ f_interior_gotoout
The block has an unstructured jump out of interior.
Definition: block.hh:84
Element
An XML element. A node in the DOM tree.
Definition: xml.hh:150
BlockBasic
A basic block for p-code operations.
Definition: block.hh:365
BlockBasic::unblockedMulti
bool unblockedMulti(int4 outslot) const
Check if this block can be removed without introducing inconsistencies.
Definition: block.cc:2440
BlockIf::nextFlowAfter
virtual FlowBlock * nextFlowAfter(const FlowBlock *bl) const
Get the leaf FlowBlock that will execute after the given FlowBlock.
Definition: block.cc:2906
BlockBasic::noInterveningStatement
static bool noInterveningStatement(PcodeOp *first, int4 path, PcodeOp *last)
Check if there is meaningful activity between two branch instructions.
Definition: block.cc:2598
PcodeOp
Lowest level operation of the p-code language.
Definition: op.hh:58
BlockGraph::buildCopy
void buildCopy(const BlockGraph &graph)
Build a copy of a BlockGraph.
Definition: block.cc:1831
BlockCondition::emit
virtual void emit(PrintLanguage *lng) const
Emit the instructions in this FlowBlock as structured code.
Definition: block.hh:526
BlockGraph::newBlockGoto
BlockGoto * newBlockGoto(FlowBlock *bl)
Build a new BlockGoto.
Definition: block.cc:1615
BlockEdge::saveXml
void saveXml(ostream &s) const
Save the edge to an XML stream.
Definition: block.cc:22
BlockCopy::getSplitPoint
virtual FlowBlock * getSplitPoint(void)
Get the leaf splitting block.
Definition: block.hh:432
BlockGraph::removeFromFlow
void removeFromFlow(FlowBlock *bl)
Remove given FlowBlock preserving flow in this.
Definition: block.cc:1458
BlockWhileDo::printHeader
virtual void printHeader(ostream &s) const
Print a simple description of this to stream.
Definition: block.cc:3111
BlockMultiGoto
A block with multiple edges out, at least one of which is an unstructured (goto) branch.
Definition: block.hh:470
BlockGraph::setStartBlock
void setStartBlock(FlowBlock *bl)
Set the entry point FlowBlock for this graph.
Definition: block.cc:1538
BlockWhileDo::nextFlowAfter
virtual FlowBlock * nextFlowAfter(const FlowBlock *bl) const
Get the leaf FlowBlock that will execute after the given FlowBlock.
Definition: block.cc:3120
BlockEdge::label
uint4 label
Label of the edge.
Definition: block.hh:45
FlowBlock::block_type
block_type
The possible block types.
Definition: block.hh:64
FlowBlock::f_defaultswitch_edge
@ f_defaultswitch_edge
This is default edge from switchblock.
Definition: block.hh:98
BlockBasic::negateCondition
virtual bool negateCondition(bool toporbottom)
Flip the condition computed by this.
Definition: block.cc:2250
FlowBlock::restoreXml
void restoreXml(const Element *el, BlockMap &resolver)
Restore this from an XML stream.
Definition: block.cc:2406
BlockGraph::markCopyBlock
static void markCopyBlock(FlowBlock *bl, uint4 fl)
Set properties on the first leaf FlowBlock.
Definition: block.cc:1162
BlockDoWhile::nextFlowAfter
virtual FlowBlock * nextFlowAfter(const FlowBlock *bl) const
Get the leaf FlowBlock that will execute after the given FlowBlock.
Definition: block.cc:3227
FlowBlock::hasLoopIn
bool hasLoopIn(void) const
Is there a looping edge coming into this block.
Definition: block.cc:398
BlockInfLoop
An infinite loop structure.
Definition: block.hh:632
RangeList
A disjoint set of Ranges, possibly across multiple address spaces.
Definition: address.hh:203
BlockList::emit
virtual void emit(PrintLanguage *lng) const
Emit the instructions in this FlowBlock as structured code.
Definition: block.hh:501
BlockCopy::printTree
virtual void printTree(ostream &s, int4 level) const
Print tree structure of any blocks owned by this.
Definition: block.cc:2621
BlockCondition::saveXmlHeader
virtual void saveXmlHeader(ostream &s) const
Save basic information as XML attributes.
Definition: block.cc:2838
BlockIf::preferComplement
virtual bool preferComplement(Funcdata &data)
Rearrange this hierarchy to simplify boolean expressions.
Definition: block.cc:2872
BlockGraph::removeBlock
void removeBlock(FlowBlock *bl)
Remove a FlowBlock from this BlockGraph.
Definition: block.cc:1430
Funcdata::printRaw
void printRaw(ostream &s) const
Print raw p-code op descriptions to a stream.
Definition: funcdata.cc:193
BlockList::printHeader
virtual void printHeader(ostream &s) const
Print a simple description of this to stream.
Definition: block.cc:2762
BlockSwitch::getNumLabels
int4 getNumLabels(int4 i) const
Get the number of labels associated with one case block.
Definition: block.hh:677
BlockGoto
A block that terminates with an unstructured (goto) branch to another block.
Definition: block.hh:444
FlowBlock::edge_flags
edge_flags
Boolean properties on edges.
Definition: block.hh:95
FlowBlock::f_interior_gotoin
@ f_interior_gotoin
Block is target of unstructured jump to its interior.
Definition: block.hh:85
JumpTable::numIndicesByBlock
int4 numIndicesByBlock(const FlowBlock *bl) const
Return the number of address table entries that target the given basic-block.
Definition: jumptable.cc:2268
FlowBlock::saveXmlHeader
virtual void saveXmlHeader(ostream &s) const
Save basic information as XML attributes.
Definition: block.cc:2346
PrintLanguage::emitBlockCondition
virtual void emitBlockCondition(const BlockCondition *bl)=0
Emit a conditional statement.
BlockMap::BlockMap
BlockMap(const BlockMap &op2)
Copy constructor.
Definition: block.cc:3437
BlockSwitch::nextFlowAfter
virtual FlowBlock * nextFlowAfter(const FlowBlock *bl) const
Get the leaf FlowBlock that will execute after the given FlowBlock.
Definition: block.cc:3418
FlowBlock::preferComplement
virtual bool preferComplement(Funcdata &data)
Rearrange this hierarchy to simplify boolean expressions.
Definition: block.hh:735
FlowBlock::f_dead
@ f_dead
Block is in process of being deleted.
Definition: block.hh:88
BlockGraph::collectReachable
void collectReachable(vector< FlowBlock * > &res, FlowBlock *bl, bool un) const
Collect reachable/unreachable FlowBlocks from a given start FlowBlock.
Definition: block.cc:2060
BlockGraph::restoreXml
void restoreXml(const Element *el, const AddrSpaceManager *m)
Restore this BlockGraph from an XML stream.
Definition: block.cc:1342
PrintLanguage::emitBlockGraph
virtual void emitBlockGraph(const BlockGraph *bl)=0
Emit (an unspecified) list of blocks.
BlockCondition::printHeader
virtual void printHeader(ostream &s) const
Print a simple description of this to stream.
Definition: block.cc:2820
FlowBlock::f_joined_block
@ f_joined_block
Block is a merged form of original basic blocks.
Definition: block.hh:91
BlockMultiGoto::nextFlowAfter
virtual FlowBlock * nextFlowAfter(const FlowBlock *bl) const
Get the leaf FlowBlock that will execute after the given FlowBlock.
Definition: block.cc:2710
FlowBlock::negateCondition
virtual bool negateCondition(bool toporbottom)
Flip the condition computed by this.
Definition: block.cc:282
RangeList::merge
void merge(const RangeList &op2)
Merge another RangeList into this.
Definition: address.cc:385
BlockGraph::newBlockCopy
BlockCopy * newBlockCopy(FlowBlock *bl)
Build a new BlockCopy.
Definition: block.cc:1594
FlowBlock::f_goto_edge
@ f_goto_edge
Edge is unstructured.
Definition: block.hh:96
FlowBlock::f_donothing_loop
@ f_donothing_loop
Block does nothing in infinite loop (halt)
Definition: block.hh:87
BlockCopy::saveXmlHeader
virtual void saveXmlHeader(ostream &s) const
Save basic information as XML attributes.
Definition: block.cc:2627
FlowBlock::setGotoBranch
void setGotoBranch(int4 i)
Mark a goto branch.
Definition: block.cc:293
Address
A low-level machine address for labelling bytes and data.
Definition: address.hh:46
BlockGraph::newBlockSwitch
BlockSwitch * newBlockSwitch(const vector< FlowBlock * > &cs, bool hasExit)
Build a new BlockSwitch.
Definition: block.cc:1810
BlockInfLoop::printHeader
virtual void printHeader(ostream &s) const
Print a simple description of this to stream.
Definition: block.cc:3248
BlockBasic::getEntryAddr
Address getEntryAddr(void) const
Get the address of the (original) first operation to execute.
Definition: block.cc:2208
BlockSwitch::emit
virtual void emit(PrintLanguage *lng) const
Emit the instructions in this FlowBlock as structured code.
Definition: block.hh:694
BlockIf::printHeader
virtual void printHeader(ostream &s) const
Print a simple description of this to stream.
Definition: block.cc:2865
Funcdata
Container for data structures associated with a single function.
Definition: funcdata.hh:45
Datatype
The base datatype class for the decompiler.
Definition: type.hh:62
BlockList
A series of blocks that execute in sequence.
Definition: block.hh:497
BlockBasic::getSplitPoint
virtual FlowBlock * getSplitPoint(void)
Get the leaf splitting block.
Definition: block.cc:2260
FlowBlock::f_switch_out
@ f_switch_out
Output is decided by switch.
Definition: block.hh:79
BlockGraph::clear
void clear(void)
Clear all component FlowBlock objects.
Definition: block.cc:1168
FlowBlock::isDecisionIn
bool isDecisionIn(int4 i) const
Can this and the i-th input be merged into a BlockIf or BlockList.
Definition: block.hh:247
BlockGraph::buildDomDepth
int4 buildDomDepth(vector< int4 > &depth) const
Calculate dominator depths.
Definition: block.cc:1962
BlockGraph::moveOutEdge
void moveOutEdge(FlowBlock *blold, int4 slot, FlowBlock *blnew)
Move indicated out edge to a new FlowBlock.
Definition: block.cc:1415
BlockGraph::addLoopEdge
void addLoopEdge(FlowBlock *begin, int4 outindex)
Mark a given edge as a loop edge.
Definition: block.cc:1364
FlowBlock::restoreXmlHeader
virtual void restoreXmlHeader(const Element *el)
Restore basic information for XML attributes.
Definition: block.cc:2353
BlockBasic::printHeader
virtual void printHeader(ostream &s) const
Print a simple description of this to stream.
Definition: block.cc:2565
BlockGoto::emit
virtual void emit(PrintLanguage *lng) const
Emit the instructions in this FlowBlock as structured code.
Definition: block.hh:457
BlockGraph::printTree
virtual void printTree(ostream &s, int4 level) const
Print tree structure of any blocks owned by this.
Definition: block.cc:1219
FlowBlock::isDecisionOut
bool isDecisionOut(int4 i) const
Can this and the i-th output be merged into a BlockIf or BlockList.
Definition: block.hh:244
BlockMap::findLevelBlock
FlowBlock * findLevelBlock(int4 index) const
Find the FlowBlock matching the given index.
Definition: block.hh:720
BlockWhileDo::emit
virtual void emit(PrintLanguage *lng) const
Emit the instructions in this FlowBlock as structured code.
Definition: block.hh:608
BlockGraph::newBlockIfGoto
BlockIf * newBlockIfGoto(FlowBlock *cond)
Build a new BlockIfGoto.
Definition: block.cc:1705
Funcdata::beginOp
list< PcodeOp * >::const_iterator beginOp(OpCode opc) const
Start of PcodeOp objects with the given op-code.
Definition: funcdata.hh:455
FlowBlock::flipInPlaceExecute
virtual void flipInPlaceExecute(void)
Perform the flip to normalize conditional branch executed by this block.
Definition: block.hh:772
BlockMap::createBlock
FlowBlock * createBlock(const string &name)
Create a FlowBlock of the named type.
Definition: block.cc:3494
BlockWhileDo
A loop structure where the condition is checked at the top.
Definition: block.hh:590
BlockSwitch::BlockSwitch
BlockSwitch(FlowBlock *ind)
Construct given the multi-exit root block.
Definition: block.cc:3264
BlockGraph::calcForwardDominator
void calcForwardDominator(const vector< FlowBlock * > &rootlist)
Calculate forward dominators.
Definition: block.cc:1860
FlowBlock::printHeader
virtual void printHeader(ostream &s) const
Print a simple description of this to stream.
Definition: block.cc:574
OpCode
OpCode
The op-code defining a specific p-code operation (PcodeOp)
Definition: opcodes.hh:35
JumpTable::getIndexByBlock
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:2315
BlockIf
A basic "if" block.
Definition: block.hh:555
BlockMultiGoto::emit
virtual void emit(PrintLanguage *lng) const
Emit the instructions in this FlowBlock as structured code.
Definition: block.hh:485
PrintLanguage::emitBlockSwitch
virtual void emitBlockSwitch(const BlockSwitch *bl)=0
Emit a switch structure.
BlockCondition::negateCondition
virtual bool negateCondition(bool toporbottom)
Flip the condition computed by this.
Definition: block.cc:2802
BlockMap
Helper class for resolving cross-references while deserializing BlockGraph objects.
Definition: block.hh:705
BlockGraph::removeEdge
void removeEdge(FlowBlock *begin, FlowBlock *end)
Remove an edge between component FlowBlocks.
Definition: block.cc:1382
BlockCopy::emit
virtual void emit(PrintLanguage *lng) const
Emit the instructions in this FlowBlock as structured code.
Definition: block.hh:428
BlockGraph::newBlockIf
BlockIf * newBlockIf(FlowBlock *cond, FlowBlock *tc)
Build a new BlockIf.
Definition: block.cc:1728
FlowBlock::getFrontLeaf
const FlowBlock * getFrontLeaf(void) const
Get the first leaf FlowBlock.
Definition: block.cc:316
BlockEdge::restoreXml
void restoreXml(const Element *el, BlockMap &resolver)
Restore this edge from an XML stream.
Definition: block.cc:34
BlockGraph::addEdge
void addEdge(FlowBlock *begin, FlowBlock *end)
Add a directed edge between component FlowBlocks.
Definition: block.cc:1352
FlowBlock::f_cross_edge
@ f_cross_edge
An edge that crosses subtrees in the spanning tree.
Definition: block.hh:102
FlowBlock::dominates
bool dominates(const FlowBlock *subBlock) const
Does this block dominate the given block.
Definition: block.cc:362
FlowBlock::f_continue_goto
@ f_continue_goto
Block ends with a continue;.
Definition: block.hh:78
FlowBlock::f_tree_edge
@ f_tree_edge
An edge in the spanning tree.
Definition: block.hh:100
BlockEdge::reverse_index
int4 reverse_index
Index for edge coming other way.
Definition: block.hh:47
BlockIf::emit
virtual void emit(PrintLanguage *lng) const
Emit the instructions in this FlowBlock as structured code.
Definition: block.hh:567
BlockBasic::hasOnlyMarkers
bool hasOnlyMarkers(void) const
Does this block contain only MULTIEQUAL and INDIRECT ops.
Definition: block.cc:2484
PrintLanguage::emitBlockBasic
virtual void emitBlockBasic(const BlockBasic *bb)=0
Emit statements in a basic block.
BlockBasic::restoreXmlBody
virtual void restoreXmlBody(List::const_iterator &iter, List::const_iterator enditer, BlockMap &resolver)
Restore details about this FlowBlock from an XML stream.
Definition: block.cc:2558
PrintLanguage::emitBlockInfLoop
virtual void emitBlockInfLoop(const BlockInfLoop *bl)=0
Emit an infinite loop structure.
BlockBasic::emit
virtual void emit(PrintLanguage *lng) const
Emit the instructions in this FlowBlock as structured code.
Definition: block.hh:390
FlowBlock::block_flags
block_flags
Boolean properties of blocks.
Definition: block.hh:75
FlowBlock::getJumptable
JumpTable * getJumptable(void) const
Get the JumpTable associated this block.
Definition: block.cc:600
BlockCopy::negateCondition
virtual bool negateCondition(bool toporbottom)
Flip the condition computed by this.
Definition: block.hh:431
FlowBlock::f_irreducible
@ f_irreducible
Edge which must be removed to make graph reducible.
Definition: block.hh:99
BlockGraph::newBlockBasic
BlockBasic * newBlockBasic(Funcdata *fd)
Build a new BlockBasic.
Definition: block.cc:1583
BlockGraph::markLabelBumpUp
virtual void markLabelBumpUp(bool bump)
Let hierarchical blocks steal labels of their (first) components.
Definition: block.cc:1187
FlowBlock::nextFlowAfter
virtual FlowBlock * nextFlowAfter(const FlowBlock *bl) const
Get the leaf FlowBlock that will execute after the given FlowBlock.
Definition: block.hh:785
FlowBlock::isLoopDAGOut
bool isLoopDAGOut(int4 i) const
Is the i-th outgoing edge part of the DAG sub-graph.
Definition: block.hh:250
FlowBlock::f_duplicate_block
@ f_duplicate_block
Block is a duplicated version of an original basic block.
Definition: block.hh:92
BlockGoto::gotoPrints
bool gotoPrints(void) const
Should a formal goto statement be emitted.
Definition: block.cc:2660
BlockList::negateCondition
virtual bool negateCondition(bool toporbottom)
Flip the condition computed by this.
Definition: block.cc:2746
FlowBlock::isJumpTarget
bool isJumpTarget(void) const
Return true if non-fallthru jump flows into this.
Definition: block.cc:305
AddrSpaceManager
A manager for different address spaces.
Definition: translate.hh:218
FlowBlock::flipInPlaceTest
virtual int4 flipInPlaceTest(vector< PcodeOp * > &fliplist) const
Test normalizing the conditional branch in this.
Definition: block.hh:762
FlowBlock::markLabelBumpUp
virtual void markLabelBumpUp(bool bump)
Let hierarchical blocks steal labels of their (first) components.
Definition: block.cc:247
BlockGraph::restoreXmlBody
virtual void restoreXmlBody(List::const_iterator &iter, List::const_iterator enditer, BlockMap &resolver)
Restore details about this FlowBlock from an XML stream.
Definition: block.cc:1306
BlockCondition
Two conditional blocks combined into one conditional using BOOL_AND or BOOL_OR.
Definition: block.hh:518
BlockBasic::flipInPlaceExecute
virtual void flipInPlaceExecute(void)
Perform the flip to normalize conditional branch executed by this block.
Definition: block.cc:2277
BlockGraph::newBlockIfElse
BlockIf * newBlockIfElse(FlowBlock *cond, FlowBlock *tc, FlowBlock *fc)
Build a new BlockIfElse.
Definition: block.cc:1746
FlowBlock::f_loop_exit_edge
@ f_loop_exit_edge
Edge exits the body of a loop.
Definition: block.hh:104
FlowBlock::f_back_edge
@ f_back_edge
Within (reducible) graph, a back edge defining a loop.
Definition: block.hh:103
BlockMap::sortList
void sortList(void)
Sort the list of FlowBlock objects.
Definition: block.cc:3484
BlockInfLoop::emit
virtual void emit(PrintLanguage *lng) const
Emit the instructions in this FlowBlock as structured code.
Definition: block.hh:638
BlockCondition::getSplitPoint
virtual FlowBlock * getSplitPoint(void)
Get the leaf splitting block.
Definition: block.hh:528
FlowBlock::saveXml
void saveXml(ostream &s) const
Write out this to an XML stream.
Definition: block.cc:2390
BlockDoWhile::printHeader
virtual void printHeader(ostream &s) const
Print a simple description of this to stream.
Definition: block.cc:3220
BlockGoto::printHeader
virtual void printHeader(ostream &s) const
Print a simple description of this to stream.
Definition: block.cc:2671
FlowBlock::saveXmlEdges
void saveXmlEdges(ostream &s) const
Save edge information to an XML stream.
Definition: block.cc:2363
BlockSwitch
A structured switch construction.
Definition: block.hh:649
BlockGoto::nextFlowAfter
virtual FlowBlock * nextFlowAfter(const FlowBlock *bl) const
Get the leaf FlowBlock that will execute after the given FlowBlock.
Definition: block.cc:2678
BlockGraph::buildDomTree
void buildDomTree(vector< vector< FlowBlock * > > &child) const
Build the dominator tree.
Definition: block.cc:1942
BlockEdge::point
FlowBlock * point
Other end of the edge.
Definition: block.hh:46
BlockCopy
This class is used to mirror the BlockBasic objects in the fixed control-flow graph for a function.
Definition: block.hh:419
BlockList::getSplitPoint
virtual FlowBlock * getSplitPoint(void)
Get the leaf splitting block.
Definition: block.cc:2755
BlockGraph::switchEdge
void switchEdge(FlowBlock *in, FlowBlock *outbefore, FlowBlock *outafter)
Move an edge from one out FlowBlock to another.
Definition: block.cc:1402
FlowBlock::compareBlockIndex
static bool compareBlockIndex(const FlowBlock *bl1, const FlowBlock *bl2)
Compare FlowBlock by index.
Definition: block.hh:794