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

Side by Side Diff: lib/Bitcode/NaCl/TestUtils/NaClBitcodeMungeWriter.cpp

Issue 1146203003: Fix abbreviation handling in munged bitcode writer. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-llvm.git@master
Patch Set: Don't allow application of abbreviation if index out of range. 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 //===- 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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698