| Index: include/llvm/Bitcode/NaCl/NaClReaderWriter.h
|
| diff --git a/include/llvm/Bitcode/NaCl/NaClReaderWriter.h b/include/llvm/Bitcode/NaCl/NaClReaderWriter.h
|
| index 2b905b97e855d426cc9894fc5798712fa11e2303..d505af0a1fb04a66b9d30ce180197d9cc65e1d53 100644
|
| --- a/include/llvm/Bitcode/NaCl/NaClReaderWriter.h
|
| +++ b/include/llvm/Bitcode/NaCl/NaClReaderWriter.h
|
| @@ -8,22 +8,142 @@
|
| //
|
| //===----------------------------------------------------------------------===//
|
| //
|
| -// This header defines interfaces to read and write LLVM bitcode files/streams.
|
| +// This header defines interfaces to read and write NaCl bitcode wire format
|
| +// files.
|
| //
|
| //===----------------------------------------------------------------------===//
|
|
|
| #ifndef LLVM_BITCODE_NACL_NACLREADERWRITER_H
|
| #define LLVM_BITCODE_NACL_NACLREADERWRITER_H
|
|
|
| +#include <string>
|
| +
|
| namespace llvm {
|
| + class MemoryBuffer;
|
| + class DataStreamer;
|
| + class LLVMContext;
|
| class Module;
|
| class raw_ostream;
|
|
|
| + /// getNaClLazyBitcodeModule - Read the header of the specified bitcode buffer
|
| + /// and prepare for lazy deserialization of function bodies. If successful,
|
| + /// this takes ownership of 'buffer' and returns a non-null pointer. On
|
| + /// error, this returns null, *does not* take ownership of Buffer, and fills
|
| + /// in *ErrMsg with an error description if ErrMsg is non-null.
|
| + Module *getNaClLazyBitcodeModule(MemoryBuffer *Buffer,
|
| + LLVMContext &Context,
|
| + std::string *ErrMsg = 0);
|
| +
|
| + /// getNaClStreamedBitcodeModule - Read the header of the specified stream
|
| + /// and prepare for lazy deserialization and streaming of function bodies.
|
| + /// On error, this returns null, and fills in *ErrMsg with an error
|
| + /// description if ErrMsg is non-null.
|
| + Module *getNaClStreamedBitcodeModule(const std::string &name,
|
| + DataStreamer *streamer,
|
| + LLVMContext &Context,
|
| + std::string *ErrMsg = 0);
|
| +
|
| + /// NaClParseBitcodeFile - Read the specified bitcode file,
|
| + /// returning the module. If an error occurs, this returns null and
|
| + /// fills in *ErrMsg if it is non-null. This method *never* takes
|
| + /// ownership of Buffer.
|
| + Module *NaClParseBitcodeFile(MemoryBuffer *Buffer, LLVMContext &Context,
|
| + std::string *ErrMsg = 0);
|
| +
|
| /// NaClWriteBitcodeToFile - Write the specified module to the
|
| /// specified raw output stream, using PNaCl wire format. For
|
| /// streams where it matters, the given stream should be in "binary"
|
| /// mode.
|
| void NaClWriteBitcodeToFile(const Module *M, raw_ostream &Out);
|
|
|
| + /// isNaClBitcodeWrapper - Return true if the given bytes are the
|
| + /// magic bytes for an LLVM IR bitcode wrapper.
|
| + ///
|
| + inline bool isNaClBitcodeWrapper(const unsigned char *BufPtr,
|
| + const unsigned char *BufEnd) {
|
| + // See if you can find the hidden message in the magic bytes :-).
|
| + // (Hint: it's a little-endian encoding.)
|
| + return BufPtr != BufEnd &&
|
| + BufPtr[0] == 0xDE &&
|
| + BufPtr[1] == 0xC0 &&
|
| + BufPtr[2] == 0x17 &&
|
| + BufPtr[3] == 0x0B;
|
| + }
|
| +
|
| + /// isNaClRawBitcode - Return true if the given bytes are the magic
|
| + /// bytes for raw LLVM IR bitcode (without a wrapper).
|
| + ///
|
| + inline bool isNaClRawBitcode(const unsigned char *BufPtr,
|
| + const unsigned char *BufEnd) {
|
| + // These bytes sort of have a hidden message, but it's not in
|
| + // little-endian this time, and it's a little redundant.
|
| + return BufPtr != BufEnd &&
|
| + BufPtr[0] == 'B' &&
|
| + BufPtr[1] == 'C' &&
|
| + BufPtr[2] == 0xc0 &&
|
| + BufPtr[3] == 0xde;
|
| + }
|
| +
|
| + /// isNaClBitcode - Return true if the given bytes are the magic bytes for
|
| + /// LLVM IR bitcode, either with or without a wrapper.
|
| + ///
|
| + inline bool isNaClBitcode(const unsigned char *BufPtr,
|
| + const unsigned char *BufEnd) {
|
| + return isNaClBitcodeWrapper(BufPtr, BufEnd) ||
|
| + isNaClRawBitcode(BufPtr, BufEnd);
|
| + }
|
| +
|
| + /// SkipNaClBitcodeWrapperHeader - Some systems wrap bc files with a
|
| + /// special header for padding or other reasons. The format of this
|
| + /// header is:
|
| + ///
|
| + /// struct bc_header {
|
| + /// uint32_t Magic; // 0x0B17C0DE
|
| + /// uint32_t Version; // Version, currently always 0.
|
| + /// uint32_t BitcodeOffset; // Offset to traditional bitcode file.
|
| + /// uint32_t BitcodeSize; // Size of traditional bitcode file.
|
| + /// ... potentially other gunk ...
|
| + /// };
|
| + ///
|
| + /// TODO(kschimpf): Consider changing Magic and/or gunk to communicate
|
| + /// file is PNaCl wire format file (rather than LLVM bitcode).
|
| + ///
|
| + /// TODO(kschimpf): Add code to read gunk in, and store it so it is
|
| + /// accessable.
|
| + ///
|
| + /// This function is called when we find a file with a matching magic number.
|
| + /// In this case, skip down to the subsection of the file that is actually a
|
| + /// BC file.
|
| + /// If 'VerifyBufferSize' is true, check that the buffer is large enough to
|
| + /// contain the whole bitcode file.
|
| + inline bool SkipNaClBitcodeWrapperHeader(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;
|
| +
|
| + unsigned Offset = ( BufPtr[OffsetField ] |
|
| + (BufPtr[OffsetField+1] << 8) |
|
| + (BufPtr[OffsetField+2] << 16) |
|
| + (BufPtr[OffsetField+3] << 24));
|
| + unsigned Size = ( BufPtr[SizeField ] |
|
| + (BufPtr[SizeField +1] << 8) |
|
| + (BufPtr[SizeField +2] << 16) |
|
| + (BufPtr[SizeField +3] << 24));
|
| +
|
| + // Verify that Offset+Size fits in the file.
|
| + if (VerifyBufferSize && Offset+Size > unsigned(BufEnd-BufPtr))
|
| + return true;
|
| + BufPtr += Offset;
|
| + BufEnd = BufPtr+Size;
|
| + return false;
|
| + }
|
| +
|
| } // end llvm namespace
|
| #endif
|
|
|