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( |
| 377 AssemblyProgram* program) { |
| 378 auto cond = [this, program](RVA rva) -> bool { |
| 379 // + 4 since offset is relative to start of next instruction. |
| 380 RVA target_rva = rva + 4 + Read32LittleEndian(RVAToPointer(rva)); |
| 381 return program->FindRel32Label(target_rva) == nullptr; |
| 382 }; |
| 383 rel32_locations_.erase( |
| 384 std::remove_if(rel32_locations_.begin(), rel32_locations_.end(), cond), |
| 385 rel32_locations_.end()); |
| 386 } |
| 387 |
365 CheckBool DisassemblerWin32X86::ParseFile(AssemblyProgram* program) { | 388 CheckBool DisassemblerWin32X86::ParseFile(AssemblyProgram* program) { |
366 // Walk all the bytes in the file, whether or not in a section. | 389 // Walk all the bytes in the file, whether or not in a section. |
367 FileOffset file_offset = 0; | 390 FileOffset file_offset = 0; |
368 while (file_offset < length()) { | 391 while (file_offset < length()) { |
369 const Section* section = FindNextSection(file_offset); | 392 const Section* section = FindNextSection(file_offset); |
370 if (section == nullptr) { | 393 if (section == nullptr) { |
371 // No more sections. There should not be extra stuff following last | 394 // No more sections. There should not be extra stuff following last |
372 // section. | 395 // section. |
373 // ParseNonSectionFileRegion(file_offset, pe_info().length(), program); | 396 // ParseNonSectionFileRegion(file_offset, pe_info().length(), program); |
374 break; | 397 break; |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
536 } | 559 } |
537 | 560 |
538 while (abs32_pos != abs32_locations_.end() && *abs32_pos < current_rva) | 561 while (abs32_pos != abs32_locations_.end() && *abs32_pos < current_rva) |
539 ++abs32_pos; | 562 ++abs32_pos; |
540 | 563 |
541 if (abs32_pos != abs32_locations_.end() && *abs32_pos == current_rva) { | 564 if (abs32_pos != abs32_locations_.end() && *abs32_pos == current_rva) { |
542 RVA target_rva = PointerToTargetRVA(p); | 565 RVA target_rva = PointerToTargetRVA(p); |
543 DCHECK_NE(kNoRVA, target_rva); | 566 DCHECK_NE(kNoRVA, target_rva); |
544 // TODO(sra): target could be Label+offset. It is not clear how to guess | 567 // TODO(sra): target could be Label+offset. It is not clear how to guess |
545 // which it might be. We assume offset==0. | 568 // which it might be. We assume offset==0. |
546 if (!program->EmitAbs32(program->FindOrMakeAbs32Label(target_rva))) | 569 Label* label = program->FindAbs32Label(target_rva); |
| 570 DCHECK(label); |
| 571 if (!program->EmitAbs32(label)) |
547 return false; | 572 return false; |
548 p += 4; | 573 p += 4; |
549 continue; | 574 continue; |
550 } | 575 } |
551 | 576 |
552 while (rel32_pos != rel32_locations_.end() && *rel32_pos < current_rva) | 577 while (rel32_pos != rel32_locations_.end() && *rel32_pos < current_rva) |
553 ++rel32_pos; | 578 ++rel32_pos; |
554 | 579 |
555 if (rel32_pos != rel32_locations_.end() && *rel32_pos == current_rva) { | 580 if (rel32_pos != rel32_locations_.end() && *rel32_pos == current_rva) { |
| 581 // + 4 since offset is relative to start of next instruction. |
556 RVA target_rva = current_rva + 4 + Read32LittleEndian(p); | 582 RVA target_rva = current_rva + 4 + Read32LittleEndian(p); |
557 if (!program->EmitRel32(program->FindOrMakeRel32Label(target_rva))) | 583 Label* label = program->FindRel32Label(target_rva); |
| 584 DCHECK(label); |
| 585 if (!program->EmitRel32(label)) |
558 return false; | 586 return false; |
559 p += 4; | 587 p += 4; |
560 continue; | 588 continue; |
561 } | 589 } |
562 | 590 |
563 if (incomplete_disassembly_) { | 591 if (incomplete_disassembly_) { |
564 if ((abs32_pos == abs32_locations_.end() || end_rva <= *abs32_pos) && | 592 if ((abs32_pos == abs32_locations_.end() || end_rva <= *abs32_pos) && |
565 (rel32_pos == rel32_locations_.end() || end_rva <= *rel32_pos) && | 593 (rel32_pos == rel32_locations_.end() || end_rva <= *rel32_pos) && |
566 (end_rva <= relocs_start_rva || current_rva >= relocs_start_rva)) { | 594 (end_rva <= relocs_start_rva || current_rva >= relocs_start_rva)) { |
567 // No more relocs in this section, don't bother encoding bytes. | 595 // 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); | 707 directory->size_ = static_cast<uint32_t>(size); |
680 return true; | 708 return true; |
681 } else { | 709 } else { |
682 directory->address_ = 0; | 710 directory->address_ = 0; |
683 directory->size_ = 0; | 711 directory->size_ = 0; |
684 return true; | 712 return true; |
685 } | 713 } |
686 } | 714 } |
687 | 715 |
688 } // namespace courgette | 716 } // namespace courgette |
OLD | NEW |