Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1670)

Unified Diff: courgette/disassembler_elf_32.cc

Issue 1935203002: [Courgette] Using LabelManager to reduce Courgette-apply peak RAM by 25%. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Sync. Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « courgette/disassembler_elf_32.h ('k') | courgette/disassembler_elf_32_arm.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: courgette/disassembler_elf_32.cc
diff --git a/courgette/disassembler_elf_32.cc b/courgette/disassembler_elf_32.cc
index d9d5043b2fdbae0bf5938c4675a7585509cdfeec..febcdeabef504e2c540c9d65dde763fbb093b776 100644
--- a/courgette/disassembler_elf_32.cc
+++ b/courgette/disassembler_elf_32.cc
@@ -5,6 +5,7 @@
#include "courgette/disassembler_elf_32.h"
#include <algorithm>
+#include <iterator>
#include <utility>
#include "base/logging.h"
@@ -33,6 +34,15 @@ std::vector<Elf32_Half> GetSectionHeaderFileOffsetOrder(
} // namespace
+DisassemblerElf32::Elf32RvaVisitor_Rel32::Elf32RvaVisitor_Rel32(
+ const std::vector<std::unique_ptr<TypedRVA>>& rva_locations)
+ : VectorRvaVisitor<std::unique_ptr<TypedRVA>>(rva_locations) {
+}
+
+RVA DisassemblerElf32::Elf32RvaVisitor_Rel32::Get() const {
+ return (*it_)->rva() + (*it_)->relative_target();
+}
+
DisassemblerElf32::DisassemblerElf32(const void* start, size_t length)
: Disassembler(start, length),
header_(nullptr),
@@ -164,12 +174,16 @@ bool DisassemblerElf32::Disassemble(AssemblyProgram* target) {
if (!ParseAbs32Relocs())
return false;
- if (!ParseRel32RelocsFromSections())
+ if (!ParseRel32RelocsFromSections()) // Does not sort rel32 locations.
return false;
+ PrecomputeLabels(target);
+ RemoveUnusedRel32Locations(target);
+
if (!ParseFile(target))
return false;
+ // Finally sort rel32 locations.
std::sort(rel32_locations_.begin(),
rel32_locations_.end(),
TypedRVA::IsLessThanByRVA);
@@ -180,6 +194,28 @@ bool DisassemblerElf32::Disassemble(AssemblyProgram* target) {
return true;
}
+CheckBool DisassemblerElf32::IsValidTargetRVA(RVA rva) const {
+ if (rva == kUnassignedRVA)
+ return false;
+
+ // |rva| is valid if it's contained in any program segment.
+ for (Elf32_Half segment_id = 0; segment_id < ProgramSegmentHeaderCount();
+ ++segment_id) {
+ const Elf32_Phdr* segment_header = ProgramSegmentHeader(segment_id);
+
+ if (segment_header->p_type != PT_LOAD)
+ continue;
+
+ Elf32_Addr begin = segment_header->p_vaddr;
+ Elf32_Addr end = segment_header->p_vaddr + segment_header->p_memsz;
+
+ if (rva >= begin && rva < end)
+ return true;
+ }
+
+ return false;
+}
+
bool DisassemblerElf32::UpdateLength() {
Elf32_Off result = 0;
@@ -238,32 +274,11 @@ CheckBool DisassemblerElf32::SectionName(const Elf32_Shdr& shdr,
return true;
}
-CheckBool DisassemblerElf32::IsValidTargetRVA(RVA rva) const {
- if (rva == kUnassignedRVA)
- return false;
-
- // It's valid if it's contained in any program segment
- for (Elf32_Half segment_id = 0; segment_id < ProgramSegmentHeaderCount();
- ++segment_id) {
- const Elf32_Phdr* segment_header = ProgramSegmentHeader(segment_id);
-
- if (segment_header->p_type != PT_LOAD)
- continue;
-
- Elf32_Addr begin = segment_header->p_vaddr;
- Elf32_Addr end = segment_header->p_vaddr + segment_header->p_memsz;
-
- if (rva >= begin && rva < end)
- return true;
- }
-
- return false;
-}
-
CheckBool DisassemblerElf32::RVAsToFileOffsets(
const std::vector<RVA>& rvas,
std::vector<FileOffset>* file_offsets) {
file_offsets->clear();
+ file_offsets->reserve(rvas.size());
for (RVA rva : rvas) {
FileOffset file_offset = RVAToFileOffset(rva);
if (file_offset == kNoFileOffset)
@@ -284,6 +299,32 @@ CheckBool DisassemblerElf32::RVAsToFileOffsets(
return true;
}
+RvaVisitor* DisassemblerElf32::CreateAbs32TargetRvaVisitor() {
+ return new RvaVisitor_Abs32(abs32_locations_, *this);
+}
+
+RvaVisitor* DisassemblerElf32::CreateRel32TargetRvaVisitor() {
+ return new Elf32RvaVisitor_Rel32(rel32_locations_);
+}
+
+void DisassemblerElf32::RemoveUnusedRel32Locations(AssemblyProgram* program) {
+ auto tail_it = rel32_locations_.begin();
+ for (auto head_it = rel32_locations_.begin();
+ head_it != rel32_locations_.end(); ++head_it) {
+ RVA target_rva = (*head_it)->rva() + (*head_it)->relative_target();
+ if (program->FindRel32Label(target_rva) == nullptr) {
+ // If address does not match a Label (because it was removed), deallocate.
+ (*head_it).reset(nullptr);
+ } else {
+ // Else squeeze nullptr to end to compactify.
+ if (tail_it != head_it)
+ (*tail_it).swap(*head_it);
+ ++tail_it;
+ }
+ }
+ rel32_locations_.resize(std::distance(rel32_locations_.begin(), tail_it));
+}
+
CheckBool DisassemblerElf32::ParseFile(AssemblyProgram* program) {
// Walk all the bytes in the file, whether or not in a section.
FileOffset file_offset = 0;
@@ -425,7 +466,9 @@ CheckBool DisassemblerElf32::ParseProgbitsSection(
RVA target_rva = PointerToTargetRVA(FileOffsetToPointer(file_offset));
DCHECK_NE(kNoRVA, target_rva);
- if (!program->EmitAbs32(program->FindOrMakeAbs32Label(target_rva)))
+ Label* label = program->FindAbs32Label(target_rva);
+ CHECK(label);
+ if (!program->EmitAbs32(label))
return false;
file_offset += sizeof(RVA);
++(*current_abs_offset);
@@ -435,12 +478,17 @@ CheckBool DisassemblerElf32::ParseProgbitsSection(
if (*current_rel != end_rel &&
file_offset == (**current_rel)->file_offset()) {
uint32_t relative_target = (**current_rel)->relative_target();
+ CHECK_EQ(RVA(origin + (file_offset - origin_offset)),
+ (**current_rel)->rva());
// This cast is for 64 bit systems, and is only safe because we
// are working on 32 bit executables.
RVA target_rva = (RVA)(origin + (file_offset - origin_offset) +
relative_target);
- if (!(**current_rel)->EmitInstruction(program, target_rva))
+ Label* label = program->FindRel32Label(target_rva);
+ CHECK(label);
+
+ if (!(**current_rel)->EmitInstruction(program, label))
return false;
file_offset += (**current_rel)->op_size();
++(*current_rel);
« no previous file with comments | « courgette/disassembler_elf_32.h ('k') | courgette/disassembler_elf_32_arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698