| Index: lib/Bitcode/NaCl/TestUtils/NaClBitcodeMunge.cpp
|
| diff --git a/lib/Bitcode/NaCl/TestUtils/NaClBitcodeMunge.cpp b/lib/Bitcode/NaCl/TestUtils/NaClBitcodeMunge.cpp
|
| index 1315e15c070d5799cdd012142d59423a9d319af2..029578234a3ce2b83df4f61fbb9a949c834a5d96 100644
|
| --- a/lib/Bitcode/NaCl/TestUtils/NaClBitcodeMunge.cpp
|
| +++ b/lib/Bitcode/NaCl/TestUtils/NaClBitcodeMunge.cpp
|
| @@ -223,6 +223,8 @@ void NaClBitcodeMunger::emitRecord(unsigned AbbrevIndex,
|
| << Values.size();
|
| ReportFatalError();
|
| }
|
| + uint64_t MaxAbbrev = (static_cast<uint64_t>(1) << NumBits) - 1;
|
| + AbbrevIndexLimitStack.push_back(MaxAbbrev);
|
| if (WriteBlockID == naclbitc::BLOCKINFO_BLOCK_ID) {
|
| if (NumBits != naclbitc::DEFAULT_MAX_ABBREV) {
|
| Fatal()
|
| @@ -232,8 +234,8 @@ void NaClBitcodeMunger::emitRecord(unsigned AbbrevIndex,
|
| }
|
| Writer->EnterBlockInfoBlock();
|
| } else {
|
| - unsigned NumPossibleAbbrevs = (1 << NumBits) - 1;
|
| - Writer->EnterSubblock(WriteBlockID, NumPossibleAbbrevs);
|
| + NaClBitcodeSelectorAbbrev CurCodeLen(MaxAbbrev);
|
| + Writer->EnterSubblock(WriteBlockID, CurCodeLen);
|
| }
|
| return;
|
| }
|
| @@ -248,6 +250,8 @@ void NaClBitcodeMunger::emitRecord(unsigned AbbrevIndex,
|
| << Values.size() << "\n";
|
| ReportFatalError();
|
| }
|
| + if (!AbbrevIndexLimitStack.empty())
|
| + AbbrevIndexLimitStack.pop_back();
|
| Writer->ExitBlock();
|
| return;
|
| case naclbitc::BLK_CODE_DEFINE_ABBREV: {
|
| @@ -276,9 +280,31 @@ void NaClBitcodeMunger::emitRecord(unsigned AbbrevIndex,
|
| default:
|
| if ((AbbrevIndex != naclbitc::UNABBREV_RECORD
|
| && !Writer->isUserRecordAbbreviation(AbbrevIndex))) {
|
| - Fatal() << "Error: Record code " << RecordCode
|
| - << " uses illegal abbreviation index " << AbbrevIndex << "\n";
|
| - ReportFatalError();
|
| + uint64_t BlockAbbrevIndexLimit = 0;
|
| + if (!AbbrevIndexLimitStack.empty())
|
| + BlockAbbrevIndexLimit = AbbrevIndexLimitStack.back();
|
| + if (AbbrevIndex > BlockAbbrevIndexLimit) {
|
| + Fatal() << "Error: Record code " << RecordCode
|
| + << " uses illegal abbreviation index " << AbbrevIndex
|
| + << ". Must not exceed " << BlockAbbrevIndexLimit << "\n";
|
| + ReportFatalError();
|
| + }
|
| + // Note: If this point is reached, the abbreviation is
|
| + // bad. However, that may be the point of munge being
|
| + // applied. Hence, emit the bad abbreviation and the data so
|
| + // that the reader can be tested on this bad input. For
|
| + // simplicity, we output the record data using the default
|
| + // abbreviation pattern.
|
| + errs() << "Warning: Record code " << RecordCode
|
| + << " uses illegal abbreviation index " << AbbrevIndex << "\n";
|
| + Writer->EmitCode(AbbrevIndex);
|
| + Writer->EmitVBR(RecordCode, 6);
|
| + uint32_t NumValues = static_cast<uint32_t>(Values.size());
|
| + Writer->EmitVBR(NumValues, 6);
|
| + for (uint32_t i = 0; i < NumValues; ++i) {
|
| + Writer->EmitVBR64(Values[i], 6);
|
| + }
|
| + return;
|
| }
|
| if (AbbrevIndex == naclbitc::UNABBREV_RECORD)
|
| Writer->EmitRecord(RecordCode, Values);
|
| @@ -370,9 +396,14 @@ bool NaClObjDumpMunger::runTestWithFlags(
|
| const char *Name, const uint64_t Munges[], size_t MungesSize,
|
| bool AddHeader, bool NoRecords, bool NoAssembly) {
|
| setupTest(Name, Munges, MungesSize, AddHeader);
|
| +
|
| + /// If running in death mode, redirect output directly to the
|
| + /// error stream (rather than buffering in DumpStream), so that
|
| + /// output can be seen in gtest death test.
|
| + raw_ostream &Output = RunAsDeathTest ? errs() : *DumpStream;
|
| // TODO(jvoung,kschimpf): Should NaClObjDump take a MemoryBufferRef
|
| // like the parser?
|
| - if (NaClObjDump(MungedInput.get(), *DumpStream, NoRecords, NoAssembly))
|
| + if (NaClObjDump(MungedInput.get(), Output, NoRecords, NoAssembly))
|
| FoundErrors = true;
|
| cleanupTest();
|
| return !FoundErrors;
|
|
|