Chromium Code Reviews| 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 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "courgette/assembly_program.h" | 10 #include "courgette/assembly_program.h" |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 162 | 162 |
| 163 if (!ParseAbs32Relocs()) | 163 if (!ParseAbs32Relocs()) |
| 164 return false; | 164 return false; |
| 165 | 165 |
| 166 if (!ParseRel32RelocsFromSections()) | 166 if (!ParseRel32RelocsFromSections()) |
| 167 return false; | 167 return false; |
| 168 | 168 |
| 169 if (!ParseFile(target)) | 169 if (!ParseFile(target)) |
| 170 return false; | 170 return false; |
| 171 | 171 |
| 172 std::sort(rel32_locations_.begin(), | |
| 173 rel32_locations_.end(), | |
| 174 TypedRVA::IsLessThanByRVA); | |
| 175 DCHECK(rel32_locations_.empty() || | |
| 176 rel32_locations_.back()->rva() != kUnassignedRVA); | |
| 177 | |
| 172 target->DefaultAssignIndexes(); | 178 target->DefaultAssignIndexes(); |
| 173 return true; | 179 return true; |
| 174 } | 180 } |
| 175 | 181 |
| 176 bool DisassemblerElf32::UpdateLength() { | 182 bool DisassemblerElf32::UpdateLength() { |
| 177 Elf32_Off result = 0; | 183 Elf32_Off result = 0; |
| 178 | 184 |
| 179 // Find the end of the last section | 185 // Find the end of the last section |
| 180 for (Elf32_Half section_id = 0; section_id < SectionHeaderCount(); | 186 for (Elf32_Half section_id = 0; section_id < SectionHeaderCount(); |
| 181 ++section_id) { | 187 ++section_id) { |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 276 } | 282 } |
| 277 return true; | 283 return true; |
| 278 } | 284 } |
| 279 | 285 |
| 280 CheckBool DisassemblerElf32::ParseFile(AssemblyProgram* program) { | 286 CheckBool DisassemblerElf32::ParseFile(AssemblyProgram* program) { |
| 281 // Walk all the bytes in the file, whether or not in a section. | 287 // Walk all the bytes in the file, whether or not in a section. |
| 282 FileOffset file_offset = 0; | 288 FileOffset file_offset = 0; |
| 283 | 289 |
| 284 std::vector<FileOffset> abs_offsets; | 290 std::vector<FileOffset> abs_offsets; |
| 285 | 291 |
| 292 // File parsing follows file offset order, and we visit abs32 and rel32 | |
| 293 // locations in lockstep. Therefore we need to extract and sort file offsets | |
| 294 // of all abs32 and rel32 locations. | |
| 286 if (!RVAsToFileOffsets(abs32_locations_, &abs_offsets)) | 295 if (!RVAsToFileOffsets(abs32_locations_, &abs_offsets)) |
| 287 return false; | 296 return false; |
| 297 std::sort(abs32_locations_.begin(), abs32_locations_.end()); | |
| 288 | 298 |
| 289 if (!RVAsToFileOffsets(&rel32_locations_)) | 299 if (!RVAsToFileOffsets(&rel32_locations_)) |
| 290 return false; | 300 return false; |
| 301 std::sort(rel32_locations_.begin(), | |
| 302 rel32_locations_.end(), | |
| 303 TypedRVA::IsLessThanByFileOffset); | |
| 291 | 304 |
| 292 std::vector<FileOffset>::iterator current_abs_offset = abs_offsets.begin(); | 305 std::vector<FileOffset>::iterator current_abs_offset = abs_offsets.begin(); |
| 306 std::vector<FileOffset>::iterator end_abs_offset = abs_offsets.end(); | |
| 307 | |
| 293 ScopedVector<TypedRVA>::iterator current_rel = rel32_locations_.begin(); | 308 ScopedVector<TypedRVA>::iterator current_rel = rel32_locations_.begin(); |
| 294 | |
| 295 std::vector<FileOffset>::iterator end_abs_offset = abs_offsets.end(); | |
| 296 ScopedVector<TypedRVA>::iterator end_rel = rel32_locations_.end(); | 309 ScopedVector<TypedRVA>::iterator end_rel = rel32_locations_.end(); |
| 297 | 310 |
| 298 // Visit section headers ordered by file offset. | 311 // Visit section headers ordered by file offset. |
| 299 for (Elf32_Half section_id : section_header_file_offset_order_) { | 312 for (Elf32_Half section_id : section_header_file_offset_order_) { |
| 300 const Elf32_Shdr* section_header = SectionHeader(section_id); | 313 const Elf32_Shdr* section_header = SectionHeader(section_id); |
| 301 | 314 |
| 302 if (section_header->sh_type == SHT_NOBITS) | 315 if (section_header->sh_type == SHT_NOBITS) |
| 303 continue; | 316 continue; |
| 304 | 317 |
| 305 if (!ParseSimpleRegion(file_offset, section_header->sh_offset, program)) | 318 if (!ParseSimpleRegion(file_offset, section_header->sh_offset, program)) |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 505 return true; | 518 return true; |
| 506 } | 519 } |
| 507 } | 520 } |
| 508 } | 521 } |
| 509 | 522 |
| 510 return false; | 523 return false; |
| 511 } | 524 } |
| 512 | 525 |
| 513 CheckBool DisassemblerElf32::ParseRel32RelocsFromSections() { | 526 CheckBool DisassemblerElf32::ParseRel32RelocsFromSections() { |
| 514 rel32_locations_.clear(); | 527 rel32_locations_.clear(); |
| 528 bool found_rel32 = false; | |
| 515 | 529 |
| 516 // Loop through sections for relocation sections | 530 // Loop through sections for relocation sections |
| 517 for (Elf32_Half section_id = 0; section_id < SectionHeaderCount(); | 531 for (Elf32_Half section_id = 0; section_id < SectionHeaderCount(); |
| 518 ++section_id) { | 532 ++section_id) { |
| 519 const Elf32_Shdr* section_header = SectionHeader(section_id); | 533 const Elf32_Shdr* section_header = SectionHeader(section_id); |
| 520 | 534 |
| 521 // TODO(huangs): Add better checks to skip non-code sections. | |
| 522 // Some debug sections can have sh_type=SHT_PROGBITS but sh_addr=0. | 535 // Some debug sections can have sh_type=SHT_PROGBITS but sh_addr=0. |
| 523 if (section_header->sh_type != SHT_PROGBITS || | 536 if (section_header->sh_type != SHT_PROGBITS || |
| 524 section_header->sh_addr == 0) | 537 section_header->sh_addr == 0) |
| 525 continue; | 538 continue; |
| 526 | 539 |
| 540 // Heuristic: Only consider ".text" section. | |
| 541 std::string section_name; | |
| 542 if (!SectionName(*section_header, §ion_name)) | |
| 543 return false; | |
| 544 if (section_name != ".text") | |
| 545 continue; | |
| 546 | |
| 547 found_rel32 = true; | |
| 527 if (!ParseRel32RelocsFromSection(section_header)) | 548 if (!ParseRel32RelocsFromSection(section_header)) |
| 528 return false; | 549 return false; |
| 529 } | 550 } |
| 551 if (!found_rel32) | |
| 552 VLOG(1) << "Warning: Found no rel32 addresses. Missing .text section?"; | |
|
Will Harris
2016/04/28 19:45:49
what does this warning mean if it's seen? is there
huangs
2016/04/28 19:53:45
The warning says "your ELF file is weird because i
Will Harris
2016/04/28 20:04:02
Acknowledged.
| |
| 530 | 553 |
| 531 std::sort(rel32_locations_.begin(), | |
| 532 rel32_locations_.end(), | |
| 533 TypedRVA::IsLessThan); | |
| 534 DCHECK(rel32_locations_.empty() || | |
| 535 rel32_locations_.back()->rva() != kUnassignedRVA); | |
| 536 return true; | 554 return true; |
| 537 } | 555 } |
| 538 | 556 |
| 539 } // namespace courgette | 557 } // namespace courgette |
| OLD | NEW |