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 <unwindstack/DwarfError.h> 20 #include <unwindstack/DwarfLocation.h> 21 #include <unwindstack/DwarfMemory.h> 22 #include <unwindstack/DwarfSection.h> 23 #include <unwindstack/DwarfStructs.h> 24 #include <unwindstack/Log.h> 25 #include <unwindstack/Memory.h> 26 #include <unwindstack/Regs.h> 27 28 #include "DwarfCfa.h" 29 #include "DwarfDebugFrame.h" 30 #include "DwarfEhFrame.h" 31 #include "DwarfEncoding.h" 32 #include "DwarfOp.h" 33 #include "RegsInfo.h" 34 35 namespace unwindstack { 36 37 DwarfSection::DwarfSection(Memory* memory) : memory_(memory) {} 38 39 const DwarfFde* DwarfSection::GetFdeFromPc(uint64_t pc) { 40 uint64_t fde_offset; 41 if (!GetFdeOffsetFromPc(pc, &fde_offset)) { 42 return nullptr; 43 } 44 const DwarfFde* fde = GetFdeFromOffset(fde_offset); 45 if (fde == nullptr) { 46 return nullptr; 47 } 48 49 // Guaranteed pc >= pc_start, need to check pc in the fde range. 50 if (pc < fde->pc_end) { 51 return fde; 52 } 53 last_error_.code = DWARF_ERROR_ILLEGAL_STATE; 54 return nullptr; 55 } 56 57 bool DwarfSection::Step(uint64_t pc, Regs* regs, Memory* process_memory, bool* finished) { 58 // Lookup the pc in the cache. 59 auto it = loc_regs_.upper_bound(pc); 60 if (it == loc_regs_.end() || pc < it->second.pc_start) { 61 last_error_.code = DWARF_ERROR_NONE; 62 const DwarfFde* fde = GetFdeFromPc(pc); 63 if (fde == nullptr || fde->cie == nullptr) { 64 last_error_.code = DWARF_ERROR_ILLEGAL_STATE; 65 return false; 66 } 67 68 // Now get the location information for this pc. 69 dwarf_loc_regs_t loc_regs; 70 if (!GetCfaLocationInfo(pc, fde, &loc_regs)) { 71 return false; 72 } 73 loc_regs.cie = fde->cie; 74 75 // Store it in the cache. 76 it = loc_regs_.emplace(loc_regs.pc_end, std::move(loc_regs)).first; 77 } 78 79 // Now eval the actual registers. 80 return Eval(it->second.cie, process_memory, it->second, regs, finished); 81 } 82 83 template <typename AddressType> 84 bool DwarfSectionImpl<AddressType>::EvalExpression(const DwarfLocation& loc, Memory* regular_memory, 85 AddressType* value, 86 RegsInfo<AddressType>* regs_info, 87 bool* is_dex_pc) { 88 DwarfOp<AddressType> op(&memory_, regular_memory); 89 op.set_regs_info(regs_info); 90 91 // Need to evaluate the op data. 92 uint64_t end = loc.values[1]; 93 uint64_t start = end - loc.values[0]; 94 if (!op.Eval(start, end)) { 95 last_error_ = op.last_error(); 96 return false; 97 } 98 if (op.StackSize() == 0) { 99 last_error_.code = DWARF_ERROR_ILLEGAL_STATE; 100 return false; 101 } 102 // We don't support an expression that evaluates to a register number. 103 if (op.is_register()) { 104 last_error_.code = DWARF_ERROR_NOT_IMPLEMENTED; 105 return false; 106 } 107 *value = op.StackAt(0); 108 if (is_dex_pc != nullptr && op.dex_pc_set()) { 109 *is_dex_pc = true; 110 } 111 return true; 112 } 113 114 template <typename AddressType> 115 struct EvalInfo { 116 const dwarf_loc_regs_t* loc_regs; 117 const DwarfCie* cie; 118 Memory* regular_memory; 119 AddressType cfa; 120 bool return_address_undefined = false; 121 RegsInfo<AddressType> regs_info; 122 }; 123 124 template <typename AddressType> 125 bool DwarfSectionImpl<AddressType>::EvalRegister(const DwarfLocation* loc, uint32_t reg, 126 AddressType* reg_ptr, void* info) { 127 EvalInfo<AddressType>* eval_info = reinterpret_cast<EvalInfo<AddressType>*>(info); 128 Memory* regular_memory = eval_info->regular_memory; 129 switch (loc->type) { 130 case DWARF_LOCATION_OFFSET: 131 if (!regular_memory->ReadFully(eval_info->cfa + loc->values[0], reg_ptr, sizeof(AddressType))) { 132 last_error_.code = DWARF_ERROR_MEMORY_INVALID; 133 last_error_.address = eval_info->cfa + loc->values[0]; 134 return false; 135 } 136 break; 137 case DWARF_LOCATION_VAL_OFFSET: 138 *reg_ptr = eval_info->cfa + loc->values[0]; 139 break; 140 case DWARF_LOCATION_REGISTER: { 141 uint32_t cur_reg = loc->values[0]; 142 if (cur_reg >= eval_info->regs_info.Total()) { 143 last_error_.code = DWARF_ERROR_ILLEGAL_VALUE; 144 return false; 145 } 146 *reg_ptr = eval_info->regs_info.Get(cur_reg) + loc->values[1]; 147 break; 148 } 149 case DWARF_LOCATION_EXPRESSION: 150 case DWARF_LOCATION_VAL_EXPRESSION: { 151 AddressType value; 152 bool is_dex_pc = false; 153 if (!EvalExpression(*loc, regular_memory, &value, &eval_info->regs_info, &is_dex_pc)) { 154 return false; 155 } 156 if (loc->type == DWARF_LOCATION_EXPRESSION) { 157 if (!regular_memory->ReadFully(value, reg_ptr, sizeof(AddressType))) { 158 last_error_.code = DWARF_ERROR_MEMORY_INVALID; 159 last_error_.address = value; 160 return false; 161 } 162 } else { 163 *reg_ptr = value; 164 if (is_dex_pc) { 165 eval_info->regs_info.regs->set_dex_pc(value); 166 } 167 } 168 break; 169 } 170 case DWARF_LOCATION_UNDEFINED: 171 if (reg == eval_info->cie->return_address_register) { 172 eval_info->return_address_undefined = true; 173 } 174 default: 175 break; 176 } 177 178 return true; 179 } 180 181 template <typename AddressType> 182 bool DwarfSectionImpl<AddressType>::Eval(const DwarfCie* cie, Memory* regular_memory, 183 const dwarf_loc_regs_t& loc_regs, Regs* regs, 184 bool* finished) { 185 RegsImpl<AddressType>* cur_regs = reinterpret_cast<RegsImpl<AddressType>*>(regs); 186 if (cie->return_address_register >= cur_regs->total_regs()) { 187 last_error_.code = DWARF_ERROR_ILLEGAL_VALUE; 188 return false; 189 } 190 191 // Get the cfa value; 192 auto cfa_entry = loc_regs.find(CFA_REG); 193 if (cfa_entry == loc_regs.end()) { 194 last_error_.code = DWARF_ERROR_CFA_NOT_DEFINED; 195 return false; 196 } 197 198 // Always set the dex pc to zero when evaluating. 199 cur_regs->set_dex_pc(0); 200 201 EvalInfo<AddressType> eval_info{.loc_regs = &loc_regs, 202 .cie = cie, 203 .regular_memory = regular_memory, 204 .regs_info = RegsInfo<AddressType>(cur_regs)}; 205 const DwarfLocation* loc = &cfa_entry->second; 206 // Only a few location types are valid for the cfa. 207 switch (loc->type) { 208 case DWARF_LOCATION_REGISTER: 209 if (loc->values[0] >= cur_regs->total_regs()) { 210 last_error_.code = DWARF_ERROR_ILLEGAL_VALUE; 211 return false; 212 } 213 eval_info.cfa = (*cur_regs)[loc->values[0]]; 214 eval_info.cfa += loc->values[1]; 215 break; 216 case DWARF_LOCATION_VAL_EXPRESSION: { 217 AddressType value; 218 if (!EvalExpression(*loc, regular_memory, &value, &eval_info.regs_info, nullptr)) { 219 return false; 220 } 221 // There is only one type of valid expression for CFA evaluation. 222 eval_info.cfa = value; 223 break; 224 } 225 default: 226 last_error_.code = DWARF_ERROR_ILLEGAL_VALUE; 227 return false; 228 } 229 230 for (const auto& entry : loc_regs) { 231 uint32_t reg = entry.first; 232 // Already handled the CFA register. 233 if (reg == CFA_REG) continue; 234 235 AddressType* reg_ptr; 236 if (reg >= cur_regs->total_regs()) { 237 // Skip this unknown register. 238 continue; 239 } 240 241 reg_ptr = eval_info.regs_info.Save(reg); 242 if (!EvalRegister(&entry.second, reg, reg_ptr, &eval_info)) { 243 return false; 244 } 245 } 246 247 // Find the return address location. 248 if (eval_info.return_address_undefined) { 249 cur_regs->set_pc(0); 250 } else { 251 cur_regs->set_pc((*cur_regs)[cie->return_address_register]); 252 } 253 254 // If the pc was set to zero, consider this the final frame. 255 *finished = (cur_regs->pc() == 0) ? true : false; 256 257 cur_regs->set_sp(eval_info.cfa); 258 259 return true; 260 } 261 262 template <typename AddressType> 263 const DwarfCie* DwarfSectionImpl<AddressType>::GetCie(uint64_t offset) { 264 auto cie_entry = cie_entries_.find(offset); 265 if (cie_entry != cie_entries_.end()) { 266 return &cie_entry->second; 267 } 268 DwarfCie* cie = &cie_entries_[offset]; 269 memory_.set_cur_offset(offset); 270 if (!FillInCie(cie)) { 271 // Erase the cached entry. 272 cie_entries_.erase(offset); 273 return nullptr; 274 } 275 return cie; 276 } 277 278 template <typename AddressType> 279 bool DwarfSectionImpl<AddressType>::FillInCie(DwarfCie* cie) { 280 uint32_t length32; 281 if (!memory_.ReadBytes(&length32, sizeof(length32))) { 282 last_error_.code = DWARF_ERROR_MEMORY_INVALID; 283 last_error_.address = memory_.cur_offset(); 284 return false; 285 } 286 // Set the default for the lsda encoding. 287 cie->lsda_encoding = DW_EH_PE_omit; 288 289 if (length32 == static_cast<uint32_t>(-1)) { 290 // 64 bit Cie 291 uint64_t length64; 292 if (!memory_.ReadBytes(&length64, sizeof(length64))) { 293 last_error_.code = DWARF_ERROR_MEMORY_INVALID; 294 last_error_.address = memory_.cur_offset(); 295 return false; 296 } 297 298 cie->cfa_instructions_end = memory_.cur_offset() + length64; 299 cie->fde_address_encoding = DW_EH_PE_sdata8; 300 301 uint64_t cie_id; 302 if (!memory_.ReadBytes(&cie_id, sizeof(cie_id))) { 303 last_error_.code = DWARF_ERROR_MEMORY_INVALID; 304 last_error_.address = memory_.cur_offset(); 305 return false; 306 } 307 if (cie_id != cie64_value_) { 308 // This is not a Cie, something has gone horribly wrong. 309 last_error_.code = DWARF_ERROR_ILLEGAL_VALUE; 310 return false; 311 } 312 } else { 313 // 32 bit Cie 314 cie->cfa_instructions_end = memory_.cur_offset() + length32; 315 cie->fde_address_encoding = DW_EH_PE_sdata4; 316 317 uint32_t cie_id; 318 if (!memory_.ReadBytes(&cie_id, sizeof(cie_id))) { 319 last_error_.code = DWARF_ERROR_MEMORY_INVALID; 320 last_error_.address = memory_.cur_offset(); 321 return false; 322 } 323 if (cie_id != cie32_value_) { 324 // This is not a Cie, something has gone horribly wrong. 325 last_error_.code = DWARF_ERROR_ILLEGAL_VALUE; 326 return false; 327 } 328 } 329 330 if (!memory_.ReadBytes(&cie->version, sizeof(cie->version))) { 331 last_error_.code = DWARF_ERROR_MEMORY_INVALID; 332 last_error_.address = memory_.cur_offset(); 333 return false; 334 } 335 336 if (cie->version != 1 && cie->version != 3 && cie->version != 4) { 337 // Unrecognized version. 338 last_error_.code = DWARF_ERROR_UNSUPPORTED_VERSION; 339 return false; 340 } 341 342 // Read the augmentation string. 343 char aug_value; 344 do { 345 if (!memory_.ReadBytes(&aug_value, 1)) { 346 last_error_.code = DWARF_ERROR_MEMORY_INVALID; 347 last_error_.address = memory_.cur_offset(); 348 return false; 349 } 350 cie->augmentation_string.push_back(aug_value); 351 } while (aug_value != '\0'); 352 353 if (cie->version == 4) { 354 // Skip the Address Size field since we only use it for validation. 355 memory_.set_cur_offset(memory_.cur_offset() + 1); 356 357 // Segment Size 358 if (!memory_.ReadBytes(&cie->segment_size, 1)) { 359 last_error_.code = DWARF_ERROR_MEMORY_INVALID; 360 last_error_.address = memory_.cur_offset(); 361 return false; 362 } 363 } 364 365 // Code Alignment Factor 366 if (!memory_.ReadULEB128(&cie->code_alignment_factor)) { 367 last_error_.code = DWARF_ERROR_MEMORY_INVALID; 368 last_error_.address = memory_.cur_offset(); 369 return false; 370 } 371 372 // Data Alignment Factor 373 if (!memory_.ReadSLEB128(&cie->data_alignment_factor)) { 374 last_error_.code = DWARF_ERROR_MEMORY_INVALID; 375 last_error_.address = memory_.cur_offset(); 376 return false; 377 } 378 379 if (cie->version == 1) { 380 // Return Address is a single byte. 381 uint8_t return_address_register; 382 if (!memory_.ReadBytes(&return_address_register, 1)) { 383 last_error_.code = DWARF_ERROR_MEMORY_INVALID; 384 last_error_.address = memory_.cur_offset(); 385 return false; 386 } 387 cie->return_address_register = return_address_register; 388 } else if (!memory_.ReadULEB128(&cie->return_address_register)) { 389 last_error_.code = DWARF_ERROR_MEMORY_INVALID; 390 last_error_.address = memory_.cur_offset(); 391 return false; 392 } 393 394 if (cie->augmentation_string[0] != 'z') { 395 cie->cfa_instructions_offset = memory_.cur_offset(); 396 return true; 397 } 398 399 uint64_t aug_length; 400 if (!memory_.ReadULEB128(&aug_length)) { 401 last_error_.code = DWARF_ERROR_MEMORY_INVALID; 402 last_error_.address = memory_.cur_offset(); 403 return false; 404 } 405 cie->cfa_instructions_offset = memory_.cur_offset() + aug_length; 406 407 for (size_t i = 1; i < cie->augmentation_string.size(); i++) { 408 switch (cie->augmentation_string[i]) { 409 case 'L': 410 if (!memory_.ReadBytes(&cie->lsda_encoding, 1)) { 411 last_error_.code = DWARF_ERROR_MEMORY_INVALID; 412 last_error_.address = memory_.cur_offset(); 413 return false; 414 } 415 break; 416 case 'P': { 417 uint8_t encoding; 418 if (!memory_.ReadBytes(&encoding, 1)) { 419 last_error_.code = DWARF_ERROR_MEMORY_INVALID; 420 last_error_.address = memory_.cur_offset(); 421 return false; 422 } 423 if (!memory_.ReadEncodedValue<AddressType>(encoding, &cie->personality_handler)) { 424 last_error_.code = DWARF_ERROR_MEMORY_INVALID; 425 last_error_.address = memory_.cur_offset(); 426 return false; 427 } 428 } break; 429 case 'R': 430 if (!memory_.ReadBytes(&cie->fde_address_encoding, 1)) { 431 last_error_.code = DWARF_ERROR_MEMORY_INVALID; 432 last_error_.address = memory_.cur_offset(); 433 return false; 434 } 435 break; 436 } 437 } 438 return true; 439 } 440 441 template <typename AddressType> 442 const DwarfFde* DwarfSectionImpl<AddressType>::GetFdeFromOffset(uint64_t offset) { 443 auto fde_entry = fde_entries_.find(offset); 444 if (fde_entry != fde_entries_.end()) { 445 return &fde_entry->second; 446 } 447 DwarfFde* fde = &fde_entries_[offset]; 448 memory_.set_cur_offset(offset); 449 if (!FillInFde(fde)) { 450 fde_entries_.erase(offset); 451 return nullptr; 452 } 453 return fde; 454 } 455 456 template <typename AddressType> 457 bool DwarfSectionImpl<AddressType>::FillInFde(DwarfFde* fde) { 458 uint32_t length32; 459 if (!memory_.ReadBytes(&length32, sizeof(length32))) { 460 last_error_.code = DWARF_ERROR_MEMORY_INVALID; 461 last_error_.address = memory_.cur_offset(); 462 return false; 463 } 464 465 if (length32 == static_cast<uint32_t>(-1)) { 466 // 64 bit Fde. 467 uint64_t length64; 468 if (!memory_.ReadBytes(&length64, sizeof(length64))) { 469 last_error_.code = DWARF_ERROR_MEMORY_INVALID; 470 last_error_.address = memory_.cur_offset(); 471 return false; 472 } 473 fde->cfa_instructions_end = memory_.cur_offset() + length64; 474 475 uint64_t value64; 476 if (!memory_.ReadBytes(&value64, sizeof(value64))) { 477 last_error_.code = DWARF_ERROR_MEMORY_INVALID; 478 last_error_.address = memory_.cur_offset(); 479 return false; 480 } 481 if (value64 == cie64_value_) { 482 // This is a Cie, this means something has gone wrong. 483 last_error_.code = DWARF_ERROR_ILLEGAL_VALUE; 484 return false; 485 } 486 487 // Get the Cie pointer, which is necessary to properly read the rest of 488 // of the Fde information. 489 fde->cie_offset = GetCieOffsetFromFde64(value64); 490 } else { 491 // 32 bit Fde. 492 fde->cfa_instructions_end = memory_.cur_offset() + length32; 493 494 uint32_t value32; 495 if (!memory_.ReadBytes(&value32, sizeof(value32))) { 496 last_error_.code = DWARF_ERROR_MEMORY_INVALID; 497 last_error_.address = memory_.cur_offset(); 498 return false; 499 } 500 if (value32 == cie32_value_) { 501 // This is a Cie, this means something has gone wrong. 502 last_error_.code = DWARF_ERROR_ILLEGAL_VALUE; 503 return false; 504 } 505 506 // Get the Cie pointer, which is necessary to properly read the rest of 507 // of the Fde information. 508 fde->cie_offset = GetCieOffsetFromFde32(value32); 509 } 510 uint64_t cur_offset = memory_.cur_offset(); 511 512 const DwarfCie* cie = GetCie(fde->cie_offset); 513 if (cie == nullptr) { 514 return false; 515 } 516 fde->cie = cie; 517 518 if (cie->segment_size != 0) { 519 // Skip over the segment selector for now. 520 cur_offset += cie->segment_size; 521 } 522 memory_.set_cur_offset(cur_offset); 523 524 if (!memory_.ReadEncodedValue<AddressType>(cie->fde_address_encoding & 0xf, &fde->pc_start)) { 525 last_error_.code = DWARF_ERROR_MEMORY_INVALID; 526 last_error_.address = memory_.cur_offset(); 527 return false; 528 } 529 fde->pc_start = AdjustPcFromFde(fde->pc_start); 530 531 if (!memory_.ReadEncodedValue<AddressType>(cie->fde_address_encoding & 0xf, &fde->pc_end)) { 532 last_error_.code = DWARF_ERROR_MEMORY_INVALID; 533 last_error_.address = memory_.cur_offset(); 534 return false; 535 } 536 fde->pc_end += fde->pc_start; 537 if (cie->augmentation_string.size() > 0 && cie->augmentation_string[0] == 'z') { 538 // Augmentation Size 539 uint64_t aug_length; 540 if (!memory_.ReadULEB128(&aug_length)) { 541 last_error_.code = DWARF_ERROR_MEMORY_INVALID; 542 last_error_.address = memory_.cur_offset(); 543 return false; 544 } 545 uint64_t cur_offset = memory_.cur_offset(); 546 547 if (!memory_.ReadEncodedValue<AddressType>(cie->lsda_encoding, &fde->lsda_address)) { 548 last_error_.code = DWARF_ERROR_MEMORY_INVALID; 549 last_error_.address = memory_.cur_offset(); 550 return false; 551 } 552 553 // Set our position to after all of the augmentation data. 554 memory_.set_cur_offset(cur_offset + aug_length); 555 } 556 fde->cfa_instructions_offset = memory_.cur_offset(); 557 558 return true; 559 } 560 561 template <typename AddressType> 562 bool DwarfSectionImpl<AddressType>::GetCfaLocationInfo(uint64_t pc, const DwarfFde* fde, 563 dwarf_loc_regs_t* loc_regs) { 564 DwarfCfa<AddressType> cfa(&memory_, fde); 565 566 // Look for the cached copy of the cie data. 567 auto reg_entry = cie_loc_regs_.find(fde->cie_offset); 568 if (reg_entry == cie_loc_regs_.end()) { 569 if (!cfa.GetLocationInfo(pc, fde->cie->cfa_instructions_offset, fde->cie->cfa_instructions_end, 570 loc_regs)) { 571 last_error_ = cfa.last_error(); 572 return false; 573 } 574 cie_loc_regs_[fde->cie_offset] = *loc_regs; 575 } 576 cfa.set_cie_loc_regs(&cie_loc_regs_[fde->cie_offset]); 577 if (!cfa.GetLocationInfo(pc, fde->cfa_instructions_offset, fde->cfa_instructions_end, loc_regs)) { 578 last_error_ = cfa.last_error(); 579 return false; 580 } 581 return true; 582 } 583 584 template <typename AddressType> 585 bool DwarfSectionImpl<AddressType>::Log(uint8_t indent, uint64_t pc, uint64_t load_bias, 586 const DwarfFde* fde) { 587 DwarfCfa<AddressType> cfa(&memory_, fde); 588 589 // Always print the cie information. 590 const DwarfCie* cie = fde->cie; 591 if (!cfa.Log(indent, pc, load_bias, cie->cfa_instructions_offset, cie->cfa_instructions_end)) { 592 last_error_ = cfa.last_error(); 593 return false; 594 } 595 if (!cfa.Log(indent, pc, load_bias, fde->cfa_instructions_offset, fde->cfa_instructions_end)) { 596 last_error_ = cfa.last_error(); 597 return false; 598 } 599 return true; 600 } 601 602 template <typename AddressType> 603 bool DwarfSectionImpl<AddressType>::Init(uint64_t offset, uint64_t size) { 604 entries_offset_ = offset; 605 entries_end_ = offset + size; 606 607 memory_.clear_func_offset(); 608 memory_.clear_text_offset(); 609 memory_.set_data_offset(offset); 610 memory_.set_cur_offset(offset); 611 memory_.set_pc_offset(offset); 612 613 return CreateSortedFdeList(); 614 } 615 616 template <typename AddressType> 617 bool DwarfSectionImpl<AddressType>::GetCieInfo(uint8_t* segment_size, uint8_t* encoding) { 618 uint8_t version; 619 if (!memory_.ReadBytes(&version, 1)) { 620 last_error_.code = DWARF_ERROR_MEMORY_INVALID; 621 last_error_.address = memory_.cur_offset(); 622 return false; 623 } 624 // Read the augmentation string. 625 std::vector<char> aug_string; 626 char aug_value; 627 bool get_encoding = false; 628 do { 629 if (!memory_.ReadBytes(&aug_value, 1)) { 630 last_error_.code = DWARF_ERROR_MEMORY_INVALID; 631 last_error_.address = memory_.cur_offset(); 632 return false; 633 } 634 if (aug_value == 'R') { 635 get_encoding = true; 636 } 637 aug_string.push_back(aug_value); 638 } while (aug_value != '\0'); 639 640 if (version == 4) { 641 // Skip the Address Size field. 642 memory_.set_cur_offset(memory_.cur_offset() + 1); 643 644 // Read the segment size. 645 if (!memory_.ReadBytes(segment_size, 1)) { 646 last_error_.code = DWARF_ERROR_MEMORY_INVALID; 647 last_error_.address = memory_.cur_offset(); 648 return false; 649 } 650 } else { 651 *segment_size = 0; 652 } 653 654 if (aug_string[0] != 'z' || !get_encoding) { 655 // No encoding 656 return true; 657 } 658 659 // Skip code alignment factor 660 uint8_t value; 661 do { 662 if (!memory_.ReadBytes(&value, 1)) { 663 last_error_.code = DWARF_ERROR_MEMORY_INVALID; 664 last_error_.address = memory_.cur_offset(); 665 return false; 666 } 667 } while (value & 0x80); 668 669 // Skip data alignment factor 670 do { 671 if (!memory_.ReadBytes(&value, 1)) { 672 last_error_.code = DWARF_ERROR_MEMORY_INVALID; 673 last_error_.address = memory_.cur_offset(); 674 return false; 675 } 676 } while (value & 0x80); 677 678 if (version == 1) { 679 // Skip return address register. 680 memory_.set_cur_offset(memory_.cur_offset() + 1); 681 } else { 682 // Skip return address register. 683 do { 684 if (!memory_.ReadBytes(&value, 1)) { 685 last_error_.code = DWARF_ERROR_MEMORY_INVALID; 686 last_error_.address = memory_.cur_offset(); 687 return false; 688 } 689 } while (value & 0x80); 690 } 691 692 // Skip the augmentation length. 693 do { 694 if (!memory_.ReadBytes(&value, 1)) { 695 last_error_.code = DWARF_ERROR_MEMORY_INVALID; 696 last_error_.address = memory_.cur_offset(); 697 return false; 698 } 699 } while (value & 0x80); 700 701 for (size_t i = 1; i < aug_string.size(); i++) { 702 if (aug_string[i] == 'R') { 703 if (!memory_.ReadBytes(encoding, 1)) { 704 last_error_.code = DWARF_ERROR_MEMORY_INVALID; 705 last_error_.address = memory_.cur_offset(); 706 return false; 707 } 708 // Got the encoding, that's all we are looking for. 709 return true; 710 } else if (aug_string[i] == 'L') { 711 memory_.set_cur_offset(memory_.cur_offset() + 1); 712 } else if (aug_string[i] == 'P') { 713 uint8_t encoding; 714 if (!memory_.ReadBytes(&encoding, 1)) { 715 last_error_.code = DWARF_ERROR_MEMORY_INVALID; 716 last_error_.address = memory_.cur_offset(); 717 return false; 718 } 719 uint64_t value; 720 if (!memory_.template ReadEncodedValue<AddressType>(encoding, &value)) { 721 last_error_.code = DWARF_ERROR_MEMORY_INVALID; 722 last_error_.address = memory_.cur_offset(); 723 return false; 724 } 725 } 726 } 727 728 // It should be impossible to get here. 729 abort(); 730 } 731 732 template <typename AddressType> 733 bool DwarfSectionImpl<AddressType>::AddFdeInfo(uint64_t entry_offset, uint8_t segment_size, 734 uint8_t encoding) { 735 if (segment_size != 0) { 736 memory_.set_cur_offset(memory_.cur_offset() + 1); 737 } 738 739 uint64_t start; 740 if (!memory_.template ReadEncodedValue<AddressType>(encoding & 0xf, &start)) { 741 last_error_.code = DWARF_ERROR_MEMORY_INVALID; 742 last_error_.address = memory_.cur_offset(); 743 return false; 744 } 745 start = AdjustPcFromFde(start); 746 747 uint64_t length; 748 if (!memory_.template ReadEncodedValue<AddressType>(encoding & 0xf, &length)) { 749 last_error_.code = DWARF_ERROR_MEMORY_INVALID; 750 last_error_.address = memory_.cur_offset(); 751 return false; 752 } 753 if (length != 0) { 754 fdes_.emplace_back(entry_offset, start, length); 755 } 756 757 return true; 758 } 759 760 template <typename AddressType> 761 bool DwarfSectionImpl<AddressType>::CreateSortedFdeList() { 762 memory_.set_cur_offset(entries_offset_); 763 764 // Loop through all of the entries and read just enough to create 765 // a sorted list of pcs. 766 // This code assumes that first comes the cie, then the fdes that 767 // it applies to. 768 uint64_t cie_offset = 0; 769 uint8_t address_encoding; 770 uint8_t segment_size; 771 while (memory_.cur_offset() < entries_end_) { 772 uint64_t cur_entry_offset = memory_.cur_offset(); 773 774 // Figure out the entry length and type. 775 uint32_t value32; 776 if (!memory_.ReadBytes(&value32, sizeof(value32))) { 777 last_error_.code = DWARF_ERROR_MEMORY_INVALID; 778 last_error_.address = memory_.cur_offset(); 779 return false; 780 } 781 782 uint64_t next_entry_offset; 783 if (value32 == static_cast<uint32_t>(-1)) { 784 uint64_t value64; 785 if (!memory_.ReadBytes(&value64, sizeof(value64))) { 786 last_error_.code = DWARF_ERROR_MEMORY_INVALID; 787 last_error_.address = memory_.cur_offset(); 788 return false; 789 } 790 next_entry_offset = memory_.cur_offset() + value64; 791 792 // Read the Cie Id of a Cie or the pointer of the Fde. 793 if (!memory_.ReadBytes(&value64, sizeof(value64))) { 794 last_error_.code = DWARF_ERROR_MEMORY_INVALID; 795 last_error_.address = memory_.cur_offset(); 796 return false; 797 } 798 799 if (value64 == cie64_value_) { 800 // Cie 64 bit 801 address_encoding = DW_EH_PE_sdata8; 802 if (!GetCieInfo(&segment_size, &address_encoding)) { 803 return false; 804 } 805 cie_offset = cur_entry_offset; 806 } else { 807 uint64_t last_cie_offset = GetCieOffsetFromFde64(value64); 808 if (last_cie_offset != cie_offset) { 809 // This means that this Fde is not following the Cie. 810 last_error_.code = DWARF_ERROR_ILLEGAL_VALUE; 811 return false; 812 } 813 814 // Fde 64 bit 815 if (!AddFdeInfo(cur_entry_offset, segment_size, address_encoding)) { 816 return false; 817 } 818 } 819 } else { 820 next_entry_offset = memory_.cur_offset() + value32; 821 822 // Read the Cie Id of a Cie or the pointer of the Fde. 823 if (!memory_.ReadBytes(&value32, sizeof(value32))) { 824 last_error_.code = DWARF_ERROR_MEMORY_INVALID; 825 last_error_.address = memory_.cur_offset(); 826 return false; 827 } 828 829 if (value32 == cie32_value_) { 830 // Cie 32 bit 831 address_encoding = DW_EH_PE_sdata4; 832 if (!GetCieInfo(&segment_size, &address_encoding)) { 833 return false; 834 } 835 cie_offset = cur_entry_offset; 836 } else { 837 uint64_t last_cie_offset = GetCieOffsetFromFde32(value32); 838 if (last_cie_offset != cie_offset) { 839 // This means that this Fde is not following the Cie. 840 last_error_.code = DWARF_ERROR_ILLEGAL_VALUE; 841 return false; 842 } 843 844 // Fde 32 bit 845 if (!AddFdeInfo(cur_entry_offset, segment_size, address_encoding)) { 846 return false; 847 } 848 } 849 } 850 851 if (next_entry_offset < memory_.cur_offset()) { 852 // Simply consider the processing done in this case. 853 break; 854 } 855 memory_.set_cur_offset(next_entry_offset); 856 } 857 858 // Sort the entries. 859 std::sort(fdes_.begin(), fdes_.end(), [](const FdeInfo& a, const FdeInfo& b) { 860 if (a.start == b.start) return a.end < b.end; 861 return a.start < b.start; 862 }); 863 864 fde_count_ = fdes_.size(); 865 866 return true; 867 } 868 869 template <typename AddressType> 870 bool DwarfSectionImpl<AddressType>::GetFdeOffsetFromPc(uint64_t pc, uint64_t* fde_offset) { 871 if (fde_count_ == 0) { 872 return false; 873 } 874 875 size_t first = 0; 876 size_t last = fde_count_; 877 while (first < last) { 878 size_t current = (first + last) / 2; 879 const FdeInfo* info = &fdes_[current]; 880 if (pc >= info->start && pc <= info->end) { 881 *fde_offset = info->offset; 882 return true; 883 } 884 885 if (pc < info->start) { 886 last = current; 887 } else { 888 first = current + 1; 889 } 890 } 891 return false; 892 } 893 894 template <typename AddressType> 895 const DwarfFde* DwarfSectionImpl<AddressType>::GetFdeFromIndex(size_t index) { 896 if (index >= fdes_.size()) { 897 return nullptr; 898 } 899 return this->GetFdeFromOffset(fdes_[index].offset); 900 } 901 902 // Explicitly instantiate DwarfSectionImpl 903 template class DwarfSectionImpl<uint32_t>; 904 template class DwarfSectionImpl<uint64_t>; 905 906 // Explicitly instantiate DwarfDebugFrame 907 template class DwarfDebugFrame<uint32_t>; 908 template class DwarfDebugFrame<uint64_t>; 909 910 // Explicitly instantiate DwarfEhFrame 911 template class DwarfEhFrame<uint32_t>; 912 template class DwarfEhFrame<uint64_t>; 913 914 } // namespace unwindstack 915