OLD | NEW |
(Empty) | |
| 1 //===- NaClBitcodeMungeReader.cpp - Read bitcode record list ----*- C++ -*-===// |
| 2 // |
| 3 // The LLVM Compiler Infrastructure |
| 4 // |
| 5 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. |
| 7 // |
| 8 //===----------------------------------------------------------------------===// |
| 9 // |
| 10 // Implements bitcode reader for NaClBitcodeRecordList and NaClMungedBitcode. |
| 11 |
| 12 #include "llvm/Bitcode/NaCl/NaClBitcodeMungeUtils.h" |
| 13 |
| 14 #include "llvm/Bitcode/NaCl/NaClBitcodeHeader.h" |
| 15 #include "llvm/Support/MemoryBuffer.h" |
| 16 |
| 17 using namespace llvm; |
| 18 |
| 19 namespace { |
| 20 |
| 21 class BitcodeParser; |
| 22 |
| 23 // \brief The state associated with parsing a bitcode buffer. |
| 24 class BitcodeParseState { |
| 25 BitcodeParseState(const BitcodeParseState&) = delete; |
| 26 BitcodeParseState &operator=(const BitcodeParseState&) = delete; |
| 27 public: |
| 28 // \brief Construct the bitcode parse state. |
| 29 // |
| 30 // \param Parser The parser used to parse the bitcode. |
| 31 // \param[out] Records Filled with parsed records. |
| 32 BitcodeParseState(BitcodeParser *Parser, |
| 33 NaClBitcodeRecordList &Records); |
| 34 |
| 35 // List to read records into. |
| 36 NaClBitcodeRecordList &Records; |
| 37 // Listener used to get abbreviations as they are read. |
| 38 NaClBitcodeParserListener AbbrevListener; |
| 39 }; |
| 40 |
| 41 // \brief The bitcode parser to extract bitcode records. |
| 42 class BitcodeParser : public NaClBitcodeParser { |
| 43 BitcodeParser(const BitcodeParser &) = delete; |
| 44 BitcodeParser &operator=(const BitcodeParser&) = delete; |
| 45 public: |
| 46 // \brief Top-level constructor for a bitcode parser. |
| 47 // |
| 48 // \param Cursor The beginning position of the bitcode to parse. |
| 49 // \param[out] Records Filled with parsed records. |
| 50 BitcodeParser(NaClBitstreamCursor &Cursor, |
| 51 NaClBitcodeRecordList &Records) |
| 52 : NaClBitcodeParser(Cursor), |
| 53 State(new BitcodeParseState(this, Records)) { |
| 54 SetListener(&State->AbbrevListener); |
| 55 } |
| 56 |
| 57 ~BitcodeParser() override { |
| 58 if (EnclosingParser == nullptr) |
| 59 delete State; |
| 60 } |
| 61 |
| 62 bool ParseBlock(unsigned BlockID) override { |
| 63 BitcodeParser NestedParser(BlockID, this); |
| 64 return NestedParser.ParseThisBlock(); |
| 65 } |
| 66 |
| 67 void EnterBlock(unsigned NumWords) override { |
| 68 NaClRecordVector Values; |
| 69 Values.push_back(GetBlockID()); |
| 70 Values.push_back(Record.GetCursor().getAbbrevIDWidth()); |
| 71 std::unique_ptr<NaClBitcodeAbbrevRecord> AbbrevRec( |
| 72 new NaClBitcodeAbbrevRecord(naclbitc::ENTER_SUBBLOCK, |
| 73 naclbitc::BLK_CODE_ENTER, |
| 74 Values)); |
| 75 State->Records.push_back(std::move(AbbrevRec)); |
| 76 } |
| 77 |
| 78 void ExitBlock() override { |
| 79 NaClRecordVector Values; |
| 80 std::unique_ptr<NaClBitcodeAbbrevRecord> AbbrevRec( |
| 81 new NaClBitcodeAbbrevRecord(naclbitc::END_BLOCK, |
| 82 naclbitc::BLK_CODE_EXIT, |
| 83 Values)); |
| 84 State->Records.push_back(std::move(AbbrevRec)); |
| 85 } |
| 86 |
| 87 void ProcessRecord() override { |
| 88 std::unique_ptr<NaClBitcodeAbbrevRecord> AbbrevRec( |
| 89 new NaClBitcodeAbbrevRecord(Record.GetAbbreviationIndex(), |
| 90 Record.GetCode(), |
| 91 Record.GetValues())); |
| 92 State->Records.push_back(std::move(AbbrevRec)); |
| 93 } |
| 94 |
| 95 void SetBID() override { |
| 96 ProcessRecord(); |
| 97 } |
| 98 |
| 99 void ProcessAbbreviation(unsigned BlockID, |
| 100 NaClBitCodeAbbrev *Abbrev, |
| 101 bool IsLocal) override { |
| 102 ProcessRecord(); |
| 103 } |
| 104 |
| 105 private: |
| 106 // \brief Nested constructor for blocks within the bitcode buffer. |
| 107 // |
| 108 // \param BlockID The identifying constant associated with the block. |
| 109 // \param EnclosingParser The bitcode parser parsing the enclosing block. |
| 110 BitcodeParser(unsigned BlockID, BitcodeParser *EnclosingParser) |
| 111 : NaClBitcodeParser(BlockID, EnclosingParser), |
| 112 State(EnclosingParser->State) {} |
| 113 |
| 114 // The state of the bitcode parser. |
| 115 BitcodeParseState* State; |
| 116 }; |
| 117 |
| 118 BitcodeParseState::BitcodeParseState(BitcodeParser *Parser, |
| 119 NaClBitcodeRecordList &Records) |
| 120 : Records(Records), AbbrevListener(Parser) {} |
| 121 |
| 122 } // end of anonymous namespace |
| 123 |
| 124 void llvm::readNaClBitcodeRecordList( |
| 125 NaClBitcodeRecordList &RecordList, |
| 126 std::unique_ptr<MemoryBuffer> InputBuffer) { |
| 127 if (InputBuffer->getBufferSize() % 4 != 0) |
| 128 report_fatal_error( |
| 129 "Bitcode stream must be a multiple of 4 bytes in length"); |
| 130 |
| 131 const unsigned char *BufPtr = |
| 132 (const unsigned char *) InputBuffer->getBufferStart(); |
| 133 const unsigned char *EndBufPtr = BufPtr + InputBuffer->getBufferSize(); |
| 134 const unsigned char *HeaderPtr = BufPtr; |
| 135 |
| 136 // Read header and verify it is good. |
| 137 NaClBitcodeHeader Header; |
| 138 if (Header.Read(HeaderPtr, EndBufPtr) || !Header.IsSupported()) |
| 139 report_fatal_error("Invalid PNaCl bitcode header.\n"); |
| 140 |
| 141 NaClBitstreamReader Reader(BufPtr, EndBufPtr, Header.getHeaderSize()); |
| 142 NaClBitstreamCursor Cursor(Reader); |
| 143 |
| 144 // Parse the bitcode buffer. |
| 145 BitcodeParser Parser(Cursor, RecordList); |
| 146 |
| 147 while (!Cursor.AtEndOfStream()) { |
| 148 if (Parser.Parse()) |
| 149 report_fatal_error("Malformed records founds, unable to continue"); |
| 150 } |
| 151 } |
| 152 |
| 153 |
| 154 NaClMungedBitcode::NaClMungedBitcode(std::unique_ptr<MemoryBuffer> InputBuffer) |
| 155 : BaseRecords(new NaClBitcodeRecordList()) { |
| 156 readNaClBitcodeRecordList(*BaseRecords, std::move(InputBuffer)); |
| 157 } |
OLD | NEW |