| Index: include/llvm/Bitcode/NaCl/NaClBitstreamReader.h
|
| diff --git a/include/llvm/Bitcode/NaCl/NaClBitstreamReader.h b/include/llvm/Bitcode/NaCl/NaClBitstreamReader.h
|
| index 97e216441939906f33f1c2d1f48585005bf51e8f..25a6cd527692f1ffa111eed8ca88c4d490013d24 100644
|
| --- a/include/llvm/Bitcode/NaCl/NaClBitstreamReader.h
|
| +++ b/include/llvm/Bitcode/NaCl/NaClBitstreamReader.h
|
| @@ -90,6 +90,11 @@ public:
|
| return InitialAddress;
|
| }
|
|
|
| + /// Returns the Bit as a Byte:BitInByte string. MinByteWidth is the
|
| + /// minimum number of characters to print out the Byte value (blank
|
| + /// fills).
|
| + static std::string getBitAddress(uint64_t Bit, unsigned MinByteWidth=1);
|
| +
|
| //===--------------------------------------------------------------------===//
|
| // Block Manipulation
|
| //===--------------------------------------------------------------------===//
|
| @@ -209,9 +214,30 @@ public:
|
| /// Unlike iterators, NaClBitstreamCursors are heavy-weight objects
|
| /// that should not be passed by value.
|
| class NaClBitstreamCursor {
|
| +public:
|
| + /// This class handles errors in the bitstream reader. Redirects
|
| + /// fatal error messages to virtual method Fatal.
|
| + class ErrorHandler {
|
| + ErrorHandler(const ErrorHandler &) = delete;
|
| + ErrorHandler &operator=(const ErrorHandler &) = delete;
|
| + public:
|
| + explicit ErrorHandler(NaClBitstreamCursor &Cursor) : Cursor(Cursor) {}
|
| + LLVM_ATTRIBUTE_NORETURN
|
| + virtual void Fatal(const std::string &ErrorMessage) const;
|
| + virtual ~ErrorHandler() {}
|
| + uint64_t getCurrentBitNo() const {
|
| + return Cursor.GetCurrentBitNo();
|
| + }
|
| + private:
|
| + NaClBitstreamCursor &Cursor;
|
| + };
|
| +
|
| +private:
|
| friend class Deserializer;
|
| NaClBitstreamReader *BitStream;
|
| size_t NextChar;
|
| + // The current error handler for the bitstream reader.
|
| + std::unique_ptr<ErrorHandler> ErrHandler;
|
|
|
| /// CurWord/word_t - This is the current data we have pulled from the stream
|
| /// but have not returned to the client. This is specifically and
|
| @@ -248,11 +274,12 @@ class NaClBitstreamCursor {
|
|
|
| public:
|
|
|
| - NaClBitstreamCursor() {
|
| + NaClBitstreamCursor() : ErrHandler(new ErrorHandler(*this)) {
|
| init(nullptr);
|
| }
|
|
|
| - explicit NaClBitstreamCursor(NaClBitstreamReader &R) { init(&R); }
|
| + explicit NaClBitstreamCursor(NaClBitstreamReader &R)
|
| + : ErrHandler(new ErrorHandler(*this)) { init(&R); }
|
|
|
| void init(NaClBitstreamReader *R) {
|
| freeState();
|
| @@ -268,6 +295,13 @@ public:
|
|
|
| void freeState();
|
|
|
| + // Replaces the current bitstream error handler with the new
|
| + // handler. Takes ownership of the new handler and deletes it when
|
| + // it is no longer needed.
|
| + void setErrorHandler(std::unique_ptr<ErrorHandler> &NewHandler) {
|
| + ErrHandler = std::move(NewHandler);
|
| + }
|
| +
|
| bool isEndPos(size_t pos) {
|
| return BitStream->getBitcodeBytes().isObjectEnd(static_cast<uint64_t>(pos));
|
| }
|
| @@ -297,6 +331,13 @@ public:
|
| return BitStream;
|
| }
|
|
|
| + /// Returns the current bit address (string) of the bit cursor.
|
| + /// MinByteWidth is the minimum number of characters to print out
|
| + /// the Byte value (blank fills).
|
| + std::string getCurrentBitAddress(unsigned MinByteWidth=1) const {
|
| + return BitStream->getBitAddress(GetCurrentBitNo(), MinByteWidth);
|
| + }
|
| +
|
| /// Flags that modify the behavior of advance().
|
| enum {
|
| /// AF_DontPopBlockAtEnd - If this flag is used, the advance() method does
|
| @@ -355,7 +396,8 @@ public:
|
| void JumpToBit(uint64_t BitNo) {
|
| uintptr_t ByteNo = uintptr_t(BitNo/8) & ~(sizeof(word_t)-1);
|
| unsigned WordBitNo = unsigned(BitNo & (sizeof(word_t)*8-1));
|
| - assert(canSkipToPos(ByteNo) && "Invalid location");
|
| + if (!canSkipToPos(ByteNo))
|
| + reportInvalidJumpToBit(BitNo);
|
|
|
| // Move the cursor to the right word.
|
| NextChar = ByteNo;
|
| @@ -553,6 +595,9 @@ private:
|
| //===--------------------------------------------------------------------===//
|
|
|
| private:
|
| + // Returns abbreviation encoding associated with Value.
|
| + NaClBitCodeAbbrevOp::Encoding getEncoding(uint64_t Value);
|
| +
|
| void skipAbbreviatedField(const NaClBitCodeAbbrevOp &Op);
|
|
|
| // Reads the next Value using the abbreviation Op. Returns true only
|
| @@ -571,12 +616,19 @@ private:
|
| unsigned NumArrayElements,
|
| SmallVectorImpl<uint64_t> &Vals);
|
|
|
| + // Reports that that abbreviation Index is not valid.
|
| + void reportInvalidAbbrevNumber(unsigned Index) const;
|
| +
|
| + // Reports that jumping to Bit is not valid.
|
| + void reportInvalidJumpToBit(uint64_t Bit) const;
|
| +
|
| public:
|
|
|
| /// getAbbrev - Return the abbreviation for the specified AbbrevId.
|
| const NaClBitCodeAbbrev *getAbbrev(unsigned AbbrevID) const {
|
| unsigned AbbrevNo = AbbrevID-naclbitc::FIRST_APPLICATION_ABBREV;
|
| - assert(AbbrevNo < CurAbbrevs.size() && "Invalid abbrev #!");
|
| + if (AbbrevNo >= CurAbbrevs.size())
|
| + reportInvalidAbbrevNumber(AbbrevID);
|
| return CurAbbrevs[AbbrevNo];
|
| }
|
|
|
|
|