Added definitions for about half of the pure virtual methods of the RiscOperators...
[dyninst.git] / dataflowAPI / rose / semantics / SymEvalSemantics.h
1 //
2 // Created by ssunny on 7/1/16.
3 //
4
5 #ifndef DYNINST_SYMEVALSEMANTICS_H
6 #define DYNINST_SYMEVALSEMANTICS_H
7
8 #include "external/rose/armv8InstructionEnum.h"
9 #include "BaseSemantics2.h"
10 #include "../../h/SymEval.h"
11
12 namespace rose {
13     namespace BinaryAnalysis {
14         namespace InstructionSemantics2 {
15             namespace SymEvalSemantics {
16
17                 /***************************************************************************************************/
18                 /*                                              SValue                                             */
19                 /***************************************************************************************************/
20
21                 typedef Sawyer::SharedPointer<class SValue> SValuePtr;
22
23                 class SValue : public BaseSemantics::SValue {
24                 protected:
25                     Dyninst::AST::Ptr expr;
26
27                     SValue(Dyninst::Absloc r, Dyninst::Address addr): BaseSemantics::SValue(64) {
28                         expr = Dyninst::DataflowAPI::VariableAST::create(Variable(Dyninst::AbsRegion(r), addr));
29                     }
30
31                     SValue(size_t nbits, uint64_t num): BaseSemantics::SValue(nbits) {
32                         expr = Dyninst::DataflowAPI::ConstantAST::create(Dyninst::DataflowAPI::Constant(num, nbits));
33                     }
34
35                     SValue(Dyninst::AST::Ptr expr): BaseSemantics::SValue(64) {
36                         this->expr = expr;
37                     }
38
39                 public:
40                     static SValuePtr instance(Dyninst::Absloc r, Dyninst::Address addr) {
41                         return SValuePtr(new SValue(r, addr));
42                     }
43
44                     static SValuePtr instance(size_t nbits, uint64_t num) {
45                         return SValuePtr(new SValue(nbits, num));
46                     }
47
48                     static SValuePtr instance(Dyninst::AST::Ptr expr) {
49                         return SValuePtr(new SValue(expr));
50                     }
51
52                 public:
53                     virtual BaseSemantics::SValuePtr undefined_(size_t nbits) const {
54                         return SValuePtr(new SValue(Dyninst::DataflowAPI::BottomAST::create(false)));
55                     }
56
57                     virtual BaseSemantics::SValuePtr unspecified_(size_t nbits) const {
58                         return SValuePtr(new SValue(Dyninst::DataflowAPI::BottomAST::create(false)));
59                     }
60
61                     //TODO
62                     virtual BaseSemantics::SValuePtr bottom_(size_t nbits) const {
63                         return SValuePtr(new SValue(Dyninst::DataflowAPI::BottomAST::create(true)));
64                     }
65
66                     virtual BaseSemantics::SValuePtr number_(size_t nbits, uint64_t num) const {
67                         return SValuePtr(new SValue(nbits, num));
68                     }
69
70                     virtual BaseSemantics::SValuePtr boolean_(bool value) const {
71                         return SValuePtr(new SValue(Dyninst::DataflowAPI::ConstantAST::create(Dyninst::DataflowAPI::Constant(value?1:0, 1))));
72                     }
73
74                     virtual BaseSemantics::SValuePtr copy(size_t new_width = 0) const {
75                         SValuePtr retval(new SValue(this->get_expression()));
76                         if (new_width!=0 && new_width!=retval->get_width())
77                             retval->set_width(new_width);
78                         return retval;
79                     }
80
81                     virtual Sawyer::Optional<BaseSemantics::SValuePtr>
82                             createOptionalMerge(const BaseSemantics::SValuePtr &other, const BaseSemantics::MergerPtr&, SMTSolver*) const;
83
84                 public:
85                     static SValuePtr promote(const BaseSemantics::SValuePtr &v) {
86                         SValuePtr retval = v.dynamicCast<SValue>();
87                         ASSERT_not_null(retval);
88                         return retval;
89                     }
90
91                 public:
92                     virtual Dyninst::AST::Ptr get_expression() {
93                         return expr;
94                     }
95
96                     virtual bool isBottom() const {
97                         return expr->getID() == Dyninst::DataflowAPI::V_BottomAST;
98                     }
99
100                     virtual bool is_number() const {
101                         return expr->getID() == Dyninst::DataflowAPI::V_ConstantAST;
102                     }
103
104                     virtual uint64_t get_number() const {
105                         assert(expr->getID() == Dyninst::DataflowAPI::V_ConstantAST);
106                         Dyninst::DataflowAPI::Constant constant = expr->val();
107                         ASSERT_not_null(constant);
108                         return constant.val;
109                     }
110
111                     virtual void print(std::ostream &, BaseSemantics::Formatter &) const { }
112
113                 };
114
115
116                 /***************************************************************************************************/
117                 /*                                          Register State                                         */
118                 /***************************************************************************************************/
119
120                 typedef boost::shared_ptr<class RegisterStateARM64> RegisterStateARM64Ptr;
121
122                 class RegisterStateARM64 : public BaseSemantics::RegisterState {
123                 public:
124                     RegisterStateARM64(const BaseSemantics::SValuePtr &protoval,
125                                        const RegisterDictionary *regdict) : RegisterState(protoval, regdict) { }
126
127                 public:
128                     static RegisterStateARM64Ptr instance(const BaseSemantics::SValuePtr &protoval,
129                                                           const RegisterDictionary *regdict) {
130                         return RegisterStateARM64Ptr(new RegisterStateARM64(protoval, regdict));
131                     }
132
133                     virtual BaseSemantics::RegisterStatePtr create(const BaseSemantics::SValuePtr &protoval,
134                                                                    const RegisterDictionary *regdict) const {
135                         return instance(protoval, regdict);
136                     }
137
138                     virtual BaseSemantics::RegisterStatePtr clone() const {
139                         ASSERT_not_implemented("RegisterState::clone() should not be called with Dyninst's SymEval policy");
140                     }
141
142                     static RegisterStateARM64Ptr promote(const BaseSemantics::RegisterStatePtr &from) {
143                         RegisterStateARM64Ptr retval = boost::dynamic_pointer_cast<RegisterStateARM64>(from);
144                         ASSERT_not_null(retval);
145                         return retval;
146                     }
147
148                 public:
149                     virtual void clear() {
150                         ASSERT_not_implemented("RegisterState::clear() should not be called with Dyninst's SymEval policy");
151                     }
152
153                     virtual void zero() {
154                         ASSERT_not_implemented("RegisterState::zero() should not be called with Dyninst's SymEval policy");
155                     }
156
157                     virtual BaseSemantics::SValuePtr readRegister(const RegisterDescriptor &reg, const BaseSemantics::SValuePtr &dflt, BaseSemantics::RiscOperators *ops);
158                     virtual void writeRegister(const RegisterDescriptor &reg, const BaseSemantics::SValuePtr &value, BaseSemantics::RiscOperators *ops);
159
160                     virtual void print(std::ostream &, BaseSemantics::Formatter &) const {}
161
162                     virtual bool merge(const RegisterDescriptor &other, BaseSemantics::RiscOperators *ops) {
163                         return true;
164                     }
165
166                     void writeRegister(const RegisterDescriptor &reg, const BaseSematics::SValuePtr &value,
167                                        Dyninst::DataflowAPI::Result_t &res, std::map<Dyninst::Absloc, Dyninst::Assignment::Ptr> &aaMap);
168
169                 private:
170                     Dyninst::AST::Ptr wrap(Dyninst::Absloc r) {
171                         return Dyninst::DataflowAPI::VariableAST::create(Dyninst::DataflowAPI::Variable(Dyninst::AbsRegion(r), addr));
172                     }
173
174                     Dyninst::Absloc convert(ARMv8GeneralPurposeRegister r, unsigned int size);
175                 };
176
177
178                 /***************************************************************************************************/
179                 /*                                           Memory State                                          */
180                 /***************************************************************************************************/
181
182                 typedef boost::shared_ptr<class MemoryStateARM64> MemoryStateARM64Ptr;
183
184                 class MemoryStateARM64 : public BaseSemantics::MemoryState {
185                 protected:
186                     MemoryStateARM64(const BaseSemantics::SValuePtr &addrProtoval, const BaseSemantics::SValuePtr &valProtoval):
187                             BaseSemantics::MemoryState(addrProtoval, valProtoval) { }
188
189                 public:
190                     static MemoryStateARM64Ptr instance(const BaseSemantics::SValuePtr &addrProtoval, const BaseSemantics::SValuePtr &valProtoval) {
191                         return MemoryStateARM64Ptr(new MemoryStateARM64(addrProtoval, valProtoval));
192                     }
193
194                     virtual BaseSemantics::MemoryStatePtr create(const BaseSemantics::SValuePtr &addrProtoval, const BaseSemantics::SValuePtr &valProtoval) const {
195                         return instance(addrProtoval, valProtoval);
196                     }
197
198                     static MemoryStateARM64Ptr promote(const BaseSemantics::MemoryStatePtr &from) {
199                         MemoryStateARM64Ptr retval = boost::dynamic_pointer_cast<MemoryStateARM64>(from);
200                         ASSERT_not_null(retval);
201                         return retval;
202                     }
203
204                 public:
205                     virtual BaseSemantics::MemoryStatePtr clone() const {
206                         ASSERT_not_implemented("MemoryState::clone() should not be called with Dyninst's SymEval policy");
207                     }
208
209                     virtual void clear() {
210                         ASSERT_not_implemented("MemoryState::clear() should not be called with Dyninst's SymEval policy");
211                     }
212
213                     virtual bool merge(const BaseSemantics::MemoryStatePtr &other, BaseSemantics::RiscOperators *addrOps, BaseSemantics::RiscOperators *valOps) {
214                         return true;
215                     }
216
217                 public:
218                     virtual BaseSemantics::SValuePtr readMemory(const BaseSemantics::SValuePtr &address, const BaseSemantics::SValuePtr &dflt,
219                                                                 BaseSemantics::RiscOperators *addrOps, BaseSemantics::RiscOperators *valOps);
220
221                     virtual void writeMemory(const BaseSemantics::SValuePtr &addr, const BaseSemantics::SValuePtr &value,
222                                              BaseSemantics::RiscOperators *addrOps, BaseSemantics::RiscOperators *valOps);
223
224                     void writeMemory(const BaseSemantics::SValuePtr &addr, const BaseSematics::SValuePtr &value,
225                                        Dyninst::DataflowAPI::Result_t &res, std::map<Dyninst::Absloc, Dyninst::Assignment::Ptr> &aaMap);
226                 };
227
228
229                 /***************************************************************************************************/
230                 /*                                                State                                            */
231                 /***************************************************************************************************/
232
233                 typedef boost::shared_ptr<class StateARM64> StateARM64Ptr;
234
235                 class StateARM64 : public BaseSemantics::State {
236                 public:
237                     StateARM64(Dyninst::DataflowAPI::Result_t &r,
238                                Dyninst::Address a,
239                                Dyninst::Architecture ac,
240                                Dyninst::InstructionAPI::Instruction::Ptr insn_,
241                                const BaseSemantics::RegisterStatePtr &registers,
242                                const BaseSemantics::MemoryStatePtr &memory): BaseSemantics::State(registers, memory) {
243                         for (Dyninst::DataflowAPI::Result_t::iterator iter = r.begin();
244                              iter != r.end(); ++iter) {
245                             Dyninst::Assignment::Ptr a = iter->first;
246                             // For a different instruction...
247                             if (a->addr() != addr)
248                                 continue;
249                             Dyninst::AbsRegion &o = a->out();
250
251                             if (o.containsOfType(Dyninst::Absloc::Register)) {
252                                 // We're assuming this is a single register...
253                                 //std::cerr << "Marking register " << a << std::endl;
254                                 aaMap[o.absloc()] = a;
255                             }
256                             else {
257                                 // Use sufficiently-unique (Heap,0) Absloc
258                                 // to represent a definition to a memory absloc
259                                 aaMap[Absloc(0)] = a;
260                             }
261                         }
262                     }
263
264                 public:
265                     static StateARM64Ptr instance(Dyninst::DataflowAPI::Result_t &r,
266                                                   Dyninst::Address a,
267                                                   Dyninst::Architecture ac,
268                                                   Dyninst::InstructionAPI::Instruction::Ptr insn_,
269                                                   const BaseSemantics::RegisterStatePtr &registers,
270                                                   const BaseSemantics::MemoryStatePtr &memory) {
271                         return StateARM64Ptr(new StateARM64(r, a, ac, insn_, registers, memory));
272                     }
273
274                     virtual BaseSemantics::StatePtr create(Dyninst::DataflowAPI::Result_t &r,
275                                                  Dyninst::Address a,
276                                                  Dyninst::Architecture ac,
277                                                  Dyninst::InstructionAPI::Instruction::Ptr insn_,
278                                                  const BaseSemantics::RegisterStatePtr &registers,
279                                                  const BaseSemantics::MemoryStatePtr &memory) const {
280                         return instance(r, a, ac, insn_, registers, memory);
281                     }
282
283                     static StateARM64Ptr promote(const BaseSemantics::StatePtr &from) {
284                         StateARM64Ptr retval = boost::dynamic_pointer_cast<StateARM64>(from);
285                         ASSERT_not_null(retval);
286                         return retval;
287                     }
288
289                 public:
290                     virtual void writeRegister(const RegisterDescriptor &reg, const BaseSemantics::SValuePtr &value, BaseSemantics::RiscOperators *ops);
291                     virtual void writeMemory(const BaseSemantics::SValuePtr &addr, const BaseSemantics::SValuePtr &value, BaseSemantics::RiscOperators *addrOps,
292                                              BaseSemantics::RiscOperators *valOps);
293
294                 protected:
295                     Dyninst::DataflowAPI::Result_t &res;
296                     Dyninst::Architecture arch;
297                     Dyninst::Address addr;
298                     Dyninst::InstructionAPI::Instruction::Ptr insn;
299
300                     std::map<Dyninst::Absloc, Dyninst::Assignment::Ptr> aaMap;
301                 };
302
303
304                 /***************************************************************************************************/
305                 /*                                          RiscOperators                                          */
306                 /***************************************************************************************************/
307                 typedef boost::shared_ptr<class RiscOperators> RiscOperatorsPtr;
308
309                 /** RISC operators for use by the Symbolic Semantics Domain of Dyninst.
310                  *
311                  */
312                 class RiscOperators : public BaseSemantics::RiscOperators {
313                 protected:
314                     RiscOperators(const BaseSemantics::SValuePtr &protoval, SMTSolver *solver = NULL)
315                             : BaseSemantics::RiscOperators(protoval, solver) {
316                         (void)SValue::promote(protoval);
317                     }
318
319                     RiscOperators(const BaseSemantics::StatePtr &state, SMTSolver *solver = NULL)
320                             : BaseSemantics::RiscOperators(state, solver) {
321                         (void)SValue::promote(state->protoval());
322                     }
323
324                 public:
325                     static RiscOperatorsPtr instance(const BaseSemantics::SValuePtr &protoval,
326                                                      SMTSolver *solver = NULL) {
327                         return RiscOperatorsPtr(new RiscOperators(protoval, solver));
328                     }
329
330                     static RiscOperatorsPtr instance(const BaseSemantics::StatePtr &state, SMTSolver *solver = NULL) {
331                         return RiscOperatorsPtr(new RiscOperators(state, solver));
332                     }
333
334                 public:
335                     virtual BaseSemantics::RiscOperatorsPtr create(const BaseSemantics::SValuePtr &protoval,
336                                                                    SMTSolver *solver = NULL) {
337                         return instance(protoval, solver);
338                     }
339
340                     virtual BaseSemantics::RiscOperatorsPtr create(const BaseSemantics::StatePtr &state,
341                                                                    SMTSolver *solver = NULL) {
342                         return instance(state, solver);
343                     }
344
345                 public:
346                     /** Run-time promotion of a base RiscOperators pointer to symbolic operators. This is a checked conversion--it
347                     *  will fail if @p x does not point to a SymbolicSemantics::RiscOperators object. */
348                     static RiscOperatorsPtr promote(const BaseSemantics::RiscOperatorsPtr &x) {
349                         RiscOperatorsPtr retval = boost::dynamic_pointer_cast<RiscOperators>(x);
350                         ASSERT_not_null(retval);
351                         return retval;
352                     }
353
354                 public:
355                     virtual BaseSemantics::SValuePtr boolean_(bool b) {
356                         SValuePtr retVal = SValue::promote(BaseSemantics::RiscOperators::boolean_(b));
357                         return retval;
358                     }
359
360                     virtual BaseSemantics::SValuePtr number_(size_t nbits, uint64_t value) {
361                         SValuePtr retval = SValue::promote(BaseSemantics::RiscOperators::number_(nbits, value));
362                         return retval;
363                     }
364
365                 public:
366                     virtual BaseSemantics::SValuePtr and_(const BaseSemantics::SValuePtr &a_,
367                                                           const BaseSemantics::SValuePtr &b_);
368                     virtual BaseSemantics::SValuePtr or_(const BaseSemantics::SValuePtr &a_,
369                                                           const BaseSemantics::SValuePtr &b_);
370                     virtual BaseSemantics::SValuePtr xor_(const BaseSemantics::SValuePtr &a_,
371                                                           const BaseSemantics::SValuePtr &b_);
372                     virtual BaseSemantics::SValuePtr invert(const BaseSemantics::SValuePtr &a_);
373                     virtual BaseSemantics::SValuePtr extract(const BaseSemantics::SValuePtr &a_,
374                                                              size_t begin, size_t end);
375                     virtual BaseSemantics::SValuePtr ite(const BaseSemantics::SValuePtr &sel_,
376                                                          const BaseSemantics::SValuePtr &a_,
377                                                          const BaseSemantics::SValuePtr &b_);
378                     virtual BaseSemantics::SValuePtr concat(const BaseSemantics::SValuePtr &a_,
379                                                             const BaseSemantics::SValuePtr &b_);
380                     virtual BaseSemantics::SValuePtr leastSignificantBit(const BaseSemantics::SValuePtr &a_);
381                     virtual BaseSemantics::SValuePtr mostSignificantBit(const BaseSemantics::SValuePtr &a_);
382                     virtual BaseSemantics::SValuePtr rotateLeft(const BaseSemantics::SValuePtr &a_,
383                                                                 const BaseSemantics::SValuePtr &b_);
384                     virtual BaseSemantics::SValuePtr rotateRight(const BaseSemantics::SValuePtr &a_,
385                                                                 const BaseSemantics::SValuePtr &b_);
386                     virtual BaseSemantics::SValuePtr shiftLeft(const BaseSemantics::SValuePtr &a_,
387                                                                 const BaseSemantics::SValuePtr &b_);
388                     virtual BaseSemantics::SValuePtr shiftRight(const BaseSemantics::SValuePtr &a_,
389                                                                 const BaseSemantics::SValuePtr &b_);
390                     virtual BaseSemantics::SValuePtr shiftRightArithmetic(const BaseSemantics::SValuePtr &a_,
391                                                                 const BaseSemantics::SValuePtr &b_);
392                     virtual BaseSemantics::SValuePtr equalToZero(const BaseSemantics::SValuePtr &a_);
393                     virtual BaseSemantics::SValuePtr signExtend(const BaseSemantics::SValuePtr &a_, size_t newwidth = 0);
394
395                 public:
396                     virtual BaseSemantics::SValuePtr readRegister(const RegisterDescriptor &reg,
397                                                                   const BaseSemantics::SValuePtr &dflt);
398                     virtual void writeRegister(const RegisterDescriptor &reg, const BaseSemantics::SValuePtr &a_);
399
400                 private:
401                     Dyninst::AST::Ptr getUnaryAST(Dyninst::DataflowAPI::ROSEOperation::Op op,
402                                          AST::Ptr a,
403                                          size_t s = 0) {
404                         return Dyninst::DataflowAPI::RoseAST::create(Dyninst::DataflowAPI::ROSEOperation(op, s), a);
405                     }
406
407                     Dyninst::AST::Ptr getBinaryAST(Dyninst::DataflowAPI::ROSEOperation::Op op,
408                                           AST::Ptr a,
409                                           AST::Ptr b,
410                                           size_t s = 0) {
411                         return Dyninst::DataflowAPI::RoseAST::create(Dyninst::DataflowAPI::ROSEOperation(op, s), a, b);
412                     }
413
414                     Dyninst::AST::Ptr getTernaryAST(Dyninst::DataflowAPI::ROSEOperation::Op op,
415                                            AST::Ptr a,
416                                            AST::Ptr b,
417                                            AST::Ptr c,
418                                            size_t s = 0) {
419                         return Dyninst::DataflowAPI::RoseAST::create(Dyninst::DataflowAPI::ROSEOperation(op, s), a, b, c);
420                     }
421
422                     SValuePtr createUnaryAST(Dyninst::DataflowAPI::ROSEOperation::Op op, const BaseSemantics::SValuePtr &a_) {
423                         Dyninst::AST::Ptr a = SValue::promote(a_)->get_expression();
424                         Dyninst::AST::Ptr ast = getUnaryAST(op, a);
425                         return ast;
426                     }
427
428                     SValuePtr createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::Op op, const BaseSemantics::SValuePtr &a_, const BaseSemantics::SValuePtr &b_) {
429                         Dyninst::AST::Ptr a = SValue::promote(a_)->get_expression();
430                         Dyninst::AST::Ptr b = SValue::promote(b_)->get_expression();
431                         Dyninst::AST::Ptr ast = getBinaryAST(op, a, b);
432                         return SValue::instance(ast);
433                     }
434
435                     SValuePtr createTernaryAST(Dyninst::DataflowAPI::ROSEOperation::Op op, const BaseSemantics::SValuePtr &a_,
436                                                const BaseSemantics::SValuePtr &b_, const BaseSemantics::SValuePtr &c_, size_t s = 0) {
437                         Dyninst::AST::Ptr a = SValue::promote(a_)->get_expression();
438                         Dyninst::AST::Ptr b = SValue::promote(b_)->get_expression();
439                         Dyninst::AST::Ptr c = SValue::promote(c_)->get_expression();
440                         Dyninst::AST::Ptr ast = getTernaryAST(op, a, b, c, s);
441                         return SValue::instance(ast);
442                     }
443
444                 };
445             }
446         }
447     }
448 }
449
450 #endif //DYNINST_SYMEVALSEMANTICS_H