summaryrefslogtreecommitdiffstats
path: root/courgette/disassembler_win32_x86.cc
diff options
context:
space:
mode:
authorhuangs <huangs@chromium.org>2015-09-18 11:52:56 -0700
committerCommit bot <commit-bot@chromium.org>2015-09-18 18:53:28 +0000
commit6d2a30316defffdd77c473547063316ebb9c279b (patch)
tree6de1afe27ab096196c1c4e92587c19519691b443 /courgette/disassembler_win32_x86.cc
parent6d5ddf5cd94ed429df19496948062fe137e68116 (diff)
downloadchromium_src-6d2a30316defffdd77c473547063316ebb9c279b.zip
chromium_src-6d2a30316defffdd77c473547063316ebb9c279b.tar.gz
chromium_src-6d2a30316defffdd77c473547063316ebb9c279b.tar.bz2
[Courgette] Refactor: Adding Rel32FinderWin32X86_Basic and Unittests
We're planning to improve heuristic to find Rel32 addresses for Win32 x86. First refactor by by extraacting the feature into its own class. This also lead to the extraction of RVA and various helpers from disassembler.h to image_utils.h. Also adding unittests for Rel32FinderWin32X86_Basic. The test is data-driven by adding a simple parser for test data. BUG= Review URL: https://codereview.chromium.org/1344173003 Cr-Commit-Position: refs/heads/master@{#349727}
Diffstat (limited to 'courgette/disassembler_win32_x86.cc')
-rw-r--r--courgette/disassembler_win32_x86.cc76
1 files changed, 9 insertions, 67 deletions
diff --git a/courgette/disassembler_win32_x86.cc b/courgette/disassembler_win32_x86.cc
index dd3dd5e..85d99f4 100644
--- a/courgette/disassembler_win32_x86.cc
+++ b/courgette/disassembler_win32_x86.cc
@@ -14,6 +14,7 @@
#include "courgette/assembly_program.h"
#include "courgette/courgette.h"
#include "courgette/encoded_program.h"
+#include "courgette/rel32_finder_win32_x86.h"
namespace courgette {
@@ -434,7 +435,6 @@ void DisassemblerWin32X86::ParseRel32RelocsFromSection(const Section* section) {
uint32 start_file_offset = section->file_offset_of_raw_data;
uint32 end_file_offset = start_file_offset + section->size_of_raw_data;
- RVA relocs_start_rva = base_relocation_table().address_;
const uint8* start_pointer = OffsetToPointer(start_file_offset);
const uint8* end_pointer = OffsetToPointer(end_file_offset);
@@ -442,75 +442,17 @@ void DisassemblerWin32X86::ParseRel32RelocsFromSection(const Section* section) {
RVA start_rva = FileOffsetToRVA(start_file_offset);
RVA end_rva = start_rva + section->virtual_size;
- // Quick way to convert from Pointer to RVA within a single Section is to
- // subtract 'pointer_to_rva'.
- const uint8* const adjust_pointer_to_rva = start_pointer - start_rva;
-
- std::vector<RVA>::iterator abs32_pos = abs32_locations_.begin();
-
- // Find the rel32 relocations.
- const uint8* p = start_pointer;
- while (p < end_pointer) {
- RVA current_rva = static_cast<RVA>(p - adjust_pointer_to_rva);
- if (current_rva == relocs_start_rva) {
- uint32 relocs_size = base_relocation_table().size_;
- if (relocs_size) {
- p += relocs_size;
- continue;
- }
- }
-
- //while (abs32_pos != abs32_locations_.end() && *abs32_pos < current_rva)
- // ++abs32_pos;
-
- // Heuristic discovery of rel32 locations in instruction stream: are the
- // next few bytes the start of an instruction containing a rel32
- // addressing mode?
- const uint8* rel32 = NULL;
-
- if (p + 5 <= end_pointer) {
- if (*p == 0xE8 || *p == 0xE9) { // jmp rel32 and call rel32
- rel32 = p + 1;
- }
- }
- if (p + 6 <= end_pointer) {
- if (*p == 0x0F && (*(p+1) & 0xF0) == 0x80) { // Jcc long form
- if (p[1] != 0x8A && p[1] != 0x8B) // JPE/JPO unlikely
- rel32 = p + 2;
- }
- }
- if (rel32) {
- RVA rel32_rva = static_cast<RVA>(rel32 - adjust_pointer_to_rva);
-
- // Is there an abs32 reloc overlapping the candidate?
- while (abs32_pos != abs32_locations_.end() && *abs32_pos < rel32_rva - 3)
- ++abs32_pos;
- // Now: (*abs32_pos > rel32_rva - 4) i.e. the lowest addressed 4-byte
- // region that could overlap rel32_rva.
- 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.
- p += (*abs32_pos + 4) - current_rva;
- continue;
- }
- }
+ Rel32FinderWin32X86_Basic finder(
+ base_relocation_table().address_,
+ base_relocation_table().address_ + base_relocation_table().size_,
+ size_of_image_);
+ finder.Find(start_pointer, end_pointer, start_rva, end_rva, abs32_locations_);
+ finder.SwapRel32Locations(&rel32_locations_);
- RVA target_rva = rel32_rva + 4 + Read32LittleEndian(rel32);
- // To be valid, rel32 target must be within image, and within this
- // section.
- if (IsValidRVA(target_rva) &&
- start_rva <= target_rva && target_rva < end_rva) {
- rel32_locations_.push_back(rel32_rva);
#if COURGETTE_HISTOGRAM_TARGETS
- ++rel32_target_rvas_[target_rva];
+ DCHECK(rel32_target_rvas_.empty());
+ finder.SwapRel32TargetRVAs(&rel32_target_rvas_);
#endif
- p = rel32 + 4;
- continue;
- }
- }
- p += 1;
- }
}
CheckBool DisassemblerWin32X86::ParseNonSectionFileRegion(