diff options
Diffstat (limited to 'llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp')
-rw-r--r-- | llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp | 79 |
1 files changed, 72 insertions, 7 deletions
diff --git a/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp b/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp index 3a08d18..1ff6328e 100644 --- a/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp +++ b/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp @@ -11,7 +11,9 @@ //===----------------------------------------------------------------------===// #include "llvm/BinaryFormat/Magic.h" +#include "llvm/IR/LLVMContext.h" #include "llvm/Object/ArchiveWriter.h" +#include "llvm/Object/IRObjectFile.h" #include "llvm/Object/MachO.h" #include "llvm/Object/MachOUniversal.h" #include "llvm/Object/MachOUniversalWriter.h" @@ -26,6 +28,8 @@ using namespace llvm; using namespace llvm::object; +static LLVMContext LLVMCtx; + typedef std::map<uint64_t, std::vector<NewArchiveMember>> MembersPerArchitectureMap; @@ -252,6 +256,38 @@ static Error verifyAndAddMachOObject(MembersPerArchitectureMap &Members, return Error::success(); } +static Error verifyAndAddIRObject(MembersPerArchitectureMap &Members, + NewArchiveMember Member, const Config &C) { + auto MBRef = Member.Buf->getMemBufferRef(); + Expected<std::unique_ptr<object::IRObjectFile>> IROrErr = + object::IRObjectFile::create(MBRef, LLVMCtx); + + // Throw error if not a valid IR object file. + if (!IROrErr) + return createFileError(Member.MemberName, IROrErr.takeError()); + + Triple TT = Triple(IROrErr->get()->getTargetTriple()); + + Expected<uint32_t> FileCPUTypeOrErr = MachO::getCPUType(TT); + if (!FileCPUTypeOrErr) + return FileCPUTypeOrErr.takeError(); + + Expected<uint32_t> FileCPUSubTypeOrErr = MachO::getCPUSubType(TT); + if (!FileCPUSubTypeOrErr) + return FileCPUSubTypeOrErr.takeError(); + + // If -arch_only is specified then skip this file if it doesn't match + // the architecture specified. + if (!ArchType.empty() && + !acceptFileArch(*FileCPUTypeOrErr, *FileCPUSubTypeOrErr, C)) { + return Error::success(); + } + + uint64_t FileCPUID = getCPUID(*FileCPUTypeOrErr, *FileCPUSubTypeOrErr); + Members[FileCPUID].push_back(std::move(Member)); + return Error::success(); +} + static Error addChildMember(MembersPerArchitectureMap &Members, const object::Archive::Child &M, const Config &C) { Expected<NewArchiveMember> NMOrErr = @@ -259,6 +295,11 @@ static Error addChildMember(MembersPerArchitectureMap &Members, if (!NMOrErr) return NMOrErr.takeError(); + file_magic Magic = identify_magic(NMOrErr->Buf->getBuffer()); + + if (Magic == file_magic::bitcode) + return verifyAndAddIRObject(Members, std::move(*NMOrErr), C); + if (Error E = verifyAndAddMachOObject(Members, std::move(*NMOrErr), C)) return E; @@ -320,21 +361,41 @@ static Error addUniversalMembers( continue; } + Expected<std::unique_ptr<IRObjectFile>> IRObjectOrError = + O.getAsIRObject(LLVMCtx); + if (IRObjectOrError) { + // A universal file member can be a MachOObjectFile, an IRObject or an + // Archive. In case we can successfully cast the member as an IRObject, it + // is safe to throw away the error generated due to casting the object as + // a MachOObjectFile. + consumeError(MachOObjOrErr.takeError()); + + NewArchiveMember NewMember = + NewArchiveMember(IRObjectOrError->get()->getMemoryBufferRef()); + NewMember.MemberName = sys::path::filename(NewMember.MemberName); + + if (Error E = verifyAndAddIRObject(Members, std::move(NewMember), C)) + return E; + continue; + } + Expected<std::unique_ptr<Archive>> ArchiveOrError = O.getAsArchive(); if (ArchiveOrError) { - // A universal file member can either be a MachOObjectFile or an Archive. - // In case we can successfully cast the member as an Archive, it is safe - // to throw away the error generated due to casting the object as a - // MachOObjectFile. + // A universal file member can be a MachOObjectFile, an IRObject or an + // Archive. In case we can successfully cast the member as an Archive, it + // is safe to throw away the error generated due to casting the object as + // a MachOObjectFile. consumeError(MachOObjOrErr.takeError()); + consumeError(IRObjectOrError.takeError()); if (Error E = processArchive(Members, **ArchiveOrError, FileName, C)) return E; continue; } - Error CombinedError = - joinErrors(ArchiveOrError.takeError(), MachOObjOrErr.takeError()); + Error CombinedError = joinErrors( + ArchiveOrError.takeError(), + joinErrors(IRObjectOrError.takeError(), MachOObjOrErr.takeError())); return createFileError(FileName, std::move(CombinedError)); } @@ -367,6 +428,10 @@ static Error addMember(MembersPerArchitectureMap &Members, return addUniversalMembers(Members, FileBuffers, std::move(*NMOrErr), FileName, C); + // Bitcode files. + if (Magic == file_magic::bitcode) + return verifyAndAddIRObject(Members, std::move(*NMOrErr), C); + if (Error E = verifyAndAddMachOObject(Members, std::move(*NMOrErr), C)) return E; return Error::success(); @@ -378,7 +443,7 @@ buildSlices(ArrayRef<OwningBinary<Archive>> OutputBinaries) { for (const auto &OB : OutputBinaries) { const Archive &A = *OB.getBinary(); - Expected<Slice> ArchiveSlice = Slice::create(A); + Expected<Slice> ArchiveSlice = Slice::create(A, &LLVMCtx); if (!ArchiveSlice) return ArchiveSlice.takeError(); Slices.push_back(*ArchiveSlice); |