summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNick Kledzik <kledzik@apple.com>2014-11-07 20:52:38 +0000
committerNick Kledzik <kledzik@apple.com>2014-11-07 20:52:38 +0000
commit7bcfe288a81f2225b8c2e09c079a298450fd4ef1 (patch)
treebb263ea26df3f8426ac6dfcf2caefb96c5aff6fb
parent23755997e460714d46335de97701552ce0244317 (diff)
downloadbcm5719-llvm-7bcfe288a81f2225b8c2e09c079a298450fd4ef1.tar.gz
bcm5719-llvm-7bcfe288a81f2225b8c2e09c079a298450fd4ef1.zip
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. llvm-svn: 221544
-rw-r--r--lld/lib/ReaderWriter/FileArchive.cpp22
1 files changed, 16 insertions, 6 deletions
diff --git a/lld/lib/ReaderWriter/FileArchive.cpp b/lld/lib/ReaderWriter/FileArchive.cpp
index 15c4cc6f334..a76399e57d0 100644
--- a/lld/lib/ReaderWriter/FileArchive.cpp
+++ b/lld/lib/ReaderWriter/FileArchive.cpp
@@ -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 {
OpenPOWER on IntegriCloud