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