mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-25 14:46:07 +00:00
[BOLT] Fix memory leak in BinarySection (#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.
This commit is contained in:
parent
baf6bd303b
commit
5daf2001a1
@ -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 @@ public:
|
||||
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;
|
||||
}
|
||||
|
@ -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); }
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user