Commit af95efbf authored by Etienne Pierre-doray's avatar Etienne Pierre-doray Committed by Commit Bot

[Zucchini]: Fix discrepancy in reference width for Elf reloc and abs32.

Adds kVAWidth to Elf32Traits and use it in
DisassemblerElfIntel::MakeReferenceGroups as the width of
kReloc and kAbs32 reference types.

Bug: 892359

Change-Id: I28930b8978393c16ee29051c48496e4f696a3fcd
Reviewed-on: https://chromium-review.googlesource.com/c/1264816
Commit-Queue: Etienne Pierre-Doray <etiennep@chromium.org>
Reviewed-by: default avatarSamuel Huang <huangs@chromium.org>
Cr-Commit-Position: refs/heads/master@{#597264}
parent da34dba0
......@@ -167,12 +167,11 @@ void Abs32WriterWin32::PutNext(Reference ref) {
/******** Exported Functions ********/
size_t RemoveOverlappingAbs32Locations(Bitness bitness,
size_t RemoveOverlappingAbs32Locations(uint32_t width,
std::vector<offset_t>* locations) {
if (locations->size() <= 1)
return 0;
uint32_t width = WidthOf(bitness);
auto slow = locations->begin();
auto fast = locations->begin() + 1;
for (;;) {
......
......@@ -127,9 +127,8 @@ class Abs32WriterWin32 : public ReferenceWriter {
};
// Given a sorted list of abs32 |locations|, removes all elements whose body
// overlaps with the body of a previous element (|bitness| determines length).
// Returns the number of elements removed.
size_t RemoveOverlappingAbs32Locations(Bitness bitness,
// (with |width| given) overlaps with the body of a previous element.
size_t RemoveOverlappingAbs32Locations(uint32_t width,
std::vector<offset_t>* locations);
} // namespace zucchini
......
......@@ -433,20 +433,20 @@ TEST(Abs32UtilsTest, Win32Write64) {
}
TEST(Abs32UtilsTest, RemoveOverlappingAbs32Locations) {
// Make |bitness| a state to reduce repetition.
Bitness bitness = kBit32;
// Make |width| a state to reduce repetition.
uint32_t width = WidthOf(kBit32);
auto run_test = [&bitness](const std::vector<offset_t>& expected_locations,
std::vector<offset_t>&& locations) {
auto run_test = [&width](const std::vector<offset_t>& expected_locations,
std::vector<offset_t>&& locations) {
ASSERT_TRUE(std::is_sorted(locations.begin(), locations.end()));
size_t expected_removals = locations.size() - expected_locations.size();
size_t removals = RemoveOverlappingAbs32Locations(bitness, &locations);
size_t removals = RemoveOverlappingAbs32Locations(width, &locations);
EXPECT_EQ(expected_removals, removals);
EXPECT_EQ(expected_locations, locations);
};
// 32-bit tests.
bitness = kBit32;
width = WidthOf(kBit32);
run_test(std::vector<offset_t>(), std::vector<offset_t>());
run_test({4U}, {4U});
run_test({4U, 10U}, {4U, 10U});
......@@ -470,7 +470,7 @@ TEST(Abs32UtilsTest, RemoveOverlappingAbs32Locations) {
run_test({1000000U}, {1000000U, 1000002U});
// 64-bit tests.
bitness = kBit64;
width = WidthOf(kBit64);
run_test(std::vector<offset_t>(), std::vector<offset_t>());
run_test({4U}, {4U});
run_test({4U, 20U}, {4U, 20U});
......
......@@ -153,23 +153,6 @@ std::unique_ptr<ReferenceWriter> DisassemblerElf<Traits>::MakeWriteRelocs(
return std::make_unique<RelocWriterElf>(image, Traits::kBitness, translator_);
}
template <class Traits>
std::unique_ptr<ReferenceReader> DisassemblerElf<Traits>::MakeReadAbs32(
offset_t lo,
offset_t hi) {
Abs32RvaExtractorWin32 abs_rva_extractor(image_, {Traits::kBitness, 0},
abs32_locations_, lo, hi);
return std::make_unique<Abs32ReaderWin32>(std::move(abs_rva_extractor),
translator_);
}
template <class Traits>
std::unique_ptr<ReferenceWriter> DisassemblerElf<Traits>::MakeWriteAbs32(
MutableBufferView image) {
return std::make_unique<Abs32WriterWin32>(
image, AbsoluteAddress(Traits::kBitness, 0), translator_);
}
template <class Traits>
bool DisassemblerElf<Traits>::ParseHeader() {
BufferSource source(image_);
......@@ -303,7 +286,7 @@ void DisassemblerElf<Traits>::ExtractInterestingSectionHeaders() {
template <class Traits>
void DisassemblerElf<Traits>::GetAbs32FromRelocSections() {
constexpr int kAbs32Width = 4;
constexpr int kAbs32Width = Traits::kVAWidth;
DCHECK(abs32_locations_.empty());
auto relocs = MakeReadRelocs(0, offset_t(size()));
for (auto ref = relocs->GetNext(); ref; ref = relocs->GetNext()) {
......@@ -317,7 +300,7 @@ void DisassemblerElf<Traits>::GetAbs32FromRelocSections() {
// Abs32 reference bodies must not overlap. If found, simply remove them.
size_t num_removed =
RemoveOverlappingAbs32Locations(Traits::kBitness, &abs32_locations_);
RemoveOverlappingAbs32Locations(kAbs32Width, &abs32_locations_);
if (num_removed) {
LOG(WARNING) << "Warning: Found and removed " << num_removed
<< " abs32 locations with overlapping bodies.";
......@@ -349,15 +332,17 @@ DisassemblerElfIntel<Traits>::~DisassemblerElfIntel() = default;
template <class Traits>
std::vector<ReferenceGroup> DisassemblerElfIntel<Traits>::MakeReferenceGroups()
const {
return {{ReferenceTypeTraits{4, TypeTag(kReloc), PoolTag(kReloc)},
&DisassemblerElfIntel<Traits>::MakeReadRelocs,
&DisassemblerElfIntel<Traits>::MakeWriteRelocs},
{ReferenceTypeTraits{4, TypeTag(kAbs32), PoolTag(kAbs32)},
&DisassemblerElfIntel<Traits>::MakeReadAbs32,
&DisassemblerElfIntel<Traits>::MakeWriteAbs32},
{ReferenceTypeTraits{4, TypeTag(kRel32), PoolTag(kRel32)},
&DisassemblerElfIntel<Traits>::MakeReadRel32,
&DisassemblerElfIntel<Traits>::MakeWriteRel32}};
return {
{ReferenceTypeTraits{sizeof(Traits::Elf_Rel::r_offset), TypeTag(kReloc),
PoolTag(kReloc)},
&DisassemblerElfIntel<Traits>::MakeReadRelocs,
&DisassemblerElfIntel<Traits>::MakeWriteRelocs},
{ReferenceTypeTraits{Traits::kVAWidth, TypeTag(kAbs32), PoolTag(kAbs32)},
&DisassemblerElfIntel<Traits>::MakeReadAbs32,
&DisassemblerElfIntel<Traits>::MakeWriteAbs32},
{ReferenceTypeTraits{4, TypeTag(kRel32), PoolTag(kRel32)},
&DisassemblerElfIntel<Traits>::MakeReadRel32,
&DisassemblerElfIntel<Traits>::MakeWriteRel32}};
}
template <class Traits>
......@@ -403,6 +388,24 @@ void DisassemblerElfIntel<Traits>::PostProcessRel32() {
std::sort(rel32_locations_.begin(), rel32_locations_.end());
}
template <class Traits>
std::unique_ptr<ReferenceReader> DisassemblerElfIntel<Traits>::MakeReadAbs32(
offset_t lo,
offset_t hi) {
Abs32RvaExtractorWin32 abs_rva_extractor(this->image_,
AbsoluteAddress(Traits::kBitness, 0),
this->abs32_locations_, lo, hi);
return std::make_unique<Abs32ReaderWin32>(std::move(abs_rva_extractor),
this->translator_);
}
template <class Traits>
std::unique_ptr<ReferenceWriter> DisassemblerElfIntel<Traits>::MakeWriteAbs32(
MutableBufferView image) {
return std::make_unique<Abs32WriterWin32>(
image, AbsoluteAddress(Traits::kBitness, 0), this->translator_);
}
template <class Traits>
std::unique_ptr<ReferenceReader> DisassemblerElfIntel<Traits>::MakeReadRel32(
offset_t lo,
......
......@@ -39,6 +39,7 @@ struct Elf32IntelTraits : public Elf32Traits {
static const char kExeTypeString[];
static constexpr elf::MachineArchitecture kMachineValue = elf::EM_386;
static constexpr uint32_t kRelType = elf::R_386_RELATIVE;
enum : uint32_t { kVAWidth = 4 };
using Rel32FinderUse = Rel32FinderX86;
};
......@@ -58,6 +59,7 @@ struct Elf64IntelTraits : public Elf64Traits {
static const char kExeTypeString[];
static constexpr elf::MachineArchitecture kMachineValue = elf::EM_X86_64;
static constexpr uint32_t kRelType = elf::R_X86_64_RELATIVE;
enum : uint32_t { kVAWidth = 8 };
using Rel32FinderUse = Rel32FinderX64;
};
......@@ -81,8 +83,6 @@ class DisassemblerElf : public Disassembler {
// Find/Receive functions that are common among different architectures.
std::unique_ptr<ReferenceReader> MakeReadRelocs(offset_t lo, offset_t hi);
std::unique_ptr<ReferenceWriter> MakeWriteRelocs(MutableBufferView image);
std::unique_ptr<ReferenceReader> MakeReadAbs32(offset_t lo, offset_t hi);
std::unique_ptr<ReferenceWriter> MakeWriteAbs32(MutableBufferView image);
const AddressTranslator& translator() const { return translator_; }
......@@ -171,6 +171,8 @@ class DisassemblerElfIntel : public DisassemblerElf<Traits> {
void PostProcessRel32() override;
// Specialized Find/Receive functions.
std::unique_ptr<ReferenceReader> MakeReadAbs32(offset_t lo, offset_t hi);
std::unique_ptr<ReferenceWriter> MakeWriteAbs32(MutableBufferView image);
std::unique_ptr<ReferenceReader> MakeReadRel32(offset_t lo, offset_t hi);
std::unique_ptr<ReferenceWriter> MakeWriteRel32(MutableBufferView image);
......
......@@ -327,7 +327,7 @@ bool DisassemblerWin32<Traits>::ParseAndStoreAbs32() {
// Abs32 reference bodies must not overlap. If found, simply remove them.
size_t num_removed =
RemoveOverlappingAbs32Locations(Traits::kBitness, &abs32_locations_);
RemoveOverlappingAbs32Locations(Traits::kVAWidth, &abs32_locations_);
LOG_IF(WARNING, num_removed) << "Found and removed " << num_removed
<< " abs32 locations with overlapping bodies.";
return true;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment