OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |