| Index: courgette/disassembler_win32_x86.cc
|
| diff --git a/courgette/disassembler_win32_x86.cc b/courgette/disassembler_win32_x86.cc
|
| index 974e864033d433bd5443e5ccd70d55036efe06d0..fc3f921d7296ca56a88be3a6a4195d3bf93fc45c 100644
|
| --- a/courgette/disassembler_win32_x86.cc
|
| +++ b/courgette/disassembler_win32_x86.cc
|
| @@ -252,6 +252,9 @@ bool DisassemblerWin32X86::Disassemble(AssemblyProgram* target) {
|
|
|
| ParseRel32RelocsFromSections();
|
|
|
| + PrecomputeLabels(target);
|
| + RemoveUnusedRel32Locations(target);
|
| +
|
| if (!ParseFile(target))
|
| return false;
|
|
|
| @@ -362,6 +365,26 @@ std::string DisassemblerWin32X86::SectionName(const Section* section) {
|
| return name;
|
| }
|
|
|
| +RvaVisitor* DisassemblerWin32X86::CreateAbs32TargetRvaVisitor() {
|
| + return new RvaVisitor_Abs32(abs32_locations_, *this);
|
| +}
|
| +
|
| +RvaVisitor* DisassemblerWin32X86::CreateRel32TargetRvaVisitor() {
|
| + return new RvaVisitor_Rel32(rel32_locations_, *this);
|
| +}
|
| +
|
| +void DisassemblerWin32X86::RemoveUnusedRel32Locations(
|
| + AssemblyProgram* program) {
|
| + auto cond = [this, program](RVA rva) -> bool {
|
| + // + 4 since offset is relative to start of next instruction.
|
| + 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 DisassemblerWin32X86::ParseFile(AssemblyProgram* program) {
|
| // Walk all the bytes in the file, whether or not in a section.
|
| FileOffset file_offset = 0;
|
| @@ -543,7 +566,9 @@ CheckBool DisassemblerWin32X86::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->EmitAbs32(program->FindOrMakeAbs32Label(target_rva)))
|
| + Label* label = program->FindAbs32Label(target_rva);
|
| + DCHECK(label);
|
| + if (!program->EmitAbs32(label))
|
| return false;
|
| p += 4;
|
| continue;
|
| @@ -553,8 +578,11 @@ CheckBool DisassemblerWin32X86::ParseFileRegion(const Section* section,
|
| ++rel32_pos;
|
|
|
| if (rel32_pos != rel32_locations_.end() && *rel32_pos == current_rva) {
|
| + // + 4 since offset is relative to start of next instruction.
|
| 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;
|
|
|