Ghidra Decompiler Analysis Engine
unify.hh
1 /* ###
2  * IP: GHIDRA
3  * REVIEWED: YES
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 #ifndef __CPUI_UNIFY__
18 #define __CPUI_UNIFY__
19 
20 #include "funcdata.hh"
21 
22 class UnifyCPrinter;
23 
25 public:
26  enum {
27  op_type, var_type, const_type, block_type
28  };
29 private:
30  uint4 type;
31  union {
32  PcodeOp *op;
33  Varnode *vn;
34  uintb *cn;
35  BlockBasic *bl;
36  } storespot;
37 public:
38  UnifyDatatype(void) { type = op_type; }
39  UnifyDatatype(uint4 tp);
40  UnifyDatatype(const UnifyDatatype &op2);
41  UnifyDatatype &operator=(const UnifyDatatype &op2);
42  ~UnifyDatatype(void);
43  uint4 getType(void) const { return type; }
44  void setOp(PcodeOp *o) { storespot.op = o; }
45  PcodeOp *getOp(void) const { return storespot.op; }
46  void setVarnode(Varnode *v) { storespot.vn = v; }
47  Varnode *getVarnode(void) const { return storespot.vn; }
48  void setBlock(BlockBasic *b) { storespot.bl = b; }
49  BlockBasic *getBlock(void) const { return storespot.bl; }
50  void setConstant(uintb val);
51  uintb getConstant(void) const { return *storespot.cn; }
52  void printVarDecl(ostream &s,int4 id,const UnifyCPrinter &cprinter) const;
53  string getBaseName(void) const;
54 };
55 
56 class UnifyState;
57 
58 class RHSConstant { // A construction that results in a constant on the right-hand side of an expression
59 public:
60  virtual ~RHSConstant(void) {}
61  virtual RHSConstant *clone(void)=0;
62  virtual uintb getConstant(UnifyState &state) const=0;
63  virtual void writeExpression(ostream &s,UnifyCPrinter &printstate) const=0;
64 };
65 
66 class ConstantNamed : public RHSConstant {
67  int4 constindex;
68 public:
69  ConstantNamed(int4 id) { constindex = id; }
70  int4 getId(void) const { return constindex; }
71  virtual RHSConstant *clone(void) { return new ConstantNamed(constindex); }
72  virtual uintb getConstant(UnifyState &state) const;
73  virtual void writeExpression(ostream &s,UnifyCPrinter &printstate) const;
74 };
75 
76 class ConstantAbsolute : public RHSConstant {
77  uintb val; // The absolute value
78 public:
79  ConstantAbsolute(uintb v) { val = v; }
80  uintb getVal(void) const { return val; }
81  virtual RHSConstant *clone(void) { return new ConstantAbsolute(val); }
82  virtual uintb getConstant(UnifyState &state) const;
83  virtual void writeExpression(ostream &s,UnifyCPrinter &printstate) const;
84 };
85 
86 class ConstantNZMask : public RHSConstant { // A varnode's non-zero mask
87  int4 varindex;
88 public:
89  ConstantNZMask(int4 ind) { varindex = ind; }
90  virtual RHSConstant *clone(void) { return new ConstantNZMask(varindex); }
91  virtual uintb getConstant(UnifyState &state) const;
92  virtual void writeExpression(ostream &s,UnifyCPrinter &printstate) const;
93 };
94 
95 class ConstantConsumed : public RHSConstant { // A varnode's consume mask
96  int4 varindex;
97 public:
98  ConstantConsumed(int4 ind) { varindex = ind; }
99  virtual RHSConstant *clone(void) { return new ConstantConsumed(varindex); }
100  virtual uintb getConstant(UnifyState &state) const;
101  virtual void writeExpression(ostream &s,UnifyCPrinter &printstate) const;
102 };
103 
104 class ConstantOffset : public RHSConstant { // A varnode's offset
105  int4 varindex;
106 public:
107  ConstantOffset(int4 ind) { varindex = ind; }
108  virtual RHSConstant *clone(void) { return new ConstantOffset(varindex); }
109  virtual uintb getConstant(UnifyState &state) const;
110  virtual void writeExpression(ostream &s,UnifyCPrinter &printstate) const;
111 };
112 
113 class ConstantIsConstant : public RHSConstant { // TRUE if the varnode is constant
114  int4 varindex;
115 public:
116  ConstantIsConstant(int4 ind) { varindex = ind; }
117  virtual RHSConstant *clone(void) { return new ConstantIsConstant(varindex); }
118  virtual uintb getConstant(UnifyState &state) const;
119  virtual void writeExpression(ostream &s,UnifyCPrinter &printstate) const;
120 };
121 
122 class ConstantHeritageKnown : public RHSConstant { // A varnode's consume mask
123  int4 varindex;
124 public:
125  ConstantHeritageKnown(int4 ind) { varindex = ind; }
126  virtual RHSConstant *clone(void) { return new ConstantHeritageKnown(varindex); }
127  virtual uintb getConstant(UnifyState &state) const;
128  virtual void writeExpression(ostream &s,UnifyCPrinter &printstate) const;
129 };
130 
131 class ConstantVarnodeSize : public RHSConstant { // A varnode's size as an actual constant
132  int4 varindex;
133 public:
134  ConstantVarnodeSize(int4 ind) { varindex = ind; }
135  virtual RHSConstant *clone(void) { return new ConstantVarnodeSize(varindex); }
136  virtual uintb getConstant(UnifyState &state) const;
137  virtual void writeExpression(ostream &s,UnifyCPrinter &printstate) const;
138 };
139 
141  RHSConstant *expr1,*expr2;
142  OpCode opc;
143 public:
144  ConstantExpression(RHSConstant *e1,RHSConstant *e2,OpCode oc) { expr1 = e1; expr2 = e2; opc = oc; }
145  virtual ~ConstantExpression(void);
146  virtual RHSConstant *clone(void);
147  virtual uintb getConstant(UnifyState &state) const;
148  virtual void writeExpression(ostream &s,UnifyCPrinter &printstate) const;
149 };
150 
152 protected:
153  int4 uniqid;
154 public:
155  TraverseConstraint(int4 i) { uniqid = i; }
156  virtual ~TraverseConstraint(void) {}
157  // int4 getId(void) const { return uniqid; }
158 };
159 
161  bool onestep; // true if first step has occurred
162  list<PcodeOp *>::const_iterator iter; // Different forward branches we could traverse
163  list<PcodeOp *>::const_iterator enditer;
164 public:
166  PcodeOp *getCurrentOp(void) const { return *iter; }
167  void initialize(Varnode *vn) { onestep = false; iter = vn->beginDescend(); enditer = vn->endDescend(); }
168  bool step(void) {
169  if (onestep)
170  ++iter;
171  else
172  onestep = true;
173  return (iter!=enditer); }
174 };
175 
177  int4 state;
178  int4 endstate;
179 public:
180  TraverseCountState(int4 i) : TraverseConstraint(i) {}
181  int4 getState(void) const { return state; }
182  void initialize(int4 end) { state = -1; endstate = end; }
183  bool step(void) { ++state; return (state != endstate); }
184 };
185 
187  vector<TraverseConstraint *> traverselist;
188  int4 currentconstraint;
189  int4 state;
190 public:
191  TraverseGroupState(int4 i) : TraverseConstraint(i) {}
192  void addTraverse(TraverseConstraint *tc) { traverselist.push_back(tc); }
193  TraverseConstraint *getSubTraverse(int4 slot) const { return traverselist[slot]; }
194  int4 getCurrentIndex(void) const { return currentconstraint; }
195  void setCurrentIndex(int4 val) { currentconstraint = val; }
196  int4 getState(void) const { return state; }
197  void setState(int4 val) { state = val; }
198 };
199 
201  friend class ConstraintGroup;
202 protected:
203  int4 uniqid; // Unique identifier for constraint for retrieving state
204  int4 maxnum;
205  UnifyConstraint *copyid(const UnifyConstraint *op) { uniqid = op->uniqid; maxnum = op->maxnum; return this; }
206 public:
207  virtual ~UnifyConstraint(void) {}
208  int4 getId(void) const { return uniqid; }
209  int4 getMaxNum(void) { return maxnum; }
210  virtual UnifyConstraint *clone(void) const=0;
211  virtual void initialize(UnifyState &state);
212  virtual bool step(UnifyState &state)=0;
213  virtual void buildTraverseState(UnifyState &state);
214  virtual void setId(int4 &id) { uniqid = id; id += 1; }
215  virtual void collectTypes(vector<UnifyDatatype> &typelist) const {}
216  virtual int4 getBaseIndex(void) const { return -1; }
217  virtual void print(ostream &s,UnifyCPrinter &printstate) const=0;
218  virtual bool isDummy(void) const { return false; }
219  virtual void removeDummy(void) {}
220 };
221 
223  int4 opindex;
224 public:
225  DummyOpConstraint(int4 ind) { maxnum = opindex = ind; }
226  virtual UnifyConstraint *clone(void) const { return (new DummyOpConstraint(opindex))->copyid(this); }
227  virtual bool step(UnifyState &state) { return true; }
228  virtual void collectTypes(vector<UnifyDatatype> &typelist) const { typelist[opindex] = UnifyDatatype(UnifyDatatype::op_type); }
229  virtual int4 getBaseIndex(void) const { return opindex; }
230  virtual void print(ostream &s,UnifyCPrinter &printstate) const {}
231  virtual bool isDummy(void) const { return true; }
232 };
233 
235  int4 varindex;
236 public:
237  DummyVarnodeConstraint(int4 ind) { maxnum = varindex = ind; }
238  virtual UnifyConstraint *clone(void) const { return (new DummyVarnodeConstraint(varindex))->copyid(this); }
239  virtual bool step(UnifyState &state) { return true; }
240  virtual void collectTypes(vector<UnifyDatatype> &typelist) const { typelist[varindex] = UnifyDatatype(UnifyDatatype::var_type); }
241  virtual int4 getBaseIndex(void) const { return varindex; }
242  virtual void print(ostream &s,UnifyCPrinter &printstate) const {}
243  virtual bool isDummy(void) const { return true; }
244 };
245 
247  int4 constindex;
248 public:
249  DummyConstConstraint(int4 ind) { maxnum = constindex = ind; }
250  virtual UnifyConstraint *clone(void) const { return (new DummyConstConstraint(constindex))->copyid(this); }
251  virtual bool step(UnifyState &state) { return true; }
252  virtual void collectTypes(vector<UnifyDatatype> &typelist) const { typelist[constindex] = UnifyDatatype(UnifyDatatype::const_type); }
253  virtual int4 getBaseIndex(void) const { return constindex; }
254  virtual void print(ostream &s,UnifyCPrinter &printstate) const {}
255  virtual bool isDummy(void) const { return true; }
256 };
257 
258 class ConstraintBoolean : public UnifyConstraint { // Constant expression must evaluate to true (or false)
259  bool istrue;
260  RHSConstant *expr;
261 public:
262  ConstraintBoolean(bool ist,RHSConstant *ex) { istrue = ist; expr = ex; maxnum = -1; }
263  virtual ~ConstraintBoolean(void) { delete expr; }
264  virtual UnifyConstraint *clone(void) const { return (new ConstraintBoolean(istrue,expr->clone()))->copyid(this); }
265  virtual bool step(UnifyState &state);
266  virtual void print(ostream &s,UnifyCPrinter &printstate) const;
267 };
268 
269 class ConstraintVarConst : public UnifyConstraint { // Create a new varnode constant
270  int4 varindex;
271  RHSConstant *expr;
272  RHSConstant *exprsz;
273 public:
274  ConstraintVarConst(int4 ind,RHSConstant *ex,RHSConstant *sz) { varindex = ind; maxnum = ind; expr = ex; exprsz = sz; }
275  virtual ~ConstraintVarConst(void);
276  virtual UnifyConstraint *clone(void) const;
277  virtual bool step(UnifyState &state);
278  virtual void collectTypes(vector<UnifyDatatype> &typelist) const;
279  virtual int4 getBaseIndex(void) const { return varindex; }
280  virtual void print(ostream &s,UnifyCPrinter &printstate) const;
281 };
282 
284  int4 constindex;
285  RHSConstant *expr;
286 public:
287  ConstraintNamedExpression(int4 ind,RHSConstant *ex) { constindex = ind, expr=ex; maxnum = constindex; }
288  virtual ~ConstraintNamedExpression(void) { delete expr; }
289  virtual UnifyConstraint *clone(void) const { return (new ConstraintNamedExpression(constindex,expr->clone()))->copyid(this); }
290  virtual bool step(UnifyState &state);
291  virtual void collectTypes(vector<UnifyDatatype> &typelist) const;
292  virtual int4 getBaseIndex(void) const { return constindex; }
293  virtual void print(ostream &s,UnifyCPrinter &printstate) const;
294 };
295 
297  int4 oldopindex;
298  int4 newopindex;
299 public:
300  ConstraintOpCopy(int4 oldind,int4 newind) { oldopindex = oldind; newopindex = newind; maxnum = (oldopindex > newopindex) ? oldopindex : newopindex; }
301  virtual UnifyConstraint *clone(void) const { return (new ConstraintOpCopy(oldopindex,newopindex))->copyid(this); }
302  virtual bool step(UnifyState &state);
303  virtual void collectTypes(vector<UnifyDatatype> &typelist) const;
304  virtual int4 getBaseIndex(void) const { return oldopindex; }
305  virtual void print(ostream &s,UnifyCPrinter &printstate) const;
306 };
307 
309  int4 opindex;
310  vector<OpCode> opcodes; // Which opcodes match
311 public:
312  ConstraintOpcode(int4 ind,const vector<OpCode> &o) { maxnum = opindex = ind; opcodes = o; }
313  const vector<OpCode> &getOpCodes(void) const { return opcodes; }
314  virtual UnifyConstraint *clone(void) const { return (new ConstraintOpcode(opindex,opcodes))->copyid(this); }
315  virtual bool step(UnifyState &state);
316  virtual void collectTypes(vector<UnifyDatatype> &typelist) const;
317  virtual int4 getBaseIndex(void) const { return opindex; }
318  virtual void print(ostream &s,UnifyCPrinter &printstate) const;
319 };
320 
322  int4 op1index;
323  int4 op2index;
324  bool istrue;
325 public:
326  ConstraintOpCompare(int4 op1ind,int4 op2ind,bool val) { op1index = op1ind; op2index = op2ind; istrue = val; maxnum = (op1index > op2index) ? op1index : op2index; }
327  virtual UnifyConstraint *clone(void) const { return (new ConstraintOpCompare(op1index,op2index,istrue))->copyid(this); }
328  virtual bool step(UnifyState &state);
329  virtual void collectTypes(vector<UnifyDatatype> &typelist) const;
330  virtual int4 getBaseIndex(void) const { return op1index; }
331  virtual void print(ostream &s,UnifyCPrinter &printstate) const;
332 };
333 
334 class ConstraintOpInput : public UnifyConstraint { // Move from op to one of its input varnodes
335  int4 opindex; // Which op
336  int4 varnodeindex; // Which input varnode
337  int4 slot; // Which slot to take
338 public:
339  ConstraintOpInput(int4 oind,int4 vind,int4 sl) { opindex = oind; varnodeindex = vind; slot = sl; maxnum = (opindex > varnodeindex) ? opindex : varnodeindex; }
340  virtual UnifyConstraint *clone(void) const { return (new ConstraintOpInput(opindex,varnodeindex,slot))->copyid(this); }
341  virtual bool step(UnifyState &state);
342  virtual void collectTypes(vector<UnifyDatatype> &typelist) const;
343  virtual int4 getBaseIndex(void) const { return varnodeindex; }
344  virtual void print(ostream &s,UnifyCPrinter &printstate) const;
345 };
346 
347 class ConstraintOpInputAny : public UnifyConstraint { // Move from op to ANY of its input varnodes
348  int4 opindex; // Which op
349  int4 varnodeindex; // What to label input varnode
350 public:
351  ConstraintOpInputAny(int4 oind,int4 vind) { opindex = oind; varnodeindex = vind; maxnum = (opindex > varnodeindex) ? opindex : varnodeindex; }
352  virtual UnifyConstraint *clone(void) const { return (new ConstraintOpInputAny(opindex,varnodeindex))->copyid(this); }
353  virtual void initialize(UnifyState &state);
354  virtual bool step(UnifyState &state);
355  virtual void collectTypes(vector<UnifyDatatype> &typelist) const;
356  virtual int4 getBaseIndex(void) const { return varnodeindex; }
357  virtual void print(ostream &s,UnifyCPrinter &printstate) const;
358 };
359 
360 class ConstraintOpOutput : public UnifyConstraint { // Move from op to its output varnode
361  int4 opindex; // Which op
362  int4 varnodeindex; // Label of output varnode
363 public:
364  ConstraintOpOutput(int4 oind,int4 vind) { opindex = oind; varnodeindex = vind; maxnum = (opindex > varnodeindex) ? opindex : varnodeindex; }
365  virtual UnifyConstraint *clone(void) const { return (new ConstraintOpOutput(opindex,varnodeindex))->copyid(this); }
366  virtual bool step(UnifyState &state);
367  virtual void collectTypes(vector<UnifyDatatype> &typelist) const;
368  virtual int4 getBaseIndex(void) const { return varnodeindex; }
369  virtual void print(ostream &s,UnifyCPrinter &printstate) const;
370 };
371 
373  int4 opindex; // Which opcode
374  int4 slot; // Which slot to examine for constant
375  uintb val; // What value parameter must match
376 public:
377  ConstraintParamConstVal(int4 oind,int4 sl,uintb v) { maxnum = opindex = oind; slot=sl; val = v; }
378  virtual UnifyConstraint *clone(void) const { return (new ConstraintParamConstVal(opindex,slot,val))->copyid(this); }
379  virtual bool step(UnifyState &state);
380  virtual void collectTypes(vector<UnifyDatatype> &typelist) const;
381  virtual void print(ostream &s,UnifyCPrinter &printstate) const;
382 };
383 
385  int4 opindex; // Which opcode
386  int4 slot; // Which slot to examine for constant
387  int4 constindex; // Which varnode is the constant
388 public:
389  ConstraintParamConst(int4 oind,int4 sl,int4 cind) { opindex = oind; slot=sl; constindex = cind; maxnum = (opindex > constindex) ? opindex : constindex; }
390  virtual UnifyConstraint *clone(void) const { return (new ConstraintParamConst(opindex,slot,constindex))->copyid(this); }
391  virtual bool step(UnifyState &state);
392  virtual void collectTypes(vector<UnifyDatatype> &typelist) const;
393  virtual int4 getBaseIndex(void) const { return constindex; }
394  virtual void print(ostream &s,UnifyCPrinter &printstate) const;
395 };
396 
398  int4 oldvarindex;
399  int4 newvarindex;
400 public:
401  ConstraintVarnodeCopy(int4 oldind,int4 newind) { oldvarindex = oldind; newvarindex = newind; maxnum = (oldvarindex > newvarindex) ? oldvarindex : newvarindex; }
402  virtual UnifyConstraint *clone(void) const { return (new ConstraintVarnodeCopy(oldvarindex,newvarindex))->copyid(this); }
403  virtual bool step(UnifyState &state);
404  virtual void collectTypes(vector<UnifyDatatype> &typelist) const;
405  virtual int4 getBaseIndex(void) const { return oldvarindex; }
406  virtual void print(ostream &s,UnifyCPrinter &printstate) const;
407 };
408 
410  int4 var1index;
411  int4 var2index;
412  bool istrue;
413 public:
414  ConstraintVarCompare(int4 var1ind,int4 var2ind,bool val) { var1index = var1ind; var2index = var2ind; istrue = val; maxnum = (var1index > var2index) ? var1index : var2index; }
415  virtual UnifyConstraint *clone(void) const { return (new ConstraintVarCompare(var1index,var2index,istrue))->copyid(this); }
416  virtual bool step(UnifyState &state);
417  virtual void collectTypes(vector<UnifyDatatype> &typelist) const;
418  virtual int4 getBaseIndex(void) const { return var1index; }
419  virtual void print(ostream &s,UnifyCPrinter &printstate) const;
420 };
421 
423  int4 opindex; // Where to store defining op
424  int4 varindex; // Which varnode to examine for def
425 public:
426  ConstraintDef(int4 oind,int4 vind) { opindex = oind; varindex = vind; maxnum = (opindex > varindex) ? opindex : varindex; }
427  virtual UnifyConstraint *clone(void) const { return (new ConstraintDef(opindex,varindex))->copyid(this); }
428  virtual bool step(UnifyState &state);
429  virtual void collectTypes(vector<UnifyDatatype> &typelist) const;
430  virtual int4 getBaseIndex(void) const { return opindex; }
431  virtual void print(ostream &s,UnifyCPrinter &printstate) const;
432 };
433 
435  int4 opindex;
436  int4 varindex;
437 public:
438  ConstraintDescend(int4 oind,int4 vind) { opindex = oind; varindex = vind; maxnum = (opindex > varindex) ? opindex : varindex; }
439  virtual UnifyConstraint *clone(void) const { return (new ConstraintDescend(opindex,varindex))->copyid(this); }
440  virtual void buildTraverseState(UnifyState &state);
441  virtual void initialize(UnifyState &state);
442  virtual bool step(UnifyState &state);
443  virtual void collectTypes(vector<UnifyDatatype> &typelist) const;
444  virtual int4 getBaseIndex(void) const { return opindex; }
445  virtual void print(ostream &s,UnifyCPrinter &printstate) const;
446 };
447 
449  int4 opindex;
450  int4 varindex;
451 public:
452  ConstraintLoneDescend(int4 oind,int4 vind) { opindex = oind; varindex = vind; maxnum = (opindex > varindex) ? opindex : varindex; }
453  virtual UnifyConstraint *clone(void) const { return (new ConstraintLoneDescend(opindex,varindex))->copyid(this); }
454  virtual bool step(UnifyState &state);
455  virtual void collectTypes(vector<UnifyDatatype> &typelist) const;
456  virtual int4 getBaseIndex(void) const { return opindex; }
457  virtual void print(ostream &s,UnifyCPrinter &printstate) const;
458 };
459 
461  int4 opindex; // For a particular binary op
462  int4 varindex_in; // Given one of its input varnodes
463  int4 varindex_out; // Label the other input to op
464 public:
465  ConstraintOtherInput(int4 oind,int4 v_in,int4 v_out) { maxnum = opindex = oind; varindex_in = v_in; varindex_out = v_out;
466  if (varindex_in > maxnum) maxnum = varindex_in; if (varindex_out > maxnum) maxnum = varindex_out; }
467  virtual UnifyConstraint *clone(void) const { return (new ConstraintOtherInput(opindex,varindex_in,varindex_out))->copyid(this); }
468  virtual int4 getBaseIndex(void) const { return varindex_out; }
469  virtual bool step(UnifyState &state);
470  virtual void collectTypes(vector<UnifyDatatype> &typelist) const;
471  virtual void print(ostream &s,UnifyCPrinter &printstate) const;
472 };
473 
475  int4 const1index; // Compare two constants resulting in a boolean
476  int4 const2index;
477  OpCode opc;
478 public:
479  ConstraintConstCompare(int4 c1ind,int4 c2ind,OpCode oc) { const1index = c1ind; const2index = c2ind; opc = oc;
480  maxnum = (const1index > const2index) ? const1index : const2index; }
481  virtual UnifyConstraint *clone(void) const { return (new ConstraintConstCompare(const1index,const2index,opc))->copyid(this); }
482  virtual bool step(UnifyState &state);
483  virtual void collectTypes(vector<UnifyDatatype> &typelist) const;
484  virtual int4 getBaseIndex(void) const { return const1index; }
485  virtual void print(ostream &s,UnifyCPrinter &printstate) const;
486 };
487 
488 // For a ConstraintGroup, the list of subconstraints must all match for the whole constraint to match.
489 // Constraints are tested first to last, i.e. testing for constraint n can assume that 1 thru n-1 match.
491 protected:
492  vector<UnifyConstraint *> constraintlist;
493 public:
494  ConstraintGroup(void);
495  virtual ~ConstraintGroup(void);
496  UnifyConstraint *getConstraint(int4 slot) const { return constraintlist[slot]; }
497  void addConstraint(UnifyConstraint *a);
498  int4 numConstraints(void) const { return constraintlist.size(); }
499  void deleteConstraint(int4 slot);
500  void mergeIn(ConstraintGroup *b);
501  virtual UnifyConstraint *clone(void) const;
502  virtual void initialize(UnifyState &state);
503  virtual bool step(UnifyState &state);
504  virtual void collectTypes(vector<UnifyDatatype> &typelist) const;
505  virtual void buildTraverseState(UnifyState &state);
506  virtual void setId(int4 &id);
507  virtual int4 getBaseIndex(void) const { return constraintlist.back()->getBaseIndex(); }
508  virtual void print(ostream &s,UnifyCPrinter &printstate) const;
509  virtual void removeDummy(void);
510 };
511 
512 // For a ConstraintOr, exactly one subconstraint needs to be true, for the whole constraint to match
513 // The constraints are tested sequentially, but there can be no dependency between subconstraints
515 public:
516  virtual UnifyConstraint *clone(void) const;
517  virtual void initialize(UnifyState &state);
518  virtual bool step(UnifyState &state);
519  virtual void buildTraverseState(UnifyState &state);
520  virtual int4 getBaseIndex(void) const { return -1; } // Does not have a base
521  virtual void print(ostream &s,UnifyCPrinter &printstate) const;
522 };
523 
524 // Action constraints, these must always step exactly once (returning true), and do their action
525 
527  int4 newopindex;
528  int4 oldopindex;
529  bool insertafter; // true if inserted AFTER oldop
530  OpCode opc; // new opcode
531  int4 numparams;
532 public:
533  ConstraintNewOp(int4 newind,int4 oldind,OpCode oc,bool iafter,int4 num);
534  virtual UnifyConstraint *clone(void) const { return (new ConstraintNewOp(newopindex,oldopindex,opc,insertafter,numparams))->copyid(this); }
535  virtual int4 getBaseIndex(void) const { return newopindex; }
536  virtual bool step(UnifyState &state);
537  virtual void collectTypes(vector<UnifyDatatype> &typelist) const;
538  virtual void print(ostream &s,UnifyCPrinter &printstate) const;
539 };
540 
542  int4 opindex;
543  int4 newvarindex;
544  int4 sizevarindex; // Negative is specific size, Positive is varnode index (for size)
545 public:
546  ConstraintNewUniqueOut(int4 oind,int4 newvarind,int4 sizeind);
547  virtual UnifyConstraint *clone(void) const { return (new ConstraintNewUniqueOut(opindex,newvarindex,sizevarindex))->copyid(this); }
548  virtual int4 getBaseIndex(void) const { return newvarindex; }
549  virtual bool step(UnifyState &state);
550  virtual void collectTypes(vector<UnifyDatatype> &typelist) const;
551  virtual void print(ostream &s,UnifyCPrinter &printstate) const;
552 };
553 
555  int4 opindex;
556  RHSConstant *slot;
557  int4 varindex;
558 public:
559  ConstraintSetInput(int4 oind,RHSConstant *sl,int4 varind) { opindex = oind; slot=sl; varindex = varind; maxnum = (opindex > varindex) ? opindex : varindex; }
560  virtual ~ConstraintSetInput(void) { delete slot; }
561  virtual UnifyConstraint *clone(void) const { return (new ConstraintSetInput(opindex,slot->clone(),varindex))->copyid(this); }
562  virtual int4 getBaseIndex(void) const { return varindex; }
563  virtual bool step(UnifyState &state);
564  virtual void collectTypes(vector<UnifyDatatype> &typelist) const;
565  virtual void print(ostream &s,UnifyCPrinter &printstate) const;
566 };
567 
569  int4 opindex;
570  RHSConstant *slot;
571  RHSConstant *val;
572  RHSConstant *exprsz;
573 public:
574  ConstraintSetInputConstVal(int4 oind,RHSConstant *sl,RHSConstant *v,RHSConstant *sz) { opindex=oind; slot=sl; val=v; exprsz = sz; maxnum = opindex; }
575  virtual ~ConstraintSetInputConstVal(void);
576  virtual UnifyConstraint *clone(void) const;
577  virtual bool step(UnifyState &state);
578  virtual void collectTypes(vector<UnifyDatatype> &typelist) const;
579  virtual void print(ostream &s,UnifyCPrinter &printstate) const;
580 };
581 
583  int4 opindex;
584  RHSConstant *slot;
585 public:
586  ConstraintRemoveInput(int4 oind,RHSConstant *sl) { opindex = oind; slot = sl; maxnum = opindex; }
587  virtual ~ConstraintRemoveInput(void) { delete slot; }
588  virtual UnifyConstraint *clone(void) const { return (new ConstraintRemoveInput(opindex,slot->clone()))->copyid(this); }
589  virtual int4 getBaseIndex(void) const { return opindex; }
590  virtual bool step(UnifyState &state);
591  virtual void collectTypes(vector<UnifyDatatype> &typelist) const;
592  virtual void print(ostream &s,UnifyCPrinter &printstate) const;
593 };
594 
596  int4 opindex;
597  OpCode opc;
598 public:
599  ConstraintSetOpcode(int4 oind,OpCode oc) { opindex = oind; opc = oc; maxnum = opindex; }
600  virtual UnifyConstraint *clone(void) const { return (new ConstraintSetOpcode(opindex,opc))->copyid(this); }
601  virtual int4 getBaseIndex(void) const { return opindex; }
602  virtual bool step(UnifyState &state);
603  virtual void collectTypes(vector<UnifyDatatype> &typelist) const;
604  virtual void print(ostream &s,UnifyCPrinter &printstate) const;
605 };
606 
607 class UnifyState {
608  ConstraintGroup *container; // containing unifyer
609  vector<UnifyDatatype> storemap;
610  vector<TraverseConstraint *> traverselist;
611  Funcdata *fd;
612 public:
614  ~UnifyState(void);
615  int4 numTraverse(void) const { return traverselist.size(); }
616  void registerTraverseConstraint(TraverseConstraint *t) { traverselist.push_back(t); }
617  UnifyDatatype &data(int4 slot) { return storemap[slot]; }
618  TraverseConstraint *getTraverse(int4 slot) const { return traverselist[slot]; }
619  Funcdata *getFunction(void) const { return fd; }
620  OpBehavior *getBehavior(OpCode opc);
621  void setFunction(Funcdata *f) { fd = f; }
622  void initialize(int4 id,Varnode *vn);
623  void initialize(int4 id,PcodeOp *op);
624 };
625 
627  vector<UnifyDatatype> storemap;
628  vector<string> namemap;
629  int4 depth;
630  int4 printingtype; // 0 = standard rule
631  string classname; // Name of the printed class
632  int4 opparam;
633  vector<OpCode> opcodelist; // List of opcodes that are recognized by rule
634  void initializeBase(ConstraintGroup *g);
635  void printGetOpList(ostream &s);
636  void printRuleHeader(ostream &s);
637  ConstraintGroup *grp;
638 public:
639  UnifyCPrinter(void) { grp = (ConstraintGroup *)0; opparam = -1; printingtype=0; }
640  int4 getDepth(void) const { return depth; }
641  void incDepth(void) { depth += 1; }
642  void decDepth(void) { depth -= 1; }
643  void printIndent(ostream &s) const { for(int4 i=0;i<depth+1;++i) s << " "; }
644  void printAbort(ostream &s);
645  void popDepth(ostream &s,int4 newdepth);
646  const string &getName(int4 id) const { return namemap[id]; }
647  void initializeRuleAction(ConstraintGroup *g,int4 opparam,const vector<OpCode> &olist);
648  void initializeBasic(ConstraintGroup *g);
649  void setClassName(const string &nm) { classname = nm; }
650  void addNames(const map<string,int4> &nmmap);
651  void printVarDecls(ostream &s) const;
652  void print(ostream &s);
653 
654 };
655 
656 // Rule language
657 // Identifiers are strict C identifiers that start with either:
658 // 'o' for a pcode op
659 // 'v' for a varnode
660 // '#' for a constant
661 // 'b' for a basic block
662 //
663 // constraints
664 // oname ( "opname" ) constrain "oname" to a given opcode
665 // oname <-(1) vname define varnode "vname" as input 1 of "oname"
666 // oname <-(1) #45 make sure input 1 to "oname" is the constant value 45
667 // oname <-(1) #name define '#name' as the constant input 1 to "oname"
668 // oname -> vname define "vname" as the output varnode of op "oname"
669 // vname <- oname define op "oname" is the op which writes "vname"
670 // vname -> oname define op "oname" as (one of) ops that reads "vname"
671 // vname ->! oname define op "oname" as the lone ops that reads "vname"
672 // oname <- vname != vname1 define "vname" as other input to binary op "oname" besides "vname1"
673 
674 // vname1( == vname2) verify that vname1 and vname2 are the same varnode
675 // vname1( != vname2) verify that vname1 and vname2 are not the same varnode
676 // oname1( == oname2) verify that ops are the same
677 // vname1 -> vname2 define vname2 as a copy of vname1
678 // oname <- vname vname is (one of) the inputs to oname
679 
680 // statements end with ;
681 // Group construct
682 // ( statement
683 // statement ...
684 // }
685 // OR construct
686 // [ statement |
687 // statement ...
688 // ]
689 
690 
691 
692 // vhi1 -> oadd1(+) ;
693 // [ ( oadd1 -> vadd1 ->! oadd2(+) -> vreshi;
694 // oadd1 <- vhizext1( != vhi1);
695 // oadd2 <- vhizext2( != vadd1); ) |
696 // ( oadd1 <- vtmpvn( != vhi1) <- oadd2(+) <-(0) vhizext1;
697 // oadd2 <-(1) vhizext2;
698 // oadd1 -> vreshi; ) ]
699 // [ ( vhizext1 <- ozext(ZEXT);
700 // vhizext2 -> vhi2; ) |
701 // ( vhizext2 <- ozext(ZEXT);
702 // vhizext1 -> vhi2; ) ]
703 // ozext <-(0) vzextin <- olesseq(<=) <-(0) vlessin <- oneg(*) <-(1) #-1
704 // [ (oneg <-(0) vtmp (== vlo1); olesseq <-(1) vlo2; ) |
705 // (oneg <-(1) vtmp (== vlo2); oneg <-(0) vlo2; ) ]
706 // vlo1 -> oloadd(+) <- vtmp( != vlo1)( == vlo2);
707 // oloadd -> vreslo;
708 
709 #endif
DummyConstConstraint
Definition: unify.hh:246
ConstantIsConstant
Definition: unify.hh:113
TraverseCountState
Definition: unify.hh:176
ConstraintOtherInput
Definition: unify.hh:460
ConstantAbsolute
Definition: unify.hh:76
ConstraintBoolean
Definition: unify.hh:258
DummyOpConstraint
Definition: unify.hh:222
ConstraintLoneDescend
Definition: unify.hh:448
ConstantNamed
Definition: unify.hh:66
ConstantConsumed
Definition: unify.hh:95
ConstraintOpCopy
Definition: unify.hh:296
ConstantOffset
Definition: unify.hh:104
ConstraintSetInputConstVal
Definition: unify.hh:568
ConstraintRemoveInput
Definition: unify.hh:582
ConstraintVarCompare
Definition: unify.hh:409
ConstraintNamedExpression
Definition: unify.hh:283
OpBehavior
Class encapsulating the action/behavior of specific pcode opcodes.
Definition: opbehavior.hh:42
UnifyCPrinter
Definition: unify.hh:626
ConstraintOr
Definition: unify.hh:514
BlockBasic
A basic block for p-code operations.
Definition: block.hh:365
ConstraintGroup
Definition: unify.hh:490
PcodeOp
Lowest level operation of the p-code language.
Definition: op.hh:58
ConstraintSetOpcode
Definition: unify.hh:595
ConstraintVarConst
Definition: unify.hh:269
TraverseConstraint
Definition: unify.hh:151
UnifyDatatype
Definition: unify.hh:24
ConstraintSetInput
Definition: unify.hh:554
Varnode
A low-level variable or contiguous set of bytes described by an Address and a size.
Definition: varnode.hh:65
ConstraintParamConst
Definition: unify.hh:384
ConstraintOpcode
Definition: unify.hh:308
ConstraintDescend
Definition: unify.hh:434
funcdata.hh
Utilities for processing data structures associated with a single function.
ConstraintParamConstVal
Definition: unify.hh:372
Funcdata
Container for data structures associated with a single function.
Definition: funcdata.hh:45
ConstantNZMask
Definition: unify.hh:86
UnifyConstraint
Definition: unify.hh:200
RHSConstant
Definition: unify.hh:58
TraverseGroupState
Definition: unify.hh:186
ConstraintNewOp
Definition: unify.hh:526
ConstantVarnodeSize
Definition: unify.hh:131
OpCode
OpCode
The op-code defining a specific p-code operation (PcodeOp)
Definition: opcodes.hh:35
ConstraintNewUniqueOut
Definition: unify.hh:541
ConstantExpression
Definition: unify.hh:140
TraverseDescendState
Definition: unify.hh:160
ConstantHeritageKnown
Definition: unify.hh:122
ConstraintDef
Definition: unify.hh:422
DummyVarnodeConstraint
Definition: unify.hh:234
UnifyState
Definition: unify.hh:607
ConstraintVarnodeCopy
Definition: unify.hh:397
ConstraintOpCompare
Definition: unify.hh:321
ConstraintOpOutput
Definition: unify.hh:360
ConstraintOpInput
Definition: unify.hh:334
ConstraintConstCompare
Definition: unify.hh:474
ConstraintOpInputAny
Definition: unify.hh:347