Allow accessing StateARM64's Dyninst::Address member in RegisterStateARM64 for use...
[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(Dyninst::DataflowAPI::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(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                         ASSERT_not_implemented("SValue::createOptionalMerge not implemented for use in dyninst");
84                     }
85
86                 public:
87                     static SValuePtr promote(const BaseSemantics::SValuePtr &v) {
88                         SValuePtr retval = v.dynamicCast<SValue>();
89                         ASSERT_not_null(retval);
90                         return retval;
91                     }
92
93                 public:
94                     virtual Dyninst::AST::Ptr get_expression() const {
95                         return expr;
96                     }
97
98                     virtual bool isBottom() const {
99                         return expr->getID() == Dyninst::AST::V_BottomAST;
100                     }
101
102                     virtual bool is_number() const {
103                         return expr->getID() == Dyninst::AST::V_ConstantAST;
104                     }
105
106                     virtual uint64_t get_number() const {
107                         assert(expr->getID() == Dyninst::AST::V_ConstantAST);
108                         //TODO
109                         Dyninst::DataflowAPI::Constant constant = boost::dynamic_pointer_cast<Dyninst::DataflowAPI::ConstantAST>(expr)->val();
110                         return constant.val;
111                     }
112
113                     virtual void print(std::ostream &, BaseSemantics::Formatter &) const { }
114
115                 };
116
117
118                 /***************************************************************************************************/
119                 /*                                          Register State                                         */
120                 /***************************************************************************************************/
121
122                 typedef boost::shared_ptr<class RegisterStateARM64> RegisterStateARM64Ptr;
123
124                 class RegisterStateARM64 : public BaseSemantics::RegisterState {
125                 public:
126                     RegisterStateARM64(const BaseSemantics::SValuePtr &protoval,
127                                        const RegisterDictionary *regdict) : RegisterState(protoval, regdict) { }
128
129                 public:
130                     static RegisterStateARM64Ptr instance(const BaseSemantics::SValuePtr &protoval,
131                                                           const RegisterDictionary *regdict) {
132                         return RegisterStateARM64Ptr(new RegisterStateARM64(protoval, regdict));
133                     }
134
135                     virtual BaseSemantics::RegisterStatePtr create(const BaseSemantics::SValuePtr &protoval,
136                                                                    const RegisterDictionary *regdict) const {
137                         return instance(protoval, regdict);
138                     }
139
140                     virtual BaseSemantics::RegisterStatePtr clone() const {
141                         ASSERT_not_implemented("RegisterState::clone() should not be called with Dyninst's SymEval policy");
142                     }
143
144                     static RegisterStateARM64Ptr promote(const BaseSemantics::RegisterStatePtr &from) {
145                         RegisterStateARM64Ptr retval = boost::dynamic_pointer_cast<RegisterStateARM64>(from);
146                         ASSERT_not_null(retval);
147                         return retval;
148                     }
149
150                 public:
151                     virtual void clear() {
152                         ASSERT_not_implemented("RegisterState::clear() should not be called with Dyninst's SymEval policy");
153                     }
154
155                     virtual void zero() {
156                         ASSERT_not_implemented("RegisterState::zero() should not be called with Dyninst's SymEval policy");
157                     }
158
159                     virtual BaseSemantics::SValuePtr readRegister(const RegisterDescriptor &reg, const BaseSemantics::SValuePtr &dflt, BaseSemantics::RiscOperators *ops);
160                     virtual void writeRegister(const RegisterDescriptor &reg, const BaseSemantics::SValuePtr &value, BaseSemantics::RiscOperators *ops);
161
162                     virtual void print(std::ostream &, BaseSemantics::Formatter &) const {}
163
164                     virtual bool merge(const BaseSemantics::RegisterStatePtr &other, BaseSemantics::RiscOperators *ops) {
165                         return true;
166                     }
167
168                     BaseSemantics::SValuePtr readRegister(const RegisterDescriptor &reg, Dyninst::Address addr);
169                     void writeRegister(const RegisterDescriptor &reg, const BaseSemantics::SValuePtr &value,
170                                        Dyninst::DataflowAPI::Result_t &res, std::map<Dyninst::Absloc, Dyninst::Assignment::Ptr> &aaMap);
171
172                 private:
173                     Dyninst::AST::Ptr wrap(Dyninst::Absloc r, Dyninst::Address addr) {
174                         return Dyninst::DataflowAPI::VariableAST::create(Dyninst::DataflowAPI::Variable(Dyninst::AbsRegion(r), addr));
175                     }
176
177                     Dyninst::Absloc convert(ARMv8GeneralPurposeRegister r, unsigned int size);
178                 };
179
180
181                 /***************************************************************************************************/
182                 /*                                           Memory State                                          */
183                 /***************************************************************************************************/
184
185                 typedef boost::shared_ptr<class MemoryStateARM64> MemoryStateARM64Ptr;
186
187                 class MemoryStateARM64 : public BaseSemantics::MemoryState {
188                 protected:
189                     MemoryStateARM64(const BaseSemantics::SValuePtr &addrProtoval, const BaseSemantics::SValuePtr &valProtoval):
190                             BaseSemantics::MemoryState(addrProtoval, valProtoval) { }
191
192                 public:
193                     static MemoryStateARM64Ptr instance(const BaseSemantics::SValuePtr &addrProtoval, const BaseSemantics::SValuePtr &valProtoval) {
194                         return MemoryStateARM64Ptr(new MemoryStateARM64(addrProtoval, valProtoval));
195                     }
196
197                     virtual BaseSemantics::MemoryStatePtr create(const BaseSemantics::SValuePtr &addrProtoval, const BaseSemantics::SValuePtr &valProtoval) const {
198                         return instance(addrProtoval, valProtoval);
199                     }
200
201                     static MemoryStateARM64Ptr promote(const BaseSemantics::MemoryStatePtr &from) {
202                         MemoryStateARM64Ptr retval = boost::dynamic_pointer_cast<MemoryStateARM64>(from);
203                         ASSERT_not_null(retval);
204                         return retval;
205                     }
206
207                 public:
208                     virtual BaseSemantics::MemoryStatePtr clone() const {
209                         ASSERT_not_implemented("MemoryState::clone() should not be called with Dyninst's SymEval policy");
210                     }
211
212                     virtual void clear() {
213                         ASSERT_not_implemented("MemoryState::clear() should not be called with Dyninst's SymEval policy");
214                     }
215
216                     virtual void print(std::ostream&, BaseSemantics::Formatter&) const {
217                         //
218                     }
219
220                     virtual bool merge(const BaseSemantics::MemoryStatePtr &other, BaseSemantics::RiscOperators *addrOps, BaseSemantics::RiscOperators *valOps) {
221                         return true;
222                     }
223
224                 public:
225                     virtual BaseSemantics::SValuePtr readMemory(const BaseSemantics::SValuePtr &address, const BaseSemantics::SValuePtr &dflt,
226                                                                 BaseSemantics::RiscOperators *addrOps, BaseSemantics::RiscOperators *valOps);
227
228                     virtual void writeMemory(const BaseSemantics::SValuePtr &addr, const BaseSemantics::SValuePtr &value,
229                                              BaseSemantics::RiscOperators *addrOps, BaseSemantics::RiscOperators *valOps);
230
231                     void writeMemory(const BaseSemantics::SValuePtr &addr, const BaseSemantics::SValuePtr &value,
232                                        Dyninst::DataflowAPI::Result_t &res, std::map<Dyninst::Absloc, Dyninst::Assignment::Ptr> &aaMap);
233                 };
234
235
236                 /***************************************************************************************************/
237                 /*                                                State                                            */
238                 /***************************************************************************************************/
239
240                 typedef boost::shared_ptr<class StateARM64> StateARM64Ptr;
241
242                 class StateARM64 : public BaseSemantics::State {
243                 public:
244                     StateARM64(Dyninst::DataflowAPI::Result_t &r,
245                                Dyninst::Address a,
246                                Dyninst::Architecture ac,
247                                Dyninst::InstructionAPI::Instruction::Ptr insn_,
248                                const BaseSemantics::RegisterStatePtr &registers,
249                                const BaseSemantics::MemoryStatePtr &memory): BaseSemantics::State(registers, memory), res(r), addr(a), arch(ac), insn(insn_) {
250                         for (Dyninst::DataflowAPI::Result_t::iterator iter = r.begin();
251                              iter != r.end(); ++iter) {
252                             Dyninst::Assignment::Ptr a = iter->first;
253                             // For a different instruction...
254                             if (a->addr() != addr)
255                                 continue;
256                             Dyninst::AbsRegion &o = a->out();
257
258                             if (o.containsOfType(Dyninst::Absloc::Register)) {
259                                 // We're assuming this is a single register...
260                                 //std::cerr << "Marking register " << a << std::endl;
261                                 aaMap[o.absloc()] = a;
262                             }
263                             else {
264                                 // Use sufficiently-unique (Heap,0) Absloc
265                                 // to represent a definition to a memory absloc
266                                 aaMap[Dyninst::Absloc(0)] = a;
267                             }
268                         }
269                     }
270
271                 public:
272                     static StateARM64Ptr instance(Dyninst::DataflowAPI::Result_t &r,
273                                                   Dyninst::Address a,
274                                                   Dyninst::Architecture ac,
275                                                   Dyninst::InstructionAPI::Instruction::Ptr insn_,
276                                                   const BaseSemantics::RegisterStatePtr &registers,
277                                                   const BaseSemantics::MemoryStatePtr &memory) {
278                         return StateARM64Ptr(new StateARM64(r, a, ac, insn_, registers, memory));
279                     }
280
281                     virtual BaseSemantics::StatePtr create(Dyninst::DataflowAPI::Result_t &r,
282                                                  Dyninst::Address a,
283                                                  Dyninst::Architecture ac,
284                                                  Dyninst::InstructionAPI::Instruction::Ptr insn_,
285                                                  const BaseSemantics::RegisterStatePtr &registers,
286                                                  const BaseSemantics::MemoryStatePtr &memory) const {
287                         return instance(r, a, ac, insn_, registers, memory);
288                     }
289
290                     static StateARM64Ptr promote(const BaseSemantics::StatePtr &from) {
291                         StateARM64Ptr retval = boost::dynamic_pointer_cast<StateARM64>(from);
292                         ASSERT_not_null(retval);
293                         return retval;
294                     }
295
296                 public:
297                     virtual BaseSemantics::SValuePtr readRegister(const RegisterDescriptor &reg, const BaseSemantics::SValuePtr &dflt, BaseSemantics::RiscOperators *ops);
298                     virtual void writeRegister(const RegisterDescriptor &reg, const BaseSemantics::SValuePtr &value, BaseSemantics::RiscOperators *ops);
299                     virtual void writeMemory(const BaseSemantics::SValuePtr &addr, const BaseSemantics::SValuePtr &value, BaseSemantics::RiscOperators *addrOps,
300                                              BaseSemantics::RiscOperators *valOps);
301
302                 protected:
303                     Dyninst::DataflowAPI::Result_t &res;
304                     Dyninst::Architecture arch;
305                     Dyninst::Address addr;
306                     Dyninst::InstructionAPI::Instruction::Ptr insn;
307
308                     std::map<Dyninst::Absloc, Dyninst::Assignment::Ptr> aaMap;
309                 };
310
311
312                 /***************************************************************************************************/
313                 /*                                          RiscOperators                                          */
314                 /***************************************************************************************************/
315                 typedef boost::shared_ptr<class RiscOperatorsARM64> RiscOperatorsARM64Ptr;
316
317                 /** RISC operators for use by the Symbolic Semantics Domain of Dyninst.
318                  *
319                  */
320                 class RiscOperatorsARM64 : public BaseSemantics::RiscOperators {
321                 protected:
322                     RiscOperatorsARM64(const BaseSemantics::SValuePtr &protoval, SMTSolver *solver = NULL)
323                             : BaseSemantics::RiscOperators(protoval, solver) {
324                         (void)SValue::promote(protoval);
325                     }
326
327                     RiscOperatorsARM64(const BaseSemantics::StatePtr &state, SMTSolver *solver = NULL)
328                             : BaseSemantics::RiscOperators(state, solver) {
329                         (void)SValue::promote(state->protoval());
330                     }
331
332                 public:
333                     static RiscOperatorsARM64Ptr instance(const BaseSemantics::SValuePtr &protoval,
334                                                      SMTSolver *solver = NULL) {
335                         return RiscOperatorsARM64Ptr(new RiscOperatorsARM64(protoval, solver));
336                     }
337
338                     static RiscOperatorsARM64Ptr instance(const BaseSemantics::StatePtr &state, SMTSolver *solver = NULL) {
339                         return RiscOperatorsARM64Ptr(new RiscOperatorsARM64(state, solver));
340                     }
341
342                 public:
343                     virtual BaseSemantics::RiscOperatorsPtr create(const BaseSemantics::SValuePtr &protoval,
344                                                                    SMTSolver *solver = NULL) const {
345                         return instance(protoval, solver);
346                     }
347
348                     virtual BaseSemantics::RiscOperatorsPtr create(const BaseSemantics::StatePtr &state,
349                                                                    SMTSolver *solver = NULL) const {
350                         return instance(state, solver);
351                     }
352
353                 public:
354                     /** Run-time promotion of a base RiscOperators pointer to symbolic operators. This is a checked conversion--it
355                     *  will fail if @p x does not point to a SymbolicSemantics::RiscOperators object. */
356                     static RiscOperatorsARM64Ptr promote(const BaseSemantics::RiscOperatorsPtr &x) {
357                         RiscOperatorsARM64Ptr retval = boost::dynamic_pointer_cast<RiscOperatorsARM64>(x);
358                         ASSERT_not_null(retval);
359                         return retval;
360                     }
361
362                 public:
363                     virtual BaseSemantics::SValuePtr boolean_(bool b) {
364                         SValuePtr retval = SValue::promote(BaseSemantics::RiscOperators::boolean_(b));
365                         return retval;
366                     }
367
368                     virtual BaseSemantics::SValuePtr number_(size_t nbits, uint64_t value) {
369                         SValuePtr retval = SValue::promote(BaseSemantics::RiscOperators::number_(nbits, value));
370                         return retval;
371                     }
372
373                 public:
374                     virtual BaseSemantics::SValuePtr and_(const BaseSemantics::SValuePtr &a_,
375                                                           const BaseSemantics::SValuePtr &b_);
376                     virtual BaseSemantics::SValuePtr or_(const BaseSemantics::SValuePtr &a_,
377                                                           const BaseSemantics::SValuePtr &b_);
378                     virtual BaseSemantics::SValuePtr xor_(const BaseSemantics::SValuePtr &a_,
379                                                           const BaseSemantics::SValuePtr &b_);
380                     virtual BaseSemantics::SValuePtr invert(const BaseSemantics::SValuePtr &a_);
381                     virtual BaseSemantics::SValuePtr extract(const BaseSemantics::SValuePtr &a_,
382                                                              size_t begin, size_t end);
383                     virtual BaseSemantics::SValuePtr ite(const BaseSemantics::SValuePtr &sel_,
384                                                          const BaseSemantics::SValuePtr &a_,
385                                                          const BaseSemantics::SValuePtr &b_);
386                     virtual BaseSemantics::SValuePtr concat(const BaseSemantics::SValuePtr &a_,
387                                                             const BaseSemantics::SValuePtr &b_);
388                     virtual BaseSemantics::SValuePtr leastSignificantSetBit(const BaseSemantics::SValuePtr &a_);
389                     virtual BaseSemantics::SValuePtr mostSignificantSetBit(const BaseSemantics::SValuePtr &a_);
390                     virtual BaseSemantics::SValuePtr rotateLeft(const BaseSemantics::SValuePtr &a_,
391                                                                 const BaseSemantics::SValuePtr &b_);
392                     virtual BaseSemantics::SValuePtr rotateRight(const BaseSemantics::SValuePtr &a_,
393                                                                 const BaseSemantics::SValuePtr &b_);
394                     virtual BaseSemantics::SValuePtr shiftLeft(const BaseSemantics::SValuePtr &a_,
395                                                                 const BaseSemantics::SValuePtr &b_);
396                     virtual BaseSemantics::SValuePtr shiftRight(const BaseSemantics::SValuePtr &a_,
397                                                                 const BaseSemantics::SValuePtr &b_);
398                     virtual BaseSemantics::SValuePtr shiftRightArithmetic(const BaseSemantics::SValuePtr &a_,
399                                                                 const BaseSemantics::SValuePtr &b_);
400                     virtual BaseSemantics::SValuePtr equalToZero(const BaseSemantics::SValuePtr &a_);
401                     virtual BaseSemantics::SValuePtr signExtend(const BaseSemantics::SValuePtr &a_,
402                                                                 size_t newwidth = 0);
403                     virtual BaseSemantics::SValuePtr add(const BaseSemantics::SValuePtr &a_,
404                                                          const BaseSemantics::SValuePtr &b_);
405                     virtual BaseSemantics::SValuePtr addWithCarries(const BaseSemantics::SValuePtr &a_,
406                                                                     const BaseSemantics::SValuePtr &b_,
407                                                                     const BaseSemantics::SValuePtr &c_,
408                                                                     BaseSemantics::SValuePtr &carry_out);
409                     virtual BaseSemantics::SValuePtr negate(const BaseSemantics::SValuePtr &a_);
410                     virtual BaseSemantics::SValuePtr signedDivide(const BaseSemantics::SValuePtr &a_,
411                                                                   const BaseSemantics::SValuePtr &b_);
412                     virtual BaseSemantics::SValuePtr signedModulo(const BaseSemantics::SValuePtr &a_,
413                                                                   const BaseSemantics::SValuePtr &b_);
414                     virtual BaseSemantics::SValuePtr signedMultiply(const BaseSemantics::SValuePtr &a_,
415                                                                   const BaseSemantics::SValuePtr &b_);
416                     virtual BaseSemantics::SValuePtr unsignedDivide(const BaseSemantics::SValuePtr &a_,
417                                                                   const BaseSemantics::SValuePtr &b_);
418                     virtual BaseSemantics::SValuePtr unsignedModulo(const BaseSemantics::SValuePtr &a_,
419                                                                   const BaseSemantics::SValuePtr &b_);
420                     virtual BaseSemantics::SValuePtr unsignedMultiply(const BaseSemantics::SValuePtr &a_,
421                                                                     const BaseSemantics::SValuePtr &b_);
422
423                 public:
424                     virtual BaseSemantics::SValuePtr readMemory(const RegisterDescriptor &segreg, const BaseSemantics::SValuePtr &addr, const BaseSemantics::SValuePtr &dflt,
425                                                  const BaseSemantics::SValuePtr &cond);
426                     virtual void writeMemory(const RegisterDescriptor &segreg, const BaseSemantics::SValuePtr &addr, const BaseSemantics::SValuePtr &data,
427                                              const BaseSemantics::SValuePtr &cond);
428
429                 private:
430                     Dyninst::AST::Ptr getUnaryAST(Dyninst::DataflowAPI::ROSEOperation::Op op,
431                                          Dyninst::AST::Ptr a,
432                                          size_t s = 0) {
433                         return Dyninst::DataflowAPI::RoseAST::create(Dyninst::DataflowAPI::ROSEOperation(op, s), a);
434                     }
435
436                     Dyninst::AST::Ptr getBinaryAST(Dyninst::DataflowAPI::ROSEOperation::Op op,
437                                                    Dyninst::AST::Ptr a,
438                                                    Dyninst::AST::Ptr b,
439                                           size_t s = 0) {
440                         return Dyninst::DataflowAPI::RoseAST::create(Dyninst::DataflowAPI::ROSEOperation(op, s), a, b);
441                     }
442
443                     Dyninst::AST::Ptr getTernaryAST(Dyninst::DataflowAPI::ROSEOperation::Op op,
444                                                     Dyninst::AST::Ptr a,
445                                                     Dyninst::AST::Ptr b,
446                                                     Dyninst::AST::Ptr c,
447                                            size_t s = 0) {
448                         return Dyninst::DataflowAPI::RoseAST::create(Dyninst::DataflowAPI::ROSEOperation(op, s), a, b, c);
449                     }
450
451                     SValuePtr createUnaryAST(Dyninst::DataflowAPI::ROSEOperation::Op op, const BaseSemantics::SValuePtr &a_) {
452                         Dyninst::AST::Ptr a = SValue::promote(a_)->get_expression();
453                         Dyninst::AST::Ptr ast = getUnaryAST(op, a);
454                         return SValue::instance(ast);
455                     }
456
457                     SValuePtr createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::Op op, const BaseSemantics::SValuePtr &a_, const BaseSemantics::SValuePtr &b_) {
458                         Dyninst::AST::Ptr a = SValue::promote(a_)->get_expression();
459                         Dyninst::AST::Ptr b = SValue::promote(b_)->get_expression();
460                         Dyninst::AST::Ptr ast = getBinaryAST(op, a, b);
461                         return SValue::instance(ast);
462                     }
463
464                     SValuePtr createTernaryAST(Dyninst::DataflowAPI::ROSEOperation::Op op, const BaseSemantics::SValuePtr &a_,
465                                                const BaseSemantics::SValuePtr &b_, const BaseSemantics::SValuePtr &c_, size_t s = 0) {
466                         Dyninst::AST::Ptr a = SValue::promote(a_)->get_expression();
467                         Dyninst::AST::Ptr b = SValue::promote(b_)->get_expression();
468                         Dyninst::AST::Ptr c = SValue::promote(c_)->get_expression();
469                         Dyninst::AST::Ptr ast = getTernaryAST(op, a, b, c, s);
470                         return SValue::instance(ast);
471                     }
472
473                 };
474             }
475         }
476     }
477 }
478
479 #endif //DYNINST_SYMEVALSEMANTICS_H