My Project
merge.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 __CPUI_MERGE__
17 #define __CPUI_MERGE__
18 
21 
22 #include "op.hh"
23 
29 class HighEdge {
30  friend class Merge;
31  HighVariable *a;
32  HighVariable *b;
33 public:
35  bool operator<(const HighEdge &op2) const { if (a==op2.a) return (b<op2.b); return (a<op2.a); }
36  HighEdge(HighVariable *c,HighVariable *d) { a=c; b=d; }
37 };
38 
44 class BlockVarnode {
45  int4 index;
46  Varnode *vn;
47 public:
48  void set(Varnode *v);
49  bool operator<(const BlockVarnode &op2) const { return (index < op2.index); }
50  Varnode *getVarnode(void) const { return vn; }
51  int4 getIndex(void) const { return index; }
52  static int4 findFront(int4 blocknum,const vector<BlockVarnode> &list);
53 };
54 
55 class Funcdata;
56 
80 class Merge {
81  Funcdata &data;
82  map<HighEdge,bool> highedgemap;
83  vector<PcodeOp *> copyTrims;
84  bool updateHigh(HighVariable *a);
85  void purgeHigh(HighVariable *high);
86  bool blockIntersection(HighVariable *a,HighVariable *b,int4 blk);
87  static bool mergeTestRequired(HighVariable *high_out,HighVariable *high_in);
88  static bool mergeTestAdjacent(HighVariable *high_out,HighVariable *high_in);
89  static bool mergeTestSpeculative(HighVariable *high_out,HighVariable *high_in);
90  static bool mergeTestBasic(Varnode *vn);
91  static void findSingleCopy(HighVariable *high,vector<Varnode *> &singlelist);
92  static bool compareHighByBlock(const HighVariable *a,const HighVariable *b);
93  static bool compareCopyByInVarnode(PcodeOp *op1,PcodeOp *op2);
94  static bool shadowedVarnode(const Varnode *vn);
95  static void findAllIntoCopies(HighVariable *high,vector<PcodeOp *> &copyIns,bool filterTemps);
96  void collectCovering(vector<Varnode *> &vlist,HighVariable *high,PcodeOp *op);
97  bool collectCorrectable(const vector<Varnode *> &vlist,list<PcodeOp *> &oplist,vector<int4> &slotlist,
98  PcodeOp *op);
99  PcodeOp *allocateCopyTrim(Varnode *inVn,Datatype *ct,const Address &addr);
100  void snipReads(Varnode *vn,list<PcodeOp *> &markedop);
101  void snipIndirect(PcodeOp *indop);
102  void eliminateIntersect(Varnode *vn,const vector<BlockVarnode> &blocksort);
103  void unifyAddress(VarnodeLocSet::const_iterator startiter,VarnodeLocSet::const_iterator enditer);
104  void trimOpOutput(PcodeOp *op);
105  void trimOpInput(PcodeOp *op,int4 slot);
106  void mergeRangeMust(VarnodeLocSet::const_iterator startiter,VarnodeLocSet::const_iterator enditer);
107  void mergeOp(PcodeOp *op);
108  void mergeIndirect(PcodeOp *indop);
109  void mergeLinear(vector<HighVariable *> &highvec);
110  bool merge(HighVariable *high1,HighVariable *high2,bool isspeculative);
111  bool checkCopyPair(HighVariable *high,PcodeOp *domOp,PcodeOp *subOp);
112  void buildDominantCopy(HighVariable *high,vector<PcodeOp *> &copy,int4 pos,int4 size);
113  void markRedundantCopies(HighVariable *high,vector<PcodeOp *> &copy,int4 pos,int4 size);
114  void processHighDominantCopy(HighVariable *high);
115  void processHighRedundantCopy(HighVariable *high);
116 public:
117  Merge(Funcdata &fd) : data(fd) {}
118  bool intersection(HighVariable *a,HighVariable *b);
119  bool inflateTest(Varnode *a,HighVariable *high);
120  void inflate(Varnode *a,HighVariable *high);
121  bool mergeTest(HighVariable *high,vector<HighVariable *> &tmplist);
122 
123  void mergeOpcode(OpCode opc);
124  void mergeByDatatype(VarnodeLocSet::const_iterator startiter,VarnodeLocSet::const_iterator enditer);
125  void mergeAddrTied(void);
126  void mergeMarker(void);
127  void mergeAdjacent(void);
128  void mergeMultiEntry(void);
129  bool hideShadows(HighVariable *high);
130  void processCopyTrims(void);
131  void markInternalCopies(void);
132 #ifdef MERGEMULTI_DEBUG
133  void verifyHighCovers(void);
134 #endif
135 };
136 
148 inline bool Merge::compareHighByBlock(const HighVariable *a,const HighVariable *b)
149 
150 {
151  int4 result = a->wholecover.compareTo(b->wholecover);
152  if ( result == 0 ) {
153  Varnode *v1 = a->getInstance( 0 );
154  Varnode *v2 = b->getInstance( 0 );
155 
156  if ( v1->getAddr() == v2->getAddr() ) {
157  PcodeOp *def1 = v1->getDef();
158  PcodeOp *def2 = v2->getDef();
159  if ( def1 == (PcodeOp *) 0 ) {
160  return true;
161  }
162  else if ( def2 == (PcodeOp *) 0 ) {
163  return false;
164  }
165  return (def1->getAddr() < def2->getAddr());
166  }
167  return (v1->getAddr() < v2->getAddr());
168  }
169  return (result < 0);
170 }
171 
172 #endif
The base datatype class for the decompiler.
Definition: type.hh:62
OpCode
The op-code defining a specific p-code operation (PcodeOp)
Definition: opcodes.hh:35
Class for merging low-level Varnodes into high-level HighVariables.
Definition: merge.hh:80
const Address & getAddr(void) const
Get the instruction address associated with this op.
Definition: op.hh:151
bool operator<(const BlockVarnode &op2) const
Comparator.
Definition: merge.hh:49
Container for data structures associated with a single function.
Definition: funcdata.hh:45
HighEdge(HighVariable *c, HighVariable *d)
Constructor.
Definition: merge.hh:36
Varnode * getVarnode(void) const
Get the Varnode represented by this.
Definition: merge.hh:50
int4 getIndex(void) const
Get the Varnode&#39;s defining block index.
Definition: merge.hh:51
int4 compareTo(const Cover &op2) const
Give ordering of this and another Cover.
Definition: cover.cc:221
PcodeOp * getDef(void)
Get the defining PcodeOp of this Varnode.
Definition: varnode.hh:172
Helper class associating a Varnode with the block where it is defined.
Definition: merge.hh:44
Varnode * getInstance(int4 i) const
Get the i-th member Varnode.
Definition: variable.hh:93
Lowest level operation of the p-code language.
Definition: op.hh:58
A low-level machine address for labelling bytes and data.
Definition: address.hh:46
A low-level variable or contiguous set of bytes described by an Address and a size.
Definition: varnode.hh:65
A record for caching a Cover intersection test between two HighVariable objects.
Definition: merge.hh:29
const Address & getAddr(void) const
Get the storage Address.
Definition: varnode.hh:167
A high-level variable modeled as a list of low-level variables, each written once.
Definition: variable.hh:38
bool operator<(const HighEdge &op2) const
Comparator.
Definition: merge.hh:35
The PcodeOp and PcodeOpBank classes.
Merge(Funcdata &fd)
Construct given a specific function.
Definition: merge.hh:117