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 ... | |
jvoung (off chromium)
2013/04/29 18:02:08
Did we put "other gunk" in the wrapper header, to
Derek Schuff
2013/04/29 18:25:38
we probably should. althoughwe might want to just
Karl
2013/04/29 20:44:37
Not yet. Added TODO to clarify we need to do this.
Karl
2013/04/29 20:44:37
Added TODO for this as well.
| |
106 /// }; | |
107 /// | |
108 /// This function is called when we find a file with a matching magic number. | |
109 /// In this case, skip down to the subsection of the file that is actually a | |
110 /// BC file. | |
111 /// If 'VerifyBufferSize' is true, check that the buffer is large enough to | |
112 /// contain the whole bitcode file. | |
113 inline bool SkipNaClBitcodeWrapperHeader(const unsigned char *&BufPtr, | |
114 const unsigned char *&BufEnd, | |
115 bool VerifyBufferSize) { | |
116 enum { | |
117 KnownHeaderSize = 4*4, // Size of header we read. | |
118 OffsetField = 2*4, // Offset in bytes to Offset field. | |
119 SizeField = 3*4 // Offset in bytes to Size field. | |
120 }; | |
121 | |
122 // Must contain the header! | |
123 if (BufEnd-BufPtr < KnownHeaderSize) return true; | |
124 | |
125 unsigned Offset = ( BufPtr[OffsetField ] | | |
126 (BufPtr[OffsetField+1] << 8) | | |
127 (BufPtr[OffsetField+2] << 16) | | |
128 (BufPtr[OffsetField+3] << 24)); | |
129 unsigned Size = ( BufPtr[SizeField ] | | |
130 (BufPtr[SizeField +1] << 8) | | |
131 (BufPtr[SizeField +2] << 16) | | |
132 (BufPtr[SizeField +3] << 24)); | |
133 | |
134 // Verify that Offset+Size fits in the file. | |
135 if (VerifyBufferSize && Offset+Size > unsigned(BufEnd-BufPtr)) | |
136 return true; | |
137 BufPtr += Offset; | |
138 BufEnd = BufPtr+Size; | |
139 return false; | |
140 } | |
141 | |
28 } // end llvm namespace | 142 } // end llvm namespace |
29 #endif | 143 #endif |
OLD | NEW |