diff options
author | Samuel Huang <huangs@chromium.org> | 2021-06-01 18:29:53 +0000 |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2021-07-25 21:31:30 -0700 |
commit | 1cec5a775590551e3c9f950afad3d95a6f6d950f (patch) | |
tree | 477daf9630e47b99f77dfe41fc357d6a0a940118 /disassembler_win32.cc | |
parent | 77468dc8869df3f7f7d56081c0c661f66554f9b2 (diff) | |
download | zucchini-1cec5a775590551e3c9f950afad3d95a6f6d950f.tar.gz |
[Zucchini] Simplify Abs32GapFinder and Rel32Finder.
Previously, using Abs32GapFinder / Rel32Finder to visit gaps / rel32
references involves calling a getter that returns an optional<> value
whose emptiness indicates end of iteration. The code to use this looks
like:
for (auto value = finder.GetNext(); value; value = finder.GetNext()) {
...
}
This CL abandons optional<> usage and caches the results in Finders,
thereby removing repetition in iteration code:
while (finder.FindNext() {
auto value = finder.GetValue();
...
}
Additional changes:
* Incorporate AddressTranslator into Rel32Finder to offload translation
work from callers.
* Add tests to integrate Abs32GapFinder with Rel32Finder.
* Stylize test data to better show overlap between abs32 references
with disassembled test data.
Bug: 918867
Change-Id: Id044b67550f81c3f46ab383c5b6200906f56ca4e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2918113
Reviewed-by: Etienne Pierre-Doray <etiennep@chromium.org>
Commit-Queue: Samuel Huang <huangs@chromium.org>
Cr-Commit-Position: refs/heads/master@{#888049}
NOKEYCHECK=True
GitOrigin-RevId: 89023e1c511e599e6aeaf0b8d80e3efa2e730b5b
Diffstat (limited to 'disassembler_win32.cc')
-rw-r--r-- | disassembler_win32.cc | 29 |
1 files changed, 11 insertions, 18 deletions
diff --git a/disassembler_win32.cc b/disassembler_win32.cc index da830bf..a23201b 100644 --- a/disassembler_win32.cc +++ b/disassembler_win32.cc @@ -363,7 +363,6 @@ bool DisassemblerWin32<Traits>::ParseAndStoreRel32() { ParseAndStoreAbs32(); - AddressTranslator::OffsetToRvaCache location_offset_to_rva(translator_); AddressTranslator::RvaToOffsetCache target_rva_checker(translator_); for (const pe::ImageSectionHeader& section : sections_) { @@ -382,24 +381,18 @@ bool DisassemblerWin32<Traits>::ParseAndStoreRel32() { image_[{section.file_offset_of_raw_data, size_to_use}]; Abs32GapFinder gap_finder(image_, region, abs32_locations_, Traits::kVAWidth); - typename Traits::RelFinder finder; + typename Traits::RelFinder rel_finder(image_, translator_); // Iterate over gaps between abs32 references, to avoid collision. - for (auto gap = gap_finder.GetNext(); gap.has_value(); - gap = gap_finder.GetNext()) { - finder.SetRegion(gap.value()); - // Iterate over heuristically detected rel32 references, validate, and add - // to |rel32_locations_|. - for (auto rel32 = finder.GetNext(); rel32.has_value(); - rel32 = finder.GetNext()) { - offset_t rel32_offset = offset_t(rel32->location - image_.begin()); - rva_t rel32_rva = location_offset_to_rva.Convert(rel32_offset); - DCHECK_NE(rel32_rva, kInvalidRva); - rva_t target_rva = rel32_rva + 4 + image_.read<uint32_t>(rel32_offset); - if (target_rva_checker.IsValid(target_rva) && - (rel32->can_point_outside_section || - (start_rva <= target_rva && target_rva < end_rva))) { - finder.Accept(); - rel32_locations_.push_back(rel32_offset); + while (gap_finder.FindNext()) { + rel_finder.SetRegion(gap_finder.GetGap()); + // Heuristically detect rel32 references, store if valid. + while (rel_finder.FindNext()) { + auto rel32 = rel_finder.GetRel32(); + if (target_rva_checker.IsValid(rel32.target_rva) && + (rel32.can_point_outside_section || + (start_rva <= rel32.target_rva && rel32.target_rva < end_rva))) { + rel_finder.Accept(); + rel32_locations_.push_back(rel32.location); } } } |