Ghidra Decompiler Analysis Engine
double.hh
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_DOUBLE__
17 #define __CPUI_DOUBLE__
18 
19 #include "ruleaction.hh"
20 #include "funcdata.hh"
21 
22 class SplitVarnode {
23  Varnode *lo; // Least significant piece of the double precision object
24  Varnode *hi; // Most significant piece of the double precision object
25  Varnode *whole; // A representative of the whole object
26  PcodeOp *defpoint; // Operation at which both -lo- and -hi- are defined
27  BlockBasic *defblock; // Block in which bot -lo- and -hi- are defined
28  uintb val; // Value of a double precision constant
29  int4 wholesize; // Size in bytes of the (virtual) whole
30  bool findWholeSplitToPieces(void);
31  bool findDefinitionPoint(void);
32  bool findWholeBuiltFromPieces(void);
33 public:
34  SplitVarnode(void) {} // For use with inHandHi
35  SplitVarnode(int4 sz,uintb v); // Initialize a double precision constant
36  SplitVarnode(Varnode *l,Varnode *h) { initPartial(l,h); }
37  void initAll(Varnode *w,Varnode *l,Varnode *h);
38  void initPartial(int4 sz,uintb v);
39  void initPartial(Varnode *l,Varnode *h);
40  bool inHandHi(Varnode *h);
41  bool inHandLo(Varnode *l);
42  bool inHandLoNoHi(Varnode *l);
43  bool inHandHiOut(Varnode *h);
44  bool inHandLoOut(Varnode *h);
45  bool isConstant(void) const { return (lo == (Varnode *)0); }
46  bool hasBothPieces(void) const { return ((hi!=(Varnode *)0)&&(lo!=(Varnode *)0)); }
47  int4 getSize(void) const { return wholesize; }
48  Varnode *getLo(void) const { return lo; }
49  Varnode *getHi(void) const { return hi; }
50  Varnode *getWhole(void) const { return whole; }
51  PcodeOp *getDefPoint(void) const { return defpoint; }
52  BlockBasic *getDefBlock(void) const { return defblock; }
53  uintb getValue(void) const { return val; }
54  bool isWholeFeasible(PcodeOp *existop);
55  bool isWholePhiFeasible(FlowBlock *bl);
56  void findCreateWhole(Funcdata &data);
57  void findCreateOutputWhole(Funcdata &data);
58  void createJoinedWhole(Funcdata &data);
59  void buildLoFromWhole(Funcdata &data);
60  void buildHiFromWhole(Funcdata &data);
61  PcodeOp *findEarliestSplitPoint(void);
62  PcodeOp *findOutExist(void);
63  static bool adjacentOffsets(Varnode *vn1,Varnode *vn2,uintb size1);
64  static bool testContiguousLoad(PcodeOp *most,PcodeOp *least,bool allowfree,PcodeOp *&first,PcodeOp *&second,AddrSpace *&spc,int4 &sizeres);
65  static bool isAddrTiedContiguous(Varnode *lo,Varnode *hi,Address &res);
66  static void wholeList(Varnode *w,vector<SplitVarnode> &splitvec);
67  static void findCopies(const SplitVarnode &in,vector<SplitVarnode> &splitvec);
68  static void getTrueFalse(PcodeOp *boolop,bool flip,BlockBasic *&trueout,BlockBasic *&falseout);
69  static bool otherwiseEmpty(PcodeOp *branchop);
70  static bool verifyMultNegOne(PcodeOp *op);
71  static PcodeOp *prepareBinaryOp(SplitVarnode &out,SplitVarnode &in1,SplitVarnode &in2);
72  static void createBinaryOp(Funcdata &data,SplitVarnode &out,SplitVarnode &in1,SplitVarnode &in2,
73  PcodeOp *existop,OpCode opc);
74  static PcodeOp *prepareShiftOp(SplitVarnode &out,SplitVarnode &in);
75  static void createShiftOp(Funcdata &data,SplitVarnode &out,SplitVarnode &in,Varnode *sa,
76  PcodeOp *existop,OpCode opc);
77  static void replaceBoolOp(Funcdata &data,PcodeOp *boolop,SplitVarnode &in1,SplitVarnode &in2,
78  OpCode opc);
79  static bool prepareBoolOp(SplitVarnode &in1,SplitVarnode &in2,PcodeOp *testop);
80  static void createBoolOp(Funcdata &data,PcodeOp *cbranch,SplitVarnode &in1,SplitVarnode &in2,
81  OpCode opc);
82  static PcodeOp *preparePhiOp(SplitVarnode &out,vector<SplitVarnode> &inlist);
83  static void createPhiOp(Funcdata &data,SplitVarnode &out,vector<SplitVarnode> &inlist,
84  PcodeOp *existop);
85  static bool prepareIndirectOp(SplitVarnode &in,PcodeOp *affector);
86  static void replaceIndirectOp(Funcdata &data,SplitVarnode &out,SplitVarnode &in,PcodeOp *affector);
87  static int4 applyRuleIn(SplitVarnode &in,Funcdata &data);
88 };
89 
90 class AddForm {
91  SplitVarnode in;
92  Varnode *hi1,*hi2,*lo1,*lo2;
93  Varnode *reshi,*reslo;
94  PcodeOp *zextop,*loadd,*add2;
95  Varnode *hizext1,*hizext2;
96  int4 slot1;
97  uintb negconst;
98  PcodeOp *existop;
99  SplitVarnode indoub;
100  SplitVarnode outdoub;
101  bool checkForCarry(PcodeOp *op);
102 public:
103  bool verify(Varnode *h,Varnode *l,PcodeOp *op);
104  bool applyRule(SplitVarnode &i,PcodeOp *op,bool workishi,Funcdata &data);
105 };
106 
107 class SubForm {
108  SplitVarnode in;
109  Varnode *hi1,*hi2,*lo1,*lo2;
110  Varnode *reshi,*reslo;
111  PcodeOp *zextop,*lessop,*negop,*loadd,*add2;
112  Varnode *hineg1,*hineg2;
113  Varnode *hizext1,*hizext2;
114  int4 slot1;
115  PcodeOp *existop;
116  SplitVarnode indoub;
117  SplitVarnode outdoub;
118 public:
119  bool verify(Varnode *h,Varnode *l,PcodeOp *op);
120  bool applyRule(SplitVarnode &i,PcodeOp *op,bool workishi,Funcdata &data);
121 };
122 
123 class LogicalForm {
124  SplitVarnode in;
125  PcodeOp *loop,*hiop;
126  Varnode *hi1,*hi2,*lo1,*lo2;
127  PcodeOp *existop;
128  SplitVarnode indoub;
129  SplitVarnode outdoub;
130  int4 findHiMatch(void);
131 public:
132  bool verify(Varnode *h,Varnode *l,PcodeOp *lop);
133  bool applyRule(SplitVarnode &i,PcodeOp *lop,bool workishi,Funcdata &data);
134 };
135 
136 class Equal1Form {
137  SplitVarnode in1;
138  SplitVarnode in2;
139  PcodeOp *loop,*hiop;
140  PcodeOp *hibool,*lobool;
141  Varnode *hi1,*lo1,*hi2,*lo2;
142  int4 hi1slot,lo1slot;
143  bool notequalformhi,notequalformlo;
144  bool setonlow;
145 public:
146  bool applyRule(SplitVarnode &i,PcodeOp *hop,bool workishi,Funcdata &data);
147 };
148 
149 class Equal2Form {
150  SplitVarnode in;
151  Varnode *hi1,*hi2,*lo1,*lo2;
152  PcodeOp *equalop,*orop;
153  PcodeOp *hixor,*loxor;
154  int4 orhislot,xorhislot;
155  SplitVarnode param2;
156  bool checkLoForm(void);
157  bool fillOutFromOr(Funcdata &data);
158  bool replace(Funcdata &data);
159 public:
160  bool applyRule(SplitVarnode &i,PcodeOp *op,bool workishi,Funcdata &data);
161 };
162 
163 class Equal3Form {
164  SplitVarnode in;
165  Varnode *hi,*lo;
166  PcodeOp *andop;
167  PcodeOp *compareop;
168  Varnode *smallc;
169 public:
170  bool verify(Varnode *h,Varnode *l,PcodeOp *aop);
171  bool applyRule(SplitVarnode &i,PcodeOp *op,bool workishi,Funcdata &data);
172 };
173 
175  SplitVarnode in;
176  SplitVarnode in2;
177  BlockBasic *hilessbl,*lolessbl,*hieqbl;
178  BlockBasic *hilesstrue,*hilessfalse;
179  BlockBasic *hieqtrue,*hieqfalse;
180  BlockBasic *lolesstrue,*lolessfalse;
181  PcodeOp *hilessbool,*lolessbool,*hieqbool;
182  PcodeOp *hiless,*hiequal,*loless;
183  Varnode *vnhil1,*vnhil2,*vnhie1,*vnhie2;
184  Varnode *vnlo1,*vnlo2;
185  Varnode *hi,*lo,*hi2,*lo2;
186  int4 hislot,loslot;
187  bool hiflip,equalflip,loflip;
188  bool lolessiszerocomp;
189  bool lolessequalform,hilessequalform,signcompare;
190  bool midlessform,midlessequal,midsigncompare;
191  bool hiconstform,midconstform,loconstform;
192  uintb hival,midval,loval;
193  OpCode finalopc;
194  bool mapBlocksFromLow(BlockBasic *lobl);
195  bool mapOpsFromBlocks(void);
196  bool checkSignedness(void);
197  bool normalizeHi(void);
198  bool normalizeMid(void);
199  bool normalizeLo(void);
200  bool checkBlockForm(void);
201  bool checkOpForm(void);
202  void setOpCode(void);
203  bool setBoolOp(void);
204  bool mapFromLow(PcodeOp *op);
205  bool testReplace(void);
206 public:
207  bool applyRule(SplitVarnode &i,PcodeOp *loop,bool workishi,Funcdata &data);
208 };
209 
211  SplitVarnode in;
212  Varnode *vn,*cvn;
213  int4 inslot;
214  bool signcompare,hilessequalform;
215  SplitVarnode constin;
216 public:
217  bool applyRule(SplitVarnode &i,PcodeOp *op,bool workishi,Funcdata &data);
218 };
219 
220 class ShiftForm {
221  SplitVarnode in;
222  OpCode opc; // Basic operation
223  PcodeOp *loshift,*midshift,*hishift;
224  PcodeOp *orop;
225  Varnode *lo,*hi,*midlo,*midhi;
226  Varnode *salo,*sahi,*samid;
227  Varnode *reslo,*reshi;
228  SplitVarnode out;
229  PcodeOp *existop;
230  bool verifyShiftAmount(void);
231  bool mapLeft(void);
232  bool mapRight(void);
233 public:
234  bool verifyLeft(Varnode *h,Varnode *l,PcodeOp *loop);
235  bool verifyRight(Varnode *h,Varnode *l,PcodeOp *hiop);
236  bool applyRuleLeft(SplitVarnode &i,PcodeOp *loop,bool workishi,Funcdata &data);
237  bool applyRuleRight(SplitVarnode &i,PcodeOp *hiop,bool workishi,Funcdata &data);
238 };
239 
240 class MultForm {
241  SplitVarnode in;
242  PcodeOp *add1,*add2;
243  PcodeOp *subhi,*sublo;
244  PcodeOp *multlo,*multhi1,*multhi2;
245  Varnode *midtmp,*lo1zext,*lo2zext;
246  Varnode *hi1,*lo1,*hi2,*lo2;
247  Varnode *reslo,*reshi;
248  SplitVarnode outdoub;
249  SplitVarnode in2;
250  PcodeOp *existop;
251  bool zextOf(Varnode *big,Varnode *small);
252  bool mapResHi(Varnode *rhi);
253  bool mapResHiSmallConst(Varnode *rhi);
254  bool findLoFromIn(void);
255  bool findLoFromInSmallConst(void);
256  bool verifyLo(void);
257  bool findResLo(void);
258  bool mapFromIn(Varnode *rhi);
259  bool mapFromInSmallConst(Varnode *rhi);
260  bool replace(Funcdata &data);
261 public:
262  bool verify(Varnode *h,Varnode *l,PcodeOp *hop);
263  bool applyRule(SplitVarnode &i,PcodeOp *hop,bool workishi,Funcdata &data);
264 };
265 
266 class PhiForm {
267  SplitVarnode in;
268  SplitVarnode outvn;
269  int4 inslot;
270  Varnode *hibase,*lobase;
271  BlockBasic *blbase;
272  PcodeOp *lophi,*hiphi;
273  PcodeOp *existop;
274 public:
275  bool verify(Varnode *h,Varnode *l,PcodeOp *hphi);
276  bool applyRule(SplitVarnode &i,PcodeOp *hphi,bool workishi,Funcdata &data);
277 };
278 
280  SplitVarnode in;
281  SplitVarnode outvn;
282  Varnode *lo,*hi;
283  Varnode *reslo,*reshi;
284  PcodeOp *affector; // Single op affecting both lo and hi
285  PcodeOp *indhi,*indlo; // Two partial CPUI_INDIRECT ops
286 public:
287  bool verify(Varnode *h,Varnode *l,PcodeOp *ihi);
288  bool applyRule(SplitVarnode &i,PcodeOp *ind,bool workishi,Funcdata &data);
289 };
290 
291 class RuleDoubleIn : public Rule {
292 public:
293  RuleDoubleIn(const string &g) : Rule(g, 0, "doublein") {}
294  virtual Rule *clone(const ActionGroupList &grouplist) const {
295  if (!grouplist.contains(getGroup())) return (Rule *)0;
296  return new RuleDoubleIn(getGroup());
297  }
298  virtual void reset(Funcdata &data);
299  virtual void getOpList(vector<uint4> &oplist) const;
300  virtual int4 applyOp(PcodeOp *op,Funcdata &data);
301 };
302 
303 class RuleDoubleLoad : public Rule {
304 public:
305  RuleDoubleLoad(const string &g) : Rule( g, 0, "doubleload") {}
306  virtual Rule *clone(const ActionGroupList &grouplist) const {
307  if (!grouplist.contains(getGroup())) return (Rule *)0;
308  return new RuleDoubleLoad(getGroup());
309  }
310  virtual void getOpList(vector<uint4> &oplist) const;
311  virtual int4 applyOp(PcodeOp *op,Funcdata &data);
312  static PcodeOp *noWriteConflict(PcodeOp *op1,PcodeOp *op2,AddrSpace *spc);
313 };
314 
315 #endif
SplitVarnode
Definition: double.hh:22
RuleDoubleIn::getOpList
virtual void getOpList(vector< uint4 > &oplist) const
List of op codes this rule operates on.
Definition: double.cc:2872
AddForm
Definition: double.hh:90
AddrSpace
A region where processor data is stored.
Definition: space.hh:73
MultForm
Definition: double.hh:240
FlowBlock
Description of a control-flow block containing PcodeOps.
Definition: block.hh:60
Rule
Class for performing a single transformation on a PcodeOp or Varnode.
Definition: action.hh:194
RuleDoubleLoad
Definition: double.hh:303
ActionGroupList
The list of groups defining a root Action.
Definition: action.hh:29
ShiftForm
Definition: double.hh:220
LogicalForm
Definition: double.hh:123
RuleDoubleLoad::applyOp
virtual int4 applyOp(PcodeOp *op, Funcdata &data)
Attempt to apply this Rule.
Definition: double.cc:2949
BlockBasic
A basic block for p-code operations.
Definition: block.hh:365
RuleDoubleIn::reset
virtual void reset(Funcdata &data)
Reset this Rule.
Definition: double.cc:2866
LessConstForm
Definition: double.hh:210
PcodeOp
Lowest level operation of the p-code language.
Definition: op.hh:58
RuleDoubleLoad::getOpList
virtual void getOpList(vector< uint4 > &oplist) const
List of op codes this rule operates on.
Definition: double.cc:2943
RuleDoubleIn::applyOp
virtual int4 applyOp(PcodeOp *op, Funcdata &data)
Attempt to apply this Rule.
Definition: double.cc:2878
IndirectForm
Definition: double.hh:279
Equal2Form
Definition: double.hh:149
Varnode
A low-level variable or contiguous set of bytes described by an Address and a size.
Definition: varnode.hh:65
RuleDoubleIn::clone
virtual Rule * clone(const ActionGroupList &grouplist) const
Clone the Rule.
Definition: double.hh:294
SubForm
Definition: double.hh:107
RuleDoubleIn
Definition: double.hh:291
funcdata.hh
Utilities for processing data structures associated with a single function.
ActionGroupList::contains
bool contains(const string &nm) const
Check if this ActionGroupList contains a given group.
Definition: action.hh:37
Address
A low-level machine address for labelling bytes and data.
Definition: address.hh:46
Funcdata
Container for data structures associated with a single function.
Definition: funcdata.hh:45
Equal1Form
Definition: double.hh:136
OpCode
OpCode
The op-code defining a specific p-code operation (PcodeOp)
Definition: opcodes.hh:35
Rule::Rule
Rule(const string &g, uint4 fl, const string &nm)
Construct given group, properties name.
Definition: action.cc:620
ruleaction.hh
This is the basic set of transformation Rule objects.
Equal3Form
Definition: double.hh:163
RuleDoubleLoad::clone
virtual Rule * clone(const ActionGroupList &grouplist) const
Clone the Rule.
Definition: double.hh:306
PhiForm
Definition: double.hh:266
LessThreeWay
Definition: double.hh:174