| Index: courgette/disassembler_win32_x64.cc
|
| diff --git a/courgette/disassembler_win32_x64.cc b/courgette/disassembler_win32_x64.cc
|
| index ffa6c36a7aade5f0d7954149fc11bc667b91543c..2db35a39d8a103f8f9fa75b6ddf403e7af6f7edc 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,26 @@ 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 {
|
| + // + 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 DisassemblerWin32X64::ParseFile(AssemblyProgram* program) {
|
| // Walk all the bytes in the file, whether or not in a section.
|
| FileOffset file_offset = 0;
|
| @@ -525,12 +548,13 @@ void DisassemblerWin32X64::ParseRel32RelocsFromSection(const Section* section) {
|
| if (abs32_pos != abs32_locations_.end()) {
|
| if (*abs32_pos < rel32_rva + 4) {
|
| // Beginning of abs32 reloc is before end of rel32 reloc so they
|
| - // overlap. Skip four bytes past the abs32 reloc.
|
| + // overlap. Skip four bytes past the abs32 reloc.
|
| p += (*abs32_pos + 4) - current_rva;
|
| continue;
|
| }
|
| }
|
|
|
| + // + 4 since offset is relative to start of next instruction.
|
| RVA target_rva = rel32_rva + 4 + Read32LittleEndian(rel32);
|
| // To be valid, rel32 target must be within image, and within this
|
| // section.
|
| @@ -614,7 +638,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;
|
| @@ -624,8 +650,11 @@ CheckBool DisassemblerWin32X64::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;
|
|
|