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 |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
111 | 111 |
112 // Marks that an abbreviation definition is being omitted (i.e. not | 112 // Marks that an abbreviation definition is being omitted (i.e. not |
113 // written) for the current block. | 113 // written) for the current block. |
114 void markCurrentBlockWithOmittedAbbreviations() { | 114 void markCurrentBlockWithOmittedAbbreviations() { |
115 assert(!ScopeStack.empty()); | 115 assert(!ScopeStack.empty()); |
116 ScopeStack.back().OmittedAbbreviations = true; | 116 ScopeStack.back().OmittedAbbreviations = true; |
117 if (getCurWriteBlockID() == naclbitc::BLOCKINFO_BLOCK_ID) | 117 if (getCurWriteBlockID() == naclbitc::BLOCKINFO_BLOCK_ID) |
118 BlocksWithOmittedAbbrevs.insert(SetBID); | 118 BlocksWithOmittedAbbrevs.insert(SetBID); |
119 } | 119 } |
120 | 120 |
| 121 // Returns true if abbreviation operand is legal. If not, logs |
| 122 // a recoverable error message and returns false. Assumes that |
| 123 // the caller does the actual error recovery if applicable. |
| 124 bool verifyAbbrevOp(NaClBitCodeAbbrevOp::Encoding Encoding, uint64_t Value, |
| 125 const NaClBitcodeAbbrevRecord &Record); |
| 126 |
121 // Converts the abbreviation record to the corresponding abbreviation. | 127 // Converts the abbreviation record to the corresponding abbreviation. |
122 // Returns nullptr if unable to build abbreviation. | 128 // Returns nullptr if unable to build abbreviation. |
123 NaClBitCodeAbbrev *buildAbbrev(const NaClBitcodeAbbrevRecord &Record); | 129 NaClBitCodeAbbrev *buildAbbrev(const NaClBitcodeAbbrevRecord &Record); |
124 | 130 |
| 131 // Gets the next value (based on Index) from the record values, |
| 132 // assigns it to ExtractedValue, and returns true. Otherwise, logs a |
| 133 // recoverable error message and returns false. Assumes that the |
| 134 // caller does the actual error recovery if applicable. |
| 135 bool LLVM_ATTRIBUTE_UNUSED_RESULT |
| 136 nextAbbrevValue(uint64_t &ExtractedValue, |
| 137 const NaClBitcodeAbbrevRecord &Record, size_t &Index) { |
| 138 if (Index >= Record.Values.size()) { |
| 139 RecoverableError() |
| 140 << "Malformed abbreviation found: " << Record << "\n"; |
| 141 return false; |
| 142 } |
| 143 ExtractedValue = Record.Values[Index++]; |
| 144 return true; |
| 145 } |
| 146 |
125 // Emits the given record to the bitcode file. Returns true if | 147 // Emits the given record to the bitcode file. Returns true if |
126 // successful. | 148 // successful. |
127 bool LLVM_ATTRIBUTE_UNUSED_RESULT | 149 bool LLVM_ATTRIBUTE_UNUSED_RESULT |
128 emitRecord(NaClBitstreamWriter &Writer, | 150 emitRecord(NaClBitstreamWriter &Writer, |
129 const NaClBitcodeAbbrevRecord &Record); | 151 const NaClBitcodeAbbrevRecord &Record); |
130 | 152 |
131 // Enter the given block | 153 // Enter the given block |
132 bool LLVM_ATTRIBUTE_UNUSED_RESULT | 154 bool LLVM_ATTRIBUTE_UNUSED_RESULT |
133 enterBlock(NaClBitstreamWriter &Writer, uint64_t WriteBlockID, | 155 enterBlock(NaClBitstreamWriter &Writer, uint64_t WriteBlockID, |
134 uint64_t NumBits, const NaClBitcodeAbbrevRecord &Record); | 156 uint64_t NumBits, const NaClBitcodeAbbrevRecord &Record); |
(...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
458 break; | 480 break; |
459 } | 481 } |
460 return true; | 482 return true; |
461 } | 483 } |
462 | 484 |
463 static NaClBitCodeAbbrev *deleteAbbrev(NaClBitCodeAbbrev *Abbrev) { | 485 static NaClBitCodeAbbrev *deleteAbbrev(NaClBitCodeAbbrev *Abbrev) { |
464 Abbrev->dropRef(); | 486 Abbrev->dropRef(); |
465 return nullptr; | 487 return nullptr; |
466 } | 488 } |
467 | 489 |
| 490 bool WriteState::verifyAbbrevOp(NaClBitCodeAbbrevOp::Encoding Encoding, |
| 491 uint64_t Value, |
| 492 const NaClBitcodeAbbrevRecord &Record) { |
| 493 if (NaClBitCodeAbbrevOp::isValid(Encoding, Value)) |
| 494 return true; |
| 495 RecoverableError() << "Invalid abbreviation " |
| 496 << NaClBitCodeAbbrevOp::getEncodingName(Encoding) |
| 497 << "(" << static_cast<int64_t>(Value) |
| 498 << ") in: " << Record << "\n"; |
| 499 return false; |
| 500 } |
| 501 |
468 NaClBitCodeAbbrev *WriteState::buildAbbrev( | 502 NaClBitCodeAbbrev *WriteState::buildAbbrev( |
469 const NaClBitcodeAbbrevRecord &Record) { | 503 const NaClBitcodeAbbrevRecord &Record) { |
470 // Note: Recover by removing abbreviation. | 504 // Note: Recover by removing abbreviation. |
471 NaClBitCodeAbbrev *Abbrev = new NaClBitCodeAbbrev(); | 505 NaClBitCodeAbbrev *Abbrev = new NaClBitCodeAbbrev(); |
472 size_t Index = 0; | 506 size_t Index = 0; |
473 size_t NumValues = Record.Values.size(); | 507 size_t NumAbbrevOps; |
474 if (NumValues == 0) { | 508 if (!nextAbbrevValue(NumAbbrevOps, Record, Index)) |
475 RecoverableError() << "Empty abbreviation record not allowed: " | |
476 << Record << "\n"; | |
477 return deleteAbbrev(Abbrev); | 509 return deleteAbbrev(Abbrev); |
478 } | 510 if (NumAbbrevOps == 0) { |
479 size_t NumAbbreviations = Record.Values[Index++]; | |
480 if (NumAbbreviations == 0) { | |
481 RecoverableError() << "Abbreviation must contain at least one operator: " | 511 RecoverableError() << "Abbreviation must contain at least one operator: " |
482 << Record << "\n"; | 512 << Record << "\n"; |
483 return deleteAbbrev(Abbrev); | 513 return deleteAbbrev(Abbrev); |
484 } | 514 } |
485 for (size_t Count = 0; Count < NumAbbreviations; ++Count) { | 515 for (size_t Count = 0; Count < NumAbbrevOps; ++Count) { |
486 if (Index >= NumValues) { | 516 uint64_t IsLiteral; |
487 RecoverableError() | 517 if (!nextAbbrevValue(IsLiteral, Record, Index)) |
488 << "Malformed abbreviation found. Expects " << NumAbbreviations | |
489 << " operands but found " << Count << ": " << Record << "\n"; | |
490 return deleteAbbrev(Abbrev); | 518 return deleteAbbrev(Abbrev); |
| 519 switch (IsLiteral) { |
| 520 case 1: { |
| 521 uint64_t Value; |
| 522 if (!nextAbbrevValue(Value, Record, Index)) |
| 523 return deleteAbbrev(Abbrev); |
| 524 if (!verifyAbbrevOp(NaClBitCodeAbbrevOp::Literal, Value, Record)) |
| 525 return deleteAbbrev(Abbrev); |
| 526 Abbrev->Add(NaClBitCodeAbbrevOp(Value)); |
| 527 break; |
491 } | 528 } |
492 switch (Record.Values[Index++]) { | 529 case 0: { |
493 case 1: | 530 uint64_t Kind; |
494 if (Index >= NumValues) { | 531 if (!nextAbbrevValue(Kind, Record, Index)) |
495 RecoverableError() << "Malformed literal abbreviation: " | |
496 << Record << "\n"; | |
497 return deleteAbbrev(Abbrev); | 532 return deleteAbbrev(Abbrev); |
| 533 switch (Kind) { |
| 534 case NaClBitCodeAbbrevOp::Fixed: { |
| 535 uint64_t Value; |
| 536 if (!nextAbbrevValue(Value, Record, Index)) |
| 537 return deleteAbbrev(Abbrev); |
| 538 if (!verifyAbbrevOp(NaClBitCodeAbbrevOp::Fixed, Value, Record)) |
| 539 return deleteAbbrev(Abbrev); |
| 540 Abbrev->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Fixed, Value)); |
| 541 break; |
498 } | 542 } |
499 Abbrev->Add(NaClBitCodeAbbrevOp(Record.Values[Index++])); | 543 case NaClBitCodeAbbrevOp::VBR: { |
500 break; | 544 uint64_t Value; |
501 case 0: { | 545 if (!nextAbbrevValue(Value, Record, Index)) |
502 if (Index >= NumValues) { | 546 return deleteAbbrev(Abbrev); |
503 RecoverableError() << "Malformed abbreviation found: " | 547 if (!verifyAbbrevOp(NaClBitCodeAbbrevOp::VBR, Value, Record)) |
504 << Record << "\n"; | 548 return deleteAbbrev(Abbrev); |
505 return deleteAbbrev(Abbrev); | 549 Abbrev->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::VBR, Value)); |
| 550 break; |
506 } | 551 } |
507 unsigned Kind = Record.Values[Index++]; | 552 case NaClBitCodeAbbrevOp::Array: |
508 switch (Kind) { | 553 if (Count + 2 != NumAbbrevOps) { |
509 case NaClBitCodeAbbrevOp::Fixed: | 554 RecoverableError() << "Array abbreviation must be second to last: " |
510 if (Index >= NumValues) { | |
511 RecoverableError() << "Malformed fixed abbreviation found: " | |
512 << Record << "\n"; | 555 << Record << "\n"; |
513 return deleteAbbrev(Abbrev); | 556 return deleteAbbrev(Abbrev); |
514 } | 557 } |
515 Abbrev->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Fixed, | |
516 Record.Values[Index++])); | |
517 break; | |
518 case NaClBitCodeAbbrevOp::VBR: | |
519 if (Index >= NumValues) { | |
520 RecoverableError() << "Malformed vbr abbreviation found: " | |
521 << Record << "\n"; | |
522 return deleteAbbrev(Abbrev); | |
523 } | |
524 Abbrev->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::VBR, | |
525 Record.Values[Index++])); | |
526 break; | |
527 case NaClBitCodeAbbrevOp::Array: | |
528 if (Index >= NumValues) { | |
529 RecoverableError() << "Malformed array abbreviation found: " | |
530 << Record << "\n"; | |
531 return deleteAbbrev(Abbrev); | |
532 } | |
533 Abbrev->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Array)); | 558 Abbrev->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Array)); |
534 break; | 559 break; |
535 case NaClBitCodeAbbrevOp::Char6: | 560 case NaClBitCodeAbbrevOp::Char6: |
536 Abbrev->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Char6)); | 561 Abbrev->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Char6)); |
537 break; | 562 break; |
538 default: | 563 default: |
539 RecoverableError() << "Unknown abbreviation kind " << Kind | 564 RecoverableError() << "Unknown abbreviation kind " << Kind |
540 << ": " << Record << "\n"; | 565 << ": " << Record << "\n"; |
541 return deleteAbbrev(Abbrev); | 566 return deleteAbbrev(Abbrev); |
542 } | 567 } |
543 break; | 568 break; |
544 } | 569 } |
545 default: | 570 default: |
546 RecoverableError() << "Error: Bad abbreviation operand encoding " | 571 RecoverableError() << "Bad abbreviation operand encoding " |
547 << Record.Values[Index-1] << ": " << Record << "\n"; | 572 << Record.Values[Index-1] << ": " << Record << "\n"; |
548 return deleteAbbrev(Abbrev); | 573 return deleteAbbrev(Abbrev); |
549 } | 574 } |
550 } | 575 } |
| 576 if (Index != Record.Values.size()) { |
| 577 RecoverableError() << "Error: Too many values for number of operands (" |
| 578 << NumAbbrevOps << "): " |
| 579 << Record << "\n"; |
| 580 return deleteAbbrev(Abbrev); |
| 581 } |
| 582 if (!Abbrev->isValid()) { |
| 583 raw_ostream &Out = RecoverableError(); |
| 584 Abbrev->Print(Out << "Abbreviation "); |
| 585 Out << " not valid: " << Record << "\n"; |
| 586 return deleteAbbrev(Abbrev); |
| 587 } |
551 return Abbrev; | 588 return Abbrev; |
552 } | 589 } |
553 | 590 |
554 } // end of anonymous namespace. | 591 } // end of anonymous namespace. |
555 | 592 |
556 NaClMungedBitcode::WriteResults NaClMungedBitcode::writeMaybeRepair( | 593 NaClMungedBitcode::WriteResults NaClMungedBitcode::writeMaybeRepair( |
557 SmallVectorImpl<char> &Buffer, bool AddHeader, | 594 SmallVectorImpl<char> &Buffer, bool AddHeader, |
558 const WriteFlags &Flags) const { | 595 const WriteFlags &Flags) const { |
559 NaClBitstreamWriter Writer(Buffer); | 596 NaClBitstreamWriter Writer(Buffer); |
560 WriteState State(Flags); | 597 WriteState State(Flags); |
561 if (AddHeader) { | 598 if (AddHeader) { |
562 NaClWriteHeader(Writer, true); | 599 NaClWriteHeader(Writer, true); |
563 } | 600 } |
564 for (const NaClBitcodeAbbrevRecord &Record : *this) { | 601 for (const NaClBitcodeAbbrevRecord &Record : *this) { |
565 if (!State.emitRecord(Writer, Record)) | 602 if (!State.emitRecord(Writer, Record)) |
566 break; | 603 break; |
567 } | 604 } |
568 bool RecoverSilently = | 605 bool RecoverSilently = |
569 State.Results.NumErrors > 0 && !Flags.getTryToRecover(); | 606 State.Results.NumErrors > 0 && !Flags.getTryToRecover(); |
570 return State.finish(Writer, RecoverSilently); | 607 return State.finish(Writer, RecoverSilently); |
571 } | 608 } |
OLD | NEW |