[lld] r175558 - [ELF] Fix memory leak by deleting BumpPtr allocated objects.

Michael J. Spencer bigcheesegs at gmail.com
Tue Feb 19 13:04:30 PST 2013


Author: mspencer
Date: Tue Feb 19 15:04:30 2013
New Revision: 175558

URL: http://llvm.org/viewvc/llvm-project?rev=175558&view=rev
Log:
[ELF] Fix memory leak by deleting BumpPtr allocated objects.

Added:
    lld/trunk/include/lld/Core/STDExtras.h
Modified:
    lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h
    lld/trunk/lib/ReaderWriter/ELF/DynamicFile.h
    lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h
    lld/trunk/lib/ReaderWriter/ELF/Writer.cpp

Added: lld/trunk/include/lld/Core/STDExtras.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/STDExtras.h?rev=175558&view=auto
==============================================================================
--- lld/trunk/include/lld/Core/STDExtras.h (added)
+++ lld/trunk/include/lld/Core/STDExtras.h Tue Feb 19 15:04:30 2013
@@ -0,0 +1,33 @@
+//===- lld/Core/STDExtra.h - Helpers for the stdlib -----------------------===//
+//
+//                             The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLD_CORE_STD_EXTRA_H
+#define LLD_CORE_STD_EXTRA_H
+
+namespace lld {
+/// \brief Deleter for smart pointers that only calls the destructor. Memory is
+/// managed elsewhere. A common use of this is for things allocated with a
+/// BumpPtrAllocator.
+template <class T>
+struct destruct_delete {
+  void operator ()(T *ptr) {
+    ptr->~T();
+  }
+};
+
+// Sadly VS 2012 doesn't support template aliases.
+// template <class T>
+// using unique_bump_ptr = std::unique_ptr<T, destruct_delete<T>>;
+
+#define LLD_UNIQUE_BUMP_PTR(...) \
+  std::unique_ptr<__VA_ARGS__, destruct_delete<__VA_ARGS__>>
+
+} // end namespace lld
+
+#endif

Modified: lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h?rev=175558&r1=175557&r2=175558&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h Tue Feb 19 15:04:30 2013
@@ -17,6 +17,7 @@
 #include "SegmentChunks.h"
 
 #include "lld/Core/LinkerOptions.h"
+#include "lld/Core/STDExtras.h"
 
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/DenseMap.h"
@@ -240,11 +241,11 @@ public:
   RelocationTable<ELFT> *getRelocationTable() {
     // Only create the relocation table if it is needed.
     if (!_relocationTable) {
-      _relocationTable = new (_allocator)
-          RelocationTable<ELFT>(_targetInfo, ".rela.plt", ORDER_REL);
-      addSection(_relocationTable);
+      _relocationTable.reset(new (_allocator)
+          RelocationTable<ELFT>(_targetInfo, ".rela.plt", ORDER_REL));
+      addSection(_relocationTable.get());
     }
-    return _relocationTable;
+    return _relocationTable.get();
   }
 
   uint64_t getTLSSize() const {
@@ -262,6 +263,7 @@ protected:
       SectionOrder sectionOrder);
 
 private:
+  llvm::BumpPtrAllocator _allocator;
   SectionMapT _sectionMap;
   MergedSectionMapT _mergedSectionMap;
   SegmentMapT _segmentMap;
@@ -270,9 +272,8 @@ private:
   std::vector<MergedSections<ELFT> *> _mergedSections;
   Header<ELFT> *_header;
   ProgramHeader<ELFT> *_programHeader;
-  RelocationTable<ELFT> *_relocationTable;
+  LLD_UNIQUE_BUMP_PTR(RelocationTable<ELFT>) _relocationTable;
   std::vector<AtomLayout *> _absoluteAtoms;
-  llvm::BumpPtrAllocator _allocator;
   const ELFTargetInfo &_targetInfo;
 };
 

Modified: lld/trunk/lib/ReaderWriter/ELF/DynamicFile.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/DynamicFile.h?rev=175558&r1=175557&r2=175558&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/DynamicFile.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/DynamicFile.h Tue Feb 19 15:04:30 2013
@@ -109,6 +109,7 @@ private:
   DynamicFile(const ELFTargetInfo &ti, StringRef name)
       : SharedLibraryFile(name), _targetInfo(ti) {}
 
+  mutable llvm::BumpPtrAllocator _alloc;
   const ELFTargetInfo &_targetInfo;
   std::unique_ptr<llvm::object::ELFObjectFile<ELFT>> _objFile;
   atom_collection_vector<DefinedAtom> _definedAtoms;
@@ -119,13 +120,12 @@ private:
   StringRef _soname;
 
   struct SymAtomPair {
-    const typename llvm::object::ELFObjectFile<ELFT>::Elf_Sym *_symbol =
-        nullptr;
-    const SharedLibraryAtom *_atom = nullptr;
+    SymAtomPair() : _symbol(nullptr), _atom(nullptr) {}
+    const typename llvm::object::ELFObjectFile<ELFT>::Elf_Sym *_symbol;
+    const SharedLibraryAtom *_atom;
   };
 
   mutable std::unordered_map<StringRef, SymAtomPair> _nameToSym;
-  mutable llvm::BumpPtrAllocator _alloc;
 };
 } // end namespace elf
 } // end namespace lld

