diff options
Diffstat (limited to 'courgette/disassembler_win32_x64.cc')
-rw-r--r-- | courgette/disassembler_win32_x64.cc | 45 |
1 files changed, 27 insertions, 18 deletions
diff --git a/courgette/disassembler_win32_x64.cc b/courgette/disassembler_win32_x64.cc index 6604268..ffa6c36 100644 --- a/courgette/disassembler_win32_x64.cc +++ b/courgette/disassembler_win32_x64.cc @@ -41,6 +41,21 @@ DisassemblerWin32X64::DisassemblerWin32X64(const void* start, size_t length) number_of_data_directories_(0) { } +RVA DisassemblerWin32X64::FileOffsetToRVA(FileOffset file_offset) const { + for (int i = 0; i < number_of_sections_; ++i) { + const Section* section = §ions_[i]; + if (file_offset >= section->file_offset_of_raw_data) { + FileOffset offset_in_section = + file_offset - section->file_offset_of_raw_data; + if (offset_in_section < section->size_of_raw_data) + return static_cast<RVA>(section->virtual_address + offset_in_section); + } + } + + NOTREACHED(); + return kNoRVA; +} + FileOffset DisassemblerWin32X64::RVAToFileOffset(RVA rva) const { const Section* section = RVAToSection(rva); if (section != nullptr) { @@ -65,19 +80,8 @@ FileOffset DisassemblerWin32X64::RVAToFileOffset(RVA rva) const { return kNoFileOffset; } -RVA DisassemblerWin32X64::FileOffsetToRVA(FileOffset file_offset) const { - for (int i = 0; i < number_of_sections_; ++i) { - const Section* section = §ions_[i]; - if (file_offset >= section->file_offset_of_raw_data) { - FileOffset offset_in_section = - file_offset - section->file_offset_of_raw_data; - if (offset_in_section < section->size_of_raw_data) - return static_cast<RVA>(section->virtual_address + offset_in_section); - } - } - - NOTREACHED(); - return kNoRVA; +RVA DisassemblerWin32X64::PointerToTargetRVA(const uint8_t* p) const { + return Address64ToRVA(Read64LittleEndian(p)); } // ParseHeader attempts to match up the buffer with the Windows data @@ -338,6 +342,12 @@ const Section* DisassemblerWin32X64::RVAToSection(RVA rva) const { return nullptr; } +RVA DisassemblerWin32X64::Address64ToRVA(uint64_t address) const { + if (address < image_base() || address >= image_base() + size_of_image_) + return kNoRVA; + return base::checked_cast<RVA>(address - image_base()); +} + std::string DisassemblerWin32X64::SectionName(const Section* section) { if (section == nullptr) return "<none>"; @@ -389,9 +399,8 @@ bool DisassemblerWin32X64::ParseAbs32Relocs() { #if COURGETTE_HISTOGRAM_TARGETS for (size_t i = 0; i < abs32_locations_.size(); ++i) { RVA rva = abs32_locations_[i]; - // The 4 bytes at the relocation are a reference to some address. - uint32_t target_address = Read32LittleEndian(RVAToPointer(rva)); - ++abs32_target_rvas_[target_address - image_base()]; + // The 8 bytes at the relocation are a reference to some address. + ++abs32_target_rvas_[PointerToTargetRVA(RVAToPointer(rva))]; } #endif return true; @@ -601,8 +610,8 @@ CheckBool DisassemblerWin32X64::ParseFileRegion(const Section* section, ++abs32_pos; if (abs32_pos != abs32_locations_.end() && *abs32_pos == current_rva) { - uint64_t target_address = Read64LittleEndian(p); - RVA target_rva = base::checked_cast<RVA>(target_address - image_base()); + RVA target_rva = PointerToTargetRVA(p); + 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))) |