[llvm] [BOLT] Fix memory leak in BinarySection (PR #82520)
Maksim Panchenko via llvm-commits
llvm-commits at lists.llvm.org
Wed Feb 21 10:49:05 PST 2024
https://github.com/maksfb created https://github.com/llvm/llvm-project/pull/82520
The change in #80950 exposed a memory leak in BinarySection. Let BinarySection manage memory passed via updateContents() unless a valid SectionID is set indicating that the contents are managed by JITLink.
>From 33341e03e501eb19f52ce963d25be6bd95c611aa Mon Sep 17 00:00:00 2001
From: Maksim Panchenko <maks at fb.com>
Date: Wed, 21 Feb 2024 00:22:48 -0800
Subject: [PATCH] [BOLT] Fix memory leak in BinarySection
The change in #80950 exposed a memory leak in BinarySection. Let
BinarySection manage memory passed via updateContents() unless a valid
SectionID is set indicating that the contents are managed by JITLink.
---
bolt/include/bolt/Core/BinarySection.h | 20 +++++++++++++-------
bolt/lib/Core/BinarySection.cpp | 13 +------------
bolt/lib/Rewrite/RewriteInstance.cpp | 9 +++------
bolt/unittests/Core/BinaryContext.cpp | 9 +++++----
4 files changed, 22 insertions(+), 29 deletions(-)
diff --git a/bolt/include/bolt/Core/BinarySection.h b/bolt/include/bolt/Core/BinarySection.h
index a85dbf28950e31..0f179877bd3df3 100644
--- a/bolt/include/bolt/Core/BinarySection.h
+++ b/bolt/include/bolt/Core/BinarySection.h
@@ -139,10 +139,7 @@ class BinarySection {
Alignment = NewAlignment;
ELFType = NewELFType;
ELFFlags = NewELFFlags;
- OutputSize = NewSize;
- OutputContents = StringRef(reinterpret_cast<const char *>(NewData),
- NewData ? NewSize : 0);
- IsFinalized = true;
+ updateContents(NewData, NewSize);
}
public:
@@ -484,9 +481,18 @@ class BinarySection {
void flushPendingRelocations(raw_pwrite_stream &OS,
SymbolResolverFuncTy Resolver);
- /// Change contents of the section.
- void updateContents(const uint8_t *Data, size_t NewSize) {
- OutputContents = StringRef(reinterpret_cast<const char *>(Data), NewSize);
+ /// Change contents of the section. Unless the section has a valid SectionID,
+ /// the memory passed in \p NewData will be managed by the instance of
+ /// BinarySection.
+ void updateContents(const uint8_t *NewData, size_t NewSize) {
+ if (getOutputData() && !hasValidSectionID() &&
+ (!hasSectionRef() ||
+ OutputContents.data() != getContentsOrQuit(Section).data())) {
+ delete[] getOutputData();
+ }
+
+ OutputContents = StringRef(reinterpret_cast<const char *>(NewData),
+ NewData ? NewSize : 0);
OutputSize = NewSize;
IsFinalized = true;
}
diff --git a/bolt/lib/Core/BinarySection.cpp b/bolt/lib/Core/BinarySection.cpp
index 564c63e81914c3..9ad49ca1b3a038 100644
--- a/bolt/lib/Core/BinarySection.cpp
+++ b/bolt/lib/Core/BinarySection.cpp
@@ -190,18 +190,7 @@ void BinarySection::flushPendingRelocations(raw_pwrite_stream &OS,
clearList(PendingRelocations);
}
-BinarySection::~BinarySection() {
- if (isReordered()) {
- delete[] getData();
- return;
- }
-
- if (!isAllocatable() && !hasValidSectionID() &&
- (!hasSectionRef() ||
- OutputContents.data() != getContentsOrQuit(Section).data())) {
- delete[] getOutputData();
- }
-}
+BinarySection::~BinarySection() { updateContents(nullptr, 0); }
void BinarySection::clearRelocations() { clearList(Relocations); }
diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp
index 954c0fc86fa175..cde195c1739074 100644
--- a/bolt/lib/Rewrite/RewriteInstance.cpp
+++ b/bolt/lib/Rewrite/RewriteInstance.cpp
@@ -4092,12 +4092,9 @@ void RewriteInstance::rewriteNoteSections() {
return getNewValueForSymbol(S->getName());
});
- // Set/modify section info.
- BinarySection &NewSection = BC->registerOrUpdateNoteSection(
- SectionName, SectionData, Size, Section.sh_addralign,
- !BSec->isWritable(), BSec->getELFType());
- NewSection.setOutputAddress(0);
- NewSection.setOutputFileOffset(NextAvailableOffset);
+ // Section contents are no longer needed, but we need to update the size so
+ // that it will be reflected in the section header table.
+ BSec->updateContents(nullptr, Size);
NextAvailableOffset += Size;
}
diff --git a/bolt/unittests/Core/BinaryContext.cpp b/bolt/unittests/Core/BinaryContext.cpp
index 1fbb07bca966a7..94ee65e63a1dcf 100644
--- a/bolt/unittests/Core/BinaryContext.cpp
+++ b/bolt/unittests/Core/BinaryContext.cpp
@@ -77,10 +77,11 @@ TEST_P(BinaryContextTester, FlushPendingRelocCALL26) {
// 12: bl func2
// 16: func2
- char Data[20] = {};
+ constexpr size_t DataSize = 20;
+ uint8_t *Data = new uint8_t[DataSize];
BinarySection &BS = BC->registerOrUpdateSection(
- ".text", ELF::SHT_PROGBITS, ELF::SHF_EXECINSTR | ELF::SHF_ALLOC,
- (uint8_t *)Data, sizeof(Data), 4);
+ ".text", ELF::SHT_PROGBITS, ELF::SHF_EXECINSTR | ELF::SHF_ALLOC, Data,
+ DataSize, 4);
MCSymbol *RelSymbol1 = BC->getOrCreateGlobalSymbol(4, "Func1");
ASSERT_TRUE(RelSymbol1);
BS.addRelocation(8, RelSymbol1, ELF::R_AARCH64_CALL26, 0, 0, true);
@@ -89,7 +90,7 @@ TEST_P(BinaryContextTester, FlushPendingRelocCALL26) {
BS.addRelocation(12, RelSymbol2, ELF::R_AARCH64_CALL26, 0, 0, true);
std::error_code EC;
- SmallVector<char> Vect(sizeof(Data));
+ SmallVector<char> Vect(DataSize);
raw_svector_ostream OS(Vect);
BS.flushPendingRelocations(OS, [&](const MCSymbol *S) {
More information about the llvm-commits
mailing list