aboutsummaryrefslogtreecommitdiff
path: root/disassembler_elf.cc
diff options
context:
space:
mode:
authorSamuel Huang <huangs@chromium.org>2021-06-01 18:29:53 +0000
committerCopybara-Service <copybara-worker@google.com>2021-07-25 21:31:30 -0700
commit1cec5a775590551e3c9f950afad3d95a6f6d950f (patch)
tree477daf9630e47b99f77dfe41fc357d6a0a940118 /disassembler_elf.cc
parent77468dc8869df3f7f7d56081c0c661f66554f9b2 (diff)
downloadzucchini-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_elf.cc')
-rw-r--r--disassembler_elf.cc34
1 files changed, 15 insertions, 19 deletions
diff --git a/disassembler_elf.cc b/disassembler_elf.cc
index 4727d1c..37cff0b 100644
--- a/disassembler_elf.cc
+++ b/disassembler_elf.cc
@@ -417,35 +417,31 @@ std::vector<ReferenceGroup> DisassemblerElfIntel<Traits>::MakeReferenceGroups()
template <class Traits>
void DisassemblerElfIntel<Traits>::ParseExecSection(
const typename Traits::Elf_Shdr& section) {
+ // |this->| is needed to access protected members of templated base class. To
+ // reduce noise, use local references for these.
ConstBufferView& image_ = this->image_;
+ const AddressTranslator& translator_ = this->translator_;
auto& abs32_locations_ = this->abs32_locations_;
- std::ptrdiff_t from_offset_to_rva = section.sh_addr - section.sh_offset;
-
// Range of values was ensured in ParseHeader().
rva_t start_rva = base::checked_cast<rva_t>(section.sh_addr);
rva_t end_rva = base::checked_cast<rva_t>(start_rva + section.sh_size);
- AddressTranslator::RvaToOffsetCache target_rva_checker(this->translator_);
+ AddressTranslator::RvaToOffsetCache target_rva_checker(translator_);
ConstBufferView region(image_.begin() + section.sh_offset, section.sh_size);
Abs32GapFinder gap_finder(image_, region, abs32_locations_, 4);
- typename Traits::Rel32FinderUse finder;
- for (auto gap = gap_finder.GetNext(); gap.has_value();
- gap = gap_finder.GetNext()) {
- finder.SetRegion(gap.value());
- for (auto rel32 = finder.GetNext(); rel32.has_value();
- rel32 = finder.GetNext()) {
- offset_t rel32_offset =
- base::checked_cast<offset_t>(rel32->location - image_.begin());
- rva_t rel32_rva = rva_t(rel32_offset + from_offset_to_rva);
- 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);
+ typename Traits::Rel32FinderUse rel_finder(image_, translator_);
+ // Iterate over gaps between abs32 references, to avoid collision.
+ while (gap_finder.FindNext()) {
+ rel_finder.SetRegion(gap_finder.GetGap());
+ 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);
}
}
}