diff options
author | huangs <huangs@chromium.org> | 2016-01-18 11:47:17 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-01-18 19:48:40 +0000 |
commit | 5748c10c40dc3fd3cf50be8a24c79ae3c7cb9b36 (patch) | |
tree | 20a31edc5418f08e382791aab08f25777acc610b /courgette | |
parent | 94cc14f85c504d884a1258f3970fb1b3ad957efd (diff) | |
download | chromium_src-5748c10c40dc3fd3cf50be8a24c79ae3c7cb9b36.zip chromium_src-5748c10c40dc3fd3cf50be8a24c79ae3c7cb9b36.tar.gz chromium_src-5748c10c40dc3fd3cf50be8a24c79ae3c7cb9b36.tar.bz2 |
[Courgette] Fix memory leak in AssemblyProgram::TrimLabels().
The leaky code is only used by EXE_ELF_32_ARM flow.
In AssemblyProgram::TrimLabels(), originally we (A) remove underused
Labels from std::map<RVA, Label*> that stores it, (B) convert all
instructions that use underused Labels to a non-Label instruction.
Problem is (A) does not deallocate Label* (owned by the std::map),
and memory leak ensues.
Naively deallocating Labels in (A) would lead to use-after free.
So we do (B) first, then do (A) while deallocating Label*.
Review URL: https://codereview.chromium.org/1570173003
Cr-Commit-Position: refs/heads/master@{#370045}
Diffstat (limited to 'courgette')
-rw-r--r-- | courgette/assembly_program.cc | 29 |
1 files changed, 13 insertions, 16 deletions
diff --git a/courgette/assembly_program.cc b/courgette/assembly_program.cc index 0767892..28a348e 100644 --- a/courgette/assembly_program.cc +++ b/courgette/assembly_program.cc @@ -502,7 +502,7 @@ Instruction* AssemblyProgram::GetByteInstruction(uint8_t byte) { const int AssemblyProgram::kLabelLowerLimit = 5; CheckBool AssemblyProgram::TrimLabels() { - // For now only trim for ARM binaries + // For now only trim for ARM binaries. if (kind() != EXE_ELF_32_ARM) return true; @@ -510,22 +510,8 @@ CheckBool AssemblyProgram::TrimLabels() { VLOG(1) << "TrimLabels: threshold " << lower_limit; - // Remove underused labels from the list of labels - RVAToLabel::iterator it = rel32_labels_.begin(); - while (it != rel32_labels_.end()) { - if (it->second->count_ <= lower_limit) { - // Note: it appears to me (grt) that this leaks the Label instances. I - // *think* the right thing would be to add it->second to a collection for - // which all elements are freed via UncheckedDelete after the instruction - // fixup loop below. - rel32_labels_.erase(it++); - } else { - ++it; - } - } - // Walk through the list of instructions, replacing trimmed labels - // with the original machine instruction + // with the original machine instruction. for (size_t i = 0; i < instructions_.size(); ++i) { Instruction* instruction = instructions_[i]; switch (instruction->op()) { @@ -552,6 +538,17 @@ CheckBool AssemblyProgram::TrimLabels() { } } + // Remove and deallocate underused Labels. + RVAToLabel::iterator it = rel32_labels_.begin(); + while (it != rel32_labels_.end()) { + if (it->second->count_ <= lower_limit) { + UncheckedDelete(it->second); + rel32_labels_.erase(it++); + } else { + ++it; + } + } + return true; } |