llvm.org GIT mirror llvm / 34c84f4
Bitcode: Introduce initial multi-module reader API. Implement getLazyBitcodeModule() and parseBitcodeFile() in terms of it. Differential Revision: https://reviews.llvm.org/D26719 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@287156 91177308-0d34-0410-b5e6-96231b3b80d8 Peter Collingbourne 3 years ago
4 changed file(s) with 150 addition(s) and 62 deletion(s). Raw diff Collapse all Expand all
3838 return errorToErrorCodeAndEmitErrors(Ctx, Val.takeError());
3939 return std::move(*Val);
4040 }
41
42 /// Represents a module in a bitcode file.
43 class BitcodeModule {
44 ArrayRef Buffer;
45 StringRef ModuleIdentifier;
46
47 // The bitstream location of the IDENTIFICATION_BLOCK.
48 uint64_t IdentificationBit;
49
50 // The bitstream location of this module's MODULE_BLOCK.
51 uint64_t ModuleBit;
52
53 BitcodeModule(ArrayRef Buffer, StringRef ModuleIdentifier,
54 uint64_t IdentificationBit, uint64_t ModuleBit)
55 : Buffer(Buffer), ModuleIdentifier(ModuleIdentifier),
56 IdentificationBit(IdentificationBit), ModuleBit(ModuleBit) {}
57
58 // Calls the ctor.
59 friend Expected>
60 getBitcodeModuleList(MemoryBufferRef Buffer);
61
62 Expected>
63 getModuleImpl(LLVMContext &Context, bool MaterializeAll,
64 bool ShouldLazyLoadMetadata);
65
66 public:
67 /// Read the bitcode module and prepare for lazy deserialization of function
68 /// bodies. If ShouldLazyLoadMetadata is true, lazily load metadata as well.
69 Expected>
70 getLazyModule(LLVMContext &Context, bool ShouldLazyLoadMetadata);
71
72 /// Read the entire bitcode module and return it.
73 Expected> parseModule(LLVMContext &Context);
74 };
75
76 /// Returns a list of modules in the specified bitcode buffer.
77 Expected>
78 getBitcodeModuleList(MemoryBufferRef Buffer);
4179
4280 /// Read the header of the specified bitcode buffer and prepare for lazy
4381 /// deserialization of function bodies. If ShouldLazyLoadMetadata is true,
606606 std::vector BundleTags;
607607
608608 public:
609 BitcodeReader(BitstreamCursor Stream, LLVMContext &Context);
609 BitcodeReader(BitstreamCursor Stream, StringRef ProducerIdentification,
610 LLVMContext &Context);
610611
611612 Error materializeForwardReferencedFunctions();
612613
840841 return std::error_code();
841842 }
842843
843 BitcodeReader::BitcodeReader(BitstreamCursor Stream, LLVMContext &Context)
844 : BitcodeReaderBase(std::move(Stream)), Context(Context), ValueList(Context),
845 MetadataList(Context) {}
844 BitcodeReader::BitcodeReader(BitstreamCursor Stream,
845 StringRef ProducerIdentification,
846 LLVMContext &Context)
847 : BitcodeReaderBase(std::move(Stream)), Context(Context),
848 ValueList(Context), MetadataList(Context) {
849 this->ProducerIdentification = ProducerIdentification;
850 }
846851
847852 Error BitcodeReader::materializeForwardReferencedFunctions() {
848853 if (WillMaterializeAllForwardRefs)
43644369
43654370 Error BitcodeReader::parseBitcodeInto(Module *M, bool ShouldLazyLoadMetadata) {
43664371 TheModule = M;
4367
4368 // We expect a number of well-defined blocks, though we don't necessarily
4369 // need to understand them all.
4370 while (true) {
4371 if (Stream.AtEndOfStream()) {
4372 // We didn't really read a proper Module.
4373 return error("Malformed IR file");
4374 }
4375
4376 BitstreamEntry Entry =
4377 Stream.advance(BitstreamCursor::AF_DontAutoprocessAbbrevs);
4378
4379 if (Entry.Kind != BitstreamEntry::SubBlock)
4380 return error("Malformed block");
4381
4382 if (Entry.ID == bitc::IDENTIFICATION_BLOCK_ID) {
4383 Expected ProducerIdentificationOrErr =
4384 readIdentificationBlock(Stream);
4385 if (!ProducerIdentificationOrErr)
4386 return ProducerIdentificationOrErr.takeError();
4387 ProducerIdentification = *ProducerIdentificationOrErr;
4388 continue;
4389 }
4390
4391 if (Entry.ID == bitc::MODULE_BLOCK_ID)
4392 return parseModule(0, ShouldLazyLoadMetadata);
4393
4394 if (Stream.SkipBlock())
4395 return error("Invalid record");
4396 }
4372 return parseModule(0, ShouldLazyLoadMetadata);
43974373 }
43984374
43994375 Error BitcodeReader::parseGlobalObjectAttachment(GlobalObject &GO,
65656541 // External interface
65666542 //===----------------------------------------------------------------------===//
65676543
6544 Expected>
6545 llvm::getBitcodeModuleList(MemoryBufferRef Buffer) {
6546 Expected StreamOrErr = initStream(Buffer);
6547 if (!StreamOrErr)
6548 return StreamOrErr.takeError();
6549 BitstreamCursor &Stream = *StreamOrErr;
6550
6551 uint64_t IdentificationBit = -1ull;
6552 std::vector Modules;
6553 while (true) {
6554 // We may be consuming bitcode from a client that leaves garbage at the end
6555 // of the bitcode stream (e.g. Apple's ar tool). If we are close enough to
6556 // the end that there cannot possibly be another module, stop looking.
6557 if (Stream.getCurrentByteNo() + 8 >= Stream.getBitcodeBytes().size())
6558 return Modules;
6559
6560 BitstreamEntry Entry = Stream.advance();
6561 switch (Entry.Kind) {
6562 case BitstreamEntry::EndBlock:
6563 case BitstreamEntry::Error:
6564 return error("Malformed block");
6565
6566 case BitstreamEntry::SubBlock:
6567 if (Entry.ID == bitc::IDENTIFICATION_BLOCK_ID)
6568 IdentificationBit = Stream.GetCurrentBitNo();
6569 else if (Entry.ID == bitc::MODULE_BLOCK_ID)
6570 Modules.push_back({Stream.getBitcodeBytes(),
6571 Buffer.getBufferIdentifier(), IdentificationBit,
6572 Stream.GetCurrentBitNo()});
6573
6574 if (Stream.SkipBlock())
6575 return error("Malformed block");
6576 continue;
6577 case BitstreamEntry::Record:
6578 Stream.skipRecord(Entry.ID);
6579 continue;
6580 }
6581 }
6582 }
6583
65686584 /// \brief Get a lazy one-at-time loading module from bitcode.
65696585 ///
65706586 /// This isn't always used in a lazy context. In particular, it's also used by
6571 /// \a parseBitcodeFile(). If this is truly lazy, then we need to eagerly pull
6587 /// \a parseModule(). If this is truly lazy, then we need to eagerly pull
65726588 /// in forward-referenced functions from block address references.
65736589 ///
65746590 /// \param[in] MaterializeAll Set to \c true if we should materialize
65756591 /// everything.
6576 static Expected>
6577 getLazyBitcodeModuleImpl(MemoryBufferRef Buffer, LLVMContext &Context,
6578 bool MaterializeAll,
6579 bool ShouldLazyLoadMetadata = false) {
6580 Expected StreamOrErr = initStream(Buffer);
6581 if (!StreamOrErr)
6582 return StreamOrErr.takeError();
6583
6584 BitcodeReader *R = new BitcodeReader(std::move(*StreamOrErr), Context);
6592 Expected>
6593 BitcodeModule::getModuleImpl(LLVMContext &Context, bool MaterializeAll,
6594 bool ShouldLazyLoadMetadata) {
6595 BitstreamCursor Stream(Buffer);
6596
6597 std::string ProducerIdentification;
6598 if (IdentificationBit != -1ull) {
6599 Stream.JumpToBit(IdentificationBit);
6600 Expected ProducerIdentificationOrErr =
6601 readIdentificationBlock(Stream);
6602 if (!ProducerIdentificationOrErr)
6603 return ProducerIdentificationOrErr.takeError();
6604
6605 ProducerIdentification = *ProducerIdentificationOrErr;
6606 }
6607
6608 Stream.JumpToBit(ModuleBit);
6609 auto *R =
6610 new BitcodeReader(std::move(Stream), ProducerIdentification, Context);
65856611
65866612 std::unique_ptr M =
6587 llvm::make_unique(Buffer.getBufferIdentifier(), Context);
6613 llvm::make_unique(ModuleIdentifier, Context);
65886614 M->setMaterializer(R);
65896615
65906616 // Delay parsing Metadata if ShouldLazyLoadMetadata is true.
66046630 }
66056631
66066632 Expected>
6633 BitcodeModule::getLazyModule(LLVMContext &Context,
6634 bool ShouldLazyLoadMetadata) {
6635 return getModuleImpl(Context, false, ShouldLazyLoadMetadata);
6636 }
6637
6638 Expected>
66076639 llvm::getLazyBitcodeModule(MemoryBufferRef Buffer,
66086640 LLVMContext &Context, bool ShouldLazyLoadMetadata) {
6609 return getLazyBitcodeModuleImpl(Buffer, Context, false,
6610 ShouldLazyLoadMetadata);
6641 Expected> MsOrErr = getBitcodeModuleList(Buffer);
6642 if (!MsOrErr)
6643 return MsOrErr.takeError();
6644
6645 if (MsOrErr->size() != 1)
6646 return error("Expected a single module");
6647
6648 return (*MsOrErr)[0].getLazyModule(Context, ShouldLazyLoadMetadata);
66116649 }
66126650
66136651 Expected>
66206658 return MOrErr;
66216659 }
66226660
6661 Expected>
6662 BitcodeModule::parseModule(LLVMContext &Context) {
6663 return getModuleImpl(Context, true, false);
6664 // TODO: Restore the use-lists to the in-memory state when the bitcode was
6665 // written. We must defer until the Module has been fully materialized.
6666 }
6667
66236668 Expected> llvm::parseBitcodeFile(MemoryBufferRef Buffer,
66246669 LLVMContext &Context) {
6625 return getLazyBitcodeModuleImpl(Buffer, Context, true);
6626 // TODO: Restore the use-lists to the in-memory state when the bitcode was
6627 // written. We must defer until the Module has been fully materialized.
6670 Expected> MsOrErr = getBitcodeModuleList(Buffer);
6671 if (!MsOrErr)
6672 return MsOrErr.takeError();
6673
6674 if (MsOrErr->size() != 1)
6675 return error("Expected a single module");
6676
6677 return (*MsOrErr)[0].parseModule(Context);
66286678 }
66296679
66306680 Expected llvm::getBitcodeTargetTriple(MemoryBufferRef Buffer) {
3030
3131 INVALID-EMPTY: Invalid bitcode signature
3232 INVALID-ENCODING: Invalid encoding
33 BAD-ABBREV: Abbreviation starts with an Array or a Blob
34 UNEXPECTED-EOF: Unexpected end of file
35 BAD-ABBREV-NUMBER: Invalid abbrev number
33 BAD-ABBREV: Malformed block
34 UNEXPECTED-EOF: Malformed block
35 BAD-ABBREV-NUMBER: Malformed block
3636 BAD-TYPE-TABLE-FORWARD-REF: Invalid TYPE table: Only named structs can be forward referenced
37 BAD-BITWIDTH: Bitwidth for integer type out of range
37 BAD-BITWIDTH: Malformed block
3838 BAD-ALIGN: Invalid alignment value
3939 MISMATCHED-EXPLICIT-GEP: Explicit gep type does not match pointee type of pointer operand
4040 MISMATCHED-EXPLICIT-LOAD: Explicit load/store type does not match pointee type of pointer operand
6868 RUN: not llvm-dis -disable-output %p/Inputs/invalid-no-proper-module.bc 2>&1 | \
6969 RUN: FileCheck --check-prefix=NO-MODULE %s
7070
71 NO-MODULE: Malformed IR file
71 NO-MODULE: Expected a single module
7272
7373 RUN: not llvm-dis -disable-output %p/Inputs/invalid-fp-shift.bc 2>&1 | \
7474 RUN: FileCheck --check-prefix=FP-SHIFT %s
104104 RUN: not llvm-dis -disable-output %p/Inputs/invalid-fwdref-type-mismatch-2.bc 2>&1 | \
105105 RUN: FileCheck --check-prefix=FWDREF-TYPE-MISMATCH %s
106106
107 FWDREF-TYPE-MISMATCH: Type mismatch in constant table!
107 FWDREF-TYPE-MISMATCH: Malformed block
108108
109109 RUN: not llvm-dis -disable-output %p/Inputs/invalid-array-element-type.bc 2>&1 | \
110110 RUN: FileCheck --check-prefix=ELEMENT-TYPE %s
153153 RUN: not llvm-dis -disable-output %p/Inputs/invalid-load-ptr-type.bc 2>&1 | \
154154 RUN: FileCheck --check-prefix=BAD-LOAD-PTR-TYPE %s
155155
156 BAD-LOAD-PTR-TYPE: Cannot load/store from pointer
156 BAD-LOAD-PTR-TYPE: Malformed block
157157
158158 RUN: not llvm-dis -disable-output %p/Inputs/invalid-inserted-value-type-mismatch.bc 2>&1 | \
159159 RUN: FileCheck --check-prefix=INSERT-TYPE-MISMATCH %s
173173 RUN: not llvm-dis -disable-output %p/Inputs/invalid-function-comdat-id.bc 2>&1 | \
174174 RUN: FileCheck --check-prefix=INVALID-FCOMDAT-ID %s
175175
176 INVALID-FCOMDAT-ID: Invalid function comdat ID
176 INVALID-FCOMDAT-ID: Malformed block
177177
178178 RUN: not llvm-dis -disable-output %p/Inputs/invalid-global-var-comdat-id.bc 2>&1 | \
179179 RUN: FileCheck --check-prefix=INVALID-GVCOMDAT-ID %s
188188 RUN: not llvm-dis -disable-output %p/Inputs/invalid-array-operand-encoding.bc 2>&1 | \
189189 RUN: FileCheck --check-prefix=ARRAY-OP-ENC %s
190190
191 ARRAY-OP-ENC: Array element type has to be an encoding of a type
191 ARRAY-OP-ENC: Malformed block
192192
193193 RUN: not llvm-dis -disable-output %p/Inputs/invalid-metadata-not-followed-named-node.bc 2>&1 | \
194194 RUN: FileCheck --check-prefix=META-NOT-FOLLOWED-BY-NAMED-META %s
195195
196 META-NOT-FOLLOWED-BY-NAMED-META: METADATA_NAME not followed by METADATA_NAMED_NODE
196 META-NOT-FOLLOWED-BY-NAMED-META: Malformed block
197197
198198 RUN: not llvm-dis -disable-output %p/Inputs/invalid-vector-length.bc 2>&1 | \
199199 RUN: FileCheck --check-prefix=VECTOR-LENGTH %s
213213 RUN: not llvm-dis -disable-output %p/Inputs/invalid-name-with-0-byte.bc 2>&1 | \
214214 RUN: FileCheck --check-prefix=NAME-WITH-0 %s
215215
216 NAME-WITH-0: Invalid value name
216 NAME-WITH-0: Malformed block
217217
218218 RUN: not llvm-dis -disable-output %p/Inputs/invalid-void-constant.bc 2>&1 | \
219219 RUN: FileCheck --check-prefix=VOID-CONSTANT-TYPE %s
0 ; RUN: not llvm-dis < %s.bc 2>&1 | FileCheck %s
11 ; PR8494
22
3 ; CHECK: Invalid record
3 ; CHECK: Malformed block