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