[lld] r221544 - Fix FileArchive member MemoryBuffer early destruction

Nick Kledzik kledzik at apple.com
Fri Nov 7 12:52:38 PST 2014


Author: kledzik
Date: Fri Nov  7 14:52:38 2014
New Revision: 221544

URL: http://llvm.org/viewvc/llvm-project?rev=221544&view=rev
Log:
Fix FileArchive member MemoryBuffer early destruction

When FileArchive loads a member, it instantiates a temporary MemoryBuffer
which points to the member range of the archive file.  The problem is that the
object file parsers call getBufferIndentifer() on that temporary MemoryBuffer
and store that StringRef as the _path data member for that lld::File.  When
FileArchive::instantiateMember() goes out of scope the MemoryBuffer is deleted
and the File::._path becomes a dangling reference.

The fix adds a vector<> to FileArchive to own the instantiated MemoryBuffers.
In addition it fixes member's path to be the standard format
(e.g. "/path/libfoo.a(foo.o)") instead of just the leaf name.

Modified:
    lld/trunk/lib/ReaderWriter/FileArchive.cpp

Modified: lld/trunk/lib/ReaderWriter/FileArchive.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/FileArchive.cpp?rev=221544&r1=221543&r2=221544&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/FileArchive.cpp (original)
+++ lld/trunk/lib/ReaderWriter/FileArchive.cpp Fri Nov  7 14:52:38 2014
@@ -133,18 +133,27 @@ private:
     if (std::error_code ec = mbOrErr.getError())
       return ec;
     llvm::MemoryBufferRef mb = mbOrErr.get();
+    std::string memberPath = (_archive->getFileName() + "("
+                           + mb.getBufferIdentifier() + ")").str();
+
     if (_logLoading)
-      llvm::outs() << _archive->getFileName() << "(" << mb.getBufferIdentifier()
-                   << ")"
-                   << "\n";
+      llvm::errs() << memberPath << "\n";
 
-    std::unique_ptr<MemoryBuffer> buf(MemoryBuffer::getMemBuffer(
-        mb.getBuffer(), mb.getBufferIdentifier(), false));
+    std::unique_ptr<MemoryBuffer> memberMB(MemoryBuffer::getMemBuffer(
+        mb.getBuffer(), memberPath, false));
 
     std::vector<std::unique_ptr<File>> files;
-    _registry.parseFile(buf, files);
+    _registry.parseFile(memberMB, files);
     assert(files.size() == 1);
     result = std::move(files[0]);
+
+    // Note: The object file parsers use getBufferIdentifier() from memberMB
+    // for the file path. And MemoryBuffer makes its own copy of the path.
+    // That means when if memberMB is destroyed, the lld:File objects will
+    // have a dangling reference for their path.  To fix that, all the
+    // MemoryBuffers for the archive members are owned by _memberBuffers.
+    _memberBuffers.push_back(std::move(memberMB));
+
     return std::error_code();
   }
 
@@ -205,6 +214,7 @@ private:
   atom_collection_vector<AbsoluteAtom> _absoluteAtoms;
   bool _isWholeArchive;
   bool _logLoading;
+  mutable std::vector<std::unique_ptr<MemoryBuffer>> _memberBuffers;
 };
 
 class ArchiveReader : public Reader {





More information about the llvm-commits mailing list