From 4b83cb5390c7c66a74bc39a9ec85d804695b14c3 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Tue, 14 Jul 2015 22:18:43 +0000 Subject: Add support for reading members out of thin archives. For now the Archive owns the buffers of the thin archive members. This makes for a simple API, but all the buffers are destructed only when the archive is destructed. This should be fine since we close the files after mmap so we should not hit an open file limit. llvm-svn: 242215 --- llvm/lib/Object/Archive.cpp | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'llvm/lib/Object') diff --git a/llvm/lib/Object/Archive.cpp b/llvm/lib/Object/Archive.cpp index c29e63941f2..d4821196a6c 100644 --- a/llvm/lib/Object/Archive.cpp +++ b/llvm/lib/Object/Archive.cpp @@ -17,6 +17,7 @@ #include "llvm/ADT/Twine.h" #include "llvm/Support/Endian.h" #include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/Path.h" using namespace llvm; using namespace object; @@ -115,6 +116,23 @@ uint64_t Archive::Child::getRawSize() const { return getHeader()->getSize(); } +ErrorOr Archive::Child::getBuffer() const { + if (!Parent->IsThin) + return StringRef(Data.data() + StartOfFile, getSize()); + ErrorOr Name = getName(); + if (std::error_code EC = Name.getError()) + return EC; + SmallString<128> FullName = + Parent->getMemoryBufferRef().getBufferIdentifier(); + sys::path::remove_filename(FullName); + sys::path::append(FullName, *Name); + ErrorOr> Buf = MemoryBuffer::getFile(FullName); + if (std::error_code EC = Buf.getError()) + return EC; + Parent->ThinBuffers.push_back(std::move(*Buf)); + return Parent->ThinBuffers.back()->getBuffer(); +} + Archive::Child Archive::Child::getNext() const { size_t SpaceToSkip = Data.size(); // If it's odd, add 1 to make it even. @@ -186,7 +204,10 @@ ErrorOr Archive::Child::getMemoryBufferRef() const { if (std::error_code EC = NameOrErr.getError()) return EC; StringRef Name = NameOrErr.get(); - return MemoryBufferRef(getBuffer(), Name); + ErrorOr Buf = getBuffer(); + if (std::error_code EC = Buf.getError()) + return EC; + return MemoryBufferRef(*Buf, Name); } ErrorOr> -- cgit v1.2.3