Skip to content

Commit

Permalink
[Courgette] Disassembler code movement and format fix.
Browse files Browse the repository at this point in the history
We wish to rename ParseAbs32Relocs() and ParseRel32RelocsFromSections(),
and make them part of the Disassembler interface. This requires moving
chunks of code. This CL does the code movement as an independent change
to reduce noise later.

Also including reformatting changes from "git cl format".

BUG=660980

Review-Url: https://codereview.chromium.org/2728653003
Cr-Commit-Position: refs/heads/master@{#454068}
  • Loading branch information
samuelhuang authored and Commit bot committed Mar 1, 2017
1 parent 63f8ee9 commit dc779d9
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 127 deletions.
130 changes: 64 additions & 66 deletions courgette/disassembler_elf_32.cc
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,70 @@ CheckBool DisassemblerElf32::RVAsToFileOffsets(
return true;
}

CheckBool DisassemblerElf32::ParseAbs32Relocs() {
abs32_locations_.clear();

// Loop through sections for relocation sections
for (Elf32_Half section_id = 0; section_id < SectionHeaderCount();
++section_id) {
const Elf32_Shdr* section_header = SectionHeader(section_id);

if (section_header->sh_type == SHT_REL) {
const Elf32_Rel* relocs_table =
reinterpret_cast<const Elf32_Rel*>(SectionBody(section_id));

int relocs_table_count =
section_header->sh_size / section_header->sh_entsize;

// Elf32_Word relocation_section_id = section_header->sh_info;

// Loop through relocation objects in the relocation section
for (int rel_id = 0; rel_id < relocs_table_count; ++rel_id) {
RVA rva;

// Quite a few of these conversions fail, and we simply skip
// them, that's okay.
if (RelToRVA(relocs_table[rel_id], &rva) && CheckSection(rva))
abs32_locations_.push_back(rva);
}
}
}

std::sort(abs32_locations_.begin(), abs32_locations_.end());
DCHECK(abs32_locations_.empty() || abs32_locations_.back() != kUnassignedRVA);
return true;
}

CheckBool DisassemblerElf32::ParseRel32RelocsFromSections() {
rel32_locations_.clear();
bool found_rel32 = false;

// Loop through sections for relocation sections
for (Elf32_Half section_id = 0; section_id < SectionHeaderCount();
++section_id) {
const Elf32_Shdr* section_header = SectionHeader(section_id);

// Some debug sections can have sh_type=SHT_PROGBITS but sh_addr=0.
if (section_header->sh_type != SHT_PROGBITS || section_header->sh_addr == 0)
continue;

// Heuristic: Only consider ".text" section.
std::string section_name;
if (!SectionName(*section_header, &section_name))
return false;
if (section_name != ".text")
continue;

found_rel32 = true;
if (!ParseRel32RelocsFromSection(section_header))
return false;
}
if (!found_rel32)
VLOG(1) << "Warning: Found no rel32 addresses. Missing .text section?";

return true;
}

RvaVisitor* DisassemblerElf32::CreateAbs32TargetRvaVisitor() {
return new RvaVisitor_Abs32(abs32_locations_, *this);
}
Expand Down Expand Up @@ -541,41 +605,6 @@ CheckBool DisassemblerElf32::ParseSimpleRegion(
return true;
}

CheckBool DisassemblerElf32::ParseAbs32Relocs() {
abs32_locations_.clear();

// Loop through sections for relocation sections
for (Elf32_Half section_id = 0; section_id < SectionHeaderCount();
++section_id) {
const Elf32_Shdr* section_header = SectionHeader(section_id);

if (section_header->sh_type == SHT_REL) {
const Elf32_Rel* relocs_table =
reinterpret_cast<const Elf32_Rel*>(SectionBody(section_id));

int relocs_table_count = section_header->sh_size /
section_header->sh_entsize;

// Elf32_Word relocation_section_id = section_header->sh_info;

// Loop through relocation objects in the relocation section
for (int rel_id = 0; rel_id < relocs_table_count; ++rel_id) {
RVA rva;

// Quite a few of these conversions fail, and we simply skip
// them, that's okay.
if (RelToRVA(relocs_table[rel_id], &rva) && CheckSection(rva))
abs32_locations_.push_back(rva);
}
}
}

std::sort(abs32_locations_.begin(), abs32_locations_.end());
DCHECK(abs32_locations_.empty() ||
abs32_locations_.back() != kUnassignedRVA);
return true;
}

CheckBool DisassemblerElf32::CheckSection(RVA rva) {
FileOffset file_offset = RVAToFileOffset(rva);
if (file_offset == kNoFileOffset)
Expand All @@ -598,35 +627,4 @@ CheckBool DisassemblerElf32::CheckSection(RVA rva) {
return false;
}

CheckBool DisassemblerElf32::ParseRel32RelocsFromSections() {
rel32_locations_.clear();
bool found_rel32 = false;

// Loop through sections for relocation sections
for (Elf32_Half section_id = 0; section_id < SectionHeaderCount();
++section_id) {
const Elf32_Shdr* section_header = SectionHeader(section_id);

// Some debug sections can have sh_type=SHT_PROGBITS but sh_addr=0.
if (section_header->sh_type != SHT_PROGBITS ||
section_header->sh_addr == 0)
continue;

// Heuristic: Only consider ".text" section.
std::string section_name;
if (!SectionName(*section_header, &section_name))
return false;
if (section_name != ".text")
continue;

found_rel32 = true;
if (!ParseRel32RelocsFromSection(section_header))
return false;
}
if (!found_rel32)
VLOG(1) << "Warning: Found no rel32 addresses. Missing .text section?";

return true;
}

} // namespace courgette
10 changes: 5 additions & 5 deletions courgette/disassembler_elf_32.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,11 @@ class DisassemblerElf32 : public Disassembler {
virtual CheckBool ParseRel32RelocsFromSection(const Elf32_Shdr* section)
WARN_UNUSED_RESULT = 0;

CheckBool ParseAbs32Relocs() WARN_UNUSED_RESULT;

// Extracts all rel32 TypedRVAs. Does not sort the result.
CheckBool ParseRel32RelocsFromSections() WARN_UNUSED_RESULT;

// Disassembler interfaces.
RvaVisitor* CreateAbs32TargetRvaVisitor() override;
RvaVisitor* CreateRel32TargetRvaVisitor() override;
Expand All @@ -201,13 +206,8 @@ class DisassemblerElf32 : public Disassembler {
InstructionReceptor* receptor) const
WARN_UNUSED_RESULT;

CheckBool ParseAbs32Relocs() WARN_UNUSED_RESULT;

CheckBool CheckSection(RVA rva) WARN_UNUSED_RESULT;

// Extracts all rel32 TypedRVAs. Does not sort the result.
CheckBool ParseRel32RelocsFromSections() WARN_UNUSED_RESULT;

const Elf32_Ehdr* header_;

Elf32_Half section_header_table_size_;
Expand Down
108 changes: 54 additions & 54 deletions courgette/disassembler_win32.cc
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,60 @@ bool DisassemblerWin32::QuickDetect(const uint8_t* start,
return true;
}

bool DisassemblerWin32::ParseAbs32Relocs() {
abs32_locations_.clear();
if (!ParseRelocs(&abs32_locations_))
return false;

#if COURGETTE_HISTOGRAM_TARGETS
for (size_t i = 0; i < abs32_locations_.size(); ++i) {
RVA rva = abs32_locations_[i];
// The 4 bytes at the relocation are a reference to some address.
++abs32_target_rvas_[PointerToTargetRVA(RVAToPointer(rva))];
}
#endif
return true;
}

void DisassemblerWin32::ParseRel32RelocsFromSections() {
FileOffset file_offset = 0;
while (file_offset < length()) {
const Section* section = FindNextSection(file_offset);
if (section == nullptr)
break;
if (file_offset < section->file_offset_of_raw_data)
file_offset = section->file_offset_of_raw_data;
ParseRel32RelocsFromSection(section);
file_offset += section->size_of_raw_data;
}
std::sort(rel32_locations_.begin(), rel32_locations_.end());
DCHECK(rel32_locations_.empty() || rel32_locations_.back() != kUnassignedRVA);

#if COURGETTE_HISTOGRAM_TARGETS
VLOG(1) << "abs32_locations_ " << abs32_locations_.size()
<< "\nrel32_locations_ " << rel32_locations_.size()
<< "\nabs32_target_rvas_ " << abs32_target_rvas_.size()
<< "\nrel32_target_rvas_ " << rel32_target_rvas_.size();

int common = 0;
std::map<RVA, int>::iterator abs32_iter = abs32_target_rvas_.begin();
std::map<RVA, int>::iterator rel32_iter = rel32_target_rvas_.begin();
while (abs32_iter != abs32_target_rvas_.end() &&
rel32_iter != rel32_target_rvas_.end()) {
if (abs32_iter->first < rel32_iter->first) {
++abs32_iter;
} else if (rel32_iter->first < abs32_iter->first) {
++rel32_iter;
} else {
++common;
++abs32_iter;
++rel32_iter;
}
}
VLOG(1) << "common " << common;
#endif
}

RvaVisitor* DisassemblerWin32::CreateAbs32TargetRvaVisitor() {
return new RvaVisitor_Abs32(abs32_locations_, *this);
}
Expand Down Expand Up @@ -420,60 +474,6 @@ CheckBool DisassemblerWin32::ParseFile(AssemblyProgram* program,
return true;
}

bool DisassemblerWin32::ParseAbs32Relocs() {
abs32_locations_.clear();
if (!ParseRelocs(&abs32_locations_))
return false;

#if COURGETTE_HISTOGRAM_TARGETS
for (size_t i = 0; i < abs32_locations_.size(); ++i) {
RVA rva = abs32_locations_[i];
// The 4 bytes at the relocation are a reference to some address.
++abs32_target_rvas_[PointerToTargetRVA(RVAToPointer(rva))];
}
#endif
return true;
}

void DisassemblerWin32::ParseRel32RelocsFromSections() {
FileOffset file_offset = 0;
while (file_offset < length()) {
const Section* section = FindNextSection(file_offset);
if (section == nullptr)
break;
if (file_offset < section->file_offset_of_raw_data)
file_offset = section->file_offset_of_raw_data;
ParseRel32RelocsFromSection(section);
file_offset += section->size_of_raw_data;
}
std::sort(rel32_locations_.begin(), rel32_locations_.end());
DCHECK(rel32_locations_.empty() || rel32_locations_.back() != kUnassignedRVA);

#if COURGETTE_HISTOGRAM_TARGETS
VLOG(1) << "abs32_locations_ " << abs32_locations_.size()
<< "\nrel32_locations_ " << rel32_locations_.size()
<< "\nabs32_target_rvas_ " << abs32_target_rvas_.size()
<< "\nrel32_target_rvas_ " << rel32_target_rvas_.size();

int common = 0;
std::map<RVA, int>::iterator abs32_iter = abs32_target_rvas_.begin();
std::map<RVA, int>::iterator rel32_iter = rel32_target_rvas_.begin();
while (abs32_iter != abs32_target_rvas_.end() &&
rel32_iter != rel32_target_rvas_.end()) {
if (abs32_iter->first < rel32_iter->first) {
++abs32_iter;
} else if (rel32_iter->first < abs32_iter->first) {
++rel32_iter;
} else {
++common;
++abs32_iter;
++rel32_iter;
}
}
VLOG(1) << "common " << common;
#endif
}

CheckBool DisassemblerWin32::ParseNonSectionFileRegion(
FileOffset start_file_offset,
FileOffset end_file_offset,
Expand Down
5 changes: 3 additions & 2 deletions courgette/disassembler_win32.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ class DisassemblerWin32 : public Disassembler {
// which will be checked against the detected one.
static bool QuickDetect(const uint8_t* start, size_t length, uint16_t magic);

bool ParseAbs32Relocs();
void ParseRel32RelocsFromSections();

// Disassembler interfaces.
RvaVisitor* CreateAbs32TargetRvaVisitor() override;
RvaVisitor* CreateRel32TargetRvaVisitor() override;
Expand All @@ -65,8 +68,6 @@ class DisassemblerWin32 : public Disassembler {

CheckBool ParseFile(AssemblyProgram* target,
InstructionReceptor* receptor) const WARN_UNUSED_RESULT;
bool ParseAbs32Relocs();
void ParseRel32RelocsFromSections();
virtual void ParseRel32RelocsFromSection(const Section* section) = 0;

CheckBool ParseNonSectionFileRegion(FileOffset start_file_offset,
Expand Down

0 comments on commit dc779d9

Please sign in to comment.