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