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 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
174 return false; | 174 return false; |
175 | 175 |
176 PrecomputeLabels(program); | 176 PrecomputeLabels(program); |
177 RemoveUnusedRel32Locations(program); | 177 RemoveUnusedRel32Locations(program); |
178 | 178 |
179 if (!program->GenerateInstructions( | 179 if (!program->GenerateInstructions( |
180 base::Bind(&DisassemblerElf32::ParseFile, base::Unretained(this)))) { | 180 base::Bind(&DisassemblerElf32::ParseFile, base::Unretained(this)))) { |
181 return false; | 181 return false; |
182 } | 182 } |
183 | 183 |
184 // Finally sort rel32 locations. | |
185 std::sort(rel32_locations_.begin(), | |
186 rel32_locations_.end(), | |
187 TypedRVA::IsLessThanByRVA); | |
188 DCHECK(rel32_locations_.empty() || | |
189 rel32_locations_.back()->rva() != kUnassignedRVA); | |
190 | |
191 program->DefaultAssignIndexes(); | 184 program->DefaultAssignIndexes(); |
192 return true; | 185 return true; |
193 } | 186 } |
194 | 187 |
195 CheckBool DisassemblerElf32::IsValidTargetRVA(RVA rva) const { | 188 CheckBool DisassemblerElf32::IsValidTargetRVA(RVA rva) const { |
196 if (rva == kUnassignedRVA) | 189 if (rva == kUnassignedRVA) |
197 return false; | 190 return false; |
198 | 191 |
199 // |rva| is valid if it's contained in any program segment. | 192 // |rva| is valid if it's contained in any program segment. |
200 for (Elf32_Half segment_id = 0; segment_id < ProgramSegmentHeaderCount(); | 193 for (Elf32_Half segment_id = 0; segment_id < ProgramSegmentHeaderCount(); |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
377 if (section_name != ".text") | 370 if (section_name != ".text") |
378 continue; | 371 continue; |
379 | 372 |
380 found_rel32 = true; | 373 found_rel32 = true; |
381 if (!ParseRel32RelocsFromSection(section_header)) | 374 if (!ParseRel32RelocsFromSection(section_header)) |
382 return false; | 375 return false; |
383 } | 376 } |
384 if (!found_rel32) | 377 if (!found_rel32) |
385 VLOG(1) << "Warning: Found no rel32 addresses. Missing .text section?"; | 378 VLOG(1) << "Warning: Found no rel32 addresses. Missing .text section?"; |
386 | 379 |
| 380 std::sort(rel32_locations_.begin(), rel32_locations_.end(), |
| 381 TypedRVA::IsLessThanByRVA); |
| 382 DCHECK(rel32_locations_.empty() || |
| 383 rel32_locations_.back()->rva() != kUnassignedRVA); |
| 384 |
387 return true; | 385 return true; |
388 } | 386 } |
389 | 387 |
390 RvaVisitor* DisassemblerElf32::CreateAbs32TargetRvaVisitor() { | 388 RvaVisitor* DisassemblerElf32::CreateAbs32TargetRvaVisitor() { |
391 return new RvaVisitor_Abs32(abs32_locations_, *this); | 389 return new RvaVisitor_Abs32(abs32_locations_, *this); |
392 } | 390 } |
393 | 391 |
394 RvaVisitor* DisassemblerElf32::CreateRel32TargetRvaVisitor() { | 392 RvaVisitor* DisassemblerElf32::CreateRel32TargetRvaVisitor() { |
395 return new Elf32RvaVisitor_Rel32(rel32_locations_); | 393 return new Elf32RvaVisitor_Rel32(rel32_locations_); |
396 } | 394 } |
(...skipping 14 matching lines...) Expand all Loading... |
411 } | 409 } |
412 } | 410 } |
413 rel32_locations_.resize(std::distance(rel32_locations_.begin(), tail_it)); | 411 rel32_locations_.resize(std::distance(rel32_locations_.begin(), tail_it)); |
414 } | 412 } |
415 | 413 |
416 CheckBool DisassemblerElf32::ParseFile(AssemblyProgram* program, | 414 CheckBool DisassemblerElf32::ParseFile(AssemblyProgram* program, |
417 InstructionReceptor* receptor) const { | 415 InstructionReceptor* receptor) const { |
418 // Walk all the bytes in the file, whether or not in a section. | 416 // Walk all the bytes in the file, whether or not in a section. |
419 FileOffset file_offset = 0; | 417 FileOffset file_offset = 0; |
420 | 418 |
421 std::vector<FileOffset> abs_offsets; | |
422 | |
423 // File parsing follows file offset order, and we visit abs32 and rel32 | 419 // File parsing follows file offset order, and we visit abs32 and rel32 |
424 // locations in lockstep. Therefore we need to extract and sort file offsets | 420 // locations in lockstep. Therefore we need to extract and sort file offsets |
425 // of all abs32 and rel32 locations. | 421 // of all abs32 and rel32 locations. For abs32, we copy the offsets to a new |
| 422 // array. |
| 423 std::vector<FileOffset> abs_offsets; |
426 if (!RVAsToFileOffsets(abs32_locations_, &abs_offsets)) | 424 if (!RVAsToFileOffsets(abs32_locations_, &abs_offsets)) |
427 return false; | 425 return false; |
428 std::sort(abs32_locations_.begin(), abs32_locations_.end()); | 426 std::sort(abs_offsets.begin(), abs_offsets.end()); |
429 | 427 |
| 428 // For rel32, TypedRVA (rather than raw offset) is stored, so sort-by-offset |
| 429 // is performed in place to save memory. At the end of function we will |
| 430 // sort-by-RVA. |
430 if (!RVAsToFileOffsets(&rel32_locations_)) | 431 if (!RVAsToFileOffsets(&rel32_locations_)) |
431 return false; | 432 return false; |
432 std::sort(rel32_locations_.begin(), | 433 std::sort(rel32_locations_.begin(), |
433 rel32_locations_.end(), | 434 rel32_locations_.end(), |
434 TypedRVA::IsLessThanByFileOffset); | 435 TypedRVA::IsLessThanByFileOffset); |
435 | 436 |
436 std::vector<FileOffset>::iterator current_abs_offset = abs_offsets.begin(); | 437 std::vector<FileOffset>::iterator current_abs_offset = abs_offsets.begin(); |
437 std::vector<FileOffset>::iterator end_abs_offset = abs_offsets.end(); | 438 std::vector<FileOffset>::iterator end_abs_offset = abs_offsets.end(); |
438 | 439 |
439 std::vector<std::unique_ptr<TypedRVA>>::iterator current_rel = | 440 std::vector<std::unique_ptr<TypedRVA>>::iterator current_rel = |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
489 << section_header->sh_type; | 490 << section_header->sh_type; |
490 } | 491 } |
491 break; | 492 break; |
492 } | 493 } |
493 } | 494 } |
494 | 495 |
495 // Rest of the file past the last section | 496 // Rest of the file past the last section |
496 if (!ParseSimpleRegion(file_offset, length(), receptor)) | 497 if (!ParseSimpleRegion(file_offset, length(), receptor)) |
497 return false; | 498 return false; |
498 | 499 |
| 500 // Restore original rel32 location order and sort by RVA order. |
| 501 std::sort(rel32_locations_.begin(), rel32_locations_.end(), |
| 502 TypedRVA::IsLessThanByRVA); |
| 503 |
499 // Make certain we consume all of the relocations as expected | 504 // Make certain we consume all of the relocations as expected |
500 return (current_abs_offset == end_abs_offset); | 505 return (current_abs_offset == end_abs_offset); |
501 } | 506 } |
502 | 507 |
503 CheckBool DisassemblerElf32::ParseProgbitsSection( | 508 CheckBool DisassemblerElf32::ParseProgbitsSection( |
504 const Elf32_Shdr* section_header, | 509 const Elf32_Shdr* section_header, |
505 std::vector<FileOffset>::iterator* current_abs_offset, | 510 std::vector<FileOffset>::iterator* current_abs_offset, |
506 std::vector<FileOffset>::iterator end_abs_offset, | 511 std::vector<FileOffset>::iterator end_abs_offset, |
507 std::vector<std::unique_ptr<TypedRVA>>::iterator* current_rel, | 512 std::vector<std::unique_ptr<TypedRVA>>::iterator* current_rel, |
508 std::vector<std::unique_ptr<TypedRVA>>::iterator end_rel, | 513 std::vector<std::unique_ptr<TypedRVA>>::iterator end_rel, |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
621 case SHT_PROGBITS: | 626 case SHT_PROGBITS: |
622 return true; | 627 return true; |
623 } | 628 } |
624 } | 629 } |
625 } | 630 } |
626 | 631 |
627 return false; | 632 return false; |
628 } | 633 } |
629 | 634 |
630 } // namespace courgette | 635 } // namespace courgette |
OLD | NEW |