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 = (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 errs() << "Warning: Record code " << RecordCode | |
288 << " uses illegal abbreviation index " << AbbrevIndex << "\n"; | |
289 // Fake writing out record using default abbreviation pattern. | |
jvoung (off chromium)
2015/02/20 00:12:42
When is this sort of error recovery needed?
Can y
Karl
2015/02/20 21:41:17
The purpose of the munger is to be able to introdu
| |
290 Writer->EmitCode(AbbrevIndex); | |
291 Writer->EmitVBR(RecordCode, 6); | |
292 uint32_t NumValues = uint32_t(Values.size()); | |
jvoung (off chromium)
2015/02/20 00:12:42
static_cast<uint32_t>()?
Karl
2015/02/20 21:41:17
Done.
| |
293 Writer->EmitVBR(NumValues, 6); | |
294 for (uint32_t i = 0; i < NumValues; ++i) { | |
295 Writer->EmitVBR64(Values[i], 6); | |
296 } | |
297 return; | |
276 } | 298 } |
277 if (AbbrevIndex == naclbitc::UNABBREV_RECORD) | 299 if (AbbrevIndex == naclbitc::UNABBREV_RECORD) |
278 Writer->EmitRecord(RecordCode, Values); | 300 Writer->EmitRecord(RecordCode, Values); |
279 else | 301 else |
280 Writer->EmitRecord(RecordCode, Values, AbbrevIndex); | 302 Writer->EmitRecord(RecordCode, Values, AbbrevIndex); |
281 return; | 303 return; |
282 } | 304 } |
283 Fatal() << "emitRecord on unimplemented code" << "\n"; | 305 Fatal() << "emitRecord on unimplemented code" << "\n"; |
284 ReportFatalError(); | 306 ReportFatalError(); |
285 } | 307 } |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
341 ReportFatalError(); | 363 ReportFatalError(); |
342 } | 364 } |
343 } | 365 } |
344 return Abbrev; | 366 return Abbrev; |
345 } | 367 } |
346 | 368 |
347 bool NaClObjDumpMunger::runTestWithFlags( | 369 bool NaClObjDumpMunger::runTestWithFlags( |
348 const char *Name, const uint64_t Munges[], size_t MungesSize, | 370 const char *Name, const uint64_t Munges[], size_t MungesSize, |
349 bool AddHeader, bool NoRecords, bool NoAssembly) { | 371 bool AddHeader, bool NoRecords, bool NoAssembly) { |
350 setupTest(Name, Munges, MungesSize, AddHeader); | 372 setupTest(Name, Munges, MungesSize, AddHeader); |
351 if (NaClObjDump(MungedInput.get(), *DumpStream, NoRecords, NoAssembly)) | 373 |
374 /// If running in death mode, redirect output directly to the | |
375 /// error stream (rather than buffering in DumpStream), so that | |
376 /// output can be seen in gtest death test. | |
377 raw_ostream &Output = RunAsDeathTest ? errs() : *DumpStream; | |
378 if (NaClObjDump(MungedInput.get(), Output, NoRecords, NoAssembly)) | |
352 FoundErrors = true; | 379 FoundErrors = true; |
353 cleanupTest(); | 380 cleanupTest(); |
354 return !FoundErrors; | 381 return !FoundErrors; |
355 } | 382 } |
356 | 383 |
357 bool NaClParseBitcodeMunger::runTest( | 384 bool NaClParseBitcodeMunger::runTest( |
358 const char *Name, const uint64_t Munges[], size_t MungesSize, | 385 const char *Name, const uint64_t Munges[], size_t MungesSize, |
359 bool VerboseErrors) { | 386 bool VerboseErrors) { |
360 bool AddHeader = true; | 387 bool AddHeader = true; |
361 setupTest(Name, Munges, MungesSize, AddHeader); | 388 setupTest(Name, Munges, MungesSize, AddHeader); |
362 LLVMContext &Context = getGlobalContext(); | 389 LLVMContext &Context = getGlobalContext(); |
363 raw_ostream *VerboseStrm = VerboseErrors ? DumpStream : nullptr; | 390 raw_ostream *VerboseStrm = VerboseErrors ? DumpStream : nullptr; |
364 ErrorOr<Module *> ModuleOrError = | 391 ErrorOr<Module *> ModuleOrError = |
365 NaClParseBitcodeFile(MungedInput.get(), Context, VerboseStrm); | 392 NaClParseBitcodeFile(MungedInput.get(), Context, VerboseStrm); |
366 if (ModuleOrError) { | 393 if (ModuleOrError) { |
367 if (VerboseErrors) | 394 if (VerboseErrors) |
368 *DumpStream << "Successful parse!\n"; | 395 *DumpStream << "Successful parse!\n"; |
369 delete ModuleOrError.get(); | 396 delete ModuleOrError.get(); |
370 } else { | 397 } else { |
371 Error() << ModuleOrError.getError().message() << "\n"; | 398 Error() << ModuleOrError.getError().message() << "\n"; |
372 } | 399 } |
373 cleanupTest(); | 400 cleanupTest(); |
374 return !FoundErrors; | 401 return !FoundErrors; |
375 } | 402 } |
OLD | NEW |