| 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 |