summaryrefslogtreecommitdiffstats
path: root/courgette/disassembler_win32_x64.cc
diff options
context:
space:
mode:
Diffstat (limited to 'courgette/disassembler_win32_x64.cc')
-rw-r--r--courgette/disassembler_win32_x64.cc45
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 = &sections_[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 = &sections_[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)))