Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(187)

Side by Side Diff: lib/Bitcode/NaCl/Reader/NaClBitcodeHeader.cpp

Issue 1122423005: Add (unsupported experimental) feature allowing byte aligned bitcode. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-llvm.git@master
Patch Set: Fix nits. Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 //===- NaClBitcodeHeader.cpp ----------------------------------------------===// 1 //===- NaClBitcodeHeader.cpp ----------------------------------------------===//
2 // PNaCl bitcode header reader. 2 // PNaCl 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
11 #include "llvm/Bitcode/NaCl/NaClBitcodeHeader.h" 11 #include "llvm/Bitcode/NaCl/NaClBitcodeHeader.h"
12
13 #include "llvm/ADT/SmallSet.h"
12 #include "llvm/Bitcode/NaCl/NaClReaderWriter.h" 14 #include "llvm/Bitcode/NaCl/NaClReaderWriter.h"
13 #include "llvm/Bitcode/ReaderWriter.h" 15 #include "llvm/Bitcode/ReaderWriter.h"
14 #include "llvm/Support/ErrorHandling.h" 16 #include "llvm/Support/ErrorHandling.h"
15 #include "llvm/Support/Format.h" 17 #include "llvm/Support/Format.h"
16 #include "llvm/Support/raw_ostream.h" 18 #include "llvm/Support/raw_ostream.h"
17 #include "llvm/Support/StreamingMemoryObject.h" 19 #include "llvm/Support/StreamingMemoryObject.h"
18 20
19 #include <limits>
20 #include <cstring> 21 #include <cstring>
21 #include <iomanip> 22 #include <iomanip>
23 #include <limits>
22 24
23 using namespace llvm; 25 using namespace llvm;
24 26
27 namespace {
28
29 // The name for each ID tag.
30 static const char *TagName[] = {
31 "Invalid", // kInvalid
32 "PNaCl Version", // kPNaClVersion
33 "Align bitcode records" // kAlignBitcodeRecords
34 };
35
36 // The name for each field type.
37 static const char *FieldTypeName[] = {
38 "uint8[]", // kBufferType
39 "uint32", // kUInt32Type
40 "flag", // kFlagType
41 "unknown" // kUnknownType
42 };
43
44 // The type associated with each ID tag.
45 static const NaClBitcodeHeaderField::FieldType ExpectedType[] = {
46 NaClBitcodeHeaderField::kUnknownType, // kInvalid
47 NaClBitcodeHeaderField::kUInt32Type, // kPNaClVersion
48 NaClBitcodeHeaderField::kFlagType // kAlignBitcodeRecords
49 };
50
51 } // end of anonymous namespace
52
53 const char *NaClBitcodeHeaderField::IDName(Tag ID) {
54 return ID > kTag_MAX ? "???" : TagName[ID];
55 }
56
57 const char *NaClBitcodeHeaderField::TypeName(FieldType FType) {
58 return FType > kFieldType_MAX ? "???" : FieldTypeName[FType];
59 }
60
25 NaClBitcodeHeaderField::NaClBitcodeHeaderField() 61 NaClBitcodeHeaderField::NaClBitcodeHeaderField()
26 : ID(kInvalid), FType(kBufferType), Len(0), Data(0) {} 62 : ID(kInvalid), FType(kBufferType), Len(0), Data(0) {}
63
64 NaClBitcodeHeaderField::NaClBitcodeHeaderField(Tag MyID)
65 : ID(MyID), FType(kFlagType), Len(0), Data(0) {
66 assert(MyID <= kTag_MAX);
67 }
27 68
28 NaClBitcodeHeaderField::NaClBitcodeHeaderField(Tag MyID, uint32_t MyValue) 69 NaClBitcodeHeaderField::NaClBitcodeHeaderField(Tag MyID, uint32_t MyValue)
29 : ID(MyID), FType(kUInt32Type), Len(4), Data(new uint8_t[4]) { 70 : ID(MyID), FType(kUInt32Type), Len(4), Data(new uint8_t[4]) {
71 assert(MyID <= kTag_MAX);
30 Data[0] = static_cast<uint8_t>(MyValue & 0xFF); 72 Data[0] = static_cast<uint8_t>(MyValue & 0xFF);
31 Data[1] = static_cast<uint8_t>((MyValue >> 8) & 0xFF); 73 Data[1] = static_cast<uint8_t>((MyValue >> 8) & 0xFF);
32 Data[2] = static_cast<uint8_t>((MyValue >> 16) & 0xFF); 74 Data[2] = static_cast<uint8_t>((MyValue >> 16) & 0xFF);
33 Data[3] = static_cast<uint8_t>((MyValue >> 24) & 0xFF); 75 Data[3] = static_cast<uint8_t>((MyValue >> 24) & 0xFF);
34 } 76 }
35 77
36 uint32_t NaClBitcodeHeaderField::GetUInt32Value() const { 78 uint32_t NaClBitcodeHeaderField::GetUInt32Value() const {
37 assert(FType == kUInt32Type && "Header field must be uint32"); 79 assert(FType == kUInt32Type && "Header field must be uint32");
38 return static_cast<uint32_t>(Data[0]) | 80 return static_cast<uint32_t>(Data[0]) |
39 (static_cast<uint32_t>(Data[1]) << 8) | 81 (static_cast<uint32_t>(Data[1]) << 8) |
40 (static_cast<uint32_t>(Data[2]) << 16) | 82 (static_cast<uint32_t>(Data[2]) << 16) |
41 (static_cast<uint32_t>(Data[2]) << 24); 83 (static_cast<uint32_t>(Data[2]) << 24);
42 } 84 }
43 85
44 NaClBitcodeHeaderField::NaClBitcodeHeaderField(Tag MyID, size_t MyLen, 86 NaClBitcodeHeaderField::NaClBitcodeHeaderField(Tag MyID, size_t MyLen,
45 uint8_t *MyData) 87 uint8_t *MyData)
46 : ID(MyID), FType(kBufferType), Len(MyLen), Data(new uint8_t[MyLen]) { 88 : ID(MyID), FType(kBufferType), Len(MyLen), Data(new uint8_t[MyLen]) {
89 assert(MyID <= kTag_MAX);
47 for (size_t i = 0; i < MyLen; ++i) { 90 for (size_t i = 0; i < MyLen; ++i) {
48 Data[i] = MyData[i]; 91 Data[i] = MyData[i];
49 } 92 }
50 } 93 }
51 94
52 bool NaClBitcodeHeaderField::Write(uint8_t *Buf, size_t BufLen) const { 95 bool NaClBitcodeHeaderField::Write(uint8_t *Buf, size_t BufLen) const {
53 size_t FieldsLen = kTagLenSize + Len; 96 size_t FieldsLen = kTagLenSize + Len;
54 size_t PadLen = (WordSize - (FieldsLen & (WordSize-1))) & (WordSize-1); 97 size_t PadLen = (WordSize - (FieldsLen & (WordSize-1))) & (WordSize-1);
55 // Ensure buffer is large enough and that length can be represented 98 // Ensure buffer is large enough and that length can be represented
56 // in 32 bits 99 // in 32 bits
(...skipping 30 matching lines...) Expand all
87 } 130 }
88 Len = Length; 131 Len = Length;
89 DecodeTypedID(IdField, ID, FType); 132 DecodeTypedID(IdField, ID, FType);
90 memcpy(Data, Buf + kTagLenSize, Len); 133 memcpy(Data, Buf + kTagLenSize, Len);
91 return true; 134 return true;
92 } 135 }
93 136
94 std::string NaClBitcodeHeaderField::Contents() const { 137 std::string NaClBitcodeHeaderField::Contents() const {
95 std::string buffer; 138 std::string buffer;
96 raw_string_ostream ss(buffer); 139 raw_string_ostream ss(buffer);
97 switch (ID) { 140 ss << IDName() << ": ";
98 case kPNaClVersion: 141 switch (FType) {
99 ss << "PNaCl Version"; 142 case kFlagType:
143 ss << "true";
100 break; 144 break;
101 case kInvalid:
102 ss << "Invalid";
103 break;
104 }
105 ss << ": ";
106 switch (FType) {
107 case kUInt32Type: 145 case kUInt32Type:
108 ss << GetUInt32Value(); 146 ss << GetUInt32Value();
109 break; 147 break;
110 case kBufferType: 148 case kBufferType:
111 ss << "["; 149 ss << "[";
112 for (size_t i = 0; i < Len; ++i) { 150 for (size_t i = 0; i < Len; ++i) {
113 if (i) 151 if (i)
114 ss << " "; 152 ss << " ";
115 ss << format("%02x", Data[i]); 153 ss << format("%02x", Data[i]);
116 } 154 }
117 ss << "]"; 155 ss << "]";
118 break; 156 break;
157 case kUnknownType:
158 ss << "unknown value";
159 break;
119 } 160 }
120 return ss.str(); 161 return ss.str();
121 } 162 }
122 163
123 NaClBitcodeHeader::NaClBitcodeHeader() 164 NaClBitcodeHeader::NaClBitcodeHeader()
124 : HeaderSize(0), UnsupportedMessage(), IsSupportedFlag(false), 165 : HeaderSize(0), UnsupportedMessage(), IsSupportedFlag(false),
125 IsReadableFlag(false), PNaClVersion(0) {} 166 IsReadableFlag(false), PNaClVersion(0) {}
126 167
127 NaClBitcodeHeader::~NaClBitcodeHeader() { 168 NaClBitcodeHeader::~NaClBitcodeHeader() {
128 for (std::vector<NaClBitcodeHeaderField *>::const_iterator 169 for (std::vector<NaClBitcodeHeaderField *>::const_iterator
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 NaClBitcodeHeaderField *Field = new NaClBitcodeHeaderField(); 209 NaClBitcodeHeaderField *Field = new NaClBitcodeHeaderField();
169 Fields.push_back(Field); 210 Fields.push_back(Field);
170 if (!Field->Read(BufPtr, BufEnd - BufPtr)) 211 if (!Field->Read(BufPtr, BufEnd - BufPtr))
171 return UnsupportedError("Bitcode read failure"); 212 return UnsupportedError("Bitcode read failure");
172 size_t FieldSize = Field->GetTotalSize(); 213 size_t FieldSize = Field->GetTotalSize();
173 BufPtr += FieldSize; 214 BufPtr += FieldSize;
174 } 215 }
175 return false; 216 return false;
176 } 217 }
177 218
178 bool NaClBitcodeHeader::Read(const unsigned char *&BufPtr, 219 bool NaClBitcodeHeader::Read(const unsigned char *BufPtr,
179 const unsigned char *&BufEnd) { 220 const unsigned char *BufEnd) {
180 unsigned NumFields; 221 unsigned NumFields;
181 unsigned NumBytes; 222 unsigned NumBytes;
182 if (ReadPrefix(BufPtr, BufEnd, NumFields, NumBytes)) 223 if (ReadPrefix(BufPtr, BufEnd, NumFields, NumBytes))
183 return true; // ReadPrefix sets UnsupportedMessage 224 return true; // ReadPrefix sets UnsupportedMessage
184 BufPtr += 2 * WordSize; 225 BufPtr += 2 * WordSize;
185 226
186 if (ReadFields(BufPtr, BufEnd, NumFields, NumBytes)) 227 if (ReadFields(BufPtr, BufEnd, NumFields, NumBytes))
187 return true; // ReadFields sets UnsupportedMessage 228 return true; // ReadFields sets UnsupportedMessage
188 BufPtr += NumBytes; 229 BufPtr += NumBytes;
189 InstallFields(); 230 InstallFields();
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
237 if (NaClBitcodeHeaderField *Version = 278 if (NaClBitcodeHeaderField *Version =
238 Header->GetTaggedField(NaClBitcodeHeaderField::kPNaClVersion)) { 279 Header->GetTaggedField(NaClBitcodeHeaderField::kPNaClVersion)) {
239 if (Version->GetType() == NaClBitcodeHeaderField::kUInt32Type) { 280 if (Version->GetType() == NaClBitcodeHeaderField::kUInt32Type) {
240 return Version; 281 return Version;
241 } 282 }
242 } 283 }
243 return 0; 284 return 0;
244 } 285 }
245 286
246 void NaClBitcodeHeader::InstallFields() { 287 void NaClBitcodeHeader::InstallFields() {
247 // Assume supported until contradicted.
248 bool UpdatedUnsupportedMessage = false;
249 IsSupportedFlag = true; 288 IsSupportedFlag = true;
250 IsReadableFlag = true; 289 IsReadableFlag = true;
251 UnsupportedMessage = "Supported"; 290 AlignBitcodeRecords = false;
252 PNaClVersion = 0; 291 PNaClVersion = 0;
253 if (NaClBitcodeHeaderField *Version = GetPNaClVersionPtr(this)) { 292 UnsupportedMessage.clear();
254 PNaClVersion = Version->GetUInt32Value(); 293 SmallSet<unsigned, NaClBitcodeHeaderField::kTag_MAX> FieldIDs;
255 } 294
256 if (PNaClVersion != 2) { 295 auto ReportProblem = [&](bool IsReadable=false) {
296 UnsupportedMessage.append("\n");
257 IsSupportedFlag = false; 297 IsSupportedFlag = false;
258 IsReadableFlag = false; 298 IsReadableFlag = IsReadableFlag && IsReadable;
259 UpdatedUnsupportedMessage = true; 299 };
260 UnsupportedMessage.clear(); 300
261 raw_string_ostream UnsupportedStream(UnsupportedMessage); 301 auto ReportProblemWithContents = [&](NaClBitcodeHeaderField *Field,
262 UnsupportedStream << "Unsupported PNaCl bitcode version: " 302 bool IsReadable=false) {
263 << PNaClVersion << "\n"; 303 UnsupportedMessage.append(": ");
264 UnsupportedStream.flush(); 304 UnsupportedMessage.append(Field->Contents());
265 } 305 ReportProblem(IsReadable);
266 if (Fields.size() != 1) { 306 };
267 IsSupportedFlag = false; 307
268 IsReadableFlag = false; 308 for (size_t i = 0, e = NumberFields(); i < e; ++i) {
269 if (!UpdatedUnsupportedMessage) 309 // Start by checking expected properties for any field
270 UnsupportedMessage = "Unknown header field(s) found"; 310 NaClBitcodeHeaderField *Field = GetField(i);
311 if (!FieldIDs.insert(Field->GetID()).second) {
312 UnsupportedMessage.append("Specified multiple times: ");
313 UnsupportedMessage.append(Field->IDName());
314 ReportProblem();
315 continue;
316 }
317 NaClBitcodeHeaderField::FieldType ExpectedTy = ExpectedType[Field->GetID()];
318 if (Field->GetType() != ExpectedTy) {
319 UnsupportedMessage.append("Expects type ");
320 UnsupportedMessage.append(NaClBitcodeHeaderField::TypeName(ExpectedTy));
321 ReportProblemWithContents(Field);
322 continue;
323 }
324 if (Field->GetType() == NaClBitcodeHeaderField::kUnknownType) {
325 UnsupportedMessage.append("Unknown value");
326 ReportProblemWithContents(Field);
327 continue;
328 }
329
330 // Check specific ID values and install.
331 switch (Field->GetID()) {
332 case NaClBitcodeHeaderField::kInvalid:
333 UnsupportedMessage.append("Unsupported");
334 ReportProblemWithContents(Field);
335 continue;
336 case NaClBitcodeHeaderField::kPNaClVersion:
337 PNaClVersion = Field->GetUInt32Value();
338 if (PNaClVersion != 2) {
339 UnsupportedMessage.append("Unsupported");
340 ReportProblemWithContents(Field);
341 continue;
342 }
343 break;
344 case NaClBitcodeHeaderField::kAlignBitcodeRecords:
345 AlignBitcodeRecords = true;
346 UnsupportedMessage.append("Unsupported");
347 ReportProblemWithContents(Field, true);
348 continue;
349 }
271 } 350 }
272 } 351 }
OLDNEW
« no previous file with comments | « lib/Bitcode/NaCl/Analysis/NaClObjDump.cpp ('k') | lib/Bitcode/NaCl/Reader/NaClBitcodeReader.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698