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

Unified 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, 10 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « include/llvm/Bitcode/NaCl/NaClBitcodeParser.h ('k') | include/llvm/Bitcode/NaCl/NaClObjDumpStream.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: include/llvm/Bitcode/NaCl/NaClBitstreamReader.h
diff --git a/include/llvm/Bitcode/NaCl/NaClBitstreamReader.h b/include/llvm/Bitcode/NaCl/NaClBitstreamReader.h
index dd53fd041db0a648068125fc3bd875f87a333835..4aa827d3d7c8716c5de71a57d03974b837af60ff 100644
--- a/include/llvm/Bitcode/NaCl/NaClBitstreamReader.h
+++ b/include/llvm/Bitcode/NaCl/NaClBitstreamReader.h
@@ -88,6 +88,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
//===--------------------------------------------------------------------===//
@@ -201,9 +206,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;
// The size of the bitcode. 0 if we don't know it yet.
size_t Size;
@@ -242,9 +268,12 @@ class NaClBitstreamCursor {
NaClBitstreamCursor &operator=(const NaClBitstreamCursor &) LLVM_DELETED_FUNCTION;
public:
- NaClBitstreamCursor() { init(nullptr); }
+ 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();
@@ -260,6 +289,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 canSkipToPos(size_t pos) const {
// pos can be skipped to if it is a valid address or one byte past the end.
return pos == 0 || BitStream->getBitcodeBytes().isValidAddress(
@@ -290,6 +326,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 {
/// If this flag is used, the advance() method does not automatically pop
@@ -347,7 +390,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;
@@ -540,6 +584,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
@@ -558,12 +605,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:
/// 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];
}
« 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