Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 //===--- Bitcode/NaCl/TestUtils/NaClBitcodeMunge.cpp - Bitcode Munger -----===// | 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 // Bitcode writer/munger implementation for testing. | 10 // Implements method NaClMungedBitcode.write(), which writes out a munged |
| 11 // | 11 // list of bitcode records using a bitstream writer. |
| 12 //===----------------------------------------------------------------------===// | |
| 13 | 12 |
| 14 #include "llvm/Bitcode/NaCl/NaClBitcodeMunge.h" | 13 #include "llvm/Bitcode/NaCl/NaClBitcodeMungeUtils.h" |
| 15 | 14 |
| 16 #include "llvm/Bitcode/NaCl/NaClBitcodeHeader.h" | |
| 17 #include "llvm/Bitcode/NaCl/NaClBitcodeParser.h" | |
| 18 #include "llvm/Bitcode/NaCl/NaClBitstreamWriter.h" | 15 #include "llvm/Bitcode/NaCl/NaClBitstreamWriter.h" |
| 19 #include "llvm/Bitcode/NaCl/NaClCompress.h" | |
| 20 #include "llvm/Bitcode/NaCl/NaClReaderWriter.h" | 16 #include "llvm/Bitcode/NaCl/NaClReaderWriter.h" |
| 21 #include "llvm/IR/LLVMContext.h" | |
| 22 #include "llvm/IR/Module.h" | |
| 23 #include "llvm/Support/ErrorHandling.h" | |
| 24 #include "llvm/Support/MemoryBuffer.h" | |
| 25 | |
| 26 #include <memory> | |
| 27 | 17 |
| 28 using namespace llvm; | 18 using namespace llvm; |
| 29 | 19 |
| 20 namespace { | |
| 21 | |
| 30 // For debugging. When true, shows each PNaCl record that is | 22 // For debugging. When true, shows each PNaCl record that is |
| 31 // emitted to the bitcode file. | 23 // emitted to the bitcode file. |
| 32 static bool DebugEmitRecord = false; | 24 static bool DebugEmitRecord = false; |
| 33 | 25 |
| 34 void NaClBitcodeMunger::setupTest( | 26 // State of bitcode writing. |
| 35 const char *TestName, const uint64_t Munges[], size_t MungesSize, | 27 struct WriteState { |
| 36 bool AddHeader) { | 28 // The block ID associated with the block being written. |
| 37 assert(DumpStream == nullptr && "Test run with DumpStream already defined"); | 29 int WriteBlockID = -1; |
| 38 assert(MungedInput.get() == nullptr | 30 // The SetBID for the blockinfo block. |
| 39 && "Test run with MungedInput already defined"); | 31 int SetBID = -1; |
| 40 FoundErrors = false; | 32 // The stack of maximum abbreviation indices allowed by block enter record. |
| 41 DumpResults.clear(); // Throw away any previous results. | 33 SmallVector<uint64_t, 3> AbbrevIndexLimitStack; |
| 42 std::string DumpBuffer; | 34 // The buffer to hold the generated fatal message. |
| 43 DumpStream = new raw_string_ostream(DumpResults); | 35 std::string FatalBuffer; |
| 44 MungedInputBuffer.clear(); | 36 // The stream to write the fatal message to. |
| 45 NaClBitstreamWriter OutStream(MungedInputBuffer); | 37 raw_string_ostream FatalStream; |
| 46 Writer = &OutStream; | |
| 47 | 38 |
| 48 if (DebugEmitRecord) { | 39 WriteState() : FatalBuffer(), FatalStream(FatalBuffer) {} |
| 49 errs() << "*** Run test: " << TestName << "\n"; | 40 |
| 41 // Returns stream to print fatal error message to. | |
| 42 // Note: Once the fatal error message has been dumped to the stream, | |
| 43 // one must call ReportFatalError to display the error and terminate | |
| 44 // execution. | |
| 45 raw_ostream &Fatal() { | |
| 46 return FatalStream << "Fatal: "; | |
| 50 } | 47 } |
| 51 | 48 |
| 52 WriteBlockID = -1; | 49 // Displays the fatal error message and exits the program. |
| 53 SetBID = -1; | 50 void ReportFatalError() { |
| 51 report_fatal_error(FatalStream.str()); | |
| 52 } | |
| 54 | 53 |
| 55 MungedBitcode.munge(Munges, MungesSize, RecordTerminator); | 54 // Converts the abbreviation record to the corresponding abbreviation. |
| 56 writeMungedBitcode(MungedBitcode, AddHeader); | 55 NaClBitCodeAbbrev *buildAbbrev(const NaClBitcodeAbbrevRecord &Record); |
| 57 | 56 |
| 58 // Add null terminator, so that we meet the requirements of the | 57 // Emits the given record to the bitcode file. |
| 59 // MemoryBuffer API. | 58 void emitRecord(NaClBitstreamWriter &Writer, |
| 60 MungedInputBuffer.push_back('\0'); | 59 const NaClBitcodeAbbrevRecord &Record, |
| 60 bool RecoverOnBadAbbrevId); | |
| 61 }; | |
| 61 | 62 |
| 62 MungedInput = MemoryBuffer::getMemBuffer( | 63 void WriteState::emitRecord(NaClBitstreamWriter &Writer, |
| 63 StringRef(MungedInputBuffer.data(), MungedInputBuffer.size()-1), | 64 const NaClBitcodeAbbrevRecord &Record, |
| 64 TestName); | 65 bool RecoverOnBadAbbrevId) { |
| 65 } | 66 size_t NumValues = Record.Values.size(); |
| 66 | |
| 67 void NaClBitcodeMunger::cleanupTest() { | |
| 68 MungedBitcode.removeEdits(); | |
| 69 MungedInput.reset(); | |
| 70 assert(DumpStream && "Dump stream removed before cleanup!"); | |
| 71 DumpStream->flush(); | |
| 72 delete DumpStream; | |
| 73 DumpStream = nullptr; | |
| 74 Writer = nullptr; | |
| 75 } | |
| 76 | |
| 77 // Return the next line of input (including eoln), starting from | |
| 78 // Pos. Then increment Pos past the end of that line. | |
| 79 static std::string getLine(const std::string &Input, size_t &Pos) { | |
| 80 std::string Line; | |
| 81 if (Pos >= Input.size()) { | |
| 82 Pos = std::string::npos; | |
| 83 return Line; | |
| 84 } | |
| 85 size_t Eoln = Input.find_first_of("\n", Pos); | |
| 86 if (Eoln != std::string::npos) { | |
| 87 for (size_t i = Pos; i <= Eoln; ++i) | |
| 88 Line.push_back(Input[i]); | |
| 89 Pos = Eoln + 1; | |
| 90 return Line; | |
| 91 } | |
| 92 Pos = std::string::npos; | |
| 93 return Input.substr(Pos); | |
| 94 } | |
| 95 | |
| 96 std::string NaClBitcodeMunger:: | |
| 97 getLinesWithTextMatch(const std::string &Substring, bool MustBePrefix) const { | |
| 98 std::string Messages; | |
| 99 size_t LastLinePos = 0; | |
| 100 while (1) { | |
| 101 std::string Line = getLine(DumpResults, LastLinePos); | |
| 102 if (LastLinePos == std::string::npos) break; | |
| 103 size_t Pos = Line.find(Substring); | |
| 104 if (Pos != std::string::npos && (!MustBePrefix || Pos == 0)) { | |
| 105 Messages.append(Line); | |
| 106 } | |
| 107 } | |
| 108 return Messages; | |
| 109 } | |
| 110 | |
| 111 void NaClBitcodeMunger::writeMungedBitcode(const NaClMungedBitcode &Bitcode, | |
| 112 bool AddHeader) { | |
| 113 if (AddHeader) { | |
| 114 NaClWriteHeader(*Writer, true); | |
| 115 } | |
| 116 for (const NaClBitcodeAbbrevRecord &Record : Bitcode) { | |
| 117 emitRecord(Record); | |
| 118 } | |
| 119 } | |
| 120 | |
| 121 void NaClBitcodeMunger::emitRecord(const NaClBitcodeAbbrevRecord &Record) { | |
| 122 if (DebugEmitRecord) { | 67 if (DebugEmitRecord) { |
| 123 errs() << "Emit " << Record.Abbrev << ": <" << Record.Code; | 68 errs() << "Emit " << Record.Abbrev << ": <" << Record.Code; |
| 124 for (size_t i = 0, e = Record.Values.size(); i < e; ++i) { | 69 for (size_t i = 0; i < NumValues; ++i) { |
| 125 errs() << ", " << Record.Values[i]; | 70 errs() << ", " << Record.Values[i]; |
| 126 } | 71 } |
| 127 errs() << ">\n"; | 72 errs() << ">\n"; |
| 128 } | 73 } |
| 129 | 74 |
| 130 switch (Record.Code) { | 75 switch (Record.Code) { |
| 131 case naclbitc::BLK_CODE_ENTER: { | 76 case naclbitc::BLK_CODE_ENTER: { |
| 132 unsigned NumBits = naclbitc::DEFAULT_MAX_ABBREV; | 77 unsigned NumBits = naclbitc::DEFAULT_MAX_ABBREV; |
| 133 WriteBlockID = -1; | 78 WriteBlockID = -1; |
| 134 if (Record.Abbrev != naclbitc::ENTER_SUBBLOCK) { | 79 if (Record.Abbrev != naclbitc::ENTER_SUBBLOCK) { |
| 135 Fatal() << "Enter block record code " << Record.Code | 80 Fatal() << "Enter block record code " << Record.Code |
| 136 << " uses illegal abbreviation index " << Record.Abbrev << "\n"; | 81 << " uses illegal abbreviation index " << Record.Abbrev << "\n"; |
| 137 ReportFatalError(); | 82 ReportFatalError(); |
| 138 } | 83 } |
| 139 if (Record.Values.size() == 2) { | 84 if (NumValues == 2) { |
| 140 WriteBlockID = Record.Values[0]; | 85 WriteBlockID = Record.Values[0]; |
| 141 NumBits = Record.Values[1]; | 86 NumBits = Record.Values[1]; |
| 142 if (NumBits > 32) { | 87 if (NumBits > 32) { |
| 143 Fatal() << "Error: Bit size " << NumBits | 88 Fatal() << "Error: Bit size " << NumBits |
| 144 << " for record should be <= 32\n"; | 89 << " for record should be <= 32\n"; |
| 145 ReportFatalError(); | 90 ReportFatalError(); |
| 146 } | 91 } |
| 147 if (NumBits < 2) { | 92 if (NumBits < 2) { |
| 148 Fatal() << "Error: Bit size " << NumBits | 93 Fatal() << "Error: Bit size " << NumBits |
| 149 << " for record should be >= 2\n"; | 94 << " for record should be >= 2\n"; |
| 150 ReportFatalError(); | 95 ReportFatalError(); |
| 151 } | 96 } |
| 152 } else { | 97 } else { |
| 153 Fatal() << "Error: Values for enter record should be of size 2. Found: " | 98 Fatal() << "Error: Values for enter record should be of size 2. Found: " |
| 154 << Record.Values.size(); | 99 << NumValues; |
| 155 ReportFatalError(); | 100 ReportFatalError(); |
| 156 } | 101 } |
| 157 uint64_t MaxAbbrev = (static_cast<uint64_t>(1) << NumBits) - 1; | 102 uint64_t MaxAbbrev = (static_cast<uint64_t>(1) << NumBits) - 1; |
| 158 AbbrevIndexLimitStack.push_back(MaxAbbrev); | 103 AbbrevIndexLimitStack.push_back(MaxAbbrev); |
| 159 if (WriteBlockID == naclbitc::BLOCKINFO_BLOCK_ID) { | 104 if (WriteBlockID == naclbitc::BLOCKINFO_BLOCK_ID) { |
| 160 if (NumBits != naclbitc::DEFAULT_MAX_ABBREV) { | 105 unsigned DefaultMaxBits = |
|
jvoung (off chromium)
2015/05/05 00:27:23
Hmm bug fix / got lucky before?
Karl
2015/05/05 22:38:04
Yep. Because the test examples didn't really use a
| |
| 106 NaClBitsNeededForValue(naclbitc::DEFAULT_MAX_ABBREV); | |
| 107 if (NumBits != DefaultMaxBits) { | |
| 161 Fatal() | 108 Fatal() |
| 162 << "Error: Numbits entry for abbreviations record not 2. Found: " | 109 << "Error: Numbits entry for abbreviations record not " |
| 163 << NumBits << "\n"; | 110 << DefaultMaxBits << ". Found: " << NumBits << "\n"; |
| 164 ReportFatalError(); | 111 ReportFatalError(); |
| 165 } | 112 } |
| 166 Writer->EnterBlockInfoBlock(); | 113 Writer.EnterBlockInfoBlock(); |
| 167 } else { | 114 } else { |
| 168 NaClBitcodeSelectorAbbrev CurCodeLen(MaxAbbrev); | 115 NaClBitcodeSelectorAbbrev CurCodeLen(MaxAbbrev); |
| 169 Writer->EnterSubblock(WriteBlockID, CurCodeLen); | 116 Writer.EnterSubblock(WriteBlockID, CurCodeLen); |
| 170 } | 117 } |
| 171 return; | 118 return; |
| 172 } | 119 } |
| 173 case naclbitc::BLK_CODE_EXIT: | 120 case naclbitc::BLK_CODE_EXIT: |
| 174 if (Record.Abbrev != naclbitc::END_BLOCK) { | 121 if (Record.Abbrev != naclbitc::END_BLOCK) { |
| 175 Fatal() << "Error: Exit block record code " << Record.Code | 122 Fatal() << "Error: Exit block record code " << Record.Code |
| 176 << " uses illegal abbreviation index " << Record.Abbrev << "\n"; | 123 << " uses illegal abbreviation index " << Record.Abbrev << "\n"; |
| 177 ReportFatalError(); | 124 ReportFatalError(); |
| 178 } | 125 } |
| 179 if (!Record.Values.empty()) { | 126 if (NumValues != 0) { |
| 180 Fatal() << "Error: Exit block should not have values. Found: " | 127 Fatal() << "Error: Exit block should not have values. Found: " |
| 181 << Record.Values.size() << "\n"; | 128 << Record.Values.size() << "\n"; |
| 182 ReportFatalError(); | 129 ReportFatalError(); |
| 183 } | 130 } |
| 184 if (!AbbrevIndexLimitStack.empty()) | 131 if (!AbbrevIndexLimitStack.empty()) |
| 185 AbbrevIndexLimitStack.pop_back(); | 132 AbbrevIndexLimitStack.pop_back(); |
| 186 Writer->ExitBlock(); | 133 Writer.ExitBlock(); |
| 187 return; | 134 return; |
| 188 case naclbitc::BLK_CODE_DEFINE_ABBREV: { | 135 case naclbitc::BLK_CODE_DEFINE_ABBREV: { |
| 189 if (Record.Abbrev != naclbitc::DEFINE_ABBREV) { | 136 if (Record.Abbrev != naclbitc::DEFINE_ABBREV) { |
| 190 Fatal() << "Error: Define abbreviation record code " << Record.Code | 137 Fatal() << "Error: Define abbreviation record code " << Record.Code |
| 191 << " uses illegal abbreviation index " << Record.Abbrev << "\n"; | 138 << " uses illegal abbreviation index " << Record.Abbrev << "\n"; |
| 192 ReportFatalError(); | 139 ReportFatalError(); |
| 193 } | 140 } |
| 194 NaClBitCodeAbbrev *Abbrev = buildAbbrev(Record); | 141 NaClBitCodeAbbrev *Abbrev = buildAbbrev(Record); |
| 195 if (Abbrev == NULL) return; | 142 if (Abbrev == NULL) return; |
| 196 if (WriteBlockID == naclbitc::BLOCKINFO_BLOCK_ID) { | 143 if (WriteBlockID == naclbitc::BLOCKINFO_BLOCK_ID) { |
| 197 Writer->EmitBlockInfoAbbrev(SetBID, Abbrev); | 144 Writer.EmitBlockInfoAbbrev(SetBID, Abbrev); |
| 198 } else { | 145 } else { |
| 199 Writer->EmitAbbrev(Abbrev); | 146 Writer.EmitAbbrev(Abbrev); |
| 200 } | 147 } |
| 201 return; | 148 return; |
| 202 } | 149 } |
| 203 case naclbitc::BLK_CODE_HEADER: | 150 case naclbitc::BLK_CODE_HEADER: |
| 204 // Note: There is no abbreviation index here. Ignore. | 151 // Note: There is no abbreviation index here. Ignore. |
| 205 for (uint64_t Value : Record.Values) | 152 for (uint64_t Value : Record.Values) |
| 206 Writer->Emit(Value, 8); | 153 Writer.Emit(Value, 8); |
| 207 return; | 154 return; |
| 208 default: | 155 default: |
| 209 if ((Record.Abbrev != naclbitc::UNABBREV_RECORD | 156 if ((Record.Abbrev != naclbitc::UNABBREV_RECORD |
| 210 && !Writer->isUserRecordAbbreviation(Record.Abbrev))) { | 157 && !Writer.isUserRecordAbbreviation(Record.Abbrev))) { |
| 211 uint64_t BlockAbbrevIndexLimit = 0; | 158 uint64_t BlockAbbrevIndexLimit = 0; |
| 212 if (!AbbrevIndexLimitStack.empty()) | 159 if (!AbbrevIndexLimitStack.empty()) |
| 213 BlockAbbrevIndexLimit = AbbrevIndexLimitStack.back(); | 160 BlockAbbrevIndexLimit = AbbrevIndexLimitStack.back(); |
| 214 if (Record.Abbrev > BlockAbbrevIndexLimit) { | 161 if (!RecoverOnBadAbbrevId || Record.Abbrev > BlockAbbrevIndexLimit) { |
| 215 Fatal() << "Error: Record code " << Record.Code | 162 // Can't generate abbreviation ID because not enough bits |
| 216 << " uses illegal abbreviation index " << Record.Abbrev | 163 // specified in block ID. |
| 217 << ". Must not exceed " << BlockAbbrevIndexLimit << "\n"; | 164 raw_ostream &ErrStrm = Fatal(); |
| 165 ErrStrm << "Error: Block ID " << WriteBlockID | |
| 166 << " Record code " << Record.Code | |
| 167 << " uses illegal abbreviation index " << Record.Abbrev; | |
| 168 if (Record.Abbrev > BlockAbbrevIndexLimit) | |
| 169 ErrStrm << ". Must not exceed " << BlockAbbrevIndexLimit; | |
| 170 ErrStrm << "\n"; | |
| 218 ReportFatalError(); | 171 ReportFatalError(); |
| 219 } | 172 } |
| 220 // Note: If this point is reached, the abbreviation is | 173 // Note: If this point is reached, the abbreviation is |
| 221 // bad. However, that may be the point of munge being | 174 // bad. However, that may be the point of munge being |
| 222 // applied. Hence, emit the bad abbreviation and the data so | 175 // applied. Hence, emit the bad abbreviation and the data so |
| 223 // that the reader can be tested on this bad input. For | 176 // that the reader can be tested on this bad input. For |
| 224 // simplicity, we output the record data using the default | 177 // simplicity, we output the record data using the default |
| 225 // abbreviation pattern. | 178 // abbreviation pattern. |
| 226 errs() << "Warning: Record code " << Record.Code | 179 errs() << "Warning: Record code " << Record.Code |
| 227 << " uses illegal abbreviation index " << Record.Abbrev << "\n"; | 180 << " uses illegal abbreviation index " << Record.Abbrev << "\n"; |
| 228 Writer->EmitCode(Record.Abbrev); | 181 Writer.EmitCode(Record.Abbrev); |
|
jvoung (off chromium)
2015/05/05 00:27:23
Just revisiting this since it's been a while... th
Karl
2015/05/05 22:38:04
Actually, your close, but not quite right. The poi
| |
| 229 Writer->EmitVBR(Record.Code, 6); | 182 Writer.EmitVBR(Record.Code, 6); |
| 230 uint32_t NumValues = static_cast<uint32_t>(Record.Values.size()); | 183 Writer.EmitVBR(NumValues, 6); |
| 231 Writer->EmitVBR(NumValues, 6); | |
| 232 for (uint32_t i = 0; i < NumValues; ++i) { | 184 for (uint32_t i = 0; i < NumValues; ++i) { |
| 233 Writer->EmitVBR64(Record.Values[i], 6); | 185 Writer.EmitVBR64(Record.Values[i], 6); |
| 234 } | 186 } |
| 235 return; | 187 return; |
| 236 } | 188 } |
| 189 if (WriteBlockID == naclbitc::BLOCKINFO_BLOCK_ID | |
| 190 && Record.Code == naclbitc::BLOCKINFO_CODE_SETBID) { | |
| 191 // Note: SetBID records are handled by Writer->EmitBlockInfoAbbrev, | |
| 192 // based on the SetBID value. Don't bother to generate SetBID record here. | |
| 193 // Rathter just set SetBID and let call to Writer->EmitBlockInfoAbbrev | |
|
jvoung (off chromium)
2015/05/05 00:27:23
Rathter -> Rather
Karl
2015/05/05 22:38:04
Done.
| |
| 194 // generate the SetBID record. | |
| 195 if (NumValues != 1) { | |
| 196 Fatal() << "SetBID record expects 1 value, found: " | |
| 197 << NumValues << "\n"; | |
| 198 ReportFatalError(); | |
| 199 } | |
| 200 if (NumValues > 0) | |
| 201 SetBID = Record.Values[0]; | |
| 202 return; | |
| 203 } | |
| 237 if (Record.Abbrev == naclbitc::UNABBREV_RECORD) | 204 if (Record.Abbrev == naclbitc::UNABBREV_RECORD) |
| 238 Writer->EmitRecord(Record.Code, Record.Values); | 205 Writer.EmitRecord(Record.Code, Record.Values); |
| 239 else | 206 else |
| 240 Writer->EmitRecord(Record.Code, Record.Values, Record.Abbrev); | 207 Writer.EmitRecord(Record.Code, Record.Values, Record.Abbrev); |
| 241 return; | 208 return; |
| 242 } | 209 } |
| 243 Fatal() << "emitRecord on unimplemented code" << "\n"; | |
| 244 ReportFatalError(); | |
| 245 } | 210 } |
| 246 | 211 |
| 247 NaClBitCodeAbbrev *NaClBitcodeMunger::buildAbbrev( | 212 // BUilds an abbreviation from the given bitcode record. |
|
jvoung (off chromium)
2015/05/05 00:27:23
BUilds -> Builds
Karl
2015/05/05 22:38:04
Removed comment since the declaration already has
| |
| 213 NaClBitCodeAbbrev *WriteState::buildAbbrev( | |
| 248 const NaClBitcodeAbbrevRecord &Record) { | 214 const NaClBitcodeAbbrevRecord &Record) { |
| 249 NaClBitCodeAbbrev *Abbrev = new NaClBitCodeAbbrev(); | 215 NaClBitCodeAbbrev *Abbrev = new NaClBitCodeAbbrev(); |
| 250 size_t Index = 0; | 216 size_t Index = 0; |
| 251 if (Record.Values.empty()) { | 217 size_t NumValues = Record.Values.size(); |
| 218 if (NumValues == 0) { | |
| 252 Fatal() << "Empty abbreviation record not allowed\n"; | 219 Fatal() << "Empty abbreviation record not allowed\n"; |
| 253 ReportFatalError(); | 220 ReportFatalError(); |
| 254 } | 221 } |
| 255 size_t NumAbbreviations = Record.Values[Index++]; | 222 size_t NumAbbreviations = Record.Values[Index++]; |
| 256 size_t NumValues = Record.Values.size(); | |
| 257 if (NumAbbreviations == 0) { | 223 if (NumAbbreviations == 0) { |
| 258 Fatal() << "Abbreviation must contain at least one operator\n"; | 224 Fatal() << "Abbreviation must contain at least one operator\n"; |
| 259 ReportFatalError(); | 225 ReportFatalError(); |
| 260 } | 226 } |
| 261 for (size_t Count = 0; Count < NumAbbreviations; ++Count) { | 227 for (size_t Count = 0; Count < NumAbbreviations; ++Count) { |
| 262 if (Index >= NumValues) { | 228 if (Index >= NumValues) { |
| 263 Fatal() << "Malformed abbreviation found. Expects " | 229 Fatal() << "Malformed abbreviation found. Expects " |
| 264 << NumAbbreviations << " operands. Found: " | 230 << NumAbbreviations << " operands. Found: " |
| 265 << Count << "\n"; | 231 << Count << "\n"; |
| 266 ReportFatalError(); | 232 ReportFatalError(); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 314 } | 280 } |
| 315 default: | 281 default: |
| 316 Fatal() << "Error: Bad literal flag in abbreviation. Found: " | 282 Fatal() << "Error: Bad literal flag in abbreviation. Found: " |
| 317 << Record.Values[Index]; | 283 << Record.Values[Index]; |
| 318 ReportFatalError(); | 284 ReportFatalError(); |
| 319 } | 285 } |
| 320 } | 286 } |
| 321 return Abbrev; | 287 return Abbrev; |
| 322 } | 288 } |
| 323 | 289 |
| 324 bool NaClObjDumpMunger::runTestWithFlags( | 290 } // end of anonymous namespace. |
| 325 const char *Name, const uint64_t Munges[], size_t MungesSize, | |
| 326 bool AddHeader, bool NoRecords, bool NoAssembly) { | |
| 327 setupTest(Name, Munges, MungesSize, AddHeader); | |
| 328 | 291 |
| 329 /// If running in death mode, redirect output directly to the | 292 void NaClMungedBitcode::write(SmallVectorImpl<char> &Buffer, |
| 330 /// error stream (rather than buffering in DumpStream), so that | 293 bool AddHeader, |
| 331 /// output can be seen in gtest death test. | 294 bool RecoverOnBadAbbrevId) const { |
| 332 raw_ostream &Output = RunAsDeathTest ? errs() : *DumpStream; | 295 NaClBitstreamWriter Writer(Buffer); |
| 333 if (NaClObjDump(MungedInput.get()->getMemBufferRef(), | 296 WriteState State; |
| 334 Output, NoRecords, NoAssembly)) | 297 if (AddHeader) { |
| 335 FoundErrors = true; | 298 NaClWriteHeader(Writer, true); |
| 336 cleanupTest(); | 299 } |
| 337 return !FoundErrors; | 300 for (const NaClBitcodeAbbrevRecord &Record : *this) { |
| 301 State.emitRecord(Writer, Record, RecoverOnBadAbbrevId); | |
|
jvoung (off chromium)
2015/05/05 00:27:23
nit: Might have been able to make RecoverOnBadAbbr
Karl
2015/05/05 22:38:04
Good point. The state is probably the better place
| |
| 302 } | |
| 338 } | 303 } |
| 339 | |
| 340 bool NaClParseBitcodeMunger::runTest( | |
| 341 const char *Name, const uint64_t Munges[], size_t MungesSize, | |
| 342 bool VerboseErrors) { | |
| 343 bool AddHeader = true; | |
| 344 setupTest(Name, Munges, MungesSize, AddHeader); | |
| 345 LLVMContext &Context = getGlobalContext(); | |
| 346 raw_ostream *VerboseStrm = VerboseErrors ? DumpStream : nullptr; | |
| 347 ErrorOr<Module *> ModuleOrError = | |
| 348 NaClParseBitcodeFile(MungedInput->getMemBufferRef(), Context, | |
| 349 VerboseStrm); | |
| 350 if (ModuleOrError) { | |
| 351 if (VerboseErrors) | |
| 352 *DumpStream << "Successful parse!\n"; | |
| 353 delete ModuleOrError.get(); | |
| 354 } else { | |
| 355 Error() << ModuleOrError.getError().message() << "\n"; | |
| 356 } | |
| 357 cleanupTest(); | |
| 358 return !FoundErrors; | |
| 359 } | |
| 360 | |
| 361 bool NaClCompressMunger::runTest(const char* Name, const uint64_t Munges[], | |
| 362 size_t MungesSize) { | |
| 363 bool AddHeader = true; | |
| 364 setupTest(Name, Munges, MungesSize, AddHeader); | |
| 365 NaClBitcodeCompressor Compressor; | |
| 366 bool Result = Compressor.compress(MungedInput.get(), *DumpStream); | |
| 367 cleanupTest(); | |
| 368 return Result; | |
| 369 } | |
| OLD | NEW |