Fixed issues seen while parsing a simple ARM binary
[dyninst.git] / dataflowAPI / rose / semantics / SymEvalSemantics.C
1 //
2 // Created by ssunny on 7/1/16.
3 //
4
5 #include <libtasn1.h>
6 #include "SymEvalSemantics.h"
7
8 using namespace rose::BinaryAnalysis::InstructionSemantics2;
9
10 ///////////////////////////////////////////////////////
11 //                                           StateARM64
12 ///////////////////////////////////////////////////////
13
14 BaseSemantics::SValuePtr SymEvalSemantics::StateARM64::readRegister(const RegisterDescriptor &desc,
15                                                                     const BaseSemantics::SValuePtr &/*dflt*/, BaseSemantics::RiscOperators */*ops*/) {
16     ASSERT_require(desc.is_valid());
17     SymEvalSemantics::RegisterStateARM64Ptr registers = SymEvalSemantics::RegisterStateARM64::promote(registerState());
18     return registers->readRegister(desc, addr);
19 }
20
21 void SymEvalSemantics::StateARM64::writeRegister(const RegisterDescriptor &reg, const BaseSemantics::SValuePtr &value,
22                                                  BaseSemantics::RiscOperators */*ops*/) {
23     ASSERT_require(reg.is_valid());
24     ASSERT_not_null(value);
25     SymEvalSemantics::RegisterStateARM64Ptr registers = SymEvalSemantics::RegisterStateARM64::promote(registerState());
26     registers->writeRegister(reg, value, res, aaMap);
27 }
28
29 void SymEvalSemantics::StateARM64::writeMemory(const BaseSemantics::SValuePtr &addr,
30                                                const BaseSemantics::SValuePtr &value,
31                                                BaseSemantics::RiscOperators */*addrOps*/,
32                                                BaseSemantics::RiscOperators */*valOps*/) {
33     ASSERT_not_null(addr);
34     ASSERT_not_null(value);
35     SymEvalSemantics::MemoryStateARM64Ptr memory = SymEvalSemantics::MemoryStateARM64::promote(memoryState());
36     memory->writeMemory(addr, value, res, aaMap);
37 }
38
39 ///////////////////////////////////////////////////////
40 //                                   RegisterStateARM64
41 ///////////////////////////////////////////////////////
42
43 BaseSemantics::SValuePtr SymEvalSemantics::RegisterStateARM64::readRegister(const RegisterDescriptor &reg,
44                                                                             Dyninst::Address addr) {
45     if(reg.get_major() != armv8_regclass_simd_fpr) {
46         ARMv8GeneralPurposeRegister r = static_cast<ARMv8GeneralPurposeRegister>(reg.get_minor());
47         unsigned int size = reg.get_nbits();
48         return SymEvalSemantics::SValue::instance(wrap(convert(r, size), addr));
49     } else {
50         ASSERT_not_implemented("readRegister not yet implemented for categories other than GPR");
51     }
52 }
53
54 BaseSemantics::SValuePtr SymEvalSemantics::RegisterStateARM64::readRegister(const RegisterDescriptor &reg,
55                                                                             const BaseSemantics::SValuePtr &/*dflt*/,
56                                                                             BaseSemantics::RiscOperators */*ops*/) {
57     ASSERT_always_forbid("overridden RegisterState::readRegister() should never be called for ARM64, always use the non-virtual readRegister that takes Dyninst::Address as an argument.");
58 }
59
60 void SymEvalSemantics::RegisterStateARM64::writeRegister(const RegisterDescriptor &reg,
61                                                          const BaseSemantics::SValuePtr &value,
62                                                          Dyninst::DataflowAPI::Result_t &res,
63                                                          std::map<Dyninst::Absloc, Dyninst::Assignment::Ptr> &aaMap) {
64     if(reg.get_major() != armv8_regclass_simd_fpr) {
65         ARMv8GeneralPurposeRegister r = static_cast<ARMv8GeneralPurposeRegister>(reg.get_minor());
66
67         std::map<Dyninst::Absloc, Dyninst::Assignment::Ptr>::iterator i = aaMap.find(convert(r, reg.get_nbits()));
68         if (i != aaMap.end()) {
69             SymEvalSemantics::SValuePtr value_ = SymEvalSemantics::SValue::promote(value);
70             res[i->second] = value_->get_expression();
71         }
72     } else {
73         ASSERT_not_implemented("writeRegister not yet implemented for categories other than GPR");
74     }
75 }
76
77 void SymEvalSemantics::RegisterStateARM64::writeRegister(const RegisterDescriptor &/*reg*/,
78                                                          const BaseSemantics::SValuePtr &/*value*/,
79                                                          BaseSemantics::RiscOperators */*ops*/) {
80     ASSERT_always_forbid("overridden RegisterState::writeRegister() should never be called for ARM64, always use the non-virtual writeRegister that also takes additional parameters.");
81 }
82
83 Dyninst::Absloc SymEvalSemantics::RegisterStateARM64::convert(ARMv8GeneralPurposeRegister r, unsigned int size) {
84     Dyninst::MachRegister mreg;
85
86     if(r != armv8_gpr_zr) {
87         mreg = (size == 32)?Dyninst::aarch64::wzr:Dyninst::aarch64::zr;
88     } else {
89         mreg = (size == 32)?Dyninst::aarch64::w0:Dyninst::aarch64::x0;
90         mreg = Dyninst::MachRegister(mreg.val() + (r - armv8_gpr_r0));
91     }
92
93     return Dyninst::Absloc(mreg);
94 }
95
96 ///////////////////////////////////////////////////////
97 //                                     MemoryStateARM64
98 ///////////////////////////////////////////////////////
99
100 //TODO: what is Len in this case?
101
102 BaseSemantics::SValuePtr SymEvalSemantics::MemoryStateARM64::readMemory(const BaseSemantics::SValuePtr &address,
103                                                                         const BaseSemantics::SValuePtr &/*dflt*/,
104                                                                         BaseSemantics::RiscOperators */*addrOps*/,
105                                                                         BaseSemantics::RiscOperators */*valOps*/) {
106     SymEvalSemantics::SValuePtr addr = SymEvalSemantics::SValue::promote(address);
107     return SymEvalSemantics::SValue::instance(Dyninst::DataflowAPI::RoseAST::create(Dyninst::DataflowAPI::ROSEOperation(Dyninst::DataflowAPI::ROSEOperation::derefOp),
108                                                  addr->get_expression(),
109                                                  Dyninst::DataflowAPI::ConstantAST::create(Dyninst::DataflowAPI::Constant(1, 1))));
110 }
111
112 void SymEvalSemantics::MemoryStateARM64::writeMemory(const BaseSemantics::SValuePtr &address,
113                                                      const BaseSemantics::SValuePtr &value,
114                                                      Dyninst::DataflowAPI::Result_t &res,
115                                                      std::map<Dyninst::Absloc, Dyninst::Assignment::Ptr> &aaMap) {
116     std::map<Dyninst::Absloc, Dyninst::Assignment::Ptr>::iterator i = aaMap.find(Dyninst::Absloc(0));
117     SymEvalSemantics::SValuePtr addr = SymEvalSemantics::SValue::promote(address);
118
119     if (i != aaMap.end()) {
120         i->second->out().setGenerator(addr->get_expression());
121         //i->second->out().setSize(Len);
122
123         SymEvalSemantics::SValuePtr data = SymEvalSemantics::SValue::promote(value);
124         res[i->second] = data->get_expression();
125     }
126 }
127
128 void SymEvalSemantics::MemoryStateARM64::writeMemory(const BaseSemantics::SValuePtr &/*addr*/,
129                                                      const BaseSemantics::SValuePtr &/*value*/,
130                                                      BaseSemantics::RiscOperators */*addrOps*/,
131                                                      BaseSemantics::RiscOperators */*valOps*/) {
132     ASSERT_always_forbid("overridden MemoryState::writeMemory() should never be called for ARM64, always use the non-virtual writeRegister that also takes additional parameters.");
133 }
134
135 ///////////////////////////////////////////////////////
136 //                                        RiscOperators
137 ///////////////////////////////////////////////////////
138
139 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsARM64::and_(const BaseSemantics::SValuePtr &a_,
140                                                                const BaseSemantics::SValuePtr &b_) {
141     return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::andOp, a_, b_);
142 }
143
144 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsARM64::or_(const BaseSemantics::SValuePtr &a_,
145                                                               const BaseSemantics::SValuePtr &b_) {
146     return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::orOp, a_, b_);
147 }
148
149 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsARM64::xor_(const BaseSemantics::SValuePtr &a_,
150                                                                const BaseSemantics::SValuePtr &b_) {
151     return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::xorOp, a_, b_);
152 }
153
154 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsARM64::invert(const BaseSemantics::SValuePtr &a_) {
155     return createUnaryAST(Dyninst::DataflowAPI::ROSEOperation::invertOp, a_);
156 }
157
158 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsARM64::extract(const BaseSemantics::SValuePtr &a_, size_t begin,
159                                                                   size_t end) {
160     BaseSemantics::SValuePtr begin_ = SymEvalSemantics::SValue::instance(64, begin);
161     BaseSemantics::SValuePtr end_ = SymEvalSemantics::SValue::instance(64, end);
162
163     return createTernaryAST(Dyninst::DataflowAPI::ROSEOperation::extractOp, a_, begin_, end_, end - begin);
164 }
165
166 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsARM64::ite(const BaseSemantics::SValuePtr &sel_,
167                                                               const BaseSemantics::SValuePtr &a_,
168                                                               const BaseSemantics::SValuePtr &b_) {
169     return createTernaryAST(Dyninst::DataflowAPI::ROSEOperation::ifOp, sel_, a_, b_);
170 }
171
172 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsARM64::concat(const BaseSemantics::SValuePtr &a_,
173                                                                  const BaseSemantics::SValuePtr &b_) {
174     //TODO: should be able to specify number of bits to concat for each expression
175     return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::concatOp, a_, b_);
176 }
177
178 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsARM64::leastSignificantSetBit(const BaseSemantics::SValuePtr &a_) {
179     return createUnaryAST(Dyninst::DataflowAPI::ROSEOperation::LSBSetOp, a_);
180 }
181
182 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsARM64::mostSignificantSetBit(const BaseSemantics::SValuePtr &a_) {
183     return createUnaryAST(Dyninst::DataflowAPI::ROSEOperation::MSBSetOp, a_);
184 }
185
186 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsARM64::rotateLeft(const BaseSemantics::SValuePtr &a_,
187                                                                      const BaseSemantics::SValuePtr &b_) {
188     return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::rotateLOp, a_, b_);
189 }
190
191 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsARM64::rotateRight(const BaseSemantics::SValuePtr &a_,
192                                                                       const BaseSemantics::SValuePtr &b_) {
193     return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::rotateROp, a_, b_);
194 }
195
196 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsARM64::shiftLeft(const BaseSemantics::SValuePtr &a_,
197                                                                     const BaseSemantics::SValuePtr &b_) {
198     return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::shiftLOp, a_, b_);
199 }
200
201 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsARM64::shiftRight(const BaseSemantics::SValuePtr &a_,
202                                                                      const BaseSemantics::SValuePtr &b_) {
203     return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::shiftROp, a_, b_);
204 }
205
206 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsARM64::shiftRightArithmetic(const BaseSemantics::SValuePtr &a_,
207                                                                                const BaseSemantics::SValuePtr &b_) {
208     return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::shiftRArithOp, a_, b_);
209 }
210
211 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsARM64::equalToZero(const BaseSemantics::SValuePtr &a_) {
212     return createUnaryAST(Dyninst::DataflowAPI::ROSEOperation::equalToZeroOp, a_);
213 }
214
215 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsARM64::signExtend(const BaseSemantics::SValuePtr &a_,
216                                                                      size_t newwidth) {
217     BaseSemantics::SValuePtr width_ = SymEvalSemantics::SValue::instance(64, newwidth);
218
219     return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::signExtendOp, a_, width_);
220 }
221
222 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsARM64::add(const BaseSemantics::SValuePtr &a_,
223                                                               const BaseSemantics::SValuePtr &b_) {
224     return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::addOp, a_, b_);
225 }
226
227 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsARM64::addWithCarries(const BaseSemantics::SValuePtr &a_,
228                                                                          const BaseSemantics::SValuePtr &b_,
229                                                                          const BaseSemantics::SValuePtr &c_,
230                                                                          BaseSemantics::SValuePtr &carry_out) {
231     BaseSemantics::SValuePtr aa_ = unsignedExtend(a_, a_->get_width() + 1);
232     BaseSemantics::SValuePtr bb_ = unsignedExtend(a_, b_->get_width() + 1);
233     BaseSemantics::SValuePtr sum_ = createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::addOp, aa_,
234                                                     createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::addOp, bb_, c_));
235
236     BaseSemantics::SValuePtr cc_ = createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::xorOp, aa_,
237                                                    createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::xorOp, bb_, sum_));
238     carry_out = extract(cc_, 1, a_->get_width() + 1);
239
240     return extract(sum_, 0, a_->get_width());
241 }
242
243 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsARM64::negate(const BaseSemantics::SValuePtr &a_) {
244     return createUnaryAST(Dyninst::DataflowAPI::ROSEOperation::negateOp, a_);
245 }
246
247 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsARM64::signedDivide(const BaseSemantics::SValuePtr &a_,
248                                                                        const BaseSemantics::SValuePtr &b_) {
249     return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::sDivOp, a_, b_);
250 }
251
252 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsARM64::signedModulo(const BaseSemantics::SValuePtr &a_,
253                                                                        const BaseSemantics::SValuePtr &b_) {
254     return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::sModOp, a_, b_);
255 }
256
257 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsARM64::signedMultiply(const BaseSemantics::SValuePtr &a_,
258                                                                          const BaseSemantics::SValuePtr &b_) {
259     return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::sMultOp, a_, b_);
260 }
261
262 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsARM64::unsignedDivide(const BaseSemantics::SValuePtr &a_,
263                                                                        const BaseSemantics::SValuePtr &b_) {
264     return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::uDivOp, a_, b_);
265 }
266
267 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsARM64::unsignedModulo(const BaseSemantics::SValuePtr &a_,
268                                                                        const BaseSemantics::SValuePtr &b_) {
269     return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::uModOp, a_, b_);
270 }
271
272 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsARM64::unsignedMultiply(const BaseSemantics::SValuePtr &a_,
273                                                                          const BaseSemantics::SValuePtr &b_) {
274     return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::uMultOp, a_, b_);
275 }
276
277 //TODO: do we deal with byte ordering?
278 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsARM64::readMemory(const RegisterDescriptor &/*segreg*/,
279                                                                      const BaseSemantics::SValuePtr &addr,
280                                                                      const BaseSemantics::SValuePtr &dflt,
281                                                                      const BaseSemantics::SValuePtr &/*cond*/) {
282     return currentState()->readMemory(addr, dflt, this, this);
283 }
284
285 void SymEvalSemantics::RiscOperatorsARM64::writeMemory(const RegisterDescriptor &/*segreg*/,
286                                                   const BaseSemantics::SValuePtr &addr,
287                                                   const BaseSemantics::SValuePtr &data,
288                                                   const BaseSemantics::SValuePtr &/*cond*/) {
289     currentState()->writeMemory(addr, data, this, this);
290 }