Index: courgette/disassembler_win32_x64.cc |
diff --git a/courgette/disassembler_win32_x64.cc b/courgette/disassembler_win32_x64.cc |
index ffa6c36a7aade5f0d7954149fc11bc667b91543c..0ea2b32368646455be913b55cafbddaf795c2eea 100644 |
--- a/courgette/disassembler_win32_x64.cc |
+++ b/courgette/disassembler_win32_x64.cc |
@@ -252,6 +252,9 @@ bool DisassemblerWin32X64::Disassemble(AssemblyProgram* target) { |
ParseRel32RelocsFromSections(); |
+ PrecomputeLabels(target); |
+ RemoveUnusedRel32Locations(target); |
+ |
if (!ParseFile(target)) |
return false; |
@@ -357,6 +360,25 @@ std::string DisassemblerWin32X64::SectionName(const Section* section) { |
return name; |
} |
+RvaVisitor* DisassemblerWin32X64::CreateAbs32TargetRvaVisitor() { |
+ return new RvaVisitor_Abs32(abs32_locations_, *this); |
+} |
+ |
+RvaVisitor* DisassemblerWin32X64::CreateRel32TargetRvaVisitor() { |
+ return new RvaVisitor_Rel32(rel32_locations_, *this); |
+} |
+ |
+void DisassemblerWin32X64::RemoveUnusedRel32Locations( |
+ AssemblyProgram* program) { |
+ auto cond = [this, program](RVA rva) -> bool { |
+ RVA target_rva = rva + 4 + Read32LittleEndian(RVAToPointer(rva)); |
+ return program->FindRel32Label(target_rva) == nullptr; |
+ }; |
+ rel32_locations_.erase( |
+ std::remove_if(rel32_locations_.begin(), rel32_locations_.end(), cond), |
+ rel32_locations_.end()); |
+} |
+ |
CheckBool DisassemblerWin32X64::ParseFile(AssemblyProgram* program) { |
// Walk all the bytes in the file, whether or not in a section. |
FileOffset file_offset = 0; |
@@ -614,7 +636,9 @@ CheckBool DisassemblerWin32X64::ParseFileRegion(const Section* section, |
DCHECK_NE(kNoRVA, target_rva); |
// TODO(sra): target could be Label+offset. It is not clear how to guess |
// which it might be. We assume offset==0. |
- if (!program->EmitAbs64(program->FindOrMakeAbs32Label(target_rva))) |
+ Label* label = program->FindAbs32Label(target_rva); |
+ DCHECK(label); |
+ if (!program->EmitAbs64(label)) |
return false; |
p += 8; |
continue; |
@@ -625,7 +649,9 @@ CheckBool DisassemblerWin32X64::ParseFileRegion(const Section* section, |
if (rel32_pos != rel32_locations_.end() && *rel32_pos == current_rva) { |
RVA target_rva = current_rva + 4 + Read32LittleEndian(p); |
- if (!program->EmitRel32(program->FindOrMakeRel32Label(target_rva))) |
+ Label* label = program->FindRel32Label(target_rva); |
+ DCHECK(label); |
+ if (!program->EmitRel32(label)) |
return false; |
p += 4; |
continue; |