My Project
blockaction.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  */
16 #ifndef __BLOCK_ACTION__
17 #define __BLOCK_ACTION__
18 
21 
22 #include "action.hh"
23 
29 class FloatingEdge {
30  FlowBlock *top;
31  FlowBlock *bottom;
32 public:
33  FloatingEdge(FlowBlock *t,FlowBlock *b) { top = t; bottom = b; }
34  FlowBlock *getTop(void) const { return top; }
35  FlowBlock *getBottom(void) const { return bottom; }
36  FlowBlock *getCurrentEdge(int4 &outedge,FlowBlock *graph);
37 };
38 
44 class LoopBody {
45  FlowBlock *head;
46  vector<FlowBlock *> tails;
47  int4 depth;
48  int4 uniquecount;
49  FlowBlock *exitblock;
50  list<FloatingEdge> exitedges;
51  LoopBody *immed_container;
52  void extendToContainer(const LoopBody &container,vector<FlowBlock *> &body) const;
53 public:
54  LoopBody(FlowBlock *h) { head=h; immed_container = (LoopBody *)0; depth=0; }
55  FlowBlock *getHead(void) const { return head; }
56  FlowBlock *getCurrentBounds(FlowBlock **top,FlowBlock *graph);
57  void addTail(FlowBlock *bl) { tails.push_back(bl); }
58  FlowBlock *getExitBlock(void) const { return exitblock; }
59  void findBase(vector<FlowBlock *> &body);
60  void extend(vector<FlowBlock *> &body) const;
61  void findExit(const vector<FlowBlock *> &body);
62  void orderTails(void);
63  void labelExitEdges(const vector<FlowBlock *> &body);
64  void labelContainments(const vector<FlowBlock *> &body,const vector<LoopBody *> &looporder);
65  void emitLikelyEdges(list<FloatingEdge> &likely,FlowBlock *graph);
66  void setExitMarks(FlowBlock *graph);
67  void clearExitMarks(FlowBlock *graph);
68  bool operator<(const LoopBody &op2) const { return (depth > op2.depth); }
69  static void mergeIdenticalHeads(vector<LoopBody *> &looporder);
70  static bool compare_ends(LoopBody *a,LoopBody *b);
71  static int4 compare_head(LoopBody *a,FlowBlock *looptop);
72  static LoopBody *find(FlowBlock *looptop,const vector<LoopBody *> &looporder);
73  static void clearMarks(vector<FlowBlock *> &body);
74 };
75 
94 class TraceDAG {
95 
96  struct BlockTrace;
97 
100  struct BranchPoint {
101  BranchPoint *parent;
102  int4 pathout;
103  FlowBlock *top;
104  vector<BlockTrace *> paths;
105  int4 depth;
106  bool ismark;
107  void createTraces(void);
108  public:
109  void markPath(void);
110  int4 distance(BranchPoint *op2);
111  FlowBlock *getPathStart(int4 i);
112  BranchPoint(void);
113  BranchPoint(BlockTrace *parenttrace);
114  ~BranchPoint(void);
115  };
116 
121  struct BlockTrace {
122  enum {
123  f_active = 1,
124  f_terminal = 2
125  };
126  uint4 flags;
127  BranchPoint *top;
128  int4 pathout;
129  FlowBlock *bottom;
130  FlowBlock *destnode;
131  int4 edgelump;
132  list<BlockTrace *>::iterator activeiter;
133  BranchPoint *derivedbp;
134  public:
135  BlockTrace(BranchPoint *t,int4 po,int4 eo);
136  BlockTrace(BranchPoint *root,int4 po,FlowBlock *bl);
137  bool isActive(void) const { return ((flags & f_active)!=0); }
138  bool isTerminal(void) const { return ((flags & f_terminal)!=0); }
139  };
140 
144  struct BadEdgeScore {
145  FlowBlock *exitproto;
146  BlockTrace *trace;
147  int4 distance;
148  int4 terminal;
149  int4 siblingedge;
150  bool compareFinal(const BadEdgeScore &op2) const;
151  bool operator<(const BadEdgeScore &op2) const;
152  };
153 
154  list<FloatingEdge> &likelygoto;
155  vector<FlowBlock *> rootlist;
156  vector<BranchPoint *> branchlist;
157  int4 activecount;
158  int4 missedactivecount;
159  list<BlockTrace *> activetrace;
160  list<BlockTrace *>::iterator current_activeiter;
161  FlowBlock *finishblock;
162  void removeTrace(BlockTrace *trace);
163  void processExitConflict(list<BadEdgeScore>::iterator start,list<BadEdgeScore>::iterator end);
164  BlockTrace *selectBadEdge(void);
165  void insertActive(BlockTrace *trace);
166  void removeActive(BlockTrace *trace);
167  bool checkOpen(BlockTrace *trace);
168  list<BlockTrace *>::iterator openBranch(BlockTrace *parent);
169  bool checkRetirement(BlockTrace *trace,FlowBlock *&exitblock);
170  list<BlockTrace *>::iterator retireBranch(BranchPoint *bp,FlowBlock *exitblock);
171  void clearVisitCount(void);
172 public:
173  TraceDAG(list<FloatingEdge> &lg);
174  ~TraceDAG(void);
175  void addRoot(FlowBlock *root) { rootlist.push_back(root); }
176  void initialize(void);
177  void pushBranches(void);
178  void setFinishBlock(FlowBlock *bl) { finishblock = bl; }
179 };
180 
191  bool finaltrace;
192  bool likelylistfull;
193  list<FloatingEdge> likelygoto;
194  list<FloatingEdge>::iterator likelyiter;
195  list<LoopBody> loopbody;
196  list<LoopBody>::iterator loopbodyiter;
197  BlockGraph &graph;
198  int4 dataflow_changecount;
199  bool checkSwitchSkips(FlowBlock *switchbl,FlowBlock *exitblock);
200  void onlyReachableFromRoot(FlowBlock *root,vector<FlowBlock *> &body);
201  int4 markExitsAsGotos(vector<FlowBlock *> &body);
202  bool clipExtraRoots(void);
203  void labelLoops(vector<LoopBody *> &looporder);
204  void orderLoopBodies(void);
205  bool updateLoopBody(void);
206  FlowBlock *selectGoto(void);
207  bool ruleBlockGoto(FlowBlock *bl);
208  bool ruleBlockCat(FlowBlock *bl);
209  bool ruleBlockOr(FlowBlock *bl);
210  bool ruleBlockProperIf(FlowBlock *bl);
211  bool ruleBlockIfElse(FlowBlock *bl);
212  bool ruleBlockIfNoExit(FlowBlock *bl);
213  bool ruleBlockWhileDo(FlowBlock *bl);
214  bool ruleBlockDoWhile(FlowBlock *bl);
215  bool ruleBlockInfLoop(FlowBlock *bl);
216  bool ruleBlockSwitch(FlowBlock *bl);
217  bool ruleCaseFallthru(FlowBlock *bl);
218  int4 collapseInternal(FlowBlock *targetbl);
219  void collapseConditions(void);
220 public:
222  int4 getChangeCount(void) const { return dataflow_changecount; }
223  void collapseAll(void);
224 };
225 
234  struct MergePair {
235  Varnode *side1;
236  Varnode *side2;
237  MergePair(Varnode *s1,Varnode *s2) { side1 = s1; side2 = s2; }
238  bool operator<(const MergePair &op2) const;
239  };
240  Funcdata &data;
241  BlockBasic *block1;
242  BlockBasic *block2;
243  BlockBasic *exita;
244  BlockBasic *exitb;
245  int4 a_in1;
246  int4 a_in2;
247  int4 b_in1;
248  int4 b_in2;
249  PcodeOp *cbranch1;
250  PcodeOp *cbranch2;
251  BlockBasic *joinblock;
252  map<MergePair,Varnode *> mergeneed;
253  bool findDups(void);
254  void checkExitBlock(BlockBasic *exit,int4 in1,int4 in2);
255  void cutDownMultiequals(BlockBasic *exit,int4 in1,int4 in2);
256  void setupMultiequals(void);
257  void moveCbranch(void); //< Move one of the duplicated CBRANCHs into the new \b joinblock
258 public:
259  ConditionalJoin(Funcdata &fd) : data(fd) { }
260  bool match(BlockBasic *b1,BlockBasic *b2);
261  void execute(void);
262  void clear(void);
263 };
264 
270 public:
271  ActionNormalizeBranches(const string &g) : Action(0,"normalizebranches",g) {}
272  virtual Action *clone(const ActionGroupList &grouplist) const {
273  if (!grouplist.contains(getGroup())) return (Action *)0;
274  return new ActionNormalizeBranches(getGroup());
275  }
276  virtual int4 apply(Funcdata &data);
277 };
278 
286 public:
287  ActionPreferComplement(const string &g) : Action(0,"prefercomplement",g) {}
288  virtual Action *clone(const ActionGroupList &grouplist) const {
289  if (!grouplist.contains(getGroup())) return (Action *)0;
290  return new ActionPreferComplement(getGroup());
291  }
292  virtual int4 apply(Funcdata &data);
293 };
294 
296 class ActionBlockStructure : public Action {
297 public:
298  ActionBlockStructure(const string &g) : Action(0,"blockstructure",g) {}
299  virtual Action *clone(const ActionGroupList &grouplist) const {
300  if (!grouplist.contains(getGroup())) return (Action *)0;
301  return new ActionBlockStructure(getGroup());
302  }
303  virtual int4 apply(Funcdata &data);
304 };
305 
309 class ActionFinalStructure : public Action {
310 public:
311  ActionFinalStructure(const string &g) : Action(0,"finalstructure",g) {}
312  virtual Action *clone(const ActionGroupList &grouplist) const {
313  if (!grouplist.contains(getGroup())) return (Action *)0;
314  return new ActionFinalStructure(getGroup());
315  }
316  virtual int4 apply(Funcdata &data);
317 };
318 
322 class ActionReturnSplit : public Action {
323  static void gatherReturnGotos(FlowBlock *parent,vector<FlowBlock *> &vec);
324  static bool isSplittable(BlockBasic *b);
325 public:
326  ActionReturnSplit(const string &g) : Action(0,"returnsplit",g) {}
327  virtual Action *clone(const ActionGroupList &grouplist) const {
328  if (!grouplist.contains(getGroup())) return (Action *)0;
329  return new ActionReturnSplit(getGroup());
330  }
331  virtual int4 apply(Funcdata &data);
332 };
333 
335 class ActionNodeJoin : public Action {
336 public:
337  ActionNodeJoin(const string &g) : Action(0,"nodejoin",g) {}
338  virtual Action *clone(const ActionGroupList &grouplist) const {
339  if (!grouplist.contains(getGroup())) return (Action *)0;
340  return new ActionNodeJoin(getGroup());
341  }
342  virtual int4 apply(Funcdata &data);
343 };
344 
345 #endif
virtual Action * clone(const ActionGroupList &grouplist) const
Clone the Action.
Definition: blockaction.hh:288
Description of a control-flow block containing PcodeOps.
Definition: block.hh:60
ActionNodeJoin(const string &g)
Constructor.
Definition: blockaction.hh:337
Structure control-flow using standard high-level code constructs.
Definition: blockaction.hh:296
FlowBlock * getCurrentEdge(int4 &outedge, FlowBlock *graph)
Get the current form of the edge.
Definition: blockaction.cc:25
The list of groups defining a root Action.
Definition: action.hh:29
Algorithm for selecting unstructured edges based an Directed Acyclic Graphs (DAG) ...
Definition: blockaction.hh:94
Container for data structures associated with a single function.
Definition: funcdata.hh:45
ActionFinalStructure(const string &g)
Constructor.
Definition: blockaction.hh:311
ActionBlockStructure(const string &g)
Constructor.
Definition: blockaction.hh:298
bool contains(const string &nm) const
Check if this ActionGroupList contains a given group.
Definition: action.hh:37
Class for holding an edge while the underlying graph is being manipulated.
Definition: blockaction.hh:29
void addRoot(FlowBlock *root)
Add a root FlowBlock to the trace.
Definition: blockaction.hh:175
virtual Action * clone(const ActionGroupList &grouplist) const
Clone the Action.
Definition: blockaction.hh:272
void setFinishBlock(FlowBlock *bl)
Mark an exit point not to trace beyond.
Definition: blockaction.hh:178
virtual Action * clone(const ActionGroupList &grouplist) const
Clone the Action.
Definition: blockaction.hh:327
Large scale transformations applied to the varnode/op graph.
Definition: action.hh:50
bool operator<(const LoopBody &op2) const
Order loop bodies by depth.
Definition: blockaction.hh:68
Lowest level operation of the p-code language.
Definition: op.hh:58
FlowBlock * getBottom(void) const
Get the ending FlowBlock.
Definition: blockaction.hh:35
Action, Rule, and other associates classes supporting transformations on function data-flow...
Perform final organization of the control-flow structure.
Definition: blockaction.hh:309
virtual Action * clone(const ActionGroupList &grouplist) const
Clone the Action.
Definition: blockaction.hh:312
FlowBlock * getHead(void) const
Return the head FlowBlock of the loop.
Definition: blockaction.hh:55
virtual Action * clone(const ActionGroupList &grouplist) const
Clone the Action.
Definition: blockaction.hh:299
ActionReturnSplit(const string &g)
Constructor.
Definition: blockaction.hh:326
FloatingEdge(FlowBlock *t, FlowBlock *b)
Construct given end points.
Definition: blockaction.hh:33
A control-flow block built out of sub-components.
Definition: block.hh:270
A low-level variable or contiguous set of bytes described by an Address and a size.
Definition: varnode.hh:65
Split the epilog code of the function.
Definition: blockaction.hh:322
A basic block for p-code operations.
Definition: block.hh:363
LoopBody(FlowBlock *h)
Construct with a loop head.
Definition: blockaction.hh:54
Flip conditional control-flow so that preferred comparison operators are used.
Definition: blockaction.hh:269
int4 getChangeCount(void) const
Get number of data-flow changes.
Definition: blockaction.hh:222
Build a code structure from a control-flow graph (BlockGraph).
Definition: blockaction.hh:190
FlowBlock * getExitBlock(void) const
Get the exit FlowBlock or NULL.
Definition: blockaction.hh:58
virtual Action * clone(const ActionGroupList &grouplist) const
Clone the Action.
Definition: blockaction.hh:338
ActionPreferComplement(const string &g)
Constructor.
Definition: blockaction.hh:287
Attempt to normalize symmetric block structures.
Definition: blockaction.hh:285
Look for conditional branch expressions that have been split and rejoin them.
Definition: blockaction.hh:335
ConditionalJoin(Funcdata &fd)
Constructor.
Definition: blockaction.hh:259
A description of the body of a loop.
Definition: blockaction.hh:44
Discover and eliminate split conditions.
Definition: blockaction.hh:232
FlowBlock * getTop(void) const
Get the starting FlowBlock.
Definition: blockaction.hh:34
void addTail(FlowBlock *bl)
Add a tail to the loop.
Definition: blockaction.hh:57
ActionNormalizeBranches(const string &g)
Constructor.
Definition: blockaction.hh:271