| 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 |