OLD | NEW |
---|---|
1 //===- NaClBitcodeMungeWriter.cpp - Write munged bitcode --------*- C++ -*-===// | 1 //===- NaClBitcodeMungeWriter.cpp - Write munged bitcode --------*- C++ -*-===// |
2 // | 2 // |
3 // The LLVM Compiler Infrastructure | 3 // The LLVM Compiler Infrastructure |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 // | 9 // |
10 // Implements method NaClMungedBitcode.write(), which writes out a munged | 10 // Implements method NaClMungedBitcode.write(), which writes out a munged |
11 // list of bitcode records using a bitstream writer. | 11 // list of bitcode records using a bitstream writer. |
12 | 12 |
13 #include "llvm/Bitcode/NaCl/NaClBitcodeMungeUtils.h" | 13 #include "llvm/Bitcode/NaCl/NaClBitcodeMungeUtils.h" |
14 | 14 |
15 #include "llvm/Bitcode/NaCl/NaClBitstreamWriter.h" | 15 #include "llvm/Bitcode/NaCl/NaClBitstreamWriter.h" |
16 #include "llvm/Bitcode/NaCl/NaClReaderWriter.h" | 16 #include "llvm/Bitcode/NaCl/NaClReaderWriter.h" |
17 #include "llvm/Support/raw_ostream.h" | 17 #include "llvm/Support/raw_ostream.h" |
18 | 18 |
19 #include <set> | |
20 | |
19 using namespace llvm; | 21 using namespace llvm; |
20 | 22 |
21 namespace { | 23 namespace { |
22 | 24 |
23 // For debugging. When true, shows trace information of emitting | 25 // For debugging. When true, shows trace information of emitting |
24 // bitcode. | 26 // bitcode. |
25 static bool DebugEmit = false; | 27 static bool DebugEmit = false; |
26 | 28 |
29 // Maximum bits that can be printed out using method | |
30 // NaClBitstreamWriter::Emit(). | |
jvoung (off chromium)
2015/05/20 22:40:09
Seems like this should be part of NaClBitstreamWri
Karl
2015/05/21 18:22:07
I agree. I originally put it there, but I didn't l
| |
31 static const unsigned MaxEmitFixedBits = 32; | |
32 | |
27 // Description of current block scope | 33 // Description of current block scope |
28 struct BlockScope { | 34 struct BlockScope { |
29 BlockScope(unsigned CurBlockID, size_t AbbrevIndexLimit) | 35 BlockScope(unsigned CurBlockID, size_t AbbrevIndexLimit) |
30 : CurBlockID(CurBlockID), AbbrevIndexLimit(AbbrevIndexLimit) {} | 36 : CurBlockID(CurBlockID), AbbrevIndexLimit(AbbrevIndexLimit), |
37 OmittedAbbreviations(false) {} | |
31 unsigned CurBlockID; | 38 unsigned CurBlockID; |
32 // Defines the maximum value for abbreviation indices in block. | 39 // Defines the maximum value for abbreviation indices in block. |
33 size_t AbbrevIndexLimit; | 40 size_t AbbrevIndexLimit; |
41 // Defines if an abbreviation definition was omitted (i.e. not | |
42 // written) from this block. Used to turn off writing further | |
43 // abbreviation definitions for this block. | |
44 bool OmittedAbbreviations; | |
34 void print(raw_ostream &Out) const { | 45 void print(raw_ostream &Out) const { |
35 Out << "BlockScope(ID=" << CurBlockID << ", AbbrevIndexLimit=" | 46 Out << "BlockScope(ID=" << CurBlockID << ", AbbrevIndexLimit=" |
36 << AbbrevIndexLimit << ")"; | 47 << AbbrevIndexLimit << "OmittedAbbreviations = " |
jvoung (off chromium)
2015/05/20 22:40:10
= spacing consistency
previous ones just did X=Y
Karl
2015/05/21 18:22:08
Done.
| |
48 << OmittedAbbreviations << ")"; | |
37 } | 49 } |
38 }; | 50 }; |
39 | 51 |
40 inline raw_ostream &operator<<(raw_ostream &Out, const BlockScope &Scope) { | 52 inline raw_ostream &operator<<(raw_ostream &Out, const BlockScope &Scope) { |
41 Scope.print(Out); | 53 Scope.print(Out); |
42 return Out; | 54 return Out; |
43 } | 55 } |
44 | 56 |
45 // State of bitcode writing. | 57 // State of bitcode writing. |
46 struct WriteState { | 58 struct WriteState { |
47 // The block ID associated with records not in any block. | 59 // The block ID associated with records not in any block. |
48 static const unsigned UnknownWriteBlockID = UINT_MAX; | 60 static const unsigned UnknownWriteBlockID = UINT_MAX; |
49 // The SetBID for the blockinfo block. | 61 // The SetBID for the blockinfo block. |
50 unsigned SetBID = UnknownWriteBlockID; | 62 unsigned SetBID = UnknownWriteBlockID; |
51 // The stack of scopes the writer is in. | 63 // The stack of scopes the writer is in. |
52 SmallVector<BlockScope, 3> ScopeStack; | 64 SmallVector<BlockScope, 3> ScopeStack; |
jvoung (off chromium)
2015/05/20 22:40:10
btw, I don't remember if this 3 was "optimized" fo
Karl
2015/05/21 18:22:07
Good point. It was optimized as you suggested. Inc
| |
53 // The set of write flags to use. | 65 // The set of write flags to use. |
54 const NaClMungedBitcode::WriteFlags &Flags; | 66 const NaClMungedBitcode::WriteFlags &Flags; |
55 // The results of the attempted write. | 67 // The results of the attempted write. |
56 NaClMungedBitcode::WriteResults Results; | 68 NaClMungedBitcode::WriteResults Results; |
57 // The minimum number of bits allowed to be specified in a block. | 69 // The minimum number of bits allowed to be specified in a block. |
58 const unsigned BlockMinBits; | 70 const unsigned BlockMinBits; |
71 // The set of block IDs for which abbreviation definitions have been | |
72 // omitted in the blockinfo block. | |
73 std::set<unsigned> BlocksWithOmittedAbbrevs; | |
jvoung (off chromium)
2015/05/20 22:40:10
Would DenseSet be better?
I suppose there are onl
Karl
2015/05/21 18:22:07
I did not expect the set to get much larger than 8
| |
59 | 74 |
60 WriteState(const NaClMungedBitcode::WriteFlags &Flags) | 75 WriteState(const NaClMungedBitcode::WriteFlags &Flags) |
61 : Flags(Flags), | 76 : Flags(Flags), |
62 BlockMinBits(NaClBitsNeededForValue(naclbitc::DEFAULT_MAX_ABBREV)) { | 77 BlockMinBits(NaClBitsNeededForValue(naclbitc::DEFAULT_MAX_ABBREV)) { |
63 BlockScope Scope(UnknownWriteBlockID, naclbitc::DEFAULT_MAX_ABBREV); | 78 BlockScope Scope(UnknownWriteBlockID, naclbitc::DEFAULT_MAX_ABBREV); |
64 ScopeStack.push_back(Scope); | 79 ScopeStack.push_back(Scope); |
65 } | 80 } |
66 | 81 |
67 // Returns stream to print error message to. | 82 // Returns stream to print error message to. |
68 raw_ostream &Error(); | 83 raw_ostream &Error(); |
(...skipping 14 matching lines...) Expand all Loading... | |
83 unsigned getCurWriteBlockID() const { | 98 unsigned getCurWriteBlockID() const { |
84 assert(!ScopeStack.empty()); | 99 assert(!ScopeStack.empty()); |
85 return ScopeStack.back().CurBlockID; | 100 return ScopeStack.back().CurBlockID; |
86 } | 101 } |
87 | 102 |
88 unsigned getCurAbbrevIndexLimit() const { | 103 unsigned getCurAbbrevIndexLimit() const { |
89 assert(!ScopeStack.empty()); | 104 assert(!ScopeStack.empty()); |
90 return ScopeStack.back().AbbrevIndexLimit; | 105 return ScopeStack.back().AbbrevIndexLimit; |
91 } | 106 } |
92 | 107 |
108 // Returns whether any abbreviation definitions were not written to | |
109 // the bitcode buffer. | |
110 bool curBlockHasOmittedAbbreviations() const { | |
111 assert(!ScopeStack.empty()); | |
112 return ScopeStack.back().OmittedAbbreviations | |
113 || BlocksWithOmittedAbbrevs.count(getCurWriteBlockID()); | |
114 } | |
115 | |
116 // Marks that an abbreviation definition is being omitted (i.e. not | |
117 // written) for the current block. | |
118 void markCurrentBlockWithOmittedAbbreviations() { | |
119 assert(!ScopeStack.empty()); | |
120 ScopeStack.back().OmittedAbbreviations = true; | |
121 if (getCurWriteBlockID() == naclbitc::BLOCKINFO_BLOCK_ID) | |
122 BlocksWithOmittedAbbrevs.insert(SetBID); | |
123 return; | |
jvoung (off chromium)
2015/05/20 22:40:10
The return doesn't seem to do much so may be bette
Karl
2015/05/21 18:22:08
Hmm. I guess this is a leftover of an earlier vers
| |
124 } | |
125 | |
93 // Converts the abbreviation record to the corresponding abbreviation. | 126 // Converts the abbreviation record to the corresponding abbreviation. |
94 // Returns nullptr if unable to build abbreviation. | 127 // Returns nullptr if unable to build abbreviation. |
95 NaClBitCodeAbbrev *buildAbbrev(const NaClBitcodeAbbrevRecord &Record); | 128 NaClBitCodeAbbrev *buildAbbrev(const NaClBitcodeAbbrevRecord &Record); |
96 | 129 |
97 // Emits the given record to the bitcode file. Returns true if | 130 // Emits the given record to the bitcode file. Returns true if |
98 // successful. | 131 // successful. |
99 bool LLVM_ATTRIBUTE_UNUSED_RESULT | 132 bool LLVM_ATTRIBUTE_UNUSED_RESULT |
100 emitRecord(NaClBitstreamWriter &Writer, const NaClBitcodeAbbrevRecord &Record) ; | 133 emitRecord(NaClBitstreamWriter &Writer, |
134 const NaClBitcodeAbbrevRecord &Record); | |
101 | 135 |
102 // Enter the given block | 136 // Enter the given block |
103 bool LLVM_ATTRIBUTE_UNUSED_RESULT | 137 bool LLVM_ATTRIBUTE_UNUSED_RESULT |
104 enterBlock(NaClBitstreamWriter &Writer, uint64_t WriteBlockID, | 138 enterBlock(NaClBitstreamWriter &Writer, uint64_t WriteBlockID, |
105 uint64_t NumBits, const NaClBitcodeAbbrevRecord &Record); | 139 uint64_t NumBits, const NaClBitcodeAbbrevRecord &Record); |
106 | 140 |
107 // Exit current block and return to previous block. Silently recovers | 141 // Exit current block and return to previous block. Silently recovers |
108 // if at outermost scope. | 142 // if at outermost scope. |
109 bool LLVM_ATTRIBUTE_UNUSED_RESULT | 143 bool LLVM_ATTRIBUTE_UNUSED_RESULT |
110 exitBlock(NaClBitstreamWriter &Writer, | 144 exitBlock(NaClBitstreamWriter &Writer, |
111 const NaClBitcodeAbbrevRecord *Record = nullptr) { | 145 const NaClBitcodeAbbrevRecord *Record = nullptr) { |
112 if (atOutermostScope()) | 146 if (atOutermostScope()) |
113 return false; | 147 return false; |
114 Writer.ExitBlock(); | 148 Writer.ExitBlock(); |
115 ScopeStack.pop_back(); | 149 ScopeStack.pop_back(); |
116 if (DebugEmit) | 150 if (DebugEmit) |
117 printScopeStack(errs()); | 151 printScopeStack(errs()); |
118 return true; | 152 return true; |
119 } | 153 } |
120 | 154 |
155 void WriteRecord(NaClBitstreamWriter &Writer, | |
156 const NaClBitcodeAbbrevRecord &Record, | |
157 bool UsesDefaultAbbrev) { | |
158 if (UsesDefaultAbbrev) | |
159 Writer.EmitRecord(Record.Code, Record.Values); | |
160 else | |
161 Writer.EmitRecord(Record.Code, Record.Values, Record.Abbrev); | |
162 | |
163 } | |
164 | |
165 // Returns true if the abbreviation index defines an anbbreviation | |
jvoung (off chromium)
2015/05/20 22:40:09
anbbreviation -> ?
Karl
2015/05/21 18:22:07
Fixed.
| |
166 // that can be applied to the record. | |
167 bool LLVM_ATTRIBUTE_UNUSED_RESULT | |
168 canApplyAbbreviation(NaClBitstreamWriter &Writer, | |
169 const NaClBitcodeAbbrevRecord &Record); | |
170 | |
121 // Completes the write. | 171 // Completes the write. |
122 NaClMungedBitcode::WriteResults &finish(NaClBitstreamWriter &Writer, | 172 NaClMungedBitcode::WriteResults &finish(NaClBitstreamWriter &Writer, |
123 bool RecoverSilently); | 173 bool RecoverSilently); |
124 | 174 |
125 void printScopeStack(raw_ostream &Out) { | 175 void printScopeStack(raw_ostream &Out) { |
126 Out << "Scope Stack:\n"; | 176 Out << "Scope Stack:\n"; |
127 for (auto &Scope : ScopeStack) | 177 for (auto &Scope : ScopeStack) |
128 Out << " " << Scope << "\n"; | 178 Out << " " << Scope << "\n"; |
129 } | 179 } |
130 }; | 180 }; |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
178 return false; | 228 return false; |
179 } | 229 } |
180 Writer.EnterBlockInfoBlock(); | 230 Writer.EnterBlockInfoBlock(); |
181 } else { | 231 } else { |
182 NaClBitcodeSelectorAbbrev CurCodeLen(MaxAbbrev); | 232 NaClBitcodeSelectorAbbrev CurCodeLen(MaxAbbrev); |
183 Writer.EnterSubblock(WriteBlockID, CurCodeLen); | 233 Writer.EnterSubblock(WriteBlockID, CurCodeLen); |
184 } | 234 } |
185 return true; | 235 return true; |
186 } | 236 } |
187 | 237 |
238 bool WriteState::canApplyAbbreviation( | |
239 NaClBitstreamWriter &Writer, const NaClBitcodeAbbrevRecord &Record) { | |
Karl
2015/05/20 20:32:04
Added following two lines to make sure that the bl
jvoung (off chromium)
2015/05/20 22:40:09
Does the Writer.getAbbreviation(...); if (Abbrev =
Karl
2015/05/21 18:22:07
This check helps. I didn't see the case until the
| |
240 if (Record.Abbrev > getCurAbbrevIndexLimit()) | |
241 return false; | |
242 | |
243 const NaClBitCodeAbbrev *Abbrev = Writer.getAbbreviation(Record.Abbrev); | |
244 if (Abbrev == nullptr) | |
245 return false; | |
246 | |
247 // Merge record code into values and then match abbreviation. | |
248 NaClBitcodeValues Values(Record); | |
249 size_t ValueIndex = 0; | |
250 size_t ValuesSize = Values.size(); | |
251 size_t AbbrevIndex = 0; | |
252 size_t AbbrevSize = Abbrev->getNumOperandInfos(); | |
253 bool FoundArray = false; | |
254 while (ValueIndex < ValuesSize && AbbrevIndex < AbbrevSize) { | |
255 const NaClBitCodeAbbrevOp *Op = &Abbrev->getOperandInfo(AbbrevIndex++); | |
256 uint64_t Value = Values[ValueIndex++]; | |
257 if (Op->getEncoding() == NaClBitCodeAbbrevOp::Array) { | |
258 if (AbbrevIndex + 1 != AbbrevSize) | |
259 return false; | |
260 Op = &Abbrev->getOperandInfo(AbbrevIndex); | |
261 --AbbrevIndex; // i.e. don't advance to next abbreviation op. | |
262 FoundArray = true; | |
263 } | |
264 switch (Op->getEncoding()) { | |
265 case NaClBitCodeAbbrevOp::Literal: | |
266 if (Value != Op->getValue()) | |
267 return false; | |
268 continue; | |
269 case NaClBitCodeAbbrevOp::Fixed: | |
270 if (Value >= (static_cast<uint64_t>(1) < MaxEmitFixedBits) | |
jvoung (off chromium)
2015/05/20 22:40:10
I assume this should actually be a shift and not (
Karl
2015/05/21 18:22:07
Yes. Fixing.
| |
271 || NaClBitsNeededForValue(Value) > Op->getValue()) | |
272 return false; | |
273 continue; | |
274 case NaClBitCodeAbbrevOp::VBR: | |
275 if (Op->getValue() < 2) | |
276 return false; | |
277 continue; | |
278 case NaClBitCodeAbbrevOp::Array: | |
279 // This should not happen | |
jvoung (off chromium)
2015/05/20 22:40:10
llvm_unreachable(...);
Karl
2015/05/21 18:22:08
Done.
| |
280 return false; | |
281 case NaClBitCodeAbbrevOp::Char6: | |
282 if (!Op->isChar6(Value)) | |
283 return false; | |
284 continue; | |
285 } | |
286 } | |
287 return ValueIndex == ValuesSize && (FoundArray || AbbrevIndex == AbbrevSize); | |
288 } | |
289 | |
188 NaClMungedBitcode::WriteResults &WriteState::finish( | 290 NaClMungedBitcode::WriteResults &WriteState::finish( |
189 NaClBitstreamWriter &Writer, bool RecoverSilently) { | 291 NaClBitstreamWriter &Writer, bool RecoverSilently) { |
190 // Be sure blocks are balanced. | 292 // Be sure blocks are balanced. |
191 while (!atOutermostScope()) { | 293 while (!atOutermostScope()) { |
192 if (!RecoverSilently) | 294 if (!RecoverSilently) |
193 RecoverableError() << "Missing close block.\n"; | 295 RecoverableError() << "Missing close block.\n"; |
194 if (!exitBlock(Writer)) { | 296 if (!exitBlock(Writer)) { |
195 Error() << "Failed to add missing close block at end of file.\n"; | 297 Error() << "Failed to add missing close block at end of file.\n"; |
196 break; | 298 break; |
197 } | 299 } |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
268 << Record << "\n"; | 370 << Record << "\n"; |
269 return false; | 371 return false; |
270 } | 372 } |
271 break; | 373 break; |
272 } | 374 } |
273 case naclbitc::BLK_CODE_DEFINE_ABBREV: { | 375 case naclbitc::BLK_CODE_DEFINE_ABBREV: { |
274 if (Record.Abbrev != naclbitc::DEFINE_ABBREV) { | 376 if (Record.Abbrev != naclbitc::DEFINE_ABBREV) { |
275 RecoverableError() | 377 RecoverableError() |
276 << "Uses illegal abbreviation index in define abbreviation record: " | 378 << "Uses illegal abbreviation index in define abbreviation record: " |
277 << Record << "\n"; | 379 << Record << "\n"; |
380 markCurrentBlockWithOmittedAbbreviations(); | |
278 if (!Flags.getTryToRecover()) | 381 if (!Flags.getTryToRecover()) |
jvoung (off chromium)
2015/05/20 22:40:10
Might be simpler to just return now like the other
Karl
2015/05/21 18:22:07
I agree that the check for omitted abbreviations s
| |
279 return false; | 382 return false; |
280 } | 383 } |
384 if (curBlockHasOmittedAbbreviations()) { | |
385 // If reached, a previous abbreviation for the block was omitted. Can't | |
386 // generate more abbreviations without having to fix abbreviation indices. | |
387 RecoverableError() << "Ignoring abbreviation: " << Record << "\n"; | |
388 return Flags.getTryToRecover(); | |
389 } | |
281 if (getCurWriteBlockID() != naclbitc::BLOCKINFO_BLOCK_ID | 390 if (getCurWriteBlockID() != naclbitc::BLOCKINFO_BLOCK_ID |
282 && Writer.getMaxCurAbbrevIndex() >= getCurAbbrevIndexLimit()) { | 391 && Writer.getMaxCurAbbrevIndex() >= getCurAbbrevIndexLimit()) { |
283 RecoverableError() << "Exceeds abbreviation index limit of " | 392 RecoverableError() << "Exceeds abbreviation index limit of " |
284 << getCurAbbrevIndexLimit() << ": " << Record << "\n"; | 393 << getCurAbbrevIndexLimit() << ": " << Record << "\n"; |
285 // Recover by not writing. | 394 // Recover by not writing. |
395 markCurrentBlockWithOmittedAbbreviations(); | |
286 return Flags.getTryToRecover(); | 396 return Flags.getTryToRecover(); |
287 } | 397 } |
288 NaClBitCodeAbbrev *Abbrev = buildAbbrev(Record); | 398 NaClBitCodeAbbrev *Abbrev = buildAbbrev(Record); |
289 if (Abbrev == NULL) | 399 if (Abbrev == nullptr) { |
400 markCurrentBlockWithOmittedAbbreviations(); | |
290 return Flags.getTryToRecover(); | 401 return Flags.getTryToRecover(); |
402 } | |
291 if (getCurWriteBlockID() == naclbitc::BLOCKINFO_BLOCK_ID) { | 403 if (getCurWriteBlockID() == naclbitc::BLOCKINFO_BLOCK_ID) { |
292 Writer.EmitBlockInfoAbbrev(SetBID, Abbrev); | 404 Writer.EmitBlockInfoAbbrev(SetBID, Abbrev); |
293 } else { | 405 } else { |
294 Writer.EmitAbbrev(Abbrev); | 406 Writer.EmitAbbrev(Abbrev); |
295 } | 407 } |
296 break; | 408 break; |
297 } | 409 } |
298 case naclbitc::BLK_CODE_HEADER: | 410 case naclbitc::BLK_CODE_HEADER: |
299 // Note: There is no abbreviation index here. Ignore. | 411 // Note: There is no abbreviation index here. Ignore. |
300 for (uint64_t Value : Record.Values) | 412 for (uint64_t Value : Record.Values) |
301 Writer.Emit(Value, 8); | 413 Writer.Emit(Value, 8); |
302 break; | 414 break; |
303 default: | 415 default: |
304 bool UsesDefaultAbbrev = Record.Abbrev == naclbitc::UNABBREV_RECORD; | 416 bool UsesDefaultAbbrev = Record.Abbrev == naclbitc::UNABBREV_RECORD; |
305 if (atOutermostScope()) { | 417 if (atOutermostScope()) { |
306 RecoverableError() << "Record outside block: " << Record << "\n"; | 418 RecoverableError() << "Record outside block: " << Record << "\n"; |
307 if (!Flags.getTryToRecover()) | 419 if (!Flags.getTryToRecover()) |
308 return false; | 420 return false; |
309 // Create a dummy block to hold record. | 421 // Create a dummy block to hold record. |
310 if (!enterBlock(Writer, UnknownWriteBlockID, | 422 if (!enterBlock(Writer, UnknownWriteBlockID, |
311 naclbitc::DEFAULT_MAX_ABBREV, Record)) { | 423 naclbitc::DEFAULT_MAX_ABBREV, Record)) { |
312 Error() << "Failed to recover from record outside block\n"; | 424 Error() << "Failed to recover from record outside block\n"; |
313 return false; | 425 return false; |
314 } | 426 } |
315 UsesDefaultAbbrev = true; | 427 UsesDefaultAbbrev = true; |
316 } | 428 } |
317 if (!UsesDefaultAbbrev | 429 if (!UsesDefaultAbbrev && !canApplyAbbreviation(Writer, Record)) { |
318 && !Writer.isUserRecordAbbreviation(Record.Abbrev)) { | 430 // Can't apply abbreviation, figure out why. |
319 // Illegal abbreviation index found. | 431 if (Writer.getAbbreviation(Record.Abbrev) != nullptr) { |
432 RecoverableError() << "Abbreviation doesn't apply to record: " | |
jvoung (off chromium)
2015/05/20 22:40:09
So here the abbreviation exists, but doesn't apply
Karl
2015/05/21 18:22:07
Yes.
| |
433 << Record << "\n"; | |
434 UsesDefaultAbbrev = true; | |
435 WriteRecord(Writer, Record, UsesDefaultAbbrev); | |
jvoung (off chromium)
2015/05/20 22:40:09
This and the one below might be the first case whe
Karl
2015/05/21 18:22:08
Done.
| |
436 return Flags.getTryToRecover(); | |
437 } | |
320 if (Flags.getWriteBadAbbrevIndex()) { | 438 if (Flags.getWriteBadAbbrevIndex()) { |
jvoung (off chromium)
2015/05/20 22:40:10
Maybe add a comment here. This CL adds the "figure
Karl
2015/05/21 18:22:08
Removed the first comment, and added a comment to
| |
321 Error() << "Uses illegal abbreviation index: " << Record << "\n"; | 439 Error() << "Uses illegal abbreviation index: " << Record << "\n"; |
322 // Generate bad abbreviation index so that the bitcode reader | 440 // Generate bad abbreviation index so that the bitcode reader |
323 // can be tested, and then quit. | 441 // can be tested, and then quit. |
324 Results.WroteBadAbbrevIndex = true; | 442 Results.WroteBadAbbrevIndex = true; |
325 Writer.EmitCode(Record.Abbrev); | 443 Writer.EmitCode(Record.Abbrev); |
326 bool RecoverSilently = true; | 444 bool RecoverSilently = true; |
327 finish(Writer, RecoverSilently); | 445 finish(Writer, RecoverSilently); |
328 return false; | 446 return false; |
329 } | 447 } |
330 RecoverableError() << "Uses illegal abbreviation index: " | 448 RecoverableError() << "Uses illegal abbreviation index: " |
331 << Record << "\n"; | 449 << Record << "\n"; |
332 if (!Flags.getTryToRecover()) | |
333 return false; | |
334 UsesDefaultAbbrev = true; | 450 UsesDefaultAbbrev = true; |
451 WriteRecord(Writer, Record, UsesDefaultAbbrev); | |
452 return Flags.getTryToRecover(); | |
335 } | 453 } |
336 if (getCurWriteBlockID() == naclbitc::BLOCKINFO_BLOCK_ID | 454 if (getCurWriteBlockID() == naclbitc::BLOCKINFO_BLOCK_ID |
337 && Record.Code == naclbitc::BLOCKINFO_CODE_SETBID) { | 455 && Record.Code == naclbitc::BLOCKINFO_CODE_SETBID) { |
338 // Note: SetBID records are handled by Writer->EmitBlockInfoAbbrev, | 456 // Note: SetBID records are handled by Writer->EmitBlockInfoAbbrev, |
339 // based on the SetBID value. Don't bother to generate SetBID record here. | 457 // based on the SetBID value. Don't bother to generate SetBID record here. |
340 // Rather just set SetBID and let call to Writer->EmitBlockInfoAbbrev | 458 // Rather just set SetBID and let call to Writer->EmitBlockInfoAbbrev |
341 // generate the SetBID record. | 459 // generate the SetBID record. |
342 if (NumValues != 1) { | 460 if (NumValues != 1) { |
343 Error() << "SetBID record expects 1 value but found " | 461 Error() << "SetBID record expects 1 value but found " |
344 << NumValues << ": " << Record << "\n"; | 462 << NumValues << ": " << Record << "\n"; |
345 return false; | 463 return false; |
346 } | 464 } |
347 SetBID = Record.Values[0]; | 465 SetBID = Record.Values[0]; |
348 return true; | 466 return true; |
349 } | 467 } |
350 if (UsesDefaultAbbrev) | 468 WriteRecord(Writer, Record, UsesDefaultAbbrev); |
351 Writer.EmitRecord(Record.Code, Record.Values); | 469 break; |
352 else | |
353 Writer.EmitRecord(Record.Code, Record.Values, Record.Abbrev); | |
354 } | 470 } |
355 return true; | 471 return true; |
356 } | 472 } |
357 | 473 |
358 static NaClBitCodeAbbrev *deleteAbbrev(NaClBitCodeAbbrev *Abbrev) { | 474 static NaClBitCodeAbbrev *deleteAbbrev(NaClBitCodeAbbrev *Abbrev) { |
359 Abbrev->dropRef(); | 475 Abbrev->dropRef(); |
360 return nullptr; | 476 return nullptr; |
361 } | 477 } |
362 | 478 |
363 NaClBitCodeAbbrev *WriteState::buildAbbrev( | 479 NaClBitCodeAbbrev *WriteState::buildAbbrev( |
(...skipping 10 matching lines...) Expand all Loading... | |
374 size_t NumAbbreviations = Record.Values[Index++]; | 490 size_t NumAbbreviations = Record.Values[Index++]; |
375 if (NumAbbreviations == 0) { | 491 if (NumAbbreviations == 0) { |
376 RecoverableError() << "Abbreviation must contain at least one operator: " | 492 RecoverableError() << "Abbreviation must contain at least one operator: " |
377 << Record << "\n"; | 493 << Record << "\n"; |
378 return deleteAbbrev(Abbrev); | 494 return deleteAbbrev(Abbrev); |
379 } | 495 } |
380 for (size_t Count = 0; Count < NumAbbreviations; ++Count) { | 496 for (size_t Count = 0; Count < NumAbbreviations; ++Count) { |
381 if (Index >= NumValues) { | 497 if (Index >= NumValues) { |
382 RecoverableError() | 498 RecoverableError() |
383 << "Malformed abbreviation found. Expects " << NumAbbreviations | 499 << "Malformed abbreviation found. Expects " << NumAbbreviations |
384 << " operands but ound " << Count << ": " << Record << "\n"; | 500 << " operands but found " << Count << ": " << Record << "\n"; |
385 return deleteAbbrev(Abbrev); | 501 return deleteAbbrev(Abbrev); |
386 } | 502 } |
387 switch (Record.Values[Index++]) { | 503 switch (Record.Values[Index++]) { |
388 case 1: | 504 case 1: |
389 if (Index >= NumValues) { | 505 if (Index >= NumValues) { |
390 RecoverableError() << "Malformed literal abbreviation: " | 506 RecoverableError() << "Malformed literal abbreviation: " |
391 << Record << "\n"; | 507 << Record << "\n"; |
392 return deleteAbbrev(Abbrev); | 508 return deleteAbbrev(Abbrev); |
393 } | 509 } |
394 Abbrev->Add(NaClBitCodeAbbrevOp(Record.Values[Index++])); | 510 Abbrev->Add(NaClBitCodeAbbrevOp(Record.Values[Index++])); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
431 Abbrev->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Char6)); | 547 Abbrev->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Char6)); |
432 break; | 548 break; |
433 default: | 549 default: |
434 RecoverableError() << "Unknown abbreviation kind " << Kind | 550 RecoverableError() << "Unknown abbreviation kind " << Kind |
435 << ": " << Record << "\n"; | 551 << ": " << Record << "\n"; |
436 return deleteAbbrev(Abbrev); | 552 return deleteAbbrev(Abbrev); |
437 } | 553 } |
438 break; | 554 break; |
439 } | 555 } |
440 default: | 556 default: |
441 RecoverableError() << "Error: Bad literal flag " << Record.Values[Index] | 557 RecoverableError() << "Error: Bad abbreviation operand encoding " |
442 << ": " << Record << "\n"; | 558 << Record.Values[Index-1] << ": " << Record << "\n"; |
443 return deleteAbbrev(Abbrev); | 559 return deleteAbbrev(Abbrev); |
444 } | 560 } |
445 } | 561 } |
446 return Abbrev; | 562 return Abbrev; |
447 } | 563 } |
448 | 564 |
449 } // end of anonymous namespace. | 565 } // end of anonymous namespace. |
450 | 566 |
451 NaClMungedBitcode::WriteResults NaClMungedBitcode::writeMaybeRepair( | 567 NaClMungedBitcode::WriteResults NaClMungedBitcode::writeMaybeRepair( |
452 SmallVectorImpl<char> &Buffer, bool AddHeader, | 568 SmallVectorImpl<char> &Buffer, bool AddHeader, |
453 const WriteFlags &Flags) const { | 569 const WriteFlags &Flags) const { |
454 NaClBitstreamWriter Writer(Buffer); | 570 NaClBitstreamWriter Writer(Buffer); |
455 WriteState State(Flags); | 571 WriteState State(Flags); |
456 if (AddHeader) { | 572 if (AddHeader) { |
457 NaClWriteHeader(Writer, true); | 573 NaClWriteHeader(Writer, true); |
458 } | 574 } |
459 for (const NaClBitcodeAbbrevRecord &Record : *this) { | 575 for (const NaClBitcodeAbbrevRecord &Record : *this) { |
460 if (!State.emitRecord(Writer, Record)) | 576 if (!State.emitRecord(Writer, Record)) |
461 break; | 577 break; |
462 } | 578 } |
463 bool RecoverSilently = | 579 bool RecoverSilently = |
464 State.Results.NumErrors > 0 && !Flags.getTryToRecover(); | 580 State.Results.NumErrors > 0 && !Flags.getTryToRecover(); |
465 return State.finish(Writer, RecoverSilently); | 581 return State.finish(Writer, RecoverSilently); |
466 } | 582 } |
OLD | NEW |