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/IR/DiagnosticInfo.h"
18#include "llvm/Support/ErrorOr.h"
19#include "llvm/Support/MemoryBuffer.h"
20#include <memory>
21#include <string>
22
23namespace llvm {
24  class BitstreamWriter;
25  class DataStreamer;
26  class LLVMContext;
27  class Module;
28  class ModulePass;
29  class raw_ostream;
30
31  /// Read the header of the specified bitcode buffer and prepare for lazy
32  /// deserialization of function bodies. If ShouldLazyLoadMetadata is true,
33  /// lazily load metadata as well. If successful, this moves Buffer. On
34  /// error, this *does not* move Buffer.
35  ErrorOr<Module *>
36  getLazyBitcodeModule(std::unique_ptr<MemoryBuffer> &&Buffer,
37                       LLVMContext &Context,
38                       DiagnosticHandlerFunction DiagnosticHandler = nullptr,
39                       bool ShouldLazyLoadMetadata = false);
40
41  /// Read the header of the specified stream and prepare for lazy
42  /// deserialization and streaming of function bodies.
43  ErrorOr<std::unique_ptr<Module>> getStreamedBitcodeModule(
44      StringRef Name, DataStreamer *Streamer, LLVMContext &Context,
45      DiagnosticHandlerFunction DiagnosticHandler = nullptr);
46
47  /// Read the header of the specified bitcode buffer and extract just the
48  /// triple information. If successful, this returns a string. On error, this
49  /// returns "".
50  std::string
51  getBitcodeTargetTriple(MemoryBufferRef Buffer, LLVMContext &Context,
52                         DiagnosticHandlerFunction DiagnosticHandler = nullptr);
53
54  /// Read the specified bitcode file, returning the module.
55  ErrorOr<Module *>
56  parseBitcodeFile(MemoryBufferRef Buffer, LLVMContext &Context,
57                   DiagnosticHandlerFunction DiagnosticHandler = nullptr);
58
59  /// \brief Write the specified module to the specified raw output stream.
60  ///
61  /// For streams where it matters, the given stream should be in "binary"
62  /// mode.
63  ///
64  /// If \c ShouldPreserveUseListOrder, encode the use-list order for each \a
65  /// Value in \c M.  These will be reconstructed exactly when \a M is
66  /// deserialized.
67  void WriteBitcodeToFile(const Module *M, raw_ostream &Out,
68                          bool ShouldPreserveUseListOrder = false);
69
70  /// isBitcodeWrapper - Return true if the given bytes are the magic bytes
71  /// for an LLVM IR bitcode wrapper.
72  ///
73  inline bool isBitcodeWrapper(const unsigned char *BufPtr,
74                               const unsigned char *BufEnd) {
75    // See if you can find the hidden message in the magic bytes :-).
76    // (Hint: it's a little-endian encoding.)
77    return BufPtr != BufEnd &&
78           BufPtr[0] == 0xDE &&
79           BufPtr[1] == 0xC0 &&
80           BufPtr[2] == 0x17 &&
81           BufPtr[3] == 0x0B;
82  }
83
84  /// isRawBitcode - Return true if the given bytes are the magic bytes for
85  /// raw LLVM IR bitcode (without a wrapper).
86  ///
87  inline bool isRawBitcode(const unsigned char *BufPtr,
88                           const unsigned char *BufEnd) {
89    // These bytes sort of have a hidden message, but it's not in
90    // little-endian this time, and it's a little redundant.
91    return BufPtr != BufEnd &&
92           BufPtr[0] == 'B' &&
93           BufPtr[1] == 'C' &&
94           BufPtr[2] == 0xc0 &&
95           BufPtr[3] == 0xde;
96  }
97
98  /// isBitcode - Return true if the given bytes are the magic bytes for
99  /// LLVM IR bitcode, either with or without a wrapper.
100  ///
101  inline bool isBitcode(const unsigned char *BufPtr,
102                        const unsigned char *BufEnd) {
103    return isBitcodeWrapper(BufPtr, BufEnd) ||
104           isRawBitcode(BufPtr, BufEnd);
105  }
106
107  /// SkipBitcodeWrapperHeader - Some systems wrap bc files with a special
108  /// header for padding or other reasons.  The format of this header is:
109  ///
110  /// struct bc_header {
111  ///   uint32_t Magic;         // 0x0B17C0DE
112  ///   uint32_t Version;       // Version, currently always 0.
113  ///   uint32_t BitcodeOffset; // Offset to traditional bitcode file.
114  ///   uint32_t BitcodeSize;   // Size of traditional bitcode file.
115  ///   ... potentially other gunk ...
116  /// };
117  ///
118  /// This function is called when we find a file with a matching magic number.
119  /// In this case, skip down to the subsection of the file that is actually a
120  /// BC file.
121  /// If 'VerifyBufferSize' is true, check that the buffer is large enough to
122  /// contain the whole bitcode file.
123  inline bool SkipBitcodeWrapperHeader(const unsigned char *&BufPtr,
124                                       const unsigned char *&BufEnd,
125                                       bool VerifyBufferSize) {
126    enum {
127      KnownHeaderSize = 4*4,  // Size of header we read.
128      OffsetField = 2*4,      // Offset in bytes to Offset field.
129      SizeField = 3*4         // Offset in bytes to Size field.
130    };
131
132    // Must contain the header!
133    if (BufEnd-BufPtr < KnownHeaderSize) return true;
134
135    unsigned Offset = ( BufPtr[OffsetField  ]        |
136                       (BufPtr[OffsetField+1] << 8)  |
137                       (BufPtr[OffsetField+2] << 16) |
138                       (BufPtr[OffsetField+3] << 24));
139    unsigned Size   = ( BufPtr[SizeField    ]        |
140                       (BufPtr[SizeField  +1] << 8)  |
141                       (BufPtr[SizeField  +2] << 16) |
142                       (BufPtr[SizeField  +3] << 24));
143
144    // Verify that Offset+Size fits in the file.
145    if (VerifyBufferSize && Offset+Size > unsigned(BufEnd-BufPtr))
146      return true;
147    BufPtr += Offset;
148    BufEnd = BufPtr+Size;
149    return false;
150  }
151
152  const std::error_category &BitcodeErrorCategory();
153  enum class BitcodeError { InvalidBitcodeSignature, CorruptedBitcode };
154  inline std::error_code make_error_code(BitcodeError E) {
155    return std::error_code(static_cast<int>(E), BitcodeErrorCategory());
156  }
157
158  class BitcodeDiagnosticInfo : public DiagnosticInfo {
159    const Twine &Msg;
160    std::error_code EC;
161
162  public:
163    BitcodeDiagnosticInfo(std::error_code EC, DiagnosticSeverity Severity,
164                          const Twine &Msg);
165    void print(DiagnosticPrinter &DP) const override;
166    std::error_code getError() const { return EC; };
167
168    static bool classof(const DiagnosticInfo *DI) {
169      return DI->getKind() == DK_Bitcode;
170    }
171  };
172
173} // End llvm namespace
174
175namespace std {
176template <> struct is_error_code_enum<llvm::BitcodeError> : std::true_type {};
177}
178
179#endif
180