| Index: lib/Bitcode/Reader/BitcodeReader.cpp
|
| diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp
|
| index 5aa6373dbb3473a5217820302f9827f8ec402fbf..5726d3b0aad1340976404b22323846309addbae6 100644
|
| --- a/lib/Bitcode/Reader/BitcodeReader.cpp
|
| +++ b/lib/Bitcode/Reader/BitcodeReader.cpp
|
| @@ -13,6 +13,7 @@
|
|
|
| #include "llvm/Bitcode/ReaderWriter.h"
|
| #include "BitcodeReader.h"
|
| +#include "llvm/Bitcode/BitcodeStream.h"
|
| #include "llvm/Constants.h"
|
| #include "llvm/DerivedTypes.h"
|
| #include "llvm/InlineAsm.h"
|
| @@ -1836,25 +1837,8 @@ bool BitcodeReader::ParseModule() {
|
|
|
| bool BitcodeReader::ParseBitcodeInto(Module *M) {
|
| TheModule = 0;
|
| -
|
| - unsigned char *BufPtr = (unsigned char *)Buffer->getBufferStart();
|
| - unsigned char *BufEnd = BufPtr+Buffer->getBufferSize();
|
| -
|
| - if (Buffer->getBufferSize() & 3) {
|
| - if (!isRawBitcode(BufPtr, BufEnd) && !isBitcodeWrapper(BufPtr, BufEnd))
|
| - return Error("Invalid bitcode signature");
|
| - else
|
| - return Error("Bitcode stream should be a multiple of 4 bytes in length");
|
| - }
|
| -
|
| - // 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, BufEnd))
|
| - if (SkipBitcodeWrapperHeader(BufPtr, BufEnd))
|
| - return Error("Invalid bitcode wrapper header");
|
| -
|
| - StreamFile.init(BufPtr, BufEnd);
|
| - Stream.init(StreamFile);
|
| + bool err;
|
| + if ((err = InitStream())) return err;
|
|
|
| // Sniff for the signature.
|
| if (Stream.Read(8) != 'B' ||
|
| @@ -1965,20 +1949,8 @@ bool BitcodeReader::ParseModuleTriple(std::string &Triple) {
|
| }
|
|
|
| bool BitcodeReader::ParseTriple(std::string &Triple) {
|
| - if (Buffer->getBufferSize() & 3)
|
| - return Error("Bitcode stream should be a multiple of 4 bytes in length");
|
| -
|
| - unsigned char *BufPtr = (unsigned char *)Buffer->getBufferStart();
|
| - unsigned char *BufEnd = BufPtr+Buffer->getBufferSize();
|
| -
|
| - // 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, BufEnd))
|
| - if (SkipBitcodeWrapperHeader(BufPtr, BufEnd))
|
| - return Error("Invalid bitcode wrapper header");
|
| -
|
| - StreamFile.init(BufPtr, BufEnd);
|
| - Stream.init(StreamFile);
|
| + bool err;
|
| + if ((err = InitStream())) return err;
|
|
|
| // Sniff for the signature.
|
| if (Stream.Read(8) != 'B' ||
|
| @@ -2961,6 +2933,54 @@ bool BitcodeReader::MaterializeModule(Module *M, std::string *ErrInfo) {
|
| return false;
|
| }
|
|
|
| +bool BitcodeReader::InitStream() {
|
| + if (StreamCallback) return InitLazyStream();
|
| + else return InitStreamFromBuffer();
|
| +}
|
| +
|
| +bool BitcodeReader::InitStreamFromBuffer() {
|
| + const unsigned char *BufPtr = (unsigned char *)Buffer->getBufferStart();
|
| + const unsigned char *BufEnd = BufPtr+Buffer->getBufferSize();
|
| +
|
| + if (Buffer->getBufferSize() & 3) {
|
| + if (!isRawBitcode(BufPtr, BufEnd) && !isBitcodeWrapper(BufPtr, BufEnd))
|
| + return Error("Invalid bitcode signature");
|
| + else
|
| + return Error("Bitcode stream should be a multiple of 4 bytes in length");
|
| + }
|
| +
|
| + // 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, BufEnd))
|
| + if (SkipBitcodeWrapperHeader(BufPtr, BufEnd, true))
|
| + return Error("Invalid bitcode wrapper header");
|
| +
|
| + StreamFile.reset(new BitstreamReader(BufPtr, BufEnd));
|
| + Stream.init(*StreamFile);
|
| +
|
| + return false;
|
| +}
|
| +
|
| +bool BitcodeReader::InitLazyStream() {
|
| + // Check and strip off the bitcode wrapper; BitstreamReader expects never to
|
| + // see it.
|
| + LazyBitstreamVector *BSV = new LazyBitstreamVector(StreamCallback);
|
| + StreamFile.reset(new BitstreamReader(BSV));
|
| + Stream.init(*StreamFile);
|
| + if (!BSV->canSkipToPos(15))
|
| + return Error("Bitcode stream must be at least 16 bytes in length");
|
| + if (!isBitcode(BSV->addressOf(0), BSV->addressOf(16))) {
|
| + return Error("Invalid bitcode signature");
|
| + }
|
| + if (isBitcodeWrapper(BSV->addressOf(0), BSV->addressOf(4))) {
|
| + const unsigned char *bitcodeStart = BSV->addressOf(0);
|
| + const unsigned char *bitcodeEnd = BSV->addressOf(16);
|
| + SkipBitcodeWrapperHeader(bitcodeStart, bitcodeEnd, false);
|
| + BSV->dropLeadingBytes(bitcodeStart - BSV->addressOf(0));
|
| + BSV->setKnownBitcodeSize(bitcodeEnd - bitcodeStart);
|
| + }
|
| + return false;
|
| +}
|
|
|
| //===----------------------------------------------------------------------===//
|
| // External interface
|
| @@ -2986,6 +3006,24 @@ Module *llvm::getLazyBitcodeModule(MemoryBuffer *Buffer,
|
| return M;
|
| }
|
|
|
| +Module *llvm::getLazyBitcodeStreamModule(const std::string& name,
|
| + StreamChunkCallback cb,
|
| + LLVMContext& Context,
|
| + std::string *ErrMsg) {
|
| + Module *M = new Module(name, Context);
|
| + BitcodeReader *R = new BitcodeReader(cb, Context);
|
| + M->setMaterializer(R);
|
| + if (R->ParseBitcodeInto(M)) {
|
| + if (ErrMsg)
|
| + *ErrMsg = R->getErrorString();
|
| +
|
| + delete M; //Also deletes R.
|
| + return 0;
|
| + }
|
| + R->setBufferOwned(false); // no buffer to delete
|
| + return M;
|
| +}
|
| +
|
| /// ParseBitcodeFile - Read the specified bitcode file, returning the module.
|
| /// If an error occurs, return null and fill in *ErrMsg if non-null.
|
| Module *llvm::ParseBitcodeFile(MemoryBuffer *Buffer, LLVMContext& Context,
|
|
|