Index: lld/ELF/Driver.h =================================================================== --- lld/ELF/Driver.h +++ lld/ELF/Driver.h @@ -16,7 +16,6 @@ #include "llvm/ADT/Optional.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSet.h" -#include "llvm/IR/LLVMContext.h" #include "llvm/Option/ArgList.h" #include "llvm/Support/raw_ostream.h" @@ -30,7 +29,6 @@ void main(ArrayRef Args, bool CanExitEarly); void addFile(StringRef Path); void addLibrary(StringRef Name); - llvm::LLVMContext Context; // to parse bitcode files std::unique_ptr Cpio; // for reproduce private: Index: lld/ELF/Driver.cpp =================================================================== --- lld/ELF/Driver.cpp +++ lld/ELF/Driver.cpp @@ -24,6 +24,7 @@ #include "lld/Driver/Driver.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringSwitch.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/TargetSelect.h" #include "llvm/Support/raw_ostream.h" #include @@ -202,12 +203,6 @@ InitializeAllAsmPrinters(); InitializeAllAsmParsers(); - // This is a flag to discard all but GlobalValue names. - // We want to enable it by default because it saves memory. - // Disable it only when a developer option (-save-temps) is given. - Driver->Context.setDiscardValueNames(!Config->SaveTemps); - Driver->Context.enableDebugTypeODRUniquing(); - // Parse and evaluate -mllvm options. std::vector V; V.push_back("lld (LLVM option parsing)"); Index: lld/ELF/InputFiles.cpp =================================================================== --- lld/ELF/InputFiles.cpp +++ lld/ELF/InputFiles.cpp @@ -653,14 +653,14 @@ } static ELFKind getBitcodeELFKind(MemoryBufferRef MB) { - Triple T(getBitcodeTargetTriple(MB, Driver->Context)); + Triple T(check(getBitcodeTargetTriple(MB))); if (T.isLittleEndian()) return T.isArch64Bit() ? ELF64LEKind : ELF32LEKind; return T.isArch64Bit() ? ELF64BEKind : ELF32BEKind; } static uint8_t getBitcodeMachineKind(MemoryBufferRef MB) { - Triple T(getBitcodeTargetTriple(MB, Driver->Context)); + Triple T(check(getBitcodeTargetTriple(MB))); switch (T.getArch()) { case Triple::aarch64: return EM_AARCH64; Index: llvm/include/llvm/Bitcode/ReaderWriter.h =================================================================== --- llvm/include/llvm/Bitcode/ReaderWriter.h +++ llvm/include/llvm/Bitcode/ReaderWriter.h @@ -17,6 +17,7 @@ #include "llvm/IR/DiagnosticInfo.h" #include "llvm/IR/ModuleSummaryIndex.h" #include "llvm/Support/Endian.h" +#include "llvm/Support/Error.h" #include "llvm/Support/ErrorOr.h" #include "llvm/Support/MemoryBuffer.h" #include @@ -37,6 +38,22 @@ static const unsigned BWH_CPUTypeField = 4*4; static const unsigned BWH_HeaderSize = 5*4; + // These functions are for converting Expected/Error values to + // ErrorOr/std::error_code for compatibility with legacy clients. FIXME: + // Remove these functions once no longer needed by the C and libLTO APIs. + + std::error_code errorToErrorCodeAndEmitErrors(LLVMContext &Ctx, Error Err); + std::error_code + errorToErrorCodeAndEmitErrors(const DiagnosticHandlerFunction &DiagHandler, + Error Err); + + template + ErrorOr expectedToErrorOrAndEmitErrors(LLVMContext &Ctx, Expected Val) { + if (!Val) + return errorToErrorCodeAndEmitErrors(Ctx, Val.takeError()); + return std::move(*Val); + } + /// Read the header of the specified bitcode buffer and prepare for lazy /// deserialization of function bodies. If ShouldLazyLoadMetadata is true, /// lazily load metadata as well. @@ -55,28 +72,23 @@ /// Read the header of the specified bitcode buffer and extract just the /// triple information. If successful, this returns a string. On error, this /// returns "". - std::string getBitcodeTargetTriple(MemoryBufferRef Buffer, - LLVMContext &Context); + Expected getBitcodeTargetTriple(MemoryBufferRef Buffer); /// Return true if \p Buffer contains a bitcode file with ObjC code (category /// or class) in it. - bool isBitcodeContainingObjCCategory(MemoryBufferRef Buffer, - LLVMContext &Context); + Expected isBitcodeContainingObjCCategory(MemoryBufferRef Buffer); /// Read the header of the specified bitcode buffer and extract just the /// producer string information. If successful, this returns a string. On /// error, this returns "". - std::string getBitcodeProducerString(MemoryBufferRef Buffer, - LLVMContext &Context); + Expected getBitcodeProducerString(MemoryBufferRef Buffer); /// Read the specified bitcode file, returning the module. ErrorOr> parseBitcodeFile(MemoryBufferRef Buffer, LLVMContext &Context); /// Check if the given bitcode buffer contains a summary block. - bool - hasGlobalValueSummary(MemoryBufferRef Buffer, - const DiagnosticHandlerFunction &DiagnosticHandler); + Expected hasGlobalValueSummary(MemoryBufferRef Buffer); /// Parse the specified bitcode buffer, returning the module summary index. ErrorOr> Index: llvm/include/llvm/Object/ModuleSummaryIndexObjectFile.h =================================================================== --- llvm/include/llvm/Object/ModuleSummaryIndexObjectFile.h +++ llvm/include/llvm/Object/ModuleSummaryIndexObjectFile.h @@ -79,12 +79,6 @@ static ErrorOr findBitcodeInMemBuffer(MemoryBufferRef Object); - /// \brief Looks for summary sections in the given memory buffer, - /// returns true if found, else false. - static bool hasGlobalValueSummaryInMemBuffer( - MemoryBufferRef Object, - const DiagnosticHandlerFunction &DiagnosticHandler); - /// \brief Parse module summary index in the given memory buffer. /// Return new ModuleSummaryIndexObjectFile instance containing parsed module /// summary/index. Index: llvm/lib/Bitcode/Reader/BitcodeReader.cpp =================================================================== --- llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -228,15 +228,281 @@ Metadata *resolveTypeRefArray(Metadata *MaybeTuple); }; +Error error(const Twine &Message) { + return make_error( + Message, make_error_code(BitcodeError::CorruptedBitcode)); +} + +/// Helper to read the header common to all bitcode files. +bool hasValidBitcodeHeader(BitstreamCursor &Stream) { + // Sniff for the signature. + if (!Stream.canSkipToPos(4) || + Stream.Read(8) != 'B' || + Stream.Read(8) != 'C' || + Stream.Read(4) != 0x0 || + Stream.Read(4) != 0xC || + Stream.Read(4) != 0xE || + Stream.Read(4) != 0xD) + return false; + return true; +} + +Expected initStream(ArrayRef Buffer) { + const unsigned char *BufPtr = Buffer.begin(); + const unsigned char *BufEnd = Buffer.end(); + + if (Buffer.size() & 3) + return error("Invalid bitcode signature"); + + // If we have a wrapper header, parse it and ignore the non-bc file contents. + // The magic number is 0x0B17C0DE stored in little endian. + if (isBitcodeWrapper(BufPtr, BufEnd)) + if (SkipBitcodeWrapperHeader(BufPtr, BufEnd, true)) + return error("Invalid bitcode wrapper header"); + + BitstreamCursor Stream(ArrayRef(BufPtr, BufEnd)); + if (!hasValidBitcodeHeader(Stream)) + return error("Invalid bitcode signature"); + + return std::move(Stream); +} + +Expected initStream(MemoryBufferRef Buffer) { + return initStream( + {(const unsigned char *)Buffer.getBufferStart(), Buffer.getBufferSize()}); +} + +/// Convert a string from a record into an std::string, return true on failure. +template +static bool convertToString(ArrayRef Record, unsigned Idx, + StrTy &Result) { + if (Idx > Record.size()) + return true; + + for (unsigned i = Idx, e = Record.size(); i != e; ++i) + Result += (char)Record[i]; + return false; +} + +/// Read the "IDENTIFICATION_BLOCK_ID" block, do some basic enforcement on the +/// "epoch" encoded in the bitcode, and return the producer name if any. +Expected readIdentificationBlock(BitstreamCursor &Stream) { + if (Stream.EnterSubBlock(bitc::IDENTIFICATION_BLOCK_ID)) + return error("Invalid record"); + + // Read all the records. + SmallVector Record; + + std::string ProducerIdentification; + + while (true) { + BitstreamEntry Entry = Stream.advance(); + + switch (Entry.Kind) { + default: + case BitstreamEntry::Error: + return error("Malformed block"); + case BitstreamEntry::EndBlock: + return ProducerIdentification; + case BitstreamEntry::Record: + // The interesting case. + break; + } + + // Read a record. + Record.clear(); + unsigned BitCode = Stream.readRecord(Entry.ID, Record); + switch (BitCode) { + default: // Default behavior: reject + return error("Invalid value"); + case bitc::IDENTIFICATION_CODE_STRING: // IDENTIFICATION: [strchr x N] + convertToString(Record, 0, ProducerIdentification); + break; + case bitc::IDENTIFICATION_CODE_EPOCH: { // EPOCH: [epoch#] + unsigned epoch = (unsigned)Record[0]; + if (epoch != bitc::BITCODE_CURRENT_EPOCH) { + return error( + Twine("Incompatible epoch: Bitcode '") + Twine(epoch) + + "' vs current: '" + Twine(bitc::BITCODE_CURRENT_EPOCH) + "'"); + } + } + } + } +} + +Expected readIdentificationCode(BitstreamCursor &Stream) { + // We expect a number of well-defined blocks, though we don't necessarily + // need to understand them all. + while (true) { + if (Stream.AtEndOfStream()) + return ""; + + BitstreamEntry Entry = Stream.advance(); + switch (Entry.Kind) { + case BitstreamEntry::EndBlock: + case BitstreamEntry::Error: + return error("Malformed block"); + + case BitstreamEntry::SubBlock: + if (Entry.ID == bitc::IDENTIFICATION_BLOCK_ID) + return readIdentificationBlock(Stream); + + // Ignore other sub-blocks. + if (Stream.SkipBlock()) + return error("Malformed block"); + continue; + case BitstreamEntry::Record: + Stream.skipRecord(Entry.ID); + continue; + } + } +} + +Expected hasObjCCategoryInModule(BitstreamCursor &Stream) { + if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) + return error("Invalid record"); + + SmallVector Record; + // Read all the records for this module. + + while (true) { + BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + + switch (Entry.Kind) { + case BitstreamEntry::SubBlock: // Handled for us already. + case BitstreamEntry::Error: + return error("Malformed block"); + case BitstreamEntry::EndBlock: + return false; + case BitstreamEntry::Record: + // The interesting case. + break; + } + + // Read a record. + switch (Stream.readRecord(Entry.ID, Record)) { + default: + break; // Default behavior, ignore unknown content. + case bitc::MODULE_CODE_SECTIONNAME: { // SECTIONNAME: [strchr x N] + std::string S; + if (convertToString(Record, 0, S)) + return error("Invalid record"); + // Check for the i386 and other (x86_64, ARM) conventions + if (S.find("__DATA, __objc_catlist") != std::string::npos || + S.find("__OBJC,__category") != std::string::npos) + return true; + break; + } + } + Record.clear(); + } + llvm_unreachable("Exit infinite loop"); +} + +Expected hasObjCCategory(BitstreamCursor &Stream) { + // We expect a number of well-defined blocks, though we don't necessarily + // need to understand them all. + while (true) { + BitstreamEntry Entry = Stream.advance(); + + switch (Entry.Kind) { + case BitstreamEntry::Error: + return error("Malformed block"); + case BitstreamEntry::EndBlock: + return Error::success(); + + case BitstreamEntry::SubBlock: + if (Entry.ID == bitc::MODULE_BLOCK_ID) + return hasObjCCategoryInModule(Stream); + + // Ignore other sub-blocks. + if (Stream.SkipBlock()) + return error("Malformed block"); + continue; + + case BitstreamEntry::Record: + Stream.skipRecord(Entry.ID); + continue; + } + } +} + +Expected readModuleTriple(BitstreamCursor &Stream) { + if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) + return error("Invalid record"); + + SmallVector Record; + + std::string Triple; + + // Read all the records for this module. + while (true) { + BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + + switch (Entry.Kind) { + case BitstreamEntry::SubBlock: // Handled for us already. + case BitstreamEntry::Error: + return error("Malformed block"); + case BitstreamEntry::EndBlock: + return Triple; + case BitstreamEntry::Record: + // The interesting case. + break; + } + + // Read a record. + switch (Stream.readRecord(Entry.ID, Record)) { + default: break; // Default behavior, ignore unknown content. + case bitc::MODULE_CODE_TRIPLE: { // TRIPLE: [strchr x N] + std::string S; + if (convertToString(Record, 0, S)) + return error("Invalid record"); + Triple = S; + break; + } + } + Record.clear(); + } + llvm_unreachable("Exit infinite loop"); +} + +Expected readTriple(BitstreamCursor &Stream) { + // We expect a number of well-defined blocks, though we don't necessarily + // need to understand them all. + while (true) { + BitstreamEntry Entry = Stream.advance(); + + switch (Entry.Kind) { + case BitstreamEntry::Error: + return error("Malformed block"); + case BitstreamEntry::EndBlock: + return Error::success(); + + case BitstreamEntry::SubBlock: + if (Entry.ID == bitc::MODULE_BLOCK_ID) + return readModuleTriple(Stream); + + // Ignore other sub-blocks. + if (Stream.SkipBlock()) + return error("Malformed block"); + continue; + + case BitstreamEntry::Record: + Stream.skipRecord(Entry.ID); + continue; + } + } +} + class BitcodeReaderBase { protected: - BitcodeReaderBase(MemoryBufferRef Buffer) : Buffer(Buffer) {} + BitcodeReaderBase(BitstreamCursor Stream) : Stream(std::move(Stream)) { + this->Stream.setBlockInfo(&BlockInfo); + } - MemoryBufferRef Buffer; BitstreamBlockInfo BlockInfo; BitstreamCursor Stream; - Error initStream(); bool readBlockInfo(); // Contains an arbitrary and optional string identifying the bitcode producer @@ -250,27 +516,7 @@ if (!ProducerIdentification.empty()) FullMsg += " (Producer: '" + ProducerIdentification + "' Reader: 'LLVM " + LLVM_VERSION_STRING "')"; - return make_error( - FullMsg, make_error_code(BitcodeError::CorruptedBitcode)); -} - -Error BitcodeReaderBase::initStream() { - const unsigned char *BufPtr = (const unsigned char*)Buffer.getBufferStart(); - const unsigned char *BufEnd = BufPtr+Buffer.getBufferSize(); - - if (Buffer.getBufferSize() & 3) - return error("Invalid bitcode signature"); - - // If we have a wrapper header, parse it and ignore the non-bc file contents. - // The magic number is 0x0B17C0DE stored in little endian. - if (isBitcodeWrapper(BufPtr, BufEnd)) - if (SkipBitcodeWrapperHeader(BufPtr, BufEnd, true)) - return error("Invalid bitcode wrapper header"); - - Stream = BitstreamCursor(ArrayRef(BufPtr, BufEnd)); - Stream.setBlockInfo(&BlockInfo); - - return Error::success(); + return ::error(FullMsg); } class BitcodeReader : public BitcodeReaderBase, public GVMaterializer { @@ -366,7 +612,7 @@ std::vector BundleTags; public: - BitcodeReader(MemoryBufferRef Buffer, LLVMContext &Context); + BitcodeReader(BitstreamCursor Stream, LLVMContext &Context); Error materializeForwardReferencedFunctions(); @@ -378,17 +624,6 @@ /// \returns true if an error occurred. Error parseBitcodeInto(Module *M, bool ShouldLazyLoadMetadata = false); - /// \brief Cheap mechanism to just extract module triple - /// \returns true if an error occurred. - Expected parseTriple(); - - /// Cheap mechanism to just extract the identification block out of bitcode. - Expected parseIdentificationBlock(); - - /// Peak at the module content and return true if any ObjC category or class - /// is found. - Expected hasObjCCategory(); - static uint64_t decodeSignRotatedValue(uint64_t V); /// Materialize any deferred Metadata block. @@ -397,11 +632,6 @@ void setStripDebugInfo() override; private: - /// Parse the "IDENTIFICATION_BLOCK_ID" block, populate the - // ProducerIdentification data member, and do some basic enforcement on the - // "epoch" encoded in the bitcode. - Error parseBitcodeVersion(); - std::vector IdentifiedStructTypes; StructType *createIdentifiedStructType(LLVMContext &Context, StringRef Name); StructType *createIdentifiedStructType(LLVMContext &Context); @@ -527,8 +757,6 @@ Error parseGlobalObjectAttachment(GlobalObject &GO, ArrayRef Record); Error parseMetadataAttachment(Function &F); - Expected parseModuleTriple(); - Expected hasObjCCategoryInModule(); Error parseUseLists(); Error findFunctionInStream( Function *F, @@ -579,21 +807,21 @@ public: ModuleSummaryIndexBitcodeReader( - MemoryBufferRef Buffer, bool CheckGlobalValSummaryPresenceOnly = false); + BitstreamCursor Stream, bool CheckGlobalValSummaryPresenceOnly = false); /// Check if the parser has encountered a summary section. bool foundGlobalValSummary() { return SeenGlobalValSummary; } /// \brief Main interface to parsing a bitcode buffer. /// \returns true if an error occurred. - Error parseSummaryIndexInto(ModuleSummaryIndex *I); + Error parseSummaryIndexInto(ModuleSummaryIndex *I, StringRef ModulePath); private: - Error parseModule(); + Error parseModule(StringRef ModulePath); Error parseValueSymbolTable( uint64_t Offset, DenseMap &ValueIdToLinkageMap); - Error parseEntireSummary(); + Error parseEntireSummary(StringRef ModulePath); Error parseModuleStringTable(); std::pair @@ -603,7 +831,10 @@ bool IsOldProfileFormat, bool HasProfile); }; -std::error_code errorToErrorCodeAndEmitErrors(LLVMContext &Ctx, Error Err) { +} // end anonymous namespace + +std::error_code llvm::errorToErrorCodeAndEmitErrors(LLVMContext &Ctx, + Error Err) { if (Err) { std::error_code EC; handleAllErrors(std::move(Err), [&](ErrorInfoBase &EIB) { @@ -615,9 +846,8 @@ return std::error_code(); } -std::error_code -errorToErrorCodeAndEmitErrors(const DiagnosticHandlerFunction &DiagHandler, - Error Err) { +std::error_code llvm::errorToErrorCodeAndEmitErrors( + const DiagnosticHandlerFunction &DiagHandler, Error Err) { if (Err) { std::error_code EC; handleAllErrors(std::move(Err), [&](ErrorInfoBase &EIB) { @@ -629,26 +859,8 @@ return std::error_code(); } -template -ErrorOr expectedToErrorOrAndEmitErrors(LLVMContext &Ctx, Expected Val) { - if (!Val) - return errorToErrorCodeAndEmitErrors(Ctx, Val.takeError()); - return std::move(*Val); -} - -template -static ErrorOr -expectedToErrorOrAndEmitErrors(const DiagnosticHandlerFunction &DiagHandler, - Expected Val) { - if (!Val) - return errorToErrorCodeAndEmitErrors(DiagHandler, Val.takeError()); - return std::move(*Val); -} - -} // end anonymous namespace - -BitcodeReader::BitcodeReader(MemoryBufferRef Buffer, LLVMContext &Context) - : BitcodeReaderBase(Buffer), Context(Context), ValueList(Context), +BitcodeReader::BitcodeReader(BitstreamCursor Stream, LLVMContext &Context) + : BitcodeReaderBase(std::move(Stream)), Context(Context), ValueList(Context), MetadataList(Context) {} Error BitcodeReader::materializeForwardReferencedFunctions() { @@ -681,25 +893,13 @@ // Reset state. WillMaterializeAllForwardRefs = false; - return Error::success(); -} - -//===----------------------------------------------------------------------===// -// Helper functions to implement forward reference resolution, etc. -//===----------------------------------------------------------------------===// - -/// Convert a string from a record into an std::string, return true on failure. -template -static bool convertToString(ArrayRef Record, unsigned Idx, - StrTy &Result) { - if (Idx > Record.size()) - return true; - - for (unsigned i = Idx, e = Record.size(); i != e; ++i) - Result += (char)Record[i]; - return false; + return Error::success(); } +//===----------------------------------------------------------------------===// +// Helper functions to implement forward reference resolution, etc. +//===----------------------------------------------------------------------===// + static bool hasImplicitComdat(size_t Val) { switch (Val) { default: @@ -3694,50 +3894,6 @@ } } -Error BitcodeReader::parseBitcodeVersion() { - if (Stream.EnterSubBlock(bitc::IDENTIFICATION_BLOCK_ID)) - return error("Invalid record"); - - // Read all the records. - SmallVector Record; - - while (true) { - BitstreamEntry Entry = Stream.advance(); - - switch (Entry.Kind) { - default: - case BitstreamEntry::Error: - return error("Malformed block"); - case BitstreamEntry::EndBlock: - return Error::success(); - case BitstreamEntry::Record: - // The interesting case. - break; - } - - // Read a record. - Record.clear(); - unsigned BitCode = Stream.readRecord(Entry.ID, Record); - switch (BitCode) { - default: // Default behavior: reject - return error("Invalid value"); - case bitc::IDENTIFICATION_CODE_STRING: { // IDENTIFICATION: [strchr x - // N] - convertToString(Record, 0, ProducerIdentification); - break; - } - case bitc::IDENTIFICATION_CODE_EPOCH: { // EPOCH: [epoch#] - unsigned epoch = (unsigned)Record[0]; - if (epoch != bitc::BITCODE_CURRENT_EPOCH) { - return error( - Twine("Incompatible epoch: Bitcode '") + Twine(epoch) + - "' vs current: '" + Twine(bitc::BITCODE_CURRENT_EPOCH) + "'"); - } - } - } - } -} - bool BitcodeReaderBase::readBlockInfo() { Optional NewBlockInfo = Stream.ReadBlockInfoBlock(); if (!NewBlockInfo) @@ -4222,30 +4378,9 @@ } } -/// Helper to read the header common to all bitcode files. -static bool hasValidBitcodeHeader(BitstreamCursor &Stream) { - // Sniff for the signature. - if (!Stream.canSkipToPos(4) || - Stream.Read(8) != 'B' || - Stream.Read(8) != 'C' || - Stream.Read(4) != 0x0 || - Stream.Read(4) != 0xC || - Stream.Read(4) != 0xE || - Stream.Read(4) != 0xD) - return false; - return true; -} - Error BitcodeReader::parseBitcodeInto(Module *M, bool ShouldLazyLoadMetadata) { TheModule = M; - if (Error Err = initStream()) - return Err; - - // Sniff for the signature. - if (!hasValidBitcodeHeader(Stream)) - return error("Invalid bitcode signature"); - // We expect a number of well-defined blocks, though we don't necessarily // need to understand them all. while (true) { @@ -4261,8 +4396,11 @@ return error("Malformed block"); if (Entry.ID == bitc::IDENTIFICATION_BLOCK_ID) { - if (Error Err = parseBitcodeVersion()) - return Err; + Expected ProducerIdentificationOrErr = + readIdentificationBlock(Stream); + if (!ProducerIdentificationOrErr) + return ProducerIdentificationOrErr.takeError(); + ProducerIdentification = *ProducerIdentificationOrErr; continue; } @@ -4274,121 +4412,6 @@ } } -Expected BitcodeReader::parseModuleTriple() { - if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) - return error("Invalid record"); - - SmallVector Record; - - std::string Triple; - - // Read all the records for this module. - while (true) { - BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); - - switch (Entry.Kind) { - case BitstreamEntry::SubBlock: // Handled for us already. - case BitstreamEntry::Error: - return error("Malformed block"); - case BitstreamEntry::EndBlock: - return Triple; - case BitstreamEntry::Record: - // The interesting case. - break; - } - - // Read a record. - switch (Stream.readRecord(Entry.ID, Record)) { - default: break; // Default behavior, ignore unknown content. - case bitc::MODULE_CODE_TRIPLE: { // TRIPLE: [strchr x N] - std::string S; - if (convertToString(Record, 0, S)) - return error("Invalid record"); - Triple = S; - break; - } - } - Record.clear(); - } - llvm_unreachable("Exit infinite loop"); -} - -Expected BitcodeReader::parseTriple() { - if (Error Err = initStream()) - return std::move(Err); - - // Sniff for the signature. - if (!hasValidBitcodeHeader(Stream)) - return error("Invalid bitcode signature"); - - // We expect a number of well-defined blocks, though we don't necessarily - // need to understand them all. - while (true) { - BitstreamEntry Entry = Stream.advance(); - - switch (Entry.Kind) { - case BitstreamEntry::Error: - return error("Malformed block"); - case BitstreamEntry::EndBlock: - return Error::success(); - - case BitstreamEntry::SubBlock: - if (Entry.ID == bitc::MODULE_BLOCK_ID) - return parseModuleTriple(); - - // Ignore other sub-blocks. - if (Stream.SkipBlock()) - return error("Malformed block"); - continue; - - case BitstreamEntry::Record: - Stream.skipRecord(Entry.ID); - continue; - } - } -} - -Expected BitcodeReader::parseIdentificationBlock() { - if (Error Err = initStream()) - return std::move(Err); - - // Sniff for the signature. - if (!hasValidBitcodeHeader(Stream)) - return error("Invalid bitcode signature"); - - // We expect a number of well-defined blocks, though we don't necessarily - // need to understand them all. - while (true) { - // This loop iterates at the top-level: since there is no enclosing block - // we need to make sure we aren't at the end of the stream before calling - // advance, otherwise we'll get an error. - if (Stream.AtEndOfStream()) - return Error::success(); - - BitstreamEntry Entry = Stream.advance(); - switch (Entry.Kind) { - case BitstreamEntry::Error: - return error("Malformed block"); - case BitstreamEntry::EndBlock: - return Error::success(); - - case BitstreamEntry::SubBlock: - if (Entry.ID == bitc::IDENTIFICATION_BLOCK_ID) { - if (Error Err = parseBitcodeVersion()) - return std::move(Err); - return ProducerIdentification; - } - // Ignore other sub-blocks. - if (Stream.SkipBlock()) - return error("Malformed block"); - continue; - case BitstreamEntry::Record: - Stream.skipRecord(Entry.ID); - continue; - } - } -} - Error BitcodeReader::parseGlobalObjectAttachment(GlobalObject &GO, ArrayRef Record) { assert(Record.size() % 2 == 0); @@ -4404,82 +4427,6 @@ return Error::success(); } -Expected BitcodeReader::hasObjCCategory() { - if (Error Err = initStream()) - return std::move(Err); - - // Sniff for the signature. - if (!hasValidBitcodeHeader(Stream)) - return error("Invalid bitcode signature"); - - // We expect a number of well-defined blocks, though we don't necessarily - // need to understand them all. - while (true) { - BitstreamEntry Entry = Stream.advance(); - - switch (Entry.Kind) { - case BitstreamEntry::Error: - return error("Malformed block"); - case BitstreamEntry::EndBlock: - return Error::success(); - - case BitstreamEntry::SubBlock: - if (Entry.ID == bitc::MODULE_BLOCK_ID) - return hasObjCCategoryInModule(); - - // Ignore other sub-blocks. - if (Stream.SkipBlock()) - return error("Malformed block"); - continue; - - case BitstreamEntry::Record: - Stream.skipRecord(Entry.ID); - continue; - } - } -} - -Expected BitcodeReader::hasObjCCategoryInModule() { - if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) - return error("Invalid record"); - - SmallVector Record; - // Read all the records for this module. - - while (true) { - BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); - - switch (Entry.Kind) { - case BitstreamEntry::SubBlock: // Handled for us already. - case BitstreamEntry::Error: - return error("Malformed block"); - case BitstreamEntry::EndBlock: - return false; - case BitstreamEntry::Record: - // The interesting case. - break; - } - - // Read a record. - switch (Stream.readRecord(Entry.ID, Record)) { - default: - break; // Default behavior, ignore unknown content. - case bitc::MODULE_CODE_SECTIONNAME: { // SECTIONNAME: [strchr x N] - std::string S; - if (convertToString(Record, 0, S)) - return error("Invalid record"); - // Check for the i386 and other (x86_64, ARM) conventions - if (S.find("__DATA, __objc_catlist") != std::string::npos || - S.find("__OBJC,__category") != std::string::npos) - return true; - break; - } - } - Record.clear(); - } - llvm_unreachable("Exit infinite loop"); -} - /// Parse metadata attachments. Error BitcodeReader::parseMetadataAttachment(Function &F) { if (Stream.EnterSubBlock(bitc::METADATA_ATTACHMENT_ID)) @@ -5981,8 +5928,8 @@ } ModuleSummaryIndexBitcodeReader::ModuleSummaryIndexBitcodeReader( - MemoryBufferRef Buffer, bool CheckGlobalValSummaryPresenceOnly) - : BitcodeReaderBase(Buffer), + BitstreamCursor Cursor, bool CheckGlobalValSummaryPresenceOnly) + : BitcodeReaderBase(std::move(Cursor)), CheckGlobalValSummaryPresenceOnly(CheckGlobalValSummaryPresenceOnly) {} std::pair @@ -6094,7 +6041,7 @@ // Parse just the blocks needed for building the index out of the module. // At the end of this routine the module Index is populated with a map // from global value id to GlobalValueSummary objects. -Error ModuleSummaryIndexBitcodeReader::parseModule() { +Error ModuleSummaryIndexBitcodeReader::parseModule(StringRef ModulePath) { if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) return error("Invalid record"); @@ -6155,7 +6102,7 @@ SeenValueSymbolTable = true; } SeenGlobalValSummary = true; - if (Error Err = parseEntireSummary()) + if (Error Err = parseEntireSummary(ModulePath)) return Err; break; case bitc::MODULE_STRTAB_BLOCK_ID: @@ -6187,7 +6134,7 @@ break; if (TheIndex->modulePaths().empty()) // We always seed the index with the module. - TheIndex->addModulePath(Buffer.getBufferIdentifier(), 0); + TheIndex->addModulePath(ModulePath, 0); if (TheIndex->modulePaths().size() != 1) return error("Don't expect multiple modules defined?"); auto &Hash = TheIndex->modulePaths().begin()->second.second; @@ -6246,7 +6193,8 @@ // Eagerly parse the entire summary block. This populates the GlobalValueSummary // objects in the index. -Error ModuleSummaryIndexBitcodeReader::parseEntireSummary() { +Error ModuleSummaryIndexBitcodeReader::parseEntireSummary( + StringRef ModulePath) { if (Stream.EnterSubBlock(bitc::GLOBALVAL_SUMMARY_BLOCK_ID)) return error("Invalid record"); SmallVector Record; @@ -6326,8 +6274,7 @@ // string table section in the per-module index, we create a single // module path string table entry with an empty (0) ID to take // ownership. - FS->setModulePath( - TheIndex->addModulePath(Buffer.getBufferIdentifier(), 0)->first()); + FS->setModulePath(TheIndex->addModulePath(ModulePath, 0)->first()); static int RefListStartIndex = 4; int CallGraphEdgeStartIndex = RefListStartIndex + NumRefs; assert(Record.size() >= RefListStartIndex + NumRefs && @@ -6365,8 +6312,7 @@ // string table section in the per-module index, we create a single // module path string table entry with an empty (0) ID to take // ownership. - AS->setModulePath( - TheIndex->addModulePath(Buffer.getBufferIdentifier(), 0)->first()); + AS->setModulePath(TheIndex->addModulePath(ModulePath, 0)->first()); GlobalValue::GUID AliaseeGUID = getGUIDFromValueId(AliaseeID).first; auto *AliaseeSummary = TheIndex->getGlobalValueSummary(AliaseeGUID); @@ -6386,8 +6332,7 @@ auto Flags = getDecodedGVSummaryFlags(RawFlags, Version); std::unique_ptr FS = llvm::make_unique(Flags); - FS->setModulePath( - TheIndex->addModulePath(Buffer.getBufferIdentifier(), 0)->first()); + FS->setModulePath(TheIndex->addModulePath(ModulePath, 0)->first()); for (unsigned I = 2, E = Record.size(); I != E; ++I) { unsigned RefValueId = Record[I]; GlobalValue::GUID RefGUID = getGUIDFromValueId(RefValueId).first; @@ -6577,17 +6522,10 @@ } // Parse the function info index from the bitcode streamer into the given index. -Error -ModuleSummaryIndexBitcodeReader::parseSummaryIndexInto(ModuleSummaryIndex *I) { +Error ModuleSummaryIndexBitcodeReader::parseSummaryIndexInto( + ModuleSummaryIndex *I, StringRef ModulePath) { TheIndex = I; - if (Error Err = initStream()) - return Err; - - // Sniff for the signature. - if (!hasValidBitcodeHeader(Stream)) - return error("Invalid bitcode signature"); - // We expect a number of well-defined blocks, though we don't necessarily // need to understand them all. while (true) { @@ -6605,7 +6543,7 @@ // If we see a MODULE_BLOCK, parse it to find the blocks needed for // building the function summary index. if (Entry.ID == bitc::MODULE_BLOCK_ID) - return parseModule(); + return parseModule(ModulePath); if (Stream.SkipBlock()) return error("Invalid record"); @@ -6655,7 +6593,11 @@ getLazyBitcodeModuleImpl(MemoryBufferRef Buffer, LLVMContext &Context, bool MaterializeAll, bool ShouldLazyLoadMetadata = false) { - BitcodeReader *R = new BitcodeReader(Buffer, Context); + Expected StreamOrErr = initStream(Buffer); + if (!StreamOrErr) + return errorToErrorCodeAndEmitErrors(Context, StreamOrErr.takeError()); + + BitcodeReader *R = new BitcodeReader(std::move(*StreamOrErr), Context); std::unique_ptr M = llvm::make_unique(Buffer.getBufferIdentifier(), Context); @@ -6701,60 +6643,62 @@ // written. We must defer until the Module has been fully materialized. } -std::string llvm::getBitcodeTargetTriple(MemoryBufferRef Buffer, - LLVMContext &Context) { - BitcodeReader R(Buffer, Context); - ErrorOr Triple = - expectedToErrorOrAndEmitErrors(Context, R.parseTriple()); - if (Triple.getError()) - return ""; - return Triple.get(); +Expected llvm::getBitcodeTargetTriple(MemoryBufferRef Buffer) { + Expected StreamOrErr = initStream(Buffer); + if (!StreamOrErr) + return StreamOrErr.takeError(); + + return readTriple(*StreamOrErr); } -bool llvm::isBitcodeContainingObjCCategory(MemoryBufferRef Buffer, - LLVMContext &Context) { - BitcodeReader R(Buffer, Context); - ErrorOr hasObjCCategory = - expectedToErrorOrAndEmitErrors(Context, R.hasObjCCategory()); - if (hasObjCCategory.getError()) - return false; - return hasObjCCategory.get(); +Expected llvm::isBitcodeContainingObjCCategory(MemoryBufferRef Buffer) { + Expected StreamOrErr = initStream(Buffer); + if (!StreamOrErr) + return StreamOrErr.takeError(); + + return hasObjCCategory(*StreamOrErr); } -std::string llvm::getBitcodeProducerString(MemoryBufferRef Buffer, - LLVMContext &Context) { - BitcodeReader R(Buffer, Context); - ErrorOr ProducerString = - expectedToErrorOrAndEmitErrors(Context, R.parseIdentificationBlock()); - if (ProducerString.getError()) - return ""; - return ProducerString.get(); +Expected llvm::getBitcodeProducerString(MemoryBufferRef Buffer) { + Expected StreamOrErr = initStream(Buffer); + if (!StreamOrErr) + return StreamOrErr.takeError(); + + return readIdentificationCode(*StreamOrErr); } // Parse the specified bitcode buffer, returning the function info index. ErrorOr> llvm::getModuleSummaryIndex( MemoryBufferRef Buffer, const DiagnosticHandlerFunction &DiagnosticHandler) { - ModuleSummaryIndexBitcodeReader R(Buffer); + Expected StreamOrErr = initStream(Buffer); + if (!StreamOrErr) + return errorToErrorCodeAndEmitErrors(DiagnosticHandler, + StreamOrErr.takeError()); + + ModuleSummaryIndexBitcodeReader R(std::move(*StreamOrErr)); auto Index = llvm::make_unique(); if (std::error_code EC = errorToErrorCodeAndEmitErrors( - DiagnosticHandler, R.parseSummaryIndexInto(Index.get()))) + DiagnosticHandler, + R.parseSummaryIndexInto(Index.get(), Buffer.getBufferIdentifier()))) return EC; return std::move(Index); } // Check if the given bitcode buffer contains a global value summary block. -bool llvm::hasGlobalValueSummary( - MemoryBufferRef Buffer, - const DiagnosticHandlerFunction &DiagnosticHandler) { - ModuleSummaryIndexBitcodeReader R(Buffer, true); +Expected llvm::hasGlobalValueSummary(MemoryBufferRef Buffer) { + Expected StreamOrErr = initStream(Buffer); + if (!StreamOrErr) + return StreamOrErr.takeError(); - if (errorToErrorCodeAndEmitErrors(DiagnosticHandler, - R.parseSummaryIndexInto(nullptr))) - return false; + ModuleSummaryIndexBitcodeReader R(std::move(*StreamOrErr), true); + + if (Error Err = + R.parseSummaryIndexInto(nullptr, Buffer.getBufferIdentifier())) + return std::move(Err); return R.foundGlobalValSummary(); } Index: llvm/lib/LTO/LTO.cpp =================================================================== --- llvm/lib/LTO/LTO.cpp +++ llvm/lib/LTO/LTO.cpp @@ -327,9 +327,11 @@ M.setTargetTriple(Conf.DefaultTriple); MemoryBufferRef MBRef = Input->Obj->getMemoryBufferRef(); - bool HasThinLTOSummary = hasGlobalValueSummary(MBRef, Conf.DiagHandler); + Expected HasThinLTOSummary = hasGlobalValueSummary(MBRef); + if (!HasThinLTOSummary) + return HasThinLTOSummary.takeError(); - if (HasThinLTOSummary) + if (*HasThinLTOSummary) return addThinLTO(std::move(Input), Res); else return addRegularLTO(std::move(Input), Res); Index: llvm/lib/LTO/LTOModule.cpp =================================================================== --- llvm/lib/LTO/LTOModule.cpp +++ llvm/lib/LTO/LTOModule.cpp @@ -76,13 +76,12 @@ bool LTOModule::isThinLTO() { // Right now the detection is only based on the summary presence. We may want // to add a dedicated flag at some point. - return hasGlobalValueSummary(IRFile->getMemoryBufferRef(), - [](const DiagnosticInfo &DI) { - DiagnosticPrinterRawOStream DP(errs()); - DI.print(DP); - errs() << '\n'; - return; - }); + Expected Result = hasGlobalValueSummary(IRFile->getMemoryBufferRef()); + if (!Result) { + logAllUnhandledErrors(Result.takeError(), errs(), ""); + return false; + } + return *Result; } bool LTOModule::isBitcodeForTarget(MemoryBuffer *Buffer, @@ -92,8 +91,11 @@ if (!BCOrErr) return false; LLVMContext Context; - std::string Triple = getBitcodeTargetTriple(*BCOrErr, Context); - return StringRef(Triple).startswith(TriplePrefix); + ErrorOr TripleOrErr = + expectedToErrorOrAndEmitErrors(Context, getBitcodeTargetTriple(*BCOrErr)); + if (!TripleOrErr) + return false; + return StringRef(*TripleOrErr).startswith(TriplePrefix); } std::string LTOModule::getProducerString(MemoryBuffer *Buffer) { @@ -102,7 +104,11 @@ if (!BCOrErr) return ""; LLVMContext Context; - return getBitcodeProducerString(*BCOrErr, Context); + ErrorOr ProducerOrErr = expectedToErrorOrAndEmitErrors( + Context, getBitcodeProducerString(*BCOrErr)); + if (!ProducerOrErr) + return ""; + return *ProducerOrErr; } ErrorOr> Index: llvm/lib/LTO/ThinLTOCodeGenerator.cpp =================================================================== --- llvm/lib/LTO/ThinLTOCodeGenerator.cpp +++ llvm/lib/LTO/ThinLTOCodeGenerator.cpp @@ -452,14 +452,23 @@ if (Modules.empty()) { // First module added, so initialize the triple and some options LLVMContext Context; - Triple TheTriple(getBitcodeTargetTriple(Buffer, Context)); + StringRef TripleStr; + ErrorOr TripleOrErr = + expectedToErrorOrAndEmitErrors(Context, getBitcodeTargetTriple(Buffer)); + if (TripleOrErr) + TripleStr = *TripleOrErr; + Triple TheTriple(TripleStr); initTMBuilder(TMBuilder, Triple(TheTriple)); } #ifndef NDEBUG else { LLVMContext Context; - assert(TMBuilder.TheTriple.str() == - getBitcodeTargetTriple(Buffer, Context) && + StringRef TripleStr; + ErrorOr TripleOrErr = + expectedToErrorOrAndEmitErrors(Context, getBitcodeTargetTriple(Buffer)); + if (TripleOrErr) + TripleStr = *TripleOrErr; + assert(TMBuilder.TheTriple.str() == TripleStr && "ThinLTO modules with different triple not supported"); } #endif Index: llvm/lib/Object/ModuleSummaryIndexObjectFile.cpp =================================================================== --- llvm/lib/Object/ModuleSummaryIndexObjectFile.cpp +++ llvm/lib/Object/ModuleSummaryIndexObjectFile.cpp @@ -67,18 +67,6 @@ } } -// Looks for module summary index in the given memory buffer. -// returns true if found, else false. -bool ModuleSummaryIndexObjectFile::hasGlobalValueSummaryInMemBuffer( - MemoryBufferRef Object, - const DiagnosticHandlerFunction &DiagnosticHandler) { - ErrorOr BCOrErr = findBitcodeInMemBuffer(Object); - if (!BCOrErr) - return false; - - return hasGlobalValueSummary(BCOrErr.get(), DiagnosticHandler); -} - // Parse module summary index in the given memory buffer. // Return new ModuleSummaryIndexObjectFile instance containing parsed // module summary/index. Index: llvm/tools/llvm-lto/llvm-lto.cpp =================================================================== --- llvm/tools/llvm-lto/llvm-lto.cpp +++ llvm/tools/llvm-lto/llvm-lto.cpp @@ -772,12 +772,12 @@ if (CheckHasObjC) { for (auto &Filename : InputFilenames) { - ErrorOr> BufferOrErr = - MemoryBuffer::getFile(Filename); - error(BufferOrErr, "error loading file '" + Filename + "'"); + ExitOnError ExitOnErr(std::string(*argv) + ": error loading file '" + + Filename + "': "); + std::unique_ptr BufferOrErr = + ExitOnErr(errorOrToExpected(MemoryBuffer::getFile(Filename))); auto Buffer = std::move(BufferOrErr.get()); - LLVMContext Ctx; - if (llvm::isBitcodeContainingObjCCategory(*Buffer, Ctx)) + if (ExitOnErr(llvm::isBitcodeContainingObjCCategory(*Buffer))) outs() << "Bitcode " << Filename << " contains ObjC\n"; else outs() << "Bitcode " << Filename << " does not contain ObjC\n"; Index: llvm/tools/lto/lto.cpp =================================================================== --- llvm/tools/lto/lto.cpp +++ llvm/tools/lto/lto.cpp @@ -187,7 +187,9 @@ if (!Buffer) return false; LLVMContext Ctx; - return llvm::isBitcodeContainingObjCCategory(*Buffer, Ctx); + ErrorOr Result = expectedToErrorOrAndEmitErrors( + Ctx, llvm::isBitcodeContainingObjCCategory(*Buffer)); + return Result && *Result; } bool lto_module_is_object_file_in_memory(const void* mem, size_t length) {