| OLD | NEW |
| 1 //===- NaClBitcodeMungeWriter.cpp - Write munged bitcode --------*- C++ -*-===// | 1 //===- NaClBitcodeMungeWriter.cpp - Write munged bitcode --------*- C++ -*-===// |
| 2 // | 2 // |
| 3 // The LLVM Compiler Infrastructure | 3 // The LLVM Compiler Infrastructure |
| 4 // | 4 // |
| 5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
| 7 // | 7 // |
| 8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
| 9 // | 9 // |
| 10 // Implements method NaClMungedBitcode.write(), which writes out a munged | 10 // Implements method NaClMungedBitcode.write(), which writes out a munged |
| 11 // list of bitcode records using a bitstream writer. | 11 // list of bitcode records using a bitstream writer. |
| 12 | 12 |
| 13 #include "llvm/Bitcode/NaCl/NaClBitcodeMungeUtils.h" | 13 #include "llvm/Bitcode/NaCl/NaClBitcodeMungeUtils.h" |
| 14 | 14 |
| 15 #include "llvm/Bitcode/NaCl/NaClBitstreamWriter.h" | 15 #include "llvm/Bitcode/NaCl/NaClBitstreamWriter.h" |
| 16 #include "llvm/Bitcode/NaCl/NaClReaderWriter.h" | 16 #include "llvm/Bitcode/NaCl/NaClReaderWriter.h" |
| 17 #include "llvm/Support/raw_ostream.h" | 17 #include "llvm/Support/raw_ostream.h" |
| 18 | 18 |
| 19 #include <set> |
| 20 |
| 19 using namespace llvm; | 21 using namespace llvm; |
| 20 | 22 |
| 21 namespace { | 23 namespace { |
| 22 | 24 |
| 23 // For debugging. When true, shows trace information of emitting | 25 // For debugging. When true, shows trace information of emitting |
| 24 // bitcode. | 26 // bitcode. |
| 25 static bool DebugEmit = false; | 27 static bool DebugEmit = false; |
| 26 | 28 |
| 27 // Description of current block scope | 29 // Description of current block scope |
| 28 struct BlockScope { | 30 struct BlockScope { |
| 29 BlockScope(unsigned CurBlockID, size_t AbbrevIndexLimit) | 31 BlockScope(unsigned CurBlockID, size_t AbbrevIndexLimit) |
| 30 : CurBlockID(CurBlockID), AbbrevIndexLimit(AbbrevIndexLimit) {} | 32 : CurBlockID(CurBlockID), AbbrevIndexLimit(AbbrevIndexLimit), |
| 33 OmittedAbbreviations(false) {} |
| 31 unsigned CurBlockID; | 34 unsigned CurBlockID; |
| 32 // Defines the maximum value for abbreviation indices in block. | 35 // Defines the maximum value for abbreviation indices in block. |
| 33 size_t AbbrevIndexLimit; | 36 size_t AbbrevIndexLimit; |
| 37 // Defines if an abbreviation definition was omitted (i.e. not |
| 38 // written) from this block. Used to turn off writing further |
| 39 // abbreviation definitions for this block. |
| 40 bool OmittedAbbreviations; |
| 34 void print(raw_ostream &Out) const { | 41 void print(raw_ostream &Out) const { |
| 35 Out << "BlockScope(ID=" << CurBlockID << ", AbbrevIndexLimit=" | 42 Out << "BlockScope(ID=" << CurBlockID << ", AbbrevIndexLimit=" |
| 36 << AbbrevIndexLimit << ")"; | 43 << AbbrevIndexLimit << "OmittedAbbreviations=" |
| 44 << OmittedAbbreviations << ")"; |
| 37 } | 45 } |
| 38 }; | 46 }; |
| 39 | 47 |
| 40 inline raw_ostream &operator<<(raw_ostream &Out, const BlockScope &Scope) { | 48 inline raw_ostream &operator<<(raw_ostream &Out, const BlockScope &Scope) { |
| 41 Scope.print(Out); | 49 Scope.print(Out); |
| 42 return Out; | 50 return Out; |
| 43 } | 51 } |
| 44 | 52 |
| 45 // State of bitcode writing. | 53 // State of bitcode writing. |
| 46 struct WriteState { | 54 struct WriteState { |
| 47 // The block ID associated with records not in any block. | 55 // The block ID associated with records not in any block. |
| 48 static const unsigned UnknownWriteBlockID = UINT_MAX; | 56 static const unsigned UnknownWriteBlockID = UINT_MAX; |
| 49 // The SetBID for the blockinfo block. | 57 // The SetBID for the blockinfo block. |
| 50 unsigned SetBID = UnknownWriteBlockID; | 58 unsigned SetBID = UnknownWriteBlockID; |
| 51 // The stack of scopes the writer is in. | 59 // The stack of scopes the writer is in. |
| 52 SmallVector<BlockScope, 3> ScopeStack; | 60 SmallVector<BlockScope, 4> ScopeStack; |
| 53 // The set of write flags to use. | 61 // The set of write flags to use. |
| 54 const NaClMungedBitcode::WriteFlags &Flags; | 62 const NaClMungedBitcode::WriteFlags &Flags; |
| 55 // The results of the attempted write. | 63 // The results of the attempted write. |
| 56 NaClMungedBitcode::WriteResults Results; | 64 NaClMungedBitcode::WriteResults Results; |
| 57 // The minimum number of bits allowed to be specified in a block. | 65 // The minimum number of bits allowed to be specified in a block. |
| 58 const unsigned BlockMinBits; | 66 const unsigned BlockMinBits; |
| 67 // The set of block IDs for which abbreviation definitions have been |
| 68 // omitted in the blockinfo block. |
| 69 std::set<unsigned> BlocksWithOmittedAbbrevs; |
| 59 | 70 |
| 60 WriteState(const NaClMungedBitcode::WriteFlags &Flags) | 71 WriteState(const NaClMungedBitcode::WriteFlags &Flags) |
| 61 : Flags(Flags), | 72 : Flags(Flags), |
| 62 BlockMinBits(NaClBitsNeededForValue(naclbitc::DEFAULT_MAX_ABBREV)) { | 73 BlockMinBits(NaClBitsNeededForValue(naclbitc::DEFAULT_MAX_ABBREV)) { |
| 63 BlockScope Scope(UnknownWriteBlockID, naclbitc::DEFAULT_MAX_ABBREV); | 74 BlockScope Scope(UnknownWriteBlockID, naclbitc::DEFAULT_MAX_ABBREV); |
| 64 ScopeStack.push_back(Scope); | 75 ScopeStack.push_back(Scope); |
| 65 } | 76 } |
| 66 | 77 |
| 67 // Returns stream to print error message to. | 78 // Returns stream to print error message to. |
| 68 raw_ostream &Error(); | 79 raw_ostream &Error(); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 83 unsigned getCurWriteBlockID() const { | 94 unsigned getCurWriteBlockID() const { |
| 84 assert(!ScopeStack.empty()); | 95 assert(!ScopeStack.empty()); |
| 85 return ScopeStack.back().CurBlockID; | 96 return ScopeStack.back().CurBlockID; |
| 86 } | 97 } |
| 87 | 98 |
| 88 unsigned getCurAbbrevIndexLimit() const { | 99 unsigned getCurAbbrevIndexLimit() const { |
| 89 assert(!ScopeStack.empty()); | 100 assert(!ScopeStack.empty()); |
| 90 return ScopeStack.back().AbbrevIndexLimit; | 101 return ScopeStack.back().AbbrevIndexLimit; |
| 91 } | 102 } |
| 92 | 103 |
| 104 // Returns whether any abbreviation definitions were not written to |
| 105 // the bitcode buffer. |
| 106 bool curBlockHasOmittedAbbreviations() const { |
| 107 assert(!ScopeStack.empty()); |
| 108 return ScopeStack.back().OmittedAbbreviations |
| 109 || BlocksWithOmittedAbbrevs.count(getCurWriteBlockID()); |
| 110 } |
| 111 |
| 112 // Marks that an abbreviation definition is being omitted (i.e. not |
| 113 // written) for the current block. |
| 114 void markCurrentBlockWithOmittedAbbreviations() { |
| 115 assert(!ScopeStack.empty()); |
| 116 ScopeStack.back().OmittedAbbreviations = true; |
| 117 if (getCurWriteBlockID() == naclbitc::BLOCKINFO_BLOCK_ID) |
| 118 BlocksWithOmittedAbbrevs.insert(SetBID); |
| 119 } |
| 120 |
| 93 // Converts the abbreviation record to the corresponding abbreviation. | 121 // Converts the abbreviation record to the corresponding abbreviation. |
| 94 // Returns nullptr if unable to build abbreviation. | 122 // Returns nullptr if unable to build abbreviation. |
| 95 NaClBitCodeAbbrev *buildAbbrev(const NaClBitcodeAbbrevRecord &Record); | 123 NaClBitCodeAbbrev *buildAbbrev(const NaClBitcodeAbbrevRecord &Record); |
| 96 | 124 |
| 97 // Emits the given record to the bitcode file. Returns true if | 125 // Emits the given record to the bitcode file. Returns true if |
| 98 // successful. | 126 // successful. |
| 99 bool LLVM_ATTRIBUTE_UNUSED_RESULT | 127 bool LLVM_ATTRIBUTE_UNUSED_RESULT |
| 100 emitRecord(NaClBitstreamWriter &Writer, const NaClBitcodeAbbrevRecord &Record)
; | 128 emitRecord(NaClBitstreamWriter &Writer, |
| 129 const NaClBitcodeAbbrevRecord &Record); |
| 101 | 130 |
| 102 // Enter the given block | 131 // Enter the given block |
| 103 bool LLVM_ATTRIBUTE_UNUSED_RESULT | 132 bool LLVM_ATTRIBUTE_UNUSED_RESULT |
| 104 enterBlock(NaClBitstreamWriter &Writer, uint64_t WriteBlockID, | 133 enterBlock(NaClBitstreamWriter &Writer, uint64_t WriteBlockID, |
| 105 uint64_t NumBits, const NaClBitcodeAbbrevRecord &Record); | 134 uint64_t NumBits, const NaClBitcodeAbbrevRecord &Record); |
| 106 | 135 |
| 107 // Exit current block and return to previous block. Silently recovers | 136 // Exit current block and return to previous block. Silently recovers |
| 108 // if at outermost scope. | 137 // if at outermost scope. |
| 109 bool LLVM_ATTRIBUTE_UNUSED_RESULT | 138 bool LLVM_ATTRIBUTE_UNUSED_RESULT |
| 110 exitBlock(NaClBitstreamWriter &Writer, | 139 exitBlock(NaClBitstreamWriter &Writer, |
| 111 const NaClBitcodeAbbrevRecord *Record = nullptr) { | 140 const NaClBitcodeAbbrevRecord *Record = nullptr) { |
| 112 if (atOutermostScope()) | 141 if (atOutermostScope()) |
| 113 return false; | 142 return false; |
| 114 Writer.ExitBlock(); | 143 Writer.ExitBlock(); |
| 115 ScopeStack.pop_back(); | 144 ScopeStack.pop_back(); |
| 116 if (DebugEmit) | 145 if (DebugEmit) |
| 117 printScopeStack(errs()); | 146 printScopeStack(errs()); |
| 118 return true; | 147 return true; |
| 119 } | 148 } |
| 120 | 149 |
| 150 void WriteRecord(NaClBitstreamWriter &Writer, |
| 151 const NaClBitcodeAbbrevRecord &Record, |
| 152 bool UsesDefaultAbbrev) { |
| 153 if (UsesDefaultAbbrev) |
| 154 Writer.EmitRecord(Record.Code, Record.Values); |
| 155 else |
| 156 Writer.EmitRecord(Record.Code, Record.Values, Record.Abbrev); |
| 157 } |
| 158 |
| 159 // Returns true if the abbreviation index defines an abbreviation |
| 160 // that can be applied to the record. |
| 161 bool LLVM_ATTRIBUTE_UNUSED_RESULT |
| 162 canApplyAbbreviation(NaClBitstreamWriter &Writer, |
| 163 const NaClBitcodeAbbrevRecord &Record); |
| 164 |
| 121 // Completes the write. | 165 // Completes the write. |
| 122 NaClMungedBitcode::WriteResults &finish(NaClBitstreamWriter &Writer, | 166 NaClMungedBitcode::WriteResults &finish(NaClBitstreamWriter &Writer, |
| 123 bool RecoverSilently); | 167 bool RecoverSilently); |
| 124 | 168 |
| 125 void printScopeStack(raw_ostream &Out) { | 169 void printScopeStack(raw_ostream &Out) { |
| 126 Out << "Scope Stack:\n"; | 170 Out << "Scope Stack:\n"; |
| 127 for (auto &Scope : ScopeStack) | 171 for (auto &Scope : ScopeStack) |
| 128 Out << " " << Scope << "\n"; | 172 Out << " " << Scope << "\n"; |
| 129 } | 173 } |
| 130 }; | 174 }; |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 178 return false; | 222 return false; |
| 179 } | 223 } |
| 180 Writer.EnterBlockInfoBlock(); | 224 Writer.EnterBlockInfoBlock(); |
| 181 } else { | 225 } else { |
| 182 NaClBitcodeSelectorAbbrev CurCodeLen(MaxAbbrev); | 226 NaClBitcodeSelectorAbbrev CurCodeLen(MaxAbbrev); |
| 183 Writer.EnterSubblock(WriteBlockID, CurCodeLen); | 227 Writer.EnterSubblock(WriteBlockID, CurCodeLen); |
| 184 } | 228 } |
| 185 return true; | 229 return true; |
| 186 } | 230 } |
| 187 | 231 |
| 232 bool WriteState::canApplyAbbreviation( |
| 233 NaClBitstreamWriter &Writer, const NaClBitcodeAbbrevRecord &Record) { |
| 234 const NaClBitCodeAbbrev *Abbrev = Writer.getAbbreviation(Record.Abbrev); |
| 235 if (Abbrev == nullptr) |
| 236 return false; |
| 237 |
| 238 // Merge record code into values and then match abbreviation. |
| 239 NaClBitcodeValues Values(Record); |
| 240 size_t ValueIndex = 0; |
| 241 size_t ValuesSize = Values.size(); |
| 242 size_t AbbrevIndex = 0; |
| 243 size_t AbbrevSize = Abbrev->getNumOperandInfos(); |
| 244 bool FoundArray = false; |
| 245 while (ValueIndex < ValuesSize && AbbrevIndex < AbbrevSize) { |
| 246 const NaClBitCodeAbbrevOp *Op = &Abbrev->getOperandInfo(AbbrevIndex++); |
| 247 uint64_t Value = Values[ValueIndex++]; |
| 248 if (Op->getEncoding() == NaClBitCodeAbbrevOp::Array) { |
| 249 if (AbbrevIndex + 1 != AbbrevSize) |
| 250 return false; |
| 251 Op = &Abbrev->getOperandInfo(AbbrevIndex); |
| 252 --AbbrevIndex; // i.e. don't advance to next abbreviation op. |
| 253 FoundArray = true; |
| 254 } |
| 255 switch (Op->getEncoding()) { |
| 256 case NaClBitCodeAbbrevOp::Literal: |
| 257 if (Value != Op->getValue()) |
| 258 return false; |
| 259 continue; |
| 260 case NaClBitCodeAbbrevOp::Fixed: |
| 261 if (Value >= (static_cast<uint64_t>(1) |
| 262 << NaClBitstreamWriter::MaxEmitNumBits) |
| 263 || NaClBitsNeededForValue(Value) > Op->getValue()) |
| 264 return false; |
| 265 continue; |
| 266 case NaClBitCodeAbbrevOp::VBR: |
| 267 if (Op->getValue() < 2) |
| 268 return false; |
| 269 continue; |
| 270 case NaClBitCodeAbbrevOp::Array: |
| 271 llvm_unreachable("Array(Array) abbreviation is not legal!"); |
| 272 case NaClBitCodeAbbrevOp::Char6: |
| 273 if (!Op->isChar6(Value)) |
| 274 return false; |
| 275 continue; |
| 276 } |
| 277 } |
| 278 return ValueIndex == ValuesSize && (FoundArray || AbbrevIndex == AbbrevSize); |
| 279 } |
| 280 |
| 188 NaClMungedBitcode::WriteResults &WriteState::finish( | 281 NaClMungedBitcode::WriteResults &WriteState::finish( |
| 189 NaClBitstreamWriter &Writer, bool RecoverSilently) { | 282 NaClBitstreamWriter &Writer, bool RecoverSilently) { |
| 190 // Be sure blocks are balanced. | 283 // Be sure blocks are balanced. |
| 191 while (!atOutermostScope()) { | 284 while (!atOutermostScope()) { |
| 192 if (!RecoverSilently) | 285 if (!RecoverSilently) |
| 193 RecoverableError() << "Missing close block.\n"; | 286 RecoverableError() << "Missing close block.\n"; |
| 194 if (!exitBlock(Writer)) { | 287 if (!exitBlock(Writer)) { |
| 195 Error() << "Failed to add missing close block at end of file.\n"; | 288 Error() << "Failed to add missing close block at end of file.\n"; |
| 196 break; | 289 break; |
| 197 } | 290 } |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 264 return false; | 357 return false; |
| 265 } | 358 } |
| 266 if (!exitBlock(Writer)) { | 359 if (!exitBlock(Writer)) { |
| 267 Error() << "Failed to write exit block, can't continue: " | 360 Error() << "Failed to write exit block, can't continue: " |
| 268 << Record << "\n"; | 361 << Record << "\n"; |
| 269 return false; | 362 return false; |
| 270 } | 363 } |
| 271 break; | 364 break; |
| 272 } | 365 } |
| 273 case naclbitc::BLK_CODE_DEFINE_ABBREV: { | 366 case naclbitc::BLK_CODE_DEFINE_ABBREV: { |
| 367 if (curBlockHasOmittedAbbreviations()) { |
| 368 // If reached, a previous abbreviation for the block was omitted. Can't |
| 369 // generate more abbreviations without having to fix abbreviation indices. |
| 370 RecoverableError() << "Ignoring abbreviation: " << Record << "\n"; |
| 371 return Flags.getTryToRecover(); |
| 372 } |
| 274 if (Record.Abbrev != naclbitc::DEFINE_ABBREV) { | 373 if (Record.Abbrev != naclbitc::DEFINE_ABBREV) { |
| 275 RecoverableError() | 374 RecoverableError() |
| 276 << "Uses illegal abbreviation index in define abbreviation record: " | 375 << "Uses illegal abbreviation index in define abbreviation record: " |
| 277 << Record << "\n"; | 376 << Record << "\n"; |
| 278 if (!Flags.getTryToRecover()) | 377 if (!Flags.getTryToRecover()) |
| 279 return false; | 378 return false; |
| 280 } | 379 } |
| 281 if (getCurWriteBlockID() != naclbitc::BLOCKINFO_BLOCK_ID | 380 NaClBitCodeAbbrev *Abbrev = buildAbbrev(Record); |
| 282 && Writer.getMaxCurAbbrevIndex() >= getCurAbbrevIndexLimit()) { | 381 if (Abbrev == nullptr) { |
| 283 RecoverableError() << "Exceeds abbreviation index limit of " | 382 markCurrentBlockWithOmittedAbbreviations(); |
| 284 << getCurAbbrevIndexLimit() << ": " << Record << "\n"; | |
| 285 // Recover by not writing. | |
| 286 return Flags.getTryToRecover(); | 383 return Flags.getTryToRecover(); |
| 287 } | 384 } |
| 288 NaClBitCodeAbbrev *Abbrev = buildAbbrev(Record); | |
| 289 if (Abbrev == NULL) | |
| 290 return Flags.getTryToRecover(); | |
| 291 if (getCurWriteBlockID() == naclbitc::BLOCKINFO_BLOCK_ID) { | 385 if (getCurWriteBlockID() == naclbitc::BLOCKINFO_BLOCK_ID) { |
| 292 Writer.EmitBlockInfoAbbrev(SetBID, Abbrev); | 386 Writer.EmitBlockInfoAbbrev(SetBID, Abbrev); |
| 293 } else { | 387 } else { |
| 294 Writer.EmitAbbrev(Abbrev); | 388 Writer.EmitAbbrev(Abbrev); |
| 295 } | 389 } |
| 296 break; | 390 break; |
| 297 } | 391 } |
| 298 case naclbitc::BLK_CODE_HEADER: | 392 case naclbitc::BLK_CODE_HEADER: |
| 299 // Note: There is no abbreviation index here. Ignore. | 393 // Note: There is no abbreviation index here. Ignore. |
| 300 for (uint64_t Value : Record.Values) | 394 for (uint64_t Value : Record.Values) |
| 301 Writer.Emit(Value, 8); | 395 Writer.Emit(Value, 8); |
| 302 break; | 396 break; |
| 303 default: | 397 default: |
| 304 bool UsesDefaultAbbrev = Record.Abbrev == naclbitc::UNABBREV_RECORD; | 398 bool UsesDefaultAbbrev = Record.Abbrev == naclbitc::UNABBREV_RECORD; |
| 305 if (atOutermostScope()) { | 399 if (atOutermostScope()) { |
| 306 RecoverableError() << "Record outside block: " << Record << "\n"; | 400 RecoverableError() << "Record outside block: " << Record << "\n"; |
| 307 if (!Flags.getTryToRecover()) | 401 if (!Flags.getTryToRecover()) |
| 308 return false; | 402 return false; |
| 309 // Create a dummy block to hold record. | 403 // Create a dummy block to hold record. |
| 310 if (!enterBlock(Writer, UnknownWriteBlockID, | 404 if (!enterBlock(Writer, UnknownWriteBlockID, |
| 311 naclbitc::DEFAULT_MAX_ABBREV, Record)) { | 405 naclbitc::DEFAULT_MAX_ABBREV, Record)) { |
| 312 Error() << "Failed to recover from record outside block\n"; | 406 Error() << "Failed to recover from record outside block\n"; |
| 313 return false; | 407 return false; |
| 314 } | 408 } |
| 315 UsesDefaultAbbrev = true; | 409 UsesDefaultAbbrev = true; |
| 316 } | 410 } |
| 317 if (!UsesDefaultAbbrev | 411 if (!UsesDefaultAbbrev && !canApplyAbbreviation(Writer, Record)) { |
| 318 && !Writer.isUserRecordAbbreviation(Record.Abbrev)) { | 412 if (Writer.getAbbreviation(Record.Abbrev) != nullptr) { |
| 319 // Illegal abbreviation index found. | 413 RecoverableError() << "Abbreviation doesn't apply to record: " |
| 414 << Record << "\n"; |
| 415 UsesDefaultAbbrev = true; |
| 416 if (!Flags.getTryToRecover()) |
| 417 return false; |
| 418 WriteRecord(Writer, Record, UsesDefaultAbbrev); |
| 419 return true; |
| 420 } |
| 320 if (Flags.getWriteBadAbbrevIndex()) { | 421 if (Flags.getWriteBadAbbrevIndex()) { |
| 422 // The abbreviation is not understood by the bitcode writer, |
| 423 // and the flag value implies that we should still write it |
| 424 // out so that unit tests for this error condition can be |
| 425 // applied. |
| 321 Error() << "Uses illegal abbreviation index: " << Record << "\n"; | 426 Error() << "Uses illegal abbreviation index: " << Record << "\n"; |
| 322 // Generate bad abbreviation index so that the bitcode reader | 427 // Generate bad abbreviation index so that the bitcode reader |
| 323 // can be tested, and then quit. | 428 // can be tested, and then quit. |
| 324 Results.WroteBadAbbrevIndex = true; | 429 Results.WroteBadAbbrevIndex = true; |
| 325 Writer.EmitCode(Record.Abbrev); | 430 Writer.EmitCode(Record.Abbrev); |
| 326 bool RecoverSilently = true; | 431 bool RecoverSilently = true; |
| 327 finish(Writer, RecoverSilently); | 432 finish(Writer, RecoverSilently); |
| 328 return false; | 433 return false; |
| 329 } | 434 } |
| 330 RecoverableError() << "Uses illegal abbreviation index: " | 435 RecoverableError() << "Uses illegal abbreviation index: " |
| 331 << Record << "\n"; | 436 << Record << "\n"; |
| 437 UsesDefaultAbbrev = true; |
| 332 if (!Flags.getTryToRecover()) | 438 if (!Flags.getTryToRecover()) |
| 333 return false; | 439 return false; |
| 334 UsesDefaultAbbrev = true; | 440 WriteRecord(Writer, Record, UsesDefaultAbbrev); |
| 441 return true; |
| 335 } | 442 } |
| 336 if (getCurWriteBlockID() == naclbitc::BLOCKINFO_BLOCK_ID | 443 if (getCurWriteBlockID() == naclbitc::BLOCKINFO_BLOCK_ID |
| 337 && Record.Code == naclbitc::BLOCKINFO_CODE_SETBID) { | 444 && Record.Code == naclbitc::BLOCKINFO_CODE_SETBID) { |
| 338 // Note: SetBID records are handled by Writer->EmitBlockInfoAbbrev, | 445 // Note: SetBID records are handled by Writer->EmitBlockInfoAbbrev, |
| 339 // based on the SetBID value. Don't bother to generate SetBID record here. | 446 // based on the SetBID value. Don't bother to generate SetBID record here. |
| 340 // Rather just set SetBID and let call to Writer->EmitBlockInfoAbbrev | 447 // Rather just set SetBID and let call to Writer->EmitBlockInfoAbbrev |
| 341 // generate the SetBID record. | 448 // generate the SetBID record. |
| 342 if (NumValues != 1) { | 449 if (NumValues != 1) { |
| 343 Error() << "SetBID record expects 1 value but found " | 450 Error() << "SetBID record expects 1 value but found " |
| 344 << NumValues << ": " << Record << "\n"; | 451 << NumValues << ": " << Record << "\n"; |
| 345 return false; | 452 return false; |
| 346 } | 453 } |
| 347 SetBID = Record.Values[0]; | 454 SetBID = Record.Values[0]; |
| 348 return true; | 455 return true; |
| 349 } | 456 } |
| 350 if (UsesDefaultAbbrev) | 457 WriteRecord(Writer, Record, UsesDefaultAbbrev); |
| 351 Writer.EmitRecord(Record.Code, Record.Values); | 458 break; |
| 352 else | |
| 353 Writer.EmitRecord(Record.Code, Record.Values, Record.Abbrev); | |
| 354 } | 459 } |
| 355 return true; | 460 return true; |
| 356 } | 461 } |
| 357 | 462 |
| 358 static NaClBitCodeAbbrev *deleteAbbrev(NaClBitCodeAbbrev *Abbrev) { | 463 static NaClBitCodeAbbrev *deleteAbbrev(NaClBitCodeAbbrev *Abbrev) { |
| 359 Abbrev->dropRef(); | 464 Abbrev->dropRef(); |
| 360 return nullptr; | 465 return nullptr; |
| 361 } | 466 } |
| 362 | 467 |
| 363 NaClBitCodeAbbrev *WriteState::buildAbbrev( | 468 NaClBitCodeAbbrev *WriteState::buildAbbrev( |
| (...skipping 10 matching lines...) Expand all Loading... |
| 374 size_t NumAbbreviations = Record.Values[Index++]; | 479 size_t NumAbbreviations = Record.Values[Index++]; |
| 375 if (NumAbbreviations == 0) { | 480 if (NumAbbreviations == 0) { |
| 376 RecoverableError() << "Abbreviation must contain at least one operator: " | 481 RecoverableError() << "Abbreviation must contain at least one operator: " |
| 377 << Record << "\n"; | 482 << Record << "\n"; |
| 378 return deleteAbbrev(Abbrev); | 483 return deleteAbbrev(Abbrev); |
| 379 } | 484 } |
| 380 for (size_t Count = 0; Count < NumAbbreviations; ++Count) { | 485 for (size_t Count = 0; Count < NumAbbreviations; ++Count) { |
| 381 if (Index >= NumValues) { | 486 if (Index >= NumValues) { |
| 382 RecoverableError() | 487 RecoverableError() |
| 383 << "Malformed abbreviation found. Expects " << NumAbbreviations | 488 << "Malformed abbreviation found. Expects " << NumAbbreviations |
| 384 << " operands but ound " << Count << ": " << Record << "\n"; | 489 << " operands but found " << Count << ": " << Record << "\n"; |
| 385 return deleteAbbrev(Abbrev); | 490 return deleteAbbrev(Abbrev); |
| 386 } | 491 } |
| 387 switch (Record.Values[Index++]) { | 492 switch (Record.Values[Index++]) { |
| 388 case 1: | 493 case 1: |
| 389 if (Index >= NumValues) { | 494 if (Index >= NumValues) { |
| 390 RecoverableError() << "Malformed literal abbreviation: " | 495 RecoverableError() << "Malformed literal abbreviation: " |
| 391 << Record << "\n"; | 496 << Record << "\n"; |
| 392 return deleteAbbrev(Abbrev); | 497 return deleteAbbrev(Abbrev); |
| 393 } | 498 } |
| 394 Abbrev->Add(NaClBitCodeAbbrevOp(Record.Values[Index++])); | 499 Abbrev->Add(NaClBitCodeAbbrevOp(Record.Values[Index++])); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 431 Abbrev->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Char6)); | 536 Abbrev->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Char6)); |
| 432 break; | 537 break; |
| 433 default: | 538 default: |
| 434 RecoverableError() << "Unknown abbreviation kind " << Kind | 539 RecoverableError() << "Unknown abbreviation kind " << Kind |
| 435 << ": " << Record << "\n"; | 540 << ": " << Record << "\n"; |
| 436 return deleteAbbrev(Abbrev); | 541 return deleteAbbrev(Abbrev); |
| 437 } | 542 } |
| 438 break; | 543 break; |
| 439 } | 544 } |
| 440 default: | 545 default: |
| 441 RecoverableError() << "Error: Bad literal flag " << Record.Values[Index] | 546 RecoverableError() << "Error: Bad abbreviation operand encoding " |
| 442 << ": " << Record << "\n"; | 547 << Record.Values[Index-1] << ": " << Record << "\n"; |
| 443 return deleteAbbrev(Abbrev); | 548 return deleteAbbrev(Abbrev); |
| 444 } | 549 } |
| 445 } | 550 } |
| 446 return Abbrev; | 551 return Abbrev; |
| 447 } | 552 } |
| 448 | 553 |
| 449 } // end of anonymous namespace. | 554 } // end of anonymous namespace. |
| 450 | 555 |
| 451 NaClMungedBitcode::WriteResults NaClMungedBitcode::writeMaybeRepair( | 556 NaClMungedBitcode::WriteResults NaClMungedBitcode::writeMaybeRepair( |
| 452 SmallVectorImpl<char> &Buffer, bool AddHeader, | 557 SmallVectorImpl<char> &Buffer, bool AddHeader, |
| 453 const WriteFlags &Flags) const { | 558 const WriteFlags &Flags) const { |
| 454 NaClBitstreamWriter Writer(Buffer); | 559 NaClBitstreamWriter Writer(Buffer); |
| 455 WriteState State(Flags); | 560 WriteState State(Flags); |
| 456 if (AddHeader) { | 561 if (AddHeader) { |
| 457 NaClWriteHeader(Writer, true); | 562 NaClWriteHeader(Writer, true); |
| 458 } | 563 } |
| 459 for (const NaClBitcodeAbbrevRecord &Record : *this) { | 564 for (const NaClBitcodeAbbrevRecord &Record : *this) { |
| 460 if (!State.emitRecord(Writer, Record)) | 565 if (!State.emitRecord(Writer, Record)) |
| 461 break; | 566 break; |
| 462 } | 567 } |
| 463 bool RecoverSilently = | 568 bool RecoverSilently = |
| 464 State.Results.NumErrors > 0 && !Flags.getTryToRecover(); | 569 State.Results.NumErrors > 0 && !Flags.getTryToRecover(); |
| 465 return State.finish(Writer, RecoverSilently); | 570 return State.finish(Writer, RecoverSilently); |
| 466 } | 571 } |
| OLD | NEW |