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

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

Issue 1139673004: Harden writer of munged bitcode for fuzzing (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-llvm.git@master
Patch Set: Fix issues in last patch. 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
« no previous file with comments | « lib/Bitcode/NaCl/TestUtils/NaClBitcodeMungeUtils.cpp ('k') | unittests/Bitcode/CMakeLists.txt » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 18
18 using namespace llvm; 19 using namespace llvm;
19 20
20 namespace { 21 namespace {
21 22
22 // For debugging. When true, shows each PNaCl record that is 23 // For debugging. When true, shows trace information of emitting
23 // emitted to the bitcode file. 24 // bitcode.
24 static bool DebugEmitRecord = false; 25 static bool DebugEmit = false;
26
27 // Description of current block scope
28 struct BlockScope {
29 BlockScope(unsigned CurBlockID, size_t AbbrevIndexLimit)
30 : CurBlockID(CurBlockID), AbbrevIndexLimit(AbbrevIndexLimit) {}
31 unsigned CurBlockID;
32 // Defines the maximum value for abbreviation indices in block.
33 size_t AbbrevIndexLimit;
34 void print(raw_ostream &Out) const {
35 Out << "BlockScope(ID=" << CurBlockID << ", AbbrevIndexLimit="
36 << AbbrevIndexLimit << ")";
37 }
38 };
39
40 inline raw_ostream &operator<<(raw_ostream &Out, const BlockScope &Scope) {
41 Scope.print(Out);
42 return Out;
43 }
25 44
26 // State of bitcode writing. 45 // State of bitcode writing.
27 struct WriteState { 46 struct WriteState {
28 // The block ID associated with the block being written. 47 // The block ID associated with records not in any block.
29 int WriteBlockID = -1; 48 static const unsigned UnknownWriteBlockID = UINT_MAX;
30 // The SetBID for the blockinfo block. 49 // The SetBID for the blockinfo block.
31 int SetBID = -1; 50 unsigned SetBID = UnknownWriteBlockID;
32 // The stack of maximum abbreviation indices allowed by block enter record. 51 // The stack of scopes the writer is in.
33 SmallVector<uint64_t, 3> AbbrevIndexLimitStack; 52 SmallVector<BlockScope, 3> ScopeStack;
34 // The set of write flags to use. 53 // The set of write flags to use.
35 const NaClMungedBitcode::WriteFlags &Flags; 54 const NaClMungedBitcode::WriteFlags &Flags;
36 // The results of the attempted write. 55 // The results of the attempted write.
37 NaClMungedBitcode::WriteResults Results; 56 NaClMungedBitcode::WriteResults Results;
57 // The minimum number of bits allowed to be specified in a block.
58 const unsigned BlockMinBits;
38 59
39 WriteState(const NaClMungedBitcode::WriteFlags &Flags) : Flags(Flags) {} 60 WriteState(const NaClMungedBitcode::WriteFlags &Flags)
61 : Flags(Flags),
62 BlockMinBits(NaClBitsNeededForValue(naclbitc::DEFAULT_MAX_ABBREV)) {
63 BlockScope Scope(UnknownWriteBlockID, naclbitc::DEFAULT_MAX_ABBREV);
64 ScopeStack.push_back(Scope);
65 }
40 66
41 // Returns stream to print error message to. 67 // Returns stream to print error message to.
42 raw_ostream &Error() { 68 raw_ostream &Error();
43 ++Results.NumErrors;
44 return Flags.getErrStream() << "Error (Block " << WriteBlockID << "): ";
45 }
46 69
47 // Returns stream to print error message to, assuming that 70 // Returns stream to print error message to, assuming that
48 // the error message can be repaired if Flags.TryToRecover is true. 71 // the error message can be repaired if Flags.TryToRecover is true.
49 raw_ostream &RecoverableError() { 72 raw_ostream &RecoverableError() {
50 if (Flags.getTryToRecover()) 73 if (Flags.getTryToRecover())
51 ++Results.NumRepairs; 74 ++Results.NumRepairs;
52 return Error(); 75 return Error();
53 } 76 }
54 77
78 bool atOutermostScope() {
79 assert(!ScopeStack.empty());
80 return ScopeStack.size() == 1;
81 }
82
83 unsigned getCurWriteBlockID() const {
84 assert(!ScopeStack.empty());
85 return ScopeStack.back().CurBlockID;
86 }
87
88 unsigned getCurAbbrevIndexLimit() const {
89 assert(!ScopeStack.empty());
90 return ScopeStack.back().AbbrevIndexLimit;
91 }
92
55 // Converts the abbreviation record to the corresponding abbreviation. 93 // Converts the abbreviation record to the corresponding abbreviation.
56 // Returns nullptr if unable to build abbreviation. 94 // Returns nullptr if unable to build abbreviation.
57 NaClBitCodeAbbrev *buildAbbrev(const NaClBitcodeAbbrevRecord &Record); 95 NaClBitCodeAbbrev *buildAbbrev(const NaClBitcodeAbbrevRecord &Record);
58 96
59 // Emits the given record to the bitcode file. Returns true if 97 // Emits the given record to the bitcode file. Returns true if
60 // successful. 98 // successful.
61 bool emitRecord(NaClBitstreamWriter &Writer, 99 bool LLVM_ATTRIBUTE_UNUSED_RESULT
62 const NaClBitcodeAbbrevRecord &Record); 100 emitRecord(NaClBitstreamWriter &Writer, const NaClBitcodeAbbrevRecord &Record) ;
63 101
64 // Adds any missing end blocks to written bitcode. 102 // Enter the given block
65 void writeMissingEndBlocks(NaClBitstreamWriter &Writer) { 103 bool LLVM_ATTRIBUTE_UNUSED_RESULT
66 while (!AbbrevIndexLimitStack.empty()) { 104 enterBlock(NaClBitstreamWriter &Writer, uint64_t WriteBlockID,
67 Writer.ExitBlock(); 105 uint64_t NumBits, const NaClBitcodeAbbrevRecord &Record);
68 AbbrevIndexLimitStack.pop_back(); 106
107 // Exit current block and return to previous block. Silently recovers
108 // if at outermost scope.
109 bool LLVM_ATTRIBUTE_UNUSED_RESULT
110 exitBlock(NaClBitstreamWriter &Writer,
111 const NaClBitcodeAbbrevRecord *Record = nullptr) {
112 if (atOutermostScope())
113 return false;
114 Writer.ExitBlock();
115 ScopeStack.pop_back();
116 if (DebugEmit)
117 printScopeStack(errs());
118 return true;
119 }
120
121 // Completes the write.
122 NaClMungedBitcode::WriteResults &finish(NaClBitstreamWriter &Writer,
123 bool RecoverSilently);
124
125 void printScopeStack(raw_ostream &Out) {
126 Out << "Scope Stack:\n";
127 for (auto &Scope : ScopeStack)
128 Out << " " << Scope << "\n";
129 }
130 };
131
132 raw_ostream &WriteState::Error() {
133 ++Results.NumErrors;
134 raw_ostream &ErrStrm = Flags.getErrStream();
135 unsigned WriteBlockID = getCurWriteBlockID();
136 ErrStrm << "Error (Block ";
137 if (WriteBlockID == UnknownWriteBlockID)
138 ErrStrm << "unknown";
139 else
140 ErrStrm << WriteBlockID;
141 return ErrStrm << "): ";
142 }
143
144 bool WriteState::enterBlock(NaClBitstreamWriter &Writer, uint64_t WriteBlockID,
145 uint64_t NumBits,
146 const NaClBitcodeAbbrevRecord &Record) {
147 if (NumBits < BlockMinBits || NumBits > naclbitc::MaxAbbrevWidth) {
148 RecoverableError()
149 << "Block index bit limit " << NumBits << " invalid. Must be in ["
150 << BlockMinBits << ".." << naclbitc::MaxAbbrevWidth << "]: "
151 << Record << "\n";
152 if (!Flags.getTryToRecover())
153 return false;
154 NumBits = naclbitc::MaxAbbrevWidth;
155 }
156 if (WriteBlockID > UINT_MAX) {
157 RecoverableError() << "Block id must be <= " << UINT_MAX
158 << ": " << Record << "\n";
159 if (!Flags.getTryToRecover())
160 return false;
161 WriteBlockID = UnknownWriteBlockID;
162 }
163
164 uint64_t MaxAbbrev = (static_cast<uint64_t>(1) << NumBits) - 1;
165 BlockScope Scope(WriteBlockID, MaxAbbrev);
166 ScopeStack.push_back(Scope);
167 if (DebugEmit)
168 printScopeStack(errs());
169 if (WriteBlockID == naclbitc::BLOCKINFO_BLOCK_ID) {
170 unsigned DefaultMaxBits =
171 NaClBitsNeededForValue(naclbitc::DEFAULT_MAX_ABBREV);
172 if (NumBits != DefaultMaxBits) {
173 RecoverableError()
174 << "Numbits entry for abbreviations record not "
175 << DefaultMaxBits << " but found " << NumBits <<
176 ": " << Record << "\n";
177 if (!Flags.getTryToRecover())
178 return false;
179 }
180 Writer.EnterBlockInfoBlock();
181 } else {
182 NaClBitcodeSelectorAbbrev CurCodeLen(MaxAbbrev);
183 Writer.EnterSubblock(WriteBlockID, CurCodeLen);
184 }
185 return true;
186 }
187
188 NaClMungedBitcode::WriteResults &WriteState::finish(
189 NaClBitstreamWriter &Writer, bool RecoverSilently) {
190 // Be sure blocks are balanced.
191 while (!atOutermostScope()) {
192 if (!RecoverSilently)
193 RecoverableError() << "Missing close block.\n";
194 if (!exitBlock(Writer)) {
195 Error() << "Failed to add missing close block at end of file.\n";
196 break;
69 } 197 }
70 } 198 }
71 }; 199
200 // Be sure that generated bitcode buffer is word aligned.
201 if (Writer.GetCurrentBitNo() % 4 * CHAR_BIT) {
202 if (!RecoverSilently)
203 RecoverableError() << "Written bitstream not word aligned\n";
204 // Force a repair so that the bitstream writer doesn't crash.
205 Writer.FlushToWord();
206 }
207 return Results;
208 }
72 209
73 bool WriteState::emitRecord(NaClBitstreamWriter &Writer, 210 bool WriteState::emitRecord(NaClBitstreamWriter &Writer,
74 const NaClBitcodeAbbrevRecord &Record) { 211 const NaClBitcodeAbbrevRecord &Record) {
75 size_t NumValues = Record.Values.size(); 212 size_t NumValues = Record.Values.size();
76 if (DebugEmitRecord) { 213 if (DebugEmit) {
77 errs() << "Emit " << Record.Abbrev << ": <" << Record.Code; 214 errs() << "Emit " << Record.Abbrev << ": <" << Record.Code;
78 for (size_t i = 0; i < NumValues; ++i) { 215 for (size_t i = 0; i < NumValues; ++i) {
79 errs() << ", " << Record.Values[i]; 216 errs() << ", " << Record.Values[i];
80 } 217 }
81 errs() << ">\n"; 218 errs() << ">\n";
82 } 219 }
83 220
84 switch (Record.Code) { 221 switch (Record.Code) {
85 case naclbitc::BLK_CODE_ENTER: { 222 case naclbitc::BLK_CODE_ENTER: {
86 unsigned NumBits = NaClBitsNeededForValue(naclbitc::DEFAULT_MAX_ABBREV); 223 uint64_t WriteBlockID = UnknownWriteBlockID;
87 WriteBlockID = -1; 224 uint64_t NumBits = naclbitc::MaxAbbrevWidth; // Default to safest value.
88 if (Record.Abbrev != naclbitc::ENTER_SUBBLOCK) { 225 if (Record.Abbrev != naclbitc::ENTER_SUBBLOCK) {
89 RecoverableError() 226 RecoverableError()
90 << "Uses illegal abbreviation index in enter block record: " 227 << "Uses illegal abbreviation index in enter block record: "
91 << Record << "\n"; 228 << Record << "\n";
92 if (!Flags.getTryToRecover()) 229 if (!Flags.getTryToRecover())
93 return false; 230 return false;
94 } 231 }
95 if (NumValues == 2) { 232 if (NumValues != 2) {
233 RecoverableError()
234 << "Values for enter record should be of size 2, but found "
235 << NumValues << ": " << Record << "\n";
236 if (!Flags.getTryToRecover())
237 return false;
238 }
239 if (NumValues > 0)
96 WriteBlockID = Record.Values[0]; 240 WriteBlockID = Record.Values[0];
241 if (NumValues > 1)
97 NumBits = Record.Values[1]; 242 NumBits = Record.Values[1];
98 if (NumBits > 32 || NumBits < 2) { 243 return enterBlock(Writer, WriteBlockID, NumBits, Record);
99 RecoverableError() 244 }
100 << "Bit size " << NumBits << " for record should be " 245 case naclbitc::BLK_CODE_EXIT: {
101 << (NumBits > 32 ? "<= 32" : ">= 2") << ": " << Record << "\n"; 246 if (atOutermostScope()) {
102 if (!Flags.getTryToRecover()) 247 RecoverableError()
103 return false; 248 << "Extraneous exit block: " << Record << "\n";
104 NumBits = 32; 249 if (!Flags.getTryToRecover())
105 } 250 return false;
106 } else { 251 break;
107 Error() << "Values for enter record should be of size 2, but found "
108 << NumValues << ": " << Record << "\n";
109 return false;
110 } 252 }
111 uint64_t MaxAbbrev = (static_cast<uint64_t>(1) << NumBits) - 1;
112 AbbrevIndexLimitStack.push_back(MaxAbbrev);
113 if (WriteBlockID == naclbitc::BLOCKINFO_BLOCK_ID) {
114 unsigned DefaultMaxBits =
115 NaClBitsNeededForValue(naclbitc::DEFAULT_MAX_ABBREV);
116 if (NumBits != DefaultMaxBits) {
117 RecoverableError()
118 << "Numbits entry for abbreviations record not "
119 << DefaultMaxBits << " but found " << NumBits <<
120 ": " << Record << "\n";
121 if (!Flags.getTryToRecover())
122 return false;
123 }
124 Writer.EnterBlockInfoBlock();
125 } else {
126 NaClBitcodeSelectorAbbrev CurCodeLen(MaxAbbrev);
127 Writer.EnterSubblock(WriteBlockID, CurCodeLen);
128 }
129 break;
130 }
131 case naclbitc::BLK_CODE_EXIT:
132 if (Record.Abbrev != naclbitc::END_BLOCK) { 253 if (Record.Abbrev != naclbitc::END_BLOCK) {
133 RecoverableError() 254 RecoverableError()
134 << "Uses illegal abbreviation index in exit block record: " 255 << "Uses illegal abbreviation index in exit block record: "
135 << Record << "\n"; 256 << Record << "\n";
136 if (!Flags.getTryToRecover()) 257 if (!Flags.getTryToRecover())
137 return false; 258 return false;
138 } 259 }
139 if (NumValues != 0) { 260 if (NumValues != 0) {
140 RecoverableError() << "Exit block should not have values: " 261 RecoverableError() << "Exit block should not have values: "
141 << Record << "\n"; 262 << Record << "\n";
142 if (!Flags.getTryToRecover()) 263 if (!Flags.getTryToRecover())
143 return false; 264 return false;
144 } 265 }
145 if (!AbbrevIndexLimitStack.empty()) 266 if (!exitBlock(Writer)) {
146 AbbrevIndexLimitStack.pop_back(); 267 Error() << "Failed to write exit block, can't continue: "
147 Writer.ExitBlock(); 268 << Record << "\n";
269 return false;
270 }
148 break; 271 break;
272 }
149 case naclbitc::BLK_CODE_DEFINE_ABBREV: { 273 case naclbitc::BLK_CODE_DEFINE_ABBREV: {
150 if (Record.Abbrev != naclbitc::DEFINE_ABBREV) { 274 if (Record.Abbrev != naclbitc::DEFINE_ABBREV) {
151 RecoverableError() 275 RecoverableError()
152 << "Uses illegal abbreviation index in define abbreviation record: " 276 << "Uses illegal abbreviation index in define abbreviation record: "
153 << Record << "\n"; 277 << Record << "\n";
154 if (!Flags.getTryToRecover()) 278 if (!Flags.getTryToRecover())
155 return false; 279 return false;
156 } 280 }
281 if (getCurWriteBlockID() != naclbitc::BLOCKINFO_BLOCK_ID
282 && Writer.getMaxCurAbbrevIndex() >= getCurAbbrevIndexLimit()) {
283 RecoverableError() << "Exceeds abbreviation index limit of "
284 << getCurAbbrevIndexLimit() << ": " << Record << "\n";
285 // Recover by not writing.
286 return Flags.getTryToRecover();
287 }
157 NaClBitCodeAbbrev *Abbrev = buildAbbrev(Record); 288 NaClBitCodeAbbrev *Abbrev = buildAbbrev(Record);
158 if (Abbrev == NULL) 289 if (Abbrev == NULL)
159 return Flags.getTryToRecover(); 290 return Flags.getTryToRecover();
160 if (WriteBlockID == naclbitc::BLOCKINFO_BLOCK_ID) { 291 if (getCurWriteBlockID() == naclbitc::BLOCKINFO_BLOCK_ID) {
161 Writer.EmitBlockInfoAbbrev(SetBID, Abbrev); 292 Writer.EmitBlockInfoAbbrev(SetBID, Abbrev);
162 } else { 293 } else {
163 Writer.EmitAbbrev(Abbrev); 294 Writer.EmitAbbrev(Abbrev);
164 } 295 }
165 break; 296 break;
166 } 297 }
167 case naclbitc::BLK_CODE_HEADER: 298 case naclbitc::BLK_CODE_HEADER:
168 // Note: There is no abbreviation index here. Ignore. 299 // Note: There is no abbreviation index here. Ignore.
169 for (uint64_t Value : Record.Values) 300 for (uint64_t Value : Record.Values)
170 Writer.Emit(Value, 8); 301 Writer.Emit(Value, 8);
171 break; 302 break;
172 default: 303 default:
173 if (AbbrevIndexLimitStack.empty()) { 304 bool UsesDefaultAbbrev = Record.Abbrev == naclbitc::UNABBREV_RECORD;
174 Error() << "Can't write record outside record block: " << Record << "\n"; 305 if (atOutermostScope()) {
175 return false; 306 RecoverableError() << "Record outside block: " << Record << "\n";
307 if (!Flags.getTryToRecover())
308 return false;
309 // Create a dummy block to hold record.
310 if (!enterBlock(Writer, UnknownWriteBlockID,
311 naclbitc::DEFAULT_MAX_ABBREV, Record)) {
312 Error() << "Failed to recover from record outside block\n";
313 return false;
314 }
315 UsesDefaultAbbrev = true;
176 } 316 }
177 bool UsesDefaultAbbrev = Record.Abbrev == naclbitc::UNABBREV_RECORD;
178 if (!UsesDefaultAbbrev 317 if (!UsesDefaultAbbrev
179 && !Writer.isUserRecordAbbreviation(Record.Abbrev)) { 318 && !Writer.isUserRecordAbbreviation(Record.Abbrev)) {
180 // Illegal abbreviation index found. 319 // Illegal abbreviation index found.
181 if (Flags.getWriteBadAbbrevIndex()) { 320 if (Flags.getWriteBadAbbrevIndex()) {
182 Error() << "Uses illegal abbreviation index: " << Record << "\n"; 321 Error() << "Uses illegal abbreviation index: " << Record << "\n";
183 // Generate bad abbreviation index so that the bitcode reader 322 // Generate bad abbreviation index so that the bitcode reader
184 // can be tested. 323 // can be tested, and then quit.
185 Results.WroteBadAbbrevIndex = true; 324 Results.WroteBadAbbrevIndex = true;
186 Writer.EmitCode(Record.Abbrev); 325 Writer.EmitCode(Record.Abbrev);
187 // Note: We need to close blocks or the bitcode Writer will terminate 326 bool RecoverSilently = true;
188 // due to assertions. 327 finish(Writer, RecoverSilently);
189 writeMissingEndBlocks(Writer);
190 return false; 328 return false;
191 } 329 }
192 RecoverableError() << "Uses illegal abbreviation index: " 330 RecoverableError() << "Uses illegal abbreviation index: "
193 << Record << "\n"; 331 << Record << "\n";
194 if (!Flags.getTryToRecover()) 332 if (!Flags.getTryToRecover())
195 return false; 333 return false;
196 UsesDefaultAbbrev = true; 334 UsesDefaultAbbrev = true;
197 } 335 }
198 if (WriteBlockID == naclbitc::BLOCKINFO_BLOCK_ID 336 if (getCurWriteBlockID() == naclbitc::BLOCKINFO_BLOCK_ID
199 && Record.Code == naclbitc::BLOCKINFO_CODE_SETBID) { 337 && Record.Code == naclbitc::BLOCKINFO_CODE_SETBID) {
200 // Note: SetBID records are handled by Writer->EmitBlockInfoAbbrev, 338 // Note: SetBID records are handled by Writer->EmitBlockInfoAbbrev,
201 // based on the SetBID value. Don't bother to generate SetBID record here. 339 // based on the SetBID value. Don't bother to generate SetBID record here.
202 // Rather just set SetBID and let call to Writer->EmitBlockInfoAbbrev 340 // Rather just set SetBID and let call to Writer->EmitBlockInfoAbbrev
203 // generate the SetBID record. 341 // generate the SetBID record.
204 if (NumValues != 1) { 342 if (NumValues != 1) {
205 Error() << "SetBID record expects 1 value but found " 343 Error() << "SetBID record expects 1 value but found "
206 << NumValues << ": " << Record << "\n"; 344 << NumValues << ": " << Record << "\n";
207 return false; 345 return false;
208 } 346 }
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
315 const WriteFlags &Flags) const { 453 const WriteFlags &Flags) const {
316 NaClBitstreamWriter Writer(Buffer); 454 NaClBitstreamWriter Writer(Buffer);
317 WriteState State(Flags); 455 WriteState State(Flags);
318 if (AddHeader) { 456 if (AddHeader) {
319 NaClWriteHeader(Writer, true); 457 NaClWriteHeader(Writer, true);
320 } 458 }
321 for (const NaClBitcodeAbbrevRecord &Record : *this) { 459 for (const NaClBitcodeAbbrevRecord &Record : *this) {
322 if (!State.emitRecord(Writer, Record)) 460 if (!State.emitRecord(Writer, Record))
323 break; 461 break;
324 } 462 }
325 if (!State.AbbrevIndexLimitStack.empty()) { 463 bool RecoverSilently =
326 State.RecoverableError() 464 State.Results.NumErrors > 0 && !Flags.getTryToRecover();
327 << "Bitcode missing " << State.AbbrevIndexLimitStack.size() 465 return State.finish(Writer, RecoverSilently);
328 << " close blocks.\n";
329 if (Flags.getTryToRecover())
330 State.writeMissingEndBlocks(Writer);
331 }
332 return State.Results;
333 } 466 }
OLDNEW
« no previous file with comments | « lib/Bitcode/NaCl/TestUtils/NaClBitcodeMungeUtils.cpp ('k') | unittests/Bitcode/CMakeLists.txt » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698