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

Side by Side Diff: unittests/Bitcode/NaClMungeWriteErrorTests.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 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
(Empty)
1 //===- llvm/unittest/Bitcode/NaClMungeWriteErrorTests.cpp -----------------===//
2 // Tests parser for PNaCl bitcode instructions.
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 // Tests write errors for munged bitcode.
12
13 #include "llvm/ADT/STLExtras.h"
14 #include "llvm/Bitcode/NaCl/NaClBitcodeMunge.h"
15 #include "llvm/Bitcode/NaCl/NaClBitcodeParser.h"
16 #include "llvm/Bitcode/NaCl/NaClLLVMBitCodes.h"
17
18 #include "gtest/gtest.h"
19
20 using namespace llvm;
21
22 namespace {
23
24 // Test list of bitcode records.
25 static const uint64_t Terminator = 0x5768798008978675LL;
26 const uint64_t BitcodeRecords[] = {
27 1, naclbitc::BLK_CODE_ENTER, naclbitc::MODULE_BLOCK_ID, 2, Terminator,
28 1, naclbitc::BLK_CODE_ENTER, naclbitc::TYPE_BLOCK_ID_NEW, 3, Terminator,
29 3, naclbitc::TYPE_CODE_NUMENTRY, 2, Terminator,
30 3, naclbitc::TYPE_CODE_VOID, Terminator,
31 3, naclbitc::TYPE_CODE_FUNCTION, 0, 0, Terminator,
32 0, naclbitc::BLK_CODE_EXIT, Terminator,
33 3, naclbitc::MODULE_CODE_FUNCTION, 1, 0, 0, 0, Terminator,
34 1, naclbitc::BLK_CODE_ENTER, naclbitc::FUNCTION_BLOCK_ID, 2, Terminator,
35 3, naclbitc::FUNC_CODE_DECLAREBLOCKS, 1, Terminator,
36 3, naclbitc::FUNC_CODE_INST_RET, Terminator,
37 0, naclbitc::BLK_CODE_EXIT, Terminator,
38 0, naclbitc::BLK_CODE_EXIT, Terminator
39 };
40
41 // Expected output when bitcode records are dumped.
42 const char* ExpectedDump =
43 " 0:0|<65532, 80, 69, 88, 69, 1, 0,|Magic Number: 'PEXE' (80, 69, "
44 "88, 69)\n"
45 " | 8, 0, 17, 0, 4, 0, 2, 0, 0, |PNaCl Version: 2\n"
46 " | 0> |\n"
47 " 16:0|1: <65535, 8, 2> |module { // BlockID = 8\n"
48 " 24:0| 1: <65535, 17, 3> | types { // BlockID = 17\n"
49 " 32:0| 3: <1, 2> | count 2;\n"
50 " 34:5| 3: <2> | @t0 = void;\n"
51 " 36:4| 3: <21, 0, 0> | @t1 = void ();\n"
52 " 39:7| 0: <65534> | }\n"
53 " 44:0| 3: <8, 1, 0, 0, 0> | define external void @f0();\n"
54 " 48:6| 1: <65535, 12, 2> | function void @f0() { \n"
55 " | | // BlockID "
56 "= 12\n"
57 " 56:0| 3: <1, 1> | blocks 1;\n"
58 " | | %b0:\n"
59 " 58:4| 3: <10> | ret void;\n"
60 " 60:2| 0: <65534> | }\n"
61 " 64:0|0: <65534> |}\n"
62 ;
63
64 // Edit to change void type with an illegal abbreviation index.
65 const uint64_t VoidTypeIndex = 3; // Index for "@t0 = void".
66 const uint64_t AbbrevIndex4VoidTypeEdit[] = {
67 VoidTypeIndex, NaClMungedBitcode::Replace,
68 4, naclbitc::TYPE_CODE_VOID, Terminator,
69 };
70
71 // Edit to add local abbreviation for "ret void", and then use on that
72 // instruction.
73 const uint64_t RetVoidIndex = 9; // return void;
74 const uint64_t UseLocalRetVoidAbbrevEdits[] = {
75 RetVoidIndex, NaClMungedBitcode::AddBefore,
76 2, naclbitc::BLK_CODE_DEFINE_ABBREV, 1, 1,
77 naclbitc::FUNC_CODE_INST_RET, Terminator,
78 RetVoidIndex, NaClMungedBitcode::Replace,
79 4, naclbitc::FUNC_CODE_INST_RET, Terminator
80 };
81
82 #define ARRAY_ARGS(Records) Records, array_lengthof(Records)
83
84 #define ARRAY_ARGS_TERM(Records) ARRAY_ARGS(Records), Terminator
85
86 std::string stringify(NaClBitcodeMunger &Munger) {
87 std::string Buffer;
88 raw_string_ostream StrBuf(Buffer);
89 Munger.getMungedBitcode().print(StrBuf);
90 return StrBuf.str();
91 }
92
93 // Show that we can dump the bitcode records
94 TEST(NaClMungeWriteErrorTests, DumpBitcodeRecords) {
95 NaClObjDumpMunger Munger(ARRAY_ARGS_TERM(BitcodeRecords));
96 EXPECT_TRUE(Munger.runTest("DumpBitcodeRecords"));
97 EXPECT_EQ(ExpectedDump, Munger.getTestResults());
98 }
99
100 // Show that by default, one can't write a bad abbreviation index.
101 TEST(NaClMungeWriteErrorTests, CantWriteBadAbbrevIndex) {
102 NaClWriteMunger Munger(ARRAY_ARGS_TERM(BitcodeRecords));
103 EXPECT_FALSE(Munger.runTest("CantWriteBadAbbrevIndex",
104 ARRAY_ARGS(AbbrevIndex4VoidTypeEdit)));
105 EXPECT_EQ(
106 "Error (Block 17): Uses illegal abbreviation index: 4: [2]\n"
107 "Error (Block 17): Missing close block.\n"
108 "Error (Block 8): Missing close block.\n"
109 "Error: Unable to generate bitcode file due to write errors\n",
110 Munger.getTestResults());
111 }
112
113 // Show that we can't write more local abbreviations than specified in
114 // the corresponding enclosing block.
115 TEST(NaClMungeWriteErrorTests, CantDumpTooManyLocalAbbreviations) {
jvoung (off chromium) 2015/05/13 00:58:17 Maybe "define" instead of "dump"? I think of the o
Karl 2015/05/13 21:39:25 Changing CantWriteTooManyLocallAbbreviations.
116 NaClWriteMunger Munger(ARRAY_ARGS_TERM(BitcodeRecords));
117 Munger.munge(ARRAY_ARGS(UseLocalRetVoidAbbrevEdits));
118 EXPECT_EQ(
119 " 1: [65535, 8, 2]\n"
120 " 1: [65535, 17, 3]\n"
121 " 3: [1, 2]\n"
122 " 3: [2]\n"
123 " 3: [21, 0, 0]\n"
124 " 0: [65534]\n"
125 " 3: [8, 1, 0, 0, 0]\n"
126 " 1: [65535, 12, 2]\n"
127 " 3: [1, 1]\n"
128 " 2: [65533, 1, 1, 10]\n"
129 " 4: [10]\n"
130 " 0: [65534]\n"
131 " 0: [65534]\n",
132 stringify(Munger));
133
134 EXPECT_FALSE(Munger.runTest("CantDumpTooManyLocalAbbreviations"));
135 EXPECT_EQ(
136 "Error (Block 12): Exceeds abbreviation index limit of 3: 2:"
137 " [65533, 1, 1, 10]\n"
138 "Error (Block 12): Missing close block.\n"
139 "Error (Block 8): Missing close block.\n"
140 "Error: Unable to generate bitcode file due to write errors\n",
141 Munger.getTestResults());
142 }
143
144 // Show what happens when there are more enter blocks then exit blocks.
145 TEST(NaClMungeWriteErrorTests, TooManyEnterBlocks) {
146 NaClWriteMunger Munger(ARRAY_ARGS_TERM(BitcodeRecords));
147 // Remove all but first two records (i.e. two enter blocks).
148 NaClMungedBitcode &MungedBitcode = Munger.getMungedBitcode();
149 for (size_t i = 2; i < MungedBitcode.getBaseRecords().size(); ++i) {
150 MungedBitcode.remove(i);
151 }
152
153 EXPECT_FALSE(Munger.runTest("TooManyEnterBlocks"));
154 EXPECT_EQ(
155 "Error (Block 17): Missing close block.\n"
156 "Error (Block 8): Missing close block.\n"
157 "Error: Unable to generate bitcode file due to write errors\n",
158 Munger.getTestResults());
159 }
160
161 // Show what happens when there are fewer enter blocks than exit
162 // blocks.
163 TEST(NaClMungeWriteErrorTests, TooFewExitBlocks) {
jvoung (off chromium) 2015/05/13 00:58:17 re: TooFewExitBlocks, in this case there are too f
Karl 2015/05/13 21:39:24 Fixing to TooMayExitBlocks.
164 NaClWriteMunger Munger(ARRAY_ARGS_TERM(BitcodeRecords));
165 // Add two exit blocks.
166 NaClMungedBitcode &MungedBitcode = Munger.getMungedBitcode();
167 NaClRecordVector Values;
168 NaClBitcodeAbbrevRecord Record(0, naclbitc::BLK_CODE_EXIT, Values);
169 for (size_t i = 0; i < 2; ++i)
170 MungedBitcode.addAfter(MungedBitcode.getBaseRecords().size() - 1, Record);
171
172 EXPECT_FALSE(Munger.runTest("TooFewExitBlocks"));
jvoung (off chromium) 2015/05/13 00:58:17 "TooFewExitBlocks" -> ?
Karl 2015/05/13 21:39:24 Done.
173 EXPECT_EQ(
174 "Error (Block unknown): Extraneous exit block: 0: [65534]\n"
175 "Error: Unable to generate bitcode file due to write errors\n",
176 Munger.getTestResults());
177 }
178
179 // Show that an error occurs when writing a bitcode record that isn't
180 // in any block.
181 TEST(NaClMungeWriteErrorTests, CantWriteRecordOutsideBlock) {
182 NaClWriteMunger Munger(ARRAY_ARGS_TERM(BitcodeRecords));
183 NaClMungedBitcode &MungedBitcode = Munger.getMungedBitcode();
184 NaClRecordVector Values;
185 Values.push_back(4);
186 NaClBitcodeAbbrevRecord Record(naclbitc::UNABBREV_RECORD,
187 naclbitc::MODULE_CODE_VERSION,
188 Values);
189
190 MungedBitcode.addAfter(MungedBitcode.getBaseRecords().size() - 1, Record);
191 EXPECT_FALSE(Munger.runTest("CantWriteRecordOutsideBlock"));
192 EXPECT_EQ(
193 "Error (Block unknown): Record outside block: 3: [1, 4]\n"
194 "Error: Unable to generate bitcode file due to write errors\n",
195 Munger.getTestResults());
196 }
197
198 // Show that error recovery works when parsing bitcode with a bad
199 // abbreviation index.
jvoung (off chromium) 2015/05/13 00:58:17 So to be clear -- the error recovery is in the wri
Karl 2015/05/13 21:39:24 Yes. Rewriting error recovery comments to be clea
200 TEST(NaClMungeWriteErrorTests, RecoverWhenParsingBadAbbrevIndex) {
201 NaClParseBitcodeMunger Munger(ARRAY_ARGS_TERM(BitcodeRecords));
202 Munger.setTryToRecoverOnWrite(true);
203 EXPECT_TRUE(
204 Munger.runTest("RecoverWhenParsingBadAbbrevIndex",
205 ARRAY_ARGS(AbbrevIndex4VoidTypeEdit), true));
206 EXPECT_EQ(
207 "Error (Block 17): Uses illegal abbreviation index: 4: [2]\n"
208 "Successful parse!\n",
209 Munger.getTestResults());
210 }
211
212 // Show that error recovery works when dumping bitcode with a bad
213 // abbreviation index.
214 TEST(NaClMungeWriteErrorTests, RecoverWhenParsingBadAbbreviationIndex) {
215 NaClObjDumpMunger Munger(ARRAY_ARGS_TERM(BitcodeRecords));
216 Munger.setTryToRecoverOnWrite(true);
217 EXPECT_TRUE(Munger.runTest("RecoverWhenParsingBadAbbreviationIndex",
218 ARRAY_ARGS(AbbrevIndex4VoidTypeEdit)));
219 std::string Results(
220 "Error (Block 17): Uses illegal abbreviation index: 4: [2]\n");
221 Results.append(ExpectedDump);
222 EXPECT_EQ(Results, Munger.getTestResults());
223 }
224
225 // Show that error recovery works when there is too many locally
226 // defined abbreviations for the corresponding number of bits defined
227 // in the corresponding enter block.
228 TEST(NaClMungeWriteErrorTests, RecoverTooManyLocalAbbreviations) {
229 NaClObjDumpMunger Munger(ARRAY_ARGS_TERM(BitcodeRecords));
230 Munger.setTryToRecoverOnWrite(true);
231 Munger.munge(ARRAY_ARGS(UseLocalRetVoidAbbrevEdits));
232
233 EXPECT_TRUE(Munger.runTest("RecoverTooManyLocalAbbreviations"));
234 std::string Results(
235 "Error (Block 12): Exceeds abbreviation index limit of 3: 2:"
236 " [65533, 1, 1, 10]\n"
237 "Error (Block 12): Uses illegal abbreviation index: 4: [10]\n");
238 Results.append(ExpectedDump);
239 EXPECT_EQ(
240 Results,
241 Munger.getTestResults());
242 }
243
244 // Show that error recovery works when there are more enter blocks than
245 // exit blocks.
246 TEST(NaClMungeWriteErrorTests, RecoverTooManyEnterBlocks) {
247 NaClObjDumpMunger Munger(ARRAY_ARGS_TERM(BitcodeRecords));
248 // Remove all but first two records (i.e. two enter blocks).
249 NaClMungedBitcode &MungedBitcode = Munger.getMungedBitcode();
250 for (size_t i = 2; i < MungedBitcode.getBaseRecords().size(); ++i) {
251 MungedBitcode.remove(i);
252 }
253
254 Munger.setTryToRecoverOnWrite(true);
255 EXPECT_TRUE(Munger.runTest("RecoverTooManyEnterBlocks"));
256 EXPECT_EQ(
257 "Error (Block 17): Missing close block.\n"
258 "Error (Block 8): Missing close block.\n"
259 " 0:0|<65532, 80, 69, 88, 69, 1, 0,|Magic Number: 'PEXE' (80, 69,"
260 " 88, 69)\n"
261 " | 8, 0, 17, 0, 4, 0, 2, 0, 0, |PNaCl Version: 2\n"
262 " | 0> |\n"
263 " 16:0|1: <65535, 8, 2> |module { // BlockID = 8\n"
264 " 24:0| 1: <65535, 17, 3> | types { // BlockID = 17\n"
265 " 32:0| 0: <65534> | }\n"
266 " 36:0|0: <65534> |}\n",
267 Munger.getTestResults());
268 }
269
270 // Show that error recovery works when there are fewer enter blocks
271 // than exit blocks.
jvoung (off chromium) 2015/05/13 00:58:17 Similar comment to TooFewExitBlocks
272 TEST(NaClMungeWriteErrorTests, RecoverTooFewExitBlocks) {
273 NaClObjDumpMunger Munger(ARRAY_ARGS_TERM(BitcodeRecords));
274 // Add two exit blocks.
275 NaClMungedBitcode &MungedBitcode = Munger.getMungedBitcode();
276 NaClRecordVector Values;
277 NaClBitcodeAbbrevRecord Record(0, naclbitc::BLK_CODE_EXIT, Values);
278 for (size_t i = 0; i < 2; ++i)
279 MungedBitcode.addAfter(MungedBitcode.getBaseRecords().size() - 1, Record);
280
281 Munger.setTryToRecoverOnWrite(true);
282 EXPECT_TRUE(Munger.runTest("RecoverTooFewExitBlocks"));
283 std::string Results(
284 "Error (Block unknown): Extraneous exit block: 0: [65534]\n"
285 "Error (Block unknown): Extraneous exit block: 0: [65534]\n");
286 Results.append(ExpectedDump);
287 EXPECT_EQ(
288 Results,
289 Munger.getTestResults());
290 }
291
292 // Show that error recovery works when writing a bitcode record that
293 // isn't in any block.
294 TEST(NaClMungeWriteErrorTests, RecoverWriteRecordOutsideBlock) {
295 NaClWriteMunger Munger(ARRAY_ARGS_TERM(BitcodeRecords));
296 NaClMungedBitcode &MungedBitcode = Munger.getMungedBitcode();
297 NaClRecordVector Values;
298 Values.push_back(4);
299 NaClBitcodeAbbrevRecord Record(naclbitc::UNABBREV_RECORD,
300 naclbitc::MODULE_CODE_VERSION,
301 Values);
302 MungedBitcode.addAfter(MungedBitcode.getBaseRecords().size() - 1, Record);
303
304 Munger.setTryToRecoverOnWrite(true);
305 EXPECT_TRUE(Munger.runTest("RecoverWriteRecordOutsideBlock"));
306 EXPECT_EQ(
307 "Error (Block unknown): Record outside block: 3: [1, 4]\n"
308 "Error (Block unknown): Missing close block.\n"
309 " 1: [65535, 8, 2]\n"
310 " 1: [65535, 17, 3]\n"
311 " 3: [1, 2]\n"
312 " 3: [2]\n"
313 " 3: [21, 0, 0]\n"
314 " 0: [65534]\n"
315 " 3: [8, 1, 0, 0, 0]\n"
316 " 1: [65535, 12, 2]\n"
317 " 3: [1, 1]\n"
318 " 3: [10]\n"
319 " 0: [65534]\n"
320 " 0: [65534]\n"
321 " 1: [65535, 4294967295, 3]\n"
322 " 3: [1, 4]\n"
323 " 0: [65534]\n",
324 Munger.getTestResults());
325 }
326
327 } // end of anonymous namespace.
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698