Added definitions for about half of the pure virtual methods of the RiscOperators...
[dyninst.git] / dataflowAPI / rose / semantics / SymEvalSemantics.C
1 //
2 // Created by ssunny on 7/1/16.
3 //
4
5 #include "SymEvalSemantics.h"
6
7 using namespace rose::BinaryAnalysis::InstructionSemantics2;
8
9 ///////////////////////////////////////////////////////
10 //                                           StateARM64
11 ///////////////////////////////////////////////////////
12
13 void SymEvalSemantics::StateARM64::writeRegister(const RegisterDescriptor &reg, const BaseSemantics::SValuePtr &value,
14                                                  BaseSemantics::RiscOperators /**ops*/) {
15     ASSERT_require(reg.is_valid());
16     ASSERT_not_null(value);
17     SymEvalSemantics::RegisterStateARM64Ptr registers = SymEvalSemantics::RegisterStateARM64::promote(value);
18     registers->writeRegister(reg, value, res, aaMap);
19 }
20
21 void SymEvalSemantics::StateARM64::writeMemory(const BaseSemantics::SValuePtr &addr,
22                                                const BaseSemantics::SValuePtr &value,
23                                                BaseSemantics::RiscOperators /**addrOps*/,
24                                                BaseSemantics::RiscOperators /**valOps*/) {
25     ASSERT_not_null(addr);
26     ASSERT_not_null(value);
27     SymEvalSemantics::MemoryStateARM64Ptr memory = SymEvalSemantics::MemoryStateARM64::promote(value);
28     memory->writeMemory(addr, value, res, aaMap);
29 }
30
31 ///////////////////////////////////////////////////////
32 //                                   RegisterStateARM64
33 ///////////////////////////////////////////////////////
34
35 BaseSemantics::SValuePtr SymEvalSemantics::RegisterStateARM64::readRegister(const RegisterDescriptor &reg,
36                                                                             const BaseSemantics::SValuePtr &dflt,
37                                                                             BaseSemantics::RiscOperators */*ops*/) {
38     if(reg.get_major() == armv8_regclass_gpr) {
39         ARMv8GeneralPurposeRegister r = reg.get_minor();
40         unsigned int size = reg.get_nbits();
41         return SValuePtr(wrap(convert(r, size)));
42     } else {
43         ASSERT_not_implemented("readRegister not yet implemented for categories other than GPR");
44     }
45 }
46
47 void SymEvalSemantics::RegisterStateARM64::writeRegister(const RegisterDescriptor &reg,
48                                                          const BaseSematics::SValuePtr &value,
49                                                          Dyninst::DataflowAPI::Result_t &res,
50                                                          std::map<Dyninst::Absloc, Dyninst::Assignment::Ptr> &aaMap) {
51     if(reg.get_major() == armv8_regclass_gpr) {
52         ARMv8GeneralPurposeRegister r = reg.get_minor();
53
54         std::map<Absloc, Assignment::Ptr>::iterator i = aaMap.find(convert(r));
55         if (i != aaMap.end()) {
56             SymEvalSemantics::SValuePtr value_ = SymEvalSemantics::SValue::promote(value);
57             res[i->second] = value_->get_expression();
58         }
59     } else {
60         ASSERT_not_implemented("writeRegister not yet implemented for categories other than GPR");
61     }
62 }
63
64 void SymEvalSemantics::RegisterStateARM64::writeRegister(const RegisterDescriptor /*&reg*/,
65                                                          const BaseSemantics::SValuePtr /*&value*/,
66                                                          BaseSemantics::RiscOperators */*ops*/) {
67     ASSERT_always_forbid("overridden RegisterState::writeRegister() should never be called for ARM64, always use the non-virtual writeRegister that also takes additional parameters.");
68 }
69
70 Dyninst::Absloc SymEvalSemantics::RegisterStateARM64::convert(ARMv8GeneralPurposeRegister r, unsigned int size) {
71     Dyninst::MachRegister mreg;
72
73     if(r != armv8_gpr_zr) {
74         mreg = (size == 32)?Dyninst::aarch64::wzr:Dyninst::aarch64::zr;
75     } else {
76         mreg = (size == 32)?Dyninst::aarch64::w0:Dyninst::aarch64::x0;
77         mreg += (r - armv8_gpr_r0);
78     }
79
80     return Dyninst::Absloc(mreg);
81 }
82
83 ///////////////////////////////////////////////////////
84 //                                     MemoryStateARM64
85 ///////////////////////////////////////////////////////
86
87 //TODO: what is Len?
88
89 BaseSemantics::SValuePtr SymEvalSemantics::MemoryStateARM64::readMemory(const BaseSemantics::SValuePtr &address,
90                                                                         const BaseSemantics::SValuePtr &/*dflt*/,
91                                                                         BaseSemantics::RiscOperators */*addrOps*/,
92                                                                         BaseSemantics::RiscOperators */*valOps*/) {
93     SymEvalSemantics::SValuePtr addr = SymEvalSemantics::SValue::promote(address);
94     return Dyninst::DataflowAPI::RoseAST::create(Dyninst::DataflowAPI::ROSEOperation(Dyninst::DataflowAPI::ROSEOperation::derefOp),
95                                                  addr->get_expression(),
96                                                  Dyninst::DataflowAPI::ConstantAST::create(Dyninst::DataflowAPI::Constant(1, 1)));
97 }
98
99 void SymEvalSemantics::MemoryStateARM64::writeMemory(const BaseSemantics::SValuePtr &address,
100                                                      const BaseSematics::SValuePtr &value,
101                                                      Dyninst::DataflowAPI::Result_t &res,
102                                                      std::map<Dyninst::Absloc, Dyninst::Assignment::Ptr> &aaMap) {
103     std::map<Dyninst::Absloc, Dyninst::Assignment::Ptr>::iterator i = aaMap.find(Dyninst::Absloc(0));
104     SymEvalSemantics::SValuePtr addr = SymEvalSemantics::SValue::promote(address);
105
106     if (i != aaMap.end()) {
107         i->second->out().setGenerator(addr->get_expression());
108         //i->second->out().setSize(Len);
109
110         SymEvalSemantics::SValuePtr data = SymEvalSemantics::SValue::promote(value);
111         res[i->second] = data->get_expression();
112     }
113 }
114
115 void SymEvalSemantics::MemoryStateARM64::writeMemory(const BaseSemantics::SValuePtr /*&addr*/,
116                                                      const BaseSemantics::SValuePtr /*&value*/,
117                                                      BaseSemantics::RiscOperators /**addrOps*/,
118                                                      BaseSemantics::RiscOperators /**valOps*/) {
119     ASSERT_always_forbid("overridden MemoryState::writeMemory() should never be called for ARM64, always use the non-virtual writeRegister that also takes additional parameters.");
120 }
121
122 ///////////////////////////////////////////////////////
123 //                                        RiscOperators
124 ///////////////////////////////////////////////////////
125
126 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperators::and_(const BaseSemantics::SValuePtr &a_,
127                                                                const BaseSemantics::SValuePtr &b_) {
128     return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::andOp, a_, b_);
129 }
130
131 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperators::or_(const BaseSemantics::SValuePtr &a_,
132                                                               const BaseSemantics::SValuePtr &b_) {
133     return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::orOp, a_, b_);
134 }
135
136 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperators::xor_(const BaseSemantics::SValuePtr &a_,
137                                                                const BaseSemantics::SValuePtr &b_) {
138     return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::xorOp, a_, b_);
139 }
140
141 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperators::invert(const BaseSemantics::SValuePtr &a_) {
142     return createUnaryAST(Dyninst::DataflowAPI::ROSEOperation::invertOp, a_);
143 }
144
145 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperators::extract(const BaseSemantics::SValuePtr &a_, size_t begin,
146                                                                   size_t end) {
147     BaseSemantics::SValuePtr begin_ = SymEvalSemantics::SValue::instance(64, begin);
148     BaseSemantics::SValue end_ = SymEvalSemantics::SValue::instance(64, end);
149
150     return createTernaryAST(Dyninst::DataflowAPI::ROSEOperation::extractOp, a_, begin_, end_, end - begin);
151 }
152
153 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperators::ite(const BaseSemantics::SValuePtr &sel_,
154                                                               const BaseSemantics::SValuePtr &a_,
155                                                               const BaseSemantics::SValuePtr &b_) {
156     return createTernaryAST(Dyninst::DataflowAPI::ROSEOperation::ifOp, sel_, a_, b_);
157 }
158
159 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperators::concat(const BaseSemantics::SValuePtr &a_,
160                                                                  const BaseSemantics::SValuePtr &b_) {
161     //TODO: should be able to specify number of bits to concat for each expression
162     return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::concatOp, a_, b_);
163 }
164
165 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperators::leastSignificantBit(const BaseSemantics::SValuePtr &a_) {
166     return createUnaryAST(Dyninst::DataflowAPI::ROSEOperation::LSBSetOp, a_);
167 }
168
169 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperators::mostSignificantBit(const BaseSemantics::SValuePtr &a_) {
170     return createUnaryAST(Dyninst::DataflowAPI::ROSEOperation::MSBSetOp, a_);
171 }
172
173 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperators::rotateLeft(const BaseSemantics::SValuePtr &a_,
174                                                                      const BaseSemantics::SValuePtr &b_) {
175     return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::rotateLOp, a_, b_);
176 }
177
178 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperators::rotateRight(const BaseSemantics::SValuePtr &a_,
179                                                                       const BaseSemantics::SValuePtr &b_) {
180     return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::rotateROp, a_, b_);
181 }
182
183 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperators::shiftLeft(const BaseSemantics::SValuePtr &a_,
184                                                                     const BaseSemantics::SValuePtr &b_) {
185     return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::shiftLOp, a_, b_);
186 }
187
188 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperators::shiftRight(const BaseSemantics::SValuePtr &a_,
189                                                                      const BaseSemantics::SValuePtr &b_) {
190     return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::shiftROp, a_, b_);
191 }
192
193 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperators::shiftRightArithmetic(const BaseSemantics::SValuePtr &a_,
194                                                                                const BaseSemantics::SValuePtr &b_) {
195     return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::shiftRArithOp, a_, b_);
196 }
197
198 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperators::equalToZero(const BaseSemantics::SValuePtr &a_) {
199     return createUnaryAST(Dyninst::DataflowAPI::ROSEOperation::equalToZeroOp, a_);
200 }
201
202 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperators::signExtend(const BaseSemantics::SValuePtr &a_,
203                                                                      size_t newwidth) {
204     BaseSemantics::SValuePtr width_ = SymEvalSemantics::SValue::instance(64, newwidth);
205
206     return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::signExtendOp, a_, width_);
207 }