Home | History | Annotate | Download | only in libunwindstack
      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>
     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>
     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>
    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>
    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>
    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>
    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>
    210 bool DwarfOp<AddressType>::op_dup() {
    211   stack_.push_front(StackAt(0));
    212   return true;
    213 }
    214 
    215 template <typename AddressType>
    216 bool DwarfOp<AddressType>::op_drop() {
    217   StackPop();
    218   return true;
    219 }
    220 
    221 template <typename AddressType>
    222 bool DwarfOp<AddressType>::op_over() {
    223   stack_.push_front(StackAt(1));
    224   return true;
    225 }
    226 
    227 template <typename AddressType>
    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>
    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>
    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>
    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>
    266 bool DwarfOp<AddressType>::op_and() {
    267   AddressType top = StackPop();
    268   stack_[0] &= top;
    269   return true;
    270 }
    271 
    272 template <typename AddressType>
    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>
    286 bool DwarfOp<AddressType>::op_minus() {
    287   AddressType top = StackPop();
    288   stack_[0] -= top;
    289   return true;
    290 }
    291 
    292 template <typename AddressType>
    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>
    304 bool DwarfOp<AddressType>::op_mul() {
    305   AddressType top = StackPop();
    306   stack_[0] *= top;
    307   return true;
    308 }
    309 
    310 template <typename AddressType>
    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>
    318 bool DwarfOp<AddressType>::op_not() {
    319   stack_[0] = ~stack_[0];
    320   return true;
    321 }
    322 
    323 template <typename AddressType>
    324 bool DwarfOp<AddressType>::op_or() {
    325   AddressType top = StackPop();
    326   stack_[0] |= top;
    327   return true;
    328 }
    329 
    330 template <typename AddressType>
    331 bool DwarfOp<AddressType>::op_plus() {
    332   AddressType top = StackPop();
    333   stack_[0] += top;
    334   return true;
    335 }
    336 
    337 template <typename AddressType>
    338 bool DwarfOp<AddressType>::op_plus_uconst() {
    339   stack_[0] += OperandAt(0);
    340   return true;
    341 }
    342 
    343 template <typename AddressType>
    344 bool DwarfOp<AddressType>::op_shl() {
    345   AddressType top = StackPop();
    346   stack_[0] <<= top;
    347   return true;
    348 }
    349 
    350 template <typename AddressType>
    351 bool DwarfOp<AddressType>::op_shr() {
    352   AddressType top = StackPop();
    353   stack_[0] >>= top;
    354   return true;
    355 }
    356 
    357 template <typename AddressType>
    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>
    366 bool DwarfOp<AddressType>::op_xor() {
    367   AddressType top = StackPop();
    368   stack_[0] ^= top;
    369   return true;
    370 }
    371 
    372 template <typename AddressType>
    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>
    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>
    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>
    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>
    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>
    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>
    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>
    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>
    438 bool DwarfOp<AddressType>::op_lit() {
    439   stack_.push_front(cur_op() - 0x30);
    440   return true;
    441 }
    442 
    443 template <typename AddressType>
    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>
    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>
    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>
    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>
    483 bool DwarfOp<AddressType>::op_nop() {
    484   return true;
    485 }
    486 
    487 template <typename AddressType>
    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