Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(641)

Unified Diff: courgette/disassembler_win32.cc

Issue 2462993003: [Courgette] Refactor: Add and use Instruction*Receptor classes; call ParseFile() in 2 passes. (Closed)
Patch Set: Make AssemblyProgram::CreateInstruction*Receptor() return CheckBool. Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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();

Powered by Google App Engine
This is Rietveld 408576698