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(); |