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
This commit is contained in:
Rafael Espindola
2015-07-14 22:18:43 +00:00
parent 4154ad467b
commit 4b83cb5390
4 changed files with 39 additions and 7 deletions

View File

@@ -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<StringRef> Archive::Child::getBuffer() const {
if (!Parent->IsThin)
return StringRef(Data.data() + StartOfFile, getSize());
ErrorOr<StringRef> 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<std::unique_ptr<MemoryBuffer>> 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<MemoryBufferRef> Archive::Child::getMemoryBufferRef() const {
if (std::error_code EC = NameOrErr.getError())
return EC;
StringRef Name = NameOrErr.get();
return MemoryBufferRef(getBuffer(), Name);
ErrorOr<StringRef> Buf = getBuffer();
if (std::error_code EC = Buf.getError())
return EC;
return MemoryBufferRef(*Buf, Name);
}
ErrorOr<std::unique_ptr<Binary>>