[lld] r221544 - Fix FileArchive member MemoryBuffer early destruction
David Blaikie
dblaikie at gmail.com
Tue Nov 11 15:15:03 PST 2014
On Fri, Nov 7, 2014 at 12:52 PM, Nick Kledzik <kledzik at apple.com> wrote:
> 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));
>
It's somewhat handy to use copy/move initialization rather than direct
initialization where possible. ie favor:
std::unique_ptr<MemoryBuffer> memberMB = MemoryBuffer::getMemBuffer(...);
over "memberMB(MemoryBuffer::getMemBuffer..." in this case.
That way it's clear that the function returns ownership via unique_ptr, not
raw pointer - and there's no risk of an explicit conversion from raw
pointer to unique_ptr occurring accidentally (while in this case it's
pretty clear/known that getMemBuffer returns ownership, writing it with
move initialization makes that more explicit).
>
> 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 {
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20141111/a11e0c60/attachment.html>
More information about the llvm-commits
mailing list