Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(329)

Side by Side Diff: lib/Bitcode/NaCl/TestUtils/NaClBitcodeMungeWriter.cpp

Issue 1157273004: Check for invalid abbreviation operators in munged bitcode. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-llvm.git@master
Patch Set: Fix nits. Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | unittests/Bitcode/NaClMungeWriteErrorTests.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | unittests/Bitcode/NaClMungeWriteErrorTests.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698