1a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth//===- NaClBitstreamReader.cpp --------------------------------------------===// 2a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth// NaClBitstreamReader implementation 3a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth// 4a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth// The LLVM Compiler Infrastructure 5a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth// 6a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth// This file is distributed under the University of Illinois Open Source 7a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth// License. See LICENSE.TXT for details. 8a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth// 9a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth//===----------------------------------------------------------------------===// 10a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth 11a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth#include "llvm/ADT/STLExtras.h" 12a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth#include "llvm/Bitcode/NaCl/NaClBitstreamReader.h" 13a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth#include "llvm/Support/Format.h" 14a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth#include "llvm/Support/raw_ostream.h" 15a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth 16a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnothusing namespace llvm; 17a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth 18a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnothnamespace { 19a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth 20a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnothstatic const char *ErrorLevelName[] = { 21a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth "Warning", 22a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth "Error", 23a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth "Fatal" 24a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth}; 25a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth 26a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth} // End of anonymous namespace. 27a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth 28a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnothstd::string llvm::naclbitc::getBitAddress(uint64_t Bit) { 29a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth std::string Buffer; 30a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth raw_string_ostream Stream(Buffer); 31a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth Stream << (Bit / 8) << ":" << (Bit % 8); 32a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth return Stream.str(); 33a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth} 34a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth 35a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnothraw_ostream &llvm::naclbitc::ErrorAt( 36a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth raw_ostream &Out, ErrorLevel Level, uint64_t BitPosition) { 37a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth assert(Level < array_lengthof(::ErrorLevelName)); 38a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth return Out << ErrorLevelName[Level] << "(" 39a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth << naclbitc::getBitAddress(BitPosition) << "): "; 40a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth} 41a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth 42a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth//===----------------------------------------------------------------------===// 43a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth// NaClBitstreamCursor implementation 44a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth//===----------------------------------------------------------------------===// 45a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth 46a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnothvoid NaClBitstreamCursor::ErrorHandler:: 47a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim StichnothFatal(const std::string &ErrorMessage) const { 48a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth // Default implementation is simply print message, and the bit where 49a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth // the error occurred. 50a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth std::string Buffer; 51a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth raw_string_ostream StrBuf(Buffer); 52a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth naclbitc::ErrorAt(StrBuf, naclbitc::Fatal, 53a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth Cursor.getErrorBitNo(getCurrentBitNo())) << ErrorMessage; 54a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth report_fatal_error(StrBuf.str()); 55a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth} 56a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth 57a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnothvoid NaClBitstreamCursor::reportInvalidAbbrevNumber(unsigned AbbrevNo) const { 58a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth std::string Buffer; 59a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth raw_string_ostream StrBuf(Buffer); 60a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth StrBuf << "Invalid abbreviation # " << AbbrevNo << " defined for record"; 61a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth ErrHandler->Fatal(StrBuf.str()); 62a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth} 63a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth 64a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnothvoid NaClBitstreamCursor::reportInvalidJumpToBit(uint64_t BitNo) const { 65a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth std::string Buffer; 66a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth raw_string_ostream StrBuf(Buffer); 67a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth StrBuf << "Invalid jump to bit " << BitNo; 68a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth ErrHandler->Fatal(StrBuf.str()); 69a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth} 70a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth 71a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth/// EnterSubBlock - Having read the ENTER_SUBBLOCK abbrevid, enter 72a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth/// the block, and return true if the block has an error. 73a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnothbool NaClBitstreamCursor::EnterSubBlock(unsigned BlockID, unsigned *NumWordsP) { 74a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth const bool IsFixed = true; 75a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth NaClBitcodeSelectorAbbrev 76a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth CodeAbbrev(IsFixed, ReadVBR(naclbitc::CodeLenWidth)); 77a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth BlockScope.push_back(Block(BitStream->getBlockInfo(BlockID), CodeAbbrev)); 78a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth SkipToFourByteBoundary(); 79a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth unsigned NumWords = Read(naclbitc::BlockSizeWidth); 80a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth if (NumWordsP) *NumWordsP = NumWords; 81a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth 82a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth // Validate that this block is sane. 83a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth if (BlockScope.back().getCodeAbbrev().NumBits == 0 || AtEndOfStream()) 84a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth return true; 85a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth 86a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth return false; 87a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth} 88a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth 89a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnothvoid NaClBitstreamCursor::skipAbbreviatedField(const NaClBitCodeAbbrevOp &Op) { 90a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth // Decode the value as we are commanded. 91a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth switch (Op.getEncoding()) { 92a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth case NaClBitCodeAbbrevOp::Literal: 93a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth // No read necessary for literal. 94a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth break; 95a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth case NaClBitCodeAbbrevOp::Fixed: 96a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth (void)Read((unsigned)Op.getValue()); 97a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth break; 98a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth case NaClBitCodeAbbrevOp::VBR: 99a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth (void)ReadVBR64((unsigned)Op.getValue()); 100a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth break; 101a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth case NaClBitCodeAbbrevOp::Array: 102a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth // This can't happen because the abbreviation must be valid. 103a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth llvm_unreachable("Bad array abbreviation encoding!"); 104a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth break; 105a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth case NaClBitCodeAbbrevOp::Char6: 106a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth (void)Read(6); 107a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth break; 108a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth } 109a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth} 110a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth 111a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth/// skipRecord - Read the current record and discard it. 112a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnothvoid NaClBitstreamCursor::skipRecord(unsigned AbbrevID) { 113a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth // Skip unabbreviated records by reading past their entries. 114a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth if (AbbrevID == naclbitc::UNABBREV_RECORD) { 115a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth unsigned Code = ReadVBR(6); 116a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth (void)Code; 117a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth unsigned NumElts = ReadVBR(6); 118a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth for (unsigned i = 0; i != NumElts; ++i) 119a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth (void)ReadVBR64(6); 120a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth SkipToByteBoundaryIfAligned(); 121a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth return; 122a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth } 123a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth 124a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth const NaClBitCodeAbbrev *Abbv = getAbbrev(AbbrevID); 125a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth 126a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth for (unsigned i = 0, e = Abbv->getNumOperandInfos(); i != e; ++i) { 127a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth const NaClBitCodeAbbrevOp &Op = Abbv->getOperandInfo(i); 128a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth switch (Op.getEncoding()) { 129a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth default: 130a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth skipAbbreviatedField(Op); 131a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth break; 132a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth case NaClBitCodeAbbrevOp::Literal: 133a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth break; 134a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth case NaClBitCodeAbbrevOp::Array: { 135a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth // Array case. Read the number of elements as a vbr6. 136a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth unsigned NumElts = ReadVBR(6); 137a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth 138a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth // Get the element encoding. 139a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth const NaClBitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i); 140a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth 141a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth // Read all the elements. 142a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth for (; NumElts; --NumElts) 143a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth skipAbbreviatedField(EltEnc); 144a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth break; 145a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth } 146a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth } 147a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth } 148a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth SkipToByteBoundaryIfAligned(); 149a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth} 150a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth 151a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnothbool NaClBitstreamCursor::readRecordAbbrevField( 152a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth const NaClBitCodeAbbrevOp &Op, uint64_t &Value) { 153a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth switch (Op.getEncoding()) { 154a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth case NaClBitCodeAbbrevOp::Literal: 155a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth Value = Op.getValue(); 156a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth break; 157a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth case NaClBitCodeAbbrevOp::Array: 158a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth // Returns number of elements in the array. 159a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth Value = ReadVBR(6); 160a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth return true; 161a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth case NaClBitCodeAbbrevOp::Fixed: 162a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth Value = Read((unsigned)Op.getValue()); 163a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth break; 164a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth case NaClBitCodeAbbrevOp::VBR: 165a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth Value = ReadVBR64((unsigned)Op.getValue()); 166a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth break; 167a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth case NaClBitCodeAbbrevOp::Char6: 168a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth Value = NaClBitCodeAbbrevOp::DecodeChar6(Read(6)); 169a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth break; 170a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth } 171a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth return false; 172a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth} 173a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth 174a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnothuint64_t NaClBitstreamCursor::readArrayAbbreviatedField( 175a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth const NaClBitCodeAbbrevOp &Op) { 176a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth // Decode the value as we are commanded. 177a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth switch (Op.getEncoding()) { 178a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth case NaClBitCodeAbbrevOp::Literal: 179a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth return Op.getValue(); 180a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth case NaClBitCodeAbbrevOp::Fixed: 181a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth return Read((unsigned)Op.getValue()); 182a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth case NaClBitCodeAbbrevOp::VBR: 183a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth return ReadVBR64((unsigned)Op.getValue()); 184a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth case NaClBitCodeAbbrevOp::Array: 185a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth // This can't happen because the abbreviation must be valid. 186a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth llvm_unreachable("Bad array abbreviation encoding!"); 187a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth break; 188a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth case NaClBitCodeAbbrevOp::Char6: 189a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth return NaClBitCodeAbbrevOp::DecodeChar6(Read(6)); 190a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth } 1911040d86c3c653916dafcac35183482ecfc60a308Karl Schimpf llvm_unreachable("Illegal abbreviation encoding for field!"); 192a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth} 193a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth 194a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnothvoid NaClBitstreamCursor::readArrayAbbrev( 195a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth const NaClBitCodeAbbrevOp &Op, unsigned NumArrayElements, 196a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth SmallVectorImpl<uint64_t> &Vals) { 197a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth for (; NumArrayElements; --NumArrayElements) { 198a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth Vals.push_back(readArrayAbbreviatedField(Op)); 199a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth } 200a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth} 201a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth 202a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnothunsigned NaClBitstreamCursor::readRecord(unsigned AbbrevID, 203a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth SmallVectorImpl<uint64_t> &Vals) { 204a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth if (AbbrevID == naclbitc::UNABBREV_RECORD) { 205a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth unsigned Code = ReadVBR(6); 206a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth unsigned NumElts = ReadVBR(6); 207a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth for (unsigned i = 0; i != NumElts; ++i) 208a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth Vals.push_back(ReadVBR64(6)); 209a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth SkipToByteBoundaryIfAligned(); 210a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth return Code; 211a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth } 212a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth 213a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth // Read code. 214a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth const NaClBitCodeAbbrev *Abbv = getAbbrev(AbbrevID); 215a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth uint64_t Value; 216a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth unsigned Code; 217a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth if (readRecordAbbrevField(Abbv->getOperandInfo(0), Value)) { 218a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth // Array found, use to read all elements. 219a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth if (Value == 0) 220a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth ErrHandler->Fatal("No code found for record!"); 221a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth const NaClBitCodeAbbrevOp &Op = Abbv->getOperandInfo(1); 222a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth Code = readArrayAbbreviatedField(Op); 223a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth readArrayAbbrev(Op, Value - 1, Vals); 224a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth SkipToByteBoundaryIfAligned(); 225a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth return Code; 226a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth } 227a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth Code = Value; 228a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth 229a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth // Read arguments. 230a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth unsigned NumOperands = Abbv->getNumOperandInfos(); 231a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth for (unsigned i = 1; i != NumOperands; ++i) { 232a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth if (readRecordAbbrevField(Abbv->getOperandInfo(i), Value)) { 233a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth ++i; 234a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth readArrayAbbrev(Abbv->getOperandInfo(i), Value, Vals); 235a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth SkipToByteBoundaryIfAligned(); 236a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth return Code; 237a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth } 238a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth Vals.push_back(Value); 239a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth } 240a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth SkipToByteBoundaryIfAligned(); 241a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth return Code; 242a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth} 243a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth 244a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth 245a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim StichnothNaClBitCodeAbbrevOp::Encoding NaClBitstreamCursor:: 246a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim StichnothgetEncoding(uint64_t Value) { 247a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth if (!NaClBitCodeAbbrevOp::isValidEncoding(Value)) { 248a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth std::string Buffer; 249a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth raw_string_ostream StrBuf(Buffer); 250a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth StrBuf << "Invalid abbreviation encoding specified in bitcode file: " 251a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth << Value; 252a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth ErrHandler->Fatal(StrBuf.str()); 253a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth } 254a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth return NaClBitCodeAbbrevOp::Encoding(Value); 255a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth} 256a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth 257a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnothvoid NaClBitstreamCursor::ReadAbbrevRecord(bool IsLocal, 258a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth NaClAbbrevListener *Listener) { 259a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth NaClBitCodeAbbrev *Abbv = BlockScope.back().appendLocalCreate(); 260a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth unsigned NumOpInfo = ReadVBR(5); 261a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth if (Listener) Listener->Values.push_back(NumOpInfo); 262a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth for (unsigned i = 0; i != NumOpInfo; ++i) { 263a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth bool IsLiteral = Read(1) ? true : false; 264a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth if (Listener) Listener->Values.push_back(IsLiteral); 265a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth if (IsLiteral) { 266a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth uint64_t Value = ReadVBR64(8); 267a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth if (Listener) Listener->Values.push_back(Value); 268a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth Abbv->Add(NaClBitCodeAbbrevOp(Value)); 269a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth continue; 270a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth } 271a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth NaClBitCodeAbbrevOp::Encoding E = getEncoding(Read(3)); 272a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth if (Listener) Listener->Values.push_back(E); 273a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth if (NaClBitCodeAbbrevOp::hasValue(E)) { 274a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth unsigned Data = ReadVBR64(5); 275a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth if (Listener) Listener->Values.push_back(Data); 276a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth 277a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth // As a special case, handle fixed(0) (i.e., a fixed field with zero bits) 278a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth // and vbr(0) as a literal zero. This is decoded the same way, and avoids 279a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth // a slow path in Read() to have to handle reading zero bits. 280a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth if ((E == NaClBitCodeAbbrevOp::Fixed || E == NaClBitCodeAbbrevOp::VBR) && 281a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth Data == 0) { 282a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth if (Listener) Listener->Values.push_back(0); 283a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth Abbv->Add(NaClBitCodeAbbrevOp(0)); 284a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth continue; 285a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth } 286a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth if (!NaClBitCodeAbbrevOp::isValid(E, Data)) { 287a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth std::string Buffer; 288a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth raw_string_ostream StrBuf(Buffer); 289a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth StrBuf << "Invalid abbreviation encoding (" 290a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth << NaClBitCodeAbbrevOp::getEncodingName(E) 291a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth << ", " << Data << ")"; 292a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth ErrHandler->Fatal(StrBuf.str()); 293a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth } 294a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth Abbv->Add(NaClBitCodeAbbrevOp(E, Data)); 295a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth } else { 296a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth if (!NaClBitCodeAbbrevOp::isValid(E)) { 297a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth std::string Buffer; 298a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth raw_string_ostream StrBuf(Buffer); 299a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth StrBuf << "Invalid abbreviation encoding (" 300a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth << NaClBitCodeAbbrevOp::getEncodingName(E) << ")"; 301a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth ErrHandler->Fatal(StrBuf.str()); 302a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth } 303a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth Abbv->Add(NaClBitCodeAbbrevOp(E)); 304a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth } 305a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth } 306a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth SkipToByteBoundaryIfAligned(); 307a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth if (!Abbv->isValid()) 308a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth ErrHandler->Fatal("Invalid abbreviation specified in bitcode file"); 309a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth if (Listener) { 310a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth Listener->ProcessAbbreviation(Abbv, IsLocal); 311a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth // Reset record information of the listener. 312a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth Listener->Values.clear(); 313a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth Listener->StartBit = GetCurrentBitNo(); 314a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth } 315a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth} 316a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth 317a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnothvoid NaClBitstreamCursor::SkipAbbrevRecord() { 318a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth unsigned NumOpInfo = ReadVBR(5); 319a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth for (unsigned i = 0; i != NumOpInfo; ++i) { 320a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth bool IsLiteral = Read(1) ? true : false; 321a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth if (IsLiteral) { 322a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth ReadVBR64(8); 323a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth continue; 324a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth } 325a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth NaClBitCodeAbbrevOp::Encoding E = getEncoding(Read(3)); 326a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth if (NaClBitCodeAbbrevOp::hasValue(E)) { 327a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth ReadVBR64(5); 328a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth } 329a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth } 330a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth SkipToByteBoundaryIfAligned(); 331a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth} 332a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth 333a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnothnamespace { 334a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth 335a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnothunsigned ValidBlockIDs[] = { 336a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth naclbitc::BLOCKINFO_BLOCK_ID, 337a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth naclbitc::CONSTANTS_BLOCK_ID, 338a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth naclbitc::FUNCTION_BLOCK_ID, 339a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth naclbitc::GLOBALVAR_BLOCK_ID, 340a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth naclbitc::MODULE_BLOCK_ID, 341a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth naclbitc::TOP_LEVEL_BLOCKID, 342a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth naclbitc::TYPE_BLOCK_ID_NEW, 343a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth naclbitc::VALUE_SYMTAB_BLOCK_ID 344a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth}; 345a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth 346a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth} // end of anonymous namespace 347a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth 348a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim StichnothNaClBitstreamReader::BlockInfoRecordsMap:: 349a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim StichnothBlockInfoRecordsMap() : IsFrozen(false) { 350a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth for (size_t BlockID : ValidBlockIDs) { 351a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth std::unique_ptr<BlockInfo> Info(new BlockInfo(BlockID)); 352a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth KnownInfos.emplace(BlockID, std::move(Info)); 353a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth } 354a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth} 355a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth 356a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim StichnothNaClBitstreamReader::BlockInfo * NaClBitstreamReader::BlockInfoRecordsMap:: 357a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim StichnothgetOrCreateUnknownBlockInfo(unsigned BlockID) { 358a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth std::unique_lock<std::mutex> Lock(UnknownBlockInfoLock); 359a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth while (true) { 360a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth auto Pos = UnknownInfos.find(BlockID); 361a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth if (Pos != UnknownInfos.end()) 362a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth return Pos->second.get(); 363a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth // Install, then let next iteration find. 364a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth std::unique_ptr<BlockInfo> Info(new BlockInfo(BlockID)); 365a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth UnknownInfos.emplace(BlockID, std::move(Info)); 366a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth } 367a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth} 368a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth 369a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim StichnothNaClBitstreamReader::BlockInfoRecordsMap::UpdateLock:: 370a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim StichnothUpdateLock(BlockInfoRecordsMap &BlockInfoRecords) 371a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth : BlockInfoRecords(BlockInfoRecords), 372a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth Lock(BlockInfoRecords.UpdateRecordsLock) {} 373a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth 374a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim StichnothNaClBitstreamReader::BlockInfoRecordsMap::UpdateLock:: 375a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth~UpdateLock() { 376a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth if (BlockInfoRecords.freeze()) 377a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth report_fatal_error("Global abbreviations block frozen while building."); 378a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth} 379a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth 380a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnothbool NaClBitstreamCursor::ReadBlockInfoBlock(NaClAbbrevListener *Listener) { 381a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth // If this is the second read of the block info block, skip it. 382a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth if (BitStream->BlockInfoRecords->isFrozen()) 383a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth return SkipBlock(); 384a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth 385a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth NaClBitstreamReader::BlockInfoRecordsMap::UpdateLock 386a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth Lock(*BitStream->BlockInfoRecords); 387a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth unsigned NumWords; 388a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth if (EnterSubBlock(naclbitc::BLOCKINFO_BLOCK_ID, &NumWords)) return true; 389a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth 390a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth if (Listener) Listener->BeginBlockInfoBlock(NumWords); 391a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth 392a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth NaClBitcodeRecordVector Record; 393a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth Block &CurBlock = BlockScope.back(); 394a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth NaClBitstreamReader::AbbrevList *UpdateAbbrevs = 395a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth &CurBlock.GlobalAbbrevs->getAbbrevs(); 396a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth bool FoundSetBID = false; 397a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth 398a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth // Read records of the BlockInfo block. 399a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth while (1) { 400a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth if (Listener) Listener->StartBit = GetCurrentBitNo(); 401a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth NaClBitstreamEntry Entry = advance(AF_DontAutoprocessAbbrevs, Listener); 402a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth 403a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth switch (Entry.Kind) { 404a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth case llvm::NaClBitstreamEntry::SubBlock: // PNaCl doesn't allow! 405a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth case llvm::NaClBitstreamEntry::Error: 406a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth return true; 407a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth case llvm::NaClBitstreamEntry::EndBlock: 408a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth if (Listener) Listener->EndBlockInfoBlock(); 409a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth return false; 410a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth case llvm::NaClBitstreamEntry::Record: 411a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth // The interesting case. 412a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth break; 413a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth } 414a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth 415a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth // Read abbrev records, associate them with CurBID. 416a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth if (Entry.ID == naclbitc::DEFINE_ABBREV) { 417a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth ReadAbbrevRecord(false, Listener); 418a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth 419a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth // ReadAbbrevRecord installs a local abbreviation. Move it to the 420a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth // appropriate BlockInfo if the corresponding SetBID record has been 421a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth // found. 422a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth if (FoundSetBID) 423a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth CurBlock.moveLocalAbbrevToAbbrevList(UpdateAbbrevs); 424a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth continue; 425a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth } 426a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth 427a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth // Read a record. 428a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth Record.clear(); 429a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth switch (readRecord(Entry.ID, Record)) { 430a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth default: 431a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth // No other records should be found! 432a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth return true; 433a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth case naclbitc::BLOCKINFO_CODE_SETBID: 434a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth if (Record.size() < 1) return true; 435a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth FoundSetBID = true; 436a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth UpdateAbbrevs = 437a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth &BitStream->getBlockInfo((unsigned)Record[0])->getAbbrevs(); 438a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth if (Listener) { 439a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth Listener->Values = Record; 440a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth Listener->SetBID(); 441a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth } 442a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth break; 443a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth } 444a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth } 445a5b16abfebb1d33fa4b4448f1bda1bf02cc0bd58Jim Stichnoth} 446