File indexing completed on 2026-05-10 08:43:22
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_BITSTREAM_BITSTREAMREADER_H
0015 #define LLVM_BITSTREAM_BITSTREAMREADER_H
0016
0017 #include "llvm/ADT/ArrayRef.h"
0018 #include "llvm/ADT/SmallVector.h"
0019 #include "llvm/Bitstream/BitCodes.h"
0020 #include "llvm/Support/Endian.h"
0021 #include "llvm/Support/Error.h"
0022 #include "llvm/Support/MemoryBufferRef.h"
0023 #include <algorithm>
0024 #include <cassert>
0025 #include <climits>
0026 #include <cstddef>
0027 #include <cstdint>
0028 #include <memory>
0029 #include <optional>
0030 #include <string>
0031 #include <utility>
0032 #include <vector>
0033
0034 namespace llvm {
0035
0036
0037 class BitstreamBlockInfo {
0038 public:
0039
0040
0041 struct BlockInfo {
0042 unsigned BlockID = 0;
0043 std::vector<std::shared_ptr<BitCodeAbbrev>> Abbrevs;
0044 std::string Name;
0045 std::vector<std::pair<unsigned, std::string>> RecordNames;
0046 };
0047
0048 private:
0049 std::vector<BlockInfo> BlockInfoRecords;
0050
0051 public:
0052
0053
0054 const BlockInfo *getBlockInfo(unsigned BlockID) const {
0055
0056 if (!BlockInfoRecords.empty() && BlockInfoRecords.back().BlockID == BlockID)
0057 return &BlockInfoRecords.back();
0058
0059 for (const BlockInfo &BI : BlockInfoRecords)
0060 if (BI.BlockID == BlockID)
0061 return &BI;
0062 return nullptr;
0063 }
0064
0065 BlockInfo &getOrCreateBlockInfo(unsigned BlockID) {
0066 if (const BlockInfo *BI = getBlockInfo(BlockID))
0067 return *const_cast<BlockInfo*>(BI);
0068
0069
0070 BlockInfoRecords.emplace_back();
0071 BlockInfoRecords.back().BlockID = BlockID;
0072 return BlockInfoRecords.back();
0073 }
0074 };
0075
0076
0077
0078
0079 class SimpleBitstreamCursor {
0080 ArrayRef<uint8_t> BitcodeBytes;
0081 size_t NextChar = 0;
0082
0083 public:
0084
0085
0086
0087
0088
0089 using word_t = size_t;
0090
0091 private:
0092 word_t CurWord = 0;
0093
0094
0095
0096 unsigned BitsInCurWord = 0;
0097
0098 public:
0099 SimpleBitstreamCursor() = default;
0100 explicit SimpleBitstreamCursor(ArrayRef<uint8_t> BitcodeBytes)
0101 : BitcodeBytes(BitcodeBytes) {}
0102 explicit SimpleBitstreamCursor(StringRef BitcodeBytes)
0103 : BitcodeBytes(arrayRefFromStringRef(BitcodeBytes)) {}
0104 explicit SimpleBitstreamCursor(MemoryBufferRef BitcodeBytes)
0105 : SimpleBitstreamCursor(BitcodeBytes.getBuffer()) {}
0106
0107 bool canSkipToPos(size_t pos) const {
0108
0109 return pos <= BitcodeBytes.size();
0110 }
0111
0112 bool AtEndOfStream() {
0113 return BitsInCurWord == 0 && BitcodeBytes.size() <= NextChar;
0114 }
0115
0116
0117 uint64_t GetCurrentBitNo() const {
0118 return uint64_t(NextChar)*CHAR_BIT - BitsInCurWord;
0119 }
0120
0121
0122 uint64_t getCurrentByteNo() const { return GetCurrentBitNo() / 8; }
0123
0124 ArrayRef<uint8_t> getBitcodeBytes() const { return BitcodeBytes; }
0125
0126
0127 Error JumpToBit(uint64_t BitNo) {
0128 size_t ByteNo = size_t(BitNo/8) & ~(sizeof(word_t)-1);
0129 unsigned WordBitNo = unsigned(BitNo & (sizeof(word_t)*8-1));
0130 assert(canSkipToPos(ByteNo) && "Invalid location");
0131
0132
0133 NextChar = ByteNo;
0134 BitsInCurWord = 0;
0135
0136
0137 if (WordBitNo) {
0138 if (Expected<word_t> Res = Read(WordBitNo))
0139 return Error::success();
0140 else
0141 return Res.takeError();
0142 }
0143
0144 return Error::success();
0145 }
0146
0147
0148 const uint8_t *getPointerToByte(uint64_t ByteNo, uint64_t NumBytes) {
0149 return BitcodeBytes.data() + ByteNo;
0150 }
0151
0152
0153
0154
0155 const uint8_t *getPointerToBit(uint64_t BitNo, uint64_t NumBytes) {
0156 assert(!(BitNo % 8) && "Expected bit on byte boundary");
0157 return getPointerToByte(BitNo / 8, NumBytes);
0158 }
0159
0160 Error fillCurWord() {
0161 if (NextChar >= BitcodeBytes.size())
0162 return createStringError(std::errc::io_error,
0163 "Unexpected end of file reading %u of %u bytes",
0164 NextChar, BitcodeBytes.size());
0165
0166
0167 const uint8_t *NextCharPtr = BitcodeBytes.data() + NextChar;
0168 unsigned BytesRead;
0169 if (BitcodeBytes.size() >= NextChar + sizeof(word_t)) {
0170 BytesRead = sizeof(word_t);
0171 CurWord =
0172 support::endian::read<word_t, llvm::endianness::little>(NextCharPtr);
0173 } else {
0174
0175 BytesRead = BitcodeBytes.size() - NextChar;
0176 CurWord = 0;
0177 for (unsigned B = 0; B != BytesRead; ++B)
0178 CurWord |= uint64_t(NextCharPtr[B]) << (B * 8);
0179 }
0180 NextChar += BytesRead;
0181 BitsInCurWord = BytesRead * 8;
0182 return Error::success();
0183 }
0184
0185 Expected<word_t> Read(unsigned NumBits) {
0186 static const unsigned BitsInWord = sizeof(word_t) * 8;
0187
0188 assert(NumBits && NumBits <= BitsInWord &&
0189 "Cannot return zero or more than BitsInWord bits!");
0190
0191 static const unsigned Mask = sizeof(word_t) > 4 ? 0x3f : 0x1f;
0192
0193
0194 if (BitsInCurWord >= NumBits) {
0195 word_t R = CurWord & (~word_t(0) >> (BitsInWord - NumBits));
0196
0197
0198 CurWord >>= (NumBits & Mask);
0199
0200 BitsInCurWord -= NumBits;
0201 return R;
0202 }
0203
0204 word_t R = BitsInCurWord ? CurWord : 0;
0205 unsigned BitsLeft = NumBits - BitsInCurWord;
0206
0207 if (Error fillResult = fillCurWord())
0208 return std::move(fillResult);
0209
0210
0211 if (BitsLeft > BitsInCurWord)
0212 return createStringError(std::errc::io_error,
0213 "Unexpected end of file reading %u of %u bits",
0214 BitsInCurWord, BitsLeft);
0215
0216 word_t R2 = CurWord & (~word_t(0) >> (BitsInWord - BitsLeft));
0217
0218
0219 CurWord >>= (BitsLeft & Mask);
0220
0221 BitsInCurWord -= BitsLeft;
0222
0223 R |= R2 << (NumBits - BitsLeft);
0224
0225 return R;
0226 }
0227
0228 Expected<uint32_t> ReadVBR(const unsigned NumBits) {
0229 Expected<unsigned> MaybeRead = Read(NumBits);
0230 if (!MaybeRead)
0231 return MaybeRead;
0232 uint32_t Piece = MaybeRead.get();
0233
0234 assert(NumBits <= 32 && NumBits >= 1 && "Invalid NumBits value");
0235 const uint32_t MaskBitOrder = (NumBits - 1);
0236 const uint32_t Mask = 1UL << MaskBitOrder;
0237
0238 if ((Piece & Mask) == 0)
0239 return Piece;
0240
0241 uint32_t Result = 0;
0242 unsigned NextBit = 0;
0243 while (true) {
0244 Result |= (Piece & (Mask - 1)) << NextBit;
0245
0246 if ((Piece & Mask) == 0)
0247 return Result;
0248
0249 NextBit += NumBits-1;
0250 if (NextBit >= 32)
0251 return createStringError(std::errc::illegal_byte_sequence,
0252 "Unterminated VBR");
0253
0254 MaybeRead = Read(NumBits);
0255 if (!MaybeRead)
0256 return MaybeRead;
0257 Piece = MaybeRead.get();
0258 }
0259 }
0260
0261
0262
0263 Expected<uint64_t> ReadVBR64(const unsigned NumBits) {
0264 Expected<uint64_t> MaybeRead = Read(NumBits);
0265 if (!MaybeRead)
0266 return MaybeRead;
0267 uint32_t Piece = MaybeRead.get();
0268 assert(NumBits <= 32 && NumBits >= 1 && "Invalid NumBits value");
0269 const uint32_t MaskBitOrder = (NumBits - 1);
0270 const uint32_t Mask = 1UL << MaskBitOrder;
0271
0272 if ((Piece & Mask) == 0)
0273 return uint64_t(Piece);
0274
0275 uint64_t Result = 0;
0276 unsigned NextBit = 0;
0277 while (true) {
0278 Result |= uint64_t(Piece & (Mask - 1)) << NextBit;
0279
0280 if ((Piece & Mask) == 0)
0281 return Result;
0282
0283 NextBit += NumBits-1;
0284 if (NextBit >= 64)
0285 return createStringError(std::errc::illegal_byte_sequence,
0286 "Unterminated VBR");
0287
0288 MaybeRead = Read(NumBits);
0289 if (!MaybeRead)
0290 return MaybeRead;
0291 Piece = MaybeRead.get();
0292 }
0293 }
0294
0295 void SkipToFourByteBoundary() {
0296
0297
0298 if (sizeof(word_t) > 4 &&
0299 BitsInCurWord >= 32) {
0300 CurWord >>= BitsInCurWord-32;
0301 BitsInCurWord = 32;
0302 return;
0303 }
0304
0305 BitsInCurWord = 0;
0306 }
0307
0308
0309 size_t SizeInBytes() const { return BitcodeBytes.size(); }
0310
0311
0312 void skipToEnd() { NextChar = BitcodeBytes.size(); }
0313
0314
0315 bool isSizePlausible(size_t Size) const {
0316
0317
0318 return Size < BitcodeBytes.size() * 8;
0319 }
0320 };
0321
0322
0323
0324 struct BitstreamEntry {
0325 enum {
0326 Error,
0327 EndBlock,
0328
0329 SubBlock,
0330 Record
0331 } Kind;
0332
0333 unsigned ID;
0334
0335 static BitstreamEntry getError() {
0336 BitstreamEntry E; E.Kind = Error; return E;
0337 }
0338
0339 static BitstreamEntry getEndBlock() {
0340 BitstreamEntry E; E.Kind = EndBlock; return E;
0341 }
0342
0343 static BitstreamEntry getSubBlock(unsigned ID) {
0344 BitstreamEntry E; E.Kind = SubBlock; E.ID = ID; return E;
0345 }
0346
0347 static BitstreamEntry getRecord(unsigned AbbrevID) {
0348 BitstreamEntry E; E.Kind = Record; E.ID = AbbrevID; return E;
0349 }
0350 };
0351
0352
0353
0354
0355
0356
0357 class BitstreamCursor : SimpleBitstreamCursor {
0358
0359
0360 unsigned CurCodeSize = 2;
0361
0362
0363 std::vector<std::shared_ptr<BitCodeAbbrev>> CurAbbrevs;
0364
0365 struct Block {
0366 unsigned PrevCodeSize;
0367 std::vector<std::shared_ptr<BitCodeAbbrev>> PrevAbbrevs;
0368
0369 explicit Block(unsigned PCS) : PrevCodeSize(PCS) {}
0370 };
0371
0372
0373 SmallVector<Block, 8> BlockScope;
0374
0375 BitstreamBlockInfo *BlockInfo = nullptr;
0376
0377 public:
0378 static const size_t MaxChunkSize = 32;
0379
0380 BitstreamCursor() = default;
0381 explicit BitstreamCursor(ArrayRef<uint8_t> BitcodeBytes)
0382 : SimpleBitstreamCursor(BitcodeBytes) {}
0383 explicit BitstreamCursor(StringRef BitcodeBytes)
0384 : SimpleBitstreamCursor(BitcodeBytes) {}
0385 explicit BitstreamCursor(MemoryBufferRef BitcodeBytes)
0386 : SimpleBitstreamCursor(BitcodeBytes) {}
0387
0388 using SimpleBitstreamCursor::AtEndOfStream;
0389 using SimpleBitstreamCursor::canSkipToPos;
0390 using SimpleBitstreamCursor::fillCurWord;
0391 using SimpleBitstreamCursor::getBitcodeBytes;
0392 using SimpleBitstreamCursor::GetCurrentBitNo;
0393 using SimpleBitstreamCursor::getCurrentByteNo;
0394 using SimpleBitstreamCursor::getPointerToByte;
0395 using SimpleBitstreamCursor::JumpToBit;
0396 using SimpleBitstreamCursor::Read;
0397 using SimpleBitstreamCursor::ReadVBR;
0398 using SimpleBitstreamCursor::ReadVBR64;
0399 using SimpleBitstreamCursor::SizeInBytes;
0400 using SimpleBitstreamCursor::skipToEnd;
0401
0402
0403 unsigned getAbbrevIDWidth() const { return CurCodeSize; }
0404
0405
0406 enum {
0407
0408
0409 AF_DontPopBlockAtEnd = 1,
0410
0411
0412
0413 AF_DontAutoprocessAbbrevs = 2
0414 };
0415
0416
0417 Expected<BitstreamEntry> advance(unsigned Flags = 0) {
0418 while (true) {
0419 if (AtEndOfStream())
0420 return BitstreamEntry::getError();
0421
0422 Expected<unsigned> MaybeCode = ReadCode();
0423 if (!MaybeCode)
0424 return MaybeCode.takeError();
0425 unsigned Code = MaybeCode.get();
0426
0427 if (Code == bitc::END_BLOCK) {
0428
0429 if (!(Flags & AF_DontPopBlockAtEnd) && ReadBlockEnd())
0430 return BitstreamEntry::getError();
0431 return BitstreamEntry::getEndBlock();
0432 }
0433
0434 if (Code == bitc::ENTER_SUBBLOCK) {
0435 if (Expected<unsigned> MaybeSubBlock = ReadSubBlockID())
0436 return BitstreamEntry::getSubBlock(MaybeSubBlock.get());
0437 else
0438 return MaybeSubBlock.takeError();
0439 }
0440
0441 if (Code == bitc::DEFINE_ABBREV &&
0442 !(Flags & AF_DontAutoprocessAbbrevs)) {
0443
0444
0445 if (Error Err = ReadAbbrevRecord())
0446 return std::move(Err);
0447 continue;
0448 }
0449
0450 return BitstreamEntry::getRecord(Code);
0451 }
0452 }
0453
0454
0455
0456 Expected<BitstreamEntry> advanceSkippingSubblocks(unsigned Flags = 0) {
0457 while (true) {
0458
0459 Expected<BitstreamEntry> MaybeEntry = advance(Flags);
0460 if (!MaybeEntry)
0461 return MaybeEntry;
0462 BitstreamEntry Entry = MaybeEntry.get();
0463
0464 if (Entry.Kind != BitstreamEntry::SubBlock)
0465 return Entry;
0466
0467
0468 if (Error Err = SkipBlock())
0469 return std::move(Err);
0470 }
0471 }
0472
0473 Expected<unsigned> ReadCode() { return Read(CurCodeSize); }
0474
0475
0476
0477
0478
0479 Expected<unsigned> ReadSubBlockID() { return ReadVBR(bitc::BlockIDWidth); }
0480
0481
0482
0483 Error SkipBlock() {
0484
0485 if (Expected<uint32_t> Res = ReadVBR(bitc::CodeLenWidth))
0486 ;
0487
0488 else
0489 return Res.takeError();
0490
0491 SkipToFourByteBoundary();
0492 Expected<unsigned> MaybeNum = Read(bitc::BlockSizeWidth);
0493 if (!MaybeNum)
0494 return MaybeNum.takeError();
0495 size_t NumFourBytes = MaybeNum.get();
0496
0497
0498
0499 size_t SkipTo = GetCurrentBitNo() + NumFourBytes * 4 * 8;
0500 if (AtEndOfStream())
0501 return createStringError(std::errc::illegal_byte_sequence,
0502 "can't skip block: already at end of stream");
0503 if (!canSkipToPos(SkipTo / 8))
0504 return createStringError(std::errc::illegal_byte_sequence,
0505 "can't skip to bit %zu from %" PRIu64, SkipTo,
0506 GetCurrentBitNo());
0507
0508 if (Error Res = JumpToBit(SkipTo))
0509 return Res;
0510
0511 return Error::success();
0512 }
0513
0514
0515 Error EnterSubBlock(unsigned BlockID, unsigned *NumWordsP = nullptr);
0516
0517 bool ReadBlockEnd() {
0518 if (BlockScope.empty()) return true;
0519
0520
0521
0522 SkipToFourByteBoundary();
0523
0524 popBlockScope();
0525 return false;
0526 }
0527
0528 private:
0529 void popBlockScope() {
0530 CurCodeSize = BlockScope.back().PrevCodeSize;
0531
0532 CurAbbrevs = std::move(BlockScope.back().PrevAbbrevs);
0533 BlockScope.pop_back();
0534 }
0535
0536
0537
0538
0539
0540 public:
0541
0542 Expected<const BitCodeAbbrev *> getAbbrev(unsigned AbbrevID) {
0543 unsigned AbbrevNo = AbbrevID - bitc::FIRST_APPLICATION_ABBREV;
0544 if (AbbrevNo >= CurAbbrevs.size())
0545 return createStringError(
0546 std::errc::illegal_byte_sequence, "Invalid abbrev number");
0547 return CurAbbrevs[AbbrevNo].get();
0548 }
0549
0550
0551 Expected<unsigned> skipRecord(unsigned AbbrevID);
0552
0553 Expected<unsigned> readRecord(unsigned AbbrevID,
0554 SmallVectorImpl<uint64_t> &Vals,
0555 StringRef *Blob = nullptr);
0556
0557
0558
0559
0560 Error ReadAbbrevRecord();
0561
0562
0563
0564
0565
0566
0567 Expected<std::optional<BitstreamBlockInfo>>
0568 ReadBlockInfoBlock(bool ReadBlockInfoNames = false);
0569
0570
0571
0572 void setBlockInfo(BitstreamBlockInfo *BI) { BlockInfo = BI; }
0573 };
0574
0575 }
0576
0577 #endif