Ghidra Decompiler Analysis Engine
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; }
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 
269 public:
270  ActionStructureTransform(const string &g) : Action(0,"structuretransform",g) {}
271  virtual Action *clone(const ActionGroupList &grouplist) const {
272  if (!grouplist.contains(getGroup())) return (Action *)0;
273  return new ActionStructureTransform(getGroup());
274  }
275  virtual int4 apply(Funcdata &data);
276 };
277 
283 public:
284  ActionNormalizeBranches(const string &g) : Action(0,"normalizebranches",g) {}
285  virtual Action *clone(const ActionGroupList &grouplist) const {
286  if (!grouplist.contains(getGroup())) return (Action *)0;
287  return new ActionNormalizeBranches(getGroup());
288  }
289  virtual int4 apply(Funcdata &data);
290 };
291 
299 public:
300  ActionPreferComplement(const string &g) : Action(0,"prefercomplement",g) {}
301  virtual Action *clone(const ActionGroupList &grouplist) const {
302  if (!grouplist.contains(getGroup())) return (Action *)0;
303  return new ActionPreferComplement(getGroup());
304  }
305  virtual int4 apply(Funcdata &data);
306 };
307 
309 class ActionBlockStructure : public Action {
310 public:
311  ActionBlockStructure(const string &g) : Action(0,"blockstructure",g) {}
312  virtual Action *clone(const ActionGroupList &grouplist) const {
313  if (!grouplist.contains(getGroup())) return (Action *)0;
314  return new ActionBlockStructure(getGroup());
315  }
316  virtual int4 apply(Funcdata &data);
317 };
318 
322 class ActionFinalStructure : public Action {
323 public:
324  ActionFinalStructure(const string &g) : Action(0,"finalstructure",g) {}
325  virtual Action *clone(const ActionGroupList &grouplist) const {
326  if (!grouplist.contains(getGroup())) return (Action *)0;
327  return new ActionFinalStructure(getGroup());
328  }
329  virtual int4 apply(Funcdata &data);
330 };
331 
335 class ActionReturnSplit : public Action {
336  static void gatherReturnGotos(FlowBlock *parent,vector<FlowBlock *> &vec);
337  static bool isSplittable(BlockBasic *b);
338 public:
339  ActionReturnSplit(const string &g) : Action(0,"returnsplit",g) {}
340  virtual Action *clone(const ActionGroupList &grouplist) const {
341  if (!grouplist.contains(getGroup())) return (Action *)0;
342  return new ActionReturnSplit(getGroup());
343  }
344  virtual int4 apply(Funcdata &data);
345 };
346 
348 class ActionNodeJoin : public Action {
349 public:
350  ActionNodeJoin(const string &g) : Action(0,"nodejoin",g) {}
351  virtual Action *clone(const ActionGroupList &grouplist) const {
352  if (!grouplist.contains(getGroup())) return (Action *)0;
353  return new ActionNodeJoin(getGroup());
354  }
355  virtual int4 apply(Funcdata &data);
356 };
357 
358 #endif
LoopBody::getCurrentBounds
FlowBlock * getCurrentBounds(FlowBlock **top, FlowBlock *graph)
Return current loop bounds (head and bottom).
Definition: blockaction.cc:90
Action::Action
Action(uint4 f, const string &nm, const string &g)
Base constructor for an Action.
Definition: action.cc:25
ActionFinalStructure
Perform final organization of the control-flow structure.
Definition: blockaction.hh:322
BlockGraph
A control-flow block built out of sub-components.
Definition: block.hh:271
LoopBody::clearExitMarks
void clearExitMarks(FlowBlock *graph)
Clear the mark on all the exits to this loop.
Definition: blockaction.cc:423
ConditionalJoin::execute
void execute(void)
Execute the merge.
Definition: blockaction.cc:2082
FloatingEdge::getCurrentEdge
FlowBlock * getCurrentEdge(int4 &outedge, FlowBlock *graph)
Get the current form of the edge.
Definition: blockaction.cc:25
TraceDAG::pushBranches
void pushBranches(void)
Push the trace through, removing edges as necessary.
Definition: blockaction.cc:976
FlowBlock
Description of a control-flow block containing PcodeOps.
Definition: block.hh:60
ActionReturnSplit
Split the epilog code of the function.
Definition: blockaction.hh:335
ActionPreferComplement::clone
virtual Action * clone(const ActionGroupList &grouplist) const
Clone the Action.
Definition: blockaction.hh:301
LoopBody::compare_head
static int4 compare_head(LoopBody *a, FlowBlock *looptop)
Compare just the head.
Definition: blockaction.cc:482
ActionReturnSplit::apply
virtual int4 apply(Funcdata &data)
Make a single attempt to apply this Action.
Definition: blockaction.cc:2252
LoopBody::labelContainments
void labelContainments(const vector< FlowBlock * > &body, const vector< LoopBody * > &looporder)
Record any loops that body contains.
Definition: blockaction.cc:320
CollapseStructure::CollapseStructure
CollapseStructure(BlockGraph &g)
Construct given a control-flow graph.
Definition: blockaction.cc:1850
ActionNormalizeBranches::apply
virtual int4 apply(Funcdata &data)
Make a single attempt to apply this Action.
Definition: blockaction.cc:2105
ActionNodeJoin::apply
virtual int4 apply(Funcdata &data)
Make a single attempt to apply this Action.
Definition: blockaction.cc:2314
ActionGroupList
The list of groups defining a root Action.
Definition: action.hh:29
ActionReturnSplit::clone
virtual Action * clone(const ActionGroupList &grouplist) const
Clone the Action.
Definition: blockaction.hh:340
ActionFinalStructure::apply
virtual int4 apply(Funcdata &data)
Make a single attempt to apply this Action.
Definition: blockaction.cc:2174
ActionStructureTransform::clone
virtual Action * clone(const ActionGroupList &grouplist) const
Clone the Action.
Definition: blockaction.hh:271
ActionFinalStructure::clone
virtual Action * clone(const ActionGroupList &grouplist) const
Clone the Action.
Definition: blockaction.hh:325
Action
Large scale transformations applied to the varnode/op graph.
Definition: action.hh:50
LoopBody::labelExitEdges
void labelExitEdges(const vector< FlowBlock * > &body)
Label edges that exit the loop.
Definition: blockaction.cc:263
BlockBasic
A basic block for p-code operations.
Definition: block.hh:365
ActionNormalizeBranches::clone
virtual Action * clone(const ActionGroupList &grouplist) const
Clone the Action.
Definition: blockaction.hh:285
PcodeOp
Lowest level operation of the p-code language.
Definition: op.hh:58
TraceDAG::initialize
void initialize(void)
Create the initial BranchPoint and BlockTrace objects.
Definition: blockaction.cc:960
LoopBody
A description of the body of a loop.
Definition: blockaction.hh:44
LoopBody::extend
void extend(vector< FlowBlock * > &body) const
Extend body (to blocks that never exit)
Definition: blockaction.cc:143
ActionNodeJoin
Look for conditional branch expressions that have been split and rejoin them.
Definition: blockaction.hh:348
CollapseStructure::collapseAll
void collapseAll(void)
Run the whole algorithm.
Definition: blockaction.cc:1857
ActionStructureTransform
Give each control-flow structure an opportunity to make a final transform.
Definition: blockaction.hh:268
ActionBlockStructure::clone
virtual Action * clone(const ActionGroupList &grouplist) const
Clone the Action.
Definition: blockaction.hh:312
Varnode
A low-level variable or contiguous set of bytes described by an Address and a size.
Definition: varnode.hh:65
LoopBody::setExitMarks
void setExitMarks(FlowBlock *graph)
Mark all the exits to this loop.
Definition: blockaction.cc:409
FloatingEdge
Class for holding an edge while the underlying graph is being manipulated.
Definition: blockaction.hh:29
ActionNodeJoin::clone
virtual Action * clone(const ActionGroupList &grouplist) const
Clone the Action.
Definition: blockaction.hh:351
TraceDAG::TraceDAG
TraceDAG(list< FloatingEdge > &lg)
Clear the visitcount field of any FlowBlock we have modified.
Definition: blockaction.cc:944
ActionGroupList::contains
bool contains(const string &nm) const
Check if this ActionGroupList contains a given group.
Definition: action.hh:37
Funcdata
Container for data structures associated with a single function.
Definition: funcdata.hh:45
ConditionalJoin::match
bool match(BlockBasic *b1, BlockBasic *b2)
Test blocks for the merge condition.
Definition: blockaction.cc:2045
ActionBlockStructure
Structure control-flow using standard high-level code constructs.
Definition: blockaction.hh:309
LoopBody::compare_ends
static bool compare_ends(LoopBody *a, LoopBody *b)
Compare the head then tail.
Definition: blockaction.cc:466
LoopBody::emitLikelyEdges
void emitLikelyEdges(list< FloatingEdge > &likely, FlowBlock *graph)
Collect likely unstructured edges.
Definition: blockaction.cc:357
ActionBlockStructure::apply
virtual int4 apply(Funcdata &data)
Make a single attempt to apply this Action.
Definition: blockaction.cc:2157
TraceDAG
Algorithm for selecting unstructured edges based an Directed Acyclic Graphs (DAG)
Definition: blockaction.hh:94
ActionPreferComplement::apply
virtual int4 apply(Funcdata &data)
Make a single attempt to apply this Action.
Definition: blockaction.cc:2128
LoopBody::find
static LoopBody * find(FlowBlock *looptop, const vector< LoopBody * > &looporder)
Find a LoopBody.
Definition: blockaction.cc:1014
LoopBody::findBase
void findBase(vector< FlowBlock * > &body)
Mark the body FlowBlocks of this loop.
Definition: blockaction.cc:112
ConditionalJoin
Discover and eliminate split conditions.
Definition: blockaction.hh:232
CollapseStructure
Build a code structure from a control-flow graph (BlockGraph).
Definition: blockaction.hh:190
LoopBody::findExit
void findExit(const vector< FlowBlock * > &body)
Choose the exit block for this loop.
Definition: blockaction.cc:175
action.hh
Action, Rule, and other associates classes supporting transformations on function data-flow.
ConditionalJoin::clear
void clear(void)
Clear for a new test.
Definition: blockaction.cc:2092
LoopBody::clearMarks
static void clearMarks(vector< FlowBlock * > &body)
Clear the body marks.
Definition: blockaction.cc:1032
LoopBody::mergeIdenticalHeads
static void mergeIdenticalHeads(vector< LoopBody * > &looporder)
Merge loop bodies that share the same head.
Definition: blockaction.cc:439
ActionStructureTransform::apply
virtual int4 apply(Funcdata &data)
Make a single attempt to apply this Action.
Definition: blockaction.cc:2098
LoopBody::orderTails
void orderTails(void)
Find preferred tail.
Definition: blockaction.cc:238
ActionPreferComplement
Attempt to normalize symmetric block structures.
Definition: blockaction.hh:298
ActionNormalizeBranches
Flip conditional control-flow so that preferred comparison operators are used.
Definition: blockaction.hh:282
TraceDAG::~TraceDAG
~TraceDAG(void)
Destructor.
Definition: blockaction.cc:951