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

Side by Side Diff: pnacl-llvm/NaClBitstreamReader.cpp

Issue 1960393002: Subzero: Add necessary PNaCl files for standalone build. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero@master
Patch Set: make format Created 4 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
« no previous file with comments | « pnacl-llvm/NaClBitcodeParser.cpp ('k') | pnacl-llvm/README.txt » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 //===- NaClBitstreamReader.cpp --------------------------------------------===//
2 // NaClBitstreamReader implementation
3 //
4 // The LLVM Compiler Infrastructure
5 //
6 // This file is distributed under the University of Illinois Open Source
7 // License. See LICENSE.TXT for details.
8 //
9 //===----------------------------------------------------------------------===//
10
11 #include "llvm/ADT/STLExtras.h"
12 #include "llvm/Bitcode/NaCl/NaClBitstreamReader.h"
13 #include "llvm/Support/Format.h"
14 #include "llvm/Support/raw_ostream.h"
15
16 using namespace llvm;
17
18 namespace {
19
20 static const char *ErrorLevelName[] = {
21 "Warning",
22 "Error",
23 "Fatal"
24 };
25
26 } // End of anonymous namespace.
27
28 std::string llvm::naclbitc::getBitAddress(uint64_t Bit) {
29 std::string Buffer;
30 raw_string_ostream Stream(Buffer);
31 Stream << (Bit / 8) << ":" << (Bit % 8);
32 return Stream.str();
33 }
34
35 raw_ostream &llvm::naclbitc::ErrorAt(
36 raw_ostream &Out, ErrorLevel Level, uint64_t BitPosition) {
37 assert(Level < array_lengthof(::ErrorLevelName));
38 return Out << ErrorLevelName[Level] << "("
39 << naclbitc::getBitAddress(BitPosition) << "): ";
40 }
41
42 //===----------------------------------------------------------------------===//
43 // NaClBitstreamCursor implementation
44 //===----------------------------------------------------------------------===//
45
46 void NaClBitstreamCursor::ErrorHandler::
47 Fatal(const std::string &ErrorMessage) const {
48 // Default implementation is simply print message, and the bit where
49 // the error occurred.
50 std::string Buffer;
51 raw_string_ostream StrBuf(Buffer);
52 naclbitc::ErrorAt(StrBuf, naclbitc::Fatal,
53 Cursor.getErrorBitNo(getCurrentBitNo())) << ErrorMessage;
54 report_fatal_error(StrBuf.str());
55 }
56
57 void NaClBitstreamCursor::reportInvalidAbbrevNumber(unsigned AbbrevNo) const {
58 std::string Buffer;
59 raw_string_ostream StrBuf(Buffer);
60 StrBuf << "Invalid abbreviation # " << AbbrevNo << " defined for record";
61 ErrHandler->Fatal(StrBuf.str());
62 }
63
64 void NaClBitstreamCursor::reportInvalidJumpToBit(uint64_t BitNo) const {
65 std::string Buffer;
66 raw_string_ostream StrBuf(Buffer);
67 StrBuf << "Invalid jump to bit " << BitNo;
68 ErrHandler->Fatal(StrBuf.str());
69 }
70
71 /// EnterSubBlock - Having read the ENTER_SUBBLOCK abbrevid, enter
72 /// the block, and return true if the block has an error.
73 bool NaClBitstreamCursor::EnterSubBlock(unsigned BlockID, unsigned *NumWordsP) {
74 const bool IsFixed = true;
75 NaClBitcodeSelectorAbbrev
76 CodeAbbrev(IsFixed, ReadVBR(naclbitc::CodeLenWidth));
77 BlockScope.push_back(Block(BitStream->getBlockInfo(BlockID), CodeAbbrev));
78 SkipToFourByteBoundary();
79 unsigned NumWords = Read(naclbitc::BlockSizeWidth);
80 if (NumWordsP) *NumWordsP = NumWords;
81
82 // Validate that this block is sane.
83 if (BlockScope.back().getCodeAbbrev().NumBits == 0 || AtEndOfStream())
84 return true;
85
86 return false;
87 }
88
89 void NaClBitstreamCursor::skipAbbreviatedField(const NaClBitCodeAbbrevOp &Op) {
90 // Decode the value as we are commanded.
91 switch (Op.getEncoding()) {
92 case NaClBitCodeAbbrevOp::Literal:
93 // No read necessary for literal.
94 break;
95 case NaClBitCodeAbbrevOp::Fixed:
96 (void)Read((unsigned)Op.getValue());
97 break;
98 case NaClBitCodeAbbrevOp::VBR:
99 (void)ReadVBR64((unsigned)Op.getValue());
100 break;
101 case NaClBitCodeAbbrevOp::Array:
102 // This can't happen because the abbreviation must be valid.
103 llvm_unreachable("Bad array abbreviation encoding!");
104 break;
105 case NaClBitCodeAbbrevOp::Char6:
106 (void)Read(6);
107 break;
108 }
109 }
110
111 /// skipRecord - Read the current record and discard it.
112 void NaClBitstreamCursor::skipRecord(unsigned AbbrevID) {
113 // Skip unabbreviated records by reading past their entries.
114 if (AbbrevID == naclbitc::UNABBREV_RECORD) {
115 unsigned Code = ReadVBR(6);
116 (void)Code;
117 unsigned NumElts = ReadVBR(6);
118 for (unsigned i = 0; i != NumElts; ++i)
119 (void)ReadVBR64(6);
120 SkipToByteBoundaryIfAligned();
121 return;
122 }
123
124 const NaClBitCodeAbbrev *Abbv = getAbbrev(AbbrevID);
125
126 for (unsigned i = 0, e = Abbv->getNumOperandInfos(); i != e; ++i) {
127 const NaClBitCodeAbbrevOp &Op = Abbv->getOperandInfo(i);
128 switch (Op.getEncoding()) {
129 default:
130 skipAbbreviatedField(Op);
131 break;
132 case NaClBitCodeAbbrevOp::Literal:
133 break;
134 case NaClBitCodeAbbrevOp::Array: {
135 // Array case. Read the number of elements as a vbr6.
136 unsigned NumElts = ReadVBR(6);
137
138 // Get the element encoding.
139 const NaClBitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i);
140
141 // Read all the elements.
142 for (; NumElts; --NumElts)
143 skipAbbreviatedField(EltEnc);
144 break;
145 }
146 }
147 }
148 SkipToByteBoundaryIfAligned();
149 }
150
151 bool NaClBitstreamCursor::readRecordAbbrevField(
152 const NaClBitCodeAbbrevOp &Op, uint64_t &Value) {
153 switch (Op.getEncoding()) {
154 case NaClBitCodeAbbrevOp::Literal:
155 Value = Op.getValue();
156 break;
157 case NaClBitCodeAbbrevOp::Array:
158 // Returns number of elements in the array.
159 Value = ReadVBR(6);
160 return true;
161 case NaClBitCodeAbbrevOp::Fixed:
162 Value = Read((unsigned)Op.getValue());
163 break;
164 case NaClBitCodeAbbrevOp::VBR:
165 Value = ReadVBR64((unsigned)Op.getValue());
166 break;
167 case NaClBitCodeAbbrevOp::Char6:
168 Value = NaClBitCodeAbbrevOp::DecodeChar6(Read(6));
169 break;
170 }
171 return false;
172 }
173
174 uint64_t NaClBitstreamCursor::readArrayAbbreviatedField(
175 const NaClBitCodeAbbrevOp &Op) {
176 // Decode the value as we are commanded.
177 switch (Op.getEncoding()) {
178 case NaClBitCodeAbbrevOp::Literal:
179 return Op.getValue();
180 case NaClBitCodeAbbrevOp::Fixed:
181 return Read((unsigned)Op.getValue());
182 case NaClBitCodeAbbrevOp::VBR:
183 return ReadVBR64((unsigned)Op.getValue());
184 case NaClBitCodeAbbrevOp::Array:
185 // This can't happen because the abbreviation must be valid.
186 llvm_unreachable("Bad array abbreviation encoding!");
187 break;
188 case NaClBitCodeAbbrevOp::Char6:
189 return NaClBitCodeAbbrevOp::DecodeChar6(Read(6));
190 }
191 }
192
193 void NaClBitstreamCursor::readArrayAbbrev(
194 const NaClBitCodeAbbrevOp &Op, unsigned NumArrayElements,
195 SmallVectorImpl<uint64_t> &Vals) {
196 for (; NumArrayElements; --NumArrayElements) {
197 Vals.push_back(readArrayAbbreviatedField(Op));
198 }
199 }
200
201 unsigned NaClBitstreamCursor::readRecord(unsigned AbbrevID,
202 SmallVectorImpl<uint64_t> &Vals) {
203 if (AbbrevID == naclbitc::UNABBREV_RECORD) {
204 unsigned Code = ReadVBR(6);
205 unsigned NumElts = ReadVBR(6);
206 for (unsigned i = 0; i != NumElts; ++i)
207 Vals.push_back(ReadVBR64(6));
208 SkipToByteBoundaryIfAligned();
209 return Code;
210 }
211
212 // Read code.
213 const NaClBitCodeAbbrev *Abbv = getAbbrev(AbbrevID);
214 uint64_t Value;
215 unsigned Code;
216 if (readRecordAbbrevField(Abbv->getOperandInfo(0), Value)) {
217 // Array found, use to read all elements.
218 if (Value == 0)
219 ErrHandler->Fatal("No code found for record!");
220 const NaClBitCodeAbbrevOp &Op = Abbv->getOperandInfo(1);
221 Code = readArrayAbbreviatedField(Op);
222 readArrayAbbrev(Op, Value - 1, Vals);
223 SkipToByteBoundaryIfAligned();
224 return Code;
225 }
226 Code = Value;
227
228 // Read arguments.
229 unsigned NumOperands = Abbv->getNumOperandInfos();
230 for (unsigned i = 1; i != NumOperands; ++i) {
231 if (readRecordAbbrevField(Abbv->getOperandInfo(i), Value)) {
232 ++i;
233 readArrayAbbrev(Abbv->getOperandInfo(i), Value, Vals);
234 SkipToByteBoundaryIfAligned();
235 return Code;
236 }
237 Vals.push_back(Value);
238 }
239 SkipToByteBoundaryIfAligned();
240 return Code;
241 }
242
243
244 NaClBitCodeAbbrevOp::Encoding NaClBitstreamCursor::
245 getEncoding(uint64_t Value) {
246 if (!NaClBitCodeAbbrevOp::isValidEncoding(Value)) {
247 std::string Buffer;
248 raw_string_ostream StrBuf(Buffer);
249 StrBuf << "Invalid abbreviation encoding specified in bitcode file: "
250 << Value;
251 ErrHandler->Fatal(StrBuf.str());
252 }
253 return NaClBitCodeAbbrevOp::Encoding(Value);
254 }
255
256 void NaClBitstreamCursor::ReadAbbrevRecord(bool IsLocal,
257 NaClAbbrevListener *Listener) {
258 NaClBitCodeAbbrev *Abbv = BlockScope.back().appendLocalCreate();
259 unsigned NumOpInfo = ReadVBR(5);
260 if (Listener) Listener->Values.push_back(NumOpInfo);
261 for (unsigned i = 0; i != NumOpInfo; ++i) {
262 bool IsLiteral = Read(1) ? true : false;
263 if (Listener) Listener->Values.push_back(IsLiteral);
264 if (IsLiteral) {
265 uint64_t Value = ReadVBR64(8);
266 if (Listener) Listener->Values.push_back(Value);
267 Abbv->Add(NaClBitCodeAbbrevOp(Value));
268 continue;
269 }
270 NaClBitCodeAbbrevOp::Encoding E = getEncoding(Read(3));
271 if (Listener) Listener->Values.push_back(E);
272 if (NaClBitCodeAbbrevOp::hasValue(E)) {
273 unsigned Data = ReadVBR64(5);
274 if (Listener) Listener->Values.push_back(Data);
275
276 // As a special case, handle fixed(0) (i.e., a fixed field with zero bits)
277 // and vbr(0) as a literal zero. This is decoded the same way, and avoids
278 // a slow path in Read() to have to handle reading zero bits.
279 if ((E == NaClBitCodeAbbrevOp::Fixed || E == NaClBitCodeAbbrevOp::VBR) &&
280 Data == 0) {
281 if (Listener) Listener->Values.push_back(0);
282 Abbv->Add(NaClBitCodeAbbrevOp(0));
283 continue;
284 }
285 if (!NaClBitCodeAbbrevOp::isValid(E, Data)) {
286 std::string Buffer;
287 raw_string_ostream StrBuf(Buffer);
288 StrBuf << "Invalid abbreviation encoding ("
289 << NaClBitCodeAbbrevOp::getEncodingName(E)
290 << ", " << Data << ")";
291 ErrHandler->Fatal(StrBuf.str());
292 }
293 Abbv->Add(NaClBitCodeAbbrevOp(E, Data));
294 } else {
295 if (!NaClBitCodeAbbrevOp::isValid(E)) {
296 std::string Buffer;
297 raw_string_ostream StrBuf(Buffer);
298 StrBuf << "Invalid abbreviation encoding ("
299 << NaClBitCodeAbbrevOp::getEncodingName(E) << ")";
300 ErrHandler->Fatal(StrBuf.str());
301 }
302 Abbv->Add(NaClBitCodeAbbrevOp(E));
303 }
304 }
305 SkipToByteBoundaryIfAligned();
306 if (!Abbv->isValid())
307 ErrHandler->Fatal("Invalid abbreviation specified in bitcode file");
308 if (Listener) {
309 Listener->ProcessAbbreviation(Abbv, IsLocal);
310 // Reset record information of the listener.
311 Listener->Values.clear();
312 Listener->StartBit = GetCurrentBitNo();
313 }
314 }
315
316 void NaClBitstreamCursor::SkipAbbrevRecord() {
317 unsigned NumOpInfo = ReadVBR(5);
318 for (unsigned i = 0; i != NumOpInfo; ++i) {
319 bool IsLiteral = Read(1) ? true : false;
320 if (IsLiteral) {
321 ReadVBR64(8);
322 continue;
323 }
324 NaClBitCodeAbbrevOp::Encoding E = getEncoding(Read(3));
325 if (NaClBitCodeAbbrevOp::hasValue(E)) {
326 ReadVBR64(5);
327 }
328 }
329 SkipToByteBoundaryIfAligned();
330 }
331
332 namespace {
333
334 unsigned ValidBlockIDs[] = {
335 naclbitc::BLOCKINFO_BLOCK_ID,
336 naclbitc::CONSTANTS_BLOCK_ID,
337 naclbitc::FUNCTION_BLOCK_ID,
338 naclbitc::GLOBALVAR_BLOCK_ID,
339 naclbitc::MODULE_BLOCK_ID,
340 naclbitc::TOP_LEVEL_BLOCKID,
341 naclbitc::TYPE_BLOCK_ID_NEW,
342 naclbitc::VALUE_SYMTAB_BLOCK_ID
343 };
344
345 } // end of anonymous namespace
346
347 NaClBitstreamReader::BlockInfoRecordsMap::
348 BlockInfoRecordsMap() : IsFrozen(false) {
349 for (size_t BlockID : ValidBlockIDs) {
350 std::unique_ptr<BlockInfo> Info(new BlockInfo(BlockID));
351 KnownInfos.emplace(BlockID, std::move(Info));
352 }
353 }
354
355 NaClBitstreamReader::BlockInfo * NaClBitstreamReader::BlockInfoRecordsMap::
356 getOrCreateUnknownBlockInfo(unsigned BlockID) {
357 std::unique_lock<std::mutex> Lock(UnknownBlockInfoLock);
358 while (true) {
359 auto Pos = UnknownInfos.find(BlockID);
360 if (Pos != UnknownInfos.end())
361 return Pos->second.get();
362 // Install, then let next iteration find.
363 std::unique_ptr<BlockInfo> Info(new BlockInfo(BlockID));
364 UnknownInfos.emplace(BlockID, std::move(Info));
365 }
366 }
367
368 NaClBitstreamReader::BlockInfoRecordsMap::UpdateLock::
369 UpdateLock(BlockInfoRecordsMap &BlockInfoRecords)
370 : BlockInfoRecords(BlockInfoRecords),
371 Lock(BlockInfoRecords.UpdateRecordsLock) {}
372
373 NaClBitstreamReader::BlockInfoRecordsMap::UpdateLock::
374 ~UpdateLock() {
375 if (BlockInfoRecords.freeze())
376 report_fatal_error("Global abbreviations block frozen while building.");
377 }
378
379 bool NaClBitstreamCursor::ReadBlockInfoBlock(NaClAbbrevListener *Listener) {
380 // If this is the second read of the block info block, skip it.
381 if (BitStream->BlockInfoRecords->isFrozen())
382 return SkipBlock();
383
384 NaClBitstreamReader::BlockInfoRecordsMap::UpdateLock
385 Lock(*BitStream->BlockInfoRecords);
386 unsigned NumWords;
387 if (EnterSubBlock(naclbitc::BLOCKINFO_BLOCK_ID, &NumWords)) return true;
388
389 if (Listener) Listener->BeginBlockInfoBlock(NumWords);
390
391 NaClBitcodeRecordVector Record;
392 Block &CurBlock = BlockScope.back();
393 NaClBitstreamReader::AbbrevList *UpdateAbbrevs =
394 &CurBlock.GlobalAbbrevs->getAbbrevs();
395 bool FoundSetBID = false;
396
397 // Read records of the BlockInfo block.
398 while (1) {
399 if (Listener) Listener->StartBit = GetCurrentBitNo();
400 NaClBitstreamEntry Entry = advance(AF_DontAutoprocessAbbrevs, Listener);
401
402 switch (Entry.Kind) {
403 case llvm::NaClBitstreamEntry::SubBlock: // PNaCl doesn't allow!
404 case llvm::NaClBitstreamEntry::Error:
405 return true;
406 case llvm::NaClBitstreamEntry::EndBlock:
407 if (Listener) Listener->EndBlockInfoBlock();
408 return false;
409 case llvm::NaClBitstreamEntry::Record:
410 // The interesting case.
411 break;
412 }
413
414 // Read abbrev records, associate them with CurBID.
415 if (Entry.ID == naclbitc::DEFINE_ABBREV) {
416 ReadAbbrevRecord(false, Listener);
417
418 // ReadAbbrevRecord installs a local abbreviation. Move it to the
419 // appropriate BlockInfo if the corresponding SetBID record has been
420 // found.
421 if (FoundSetBID)
422 CurBlock.moveLocalAbbrevToAbbrevList(UpdateAbbrevs);
423 continue;
424 }
425
426 // Read a record.
427 Record.clear();
428 switch (readRecord(Entry.ID, Record)) {
429 default:
430 // No other records should be found!
431 return true;
432 case naclbitc::BLOCKINFO_CODE_SETBID:
433 if (Record.size() < 1) return true;
434 FoundSetBID = true;
435 UpdateAbbrevs =
436 &BitStream->getBlockInfo((unsigned)Record[0])->getAbbrevs();
437 if (Listener) {
438 Listener->Values = Record;
439 Listener->SetBID();
440 }
441 break;
442 }
443 }
444 }
OLDNEW
« no previous file with comments | « pnacl-llvm/NaClBitcodeParser.cpp ('k') | pnacl-llvm/README.txt » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698