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 |