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 |