| OLD | NEW |
| 1 //===--- Bitcode/NaCl/TestUtils/NaClBitcodeMunge.cpp - Bitcode Munger -----===// | 1 //===--- Bitcode/NaCl/TestUtils/NaClBitcodeMunge.cpp - Bitcode Munger -----===// |
| 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 // Bitcode writer/munger implementation for testing. |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 216 if (NumBits < 2) { | 216 if (NumBits < 2) { |
| 217 Fatal() << "Error: Bit size " << NumBits | 217 Fatal() << "Error: Bit size " << NumBits |
| 218 << " for record should be >= 2\n"; | 218 << " for record should be >= 2\n"; |
| 219 ReportFatalError(); | 219 ReportFatalError(); |
| 220 } | 220 } |
| 221 } else { | 221 } else { |
| 222 Fatal() << "Error: Values for enter record should be of size 2. Found: " | 222 Fatal() << "Error: Values for enter record should be of size 2. Found: " |
| 223 << Values.size(); | 223 << Values.size(); |
| 224 ReportFatalError(); | 224 ReportFatalError(); |
| 225 } | 225 } |
| 226 uint64_t MaxAbbrev = (static_cast<uint64_t>(1) << NumBits) - 1; |
| 227 AbbrevIndexLimitStack.push_back(MaxAbbrev); |
| 226 if (WriteBlockID == naclbitc::BLOCKINFO_BLOCK_ID) { | 228 if (WriteBlockID == naclbitc::BLOCKINFO_BLOCK_ID) { |
| 227 if (NumBits != naclbitc::DEFAULT_MAX_ABBREV) { | 229 if (NumBits != naclbitc::DEFAULT_MAX_ABBREV) { |
| 228 Fatal() | 230 Fatal() |
| 229 << "Error: Numbits entry for abbreviations record not 2. Found: " | 231 << "Error: Numbits entry for abbreviations record not 2. Found: " |
| 230 << NumBits << "\n"; | 232 << NumBits << "\n"; |
| 231 ReportFatalError(); | 233 ReportFatalError(); |
| 232 } | 234 } |
| 233 Writer->EnterBlockInfoBlock(); | 235 Writer->EnterBlockInfoBlock(); |
| 234 } else { | 236 } else { |
| 235 unsigned NumPossibleAbbrevs = (1 << NumBits) - 1; | 237 NaClBitcodeSelectorAbbrev CurCodeLen(MaxAbbrev); |
| 236 Writer->EnterSubblock(WriteBlockID, NumPossibleAbbrevs); | 238 Writer->EnterSubblock(WriteBlockID, CurCodeLen); |
| 237 } | 239 } |
| 238 return; | 240 return; |
| 239 } | 241 } |
| 240 case naclbitc::BLK_CODE_EXIT: | 242 case naclbitc::BLK_CODE_EXIT: |
| 241 if (AbbrevIndex != naclbitc::END_BLOCK) { | 243 if (AbbrevIndex != naclbitc::END_BLOCK) { |
| 242 Fatal() << "Error: Exit block record code " << RecordCode | 244 Fatal() << "Error: Exit block record code " << RecordCode |
| 243 << " uses illegal abbreviation index " << AbbrevIndex << "\n"; | 245 << " uses illegal abbreviation index " << AbbrevIndex << "\n"; |
| 244 ReportFatalError(); | 246 ReportFatalError(); |
| 245 } | 247 } |
| 246 if (!Values.empty()) { | 248 if (!Values.empty()) { |
| 247 Fatal() << "Error: Exit block should not have values. Found: " | 249 Fatal() << "Error: Exit block should not have values. Found: " |
| 248 << Values.size() << "\n"; | 250 << Values.size() << "\n"; |
| 249 ReportFatalError(); | 251 ReportFatalError(); |
| 250 } | 252 } |
| 253 if (!AbbrevIndexLimitStack.empty()) |
| 254 AbbrevIndexLimitStack.pop_back(); |
| 251 Writer->ExitBlock(); | 255 Writer->ExitBlock(); |
| 252 return; | 256 return; |
| 253 case naclbitc::BLK_CODE_DEFINE_ABBREV: { | 257 case naclbitc::BLK_CODE_DEFINE_ABBREV: { |
| 254 if (AbbrevIndex != naclbitc::DEFINE_ABBREV) { | 258 if (AbbrevIndex != naclbitc::DEFINE_ABBREV) { |
| 255 Fatal() << "Error: Define abbreviation record code " << RecordCode | 259 Fatal() << "Error: Define abbreviation record code " << RecordCode |
| 256 << " uses illegal abbreviation index " << AbbrevIndex << "\n"; | 260 << " uses illegal abbreviation index " << AbbrevIndex << "\n"; |
| 257 ReportFatalError(); | 261 ReportFatalError(); |
| 258 } | 262 } |
| 259 NaClBitCodeAbbrev *Abbrev = buildAbbrev(RecordCode, Values); | 263 NaClBitCodeAbbrev *Abbrev = buildAbbrev(RecordCode, Values); |
| 260 if (Abbrev == NULL) return; | 264 if (Abbrev == NULL) return; |
| 261 if (WriteBlockID == naclbitc::BLOCKINFO_BLOCK_ID) { | 265 if (WriteBlockID == naclbitc::BLOCKINFO_BLOCK_ID) { |
| 262 Writer->EmitBlockInfoAbbrev(SetBID, Abbrev); | 266 Writer->EmitBlockInfoAbbrev(SetBID, Abbrev); |
| 263 } else { | 267 } else { |
| 264 Writer->EmitAbbrev(Abbrev); | 268 Writer->EmitAbbrev(Abbrev); |
| 265 } | 269 } |
| 266 return; | 270 return; |
| 267 } | 271 } |
| 268 case naclbitc::BLK_CODE_HEADER: | 272 case naclbitc::BLK_CODE_HEADER: |
| 269 // Note: There is no abbreviation index here. Ignore. | 273 // Note: There is no abbreviation index here. Ignore. |
| 270 for (SmallVectorImpl<uint64_t>::const_iterator | 274 for (SmallVectorImpl<uint64_t>::const_iterator |
| 271 Iter = Values.begin(), IterEnd = Values.end(); | 275 Iter = Values.begin(), IterEnd = Values.end(); |
| 272 Iter != IterEnd; ++Iter) { | 276 Iter != IterEnd; ++Iter) { |
| 273 Writer->Emit(*Iter, 8); | 277 Writer->Emit(*Iter, 8); |
| 274 } | 278 } |
| 275 return; | 279 return; |
| 276 default: | 280 default: |
| 277 if ((AbbrevIndex != naclbitc::UNABBREV_RECORD | 281 if ((AbbrevIndex != naclbitc::UNABBREV_RECORD |
| 278 && !Writer->isUserRecordAbbreviation(AbbrevIndex))) { | 282 && !Writer->isUserRecordAbbreviation(AbbrevIndex))) { |
| 279 Fatal() << "Error: Record code " << RecordCode | 283 uint64_t BlockAbbrevIndexLimit = 0; |
| 280 << " uses illegal abbreviation index " << AbbrevIndex << "\n"; | 284 if (!AbbrevIndexLimitStack.empty()) |
| 281 ReportFatalError(); | 285 BlockAbbrevIndexLimit = AbbrevIndexLimitStack.back(); |
| 286 if (AbbrevIndex > BlockAbbrevIndexLimit) { |
| 287 Fatal() << "Error: Record code " << RecordCode |
| 288 << " uses illegal abbreviation index " << AbbrevIndex |
| 289 << ". Must not exceed " << BlockAbbrevIndexLimit << "\n"; |
| 290 ReportFatalError(); |
| 291 } |
| 292 // Note: If this point is reached, the abbreviation is |
| 293 // bad. However, that may be the point of munge being |
| 294 // applied. Hence, emit the bad abbreviation and the data so |
| 295 // that the reader can be tested on this bad input. For |
| 296 // simplicity, we output the record data using the default |
| 297 // abbreviation pattern. |
| 298 errs() << "Warning: Record code " << RecordCode |
| 299 << " uses illegal abbreviation index " << AbbrevIndex << "\n"; |
| 300 Writer->EmitCode(AbbrevIndex); |
| 301 Writer->EmitVBR(RecordCode, 6); |
| 302 uint32_t NumValues = static_cast<uint32_t>(Values.size()); |
| 303 Writer->EmitVBR(NumValues, 6); |
| 304 for (uint32_t i = 0; i < NumValues; ++i) { |
| 305 Writer->EmitVBR64(Values[i], 6); |
| 306 } |
| 307 return; |
| 282 } | 308 } |
| 283 if (AbbrevIndex == naclbitc::UNABBREV_RECORD) | 309 if (AbbrevIndex == naclbitc::UNABBREV_RECORD) |
| 284 Writer->EmitRecord(RecordCode, Values); | 310 Writer->EmitRecord(RecordCode, Values); |
| 285 else | 311 else |
| 286 Writer->EmitRecord(RecordCode, Values, AbbrevIndex); | 312 Writer->EmitRecord(RecordCode, Values, AbbrevIndex); |
| 287 return; | 313 return; |
| 288 } | 314 } |
| 289 Fatal() << "emitRecord on unimplemented code" << "\n"; | 315 Fatal() << "emitRecord on unimplemented code" << "\n"; |
| 290 ReportFatalError(); | 316 ReportFatalError(); |
| 291 } | 317 } |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 363 ReportFatalError(); | 389 ReportFatalError(); |
| 364 } | 390 } |
| 365 } | 391 } |
| 366 return Abbrev; | 392 return Abbrev; |
| 367 } | 393 } |
| 368 | 394 |
| 369 bool NaClObjDumpMunger::runTestWithFlags( | 395 bool NaClObjDumpMunger::runTestWithFlags( |
| 370 const char *Name, const uint64_t Munges[], size_t MungesSize, | 396 const char *Name, const uint64_t Munges[], size_t MungesSize, |
| 371 bool AddHeader, bool NoRecords, bool NoAssembly) { | 397 bool AddHeader, bool NoRecords, bool NoAssembly) { |
| 372 setupTest(Name, Munges, MungesSize, AddHeader); | 398 setupTest(Name, Munges, MungesSize, AddHeader); |
| 399 |
| 400 /// If running in death mode, redirect output directly to the |
| 401 /// error stream (rather than buffering in DumpStream), so that |
| 402 /// output can be seen in gtest death test. |
| 403 raw_ostream &Output = RunAsDeathTest ? errs() : *DumpStream; |
| 373 // TODO(jvoung,kschimpf): Should NaClObjDump take a MemoryBufferRef | 404 // TODO(jvoung,kschimpf): Should NaClObjDump take a MemoryBufferRef |
| 374 // like the parser? | 405 // like the parser? |
| 375 if (NaClObjDump(MungedInput.get(), *DumpStream, NoRecords, NoAssembly)) | 406 if (NaClObjDump(MungedInput.get(), Output, NoRecords, NoAssembly)) |
| 376 FoundErrors = true; | 407 FoundErrors = true; |
| 377 cleanupTest(); | 408 cleanupTest(); |
| 378 return !FoundErrors; | 409 return !FoundErrors; |
| 379 } | 410 } |
| 380 | 411 |
| 381 bool NaClParseBitcodeMunger::runTest( | 412 bool NaClParseBitcodeMunger::runTest( |
| 382 const char *Name, const uint64_t Munges[], size_t MungesSize, | 413 const char *Name, const uint64_t Munges[], size_t MungesSize, |
| 383 bool VerboseErrors) { | 414 bool VerboseErrors) { |
| 384 bool AddHeader = true; | 415 bool AddHeader = true; |
| 385 setupTest(Name, Munges, MungesSize, AddHeader); | 416 setupTest(Name, Munges, MungesSize, AddHeader); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 401 | 432 |
| 402 bool NaClCompressMunger::runTest(const char* Name, const uint64_t Munges[], | 433 bool NaClCompressMunger::runTest(const char* Name, const uint64_t Munges[], |
| 403 size_t MungesSize) { | 434 size_t MungesSize) { |
| 404 bool AddHeader = true; | 435 bool AddHeader = true; |
| 405 setupTest(Name, Munges, MungesSize, AddHeader); | 436 setupTest(Name, Munges, MungesSize, AddHeader); |
| 406 NaClBitcodeCompressor Compressor; | 437 NaClBitcodeCompressor Compressor; |
| 407 bool Result = Compressor.compress(MungedInput.get(), *DumpStream); | 438 bool Result = Compressor.compress(MungedInput.get(), *DumpStream); |
| 408 cleanupTest(); | 439 cleanupTest(); |
| 409 return Result; | 440 return Result; |
| 410 } | 441 } |
| OLD | NEW |