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