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