| 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 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 211 if (NumBits > 32) { | 211 if (NumBits > 32) { |
| 212 Fatal() << "Error: Bit size " << NumBits | 212 Fatal() << "Error: Bit size " << NumBits |
| 213 << " for record should be <= 32\n"; | 213 << " for record should be <= 32\n"; |
| 214 ReportFatalError(); | 214 ReportFatalError(); |
| 215 } | 215 } |
| 216 } else { | 216 } else { |
| 217 Fatal() << "Error: Values for enter record should be of size 2. Found: " | 217 Fatal() << "Error: Values for enter record should be of size 2. Found: " |
| 218 << Values.size(); | 218 << Values.size(); |
| 219 ReportFatalError(); | 219 ReportFatalError(); |
| 220 } | 220 } |
| 221 uint64_t MaxAbbrev = (static_cast<uint64_t>(1) << NumBits) - 1; |
| 222 AbbrevIndexLimitStack.push_back(MaxAbbrev); |
| 221 if (WriteBlockID == naclbitc::BLOCKINFO_BLOCK_ID) { | 223 if (WriteBlockID == naclbitc::BLOCKINFO_BLOCK_ID) { |
| 222 if (NumBits != naclbitc::DEFAULT_MAX_ABBREV) { | 224 if (NumBits != naclbitc::DEFAULT_MAX_ABBREV) { |
| 223 Fatal() | 225 Fatal() |
| 224 << "Error: Numbits entry for abbreviations record not 2. Found: " | 226 << "Error: Numbits entry for abbreviations record not 2. Found: " |
| 225 << NumBits << "\n"; | 227 << NumBits << "\n"; |
| 226 ReportFatalError(); | 228 ReportFatalError(); |
| 227 } | 229 } |
| 228 Writer->EnterBlockInfoBlock(); | 230 Writer->EnterBlockInfoBlock(); |
| 229 } else { | 231 } else { |
| 230 Writer->EnterSubblock(WriteBlockID, NumBits); | 232 NaClBitcodeSelectorAbbrev CurCodeLen(MaxAbbrev); |
| 233 Writer->EnterSubblock(WriteBlockID, CurCodeLen); |
| 231 } | 234 } |
| 232 return; | 235 return; |
| 233 } | 236 } |
| 234 case naclbitc::BLK_CODE_EXIT: | 237 case naclbitc::BLK_CODE_EXIT: |
| 235 if (AbbrevIndex != naclbitc::END_BLOCK) { | 238 if (AbbrevIndex != naclbitc::END_BLOCK) { |
| 236 Fatal() << "Error: Exit block record code " << RecordCode | 239 Fatal() << "Error: Exit block record code " << RecordCode |
| 237 << " uses illegal abbreviation index " << AbbrevIndex << "\n"; | 240 << " uses illegal abbreviation index " << AbbrevIndex << "\n"; |
| 238 ReportFatalError(); | 241 ReportFatalError(); |
| 239 } | 242 } |
| 240 if (!Values.empty()) { | 243 if (!Values.empty()) { |
| 241 Fatal() << "Error: Exit block should not have values. Found: " | 244 Fatal() << "Error: Exit block should not have values. Found: " |
| 242 << Values.size() << "\n"; | 245 << Values.size() << "\n"; |
| 243 ReportFatalError(); | 246 ReportFatalError(); |
| 244 } | 247 } |
| 248 if (!AbbrevIndexLimitStack.empty()) |
| 249 AbbrevIndexLimitStack.pop_back(); |
| 245 Writer->ExitBlock(); | 250 Writer->ExitBlock(); |
| 246 return; | 251 return; |
| 247 case naclbitc::BLK_CODE_DEFINE_ABBREV: { | 252 case naclbitc::BLK_CODE_DEFINE_ABBREV: { |
| 248 if (AbbrevIndex != naclbitc::DEFINE_ABBREV) { | 253 if (AbbrevIndex != naclbitc::DEFINE_ABBREV) { |
| 249 Fatal() << "Error: Define abbreviation record code " << RecordCode | 254 Fatal() << "Error: Define abbreviation record code " << RecordCode |
| 250 << " uses illegal abbreviation index " << AbbrevIndex << "\n"; | 255 << " uses illegal abbreviation index " << AbbrevIndex << "\n"; |
| 251 ReportFatalError(); | 256 ReportFatalError(); |
| 252 } | 257 } |
| 253 NaClBitCodeAbbrev *Abbrev = buildAbbrev(RecordCode, Values); | 258 NaClBitCodeAbbrev *Abbrev = buildAbbrev(RecordCode, Values); |
| 254 if (Abbrev == NULL) return; | 259 if (Abbrev == NULL) return; |
| 255 if (WriteBlockID == naclbitc::BLOCKINFO_BLOCK_ID) { | 260 if (WriteBlockID == naclbitc::BLOCKINFO_BLOCK_ID) { |
| 256 Writer->EmitBlockInfoAbbrev(SetBID, Abbrev); | 261 Writer->EmitBlockInfoAbbrev(SetBID, Abbrev); |
| 257 } else { | 262 } else { |
| 258 Writer->EmitAbbrev(Abbrev); | 263 Writer->EmitAbbrev(Abbrev); |
| 259 } | 264 } |
| 260 return; | 265 return; |
| 261 } | 266 } |
| 262 case naclbitc::BLK_CODE_HEADER: | 267 case naclbitc::BLK_CODE_HEADER: |
| 263 // Note: There is no abbreviation index here. Ignore. | 268 // Note: There is no abbreviation index here. Ignore. |
| 264 for (SmallVectorImpl<uint64_t>::const_iterator | 269 for (SmallVectorImpl<uint64_t>::const_iterator |
| 265 Iter = Values.begin(), IterEnd = Values.end(); | 270 Iter = Values.begin(), IterEnd = Values.end(); |
| 266 Iter != IterEnd; ++Iter) { | 271 Iter != IterEnd; ++Iter) { |
| 267 Writer->Emit(*Iter, 8); | 272 Writer->Emit(*Iter, 8); |
| 268 } | 273 } |
| 269 return; | 274 return; |
| 270 default: | 275 default: |
| 271 if ((AbbrevIndex != naclbitc::UNABBREV_RECORD | 276 if ((AbbrevIndex != naclbitc::UNABBREV_RECORD |
| 272 && !Writer->isUserRecordAbbreviation(AbbrevIndex))) { | 277 && !Writer->isUserRecordAbbreviation(AbbrevIndex))) { |
| 273 Fatal() << "Error: Record code " << RecordCode | 278 uint64_t BlockAbbrevIndexLimit = 0; |
| 274 << " uses illegal abbreviation index " << AbbrevIndex << "\n"; | 279 if (!AbbrevIndexLimitStack.empty()) |
| 275 ReportFatalError(); | 280 BlockAbbrevIndexLimit = AbbrevIndexLimitStack.back(); |
| 281 if (AbbrevIndex > BlockAbbrevIndexLimit) { |
| 282 Fatal() << "Error: Record code " << RecordCode |
| 283 << " uses illegal abbreviation index " << AbbrevIndex |
| 284 << ". Must not exceed " << BlockAbbrevIndexLimit << "\n"; |
| 285 ReportFatalError(); |
| 286 } |
| 287 // Note: If this point is reached, the abbreviation is |
| 288 // bad. However, that may be the point of munge being |
| 289 // applied. Hence, emit the bad abbreviation and the data so |
| 290 // that the reader can be tested on this bad input. For |
| 291 // simplicity, we output the record data using the default |
| 292 // abbreviation pattern. |
| 293 errs() << "Warning: Record code " << RecordCode |
| 294 << " uses illegal abbreviation index " << AbbrevIndex << "\n"; |
| 295 Writer->EmitCode(AbbrevIndex); |
| 296 Writer->EmitVBR(RecordCode, 6); |
| 297 uint32_t NumValues = static_cast<uint32_t>(Values.size()); |
| 298 Writer->EmitVBR(NumValues, 6); |
| 299 for (uint32_t i = 0; i < NumValues; ++i) { |
| 300 Writer->EmitVBR64(Values[i], 6); |
| 301 } |
| 302 return; |
| 276 } | 303 } |
| 277 if (AbbrevIndex == naclbitc::UNABBREV_RECORD) | 304 if (AbbrevIndex == naclbitc::UNABBREV_RECORD) |
| 278 Writer->EmitRecord(RecordCode, Values); | 305 Writer->EmitRecord(RecordCode, Values); |
| 279 else | 306 else |
| 280 Writer->EmitRecord(RecordCode, Values, AbbrevIndex); | 307 Writer->EmitRecord(RecordCode, Values, AbbrevIndex); |
| 281 return; | 308 return; |
| 282 } | 309 } |
| 283 Fatal() << "emitRecord on unimplemented code" << "\n"; | 310 Fatal() << "emitRecord on unimplemented code" << "\n"; |
| 284 ReportFatalError(); | 311 ReportFatalError(); |
| 285 } | 312 } |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 341 ReportFatalError(); | 368 ReportFatalError(); |
| 342 } | 369 } |
| 343 } | 370 } |
| 344 return Abbrev; | 371 return Abbrev; |
| 345 } | 372 } |
| 346 | 373 |
| 347 bool NaClObjDumpMunger::runTestWithFlags( | 374 bool NaClObjDumpMunger::runTestWithFlags( |
| 348 const char *Name, const uint64_t Munges[], size_t MungesSize, | 375 const char *Name, const uint64_t Munges[], size_t MungesSize, |
| 349 bool AddHeader, bool NoRecords, bool NoAssembly) { | 376 bool AddHeader, bool NoRecords, bool NoAssembly) { |
| 350 setupTest(Name, Munges, MungesSize, AddHeader); | 377 setupTest(Name, Munges, MungesSize, AddHeader); |
| 351 if (NaClObjDump(MungedInput.get(), *DumpStream, NoRecords, NoAssembly)) | 378 |
| 379 /// If running in death mode, redirect output directly to the |
| 380 /// error stream (rather than buffering in DumpStream), so that |
| 381 /// output can be seen in gtest death test. |
| 382 raw_ostream &Output = RunAsDeathTest ? errs() : *DumpStream; |
| 383 if (NaClObjDump(MungedInput.get(), Output, NoRecords, NoAssembly)) |
| 352 FoundErrors = true; | 384 FoundErrors = true; |
| 353 cleanupTest(); | 385 cleanupTest(); |
| 354 return !FoundErrors; | 386 return !FoundErrors; |
| 355 } | 387 } |
| 356 | 388 |
| 357 bool NaClParseBitcodeMunger::runTest( | 389 bool NaClParseBitcodeMunger::runTest( |
| 358 const char *Name, const uint64_t Munges[], size_t MungesSize, | 390 const char *Name, const uint64_t Munges[], size_t MungesSize, |
| 359 bool VerboseErrors) { | 391 bool VerboseErrors) { |
| 360 bool AddHeader = true; | 392 bool AddHeader = true; |
| 361 setupTest(Name, Munges, MungesSize, AddHeader); | 393 setupTest(Name, Munges, MungesSize, AddHeader); |
| 362 LLVMContext &Context = getGlobalContext(); | 394 LLVMContext &Context = getGlobalContext(); |
| 363 raw_ostream *VerboseStrm = VerboseErrors ? DumpStream : nullptr; | 395 raw_ostream *VerboseStrm = VerboseErrors ? DumpStream : nullptr; |
| 364 ErrorOr<Module *> ModuleOrError = | 396 ErrorOr<Module *> ModuleOrError = |
| 365 NaClParseBitcodeFile(MungedInput.get(), Context, VerboseStrm); | 397 NaClParseBitcodeFile(MungedInput.get(), Context, VerboseStrm); |
| 366 if (ModuleOrError) { | 398 if (ModuleOrError) { |
| 367 if (VerboseErrors) | 399 if (VerboseErrors) |
| 368 *DumpStream << "Successful parse!\n"; | 400 *DumpStream << "Successful parse!\n"; |
| 369 delete ModuleOrError.get(); | 401 delete ModuleOrError.get(); |
| 370 } else { | 402 } else { |
| 371 Error() << ModuleOrError.getError().message() << "\n"; | 403 Error() << ModuleOrError.getError().message() << "\n"; |
| 372 } | 404 } |
| 373 cleanupTest(); | 405 cleanupTest(); |
| 374 return !FoundErrors; | 406 return !FoundErrors; |
| 375 } | 407 } |
| OLD | NEW |