aboutsummaryrefslogtreecommitdiff
path: root/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp')
-rw-r--r--llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp46
1 files changed, 42 insertions, 4 deletions
diff --git a/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp b/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp
index ac61ffe..bd1d9ac 100644
--- a/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp
+++ b/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp
@@ -10,6 +10,7 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/BinaryFormat/Magic.h"
#include "llvm/Object/ArchiveWriter.h"
#include "llvm/Object/MachO.h"
#include "llvm/Object/ObjectFile.h"
@@ -58,11 +59,26 @@ static Error verifyMachOObject(const NewArchiveMember &Member) {
return Error::success();
}
-static Error addMember(std::vector<NewArchiveMember> &Members,
- StringRef FileName) {
+static Error addChildMember(std::vector<NewArchiveMember> &Members,
+ const object::Archive::Child &M) {
Expected<NewArchiveMember> NMOrErr =
- NewArchiveMember::getFile(FileName, /*Deterministic=*/true);
+ NewArchiveMember::getOldMember(M, /*Deterministic=*/true);
+ if (!NMOrErr)
+ return NMOrErr.takeError();
+
+ // Verify that Member is a Mach-O object file.
+ if (Error E = verifyMachOObject(*NMOrErr))
+ return E;
+
+ Members.push_back(std::move(*NMOrErr));
+ return Error::success();
+}
+static Error
+addMember(std::vector<NewArchiveMember> &Members, StringRef FileName,
+ std::vector<std::unique_ptr<MemoryBuffer>> &ArchiveBuffers) {
+ Expected<NewArchiveMember> NMOrErr =
+ NewArchiveMember::getFile(FileName, /*Deterministic=*/true);
if (!NMOrErr)
return createFileError(FileName, NMOrErr.takeError());
@@ -70,6 +86,27 @@ static Error addMember(std::vector<NewArchiveMember> &Members,
// name.
NMOrErr->MemberName = sys::path::filename(NMOrErr->MemberName);
+ // Flatten archives.
+ if (identify_magic(NMOrErr->Buf->getBuffer()) == file_magic::archive) {
+ Expected<std::unique_ptr<Archive>> LibOrErr =
+ object::Archive::create(NMOrErr->Buf->getMemBufferRef());
+ if (!LibOrErr)
+ return createFileError(FileName, LibOrErr.takeError());
+ object::Archive &Lib = **LibOrErr;
+
+ Error Err = Error::success();
+ for (const object::Archive::Child &Child : Lib.children(Err))
+ if (Error E = addChildMember(Members, Child))
+ return createFileError(FileName, std::move(E));
+ if (Err)
+ return createFileError(FileName, std::move(Err));
+
+ // Update vector ArchiveBuffers with the MemoryBuffers to transfer
+ // ownership.
+ ArchiveBuffers.push_back(std::move(NMOrErr->Buf));
+ return Error::success();
+ }
+
// Verify that Member is a Mach-O object file.
if (Error E = verifyMachOObject(*NMOrErr))
return E;
@@ -80,8 +117,9 @@ static Error addMember(std::vector<NewArchiveMember> &Members,
static Error createStaticLibrary() {
std::vector<NewArchiveMember> NewMembers;
+ std::vector<std::unique_ptr<MemoryBuffer>> ArchiveBuffers;
for (StringRef Member : InputFiles)
- if (Error E = addMember(NewMembers, Member))
+ if (Error E = addMember(NewMembers, Member, ArchiveBuffers))
return E;
if (Error E = writeArchive(OutputFile, NewMembers,