Chromium Code Reviews| Index: lib/Bitcode/NaCl/TestUtils/NaClBitcodeMunge.cpp |
| diff --git a/lib/Bitcode/NaCl/TestUtils/NaClBitcodeMunge.cpp b/lib/Bitcode/NaCl/TestUtils/NaClBitcodeMunge.cpp |
| index 2d88585ab5c81813db593a15b3473cc1d74627f9..147cee6c1d1f12e8d79767adf71fe45902f24602 100644 |
| --- a/lib/Bitcode/NaCl/TestUtils/NaClBitcodeMunge.cpp |
| +++ b/lib/Bitcode/NaCl/TestUtils/NaClBitcodeMunge.cpp |
| @@ -15,7 +15,6 @@ |
| #include "llvm/Bitcode/NaCl/NaClBitcodeHeader.h" |
| #include "llvm/Bitcode/NaCl/NaClBitcodeParser.h" |
| -#include "llvm/Bitcode/NaCl/NaClBitstreamWriter.h" |
| #include "llvm/Bitcode/NaCl/NaClCompress.h" |
| #include "llvm/Bitcode/NaCl/NaClReaderWriter.h" |
| #include "llvm/IR/LLVMContext.h" |
| @@ -27,9 +26,8 @@ |
| using namespace llvm; |
| -// For debugging. When true, shows each PNaCl record that is |
| -// emitted to the bitcode file. |
| -static bool DebugEmitRecord = false; |
| +// For debugging. When true, shows each test being run. |
| +static bool TraceTestRuns = false; |
| void NaClBitcodeMunger::setupTest( |
| const char *TestName, const uint64_t Munges[], size_t MungesSize, |
| @@ -42,18 +40,18 @@ void NaClBitcodeMunger::setupTest( |
| std::string DumpBuffer; |
| DumpStream = new raw_string_ostream(DumpResults); |
| MungedInputBuffer.clear(); |
| - NaClBitstreamWriter OutStream(MungedInputBuffer); |
| - Writer = &OutStream; |
| - if (DebugEmitRecord) { |
| + if (TraceTestRuns) { |
| errs() << "*** Run test: " << TestName << "\n"; |
| } |
| - WriteBlockID = -1; |
| - SetBID = -1; |
| - |
| MungedBitcode.munge(Munges, MungesSize, RecordTerminator); |
| - writeMungedBitcode(MungedBitcode, AddHeader); |
| + NaClMungedBitcode::WriteResults Results = |
| + MungedBitcode.writeMaybeRepair(MungedInputBuffer, AddHeader, WriteFlags); |
| + if (Results.HasErrors |
| + && (!WriteFlags.TryToRecover || !Results.HasRepairs) |
|
jvoung (off chromium)
2015/05/06 22:08:09
Hmm might be easier to read with a round of Captai
Karl
2015/05/07 20:09:18
Done.
|
| + && (!WriteFlags.SaveBadAbbrevIndices || !Results.SavedBadAbbrevIndices)) |
| + report_fatal_error("Unable to generate bitcode file due to write errors"); |
| // Add null terminator, so that we meet the requirements of the |
| // MemoryBuffer API. |
| @@ -71,7 +69,6 @@ void NaClBitcodeMunger::cleanupTest() { |
| DumpStream->flush(); |
| delete DumpStream; |
| DumpStream = nullptr; |
| - Writer = nullptr; |
| } |
| // Return the next line of input (including eoln), starting from |
| @@ -108,219 +105,6 @@ getLinesWithTextMatch(const std::string &Substring, bool MustBePrefix) const { |
| return Messages; |
| } |
| -void NaClBitcodeMunger::writeMungedBitcode(const NaClMungedBitcode &Bitcode, |
| - bool AddHeader) { |
| - if (AddHeader) { |
| - NaClWriteHeader(*Writer, true); |
| - } |
| - for (const NaClBitcodeAbbrevRecord &Record : Bitcode) { |
| - emitRecord(Record); |
| - } |
| -} |
| - |
| -void NaClBitcodeMunger::emitRecord(const NaClBitcodeAbbrevRecord &Record) { |
| - if (DebugEmitRecord) { |
| - errs() << "Emit " << Record.Abbrev << ": <" << Record.Code; |
| - for (size_t i = 0, e = Record.Values.size(); i < e; ++i) { |
| - errs() << ", " << Record.Values[i]; |
| - } |
| - errs() << ">\n"; |
| - } |
| - |
| - switch (Record.Code) { |
| - case naclbitc::BLK_CODE_ENTER: { |
| - unsigned NumBits = naclbitc::DEFAULT_MAX_ABBREV; |
| - WriteBlockID = -1; |
| - if (Record.Abbrev != naclbitc::ENTER_SUBBLOCK) { |
| - Fatal() << "Enter block record code " << Record.Code |
| - << " uses illegal abbreviation index " << Record.Abbrev << "\n"; |
| - ReportFatalError(); |
| - } |
| - if (Record.Values.size() == 2) { |
| - WriteBlockID = Record.Values[0]; |
| - NumBits = Record.Values[1]; |
| - if (NumBits > 32) { |
| - Fatal() << "Error: Bit size " << NumBits |
| - << " for record should be <= 32\n"; |
| - ReportFatalError(); |
| - } |
| - if (NumBits < 2) { |
| - Fatal() << "Error: Bit size " << NumBits |
| - << " for record should be >= 2\n"; |
| - ReportFatalError(); |
| - } |
| - } else { |
| - Fatal() << "Error: Values for enter record should be of size 2. Found: " |
| - << Record.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() |
| - << "Error: Numbits entry for abbreviations record not 2. Found: " |
| - << NumBits << "\n"; |
| - ReportFatalError(); |
| - } |
| - Writer->EnterBlockInfoBlock(); |
| - } else { |
| - NaClBitcodeSelectorAbbrev CurCodeLen(MaxAbbrev); |
| - Writer->EnterSubblock(WriteBlockID, CurCodeLen); |
| - } |
| - return; |
| - } |
| - case naclbitc::BLK_CODE_EXIT: |
| - if (Record.Abbrev != naclbitc::END_BLOCK) { |
| - Fatal() << "Error: Exit block record code " << Record.Code |
| - << " uses illegal abbreviation index " << Record.Abbrev << "\n"; |
| - ReportFatalError(); |
| - } |
| - if (!Record.Values.empty()) { |
| - Fatal() << "Error: Exit block should not have values. Found: " |
| - << Record.Values.size() << "\n"; |
| - ReportFatalError(); |
| - } |
| - if (!AbbrevIndexLimitStack.empty()) |
| - AbbrevIndexLimitStack.pop_back(); |
| - Writer->ExitBlock(); |
| - return; |
| - case naclbitc::BLK_CODE_DEFINE_ABBREV: { |
| - if (Record.Abbrev != naclbitc::DEFINE_ABBREV) { |
| - Fatal() << "Error: Define abbreviation record code " << Record.Code |
| - << " uses illegal abbreviation index " << Record.Abbrev << "\n"; |
| - ReportFatalError(); |
| - } |
| - NaClBitCodeAbbrev *Abbrev = buildAbbrev(Record); |
| - if (Abbrev == NULL) return; |
| - if (WriteBlockID == naclbitc::BLOCKINFO_BLOCK_ID) { |
| - Writer->EmitBlockInfoAbbrev(SetBID, Abbrev); |
| - } else { |
| - Writer->EmitAbbrev(Abbrev); |
| - } |
| - return; |
| - } |
| - case naclbitc::BLK_CODE_HEADER: |
| - // Note: There is no abbreviation index here. Ignore. |
| - for (uint64_t Value : Record.Values) |
| - Writer->Emit(Value, 8); |
| - return; |
| - default: |
| - if ((Record.Abbrev != naclbitc::UNABBREV_RECORD |
| - && !Writer->isUserRecordAbbreviation(Record.Abbrev))) { |
| - uint64_t BlockAbbrevIndexLimit = 0; |
| - if (!AbbrevIndexLimitStack.empty()) |
| - BlockAbbrevIndexLimit = AbbrevIndexLimitStack.back(); |
| - if (Record.Abbrev > BlockAbbrevIndexLimit) { |
| - Fatal() << "Error: Record code " << Record.Code |
| - << " uses illegal abbreviation index " << Record.Abbrev |
| - << ". 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 " << Record.Code |
| - << " uses illegal abbreviation index " << Record.Abbrev << "\n"; |
| - Writer->EmitCode(Record.Abbrev); |
| - Writer->EmitVBR(Record.Code, 6); |
| - uint32_t NumValues = static_cast<uint32_t>(Record.Values.size()); |
| - Writer->EmitVBR(NumValues, 6); |
| - for (uint32_t i = 0; i < NumValues; ++i) { |
| - Writer->EmitVBR64(Record.Values[i], 6); |
| - } |
| - return; |
| - } |
| - if (Record.Abbrev == naclbitc::UNABBREV_RECORD) |
| - Writer->EmitRecord(Record.Code, Record.Values); |
| - else |
| - Writer->EmitRecord(Record.Code, Record.Values, Record.Abbrev); |
| - return; |
| - } |
| - Fatal() << "emitRecord on unimplemented code" << "\n"; |
| - ReportFatalError(); |
| -} |
| - |
| -NaClBitCodeAbbrev *NaClBitcodeMunger::buildAbbrev( |
| - const NaClBitcodeAbbrevRecord &Record) { |
| - NaClBitCodeAbbrev *Abbrev = new NaClBitCodeAbbrev(); |
| - size_t Index = 0; |
| - if (Record.Values.empty()) { |
| - Fatal() << "Empty abbreviation record not allowed\n"; |
| - ReportFatalError(); |
| - } |
| - size_t NumAbbreviations = Record.Values[Index++]; |
| - size_t NumValues = Record.Values.size(); |
| - if (NumAbbreviations == 0) { |
| - Fatal() << "Abbreviation must contain at least one operator\n"; |
| - ReportFatalError(); |
| - } |
| - for (size_t Count = 0; Count < NumAbbreviations; ++Count) { |
| - if (Index >= NumValues) { |
| - Fatal() << "Malformed abbreviation found. Expects " |
| - << NumAbbreviations << " operands. Found: " |
| - << Count << "\n"; |
| - ReportFatalError(); |
| - } |
| - switch (Record.Values[Index++]) { |
| - case 1: |
| - if (Index >= NumValues) { |
| - Fatal() << "Malformed literal abbreviation.\n"; |
| - ReportFatalError(); |
| - } |
| - Abbrev->Add(NaClBitCodeAbbrevOp(Record.Values[Index++])); |
| - break; |
| - case 0: { |
| - if (Index >= NumValues) { |
| - Fatal() << "Malformed abbreviation found.\n"; |
| - ReportFatalError(); |
| - } |
| - unsigned Kind = Record.Values[Index++]; |
| - switch (Kind) { |
| - case NaClBitCodeAbbrevOp::Fixed: |
| - if (Index >= NumValues) { |
| - Fatal() << "Malformed fixed abbreviation found.\n"; |
| - ReportFatalError(); |
| - } |
| - Abbrev->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Fixed, |
| - Record.Values[Index++])); |
| - break; |
| - case NaClBitCodeAbbrevOp::VBR: |
| - if (Index >= NumValues) { |
| - Fatal() << "Malformed vbr abbreviation found.\n"; |
| - ReportFatalError(); |
| - } |
| - Abbrev->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::VBR, |
| - Record.Values[Index++])); |
| - break; |
| - case NaClBitCodeAbbrevOp::Array: |
| - if (Index >= NumValues) { |
| - Fatal() << "Malformed array abbreviation found.\n"; |
| - ReportFatalError(); |
| - } |
| - Abbrev->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Array)); |
| - break; |
| - case NaClBitCodeAbbrevOp::Char6: |
| - Abbrev->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Char6)); |
| - break; |
| - default: |
| - Fatal() << "Unknown abbreviation kind. Found: " << Kind << "\n"; |
| - ReportFatalError(); |
| - } |
| - break; |
| - } |
| - default: |
| - Fatal() << "Error: Bad literal flag in abbreviation. Found: " |
| - << Record.Values[Index]; |
| - ReportFatalError(); |
| - } |
| - } |
| - return Abbrev; |
| -} |
| - |
| bool NaClObjDumpMunger::runTestWithFlags( |
| const char *Name, const uint64_t Munges[], size_t MungesSize, |
| bool AddHeader, bool NoRecords, bool NoAssembly) { |