Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(89)

Side by Side Diff: lib/Bitcode/NaCl/Analysis/NaClObjDump.cpp

Issue 932953002: Fix the NaCl bitstream reader to report fatal errors. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-llvm.git@master
Patch Set: Merge with master Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 //===-- NaClObjDump.cpp - Dump PNaCl bitcode contents ---------------------===// 1 //===-- NaClObjDump.cpp - Dump PNaCl bitcode contents ---------------------===//
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 #include "llvm/ADT/STLExtras.h" 10 #include "llvm/ADT/STLExtras.h"
(...skipping 537 matching lines...) Expand 10 before | Expand all | Expand 10 after
548 } 548 }
549 549
550 /// Top-level class to parse bitcode file and transform to 550 /// Top-level class to parse bitcode file and transform to
551 /// corresponding disassembled code. 551 /// corresponding disassembled code.
552 class NaClDisTopLevelParser : public NaClBitcodeParser { 552 class NaClDisTopLevelParser : public NaClBitcodeParser {
553 NaClDisTopLevelParser(const NaClDisTopLevelParser&) LLVM_DELETED_FUNCTION; 553 NaClDisTopLevelParser(const NaClDisTopLevelParser&) LLVM_DELETED_FUNCTION;
554 void operator=(const NaClDisTopLevelParser&) LLVM_DELETED_FUNCTION; 554 void operator=(const NaClDisTopLevelParser&) LLVM_DELETED_FUNCTION;
555 555
556 public: 556 public:
557 NaClDisTopLevelParser(NaClBitcodeHeader &Header, 557 NaClDisTopLevelParser(NaClBitcodeHeader &Header,
558 const unsigned char *HeaderBuffer,
559 NaClBitstreamCursor &Cursor, 558 NaClBitstreamCursor &Cursor,
560 naclbitc::ObjDumpStream &ObjDump) 559 naclbitc::ObjDumpStream &ObjDump)
561 : NaClBitcodeParser(Cursor), 560 : NaClBitcodeParser(Cursor),
562 Mod("ObjDump", getGlobalContext()), 561 Mod("ObjDump", getGlobalContext()),
563 ObjDump(ObjDump), 562 ObjDump(ObjDump),
564 AbbrevListener(this), 563 AbbrevListener(this),
565 DL(&Mod), 564 DL(&Mod),
566 AllowedIntrinsics(&Mod.getContext()), 565 AllowedIntrinsics(&Mod.getContext()),
567 AssemblyFormatter(ObjDump), 566 AssemblyFormatter(ObjDump),
568 Header(Header), 567 Header(Header),
569 HeaderBuffer(HeaderBuffer),
570 NumFunctions(0), 568 NumFunctions(0),
571 NumGlobals(0), 569 NumGlobals(0),
572 ExpectedNumGlobals(0), 570 ExpectedNumGlobals(0),
573 NumParams(0), 571 NumParams(0),
574 NumConstants(0), 572 NumConstants(0),
575 NumValuedInsts(0), 573 NumValuedInsts(0),
576 UnknownType(Type::getVoidTy(Mod.getContext())), 574 UnknownType(Type::getVoidTy(Mod.getContext())),
577 PointerType(Type::getInt32Ty(Mod.getContext())), 575 PointerType(Type::getInt32Ty(Mod.getContext())),
578 ComparisonType(Type::getInt1Ty(Mod.getContext())), 576 ComparisonType(Type::getInt1Ty(Mod.getContext())),
579 NumDefinedFunctions(0) { 577 NumDefinedFunctions(0) {
580 SetListener(&AbbrevListener); 578 SetListener(&AbbrevListener);
581 } 579 }
582 580
583 ~NaClDisTopLevelParser() override { 581 ~NaClDisTopLevelParser() override {
584 // Be sure to flush any remaining errors. 582 // Be sure to flush any remaining errors.
585 ObjDump.Flush(); 583 ObjDump.Flush();
586 } 584 }
587 585
588 // Returns the number of errors that were sent to the ObjDump. 586 // Returns the number of errors that were sent to the ObjDump.
589 unsigned GetNumErrors() { 587 unsigned GetNumErrors() {
590 return ObjDump.GetNumErrors(); 588 return ObjDump.GetNumErrors();
591 } 589 }
592 590
593 /// Generates an error with the given message. 591 /// Generates an error with the given message.
594 bool Error(const std::string &Message) override { 592 bool ErrorAt(uint64_t Bit, const std::string &Message) final {
595 // Use local error routine so that all errors are treated uniformly. 593 // Use local error routine so that all errors are treated uniformly.
596 ObjDump.Error() << Message << "\n"; 594 ObjDump.Error(Bit) << Message << "\n";
597 return true; 595 return true;
598 } 596 }
599 597
600 /// Flushes out objdump and then exits with fatal error. 598 /// Flushes out objdump and then exits with fatal error.
599 LLVM_ATTRIBUTE_NORETURN
601 void Fatal() { 600 void Fatal() {
602 Fatal(""); 601 NaClBitcodeParser::Fatal();
603 } 602 }
604 603
605 /// Flushes out objdump and then exits with fatal error, using 604 /// Flushes out objdump and then exits with fatal error, using
606 /// the given message. 605 /// the given message.
607 void Fatal(const std::string &Message) { 606 LLVM_ATTRIBUTE_NORETURN
608 ObjDump.Fatal(Message); 607 void FatalAt(uint64_t Bit, const std::string &Message) final {
608 ObjDump.Fatal(Bit, Message);
609 } 609 }
610 610
611 /// Parses the top-level module block. 611 /// Parses the top-level module block.
612 bool ParseBlock(unsigned BlockID) override; 612 bool ParseBlock(unsigned BlockID) override;
613 613
614 /// Installs the given type to the next available type index. 614 /// Installs the given type to the next available type index.
615 void InstallType(Type *Ty) { 615 void InstallType(Type *Ty) {
616 TypeIdType.push_back(Ty); 616 TypeIdType.push_back(Ty);
617 } 617 }
618 618
(...skipping 494 matching lines...) Expand 10 before | Expand all | Expand 10 after
1113 // Listener used to get abbreviations as they are read. 1113 // Listener used to get abbreviations as they are read.
1114 NaClBitcodeParserListener AbbrevListener; 1114 NaClBitcodeParserListener AbbrevListener;
1115 // DataLayout to use. 1115 // DataLayout to use.
1116 const DataLayout DL; 1116 const DataLayout DL;
1117 // The set of allowed intrinsics. 1117 // The set of allowed intrinsics.
1118 PNaClAllowedIntrinsics AllowedIntrinsics; 1118 PNaClAllowedIntrinsics AllowedIntrinsics;
1119 // The formatter to use to format assembly code. 1119 // The formatter to use to format assembly code.
1120 AssemblyTextFormatter AssemblyFormatter; 1120 AssemblyTextFormatter AssemblyFormatter;
1121 // The header appearing before the beginning of the input stream. 1121 // The header appearing before the beginning of the input stream.
1122 NaClBitcodeHeader &Header; 1122 NaClBitcodeHeader &Header;
1123 // Pointer to the buffer containing the header.
1124 const unsigned char *HeaderBuffer;
1125 // The list of known types (index i defines the type associated with 1123 // The list of known types (index i defines the type associated with
1126 // type index i). 1124 // type index i).
1127 std::vector<Type*> TypeIdType; 1125 std::vector<Type*> TypeIdType;
1128 // The list of known function signatures (index i defines the type 1126 // The list of known function signatures (index i defines the type
1129 // signature associated with function index i). 1127 // signature associated with function index i).
1130 std::vector<FunctionType*> FunctionIdType; 1128 std::vector<FunctionType*> FunctionIdType;
1131 // boolean flag defining if function id is an intrinsic. 1129 // boolean flag defining if function id is an intrinsic.
1132 std::vector<bool> FunctionIdIsIntrinsic; 1130 std::vector<bool> FunctionIdIsIntrinsic;
1133 // The list of record bit addresses associated with corresponding 1131 // The list of record bit addresses associated with corresponding
1134 // declaration of function IDs. 1132 // declaration of function IDs.
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
1364 } 1362 }
1365 1363
1366 raw_ostream &Warnings() { 1364 raw_ostream &Warnings() {
1367 return Context->Warnings(); 1365 return Context->Warnings();
1368 } 1366 }
1369 1367
1370 void Fatal() { 1368 void Fatal() {
1371 return Context->Fatal(); 1369 return Context->Fatal();
1372 } 1370 }
1373 1371
1374 void Fatal(const std::string &Message) { 1372 void FatalAt(uint64_t Bit, const std::string &Message) override {
1375 return Context->Fatal(Message); 1373 return Context->FatalAt(Bit, Message);
1376 } 1374 }
1377 1375
1378 const std::string &GetAssemblyIndent() const { 1376 const std::string &GetAssemblyIndent() const {
1379 return Context->GetAssemblyIndent(); 1377 return Context->GetAssemblyIndent();
1380 } 1378 }
1381 1379
1382 unsigned GetAssemblyNumTabs() const { 1380 unsigned GetAssemblyNumTabs() const {
1383 return Context->GetAssemblyNumTabs(); 1381 return Context->GetAssemblyNumTabs();
1384 } 1382 }
1385 1383
(...skipping 2095 matching lines...) Expand 10 before | Expand all | Expand 10 after
3481 break; 3479 break;
3482 } 3480 }
3483 default: 3481 default:
3484 Errors() << "Unknown record found in module block\n"; 3482 Errors() << "Unknown record found in module block\n";
3485 break; 3483 break;
3486 } 3484 }
3487 ObjDumpWrite(Record.GetStartBit(), Record); 3485 ObjDumpWrite(Record.GetStartBit(), Record);
3488 } 3486 }
3489 3487
3490 bool NaClDisTopLevelParser::ParseBlock(unsigned BlockID) { 3488 bool NaClDisTopLevelParser::ParseBlock(unsigned BlockID) {
3491 // Before parsing top-level module block. Describe header. 3489 // Before parsing top-level module block. Describe header by
3492 NaClBitcodeRecordData Record; 3490 // reconstructing the corresponding header record.
3491 NaClBitcodeRecordData HeaderRecord;
3493 size_t HeaderSize = Header.getHeaderSize(); 3492 size_t HeaderSize = Header.getHeaderSize();
3494 Record.Code = naclbitc::BLK_CODE_HEADER; 3493 HeaderRecord.Code = naclbitc::BLK_CODE_HEADER;
3494 NaClBitstreamCursor &Cursor = Record.GetCursor();
3495 uint64_t CurPos = Cursor.GetCurrentBitNo();
3496 Cursor.JumpToBit(0);
3495 for (size_t i = 0; i < HeaderSize; ++i) { 3497 for (size_t i = 0; i < HeaderSize; ++i) {
3496 Record.Values.push_back(HeaderBuffer[i]); 3498 HeaderRecord.Values.push_back(Cursor.Read(CHAR_BIT));
3497 } 3499 }
3500 Cursor.JumpToBit(CurPos);
3498 if (ObjDump.GetDumpRecords() && ObjDump.GetDumpAssembly()) { 3501 if (ObjDump.GetDumpRecords() && ObjDump.GetDumpAssembly()) {
3499 if (HeaderSize >= 4) { 3502 if (HeaderSize >= 4) {
3500 const NaClRecordVector &Values = Record.Values; 3503 const NaClRecordVector &Values = HeaderRecord.Values;
3501 Tokens() << "Magic" << Space() << "Number" << Colon() 3504 Tokens() << "Magic" << Space() << "Number" << Colon()
3502 << Space() << StartCluster() << StartCluster() << "'" 3505 << Space() << StartCluster() << StartCluster() << "'"
3503 << (char) Values[0] << (char) Values[1] 3506 << (char) Values[0] << (char) Values[1]
3504 << (char) Values[2] << (char) Values[3] 3507 << (char) Values[2] << (char) Values[3]
3505 << "'" << FinishCluster() << Space() 3508 << "'" << FinishCluster() << Space()
3506 << StartCluster() << OpenParen() 3509 << StartCluster() << OpenParen()
3507 << Values[0] << Comma() << Space() 3510 << Values[0] << Comma() << Space()
3508 << Values[1] << Comma() << Space() 3511 << Values[1] << Comma() << Space()
3509 << Values[2] << Comma() << Space() 3512 << Values[2] << Comma() << Space()
3510 << Values[3] << CloseParen() << FinishCluster() 3513 << Values[3] << CloseParen() << FinishCluster()
3511 << FinishCluster() << Endline(); 3514 << FinishCluster() << Endline();
3512 } 3515 }
3513 // Show interpretation of header as assembly. 3516 // Show interpretation of header as assembly.
3514 for (size_t i = 0; i < Header.NumberFields(); ++i) { 3517 for (size_t i = 0; i < Header.NumberFields(); ++i) {
3515 Tokens() << Header.GetField(i)->Contents() << Endline(); 3518 Tokens() << Header.GetField(i)->Contents() << Endline();
3516 } 3519 }
3517 } 3520 }
3518 ObjDump.Write(0, Record); 3521 ObjDump.Write(0, HeaderRecord);
3519 ObjDump.SetStartOffset(HeaderSize * 8);
3520 3522
3521 if (BlockID != naclbitc::MODULE_BLOCK_ID) 3523 if (BlockID != naclbitc::MODULE_BLOCK_ID)
3522 return Error("Module block expected at top-level, but not found"); 3524 return Error("Module block expected at top-level, but not found");
3523 3525
3524 // Now parse a module block. 3526 // Now parse a module block.
3525 NaClDisModuleParser Parser(BlockID, this); 3527 NaClDisModuleParser Parser(BlockID, this);
3526 return Parser.ParseThisBlock(); 3528 return Parser.ParseThisBlock();
3527 } 3529 }
3528 3530
3529 } 3531 }
(...skipping 10 matching lines...) Expand all
3540 << "Bitcode stream should be a multiple of 4 bytes in length.\n"; 3542 << "Bitcode stream should be a multiple of 4 bytes in length.\n";
3541 return true; 3543 return true;
3542 } 3544 }
3543 3545
3544 const unsigned char *BufPtr = (const unsigned char *)MemBuf->getBufferStart(); 3546 const unsigned char *BufPtr = (const unsigned char *)MemBuf->getBufferStart();
3545 const unsigned char *EndBufPtr = BufPtr+MemBuf->getBufferSize(); 3547 const unsigned char *EndBufPtr = BufPtr+MemBuf->getBufferSize();
3546 const unsigned char *HeaderPtr = BufPtr; 3548 const unsigned char *HeaderPtr = BufPtr;
3547 3549
3548 // Read header and verify it is good. 3550 // Read header and verify it is good.
3549 NaClBitcodeHeader Header; 3551 NaClBitcodeHeader Header;
3550 if (Header.Read(BufPtr, EndBufPtr) || !Header.IsSupported()) { 3552 if (Header.Read(HeaderPtr, EndBufPtr) || !Header.IsSupported()) {
3551 ObjDump.Error() << "Invalid PNaCl bitcode header.\n"; 3553 ObjDump.Error() << "Invalid PNaCl bitcode header.\n";
3552 return true; 3554 return true;
3553 } 3555 }
3554 3556
3555 // Create a bitstream reader to read the bitcode file. 3557 // Create a bitstream reader to read the bitcode file.
3556 NaClBitstreamReader InputStreamFile(BufPtr, EndBufPtr); 3558 NaClBitstreamReader InputStreamFile(BufPtr, EndBufPtr,
3559 Header.getHeaderSize());
3557 NaClBitstreamCursor InputStream(InputStreamFile); 3560 NaClBitstreamCursor InputStream(InputStreamFile);
3558 3561
3559 // Parse the the bitcode file. 3562 // Parse the the bitcode file.
3560 ::NaClDisTopLevelParser Parser(Header, HeaderPtr, InputStream, ObjDump); 3563 ::NaClDisTopLevelParser Parser(Header, InputStream, ObjDump);
3561 int NumBlocksRead = 0; 3564 int NumBlocksRead = 0;
3562 bool ErrorsFound = false; 3565 bool ErrorsFound = false;
3563 while (!InputStream.AtEndOfStream()) { 3566 while (!InputStream.AtEndOfStream()) {
3564 ++NumBlocksRead; 3567 ++NumBlocksRead;
3565 if (Parser.Parse()) ErrorsFound = true; 3568 if (Parser.Parse()) ErrorsFound = true;
3566 } 3569 }
3567 3570
3568 if (NumBlocksRead != 1) { 3571 if (NumBlocksRead != 1) {
3569 ObjDump.Error() << "Expected 1 top level block in bitcode: Found:" 3572 ObjDump.Error() << "Expected 1 top level block in bitcode: Found:"
3570 << NumBlocksRead << "\n"; 3573 << NumBlocksRead << "\n";
3571 ErrorsFound = true; 3574 ErrorsFound = true;
3572 } 3575 }
3573 3576
3574 ObjDump.Flush(); 3577 ObjDump.Flush();
3575 return ErrorsFound || Parser.GetNumErrors() > 0; 3578 return ErrorsFound || Parser.GetNumErrors() > 0;
3576 } 3579 }
3577 3580
3578 } 3581 }
OLDNEW
« no previous file with comments | « include/llvm/Bitcode/NaCl/NaClObjDumpStream.h ('k') | lib/Bitcode/NaCl/Analysis/NaClObjDumpStream.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698