From 1c8c365de2ac59198e6ef9d61a5557b846ce0bca Mon Sep 17 00:00:00 2001 From: Christian Sigg Date: Sun, 17 Sep 2023 13:46:01 +0200 Subject: [mlir][bytecode] Check that bytecode source buffer is sufficiently aligned. (#66380) Before this change, the `ByteCode` test failed on CentOS 7 with devtoolset-9, because strings happen to be only 8 byte aligned. In general though, strings have no alignment guarantee. Increase resource alignment in test to 32 bytes. Adjust test to sufficiently align buffer. Add test to check error when buffer is insufficiently aligned. --- mlir/lib/Bytecode/Reader/BytecodeReader.cpp | 33 +++++++++++++++++++---------- 1 file changed, 22 insertions(+), 11 deletions(-) (limited to 'mlir/lib/Bytecode/Reader/BytecodeReader.cpp') diff --git a/mlir/lib/Bytecode/Reader/BytecodeReader.cpp b/mlir/lib/Bytecode/Reader/BytecodeReader.cpp index 483cbfd..98a080d 100644 --- a/mlir/lib/Bytecode/Reader/BytecodeReader.cpp +++ b/mlir/lib/Bytecode/Reader/BytecodeReader.cpp @@ -11,7 +11,6 @@ #include "mlir/Bytecode/BytecodeImplementation.h" #include "mlir/Bytecode/BytecodeOpInterface.h" #include "mlir/Bytecode/Encoding.h" -#include "mlir/IR/BuiltinDialect.h" #include "mlir/IR/BuiltinOps.h" #include "mlir/IR/Diagnostics.h" #include "mlir/IR/OpImplementation.h" @@ -20,15 +19,13 @@ #include "mlir/Support/LLVM.h" #include "mlir/Support/LogicalResult.h" #include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/MapVector.h" #include "llvm/ADT/ScopeExit.h" -#include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Endian.h" #include "llvm/Support/MemoryBufferRef.h" -#include "llvm/Support/SaveAndRestore.h" #include "llvm/Support/SourceMgr.h" + #include #include #include @@ -93,25 +90,36 @@ namespace { class EncodingReader { public: explicit EncodingReader(ArrayRef contents, Location fileLoc) - : dataIt(contents.data()), dataEnd(contents.end()), fileLoc(fileLoc) {} + : buffer(contents), dataIt(buffer.begin()), fileLoc(fileLoc) {} explicit EncodingReader(StringRef contents, Location fileLoc) : EncodingReader({reinterpret_cast(contents.data()), contents.size()}, fileLoc) {} /// Returns true if the entire section has been read. - bool empty() const { return dataIt == dataEnd; } + bool empty() const { return dataIt == buffer.end(); } /// Returns the remaining size of the bytecode. - size_t size() const { return dataEnd - dataIt; } + size_t size() const { return buffer.end() - dataIt; } /// Align the current reader position to the specified alignment. LogicalResult alignTo(unsigned alignment) { if (!llvm::isPowerOf2_32(alignment)) return emitError("expected alignment to be a power-of-two"); + auto isUnaligned = [&](const uint8_t *ptr) { + return ((uintptr_t)ptr & (alignment - 1)) != 0; + }; + + // Ensure the data buffer was sufficiently aligned in the first place. + if (LLVM_UNLIKELY(isUnaligned(buffer.begin()))) { + return emitError("expected bytecode buffer to be aligned to ", alignment, + ", but got pointer: '0x" + + llvm::utohexstr((uintptr_t)buffer.begin()) + "'"); + } + // Shift the reader position to the next alignment boundary. - while (uintptr_t(dataIt) & (uintptr_t(alignment) - 1)) { + while (isUnaligned(dataIt)) { uint8_t padding; if (failed(parseByte(padding))) return failure(); @@ -123,7 +131,7 @@ public: // Ensure the data iterator is now aligned. This case is unlikely because we // *just* went through the effort to align the data iterator. - if (LLVM_UNLIKELY(!llvm::isAddrAligned(llvm::Align(alignment), dataIt))) { + if (LLVM_UNLIKELY(isUnaligned(dataIt))) { return emitError("expected data iterator aligned to ", alignment, ", but got pointer: '0x" + llvm::utohexstr((uintptr_t)dataIt) + "'"); @@ -320,8 +328,11 @@ private: return success(); } - /// The current data iterator, and an iterator to the end of the buffer. - const uint8_t *dataIt, *dataEnd; + /// The bytecode buffer. + ArrayRef buffer; + + /// The current iterator within the 'buffer'. + const uint8_t *dataIt; /// A location for the bytecode used to report errors. Location fileLoc; -- cgit v1.1