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

Side by Side Diff: include/llvm/Bitcode/NaCl/NaClBitstreamReader.h

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 //===- NaClBitstreamReader.h -----------------------------------*- C++ -*-===// 1 //===- NaClBitstreamReader.h -----------------------------------*- C++ -*-===//
2 // Low-level bitstream reader interface 2 // Low-level bitstream reader interface
3 // 3 //
4 // The LLVM Compiler Infrastructure 4 // The LLVM Compiler Infrastructure
5 // 5 //
6 // This file is distributed under the University of Illinois Open Source 6 // This file is distributed under the University of Illinois Open Source
7 // License. See LICENSE.TXT for details. 7 // License. See LICENSE.TXT for details.
8 // 8 //
9 //===----------------------------------------------------------------------===// 9 //===----------------------------------------------------------------------===//
10 // 10 //
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
81 Info.Abbrevs[i]->dropRef(); 81 Info.Abbrevs[i]->dropRef();
82 BlockInfoRecords.pop_back(); 82 BlockInfoRecords.pop_back();
83 } 83 }
84 } 84 }
85 85
86 /// \brief Returns the initial address (after the header) of the input stream. 86 /// \brief Returns the initial address (after the header) of the input stream.
87 size_t getInitialAddress() const { 87 size_t getInitialAddress() const {
88 return InitialAddress; 88 return InitialAddress;
89 } 89 }
90 90
91 /// Returns the Bit as a Byte:BitInByte string. MinByteWidth is the
92 /// minimum number of characters to print out the Byte value (blank
93 /// fills).
94 static std::string getBitAddress(uint64_t Bit, unsigned MinByteWidth=1);
95
91 //===--------------------------------------------------------------------===// 96 //===--------------------------------------------------------------------===//
92 // Block Manipulation 97 // Block Manipulation
93 //===--------------------------------------------------------------------===// 98 //===--------------------------------------------------------------------===//
94 99
95 /// Return true if we've already read and processed the block info block for 100 /// Return true if we've already read and processed the block info block for
96 /// this Bitstream. We only process it for the first cursor that walks over 101 /// this Bitstream. We only process it for the first cursor that walks over
97 /// it. 102 /// it.
98 bool hasBlockInfoRecords() const { return !BlockInfoRecords.empty(); } 103 bool hasBlockInfoRecords() const { return !BlockInfoRecords.empty(); }
99 104
100 /// If there is block info for the specified ID, return it, otherwise return 105 /// If there is block info for the specified ID, return it, otherwise return
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 uint64_t StartBit; 199 uint64_t StartBit;
195 }; 200 };
196 201
197 /// This represents a position within a bitcode file. There may be multiple 202 /// This represents a position within a bitcode file. There may be multiple
198 /// independent cursors reading within one bitstream, each maintaining their 203 /// independent cursors reading within one bitstream, each maintaining their
199 /// own local state. 204 /// own local state.
200 /// 205 ///
201 /// Unlike iterators, NaClBitstreamCursors are heavy-weight objects 206 /// Unlike iterators, NaClBitstreamCursors are heavy-weight objects
202 /// that should not be passed by value. 207 /// that should not be passed by value.
203 class NaClBitstreamCursor { 208 class NaClBitstreamCursor {
209 public:
210 /// This class handles errors in the bitstream reader. Redirects
211 /// fatal error messages to virtual method Fatal.
212 class ErrorHandler {
213 ErrorHandler(const ErrorHandler &) = delete;
214 ErrorHandler &operator=(const ErrorHandler &) = delete;
215 public:
216 explicit ErrorHandler(NaClBitstreamCursor &Cursor) : Cursor(Cursor) {}
217 LLVM_ATTRIBUTE_NORETURN
218 virtual void Fatal(const std::string &ErrorMessage) const;
219 virtual ~ErrorHandler() {}
220 uint64_t getCurrentBitNo() const {
221 return Cursor.GetCurrentBitNo();
222 }
223 private:
224 NaClBitstreamCursor &Cursor;
225 };
226
227 private:
204 friend class Deserializer; 228 friend class Deserializer;
205 NaClBitstreamReader *BitStream; 229 NaClBitstreamReader *BitStream;
206 size_t NextChar; 230 size_t NextChar;
231 // The current error handler for the bitstream reader.
232 std::unique_ptr<ErrorHandler> ErrHandler;
207 233
208 // The size of the bitcode. 0 if we don't know it yet. 234 // The size of the bitcode. 0 if we don't know it yet.
209 size_t Size; 235 size_t Size;
210 236
211 /// This is the current data we have pulled from the stream but have not 237 /// This is the current data we have pulled from the stream but have not
212 /// returned to the client. This is specifically and intentionally defined to 238 /// returned to the client. This is specifically and intentionally defined to
213 /// follow the word size of the host machine for efficiency. We use word_t in 239 /// follow the word size of the host machine for efficiency. We use word_t in
214 /// places that are aware of this to make it perfectly explicit what is going 240 /// places that are aware of this to make it perfectly explicit what is going
215 /// on. 241 /// on.
216 typedef size_t word_t; 242 typedef size_t word_t;
(...skipping 18 matching lines...) Expand all
235 : PrevCodeSize(PCS) {} 261 : PrevCodeSize(PCS) {}
236 }; 262 };
237 263
238 /// This tracks the codesize of parent blocks. 264 /// This tracks the codesize of parent blocks.
239 SmallVector<Block, 8> BlockScope; 265 SmallVector<Block, 8> BlockScope;
240 266
241 NaClBitstreamCursor(const NaClBitstreamCursor &) LLVM_DELETED_FUNCTION; 267 NaClBitstreamCursor(const NaClBitstreamCursor &) LLVM_DELETED_FUNCTION;
242 NaClBitstreamCursor &operator=(const NaClBitstreamCursor &) LLVM_DELETED_FUNCT ION; 268 NaClBitstreamCursor &operator=(const NaClBitstreamCursor &) LLVM_DELETED_FUNCT ION;
243 269
244 public: 270 public:
245 NaClBitstreamCursor() { init(nullptr); } 271 NaClBitstreamCursor() : ErrHandler(new ErrorHandler(*this)) {
272 init(nullptr);
273 }
246 274
247 explicit NaClBitstreamCursor(NaClBitstreamReader &R) { init(&R); } 275 explicit NaClBitstreamCursor(NaClBitstreamReader &R)
276 : ErrHandler(new ErrorHandler(*this)) { init(&R); }
248 277
249 void init(NaClBitstreamReader *R) { 278 void init(NaClBitstreamReader *R) {
250 freeState(); 279 freeState();
251 BitStream = R; 280 BitStream = R;
252 NextChar = (BitStream == nullptr) ? 0 : BitStream->getInitialAddress(); 281 NextChar = (BitStream == nullptr) ? 0 : BitStream->getInitialAddress();
253 Size = 0; 282 Size = 0;
254 BitsInCurWord = 0; 283 BitsInCurWord = 0;
255 } 284 }
256 285
257 ~NaClBitstreamCursor() { 286 ~NaClBitstreamCursor() {
258 freeState(); 287 freeState();
259 } 288 }
260 289
261 void freeState(); 290 void freeState();
262 291
292 // Replaces the current bitstream error handler with the new
293 // handler. Takes ownership of the new handler and deletes it when
294 // it is no longer needed.
295 void setErrorHandler(std::unique_ptr<ErrorHandler> &NewHandler) {
296 ErrHandler = std::move(NewHandler);
297 }
298
263 bool canSkipToPos(size_t pos) const { 299 bool canSkipToPos(size_t pos) const {
264 // pos can be skipped to if it is a valid address or one byte past the end. 300 // pos can be skipped to if it is a valid address or one byte past the end.
265 return pos == 0 || BitStream->getBitcodeBytes().isValidAddress( 301 return pos == 0 || BitStream->getBitcodeBytes().isValidAddress(
266 static_cast<uint64_t>(pos - 1)); 302 static_cast<uint64_t>(pos - 1));
267 } 303 }
268 304
269 bool AtEndOfStream() { 305 bool AtEndOfStream() {
270 if (BitsInCurWord != 0) 306 if (BitsInCurWord != 0)
271 return false; 307 return false;
272 if (Size != 0) 308 if (Size != 0)
(...skipping 10 matching lines...) Expand all
283 return NextChar*CHAR_BIT - BitsInCurWord; 319 return NextChar*CHAR_BIT - BitsInCurWord;
284 } 320 }
285 321
286 NaClBitstreamReader *getBitStreamReader() { 322 NaClBitstreamReader *getBitStreamReader() {
287 return BitStream; 323 return BitStream;
288 } 324 }
289 const NaClBitstreamReader *getBitStreamReader() const { 325 const NaClBitstreamReader *getBitStreamReader() const {
290 return BitStream; 326 return BitStream;
291 } 327 }
292 328
329 /// Returns the current bit address (string) of the bit cursor.
330 /// MinByteWidth is the minimum number of characters to print out
331 /// the Byte value (blank fills).
332 std::string getCurrentBitAddress(unsigned MinByteWidth=1) const {
333 return BitStream->getBitAddress(GetCurrentBitNo(), MinByteWidth);
334 }
335
293 /// Flags that modify the behavior of advance(). 336 /// Flags that modify the behavior of advance().
294 enum { 337 enum {
295 /// If this flag is used, the advance() method does not automatically pop 338 /// If this flag is used, the advance() method does not automatically pop
296 /// the block scope when the end of a block is reached. 339 /// the block scope when the end of a block is reached.
297 AF_DontPopBlockAtEnd = 1, 340 AF_DontPopBlockAtEnd = 1,
298 341
299 /// If this flag is used, abbrev entries are returned just like normal 342 /// If this flag is used, abbrev entries are returned just like normal
300 /// records. 343 /// records.
301 AF_DontAutoprocessAbbrevs = 2 344 AF_DontAutoprocessAbbrevs = 2
302 }; 345 };
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 // If we found a sub-block, just skip over it and check the next entry. 383 // If we found a sub-block, just skip over it and check the next entry.
341 if (SkipBlock()) 384 if (SkipBlock())
342 return NaClBitstreamEntry::getError(); 385 return NaClBitstreamEntry::getError();
343 } 386 }
344 } 387 }
345 388
346 /// Reset the stream to the specified bit number. 389 /// Reset the stream to the specified bit number.
347 void JumpToBit(uint64_t BitNo) { 390 void JumpToBit(uint64_t BitNo) {
348 uintptr_t ByteNo = uintptr_t(BitNo/8) & ~(sizeof(word_t)-1); 391 uintptr_t ByteNo = uintptr_t(BitNo/8) & ~(sizeof(word_t)-1);
349 unsigned WordBitNo = unsigned(BitNo & (sizeof(word_t)*8-1)); 392 unsigned WordBitNo = unsigned(BitNo & (sizeof(word_t)*8-1));
350 assert(canSkipToPos(ByteNo) && "Invalid location"); 393 if (!canSkipToPos(ByteNo))
394 reportInvalidJumpToBit(BitNo);
351 395
352 // Move the cursor to the right word. 396 // Move the cursor to the right word.
353 NextChar = ByteNo; 397 NextChar = ByteNo;
354 BitsInCurWord = 0; 398 BitsInCurWord = 0;
355 399
356 // Skip over any bits that are already consumed. 400 // Skip over any bits that are already consumed.
357 if (WordBitNo) 401 if (WordBitNo)
358 Read(WordBitNo); 402 Read(WordBitNo);
359 } 403 }
360 404
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
533 577
534 BlockScope.back().PrevAbbrevs.swap(CurAbbrevs); 578 BlockScope.back().PrevAbbrevs.swap(CurAbbrevs);
535 BlockScope.pop_back(); 579 BlockScope.pop_back();
536 } 580 }
537 581
538 //===--------------------------------------------------------------------===// 582 //===--------------------------------------------------------------------===//
539 // Record Processing 583 // Record Processing
540 //===--------------------------------------------------------------------===// 584 //===--------------------------------------------------------------------===//
541 585
542 private: 586 private:
587 // Returns abbreviation encoding associated with Value.
588 NaClBitCodeAbbrevOp::Encoding getEncoding(uint64_t Value);
589
543 void skipAbbreviatedField(const NaClBitCodeAbbrevOp &Op); 590 void skipAbbreviatedField(const NaClBitCodeAbbrevOp &Op);
544 591
545 // Reads the next Value using the abbreviation Op. Returns true only 592 // Reads the next Value using the abbreviation Op. Returns true only
546 // if Op is an array (and sets Value to the number of elements in the 593 // if Op is an array (and sets Value to the number of elements in the
547 // array). 594 // array).
548 inline bool readRecordAbbrevField(const NaClBitCodeAbbrevOp &Op, 595 inline bool readRecordAbbrevField(const NaClBitCodeAbbrevOp &Op,
549 uint64_t &Value); 596 uint64_t &Value);
550 597
551 // Reads and returns the next value using the abbreviation Op, 598 // Reads and returns the next value using the abbreviation Op,
552 // assuming Op appears after an array abbreviation. 599 // assuming Op appears after an array abbreviation.
553 inline uint64_t readArrayAbbreviatedField(const NaClBitCodeAbbrevOp &Op); 600 inline uint64_t readArrayAbbreviatedField(const NaClBitCodeAbbrevOp &Op);
554 601
555 // Reads the array abbreviation Op, NumArrayElements times, putting 602 // Reads the array abbreviation Op, NumArrayElements times, putting
556 // the read values in Vals. 603 // the read values in Vals.
557 inline void readArrayAbbrev(const NaClBitCodeAbbrevOp &Op, 604 inline void readArrayAbbrev(const NaClBitCodeAbbrevOp &Op,
558 unsigned NumArrayElements, 605 unsigned NumArrayElements,
559 SmallVectorImpl<uint64_t> &Vals); 606 SmallVectorImpl<uint64_t> &Vals);
560 607
608 // Reports that that abbreviation Index is not valid.
609 void reportInvalidAbbrevNumber(unsigned Index) const;
610
611 // Reports that jumping to Bit is not valid.
612 void reportInvalidJumpToBit(uint64_t Bit) const;
613
561 public: 614 public:
562 615
563 /// Return the abbreviation for the specified AbbrevId. 616 /// Return the abbreviation for the specified AbbrevId.
564 const NaClBitCodeAbbrev *getAbbrev(unsigned AbbrevID) const { 617 const NaClBitCodeAbbrev *getAbbrev(unsigned AbbrevID) const {
565 unsigned AbbrevNo = AbbrevID-naclbitc::FIRST_APPLICATION_ABBREV; 618 unsigned AbbrevNo = AbbrevID-naclbitc::FIRST_APPLICATION_ABBREV;
566 assert(AbbrevNo < CurAbbrevs.size() && "Invalid abbrev #!"); 619 if (AbbrevNo >= CurAbbrevs.size())
620 reportInvalidAbbrevNumber(AbbrevID);
567 return CurAbbrevs[AbbrevNo]; 621 return CurAbbrevs[AbbrevNo];
568 } 622 }
569 623
570 /// Read the current record and discard it. 624 /// Read the current record and discard it.
571 void skipRecord(unsigned AbbrevID); 625 void skipRecord(unsigned AbbrevID);
572 626
573 unsigned readRecord(unsigned AbbrevID, SmallVectorImpl<uint64_t> &Vals); 627 unsigned readRecord(unsigned AbbrevID, SmallVectorImpl<uint64_t> &Vals);
574 628
575 //===--------------------------------------------------------------------===// 629 //===--------------------------------------------------------------------===//
576 // Abbrev Processing 630 // Abbrev Processing
577 //===--------------------------------------------------------------------===// 631 //===--------------------------------------------------------------------===//
578 // IsLocal indicates where the abbreviation occurs. If it is in the 632 // IsLocal indicates where the abbreviation occurs. If it is in the
579 // BlockInfo block, IsLocal is false. In all other cases, IsLocal is 633 // BlockInfo block, IsLocal is false. In all other cases, IsLocal is
580 // true. 634 // true.
581 void ReadAbbrevRecord(bool IsLocal, 635 void ReadAbbrevRecord(bool IsLocal,
582 NaClAbbrevListener *Listener); 636 NaClAbbrevListener *Listener);
583 637
584 // Skips over an abbreviation record. Duplicates code of ReadAbbrevRecord, 638 // Skips over an abbreviation record. Duplicates code of ReadAbbrevRecord,
585 // except that no abbreviation is built. 639 // except that no abbreviation is built.
586 void SkipAbbrevRecord(); 640 void SkipAbbrevRecord();
587 641
588 bool ReadBlockInfoBlock(NaClAbbrevListener *Listener); 642 bool ReadBlockInfoBlock(NaClAbbrevListener *Listener);
589 }; 643 };
590 644
591 } // End llvm namespace 645 } // End llvm namespace
592 646
593 #endif 647 #endif
OLDNEW
« no previous file with comments | « include/llvm/Bitcode/NaCl/NaClBitcodeParser.h ('k') | include/llvm/Bitcode/NaCl/NaClObjDumpStream.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698