OLD | NEW |
1 //===-- llvm/Bitcode/NaCl/NaClBitcodeHeader.h - ----------------*- C++ -*-===// | 1 //===-- llvm/Bitcode/NaCl/NaClBitcodeHeader.h - ----------------*- C++ -*-===// |
2 // NaCl Bitcode header reader. | 2 // NaCl Bitcode header reader. |
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 // |
(...skipping 20 matching lines...) Expand all Loading... |
31 // The serialized format has 2 fixed subfields (ID:type and data length) and the | 31 // The serialized format has 2 fixed subfields (ID:type and data length) and the |
32 // variable-length data subfield | 32 // variable-length data subfield |
33 class NaClBitcodeHeaderField { | 33 class NaClBitcodeHeaderField { |
34 NaClBitcodeHeaderField(const NaClBitcodeHeaderField &) LLVM_DELETED_FUNCTION; | 34 NaClBitcodeHeaderField(const NaClBitcodeHeaderField &) LLVM_DELETED_FUNCTION; |
35 void operator=(const NaClBitcodeHeaderField &)LLVM_DELETED_FUNCTION; | 35 void operator=(const NaClBitcodeHeaderField &)LLVM_DELETED_FUNCTION; |
36 | 36 |
37 public: | 37 public: |
38 // Defines the ID associated with the value. Valid values are in | 38 // Defines the ID associated with the value. Valid values are in |
39 // {0x0, ..., 0xFFF} | 39 // {0x0, ..., 0xFFF} |
40 typedef enum { | 40 typedef enum { |
41 kInvalid = 0, // KUnknownType. | 41 kInvalid = 0, // KUnknownType. |
42 kPNaClVersion = 1 // kUint32. | 42 kPNaClVersion = 1, // kUint32Type. |
| 43 kAlignBitcodeRecords = 2, // kFlagType. |
| 44 kTag_MAX = kAlignBitcodeRecords |
43 } Tag; | 45 } Tag; |
44 // Defines the type of value. | 46 // Defines the type of value. |
45 typedef enum { | 47 typedef enum { |
46 kBufferType, // Buffer of form uint8_t[len]. | 48 kBufferType, // Buffer of form uint8_t[len]. |
47 kUInt32Type | 49 kUInt32Type, |
| 50 kFlagType, |
| 51 kUnknownType, |
| 52 kFieldType_MAX = kUnknownType |
48 } FieldType; | 53 } FieldType; |
49 // Defines the number of bytes in a (32-bit) word. | 54 // Defines the number of bytes in a (32-bit) word. |
50 static const int WordSize = 4; | 55 static const int WordSize = 4; |
51 | 56 |
52 // Defines the encoding of the fixed fields {i.e. ID:type and data length). | 57 // Defines the encoding of the fixed fields {i.e. ID:type and data length). |
53 typedef uint16_t FixedSubfield; | 58 typedef uint16_t FixedSubfield; |
54 | 59 |
55 // Create an invalid header field. | 60 // Create an invalid header field. |
56 NaClBitcodeHeaderField(); | 61 NaClBitcodeHeaderField(); |
57 | 62 |
| 63 // Creates a header field where MyID is a flag. |
| 64 NaClBitcodeHeaderField(Tag MyID); |
| 65 |
58 // Create a header field with an uint32_t value. | 66 // Create a header field with an uint32_t value. |
59 NaClBitcodeHeaderField(Tag MyID, uint32_t value); | 67 NaClBitcodeHeaderField(Tag MyID, uint32_t value); |
60 | 68 |
61 // Create a header field for the given data. | 69 // Create a header field for the given data. |
62 NaClBitcodeHeaderField(Tag MyID, size_t MyLen, uint8_t *MyData); | 70 NaClBitcodeHeaderField(Tag MyID, size_t MyLen, uint8_t *MyData); |
63 | 71 |
64 virtual ~NaClBitcodeHeaderField() { | 72 virtual ~NaClBitcodeHeaderField() { |
65 if (Data) | 73 if (Data) |
66 delete[] Data; | 74 delete[] Data; |
67 } | 75 } |
68 | 76 |
69 /// \brief Number of bytes used to represent header field. | 77 /// \brief Number of bytes used to represent header field. |
70 size_t GetTotalSize() const { | 78 size_t GetTotalSize() const { |
71 // Round up to 4 byte alignment | 79 // Round up to 4 byte alignment |
72 return (kTagLenSize + Len + (WordSize - 1)) & ~(WordSize - 1); | 80 return (kTagLenSize + Len + (WordSize - 1)) & ~(WordSize - 1); |
73 } | 81 } |
74 | 82 |
75 /// \brief Write field into Buf[BufLen]. | 83 /// \brief Write field into Buf[BufLen]. |
76 bool Write(uint8_t *Buf, size_t BufLen) const; | 84 bool Write(uint8_t *Buf, size_t BufLen) const; |
77 | 85 |
78 /// \brief Read field from Buf[BufLen]. | 86 /// \brief Read field from Buf[BufLen]. |
79 bool Read(const uint8_t *Buf, size_t BufLen); | 87 bool Read(const uint8_t *Buf, size_t BufLen); |
80 | 88 |
| 89 /// \brief Returns string describing ID of field. |
| 90 static const char *IDName(Tag ID); |
| 91 const char *IDName() const { |
| 92 return IDName(ID); |
| 93 } |
| 94 |
| 95 /// \brief Returns string describing type of field. |
| 96 static const char *TypeName(FieldType FType); |
| 97 const char *TypeName() const { |
| 98 return TypeName(FType); |
| 99 } |
| 100 |
81 /// \brief Returns string describing field. | 101 /// \brief Returns string describing field. |
82 std::string Contents() const; | 102 std::string Contents() const; |
83 | 103 |
84 /// \brief Get the data size from a serialized field to allow allocation. | 104 /// \brief Get the data size from a serialized field to allow allocation. |
85 static size_t GetDataSizeFromSerialized(const uint8_t *Buf) { | 105 static size_t GetDataSizeFromSerialized(const uint8_t *Buf) { |
86 FixedSubfield Length; | 106 FixedSubfield Length; |
87 ReadFixedSubfield(&Length, Buf + sizeof(FixedSubfield)); | 107 ReadFixedSubfield(&Length, Buf + sizeof(FixedSubfield)); |
88 return Length; | 108 return Length; |
89 } | 109 } |
90 | 110 |
(...skipping 10 matching lines...) Expand all Loading... |
101 | 121 |
102 /// \brief Returns the uint32_t value stored. Requires that | 122 /// \brief Returns the uint32_t value stored. Requires that |
103 /// getType() == kUint32Type | 123 /// getType() == kUint32Type |
104 uint32_t GetUInt32Value() const; | 124 uint32_t GetUInt32Value() const; |
105 | 125 |
106 private: | 126 private: |
107 // Convert ID:Type into a fixed subfield | 127 // Convert ID:Type into a fixed subfield |
108 FixedSubfield EncodeTypedID() const { return (ID << 4) | FType; } | 128 FixedSubfield EncodeTypedID() const { return (ID << 4) | FType; } |
109 // Extract out ID and Type from a fixed subfield. | 129 // Extract out ID and Type from a fixed subfield. |
110 void DecodeTypedID(FixedSubfield Subfield, Tag &ID, FieldType &FType) { | 130 void DecodeTypedID(FixedSubfield Subfield, Tag &ID, FieldType &FType) { |
111 ID = static_cast<Tag>(Subfield >> 4); | 131 FixedSubfield PossibleID = Subfield >> 4; |
112 FType = static_cast<FieldType>(Subfield & 0xF); | 132 ID = (PossibleID > kTag_MAX ? kInvalid : static_cast<Tag>(PossibleID)); |
| 133 FixedSubfield PossibleFType = Subfield & 0xF; |
| 134 FType = (PossibleFType > kFieldType_MAX |
| 135 ? kUnknownType : static_cast<FieldType>(PossibleFType)); |
113 } | 136 } |
114 // Combined size of the fixed subfields | 137 // Combined size of the fixed subfields |
115 const static size_t kTagLenSize = 2 * sizeof(FixedSubfield); | 138 const static size_t kTagLenSize = 2 * sizeof(FixedSubfield); |
116 static void WriteFixedSubfield(FixedSubfield Value, uint8_t *Buf) { | 139 static void WriteFixedSubfield(FixedSubfield Value, uint8_t *Buf) { |
117 Buf[0] = Value & 0xFF; | 140 Buf[0] = Value & 0xFF; |
118 Buf[1] = (Value >> 8) & 0xFF; | 141 Buf[1] = (Value >> 8) & 0xFF; |
119 } | 142 } |
120 static void ReadFixedSubfield(FixedSubfield *Value, const uint8_t *Buf) { | 143 static void ReadFixedSubfield(FixedSubfield *Value, const uint8_t *Buf) { |
121 *Value = Buf[0] | Buf[1] << 8; | 144 *Value = Buf[0] | Buf[1] << 8; |
122 } | 145 } |
(...skipping 14 matching lines...) Expand all Loading... |
137 // The number of bytes in the PNaCl header. | 160 // The number of bytes in the PNaCl header. |
138 size_t HeaderSize; | 161 size_t HeaderSize; |
139 // String defining why it is unsupported (if unsupported). | 162 // String defining why it is unsupported (if unsupported). |
140 std::string UnsupportedMessage; | 163 std::string UnsupportedMessage; |
141 // Flag defining if header is supported. | 164 // Flag defining if header is supported. |
142 bool IsSupportedFlag; | 165 bool IsSupportedFlag; |
143 // Flag defining if the corresponding bitcode file is readable. | 166 // Flag defining if the corresponding bitcode file is readable. |
144 bool IsReadableFlag; | 167 bool IsReadableFlag; |
145 // Defines the PNaCl version defined by the header file. | 168 // Defines the PNaCl version defined by the header file. |
146 uint32_t PNaClVersion; | 169 uint32_t PNaClVersion; |
| 170 // Byte align bitcode records when nonzero. |
| 171 bool AlignBitcodeRecords = false; |
147 | 172 |
148 public: | 173 public: |
149 static const int WordSize = NaClBitcodeHeaderField::WordSize; | 174 static const int WordSize = NaClBitcodeHeaderField::WordSize; |
150 | 175 |
151 NaClBitcodeHeader(); | 176 NaClBitcodeHeader(); |
152 ~NaClBitcodeHeader(); | 177 ~NaClBitcodeHeader(); |
153 | 178 |
154 /// \brief Installs the fields of the header, defining if the header | 179 /// \brief Installs the fields of the header, defining if the header |
155 /// is readable and supported. Sets UnsupportedMessage on failure. | 180 /// is readable and supported. Sets UnsupportedMessage on failure. |
156 void InstallFields(); | 181 void InstallFields(); |
157 | 182 |
158 /// \brief Adds a field to the list of fields in a header. Takes ownership | 183 /// \brief Adds a field to the list of fields in a header. Takes ownership |
159 /// of fields added. | 184 /// of fields added. |
160 void push_back(NaClBitcodeHeaderField *Field) { | 185 void push_back(NaClBitcodeHeaderField *Field) { |
161 Fields.push_back(Field); | 186 Fields.push_back(Field); |
162 } | 187 } |
163 | 188 |
164 /// \brief Read the PNaCl bitcode header, The format of the header is: | 189 /// \brief Read the PNaCl bitcode header, The format of the header is: |
165 /// | 190 /// |
166 /// 1) 'PEXE' - The four character sequence defining the magic number. | 191 /// 1) 'PEXE' - The four character sequence defining the magic number. |
167 /// 2) uint_16 num_fields - The number of NaClBitcodeHeaderField's. | 192 /// 2) uint_16 num_fields - The number of NaClBitcodeHeaderField's. |
168 /// 3) uint_16 num_bytes - The number of bytes to hold fields in | 193 /// 3) uint_16 num_bytes - The number of bytes to hold fields in |
169 /// the header. | 194 /// the header. |
170 /// 4) NaClBitcodeHeaderField f1 - The first bitcode header field. | 195 /// 4) NaClBitcodeHeaderField f1 - The first bitcode header field. |
171 /// ... | 196 /// ... |
172 /// 2 + num_fields) NaClBitcodeHeaderField fn - The last bitcode header | 197 /// 2 + num_fields) NaClBitcodeHeaderField fn - The last bitcode header |
173 /// field. | 198 /// field. |
174 /// | 199 /// |
175 /// Returns false if able to read (all of) the bitcode header. | 200 /// Returns false if able to read (all of) the bitcode header. |
176 bool Read(const unsigned char *&BufPtr, const unsigned char *&BufEnd); | 201 bool Read(const unsigned char *BufPtr, const unsigned char *BufEnd); |
177 | 202 |
178 // \brief Read the PNaCl bitcode header, recording the fields found | 203 // \brief Read the PNaCl bitcode header, recording the fields found |
179 // in the header. Returns false if able to read (all of) the bitcode header. | 204 // in the header. Returns false if able to read (all of) the bitcode header. |
180 bool Read(MemoryObject *Bytes); | 205 bool Read(MemoryObject *Bytes); |
181 | 206 |
182 // \brief Returns the number of bytes read to consume the header. | 207 // \brief Returns the number of bytes read to consume the header. |
183 size_t getHeaderSize() { return HeaderSize; } | 208 size_t getHeaderSize() { return HeaderSize; } |
184 | 209 |
185 /// \brief Returns string describing why the header describes | 210 /// \brief Returns string describing why the header describes |
186 /// an unsupported PNaCl Bitcode file. | 211 /// an unsupported PNaCl Bitcode file. |
(...skipping 15 matching lines...) Expand all Loading... |
202 /// (0 if no such field). | 227 /// (0 if no such field). |
203 NaClBitcodeHeaderField *GetTaggedField(NaClBitcodeHeaderField::Tag ID) const; | 228 NaClBitcodeHeaderField *GetTaggedField(NaClBitcodeHeaderField::Tag ID) const; |
204 | 229 |
205 /// \brief Returns a pointer to the Nth field in the header | 230 /// \brief Returns a pointer to the Nth field in the header |
206 /// (0 if no such field). | 231 /// (0 if no such field). |
207 NaClBitcodeHeaderField *GetField(size_t index) const; | 232 NaClBitcodeHeaderField *GetField(size_t index) const; |
208 | 233 |
209 /// \brief Returns the PNaClVersion, as defined by the header. | 234 /// \brief Returns the PNaClVersion, as defined by the header. |
210 uint32_t GetPNaClVersion() const { return PNaClVersion; } | 235 uint32_t GetPNaClVersion() const { return PNaClVersion; } |
211 | 236 |
| 237 /// \brief Returns if one should byte align bitcode records. |
| 238 bool getAlignBitcodeRecords() const { return AlignBitcodeRecords; } |
| 239 |
212 private: | 240 private: |
213 // Reads and verifies the first 8 bytes of the header, consisting | 241 // Reads and verifies the first 8 bytes of the header, consisting |
214 // of the magic number 'PEXE', and the value defining the number | 242 // of the magic number 'PEXE', and the value defining the number |
215 // of fields and number of bytes used to hold fields. | 243 // of fields and number of bytes used to hold fields. |
216 // Returns false if successful, sets UnsupportedMessage otherwise. | 244 // Returns false if successful, sets UnsupportedMessage otherwise. |
217 bool ReadPrefix(const unsigned char *BufPtr, const unsigned char *BufEnd, | 245 bool ReadPrefix(const unsigned char *BufPtr, const unsigned char *BufEnd, |
218 unsigned &NumFields, unsigned &NumBytes); | 246 unsigned &NumFields, unsigned &NumBytes); |
219 | 247 |
220 // Reads and verifies the fields in the header. | 248 // Reads and verifies the fields in the header. |
221 // Returns false if successful, sets UnsupportedMessage otherwise. | 249 // Returns false if successful, sets UnsupportedMessage otherwise. |
222 bool ReadFields(const unsigned char *BufPtr, const unsigned char *BufEnd, | 250 bool ReadFields(const unsigned char *BufPtr, const unsigned char *BufEnd, |
223 unsigned NumFields, unsigned NumBytes); | 251 unsigned NumFields, unsigned NumBytes); |
224 | 252 |
225 // Sets the Unsupported error message and returns true. | 253 // Sets the Unsupported error message and returns true. |
226 bool UnsupportedError(StringRef Message) { | 254 bool UnsupportedError(StringRef Message) { |
227 UnsupportedMessage = Message.str(); | 255 UnsupportedMessage = Message.str(); |
228 return true; | 256 return true; |
229 } | 257 } |
230 | 258 |
231 }; | 259 }; |
232 | 260 |
233 } // namespace llvm | 261 } // namespace llvm |
234 | 262 |
235 #endif | 263 #endif |
OLD | NEW |