Modified: lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h?rev=175558&r1=175557&r2=175558&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h Tue Feb 19 15:04:30 2013
@@ -557,9 +557,9 @@ public:
   void setStringSection(StringTable<ELFT> *s) { _stringSection = s; }
 
 private:
+  llvm::BumpPtrAllocator _symbolAllocate;
   StringTable<ELFT> *_stringSection;
   std::vector<Elf_Sym*> _symbolTable;
-  llvm::BumpPtrAllocator _symbolAllocate;
 };
 
 /// ELF Symbol Table 

Modified: lld/trunk/lib/ReaderWriter/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Writer.cpp?rev=175558&r1=175557&r2=175558&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Writer.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Writer.cpp Tue Feb 19 15:04:30 2013
@@ -52,19 +52,20 @@ private:
 
   void createDefaultSections();
 
+  llvm::BumpPtrAllocator _alloc;
+
   const ELFTargetInfo &_targetInfo;
   TargetHandler<ELFT> &_targetHandler;
 
   typedef llvm::DenseMap<const Atom *, uint64_t> AtomToAddress;
   AtomToAddress _atomToAddressMap;
-  llvm::BumpPtrAllocator _chunkAllocate;
   TargetLayout<ELFT> *_layout;
-  Header<ELFT> *_Header;
-  ProgramHeader<ELFT> *_programHeader;
-  SymbolTable<ELFT> * _symtab;
-  StringTable<ELFT> *_strtab;
-  StringTable<ELFT> *_shstrtab;
-  SectionHeader<ELFT> *_shdrtab;
+  LLD_UNIQUE_BUMP_PTR(Header<ELFT>) _Header;
+  LLD_UNIQUE_BUMP_PTR(ProgramHeader<ELFT>) _programHeader;
+  LLD_UNIQUE_BUMP_PTR(SymbolTable<ELFT>) _symtab;
+  LLD_UNIQUE_BUMP_PTR(StringTable<ELFT>) _strtab;
+  LLD_UNIQUE_BUMP_PTR(StringTable<ELFT>) _shstrtab;
+  LLD_UNIQUE_BUMP_PTR(SectionHeader<ELFT>) _shdrtab;
   CRuntimeFile<ELFT> _runtimeFile;
 };
 
@@ -282,7 +283,7 @@ ExecutableWriter<ELFT>::writeFile(const
     _Header->e_version(1);
   } else {
     // override the contents of the ELF Header
-    _targetHandler.setHeaderInfo(_Header);
+    _targetHandler.setHeaderInfo(_Header.get());
   }
   _Header->e_phoff(_programHeader->fileOffset());
   _Header->e_shoff(_shdrtab->fileOffset());
@@ -309,25 +310,25 @@ ExecutableWriter<ELFT>::writeFile(const
 
 template<class ELFT>
 void ExecutableWriter<ELFT>::createDefaultSections() {
-  _Header = new Header<ELFT>(_targetInfo);
-  _programHeader = new ProgramHeader<ELFT>(_targetInfo);
-  _layout->setHeader(_Header);
-  _layout->setProgramHeader(_programHeader);
-
-  _symtab = new SymbolTable<
-      ELFT>(_targetInfo, ".symtab", DefaultLayout<ELFT>::ORDER_SYMBOL_TABLE);
-  _strtab = new StringTable<
-      ELFT>(_targetInfo, ".strtab", DefaultLayout<ELFT>::ORDER_STRING_TABLE);
-  _shstrtab = new StringTable<ELFT>(
-      _targetInfo, ".shstrtab", DefaultLayout<ELFT>::ORDER_SECTION_STRINGS);
-  _shdrtab = new SectionHeader<
-      ELFT>(_targetInfo, DefaultLayout<ELFT>::ORDER_SECTION_HEADERS);
-  _layout->addSection(_symtab);
-  _layout->addSection(_strtab);
-  _layout->addSection(_shstrtab);
-  _shdrtab->setStringSection(_shstrtab);
-  _symtab->setStringSection(_strtab);
-  _layout->addSection(_shdrtab);
+  _Header.reset(new (_alloc) Header<ELFT>(_targetInfo));
+  _programHeader.reset(new (_alloc) ProgramHeader<ELFT>(_targetInfo));
+  _layout->setHeader(_Header.get());
+  _layout->setProgramHeader(_programHeader.get());
+
+  _symtab.reset(new (_alloc) SymbolTable<ELFT>(
+      _targetInfo, ".symtab", DefaultLayout<ELFT>::ORDER_SYMBOL_TABLE));
+  _strtab.reset(new (_alloc) StringTable<ELFT>(
+      _targetInfo, ".strtab", DefaultLayout<ELFT>::ORDER_STRING_TABLE));
+  _shstrtab.reset(new (_alloc) StringTable<ELFT>(
+      _targetInfo, ".shstrtab", DefaultLayout<ELFT>::ORDER_SECTION_STRINGS));
+  _shdrtab.reset(new (_alloc) SectionHeader<ELFT>(
+      _targetInfo, DefaultLayout<ELFT>::ORDER_SECTION_HEADERS));
+  _layout->addSection(_symtab.get());
+  _layout->addSection(_strtab.get());
+  _layout->addSection(_shstrtab.get());
+  _shdrtab->setStringSection(_shstrtab.get());
+  _symtab->setStringSection(_strtab.get());
+  _layout->addSection(_shdrtab.get());
 
   // give a chance for the target to add sections
   _targetHandler.createDefaultSections();





More information about the llvm-commits mailing list