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