| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "courgette/disassembler_elf_32.h" | 5 #include "courgette/disassembler_elf_32.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <iterator> | 8 #include <iterator> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 316 std::vector<std::unique_ptr<TypedRVA>>* typed_rvas) const { | 316 std::vector<std::unique_ptr<TypedRVA>>* typed_rvas) const { |
| 317 for (auto& typed_rva : *typed_rvas) { | 317 for (auto& typed_rva : *typed_rvas) { |
| 318 FileOffset file_offset = RVAToFileOffset(typed_rva->rva()); | 318 FileOffset file_offset = RVAToFileOffset(typed_rva->rva()); |
| 319 if (file_offset == kNoFileOffset) | 319 if (file_offset == kNoFileOffset) |
| 320 return false; | 320 return false; |
| 321 typed_rva->set_file_offset(file_offset); | 321 typed_rva->set_file_offset(file_offset); |
| 322 } | 322 } |
| 323 return true; | 323 return true; |
| 324 } | 324 } |
| 325 | 325 |
| 326 CheckBool DisassemblerElf32::ParseAbs32Relocs() { |
| 327 abs32_locations_.clear(); |
| 328 |
| 329 // Loop through sections for relocation sections |
| 330 for (Elf32_Half section_id = 0; section_id < SectionHeaderCount(); |
| 331 ++section_id) { |
| 332 const Elf32_Shdr* section_header = SectionHeader(section_id); |
| 333 |
| 334 if (section_header->sh_type == SHT_REL) { |
| 335 const Elf32_Rel* relocs_table = |
| 336 reinterpret_cast<const Elf32_Rel*>(SectionBody(section_id)); |
| 337 |
| 338 int relocs_table_count = |
| 339 section_header->sh_size / section_header->sh_entsize; |
| 340 |
| 341 // Elf32_Word relocation_section_id = section_header->sh_info; |
| 342 |
| 343 // Loop through relocation objects in the relocation section |
| 344 for (int rel_id = 0; rel_id < relocs_table_count; ++rel_id) { |
| 345 RVA rva; |
| 346 |
| 347 // Quite a few of these conversions fail, and we simply skip |
| 348 // them, that's okay. |
| 349 if (RelToRVA(relocs_table[rel_id], &rva) && CheckSection(rva)) |
| 350 abs32_locations_.push_back(rva); |
| 351 } |
| 352 } |
| 353 } |
| 354 |
| 355 std::sort(abs32_locations_.begin(), abs32_locations_.end()); |
| 356 DCHECK(abs32_locations_.empty() || abs32_locations_.back() != kUnassignedRVA); |
| 357 return true; |
| 358 } |
| 359 |
| 360 CheckBool DisassemblerElf32::ParseRel32RelocsFromSections() { |
| 361 rel32_locations_.clear(); |
| 362 bool found_rel32 = false; |
| 363 |
| 364 // Loop through sections for relocation sections |
| 365 for (Elf32_Half section_id = 0; section_id < SectionHeaderCount(); |
| 366 ++section_id) { |
| 367 const Elf32_Shdr* section_header = SectionHeader(section_id); |
| 368 |
| 369 // Some debug sections can have sh_type=SHT_PROGBITS but sh_addr=0. |
| 370 if (section_header->sh_type != SHT_PROGBITS || section_header->sh_addr == 0) |
| 371 continue; |
| 372 |
| 373 // Heuristic: Only consider ".text" section. |
| 374 std::string section_name; |
| 375 if (!SectionName(*section_header, §ion_name)) |
| 376 return false; |
| 377 if (section_name != ".text") |
| 378 continue; |
| 379 |
| 380 found_rel32 = true; |
| 381 if (!ParseRel32RelocsFromSection(section_header)) |
| 382 return false; |
| 383 } |
| 384 if (!found_rel32) |
| 385 VLOG(1) << "Warning: Found no rel32 addresses. Missing .text section?"; |
| 386 |
| 387 return true; |
| 388 } |
| 389 |
| 326 RvaVisitor* DisassemblerElf32::CreateAbs32TargetRvaVisitor() { | 390 RvaVisitor* DisassemblerElf32::CreateAbs32TargetRvaVisitor() { |
| 327 return new RvaVisitor_Abs32(abs32_locations_, *this); | 391 return new RvaVisitor_Abs32(abs32_locations_, *this); |
| 328 } | 392 } |
| 329 | 393 |
| 330 RvaVisitor* DisassemblerElf32::CreateRel32TargetRvaVisitor() { | 394 RvaVisitor* DisassemblerElf32::CreateRel32TargetRvaVisitor() { |
| 331 return new Elf32RvaVisitor_Rel32(rel32_locations_); | 395 return new Elf32RvaVisitor_Rel32(rel32_locations_); |
| 332 } | 396 } |
| 333 | 397 |
| 334 void DisassemblerElf32::RemoveUnusedRel32Locations(AssemblyProgram* program) { | 398 void DisassemblerElf32::RemoveUnusedRel32Locations(AssemblyProgram* program) { |
| 335 auto tail_it = rel32_locations_.begin(); | 399 auto tail_it = rel32_locations_.begin(); |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 534 const size_t len = end_file_offset - start_file_offset; | 598 const size_t len = end_file_offset - start_file_offset; |
| 535 | 599 |
| 536 if (!receptor->EmitMultipleBytes(FileOffsetToPointer(start_file_offset), | 600 if (!receptor->EmitMultipleBytes(FileOffsetToPointer(start_file_offset), |
| 537 len)) { | 601 len)) { |
| 538 return false; | 602 return false; |
| 539 } | 603 } |
| 540 | 604 |
| 541 return true; | 605 return true; |
| 542 } | 606 } |
| 543 | 607 |
| 544 CheckBool DisassemblerElf32::ParseAbs32Relocs() { | |
| 545 abs32_locations_.clear(); | |
| 546 | |
| 547 // Loop through sections for relocation sections | |
| 548 for (Elf32_Half section_id = 0; section_id < SectionHeaderCount(); | |
| 549 ++section_id) { | |
| 550 const Elf32_Shdr* section_header = SectionHeader(section_id); | |
| 551 | |
| 552 if (section_header->sh_type == SHT_REL) { | |
| 553 const Elf32_Rel* relocs_table = | |
| 554 reinterpret_cast<const Elf32_Rel*>(SectionBody(section_id)); | |
| 555 | |
| 556 int relocs_table_count = section_header->sh_size / | |
| 557 section_header->sh_entsize; | |
| 558 | |
| 559 // Elf32_Word relocation_section_id = section_header->sh_info; | |
| 560 | |
| 561 // Loop through relocation objects in the relocation section | |
| 562 for (int rel_id = 0; rel_id < relocs_table_count; ++rel_id) { | |
| 563 RVA rva; | |
| 564 | |
| 565 // Quite a few of these conversions fail, and we simply skip | |
| 566 // them, that's okay. | |
| 567 if (RelToRVA(relocs_table[rel_id], &rva) && CheckSection(rva)) | |
| 568 abs32_locations_.push_back(rva); | |
| 569 } | |
| 570 } | |
| 571 } | |
| 572 | |
| 573 std::sort(abs32_locations_.begin(), abs32_locations_.end()); | |
| 574 DCHECK(abs32_locations_.empty() || | |
| 575 abs32_locations_.back() != kUnassignedRVA); | |
| 576 return true; | |
| 577 } | |
| 578 | |
| 579 CheckBool DisassemblerElf32::CheckSection(RVA rva) { | 608 CheckBool DisassemblerElf32::CheckSection(RVA rva) { |
| 580 FileOffset file_offset = RVAToFileOffset(rva); | 609 FileOffset file_offset = RVAToFileOffset(rva); |
| 581 if (file_offset == kNoFileOffset) | 610 if (file_offset == kNoFileOffset) |
| 582 return false; | 611 return false; |
| 583 | 612 |
| 584 for (Elf32_Half section_id = 0; section_id < SectionHeaderCount(); | 613 for (Elf32_Half section_id = 0; section_id < SectionHeaderCount(); |
| 585 ++section_id) { | 614 ++section_id) { |
| 586 const Elf32_Shdr* section_header = SectionHeader(section_id); | 615 const Elf32_Shdr* section_header = SectionHeader(section_id); |
| 587 | 616 |
| 588 if (file_offset >= section_header->sh_offset && | 617 if (file_offset >= section_header->sh_offset && |
| 589 file_offset < (section_header->sh_offset + section_header->sh_size)) { | 618 file_offset < (section_header->sh_offset + section_header->sh_size)) { |
| 590 switch (section_header->sh_type) { | 619 switch (section_header->sh_type) { |
| 591 case SHT_REL: // Falls through. | 620 case SHT_REL: // Falls through. |
| 592 case SHT_PROGBITS: | 621 case SHT_PROGBITS: |
| 593 return true; | 622 return true; |
| 594 } | 623 } |
| 595 } | 624 } |
| 596 } | 625 } |
| 597 | 626 |
| 598 return false; | 627 return false; |
| 599 } | 628 } |
| 600 | 629 |
| 601 CheckBool DisassemblerElf32::ParseRel32RelocsFromSections() { | |
| 602 rel32_locations_.clear(); | |
| 603 bool found_rel32 = false; | |
| 604 | |
| 605 // Loop through sections for relocation sections | |
| 606 for (Elf32_Half section_id = 0; section_id < SectionHeaderCount(); | |
| 607 ++section_id) { | |
| 608 const Elf32_Shdr* section_header = SectionHeader(section_id); | |
| 609 | |
| 610 // Some debug sections can have sh_type=SHT_PROGBITS but sh_addr=0. | |
| 611 if (section_header->sh_type != SHT_PROGBITS || | |
| 612 section_header->sh_addr == 0) | |
| 613 continue; | |
| 614 | |
| 615 // Heuristic: Only consider ".text" section. | |
| 616 std::string section_name; | |
| 617 if (!SectionName(*section_header, §ion_name)) | |
| 618 return false; | |
| 619 if (section_name != ".text") | |
| 620 continue; | |
| 621 | |
| 622 found_rel32 = true; | |
| 623 if (!ParseRel32RelocsFromSection(section_header)) | |
| 624 return false; | |
| 625 } | |
| 626 if (!found_rel32) | |
| 627 VLOG(1) << "Warning: Found no rel32 addresses. Missing .text section?"; | |
| 628 | |
| 629 return true; | |
| 630 } | |
| 631 | |
| 632 } // namespace courgette | 630 } // namespace courgette |
| OLD | NEW |