| Index: courgette/disassembler_win32.cc
|
| diff --git a/courgette/disassembler_win32.cc b/courgette/disassembler_win32.cc
|
| index c039dd346a60fb5722aa976ed782c65596941279..b7dd7a9d53c84c9fbf97a10dbc89bebecc8c6a2c 100644
|
| --- a/courgette/disassembler_win32.cc
|
| +++ b/courgette/disassembler_win32.cc
|
| @@ -237,8 +237,18 @@ bool DisassemblerWin32::Disassemble(AssemblyProgram* target) {
|
| PrecomputeLabels(target);
|
| RemoveUnusedRel32Locations(target);
|
|
|
| - if (!ParseFile(target))
|
| + // Pass 1: Count the space needed to store instructions.
|
| + InstructionCountReceptor* count_receptor = nullptr;
|
| + if (!target->CreateInstructionCountReceptor(&count_receptor) ||
|
| + !ParseFile(target, count_receptor)) {
|
| return false;
|
| + }
|
| + // Pass 2: Emit all instructions.
|
| + InstructionStoreReceptor* store_receptor = nullptr;
|
| + if (!target->CreateInstructionStoreReceptor(&store_receptor) ||
|
| + !ParseFile(target, store_receptor)) {
|
| + return false;
|
| + }
|
|
|
| target->DefaultAssignIndexes();
|
|
|
| @@ -388,7 +398,8 @@ void DisassemblerWin32::RemoveUnusedRel32Locations(
|
| rel32_locations_.end());
|
| }
|
|
|
| -CheckBool DisassemblerWin32::ParseFile(AssemblyProgram* program) {
|
| +CheckBool DisassemblerWin32::ParseFile(AssemblyProgram* program,
|
| + InstructionReceptor* receptor) const {
|
| // Walk all the bytes in the file, whether or not in a section.
|
| FileOffset file_offset = 0;
|
| while (file_offset < length()) {
|
| @@ -396,20 +407,20 @@ CheckBool DisassemblerWin32::ParseFile(AssemblyProgram* program) {
|
| if (section == nullptr) {
|
| // No more sections. There should not be extra stuff following last
|
| // section.
|
| - // ParseNonSectionFileRegion(file_offset, pe_info().length(), program);
|
| + // ParseNonSectionFileRegion(file_offset, pe_info().length(), receptor);
|
| break;
|
| }
|
| if (file_offset < section->file_offset_of_raw_data) {
|
| FileOffset section_start_offset = section->file_offset_of_raw_data;
|
| if (!ParseNonSectionFileRegion(file_offset, section_start_offset,
|
| - program)) {
|
| + receptor)) {
|
| return false;
|
| }
|
|
|
| file_offset = section_start_offset;
|
| }
|
| FileOffset end = file_offset + section->size_of_raw_data;
|
| - if (!ParseFileRegion(section, file_offset, end, program))
|
| + if (!ParseFileRegion(section, file_offset, end, program, receptor))
|
| return false;
|
| file_offset = end;
|
| }
|
| @@ -479,13 +490,13 @@ void DisassemblerWin32::ParseRel32RelocsFromSections() {
|
| CheckBool DisassemblerWin32::ParseNonSectionFileRegion(
|
| FileOffset start_file_offset,
|
| FileOffset end_file_offset,
|
| - AssemblyProgram* program) {
|
| + InstructionReceptor* receptor) const {
|
| if (incomplete_disassembly_)
|
| return true;
|
|
|
| if (end_file_offset > start_file_offset) {
|
| - if (!program->EmitBytesInstruction(FileOffsetToPointer(start_file_offset),
|
| - end_file_offset - start_file_offset)) {
|
| + if (!receptor->EmitMultipleBytes(FileOffsetToPointer(start_file_offset),
|
| + end_file_offset - start_file_offset)) {
|
| return false;
|
| }
|
| }
|
| @@ -493,10 +504,12 @@ CheckBool DisassemblerWin32::ParseNonSectionFileRegion(
|
| return true;
|
| }
|
|
|
| -CheckBool DisassemblerWin32::ParseFileRegion(const Section* section,
|
| - FileOffset start_file_offset,
|
| - FileOffset end_file_offset,
|
| - AssemblyProgram* program) {
|
| +CheckBool DisassemblerWin32::ParseFileRegion(
|
| + const Section* section,
|
| + FileOffset start_file_offset,
|
| + FileOffset end_file_offset,
|
| + AssemblyProgram* program,
|
| + InstructionReceptor* receptor) const {
|
| RVA relocs_start_rva = base_relocation_table().address_;
|
|
|
| const uint8_t* start_pointer = FileOffsetToPointer(start_file_offset);
|
| @@ -510,10 +523,10 @@ CheckBool DisassemblerWin32::ParseFileRegion(const Section* section,
|
| // subtract 'pointer_to_rva'.
|
| const uint8_t* const adjust_pointer_to_rva = start_pointer - start_rva;
|
|
|
| - std::vector<RVA>::iterator rel32_pos = rel32_locations_.begin();
|
| - std::vector<RVA>::iterator abs32_pos = abs32_locations_.begin();
|
| + std::vector<RVA>::const_iterator rel32_pos = rel32_locations_.begin();
|
| + std::vector<RVA>::const_iterator abs32_pos = abs32_locations_.begin();
|
|
|
| - if (!program->EmitOriginInstruction(start_rva))
|
| + if (!receptor->EmitOrigin(start_rva))
|
| return false;
|
|
|
| const uint8_t* p = start_pointer;
|
| @@ -525,7 +538,7 @@ CheckBool DisassemblerWin32::ParseFileRegion(const Section* section,
|
| // actually be anywhere. Make sure we skip it because we will regenerate it
|
| // during assembly.
|
| if (current_rva == relocs_start_rva) {
|
| - if (!program->EmitPeRelocsInstruction())
|
| + if (!receptor->EmitPeRelocs())
|
| return false;
|
| uint32_t relocs_size = base_relocation_table().size_;
|
| if (relocs_size) {
|
| @@ -544,7 +557,7 @@ CheckBool DisassemblerWin32::ParseFileRegion(const Section* section,
|
| // which it might be. We assume offset==0.
|
| Label* label = program->FindAbs32Label(target_rva);
|
| DCHECK(label);
|
| - if (!EmitAbs(label, program))
|
| + if (!EmitAbs(label, receptor))
|
| return false;
|
| p += kVAWidth;
|
| continue;
|
| @@ -558,7 +571,7 @@ CheckBool DisassemblerWin32::ParseFileRegion(const Section* section,
|
| RVA target_rva = current_rva + 4 + Read32LittleEndian(p);
|
| Label* label = program->FindRel32Label(target_rva);
|
| DCHECK(label);
|
| - if (!program->EmitRel32(label))
|
| + if (!receptor->EmitRel32(label))
|
| return false;
|
| p += 4;
|
| continue;
|
| @@ -573,7 +586,7 @@ CheckBool DisassemblerWin32::ParseFileRegion(const Section* section,
|
| }
|
| }
|
|
|
| - if (!program->EmitByteInstruction(*p))
|
| + if (!receptor->EmitSingleByte(*p))
|
| return false;
|
| p += 1;
|
| }
|
| @@ -587,7 +600,7 @@ CheckBool DisassemblerWin32::ParseFileRegion(const Section* section,
|
| // command-line configuration for this feature because this code has to be
|
| // small, which means compiled-out.
|
| void DisassemblerWin32::HistogramTargets(const char* kind,
|
| - const std::map<RVA, int>& map) {
|
| + const std::map<RVA, int>& map) const {
|
| int total = 0;
|
| std::map<int, std::vector<RVA>> h;
|
| for (std::map<RVA, int>::const_iterator p = map.begin(); p != map.end();
|
|
|