1d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines//===-- llvm/Bitcode/ReaderWriter.h - Bitcode reader/writers ----*- C++ -*-===//
2d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines//
3d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines//                     The LLVM Compiler Infrastructure
4d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines//
5d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines// This file is distributed under the University of Illinois Open Source
6d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines// License. See LICENSE.TXT for details.
7d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines//
8d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines//===----------------------------------------------------------------------===//
9d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines//
10d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines// This header defines interfaces to read and write LLVM bitcode files/streams.
11d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines//
12d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines//===----------------------------------------------------------------------===//
13d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines
14d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines#ifndef LLVM_BITCODE_3_2_H
15d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines#define LLVM_BITCODE_3_2_H
16d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines
17d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines#include <string>
18d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines
19d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hinesnamespace llvm {
20d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  class Module;
21d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  class MemoryBuffer;
22d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  class ModulePass;
23d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  class BitstreamWriter;
24d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  class LLVMContext;
25d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  class raw_ostream;
26d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines}  // End llvm namespace
27d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines
28d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hinesnamespace llvm_3_2 {
29d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  /// getLazyBitcodeModule - Read the header of the specified bitcode buffer
30d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  /// and prepare for lazy deserialization of function bodies.  If successful,
31d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  /// this takes ownership of 'buffer' and returns a non-null pointer.  On
32d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  /// error, this returns null, *does not* take ownership of Buffer, and fills
33d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  /// in *ErrMsg with an error description if ErrMsg is non-null.
34d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  llvm::Module *getLazyBitcodeModule(llvm::MemoryBuffer *Buffer,
35d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines                               llvm::LLVMContext& Context,
36d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines                               std::string *ErrMsg = 0);
37d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines
38d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  /// getBitcodeTargetTriple - Read the header of the specified bitcode
39d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  /// buffer and extract just the triple information. If successful,
40d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  /// this returns a string and *does not* take ownership
41d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  /// of 'buffer'. On error, this returns "", and fills in *ErrMsg
42d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  /// if ErrMsg is non-null.
43d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  std::string getBitcodeTargetTriple(llvm::MemoryBuffer *Buffer,
44d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines                                     llvm::LLVMContext& Context,
45d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines                                     std::string *ErrMsg = 0);
46d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines
47d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  /// ParseBitcodeFile - Read the specified bitcode file, returning the module.
48d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  /// If an error occurs, this returns null and fills in *ErrMsg if it is
49d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  /// non-null.  This method *never* takes ownership of Buffer.
50d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  llvm::Module *ParseBitcodeFile(llvm::MemoryBuffer *Buffer, llvm::LLVMContext& Context,
51d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines                           std::string *ErrMsg = 0);
52d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines
53d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  /// WriteBitcodeToFile - Write the specified module to the specified
54d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  /// raw output stream.  For streams where it matters, the given stream
55d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  /// should be in "binary" mode.
56d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  void WriteBitcodeToFile(const llvm::Module *M, llvm::raw_ostream &Out);
57d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines
58d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  /// createBitcodeWriterPass - Create and return a pass that writes the module
59d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  /// to the specified ostream.
60d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  llvm::ModulePass *createBitcodeWriterPass(llvm::raw_ostream &Str);
61d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines
62d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines
63d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  /// isBitcodeWrapper - Return true if the given bytes are the magic bytes
64d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  /// for an LLVM IR bitcode wrapper.
65d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  ///
66d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  static inline bool isBitcodeWrapper(const unsigned char *BufPtr,
67d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines                                      const unsigned char *BufEnd) {
68d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines    // See if you can find the hidden message in the magic bytes :-).
69d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines    // (Hint: it's a little-endian encoding.)
70d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines    return BufPtr != BufEnd &&
71d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines           BufPtr[0] == 0xDE &&
72d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines           BufPtr[1] == 0xC0 &&
73d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines           BufPtr[2] == 0x17 &&
74d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines           BufPtr[3] == 0x0B;
75d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  }
76d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines
77d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  /// isRawBitcode - Return true if the given bytes are the magic bytes for
78d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  /// raw LLVM IR bitcode (without a wrapper).
79d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  ///
80d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  static inline bool isRawBitcode(const unsigned char *BufPtr,
81d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines                                  const unsigned char *BufEnd) {
82d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines    // These bytes sort of have a hidden message, but it's not in
83d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines    // little-endian this time, and it's a little redundant.
84d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines    return BufPtr != BufEnd &&
85d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines           BufPtr[0] == 'B' &&
86d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines           BufPtr[1] == 'C' &&
87d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines           BufPtr[2] == 0xc0 &&
88d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines           BufPtr[3] == 0xde;
89d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  }
90d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines
91d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  /// isBitcode - Return true if the given bytes are the magic bytes for
92d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  /// LLVM IR bitcode, either with or without a wrapper.
93d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  ///
94d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  static bool inline isBitcode(const unsigned char *BufPtr,
95d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines                               const unsigned char *BufEnd) {
96d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines    return isBitcodeWrapper(BufPtr, BufEnd) ||
97d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines           isRawBitcode(BufPtr, BufEnd);
98d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  }
99d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines
100d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  /// SkipBitcodeWrapperHeader - Some systems wrap bc files with a special
101d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  /// header for padding or other reasons.  The format of this header is:
102d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  ///
103d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  /// struct bc_header {
104d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  ///   uint32_t Magic;         // 0x0B17C0DE
105d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  ///   uint32_t Version;       // Version, currently always 0.
106d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  ///   uint32_t BitcodeOffset; // Offset to traditional bitcode file.
107d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  ///   uint32_t BitcodeSize;   // Size of traditional bitcode file.
108d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  ///   ... potentially other gunk ...
109d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  /// };
110d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  ///
111d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  /// This function is called when we find a file with a matching magic number.
112d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  /// In this case, skip down to the subsection of the file that is actually a
113d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  /// BC file.
114d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  static inline bool SkipBitcodeWrapperHeader(unsigned char *&BufPtr,
115d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines                                              unsigned char *&BufEnd) {
116d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines    enum {
117d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines      KnownHeaderSize = 4*4,  // Size of header we read.
118d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines      OffsetField = 2*4,      // Offset in bytes to Offset field.
119d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines      SizeField = 3*4         // Offset in bytes to Size field.
120d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines    };
121d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines
122d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines    // Must contain the header!
123d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines    if (BufEnd-BufPtr < KnownHeaderSize) return true;
124d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines
125d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines    unsigned Offset = ( BufPtr[OffsetField  ]        |
126d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines                       (BufPtr[OffsetField+1] << 8)  |
127d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines                       (BufPtr[OffsetField+2] << 16) |
128d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines                       (BufPtr[OffsetField+3] << 24));
129d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines    unsigned Size   = ( BufPtr[SizeField    ]        |
130d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines                       (BufPtr[SizeField  +1] << 8)  |
131d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines                       (BufPtr[SizeField  +2] << 16) |
132d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines                       (BufPtr[SizeField  +3] << 24));
133d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines
134d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines    // Verify that Offset+Size fits in the file.
135d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines    if (Offset+Size > unsigned(BufEnd-BufPtr))
136d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines      return true;
137d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines    BufPtr += Offset;
138d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines    BufEnd = BufPtr+Size;
139d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines    return false;
140d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines  }
141d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines}  // End llvm_3_2 namespace
142d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines
143d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines#endif
144