1 /*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <stdint.h>
18
19 #include <deque>
20 #include <string>
21 #include <vector>
22
23 #include <android-base/stringprintf.h>
24
25 #include <unwindstack/DwarfError.h>
26 #include <unwindstack/DwarfMemory.h>
27 #include <unwindstack/Log.h>
28 #include <unwindstack/Memory.h>
29 #include <unwindstack/Regs.h>
30
31 #include "DwarfOp.h"
32
33 namespace unwindstack {
34
35 template <typename AddressType>
36 constexpr typename DwarfOp<AddressType>::OpCallback DwarfOp<AddressType>::kCallbackTable[256];
37
38 template <typename AddressType>
Eval(uint64_t start,uint64_t end)39 bool DwarfOp<AddressType>::Eval(uint64_t start, uint64_t end) {
40 is_register_ = false;
41 stack_.clear();
42 memory_->set_cur_offset(start);
43 dex_pc_set_ = false;
44
45 // Unroll the first Decode calls to be able to check for a special
46 // sequence of ops and values that indicate this is the dex pc.
47 // The pattern is:
48 // OP_const4u (0x0c) 'D' 'E' 'X' '1'
49 // OP_drop (0x13)
50 if (memory_->cur_offset() < end) {
51 if (!Decode()) {
52 return false;
53 }
54 } else {
55 return true;
56 }
57 bool check_for_drop;
58 if (cur_op_ == 0x0c && operands_.back() == 0x31584544) {
59 check_for_drop = true;
60 } else {
61 check_for_drop = false;
62 }
63 if (memory_->cur_offset() < end) {
64 if (!Decode()) {
65 return false;
66 }
67 } else {
68 return true;
69 }
70
71 if (check_for_drop && cur_op_ == 0x13) {
72 dex_pc_set_ = true;
73 }
74
75 uint32_t iterations = 2;
76 while (memory_->cur_offset() < end) {
77 if (!Decode()) {
78 return false;
79 }
80 // To protect against a branch that creates an infinite loop,
81 // terminate if the number of iterations gets too high.
82 if (iterations++ == 1000) {
83 last_error_.code = DWARF_ERROR_TOO_MANY_ITERATIONS;
84 return false;
85 }
86 }
87 return true;
88 }
89
90 template <typename AddressType>
Decode()91 bool DwarfOp<AddressType>::Decode() {
92 last_error_.code = DWARF_ERROR_NONE;
93 if (!memory_->ReadBytes(&cur_op_, 1)) {
94 last_error_.code = DWARF_ERROR_MEMORY_INVALID;
95 last_error_.address = memory_->cur_offset();
96 return false;
97 }
98
99 const auto* op = &kCallbackTable[cur_op_];
100 const auto handle_func = op->handle_func;
101 if (handle_func == nullptr) {
102 last_error_.code = DWARF_ERROR_ILLEGAL_VALUE;
103 return false;
104 }
105
106 // Make sure that the required number of stack elements is available.
107 if (stack_.size() < op->num_required_stack_values) {
108 last_error_.code = DWARF_ERROR_STACK_INDEX_NOT_VALID;
109 return false;
110 }
111
112 operands_.clear();
113 for (size_t i = 0; i < op->num_operands; i++) {
114 uint64_t value;
115 if (!memory_->ReadEncodedValue<AddressType>(op->operands[i], &value)) {
116 last_error_.code = DWARF_ERROR_MEMORY_INVALID;
117 last_error_.address = memory_->cur_offset();
118 return false;
119 }
120 operands_.push_back(value);
121 }
122 return (this->*handle_func)();
123 }
124
125 template <typename AddressType>
GetLogInfo(uint64_t start,uint64_t end,std::vector<std::string> * lines)126 void DwarfOp<AddressType>::GetLogInfo(uint64_t start, uint64_t end,
127 std::vector<std::string>* lines) {
128 memory_->set_cur_offset(start);
129 while (memory_->cur_offset() < end) {
130 uint8_t cur_op;
131 if (!memory_->ReadBytes(&cur_op, 1)) {
132 return;
133 }
134
135 std::string raw_string(android::base::StringPrintf("Raw Data: 0x%02x", cur_op));
136 std::string log_string;
137 const auto* op = &kCallbackTable[cur_op];
138 if (op->handle_func == nullptr) {
139 log_string = "Illegal";
140 } else {
141 log_string = op->name;
142 uint64_t start_offset = memory_->cur_offset();
143 for (size_t i = 0; i < op->num_operands; i++) {
144 uint64_t value;
145 if (!memory_->ReadEncodedValue<AddressType>(op->operands[i], &value)) {
146 return;
147 }
148 log_string += ' ' + std::to_string(value);
149 }
150 uint64_t end_offset = memory_->cur_offset();
151
152 memory_->set_cur_offset(start_offset);
153 for (size_t i = start_offset; i < end_offset; i++) {
154 uint8_t byte;
155 if (!memory_->ReadBytes(&byte, 1)) {
156 return;
157 }
158 raw_string += android::base::StringPrintf(" 0x%02x", byte);
159 }
160 memory_->set_cur_offset(end_offset);
161 }
162 lines->push_back(std::move(log_string));
163 lines->push_back(std::move(raw_string));
164 }
165 }
166
167 template <typename AddressType>
op_deref()168 bool DwarfOp<AddressType>::op_deref() {
169 // Read the address and dereference it.
170 AddressType addr = StackPop();
171 AddressType value;
172 if (!regular_memory()->ReadFully(addr, &value, sizeof(value))) {
173 last_error_.code = DWARF_ERROR_MEMORY_INVALID;
174 last_error_.address = addr;
175 return false;
176 }
177 stack_.push_front(value);
178 return true;
179 }
180
181 template <typename AddressType>
op_deref_size()182 bool DwarfOp<AddressType>::op_deref_size() {
183 AddressType bytes_to_read = OperandAt(0);
184 if (bytes_to_read > sizeof(AddressType) || bytes_to_read == 0) {
185 last_error_.code = DWARF_ERROR_ILLEGAL_VALUE;
186 return false;
187 }
188 // Read the address and dereference it.
189 AddressType addr = StackPop();
190 AddressType value = 0;
191 if (!regular_memory()->ReadFully(addr, &value, bytes_to_read)) {
192 last_error_.code = DWARF_ERROR_MEMORY_INVALID;
193 last_error_.address = addr;
194 return false;
195 }
196 stack_.push_front(value);
197 return true;
198 }
199
200 template <typename AddressType>
op_push()201 bool DwarfOp<AddressType>::op_push() {
202 // Push all of the operands.
203 for (auto operand : operands_) {
204 stack_.push_front(operand);
205 }
206 return true;
207 }
208
209 template <typename AddressType>
op_dup()210 bool DwarfOp<AddressType>::op_dup() {
211 stack_.push_front(StackAt(0));
212 return true;
213 }
214
215 template <typename AddressType>
op_drop()216 bool DwarfOp<AddressType>::op_drop() {
217 StackPop();
218 return true;
219 }
220
221 template <typename AddressType>
op_over()222 bool DwarfOp<AddressType>::op_over() {
223 stack_.push_front(StackAt(1));
224 return true;
225 }
226
227 template <typename AddressType>
op_pick()228 bool DwarfOp<AddressType>::op_pick() {
229 AddressType index = OperandAt(0);
230 if (index > StackSize()) {
231 last_error_.code = DWARF_ERROR_STACK_INDEX_NOT_VALID;
232 return false;
233 }
234 stack_.push_front(StackAt(index));
235 return true;
236 }
237
238 template <typename AddressType>
op_swap()239 bool DwarfOp<AddressType>::op_swap() {
240 AddressType old_value = stack_[0];
241 stack_[0] = stack_[1];
242 stack_[1] = old_value;
243 return true;
244 }
245
246 template <typename AddressType>
op_rot()247 bool DwarfOp<AddressType>::op_rot() {
248 AddressType top = stack_[0];
249 stack_[0] = stack_[1];
250 stack_[1] = stack_[2];
251 stack_[2] = top;
252 return true;
253 }
254
255 template <typename AddressType>
op_abs()256 bool DwarfOp<AddressType>::op_abs() {
257 SignedType signed_value = static_cast<SignedType>(stack_[0]);
258 if (signed_value < 0) {
259 signed_value = -signed_value;
260 }
261 stack_[0] = static_cast<AddressType>(signed_value);
262 return true;
263 }
264
265 template <typename AddressType>
op_and()266 bool DwarfOp<AddressType>::op_and() {
267 AddressType top = StackPop();
268 stack_[0] &= top;
269 return true;
270 }
271
272 template <typename AddressType>
op_div()273 bool DwarfOp<AddressType>::op_div() {
274 AddressType top = StackPop();
275 if (top == 0) {
276 last_error_.code = DWARF_ERROR_ILLEGAL_VALUE;
277 return false;
278 }
279 SignedType signed_divisor = static_cast<SignedType>(top);
280 SignedType signed_dividend = static_cast<SignedType>(stack_[0]);
281 stack_[0] = static_cast<AddressType>(signed_dividend / signed_divisor);
282 return true;
283 }
284
285 template <typename AddressType>
op_minus()286 bool DwarfOp<AddressType>::op_minus() {
287 AddressType top = StackPop();
288 stack_[0] -= top;
289 return true;
290 }
291
292 template <typename AddressType>
op_mod()293 bool DwarfOp<AddressType>::op_mod() {
294 AddressType top = StackPop();
295 if (top == 0) {
296 last_error_.code = DWARF_ERROR_ILLEGAL_VALUE;
297 return false;
298 }
299 stack_[0] %= top;
300 return true;
301 }
302
303 template <typename AddressType>
op_mul()304 bool DwarfOp<AddressType>::op_mul() {
305 AddressType top = StackPop();
306 stack_[0] *= top;
307 return true;
308 }
309
310 template <typename AddressType>
op_neg()311 bool DwarfOp<AddressType>::op_neg() {
312 SignedType signed_value = static_cast<SignedType>(stack_[0]);
313 stack_[0] = static_cast<AddressType>(-signed_value);
314 return true;
315 }
316
317 template <typename AddressType>
op_not()318 bool DwarfOp<AddressType>::op_not() {
319 stack_[0] = ~stack_[0];
320 return true;
321 }
322
323 template <typename AddressType>
op_or()324 bool DwarfOp<AddressType>::op_or() {
325 AddressType top = StackPop();
326 stack_[0] |= top;
327 return true;
328 }
329
330 template <typename AddressType>
op_plus()331 bool DwarfOp<AddressType>::op_plus() {
332 AddressType top = StackPop();
333 stack_[0] += top;
334 return true;
335 }
336
337 template <typename AddressType>
op_plus_uconst()338 bool DwarfOp<AddressType>::op_plus_uconst() {
339 stack_[0] += OperandAt(0);
340 return true;
341 }
342
343 template <typename AddressType>
op_shl()344 bool DwarfOp<AddressType>::op_shl() {
345 AddressType top = StackPop();
346 stack_[0] <<= top;
347 return true;
348 }
349
350 template <typename AddressType>
op_shr()351 bool DwarfOp<AddressType>::op_shr() {
352 AddressType top = StackPop();
353 stack_[0] >>= top;
354 return true;
355 }
356
357 template <typename AddressType>
op_shra()358 bool DwarfOp<AddressType>::op_shra() {
359 AddressType top = StackPop();
360 SignedType signed_value = static_cast<SignedType>(stack_[0]) >> top;
361 stack_[0] = static_cast<AddressType>(signed_value);
362 return true;
363 }
364
365 template <typename AddressType>
op_xor()366 bool DwarfOp<AddressType>::op_xor() {
367 AddressType top = StackPop();
368 stack_[0] ^= top;
369 return true;
370 }
371
372 template <typename AddressType>
op_bra()373 bool DwarfOp<AddressType>::op_bra() {
374 // Requires one stack element.
375 AddressType top = StackPop();
376 int16_t offset = static_cast<int16_t>(OperandAt(0));
377 uint64_t cur_offset;
378 if (top != 0) {
379 cur_offset = memory_->cur_offset() + offset;
380 } else {
381 cur_offset = memory_->cur_offset() - offset;
382 }
383 memory_->set_cur_offset(cur_offset);
384 return true;
385 }
386
387 template <typename AddressType>
op_eq()388 bool DwarfOp<AddressType>::op_eq() {
389 AddressType top = StackPop();
390 stack_[0] = bool_to_dwarf_bool(stack_[0] == top);
391 return true;
392 }
393
394 template <typename AddressType>
op_ge()395 bool DwarfOp<AddressType>::op_ge() {
396 AddressType top = StackPop();
397 stack_[0] = bool_to_dwarf_bool(stack_[0] >= top);
398 return true;
399 }
400
401 template <typename AddressType>
op_gt()402 bool DwarfOp<AddressType>::op_gt() {
403 AddressType top = StackPop();
404 stack_[0] = bool_to_dwarf_bool(stack_[0] > top);
405 return true;
406 }
407
408 template <typename AddressType>
op_le()409 bool DwarfOp<AddressType>::op_le() {
410 AddressType top = StackPop();
411 stack_[0] = bool_to_dwarf_bool(stack_[0] <= top);
412 return true;
413 }
414
415 template <typename AddressType>
op_lt()416 bool DwarfOp<AddressType>::op_lt() {
417 AddressType top = StackPop();
418 stack_[0] = bool_to_dwarf_bool(stack_[0] < top);
419 return true;
420 }
421
422 template <typename AddressType>
op_ne()423 bool DwarfOp<AddressType>::op_ne() {
424 AddressType top = StackPop();
425 stack_[0] = bool_to_dwarf_bool(stack_[0] != top);
426 return true;
427 }
428
429 template <typename AddressType>
op_skip()430 bool DwarfOp<AddressType>::op_skip() {
431 int16_t offset = static_cast<int16_t>(OperandAt(0));
432 uint64_t cur_offset = memory_->cur_offset() + offset;
433 memory_->set_cur_offset(cur_offset);
434 return true;
435 }
436
437 template <typename AddressType>
op_lit()438 bool DwarfOp<AddressType>::op_lit() {
439 stack_.push_front(cur_op() - 0x30);
440 return true;
441 }
442
443 template <typename AddressType>
op_reg()444 bool DwarfOp<AddressType>::op_reg() {
445 is_register_ = true;
446 stack_.push_front(cur_op() - 0x50);
447 return true;
448 }
449
450 template <typename AddressType>
op_regx()451 bool DwarfOp<AddressType>::op_regx() {
452 is_register_ = true;
453 stack_.push_front(OperandAt(0));
454 return true;
455 }
456
457 // It's not clear for breg/bregx, if this op should read the current
458 // value of the register, or where we think that register is located.
459 // For simplicity, the code will read the value before doing the unwind.
460 template <typename AddressType>
op_breg()461 bool DwarfOp<AddressType>::op_breg() {
462 uint16_t reg = cur_op() - 0x70;
463 if (reg >= regs_info_->Total()) {
464 last_error_.code = DWARF_ERROR_ILLEGAL_VALUE;
465 return false;
466 }
467 stack_.push_front(regs_info_->Get(reg) + OperandAt(0));
468 return true;
469 }
470
471 template <typename AddressType>
op_bregx()472 bool DwarfOp<AddressType>::op_bregx() {
473 AddressType reg = OperandAt(0);
474 if (reg >= regs_info_->Total()) {
475 last_error_.code = DWARF_ERROR_ILLEGAL_VALUE;
476 return false;
477 }
478 stack_.push_front(regs_info_->Get(reg) + OperandAt(1));
479 return true;
480 }
481
482 template <typename AddressType>
op_nop()483 bool DwarfOp<AddressType>::op_nop() {
484 return true;
485 }
486
487 template <typename AddressType>
op_not_implemented()488 bool DwarfOp<AddressType>::op_not_implemented() {
489 last_error_.code = DWARF_ERROR_NOT_IMPLEMENTED;
490 return false;
491 }
492
493 // Explicitly instantiate DwarfOp.
494 template class DwarfOp<uint32_t>;
495 template class DwarfOp<uint64_t>;
496
497 } // namespace unwindstack
498