diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index e71e106dbf11..9256baa89466 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -228,15 +228,54 @@ private: 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(MemoryBufferRef Buffer) { + 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"); + + BitstreamCursor Stream(ArrayRef(BufPtr, BufEnd)); + if (!hasValidBitcodeHeader(Stream)) + return error("Invalid bitcode signature"); + + return std::move(Stream); +} + 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 +289,7 @@ Error BitcodeReaderBase::error(const Twine &Message) { 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 +385,7 @@ class BitcodeReader : public BitcodeReaderBase, public GVMaterializer { std::vector BundleTags; public: - BitcodeReader(MemoryBufferRef Buffer, LLVMContext &Context); + BitcodeReader(BitstreamCursor Stream, LLVMContext &Context); Error materializeForwardReferencedFunctions(); @@ -579,21 +598,21 @@ class ModuleSummaryIndexBitcodeReader : public BitcodeReaderBase { 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 @@ -647,8 +666,8 @@ expectedToErrorOrAndEmitErrors(const DiagnosticHandlerFunction &DiagHandler, } // 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() { @@ -4222,30 +4241,9 @@ Error BitcodeReader::parseModule(uint64_t ResumeBit, } } -/// 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) { @@ -4314,13 +4312,6 @@ Expected BitcodeReader::parseModuleTriple() { } 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) { @@ -4349,13 +4340,6 @@ Expected BitcodeReader::parseTriple() { } 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) { @@ -4405,13 +4389,6 @@ Error BitcodeReader::parseGlobalObjectAttachment(GlobalObject &GO, } 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) { @@ -5981,8 +5958,8 @@ std::vector BitcodeReader::getIdentifiedStructTypes() const { } ModuleSummaryIndexBitcodeReader::ModuleSummaryIndexBitcodeReader( - MemoryBufferRef Buffer, bool CheckGlobalValSummaryPresenceOnly) - : BitcodeReaderBase(Buffer), + BitstreamCursor Cursor, bool CheckGlobalValSummaryPresenceOnly) + : BitcodeReaderBase(std::move(Cursor)), CheckGlobalValSummaryPresenceOnly(CheckGlobalValSummaryPresenceOnly) {} std::pair @@ -6094,7 +6071,7 @@ Error ModuleSummaryIndexBitcodeReader::parseValueSymbolTable( // 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 +6132,7 @@ Error ModuleSummaryIndexBitcodeReader::parseModule() { SeenValueSymbolTable = true; } SeenGlobalValSummary = true; - if (Error Err = parseEntireSummary()) + if (Error Err = parseEntireSummary(ModulePath)) return Err; break; case bitc::MODULE_STRTAB_BLOCK_ID: @@ -6187,7 +6164,7 @@ Error ModuleSummaryIndexBitcodeReader::parseModule() { 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 +6223,8 @@ Error ModuleSummaryIndexBitcodeReader::parseModule() { // 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 +6304,7 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary() { // 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 +6342,7 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary() { // 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 +6362,7 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary() { 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 +6552,10 @@ Error ModuleSummaryIndexBitcodeReader::parseModuleStringTable() { } // 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 +6573,7 @@ ModuleSummaryIndexBitcodeReader::parseSummaryIndexInto(ModuleSummaryIndex *I) { // 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 +6623,11 @@ static ErrorOr> 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); @@ -6703,7 +6675,12 @@ ErrorOr> llvm::parseBitcodeFile(MemoryBufferRef Buffer, std::string llvm::getBitcodeTargetTriple(MemoryBufferRef Buffer, LLVMContext &Context) { - BitcodeReader R(Buffer, Context); + ErrorOr StreamOrErr = + expectedToErrorOrAndEmitErrors(Context, initStream(Buffer)); + if (!StreamOrErr) + return ""; + + BitcodeReader R(std::move(*StreamOrErr), Context); ErrorOr Triple = expectedToErrorOrAndEmitErrors(Context, R.parseTriple()); if (Triple.getError()) @@ -6713,7 +6690,12 @@ std::string llvm::getBitcodeTargetTriple(MemoryBufferRef Buffer, bool llvm::isBitcodeContainingObjCCategory(MemoryBufferRef Buffer, LLVMContext &Context) { - BitcodeReader R(Buffer, Context); + ErrorOr StreamOrErr = + expectedToErrorOrAndEmitErrors(Context, initStream(Buffer)); + if (!StreamOrErr) + return false; + + BitcodeReader R(std::move(*StreamOrErr), Context); ErrorOr hasObjCCategory = expectedToErrorOrAndEmitErrors(Context, R.hasObjCCategory()); if (hasObjCCategory.getError()) @@ -6723,7 +6705,12 @@ bool llvm::isBitcodeContainingObjCCategory(MemoryBufferRef Buffer, std::string llvm::getBitcodeProducerString(MemoryBufferRef Buffer, LLVMContext &Context) { - BitcodeReader R(Buffer, Context); + ErrorOr StreamOrErr = + expectedToErrorOrAndEmitErrors(Context, initStream(Buffer)); + if (!StreamOrErr) + return ""; + + BitcodeReader R(std::move(*StreamOrErr), Context); ErrorOr ProducerString = expectedToErrorOrAndEmitErrors(Context, R.parseIdentificationBlock()); if (ProducerString.getError()) @@ -6735,12 +6722,18 @@ std::string llvm::getBitcodeProducerString(MemoryBufferRef Buffer, 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); @@ -6750,10 +6743,15 @@ ErrorOr> llvm::getModuleSummaryIndex( bool llvm::hasGlobalValueSummary( MemoryBufferRef Buffer, const DiagnosticHandlerFunction &DiagnosticHandler) { - ModuleSummaryIndexBitcodeReader R(Buffer, true); + ErrorOr StreamOrErr = expectedToErrorOrAndEmitErrors( + DiagnosticHandler, initStream(Buffer)); + if (!StreamOrErr) + return false; - if (errorToErrorCodeAndEmitErrors(DiagnosticHandler, - R.parseSummaryIndexInto(nullptr))) + ModuleSummaryIndexBitcodeReader R(std::move(*StreamOrErr), true); + if (errorToErrorCodeAndEmitErrors( + DiagnosticHandler, + R.parseSummaryIndexInto(nullptr, Buffer.getBufferIdentifier()))) return false; return R.foundGlobalValSummary();