Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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_win32_x86.h" | 5 #include "courgette/disassembler_win32_x86.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 245 if (!ok()) | 245 if (!ok()) |
| 246 return false; | 246 return false; |
| 247 | 247 |
| 248 target->set_image_base(image_base()); | 248 target->set_image_base(image_base()); |
| 249 | 249 |
| 250 if (!ParseAbs32Relocs()) | 250 if (!ParseAbs32Relocs()) |
| 251 return false; | 251 return false; |
| 252 | 252 |
| 253 ParseRel32RelocsFromSections(); | 253 ParseRel32RelocsFromSections(); |
| 254 | 254 |
| 255 PrecomputeLabels(target); | |
| 256 RemoveUnusedRel32Locations(target); | |
| 257 | |
| 255 if (!ParseFile(target)) | 258 if (!ParseFile(target)) |
| 256 return false; | 259 return false; |
| 257 | 260 |
| 258 target->DefaultAssignIndexes(); | 261 target->DefaultAssignIndexes(); |
| 259 | 262 |
| 260 return true; | 263 return true; |
| 261 } | 264 } |
| 262 | 265 |
| 263 //////////////////////////////////////////////////////////////////////////////// | 266 //////////////////////////////////////////////////////////////////////////////// |
| 264 | 267 |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 355 | 358 |
| 356 std::string DisassemblerWin32X86::SectionName(const Section* section) { | 359 std::string DisassemblerWin32X86::SectionName(const Section* section) { |
| 357 if (section == nullptr) | 360 if (section == nullptr) |
| 358 return "<none>"; | 361 return "<none>"; |
| 359 char name[9]; | 362 char name[9]; |
| 360 memcpy(name, section->name, 8); | 363 memcpy(name, section->name, 8); |
| 361 name[8] = '\0'; // Ensure termination. | 364 name[8] = '\0'; // Ensure termination. |
| 362 return name; | 365 return name; |
| 363 } | 366 } |
| 364 | 367 |
| 368 RvaVisitor* DisassemblerWin32X86::CreateAbs32TargetRvaVisitor() { | |
| 369 return new RvaVisitor_Abs32(abs32_locations_, *this); | |
| 370 } | |
| 371 | |
| 372 RvaVisitor* DisassemblerWin32X86::CreateRel32TargetRvaVisitor() { | |
| 373 return new RvaVisitor_Rel32(rel32_locations_, *this); | |
| 374 } | |
| 375 | |
| 376 void DisassemblerWin32X86::RemoveUnusedRel32Locations( | |
|
Will Harris
2016/05/04 18:02:26
hmm I wonder if a future refactor could introduce
huangs
2016/05/04 19:33:59
Yup! That's planned in go/courgette-ideas-2016 un
| |
| 377 AssemblyProgram* program) { | |
| 378 auto cond = [this, program](RVA rva) -> bool { | |
| 379 RVA target_rva = rva + 4 + Read32LittleEndian(RVAToPointer(rva)); | |
|
Will Harris
2016/05/04 18:02:26
can you explain this +4?
huangs
2016/05/04 19:33:59
Added comment. Also updating rel32_finder_win32_x8
| |
| 380 return program->FindRel32Label(target_rva) == nullptr; | |
| 381 }; | |
| 382 rel32_locations_.erase( | |
| 383 std::remove_if(rel32_locations_.begin(), rel32_locations_.end(), cond), | |
| 384 rel32_locations_.end()); | |
| 385 } | |
| 386 | |
| 365 CheckBool DisassemblerWin32X86::ParseFile(AssemblyProgram* program) { | 387 CheckBool DisassemblerWin32X86::ParseFile(AssemblyProgram* program) { |
| 366 // Walk all the bytes in the file, whether or not in a section. | 388 // Walk all the bytes in the file, whether or not in a section. |
| 367 FileOffset file_offset = 0; | 389 FileOffset file_offset = 0; |
| 368 while (file_offset < length()) { | 390 while (file_offset < length()) { |
| 369 const Section* section = FindNextSection(file_offset); | 391 const Section* section = FindNextSection(file_offset); |
| 370 if (section == nullptr) { | 392 if (section == nullptr) { |
| 371 // No more sections. There should not be extra stuff following last | 393 // No more sections. There should not be extra stuff following last |
| 372 // section. | 394 // section. |
| 373 // ParseNonSectionFileRegion(file_offset, pe_info().length(), program); | 395 // ParseNonSectionFileRegion(file_offset, pe_info().length(), program); |
| 374 break; | 396 break; |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 536 } | 558 } |
| 537 | 559 |
| 538 while (abs32_pos != abs32_locations_.end() && *abs32_pos < current_rva) | 560 while (abs32_pos != abs32_locations_.end() && *abs32_pos < current_rva) |
| 539 ++abs32_pos; | 561 ++abs32_pos; |
| 540 | 562 |
| 541 if (abs32_pos != abs32_locations_.end() && *abs32_pos == current_rva) { | 563 if (abs32_pos != abs32_locations_.end() && *abs32_pos == current_rva) { |
| 542 RVA target_rva = PointerToTargetRVA(p); | 564 RVA target_rva = PointerToTargetRVA(p); |
| 543 DCHECK_NE(kNoRVA, target_rva); | 565 DCHECK_NE(kNoRVA, target_rva); |
| 544 // TODO(sra): target could be Label+offset. It is not clear how to guess | 566 // TODO(sra): target could be Label+offset. It is not clear how to guess |
| 545 // which it might be. We assume offset==0. | 567 // which it might be. We assume offset==0. |
| 546 if (!program->EmitAbs32(program->FindOrMakeAbs32Label(target_rva))) | 568 Label* label = program->FindAbs32Label(target_rva); |
| 569 DCHECK(label); | |
| 570 if (!program->EmitAbs32(label)) | |
| 547 return false; | 571 return false; |
| 548 p += 4; | 572 p += 4; |
| 549 continue; | 573 continue; |
| 550 } | 574 } |
| 551 | 575 |
| 552 while (rel32_pos != rel32_locations_.end() && *rel32_pos < current_rva) | 576 while (rel32_pos != rel32_locations_.end() && *rel32_pos < current_rva) |
| 553 ++rel32_pos; | 577 ++rel32_pos; |
| 554 | 578 |
| 555 if (rel32_pos != rel32_locations_.end() && *rel32_pos == current_rva) { | 579 if (rel32_pos != rel32_locations_.end() && *rel32_pos == current_rva) { |
| 556 RVA target_rva = current_rva + 4 + Read32LittleEndian(p); | 580 RVA target_rva = current_rva + 4 + Read32LittleEndian(p); |
| 557 if (!program->EmitRel32(program->FindOrMakeRel32Label(target_rva))) | 581 Label* label = program->FindRel32Label(target_rva); |
| 582 DCHECK(label); | |
| 583 if (!program->EmitRel32(label)) | |
| 558 return false; | 584 return false; |
| 559 p += 4; | 585 p += 4; |
| 560 continue; | 586 continue; |
| 561 } | 587 } |
| 562 | 588 |
| 563 if (incomplete_disassembly_) { | 589 if (incomplete_disassembly_) { |
| 564 if ((abs32_pos == abs32_locations_.end() || end_rva <= *abs32_pos) && | 590 if ((abs32_pos == abs32_locations_.end() || end_rva <= *abs32_pos) && |
| 565 (rel32_pos == rel32_locations_.end() || end_rva <= *rel32_pos) && | 591 (rel32_pos == rel32_locations_.end() || end_rva <= *rel32_pos) && |
| 566 (end_rva <= relocs_start_rva || current_rva >= relocs_start_rva)) { | 592 (end_rva <= relocs_start_rva || current_rva >= relocs_start_rva)) { |
| 567 // No more relocs in this section, don't bother encoding bytes. | 593 // No more relocs in this section, don't bother encoding bytes. |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 679 directory->size_ = static_cast<uint32_t>(size); | 705 directory->size_ = static_cast<uint32_t>(size); |
| 680 return true; | 706 return true; |
| 681 } else { | 707 } else { |
| 682 directory->address_ = 0; | 708 directory->address_ = 0; |
| 683 directory->size_ = 0; | 709 directory->size_ = 0; |
| 684 return true; | 710 return true; |
| 685 } | 711 } |
| 686 } | 712 } |
| 687 | 713 |
| 688 } // namespace courgette | 714 } // namespace courgette |
| OLD | NEW |