Index: llvm/trunk/include/llvm/Bitcode/ReaderWriter.h =================================================================== --- llvm/trunk/include/llvm/Bitcode/ReaderWriter.h +++ llvm/trunk/include/llvm/Bitcode/ReaderWriter.h @@ -30,6 +30,14 @@ class ModulePass; class raw_ostream; + /// Offsets of the 32-bit fields of bitcode wrapper header. + static const unsigned BWH_MagicField = 0*4; + static const unsigned BWH_VersionField = 1*4; + static const unsigned BWH_OffsetField = 2*4; + static const unsigned BWH_SizeField = 3*4; + static const unsigned BWH_CPUTypeField = 4*4; + static const unsigned BWH_HeaderSize = 5*4; + /// Read the header of the specified bitcode buffer and prepare for lazy /// deserialization of function bodies. If ShouldLazyLoadMetadata is true, /// lazily load metadata as well. If successful, this moves Buffer. On @@ -163,17 +171,12 @@ inline bool SkipBitcodeWrapperHeader(const unsigned char *&BufPtr, const unsigned char *&BufEnd, bool VerifyBufferSize) { - enum { - KnownHeaderSize = 4*4, // Size of header we read. - OffsetField = 2*4, // Offset in bytes to Offset field. - SizeField = 3*4 // Offset in bytes to Size field. - }; - - // Must contain the header! - if (BufEnd-BufPtr < KnownHeaderSize) return true; + // Must contain the offset and size field! + if (BufEnd - BufPtr < BWH_SizeField + 4) + return true; - unsigned Offset = support::endian::read32le(&BufPtr[OffsetField]); - unsigned Size = support::endian::read32le(&BufPtr[SizeField]); + unsigned Offset = support::endian::read32le(&BufPtr[BWH_OffsetField]); + unsigned Size = support::endian::read32le(&BufPtr[BWH_SizeField]); // Verify that Offset+Size fits in the file. if (VerifyBufferSize && Offset+Size > unsigned(BufEnd-BufPtr)) Index: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp =================================================================== --- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp +++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -2966,10 +2966,6 @@ /// uint32_t CPUType; // CPU specifier. /// ... potentially more later ... /// }; -enum { - DarwinBCSizeFieldOffset = 3*4, // Offset to bitcode_size. - DarwinBCHeaderSize = 5*4 -}; static void WriteInt32ToBuffer(uint32_t Value, SmallVectorImpl &Buffer, uint32_t &Position) { @@ -3005,10 +3001,10 @@ CPUType = DARWIN_CPU_TYPE_ARM; // Traditional Bitcode starts after header. - assert(Buffer.size() >= DarwinBCHeaderSize && + assert(Buffer.size() >= BWH_HeaderSize && "Expected header size to be reserved"); - unsigned BCOffset = DarwinBCHeaderSize; - unsigned BCSize = Buffer.size()-DarwinBCHeaderSize; + unsigned BCOffset = BWH_HeaderSize; + unsigned BCSize = Buffer.size() - BWH_HeaderSize; // Write the magic and version. unsigned Position = 0; @@ -3046,7 +3042,7 @@ // header. Triple TT(M->getTargetTriple()); if (TT.isOSDarwin() || TT.isOSBinFormatMachO()) - Buffer.insert(Buffer.begin(), DarwinBCHeaderSize, 0); + Buffer.insert(Buffer.begin(), BWH_HeaderSize, 0); // Emit the module into the buffer. { Index: llvm/trunk/test/Bitcode/bitcode-wrapper-header-armv7m.ll =================================================================== --- llvm/trunk/test/Bitcode/bitcode-wrapper-header-armv7m.ll +++ llvm/trunk/test/Bitcode/bitcode-wrapper-header-armv7m.ll @@ -0,0 +1,5 @@ +; RUN: llvm-as < %s | llvm-bcanalyzer -dump | FileCheck %s + +target triple = "thumbv7m-apple-unknown-macho" + +; CHECK: Index: llvm/trunk/test/Bitcode/bitcode-wrapper-header-x86_64.ll =================================================================== --- llvm/trunk/test/Bitcode/bitcode-wrapper-header-x86_64.ll +++ llvm/trunk/test/Bitcode/bitcode-wrapper-header-x86_64.ll @@ -0,0 +1,5 @@ +; RUN: llvm-as < %s | llvm-bcanalyzer -dump | FileCheck %s + +target triple = "x86_64-apple-macosx10.11.0" + +; CHECK: Index: llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp =================================================================== --- llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp +++ llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp @@ -600,9 +600,28 @@ // If we have a wrapper header, parse it and ignore the non-bc file contents. // The magic number is 0x0B17C0DE stored in little endian. - if (isBitcodeWrapper(BufPtr, EndBufPtr)) + if (isBitcodeWrapper(BufPtr, EndBufPtr)) { + if (EndBufPtr - BufPtr < BWH_HeaderSize) + return Error("Invalid bitcode wrapper header"); + + if (Dump) { + unsigned Magic = support::endian::read32le(&BufPtr[BWH_MagicField]); + unsigned Version = support::endian::read32le(&BufPtr[BWH_VersionField]); + unsigned Offset = support::endian::read32le(&BufPtr[BWH_OffsetField]); + unsigned Size = support::endian::read32le(&BufPtr[BWH_SizeField]); + unsigned CPUType = support::endian::read32le(&BufPtr[BWH_CPUTypeField]); + + outs() << "\n"; + } + if (SkipBitcodeWrapperHeader(BufPtr, EndBufPtr, true)) return Error("Invalid bitcode wrapper header"); + } StreamFile = BitstreamReader(BufPtr, EndBufPtr); Stream = BitstreamCursor(StreamFile);