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) { ...@@ -167,12 +167,11 @@ void Abs32WriterWin32::PutNext(Reference ref) {
/******** Exported Functions ********/ /******** Exported Functions ********/
size_t RemoveOverlappingAbs32Locations(Bitness bitness, size_t RemoveOverlappingAbs32Locations(uint32_t width,
std::vector<offset_t>* locations) { std::vector<offset_t>* locations) {
if (locations->size() <= 1) if (locations->size() <= 1)
return 0; return 0;
uint32_t width = WidthOf(bitness);
auto slow = locations->begin(); auto slow = locations->begin();
auto fast = locations->begin() + 1; auto fast = locations->begin() + 1;
for (;;) { for (;;) {
......
...@@ -127,9 +127,8 @@ class Abs32WriterWin32 : public ReferenceWriter { ...@@ -127,9 +127,8 @@ class Abs32WriterWin32 : public ReferenceWriter {
}; };
// Given a sorted list of abs32 |locations|, removes all elements whose body // Given a sorted list of abs32 |locations|, removes all elements whose body
// overlaps with the body of a previous element (|bitness| determines length). // (with |width| given) overlaps with the body of a previous element.
// Returns the number of elements removed. size_t RemoveOverlappingAbs32Locations(uint32_t width,
size_t RemoveOverlappingAbs32Locations(Bitness bitness,
std::vector<offset_t>* locations); std::vector<offset_t>* locations);
} // namespace zucchini } // namespace zucchini
......
...@@ -433,20 +433,20 @@ TEST(Abs32UtilsTest, Win32Write64) { ...@@ -433,20 +433,20 @@ TEST(Abs32UtilsTest, Win32Write64) {
} }
TEST(Abs32UtilsTest, RemoveOverlappingAbs32Locations) { TEST(Abs32UtilsTest, RemoveOverlappingAbs32Locations) {
// Make |bitness| a state to reduce repetition. // Make |width| a state to reduce repetition.
Bitness bitness = kBit32; uint32_t width = WidthOf(kBit32);
auto run_test = [&bitness](const std::vector<offset_t>& expected_locations, auto run_test = [&width](const std::vector<offset_t>& expected_locations,
std::vector<offset_t>&& locations) { std::vector<offset_t>&& locations) {
ASSERT_TRUE(std::is_sorted(locations.begin(), locations.end())); ASSERT_TRUE(std::is_sorted(locations.begin(), locations.end()));
size_t expected_removals = locations.size() - expected_locations.size(); 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_removals, removals);
EXPECT_EQ(expected_locations, locations); EXPECT_EQ(expected_locations, locations);
}; };
// 32-bit tests. // 32-bit tests.
bitness = kBit32; width = WidthOf(kBit32);
run_test(std::vector<offset_t>(), std::vector<offset_t>()); run_test(std::vector<offset_t>(), std::vector<offset_t>());
run_test({4U}, {4U}); run_test({4U}, {4U});
run_test({4U, 10U}, {4U, 10U}); run_test({4U, 10U}, {4U, 10U});
...@@ -470,7 +470,7 @@ TEST(Abs32UtilsTest, RemoveOverlappingAbs32Locations) { ...@@ -470,7 +470,7 @@ TEST(Abs32UtilsTest, RemoveOverlappingAbs32Locations) {
run_test({1000000U}, {1000000U, 1000002U}); run_test({1000000U}, {1000000U, 1000002U});
// 64-bit tests. // 64-bit tests.
bitness = kBit64; width = WidthOf(kBit64);
run_test(std::vector<offset_t>(), std::vector<offset_t>()); run_test(std::vector<offset_t>(), std::vector<offset_t>());
run_test({4U}, {4U}); run_test({4U}, {4U});
run_test({4U, 20U}, {4U, 20U}); run_test({4U, 20U}, {4U, 20U});
......
...@@ -153,23 +153,6 @@ std::unique_ptr<ReferenceWriter> DisassemblerElf<Traits>::MakeWriteRelocs( ...@@ -153,23 +153,6 @@ std::unique_ptr<ReferenceWriter> DisassemblerElf<Traits>::MakeWriteRelocs(
return std::make_unique<RelocWriterElf>(image, Traits::kBitness, translator_); 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> template <class Traits>
bool DisassemblerElf<Traits>::ParseHeader() { bool DisassemblerElf<Traits>::ParseHeader() {
BufferSource source(image_); BufferSource source(image_);
...@@ -303,7 +286,7 @@ void DisassemblerElf<Traits>::ExtractInterestingSectionHeaders() { ...@@ -303,7 +286,7 @@ void DisassemblerElf<Traits>::ExtractInterestingSectionHeaders() {
template <class Traits> template <class Traits>
void DisassemblerElf<Traits>::GetAbs32FromRelocSections() { void DisassemblerElf<Traits>::GetAbs32FromRelocSections() {
constexpr int kAbs32Width = 4; constexpr int kAbs32Width = Traits::kVAWidth;
DCHECK(abs32_locations_.empty()); DCHECK(abs32_locations_.empty());
auto relocs = MakeReadRelocs(0, offset_t(size())); auto relocs = MakeReadRelocs(0, offset_t(size()));
for (auto ref = relocs->GetNext(); ref; ref = relocs->GetNext()) { for (auto ref = relocs->GetNext(); ref; ref = relocs->GetNext()) {
...@@ -317,7 +300,7 @@ void DisassemblerElf<Traits>::GetAbs32FromRelocSections() { ...@@ -317,7 +300,7 @@ void DisassemblerElf<Traits>::GetAbs32FromRelocSections() {
// Abs32 reference bodies must not overlap. If found, simply remove them. // Abs32 reference bodies must not overlap. If found, simply remove them.
size_t num_removed = size_t num_removed =
RemoveOverlappingAbs32Locations(Traits::kBitness, &abs32_locations_); RemoveOverlappingAbs32Locations(kAbs32Width, &abs32_locations_);
if (num_removed) { if (num_removed) {
LOG(WARNING) << "Warning: Found and removed " << num_removed LOG(WARNING) << "Warning: Found and removed " << num_removed
<< " abs32 locations with overlapping bodies."; << " abs32 locations with overlapping bodies.";
...@@ -349,15 +332,17 @@ DisassemblerElfIntel<Traits>::~DisassemblerElfIntel() = default; ...@@ -349,15 +332,17 @@ DisassemblerElfIntel<Traits>::~DisassemblerElfIntel() = default;
template <class Traits> template <class Traits>
std::vector<ReferenceGroup> DisassemblerElfIntel<Traits>::MakeReferenceGroups() std::vector<ReferenceGroup> DisassemblerElfIntel<Traits>::MakeReferenceGroups()
const { const {
return {{ReferenceTypeTraits{4, TypeTag(kReloc), PoolTag(kReloc)}, return {
&DisassemblerElfIntel<Traits>::MakeReadRelocs, {ReferenceTypeTraits{sizeof(Traits::Elf_Rel::r_offset), TypeTag(kReloc),
&DisassemblerElfIntel<Traits>::MakeWriteRelocs}, PoolTag(kReloc)},
{ReferenceTypeTraits{4, TypeTag(kAbs32), PoolTag(kAbs32)}, &DisassemblerElfIntel<Traits>::MakeReadRelocs,
&DisassemblerElfIntel<Traits>::MakeReadAbs32, &DisassemblerElfIntel<Traits>::MakeWriteRelocs},
&DisassemblerElfIntel<Traits>::MakeWriteAbs32}, {ReferenceTypeTraits{Traits::kVAWidth, TypeTag(kAbs32), PoolTag(kAbs32)},
{ReferenceTypeTraits{4, TypeTag(kRel32), PoolTag(kRel32)}, &DisassemblerElfIntel<Traits>::MakeReadAbs32,
&DisassemblerElfIntel<Traits>::MakeReadRel32, &DisassemblerElfIntel<Traits>::MakeWriteAbs32},
&DisassemblerElfIntel<Traits>::MakeWriteRel32}}; {ReferenceTypeTraits{4, TypeTag(kRel32), PoolTag(kRel32)},
&DisassemblerElfIntel<Traits>::MakeReadRel32,
&DisassemblerElfIntel<Traits>::MakeWriteRel32}};
} }
template <class Traits> template <class Traits>
...@@ -403,6 +388,24 @@ void DisassemblerElfIntel<Traits>::PostProcessRel32() { ...@@ -403,6 +388,24 @@ void DisassemblerElfIntel<Traits>::PostProcessRel32() {
std::sort(rel32_locations_.begin(), rel32_locations_.end()); 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> template <class Traits>
std::unique_ptr<ReferenceReader> DisassemblerElfIntel<Traits>::MakeReadRel32( std::unique_ptr<ReferenceReader> DisassemblerElfIntel<Traits>::MakeReadRel32(
offset_t lo, offset_t lo,
......
...@@ -39,6 +39,7 @@ struct Elf32IntelTraits : public Elf32Traits { ...@@ -39,6 +39,7 @@ struct Elf32IntelTraits : public Elf32Traits {
static const char kExeTypeString[]; static const char kExeTypeString[];
static constexpr elf::MachineArchitecture kMachineValue = elf::EM_386; static constexpr elf::MachineArchitecture kMachineValue = elf::EM_386;
static constexpr uint32_t kRelType = elf::R_386_RELATIVE; static constexpr uint32_t kRelType = elf::R_386_RELATIVE;
enum : uint32_t { kVAWidth = 4 };
using Rel32FinderUse = Rel32FinderX86; using Rel32FinderUse = Rel32FinderX86;
}; };
...@@ -58,6 +59,7 @@ struct Elf64IntelTraits : public Elf64Traits { ...@@ -58,6 +59,7 @@ struct Elf64IntelTraits : public Elf64Traits {
static const char kExeTypeString[]; static const char kExeTypeString[];
static constexpr elf::MachineArchitecture kMachineValue = elf::EM_X86_64; static constexpr elf::MachineArchitecture kMachineValue = elf::EM_X86_64;
static constexpr uint32_t kRelType = elf::R_X86_64_RELATIVE; static constexpr uint32_t kRelType = elf::R_X86_64_RELATIVE;
enum : uint32_t { kVAWidth = 8 };
using Rel32FinderUse = Rel32FinderX64; using Rel32FinderUse = Rel32FinderX64;
}; };
...@@ -81,8 +83,6 @@ class DisassemblerElf : public Disassembler { ...@@ -81,8 +83,6 @@ class DisassemblerElf : public Disassembler {
// Find/Receive functions that are common among different architectures. // Find/Receive functions that are common among different architectures.
std::unique_ptr<ReferenceReader> MakeReadRelocs(offset_t lo, offset_t hi); std::unique_ptr<ReferenceReader> MakeReadRelocs(offset_t lo, offset_t hi);
std::unique_ptr<ReferenceWriter> MakeWriteRelocs(MutableBufferView image); 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_; } const AddressTranslator& translator() const { return translator_; }
...@@ -171,6 +171,8 @@ class DisassemblerElfIntel : public DisassemblerElf<Traits> { ...@@ -171,6 +171,8 @@ class DisassemblerElfIntel : public DisassemblerElf<Traits> {
void PostProcessRel32() override; void PostProcessRel32() override;
// Specialized Find/Receive functions. // 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<ReferenceReader> MakeReadRel32(offset_t lo, offset_t hi);
std::unique_ptr<ReferenceWriter> MakeWriteRel32(MutableBufferView image); std::unique_ptr<ReferenceWriter> MakeWriteRel32(MutableBufferView image);
......
...@@ -327,7 +327,7 @@ bool DisassemblerWin32<Traits>::ParseAndStoreAbs32() { ...@@ -327,7 +327,7 @@ bool DisassemblerWin32<Traits>::ParseAndStoreAbs32() {
// Abs32 reference bodies must not overlap. If found, simply remove them. // Abs32 reference bodies must not overlap. If found, simply remove them.
size_t num_removed = size_t num_removed =
RemoveOverlappingAbs32Locations(Traits::kBitness, &abs32_locations_); RemoveOverlappingAbs32Locations(Traits::kVAWidth, &abs32_locations_);
LOG_IF(WARNING, num_removed) << "Found and removed " << num_removed LOG_IF(WARNING, num_removed) << "Found and removed " << num_removed
<< " abs32 locations with overlapping bodies."; << " abs32 locations with overlapping bodies.";
return true; 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