aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Object/Archive.cpp
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2015-07-14 22:18:43 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2015-07-14 22:18:43 +0000
commit4b83cb5390c7c66a74bc39a9ec85d804695b14c3 (patch)
treec4cd019d82af12d73a38b475e76cb40a5056280e /llvm/lib/Object/Archive.cpp
parent4154ad467b177729ffbbc90ab0799cfc08b9b04d (diff)
downloadllvm-4b83cb5390c7c66a74bc39a9ec85d804695b14c3.zip
llvm-4b83cb5390c7c66a74bc39a9ec85d804695b14c3.tar.gz
llvm-4b83cb5390c7c66a74bc39a9ec85d804695b14c3.tar.bz2
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
Diffstat (limited to 'llvm/lib/Object/Archive.cpp')
-rw-r--r--llvm/lib/Object/Archive.cpp23
1 files changed, 22 insertions, 1 deletions
diff --git a/llvm/lib/Object/Archive.cpp b/llvm/lib/Object/Archive.cpp
index c29e639..d482119 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<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>>