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

Side by Side Diff: unittests/Bitcode/NaClMungeWriteErrorTests.cpp

Issue 1157273004: Check for invalid abbreviation operators in munged bitcode. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-llvm.git@master
Patch Set: Fix nits. Created 5 years, 6 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/NaClBitcodeMungeWriter.cpp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 //===- llvm/unittest/Bitcode/NaClMungeWriteErrorTests.cpp -----------------===// 1 //===- llvm/unittest/Bitcode/NaClMungeWriteErrorTests.cpp -----------------===//
2 // Tests parser for PNaCl bitcode instructions. 2 // Tests parser for PNaCl bitcode instructions.
3 // 3 //
4 // The LLVM Compiler Infrastructure 4 // The LLVM Compiler Infrastructure
5 // 5 //
6 // This file is distributed under the University of Illinois Open Source 6 // This file is distributed under the University of Illinois Open Source
7 // License. See LICENSE.TXT for details. 7 // License. See LICENSE.TXT for details.
8 // 8 //
9 //===----------------------------------------------------------------------===// 9 //===----------------------------------------------------------------------===//
10 10
(...skipping 19 matching lines...) Expand all
30 3, naclbitc::TYPE_CODE_FUNCTION, 0, 0, Terminator, 30 3, naclbitc::TYPE_CODE_FUNCTION, 0, 0, Terminator,
31 0, naclbitc::BLK_CODE_EXIT, Terminator, 31 0, naclbitc::BLK_CODE_EXIT, Terminator,
32 3, naclbitc::MODULE_CODE_FUNCTION, 1, 0, 0, 0, Terminator, 32 3, naclbitc::MODULE_CODE_FUNCTION, 1, 0, 0, 0, Terminator,
33 1, naclbitc::BLK_CODE_ENTER, naclbitc::FUNCTION_BLOCK_ID, 2, Terminator, 33 1, naclbitc::BLK_CODE_ENTER, naclbitc::FUNCTION_BLOCK_ID, 2, Terminator,
34 3, naclbitc::FUNC_CODE_DECLAREBLOCKS, 1, Terminator, 34 3, naclbitc::FUNC_CODE_DECLAREBLOCKS, 1, Terminator,
35 3, naclbitc::FUNC_CODE_INST_RET, Terminator, 35 3, naclbitc::FUNC_CODE_INST_RET, Terminator,
36 0, naclbitc::BLK_CODE_EXIT, Terminator, 36 0, naclbitc::BLK_CODE_EXIT, Terminator,
37 0, naclbitc::BLK_CODE_EXIT, Terminator 37 0, naclbitc::BLK_CODE_EXIT, Terminator
38 }; 38 };
39 39
40 // Indices to records in bitcode.
41 const uint64_t VoidTypeIndex = 3; // Index for "@t0 = void".
42 const uint64_t RetVoidIndex = 9; // return void;
43 const uint64_t LastExitBlockIndex = 11;
44
40 // Expected output when bitcode records are dumped. 45 // Expected output when bitcode records are dumped.
41 const char* ExpectedDump = 46 const char *ExpectedDumpedBitcode =
42 " 0:0|<65532, 80, 69, 88, 69, 1, 0,|Magic Number: 'PEXE' (80, 69, " 47 " 0:0|<65532, 80, 69, 88, 69, 1, 0,|Magic Number: 'PEXE' (80, 69, "
43 "88, 69)\n" 48 "88, 69)\n"
44 " | 8, 0, 17, 0, 4, 0, 2, 0, 0, |PNaCl Version: 2\n" 49 " | 8, 0, 17, 0, 4, 0, 2, 0, 0, |PNaCl Version: 2\n"
45 " | 0> |\n" 50 " | 0> |\n"
46 " 16:0|1: <65535, 8, 2> |module { // BlockID = 8\n" 51 " 16:0|1: <65535, 8, 2> |module { // BlockID = 8\n"
47 " 24:0| 1: <65535, 17, 3> | types { // BlockID = 17\n" 52 " 24:0| 1: <65535, 17, 3> | types { // BlockID = 17\n"
48 " 32:0| 3: <1, 2> | count 2;\n" 53 " 32:0| 3: <1, 2> | count 2;\n"
49 " 34:5| 3: <2> | @t0 = void;\n" 54 " 34:5| 3: <2> | @t0 = void;\n"
50 " 36:4| 3: <21, 0, 0> | @t1 = void ();\n" 55 " 36:4| 3: <21, 0, 0> | @t1 = void ();\n"
51 " 39:7| 0: <65534> | }\n" 56 " 39:7| 0: <65534> | }\n"
52 " 44:0| 3: <8, 1, 0, 0, 0> | define external void @f0();\n" 57 " 44:0| 3: <8, 1, 0, 0, 0> | define external void @f0();\n"
53 " 48:6| 1: <65535, 12, 2> | function void @f0() { \n" 58 " 48:6| 1: <65535, 12, 2> | function void @f0() { \n"
54 " | | // BlockID " 59 " | | // BlockID "
55 "= 12\n" 60 "= 12\n"
56 " 56:0| 3: <1, 1> | blocks 1;\n" 61 " 56:0| 3: <1, 1> | blocks 1;\n"
57 " | | %b0:\n" 62 " | | %b0:\n"
58 " 58:4| 3: <10> | ret void;\n" 63 " 58:4| 3: <10> | ret void;\n"
59 " 60:2| 0: <65534> | }\n" 64 " 60:2| 0: <65534> | }\n"
60 " 64:0|0: <65534> |}\n" 65 " 64:0|0: <65534> |}\n"
61 ; 66 ;
62 67
68 const char *UnableToContinue =
69 "Error: Unable to generate bitcode file due to write errors\n";
70
71 const char *NoErrorRecoveryMessages = "";
72
73 // Runs write munging tests on BitcodeRecords with the given Edits. It
74 // then parses the written bitcode. ErrorMessages is the expected
75 // error messages logged by the write munging, when no error recovery
76 // is allowed. ErrorRecoveryMessages are messages, in addition to
77 // ErrorMessages, when the writer applies error recovery.
78 void CheckParseEdits(const uint64_t *Edits, size_t EditsSize,
79 std::string ErrorMessages,
80 std::string ErrorRecoveryMessages) {
81 NaClParseBitcodeMunger Munger(ARRAY_TERM(BitcodeRecords));
82 EXPECT_FALSE(Munger.runTest(Edits, EditsSize, true));
83 std::string BadResults(ErrorMessages);
84 BadResults.append(UnableToContinue);
85 EXPECT_EQ(BadResults, Munger.getTestResults());
86
87 Munger.setTryToRecoverOnWrite(true);
88 EXPECT_TRUE(Munger.runTest(Edits, EditsSize, true));
89 std::string GoodResults(ErrorMessages);
90 GoodResults.append(ErrorRecoveryMessages);
91 GoodResults.append("Successful parse!\n");
92 EXPECT_EQ(GoodResults, Munger.getTestResults());
93 }
94
95 // Same as CheckParseEdits, but also runs the bitcode dumper on the
96 // written bitcode records. DumpedBitcode is the expected dumped
jvoung (off chromium) 2015/05/29 16:43:25 extra space (line up comments)
Karl 2015/05/29 20:02:16 Done.
97 // bitcode.
98 void CheckDumpEdits(const uint64_t *Edits, size_t EditsSize,
99 std::string ErrorMessages,
100 std::string ErrorRecoveryMessages,
101 std::string DumpedBitcode) {
102 NaClObjDumpMunger Munger(ARRAY_TERM(BitcodeRecords));
103 EXPECT_FALSE(Munger.runTest(Edits, EditsSize));
104 std::string BadResults(ErrorMessages);
105 BadResults.append(UnableToContinue);
106 EXPECT_EQ(BadResults, Munger.getTestResults());
107
108 Munger.setTryToRecoverOnWrite(true);
109 EXPECT_TRUE(Munger.runTest(Edits, EditsSize));
110 std::string GoodResults(ErrorMessages);
111 GoodResults.append(ErrorRecoveryMessages);
112 GoodResults.append(DumpedBitcode);
113 EXPECT_EQ(GoodResults, Munger.getTestResults());
114
115 // Verify that we can also parse the bitcode.
116 CheckParseEdits(Edits, EditsSize, ErrorMessages, ErrorRecoveryMessages);
117 }
118
119 // Same as ExpectedDumpedBitcode, but is just the records dumped by the
120 // simplier write munger.
jvoung (off chromium) 2015/05/29 16:43:25 simplier -> simpler
Karl 2015/05/29 20:02:16 Done.
121 const char *ExpectedRecords =
122 " 1: [65535, 8, 2]\n"
123 " 1: [65535, 17, 3]\n"
124 " 3: [1, 2]\n"
125 " 3: [2]\n"
126 " 3: [21, 0, 0]\n"
127 " 0: [65534]\n"
128 " 3: [8, 1, 0, 0, 0]\n"
129 " 1: [65535, 12, 2]\n"
130 " 3: [1, 1]\n"
131 " 3: [10]\n"
132 " 0: [65534]\n"
133 " 0: [65534]\n";
134
135 // Same as CheckParseEdits, but run the simplier write munger instead
jvoung (off chromium) 2015/05/29 16:43:25 simplier -> simpler
Karl 2015/05/29 20:02:16 Done.
136 // of the bitcode parser. Records is the the records dumped by the
jvoung (off chromium) 2015/05/29 16:43:25 the the -> the
Karl 2015/05/29 20:02:16 Done.
137 // write munger. This should be used in cases where the written munged
138 // records is not valid bitcode.
139 void CheckWriteEdits(const uint64_t *Edits, size_t EditsSize,
140 std::string ExpectedErrorMessage,
141 std::string ErrorRecoveryMessages,
142 std::string Records) {
143 NaClWriteMunger Munger(ARRAY_TERM(BitcodeRecords));
144 EXPECT_FALSE(Munger.runTest(Edits, EditsSize));
145 std::string BadResults(ExpectedErrorMessage);
146 BadResults.append(UnableToContinue);
147 EXPECT_EQ(BadResults, Munger.getTestResults());
148
149 Munger.setTryToRecoverOnWrite(true);
150 EXPECT_TRUE(Munger.runTest(Edits, EditsSize));
151 std::string GoodResults(ExpectedErrorMessage);
152 GoodResults.append(ErrorRecoveryMessages);
153 GoodResults.append(Records);
154 EXPECT_EQ(GoodResults, Munger.getTestResults());
155 }
156
157 // Show that we can dump the bitcode records
158 TEST(NaClMungeWriteErrorTests, DumpBitcodeRecords) {
159 NaClObjDumpMunger Munger(ARRAY_TERM(BitcodeRecords));
160 EXPECT_TRUE(Munger.runTest());
161 EXPECT_EQ(ExpectedDumpedBitcode, Munger.getTestResults());
162 }
163
63 // Edit to change void type with an illegal abbreviation index. 164 // Edit to change void type with an illegal abbreviation index.
64 const uint64_t VoidTypeIndex = 3; // Index for "@t0 = void".
65 const uint64_t AbbrevIndex4VoidTypeEdit[] = { 165 const uint64_t AbbrevIndex4VoidTypeEdit[] = {
66 VoidTypeIndex, NaClMungedBitcode::Replace, 166 VoidTypeIndex, NaClMungedBitcode::Replace,
67 4, naclbitc::TYPE_CODE_VOID, Terminator, 167 4, naclbitc::TYPE_CODE_VOID, Terminator,
68 }; 168 };
69 169
70 // Edit to add local abbreviation for "ret void", and then use on that
71 // instruction.
72 const uint64_t RetVoidIndex = 9; // return void;
73 const uint64_t UseLocalRetVoidAbbrevEdits[] = {
74 RetVoidIndex, NaClMungedBitcode::AddBefore,
75 2, naclbitc::BLK_CODE_DEFINE_ABBREV, 1, 1,
76 naclbitc::FUNC_CODE_INST_RET, Terminator,
77 RetVoidIndex, NaClMungedBitcode::Replace,
78 4, naclbitc::FUNC_CODE_INST_RET, Terminator
79 };
80
81 // Show that we can dump the bitcode records
82 TEST(NaClMungeWriteErrorTests, DumpBitcodeRecords) {
83 NaClObjDumpMunger Munger(ARRAY_TERM(BitcodeRecords));
84 EXPECT_TRUE(Munger.runTest());
85 EXPECT_EQ(ExpectedDump, Munger.getTestResults());
86 }
87
88 // Show that by default, one can't write a bad abbreviation index. 170 // Show that by default, one can't write a bad abbreviation index.
89 TEST(NaClMungeWriteErrorTests, CantWriteBadAbbrevIndex) { 171 TEST(NaClMungeWriteErrorTests, CantWriteBadAbbrevIndex) {
172 CheckDumpEdits(
173 ARRAY(AbbrevIndex4VoidTypeEdit),
174 "Error (Block 17): Uses illegal abbreviation index: 4: [2]\n",
175 NoErrorRecoveryMessages,
176 ExpectedDumpedBitcode);
177 }
178
179 // Show that writing out an illegal abbreviation index, causes the
180 // parser to fail.
181 TEST(MyNaClMungerWriteErrorTests, DieOnWriteBadAbbreviationIndex) {
90 NaClWriteMunger Munger(ARRAY_TERM(BitcodeRecords)); 182 NaClWriteMunger Munger(ARRAY_TERM(BitcodeRecords));
91 EXPECT_FALSE(Munger.runTest(ARRAY(AbbrevIndex4VoidTypeEdit))); 183 Munger.setWriteBadAbbrevIndex(true);
92 EXPECT_EQ( 184 Munger.setRunAsDeathTest(true);
93 "Error (Block 17): Uses illegal abbreviation index: 4: [2]\n" 185 EXPECT_DEATH(
94 "Error: Unable to generate bitcode file due to write errors\n", 186 Munger.runTest(ARRAY(AbbrevIndex4VoidTypeEdit)),
95 Munger.getTestResults()); 187 ".*"
96 } 188 // Report problem while writing.
97 189 "Error \\(Block 17\\)\\: Uses illegal abbreviation index\\: 4\\: \\[2\\]"
98 // Show that we use more local abbreviations than specified in the 190 ".*"
191 // Corresponding error while parsing.
192 "Fatal\\(35\\:0)\\: Invalid abbreviation \\# 4 defined for record"
193 ".*"
194 // Output of report_fatal_error.
195 "LLVM ERROR\\: Unable to continue"
196 ".*");
197 }
198
199 // Show what happens when we use more local abbreviations than specified in the
99 // corresponding enclosing block. 200 // corresponding enclosing block.
100 TEST(NaClMungeWriteErrorTests, CantWriteTooManyLocalAbbreviations) { 201 TEST(NaClMungeWriteErrorTests, CantWriteTooManyLocalAbbreviations) {
101 NaClWriteMunger Munger(ARRAY_TERM(BitcodeRecords)); 202 // Edit to add local abbreviation for "ret void", and then use on that
102 Munger.munge(ARRAY(UseLocalRetVoidAbbrevEdits)); 203 // instruction.
103 EXPECT_EQ( 204 const uint64_t UseLocalRetVoidAbbrevEdits[] = {
104 " 1: [65535, 8, 2]\n" 205 RetVoidIndex, NaClMungedBitcode::AddBefore,
105 " 1: [65535, 17, 3]\n" 206 2, naclbitc::BLK_CODE_DEFINE_ABBREV, 1, 1,
106 " 3: [1, 2]\n" 207 naclbitc::FUNC_CODE_INST_RET, Terminator,
107 " 3: [2]\n" 208 RetVoidIndex, NaClMungedBitcode::Replace,
108 " 3: [21, 0, 0]\n" 209 4, naclbitc::FUNC_CODE_INST_RET, Terminator
109 " 0: [65534]\n" 210 };
110 " 3: [8, 1, 0, 0, 0]\n" 211
111 " 1: [65535, 12, 2]\n" // Only allows 2 bits for abbrevs. 212 CheckDumpEdits(
112 " 3: [1, 1]\n" 213 ARRAY(UseLocalRetVoidAbbrevEdits),
113 " 2: [65533, 1, 1, 10]\n" // defines abbev 4: 214 "Error (Block 12): Uses illegal abbreviation index: 4: [10]\n",
114 " 4: [10]\n" // can't use, 4 can't fit in two bits. 215 NoErrorRecoveryMessages,
115 " 0: [65534]\n" 216 " 0:0|<65532, 80, 69, 88, 69, 1, 0,|Magic Number: 'PEXE'"
116 " 0: [65534]\n", 217 " (80, 69, 88, 69)\n"
117 stringify(Munger)); 218 " | 8, 0, 17, 0, 4, 0, 2, 0, 0, |PNaCl Version: 2\n"
118 219 " | 0> |\n"
119 EXPECT_FALSE(Munger.runTest()); 220 " 16:0|1: <65535, 8, 2> |module { // BlockID = 8\n"
120 EXPECT_EQ( 221 " 24:0| 1: <65535, 17, 3> | types { // BlockID = 17\n"
121 "Error (Block 12): Uses illegal abbreviation index: 4: [10]\n" 222 " 32:0| 3: <1, 2> | count 2;\n"
122 "Error: Unable to generate bitcode file due to write errors\n", 223 " 34:5| 3: <2> | @t0 = void;\n"
123 Munger.getTestResults()); 224 " 36:4| 3: <21, 0, 0> | @t1 = void ();\n"
225 " 39:7| 0: <65534> | }\n"
226 " 44:0| 3: <8, 1, 0, 0, 0> | define external void @f0();\n"
227 // Block only specifies 2 bits for abbreviations (i.e. limit = 3).
228 " 48:6| 1: <65535, 12, 2> | function void @f0() { \n"
229 " | | // BlockID"
230 " = 12\n"
231 " 56:0| 3: <1, 1> | blocks 1;\n"
232 // Added abbreviation. Defines abbreviation index 4.
233 " 58:4| 2: <65533, 1, 1, 10> | %a0 = abbrev <10>;\n"
234 " | | %b0:\n"
235 // Repaired abbreviation index of 4 (now 3).
236 " 60:4| 3: <10> | ret void;\n"
237 " 62:2| 0: <65534> | }\n"
238 " 64:0|0: <65534> |}\n");
124 } 239 }
125 240
126 // Show what happens when there are more enter blocks then exit blocks. 241 // Show what happens when there are more enter blocks then exit blocks.
127 TEST(NaClMungeWriteErrorTests, CantWriteTooManyEnterBlocks) { 242 TEST(NaClMungeWriteErrorTests, CantWriteTooManyEnterBlocks) {
128 NaClWriteMunger Munger(ARRAY_TERM(BitcodeRecords)); 243 // Remove all records except the first two records in BitcodeRecords.
129 // Remove all but first two records (i.e. two enter blocks). 244 const uint64_t Edits[] = {
130 NaClMungedBitcode &MungedBitcode = Munger.getMungedBitcode(); 245 2, NaClMungedBitcode::Remove,
131 for (size_t i = 2; i < MungedBitcode.getBaseRecords().size(); ++i) { 246 3, NaClMungedBitcode::Remove,
132 MungedBitcode.remove(i); 247 4, NaClMungedBitcode::Remove,
133 } 248 5, NaClMungedBitcode::Remove,
134 249 6, NaClMungedBitcode::Remove,
135 EXPECT_FALSE(Munger.runTest()); 250 7, NaClMungedBitcode::Remove,
136 EXPECT_EQ( 251 8, NaClMungedBitcode::Remove,
252 9, NaClMungedBitcode::Remove,
253 10, NaClMungedBitcode::Remove,
254 11, NaClMungedBitcode::Remove
255 };
256 CheckDumpEdits(
257 ARRAY(Edits),
137 "Error (Block 17): Missing close block.\n" 258 "Error (Block 17): Missing close block.\n"
138 "Error (Block 8): Missing close block.\n" 259 "Error (Block 8): Missing close block.\n",
139 "Error: Unable to generate bitcode file due to write errors\n", 260 NoErrorRecoveryMessages,
140 Munger.getTestResults()); 261 " 0:0|<65532, 80, 69, 88, 69, 1, 0,|Magic Number: 'PEXE' (80, 69,"
262 " 88, 69)\n"
263 " | 8, 0, 17, 0, 4, 0, 2, 0, 0, |PNaCl Version: 2\n"
264 " | 0> |\n"
265 " 16:0|1: <65535, 8, 2> |module { // BlockID = 8\n"
266 " 24:0| 1: <65535, 17, 3> | types { // BlockID = 17\n"
267 " 32:0| 0: <65534> | }\n"
268 " 36:0|0: <65534> |}\n");
141 } 269 }
142 270
143 // Show what happens when there are fewer enter blocks than exit 271 // Show what happens when there are fewer enter blocks than exit
144 // blocks. 272 // blocks.
145 TEST(NaClMungeWriteErrorTests, CantWriteTooManyExitBlocks) { 273 TEST(NaClMungeWriteErrorTests, CantWriteTooManyExitBlocks) {
146 NaClWriteMunger Munger(ARRAY_TERM(BitcodeRecords)); 274 // Add two blocks to the end of BitcodeRecords.
147 // Add two exit blocks. 275 const uint64_t Edits[] = {
148 NaClMungedBitcode &MungedBitcode = Munger.getMungedBitcode(); 276 LastExitBlockIndex, NaClMungedBitcode::AddAfter,
149 NaClRecordVector Values; 277 naclbitc::END_BLOCK, naclbitc::BLK_CODE_EXIT, Terminator,
150 NaClBitcodeAbbrevRecord Record(0, naclbitc::BLK_CODE_EXIT, Values); 278 LastExitBlockIndex, NaClMungedBitcode::AddAfter,
151 for (size_t i = 0; i < 2; ++i) 279 naclbitc::END_BLOCK, naclbitc::BLK_CODE_EXIT, Terminator
152 MungedBitcode.addAfter(MungedBitcode.getBaseRecords().size() - 1, Record); 280 };
153 281 CheckDumpEdits(
154 EXPECT_FALSE(Munger.runTest()); 282 ARRAY(Edits),
155 EXPECT_EQ( 283 "Error (Block unknown): Extraneous exit block: 0: [65534]\n",
156 "Error (Block unknown): Extraneous exit block: 0: [65534]\n" 284 "Error (Block unknown): Extraneous exit block: 0: [65534]\n",
157 "Error: Unable to generate bitcode file due to write errors\n", 285 ExpectedDumpedBitcode);
158 Munger.getTestResults());
159 } 286 }
160 287
161 // Show that an error occurs when writing a bitcode record that isn't 288 // Show that an error occurs when writing a bitcode record that isn't
162 // in any block. 289 // in any block.
163 TEST(NaClMungeWriteErrorTests, CantWriteRecordOutsideBlock) { 290 TEST(NaClMungeWriteErrorTests, CantWriteRecordOutsideBlock) {
164 NaClWriteMunger Munger(ARRAY_TERM(BitcodeRecords)); 291 const uint64_t Edit[] = {
165 NaClMungedBitcode &MungedBitcode = Munger.getMungedBitcode(); 292 LastExitBlockIndex, NaClMungedBitcode::AddAfter,
166 NaClRecordVector Values; 293 naclbitc::UNABBREV_RECORD, naclbitc::MODULE_CODE_VERSION, 4, Terminator
167 Values.push_back(4); 294 };
168 NaClBitcodeAbbrevRecord Record(naclbitc::UNABBREV_RECORD, 295 std::string Records(ExpectedRecords);
169 naclbitc::MODULE_CODE_VERSION, 296 Records.append(
170 Values); 297 " 1: [65535, 4294967295, 3]\n"
171 298 " 3: [1, 4]\n"
172 MungedBitcode.addAfter(MungedBitcode.getBaseRecords().size() - 1, Record); 299 " 0: [65534]\n");
173 EXPECT_FALSE(Munger.runTest()); 300 CheckWriteEdits(
174 EXPECT_EQ( 301 ARRAY(Edit),
175 "Error (Block unknown): Record outside block: 3: [1, 4]\n" 302 "Error (Block unknown): Record outside block: 3: [1, 4]\n",
176 "Error: Unable to generate bitcode file due to write errors\n", 303 "Error (Block unknown): Missing close block.\n",
177 Munger.getTestResults()); 304 Records);
178 } 305 }
179 306
180 // Show that no error occurs if we write out the maximum allowable 307 // Show that no error occurs if we write out the maximum allowable
181 // block abbreviation index bit limit. 308 // block abbreviation index bit limit.
182 TEST(NaClMungerWriteErrorTests, CanWriteBlockWithMaxLimit) { 309 TEST(NaClMungerWriteErrorTests, CanWriteBlockWithMaxLimit) {
183 // Replace initial block enter with maximum bit size. 310 // Replace initial block enter with maximum bit size.
184 const uint64_t Edit[] = { 311 const uint64_t Edit[] = {
185 0, NaClMungedBitcode::Replace, 312 0, NaClMungedBitcode::Replace,
186 1, naclbitc::BLK_CODE_ENTER, naclbitc::MODULE_BLOCK_ID, 313 1, naclbitc::BLK_CODE_ENTER, naclbitc::MODULE_BLOCK_ID,
187 naclbitc::MaxAbbrevWidth, Terminator 314 naclbitc::MaxAbbrevWidth, Terminator
188 }; 315 };
189 NaClWriteMunger Munger(ARRAY_TERM(BitcodeRecords)); 316 NaClWriteMunger Munger(ARRAY_TERM(BitcodeRecords));
190 EXPECT_TRUE(Munger.runTest(ARRAY(Edit))); 317 EXPECT_TRUE(Munger.runTest(ARRAY(Edit)));
191 EXPECT_EQ( 318 EXPECT_EQ(
192 " 1: [65535, 8, 32]\n" 319 " 1: [65535, 8, 32]\n" // Max abbreviation bit limit (32).
193 " 1: [65535, 17, 3]\n" 320 " 1: [65535, 17, 3]\n"
194 " 3: [1, 2]\n" 321 " 3: [1, 2]\n"
195 " 3: [2]\n" 322 " 3: [2]\n"
196 " 3: [21, 0, 0]\n" 323 " 3: [21, 0, 0]\n"
197 " 0: [65534]\n" 324 " 0: [65534]\n"
198 " 3: [8, 1, 0, 0, 0]\n" 325 " 3: [8, 1, 0, 0, 0]\n"
199 " 1: [65535, 12, 2]\n" 326 " 1: [65535, 12, 2]\n"
200 " 3: [1, 1]\n" 327 " 3: [1, 1]\n"
201 " 3: [10]\n" 328 " 3: [10]\n"
202 " 0: [65534]\n" 329 " 0: [65534]\n"
203 " 0: [65534]\n", 330 " 0: [65534]\n",
204 Munger.getTestResults()); 331 Munger.getTestResults());
205 } 332 }
206 333
207 // Show that an error occurs if the block abbreviation index bit limit is 334 // Show that an error occurs if the block abbreviation index bit limit is
208 // greater than the maximum allowable. 335 // greater than the maximum allowable.
209 TEST(NaClMungerWriteErrorTests, CantWriteBlockWithBadBitLimit) { 336 TEST(NaClMungerWriteErrorTests, CantWriteBlockWithBadBitLimit) {
210 // Replace initial block enter with value out of range. 337 // Replace initial block enter with value out of range.
211 const uint64_t Edit[] = { 338 const uint64_t Edit[] = {
212 0, NaClMungedBitcode::Replace, 339 0, NaClMungedBitcode::Replace,
213 1, naclbitc::BLK_CODE_ENTER, naclbitc::MODULE_BLOCK_ID, 340 1, naclbitc::BLK_CODE_ENTER, naclbitc::MODULE_BLOCK_ID,
214 naclbitc::MaxAbbrevWidth + 1, Terminator 341 naclbitc::MaxAbbrevWidth + 1, Terminator
215 }; 342 };
216 NaClWriteMunger Munger(ARRAY_TERM(BitcodeRecords)); 343 CheckDumpEdits(
217 EXPECT_FALSE(Munger.runTest(ARRAY(Edit))); 344 ARRAY(Edit),
218 EXPECT_EQ(
219 "Error (Block unknown): Block index bit limit 33 invalid. Must be in" 345 "Error (Block unknown): Block index bit limit 33 invalid. Must be in"
220 " [2..32]: 1: [65535, 8, 33]\n" 346 " [2..32]: 1: [65535, 8, 33]\n",
221 "Error: Unable to generate bitcode file due to write errors\n", 347 "",
222 Munger.getTestResults()); 348 " 0:0|<65532, 80, 69, 88, 69, 1, 0,|Magic Number: 'PEXE' (80, 69,"
349 " 88, 69)\n"
350 " | 8, 0, 17, 0, 4, 0, 2, 0, 0, |PNaCl Version: 2\n"
351 " | 0> |\n"
352 // Corrected bitsize from 33 to 32.
353 " 16:0|1: <65535, 8, 32> |module { // BlockID = 8\n"
354 " 24:0| 1: <65535, 17, 3> | types { // BlockID = 17\n"
355 " 36:0| 3: <1, 2> | count 2;\n"
356 " 38:5| 3: <2> | @t0 = void;\n"
357 " 40:4| 3: <21, 0, 0> | @t1 = void ();\n"
358 " 43:7| 0: <65534> | }\n"
359 " 48:0| 3: <8, 1, 0, 0, 0> | define external void @f0();\n"
360 " 56:4| 1: <65535, 12, 2> | function void @f0() { \n"
361 " | | // BlockID"
362 " = 12\n"
363 " 68:0| 3: <1, 1> | blocks 1;\n"
364 " | | %b0:\n"
365 " 70:4| 3: <10> | ret void;\n"
366 " 72:2| 0: <65534> | }\n"
367 " 76:0|0: <65534> |}\n");
223 } 368 }
224 369
225 // Show that we can't write an enter block with a very large block id. 370 // Show that we can't write an enter block with a very large block id.
226 TEST(NaClMungerWriteErrorTests, CantWriteBlockWithLargeBlockID) { 371 TEST(NaClMungerWriteErrorTests, CantWriteBlockWithLargeBlockID) {
227 // Replace initial block enter with value out of range. 372 // Replace initial block enter with value out of range.
228 const uint64_t Edit[] = { 373 const uint64_t Edit[] = {
229 0, NaClMungedBitcode::Replace, 374 0, NaClMungedBitcode::Replace,
230 1, naclbitc::BLK_CODE_ENTER, (uint64_t)1 << 33, 2, Terminator 375 1, naclbitc::BLK_CODE_ENTER, (uint64_t)1 << 33, 2, Terminator
231 }; 376 };
232 NaClWriteMunger Munger(ARRAY_TERM(BitcodeRecords)); 377 CheckWriteEdits(
233 EXPECT_FALSE(Munger.runTest(ARRAY(Edit))); 378 ARRAY(Edit),
234 EXPECT_EQ(
235 "Error (Block unknown): Block id must be <= 4294967295: 1:" 379 "Error (Block unknown): Block id must be <= 4294967295: 1:"
236 " [65535, 8589934592, 2]\n" 380 " [65535, 8589934592, 2]\n",
237 "Error: Unable to generate bitcode file due to write errors\n", 381 "",
238 Munger.getTestResults()); 382 // Note that the maximum block ID is used for recovery.
239 } 383 " 1: [65535, 4294967295, 2]\n"
240 384 " 1: [65535, 17, 3]\n"
241 // Show that writing successfully writes out an illegal abbreviation 385 " 3: [1, 2]\n"
242 // index, and then the parser fails to parse that illegal abbreviation. 386 " 3: [2]\n"
243 TEST(MyNaClMungerWriteErrorTests, DieOnWriteBadAbbreviationIndex) { 387 " 3: [21, 0, 0]\n"
244 NaClWriteMunger Munger(ARRAY_TERM(BitcodeRecords)); 388 " 0: [65534]\n"
245 Munger.setWriteBadAbbrevIndex(true); 389 " 3: [8, 1, 0, 0, 0]\n"
246 Munger.setRunAsDeathTest(true); 390 " 1: [65535, 12, 2]\n"
247 EXPECT_DEATH( 391 " 3: [1, 1]\n"
248 Munger.runTest(ARRAY(AbbrevIndex4VoidTypeEdit)), 392 " 3: [10]\n"
249 ".*" 393 " 0: [65534]\n"
250 // Report problem while writing. 394 " 0: [65534]\n");
251 "Error \\(Block 17\\)\\: Uses illegal abbreviation index\\: 4\\: \\[2\\]"
252 ".*"
253 // Corresponding error while parsing.
254 "Fatal\\(35\\:0)\\: Invalid abbreviation \\# 4 defined for record"
255 ".*"
256 // Output of report_fatal_error.
257 "LLVM ERROR\\: Unable to continue"
258 ".*");
259 } 395 }
260 396
261 // Show that we check that the abbreviation actually applies to the 397 // Show that we check that the abbreviation actually applies to the
262 // record associated with that abbreviation. Also shows that we repair 398 // record associated with that abbreviation. Also shows that we repair
263 // the problem by applying the default abbreviation instead. 399 // the problem by applying the default abbreviation instead.
264 TEST(NaClMungeWriteErrorsTests, TestMismatchedAbbreviation) { 400 TEST(NaClMungeWriteErrorsTests, TestMismatchedAbbreviation) {
265 // Create edits to: 401 // Create edits to:
266 // 1) Expand the number of abbreviation index bits for the block from 2 to 3. 402 // 1) Expand the number of abbreviation index bits for the block from 2 to 3.
267 // 2) Introduce the incorrect abbreviation for the return instruction. 403 // 2) Introduce the incorrect abbreviation for the return instruction.
268 // i.e. [9] instead of [10]. 404 // i.e. [9] instead of [10].
269 // 3) Apply the bad abbreviation to record "ret" 405 // 3) Apply the bad abbreviation to record "ret"
270 const uint64_t FunctionEnterIndex = 7; 406 const uint64_t FunctionEnterIndex = 7;
271 const uint64_t Edits[] { 407 const uint64_t Edits[] {
408 // Upped abbreviation index bits to 3
272 FunctionEnterIndex, NaClMungedBitcode::Replace, 409 FunctionEnterIndex, NaClMungedBitcode::Replace,
273 1, naclbitc::BLK_CODE_ENTER, naclbitc::FUNCTION_BLOCK_ID, 3, Terminator, 410 1, naclbitc::BLK_CODE_ENTER, naclbitc::FUNCTION_BLOCK_ID, 3, Terminator,
411 // abbrev 4: [9]
274 RetVoidIndex, NaClMungedBitcode::AddBefore, 412 RetVoidIndex, NaClMungedBitcode::AddBefore,
275 2, naclbitc::BLK_CODE_DEFINE_ABBREV, 1, 1, 413 2, naclbitc::BLK_CODE_DEFINE_ABBREV, 1, 1,
276 naclbitc::FUNC_CODE_INST_RET - 1, Terminator, 414 naclbitc::FUNC_CODE_INST_RET - 1, Terminator,
415 // "ret" with bad abbreviation (4).
277 RetVoidIndex, NaClMungedBitcode::Replace, 416 RetVoidIndex, NaClMungedBitcode::Replace,
278 4, naclbitc::FUNC_CODE_INST_RET, Terminator 417 4, naclbitc::FUNC_CODE_INST_RET, Terminator
279 }; 418 };
280 419
281 NaClWriteMunger Munger(ARRAY_TERM(BitcodeRecords)); 420 CheckDumpEdits(
282 Munger.munge(ARRAY(Edits)); 421 ARRAY(Edits),
283 EXPECT_EQ( 422 "Error (Block 12): Abbreviation doesn't apply to record: 4: [10]\n",
284 " 1: [65535, 8, 2]\n" 423 "",
285 " 1: [65535, 17, 3]\n" 424 " 0:0|<65532, 80, 69, 88, 69, 1, 0,|Magic Number: 'PEXE' (80, 69,"
286 " 3: [1, 2]\n" 425 " 88, 69)\n"
287 " 3: [2]\n" 426 " | 8, 0, 17, 0, 4, 0, 2, 0, 0, |PNaCl Version: 2\n"
288 " 3: [21, 0, 0]\n" 427 " | 0> |\n"
289 " 0: [65534]\n" 428 " 16:0|1: <65535, 8, 2> |module { // BlockID = 8\n"
290 " 3: [8, 1, 0, 0, 0]\n" 429 " 24:0| 1: <65535, 17, 3> | types { // BlockID = 17\n"
291 " 1: [65535, 12, 3]\n" // Upped abbreviation index bits to 3 430 " 32:0| 3: <1, 2> | count 2;\n"
292 " 3: [1, 1]\n" 431 " 34:5| 3: <2> | @t0 = void;\n"
293 " 2: [65533, 1, 1, 9]\n" // added abbrev 4: [9] 432 " 36:4| 3: <21, 0, 0> | @t1 = void ();\n"
294 " 4: [10]\n" // "ret" with bad abbreviation. 433 " 39:7| 0: <65534> | }\n"
295 " 0: [65534]\n" 434 " 44:0| 3: <8, 1, 0, 0, 0> | define external void @f0();\n"
296 " 0: [65534]\n", 435 // Upped abbreviation index bits to 3
297 stringify(Munger)); 436 " 48:6| 1: <65535, 12, 3> | function void @f0() { \n"
298 437 " | | // BlockID"
299 // Show detected error 438 " = 12\n"
300 EXPECT_FALSE(Munger.runTest()); 439 " 56:0| 3: <1, 1> | blocks 1;\n"
301 EXPECT_EQ( 440 // added abbrev 4: [9]
302 "Error (Block 12): Abbreviation doesn't apply to record: 4: [10]\n" 441 " 58:5| 2: <65533, 1, 1, 9> | %a0 = abbrev <9>;\n"
303 "Error: Unable to generate bitcode file due to write errors\n", 442 " | | %b0:\n"
304 Munger.getTestResults()); 443 // Implicit repair of abbreviation index (from 4 to 3: the default abbrev)
305 444 " 60:6| 3: <10> | ret void;\n"
306 // Show that the writer can recover. 445 " 62:5| 0: <65534> | }\n"
307 Munger.setTryToRecoverOnWrite(true); 446 " 64:0|0: <65534> |}\n");
308 EXPECT_TRUE(Munger.runTest(ARRAY(Edits)));
309 EXPECT_EQ(
310 "Error (Block 12): Abbreviation doesn't apply to record: 4: [10]\n"
311 " 1: [65535, 8, 2]\n"
312 " 1: [65535, 17, 3]\n"
313 " 3: [1, 2]\n"
314 " 3: [2]\n"
315 " 3: [21, 0, 0]\n"
316 " 0: [65534]\n"
317 " 3: [8, 1, 0, 0, 0]\n"
318 " 1: [65535, 12, 3]\n"
319 " 3: [1, 1]\n"
320 " 2: [65533, 1, 1, 9]\n"
321 " 3: [10]\n" // Implicit repair here.
322 " 0: [65534]\n"
323 " 0: [65534]\n",
324 Munger.getTestResults());
325 } 447 }
326 448
327 // Show that we recognize when an abbreviation definition record is 449 // Show that we recognize when an abbreviation definition record is
328 // malformed. Also show that we repair the problem by removing the 450 // malformed. Also show that we repair the problem by removing the
329 // definition. 451 // definition.
330 TEST(NaClMungeWriteErrorsTests, TestWritingMalformedAbbreviation) { 452 TEST(NaClMungeWriteErrorsTests, TestWritingMalformedAbbreviation) {
331 // Create edits to: 453 // Create edits to:
332 // 1) Expand the number of abbreviation index bits for the block from 2 to 3. 454 // 1) Expand the number of abbreviation index bits for the block from 2 to 3.
333 // 2) Leave out the "literal" operand encoding out. 455 // 2) Leave out the "literal" operand encoding out.
334 const uint64_t FunctionEnterIndex = 7; 456 const uint64_t FunctionEnterIndex = 7;
335 const uint64_t Edits[] { 457 const uint64_t Edits[] {
336 FunctionEnterIndex, NaClMungedBitcode::Replace, // Set Abbrev bits = 3 458 FunctionEnterIndex, NaClMungedBitcode::Replace, // Set Abbrev bits = 3
337 1, naclbitc::BLK_CODE_ENTER, naclbitc::FUNCTION_BLOCK_ID, 3, Terminator, 459 1, naclbitc::BLK_CODE_ENTER, naclbitc::FUNCTION_BLOCK_ID, 3, Terminator,
338 RetVoidIndex, NaClMungedBitcode::AddBefore, 460 RetVoidIndex, NaClMungedBitcode::AddBefore,
339 // Bad abbreviation! Intentionally leave out "literal" operand: 1 461 // Bad abbreviation! Intentionally leave out "literal" operand: 1
340 2, naclbitc::BLK_CODE_DEFINE_ABBREV, 1, // 1, 462 2, naclbitc::BLK_CODE_DEFINE_ABBREV, 1, // 1,
341 naclbitc::FUNC_CODE_INST_RET, Terminator, 463 naclbitc::FUNC_CODE_INST_RET, Terminator,
342 }; 464 };
343 465
344 // Show that the error is detected. 466 CheckDumpEdits(
345 NaClWriteMunger Munger(ARRAY_TERM(BitcodeRecords)); 467 ARRAY(Edits),
346 EXPECT_FALSE(Munger.runTest(ARRAY(Edits))); 468 "Error (Block 12): Bad abbreviation operand encoding 10:"
347 EXPECT_EQ( 469 " 2: [65533, 1, 10]\n",
348 "Error (Block 12): Error: Bad abbreviation operand encoding 10:" 470 "",
349 " 2: [65533, 1, 10]\n" 471 " 0:0|<65532, 80, 69, 88, 69, 1, 0,|Magic Number: 'PEXE' (80, 69,"
350 "Error: Unable to generate bitcode file due to write errors\n", 472 " 88, 69)\n"
351 Munger.getTestResults()); 473 " | 8, 0, 17, 0, 4, 0, 2, 0, 0, |PNaCl Version: 2\n"
352 474 " | 0> |\n"
353 // Show that the writer can recover. 475 " 16:0|1: <65535, 8, 2> |module { // BlockID = 8\n"
354 Munger.setTryToRecoverOnWrite(true); 476 " 24:0| 1: <65535, 17, 3> | types { // BlockID = 17\n"
355 EXPECT_TRUE(Munger.runTest(ARRAY(Edits))); 477 " 32:0| 3: <1, 2> | count 2;\n"
356 EXPECT_EQ( 478 " 34:5| 3: <2> | @t0 = void;\n"
357 "Error (Block 12): Error: Bad abbreviation operand encoding 10: " 479 " 36:4| 3: <21, 0, 0> | @t1 = void ();\n"
358 "2: [65533, 1, 10]\n" 480 " 39:7| 0: <65534> | }\n"
359 " 1: [65535, 8, 2]\n" 481 " 44:0| 3: <8, 1, 0, 0, 0> | define external void @f0();\n"
360 " 1: [65535, 17, 3]\n" 482 // Edit to change number of abbrev bits to 3.
361 " 3: [1, 2]\n" 483 " 48:6| 1: <65535, 12, 3> | function void @f0() { \n"
362 " 3: [2]\n" 484 " | | // BlockID"
363 " 3: [21, 0, 0]\n" 485 " = 12\n"
364 " 0: [65534]\n" 486 " 56:0| 3: <1, 1> | blocks 1;\n"
365 " 3: [8, 1, 0, 0, 0]\n" 487 " | | %b0:\n"
366 " 1: [65535, 12, 3]\n" // Note: not followed by abbreviation def. 488 " 58:5| 3: <10> | ret void;\n"
367 " 3: [1, 1]\n" 489 " 60:4| 0: <65534> | }\n"
368 " 3: [10]\n" 490 " 64:0|0: <65534> |}\n");
369 " 0: [65534]\n"
370 " 0: [65534]\n",
371 Munger.getTestResults());
372 } 491 }
373 492
374 // Show how we deal with additional abbreviations defined for a block, 493 // Show how we deal with additional abbreviations defined for a block,
375 // once a bad abbreviation definition record is found. That is, we 494 // once a bad abbreviation definition record is found. That is, we
376 // remove all succeeding abbreviations definitions for that block. In 495 // remove all succeeding abbreviations definitions for that block. In
377 // addition, any record refering to a remove abbreviation is changed 496 // addition, any record refering to a remove abbreviation is changed
378 // to use the default abbreviation. 497 // to use the default abbreviation.
379 TEST(NaClMungedWriteErrorTests, TestRemovingAbbrevWithMultAbbrevs) { 498 TEST(NaClMungedWriteErrorTests, TestRemovingAbbrevWithMultAbbrevs) {
380 NaClWriteMunger Munger(ARRAY_TERM(BitcodeRecords)); 499 NaClWriteMunger Munger(ARRAY_TERM(BitcodeRecords));
381 const uint64_t FunctionEnterIndex = 7; 500 const uint64_t FunctionEnterIndex = 7;
382 const uint64_t Edits[] { 501 const uint64_t Edits[] {
383 FunctionEnterIndex, NaClMungedBitcode::Replace, // Set Abbrev bits = 3 502 FunctionEnterIndex, NaClMungedBitcode::Replace, // Set Abbrev bits = 3
384 1, naclbitc::BLK_CODE_ENTER, naclbitc::FUNCTION_BLOCK_ID, 3, Terminator, 503 1, naclbitc::BLK_CODE_ENTER, naclbitc::FUNCTION_BLOCK_ID, 3, Terminator,
385 RetVoidIndex, NaClMungedBitcode::AddBefore, // bad abbreviation! 504 RetVoidIndex, NaClMungedBitcode::AddBefore, // bad abbreviation!
386 2, naclbitc::BLK_CODE_DEFINE_ABBREV, 1, // 1, 505 2, naclbitc::BLK_CODE_DEFINE_ABBREV, 1, // 1,
387 naclbitc::FUNC_CODE_INST_RET - 1, Terminator, 506 naclbitc::FUNC_CODE_INST_RET - 1, Terminator,
388 RetVoidIndex, NaClMungedBitcode::AddBefore, // good abbreviation to ignore. 507 RetVoidIndex, NaClMungedBitcode::AddBefore, // good abbreviation to ignore.
389 2, naclbitc::BLK_CODE_DEFINE_ABBREV, 1, 1, 508 2, naclbitc::BLK_CODE_DEFINE_ABBREV, 1, 1,
390 naclbitc::FUNC_CODE_INST_RET, Terminator, 509 naclbitc::FUNC_CODE_INST_RET, Terminator,
391 RetVoidIndex, NaClMungedBitcode::Replace, // reference to good abreviation. 510 RetVoidIndex, NaClMungedBitcode::Replace, // reference to good abreviation.
392 5, naclbitc::FUNC_CODE_INST_RET, Terminator 511 5, naclbitc::FUNC_CODE_INST_RET, Terminator
393 }; 512 };
394 513
395 Munger.setTryToRecoverOnWrite(true); 514 CheckDumpEdits(
396 EXPECT_TRUE(Munger.runTest(ARRAY(Edits))); 515 ARRAY(Edits),
397 EXPECT_EQ( 516 "Error (Block 12): Bad abbreviation operand encoding 9:"
398 "Error (Block 12): Error: Bad abbreviation operand encoding 9:" 517 " 2: [65533, 1, 9]\n",
399 " 2: [65533, 1, 9]\n"
400 "Error (Block 12): Ignoring abbreviation: 2: [65533, 1, 1, 10]\n" 518 "Error (Block 12): Ignoring abbreviation: 2: [65533, 1, 1, 10]\n"
401 "Error (Block 12): Uses illegal abbreviation index: 5: [10]\n" 519 "Error (Block 12): Uses illegal abbreviation index: 5: [10]\n",
402 " 1: [65535, 8, 2]\n" 520 " 0:0|<65532, 80, 69, 88, 69, 1, 0,|Magic Number: 'PEXE' (80, 69,"
403 " 1: [65535, 17, 3]\n" 521 " 88, 69)\n"
404 " 3: [1, 2]\n"
405 " 3: [2]\n"
406 " 3: [21, 0, 0]\n"
407 " 0: [65534]\n"
408 " 3: [8, 1, 0, 0, 0]\n"
409 " 1: [65535, 12, 3]\n"
410 " 3: [1, 1]\n"
411 " 3: [10]\n" // Abbreviation index 5 replaced with default.
412 " 0: [65534]\n"
413 " 0: [65534]\n",
414 Munger.getTestResults());
415 }
416
417 // Show that error recovery works when writing an illegal abbreviation
418 // index. Show success by parsing fixed bitcode.
419 TEST(NaClMungeWriteErrorTests, RecoverWhenParsingBadAbbrevIndex) {
420 NaClParseBitcodeMunger Munger(ARRAY_TERM(BitcodeRecords));
421 Munger.setTryToRecoverOnWrite(true);
422 EXPECT_TRUE(
423 Munger.runTest(ARRAY(AbbrevIndex4VoidTypeEdit), true));
424 EXPECT_EQ(
425 "Error (Block 17): Uses illegal abbreviation index: 4: [2]\n"
426 "Successful parse!\n",
427 Munger.getTestResults());
428 }
429
430 // Show that error recovery works when writing an illegal abbreviation
431 // index. Show success by Dumping fixed bitcode.
432 TEST(NaClMungeWriteErrorTests, RecoverWhenParsingBadAbbreviationIndex) {
433 NaClObjDumpMunger Munger(ARRAY_TERM(BitcodeRecords));
434 Munger.setTryToRecoverOnWrite(true);
435 EXPECT_TRUE(Munger.runTest(ARRAY(AbbrevIndex4VoidTypeEdit)));
436 std::string Results(
437 "Error (Block 17): Uses illegal abbreviation index: 4: [2]\n");
438 Results.append(ExpectedDump);
439 EXPECT_EQ(Results, Munger.getTestResults());
440 }
441
442 // Show that error recovery works when writing too many locally
443 // defined abbreviations for the corresponding number of bits defined
444 // in the corresponding enter block. Show success by dumping the fixed
445 // bitcode.
446 TEST(NaClMungeWriteErrorTests, RecoverTooManyLocalAbbreviations) {
447 NaClObjDumpMunger Munger(ARRAY_TERM(BitcodeRecords));
448 Munger.setTryToRecoverOnWrite(true);
449 Munger.munge(ARRAY(UseLocalRetVoidAbbrevEdits));
450 EXPECT_TRUE(Munger.runTest());
451 EXPECT_EQ(
452 "Error (Block 12): Uses illegal abbreviation index: 4: [10]\n"
453 " 0:0|<65532, 80, 69, 88, 69, 1, 0,|Magic Number: 'PEXE'"
454 " (80, 69, 88, 69)\n"
455 " | 8, 0, 17, 0, 4, 0, 2, 0, 0, |PNaCl Version: 2\n" 522 " | 8, 0, 17, 0, 4, 0, 2, 0, 0, |PNaCl Version: 2\n"
456 " | 0> |\n" 523 " | 0> |\n"
457 " 16:0|1: <65535, 8, 2> |module { // BlockID = 8\n" 524 " 16:0|1: <65535, 8, 2> |module { // BlockID = 8\n"
458 " 24:0| 1: <65535, 17, 3> | types { // BlockID = 17\n" 525 " 24:0| 1: <65535, 17, 3> | types { // BlockID = 17\n"
459 " 32:0| 3: <1, 2> | count 2;\n" 526 " 32:0| 3: <1, 2> | count 2;\n"
460 " 34:5| 3: <2> | @t0 = void;\n" 527 " 34:5| 3: <2> | @t0 = void;\n"
461 " 36:4| 3: <21, 0, 0> | @t1 = void ();\n" 528 " 36:4| 3: <21, 0, 0> | @t1 = void ();\n"
462 " 39:7| 0: <65534> | }\n" 529 " 39:7| 0: <65534> | }\n"
463 " 44:0| 3: <8, 1, 0, 0, 0> | define external void @f0();\n" 530 " 44:0| 3: <8, 1, 0, 0, 0> | define external void @f0();\n"
464 // Block only specifies 2 bits for abbreviations (i.e. limit = 3). 531 // Edit to change number of abbrev bits to 3.
465 " 48:6| 1: <65535, 12, 2> | function void @f0() { \n" 532 " 48:6| 1: <65535, 12, 3> | function void @f0() { \n"
466 " | | // BlockID" 533 " | | // BlockID"
467 " = 12\n" 534 " = 12\n"
468 " 56:0| 3: <1, 1> | blocks 1;\n" 535 " 56:0| 3: <1, 1> | blocks 1;\n"
469 // Added abbreviation. Defines abbreviation index 4.
470 " 58:4| 2: <65533, 1, 1, 10> | %a0 = abbrev <10>;\n"
471 " | | %b0:\n" 536 " | | %b0:\n"
472 // Repaired abbreviation index of 4 (now 3). 537 " 58:5| 3: <10> | ret void;\n"
473 " 60:4| 3: <10> | ret void;\n" 538 " 60:4| 0: <65534> | }\n"
474 " 62:2| 0: <65534> | }\n" 539 " 64:0|0: <65534> |}\n");
475 " 64:0|0: <65534> |}\n",
476 Munger.getTestResults());
477 } 540 }
478 541
479 // Show that error recovery works when writing and there are more 542 // Show that inserting an abbreviation with a bad fixed width is dealt with.
480 // enter blocks than exit blocks. Show success by dumping fixed 543 TEST(NaClMungeWriteErrorTests, InvalidFixedAbbreviationSize) {
481 // bitcode. 544 // Insert bad abbreviation Fixed(36) into type block.
482 TEST(NaClMungeWriteErrorTests, RecoverTooManyEnterBlocks) { 545 assert(36 > naclbitc::MaxAbbrevWidth);
483 NaClObjDumpMunger Munger(ARRAY_TERM(BitcodeRecords)); 546 const uint64_t Edit[] = {
484 // Remove all but first two records (i.e. two enter blocks). 547 VoidTypeIndex, NaClMungedBitcode::AddBefore,
485 NaClMungedBitcode &MungedBitcode = Munger.getMungedBitcode(); 548 naclbitc::DEFINE_ABBREV, naclbitc::BLK_CODE_DEFINE_ABBREV, 1,
486 for (size_t i = 2; i < MungedBitcode.getBaseRecords().size(); ++i) { 549 0, NaClBitCodeAbbrevOp::Fixed, 36, Terminator
487 MungedBitcode.remove(i); 550 };
488 } 551 CheckDumpEdits(
489 552 ARRAY(Edit),
490 Munger.setTryToRecoverOnWrite(true); 553 "Error (Block 17): Invalid abbreviation Fixed(36) in: 2: [65533, 1, 0,"
491 EXPECT_TRUE(Munger.runTest()); 554 " 1, 36]\n",
492 EXPECT_EQ( 555 NoErrorRecoveryMessages,
493 "Error (Block 17): Missing close block.\n" 556 ExpectedDumpedBitcode);
494 "Error (Block 8): Missing close block.\n"
495 " 0:0|<65532, 80, 69, 88, 69, 1, 0,|Magic Number: 'PEXE' (80, 69,"
496 " 88, 69)\n"
497 " | 8, 0, 17, 0, 4, 0, 2, 0, 0, |PNaCl Version: 2\n"
498 " | 0> |\n"
499 " 16:0|1: <65535, 8, 2> |module { // BlockID = 8\n"
500 " 24:0| 1: <65535, 17, 3> | types { // BlockID = 17\n"
501 " 32:0| 0: <65534> | }\n"
502 " 36:0|0: <65534> |}\n",
503 Munger.getTestResults());
504 } 557 }
505 558
506 // Show that error recovery works when writing and there are fewer 559 // Show that inserting an abbreviation with a bad vbr width is dealt with.
507 // enter blocks than exit blocks. Show success by dumping the fixed 560 TEST(NaClMungeWriteErrorTests, InvalidVbrAbbreviationSize) {
508 // bitcode. 561 // Insert bad abbreviation Vbr(36) into type block.
509 TEST(NaClMungeWriteErrorTests, RecoverTooManyExitBlocks) { 562 assert(36 > naclbitc::MaxAbbrevWidth);
510 NaClObjDumpMunger Munger(ARRAY_TERM(BitcodeRecords)); 563 const uint64_t Edit[] = {
511 // Add two exit blocks. 564 VoidTypeIndex, NaClMungedBitcode::AddBefore,
512 NaClMungedBitcode &MungedBitcode = Munger.getMungedBitcode(); 565 naclbitc::DEFINE_ABBREV, naclbitc::BLK_CODE_DEFINE_ABBREV, 1,
513 NaClRecordVector Values; 566 0, NaClBitCodeAbbrevOp::VBR, 36, Terminator
514 NaClBitcodeAbbrevRecord Record(0, naclbitc::BLK_CODE_EXIT, Values); 567 };
515 for (size_t i = 0; i < 2; ++i) 568 CheckDumpEdits(
516 MungedBitcode.addAfter(MungedBitcode.getBaseRecords().size() - 1, Record); 569 ARRAY(Edit),
517 570 "Error (Block 17): Invalid abbreviation VBR(36) in: 2: [65533, 1, 0,"
518 Munger.setTryToRecoverOnWrite(true); 571 " 2, 36]\n",
519 EXPECT_TRUE(Munger.runTest()); 572 NoErrorRecoveryMessages,
520 std::string Results( 573 ExpectedDumpedBitcode);
521 "Error (Block unknown): Extraneous exit block: 0: [65534]\n"
522 "Error (Block unknown): Extraneous exit block: 0: [65534]\n");
523 Results.append(ExpectedDump);
524 EXPECT_EQ(
525 Results,
526 Munger.getTestResults());
527 } 574 }
528 575
529 // Show that error recovery works when writing a bitcode record that 576 // Show that the array operator can't appear last.
530 // isn't in any block. Show success by showing fixed bitcode records. 577 TEST(NaClMungeWriteErrorTests, InvalidArrayAbbreviationLast) {
531 TEST(NaClMungeWriteErrorTests, RecoverWriteRecordOutsideBlock) { 578 const uint64_t Edit[] = {
532 NaClWriteMunger Munger(ARRAY_TERM(BitcodeRecords)); 579 VoidTypeIndex, NaClMungedBitcode::AddBefore,
533 NaClMungedBitcode &MungedBitcode = Munger.getMungedBitcode(); 580 naclbitc::DEFINE_ABBREV, naclbitc::BLK_CODE_DEFINE_ABBREV, 1,
534 NaClRecordVector Values; 581 0, NaClBitCodeAbbrevOp::Array, Terminator
535 Values.push_back(4); 582 };
536 NaClBitcodeAbbrevRecord Record(naclbitc::UNABBREV_RECORD, 583 CheckDumpEdits(
537 naclbitc::MODULE_CODE_VERSION, 584 ARRAY(Edit),
538 Values); 585 "Error (Block 17): Array abbreviation must be second to last: 2: [65533,"
539 MungedBitcode.addAfter(MungedBitcode.getBaseRecords().size() - 1, Record); 586 " 1, 0, 3]\n",
587 NoErrorRecoveryMessages,
588 ExpectedDumpedBitcode);
589 }
540 590
541 Munger.setTryToRecoverOnWrite(true); 591 // Show that the array operator can't appear before the second to last
542 EXPECT_TRUE(Munger.runTest()); 592 // operand.
543 EXPECT_EQ( 593 TEST(NaClMungeWriteErrorTests, InvalidArrayAbbreviationTooEarly) {
544 "Error (Block unknown): Record outside block: 3: [1, 4]\n" 594 const uint64_t Edit[] = {
545 "Error (Block unknown): Missing close block.\n" 595 VoidTypeIndex, NaClMungedBitcode::AddBefore,
546 " 1: [65535, 8, 2]\n" 596 naclbitc::DEFINE_ABBREV, naclbitc::BLK_CODE_DEFINE_ABBREV, 3,
547 " 1: [65535, 17, 3]\n" 597 0, NaClBitCodeAbbrevOp::Array, // array
548 " 3: [1, 2]\n" 598 1, 15, // lit(15)
549 " 3: [2]\n" 599 1, 10, // lit(10)
550 " 3: [21, 0, 0]\n" 600 Terminator
551 " 0: [65534]\n" 601 };
552 " 3: [8, 1, 0, 0, 0]\n" 602 CheckDumpEdits(
553 " 1: [65535, 12, 2]\n" 603 ARRAY(Edit),
554 " 3: [1, 1]\n" 604 "Error (Block 17): Array abbreviation must be second to last: 2: [65533,"
555 " 3: [10]\n" 605 " 3, 0, 3, 1, 15, 1, 10]\n",
556 " 0: [65534]\n" 606 NoErrorRecoveryMessages,
557 " 0: [65534]\n" 607 ExpectedDumpedBitcode);
558 " 1: [65535, 4294967295, 3]\n" 608 }
559 " 3: [1, 4]\n" 609
560 " 0: [65534]\n", 610 // Show that the array operator can't appear as last two operators.
561 Munger.getTestResults()); 611 TEST(NaClMungeWriteErrorTests, InvalidArrayAbbreviationLastTwo) {
612 const uint64_t Edit[] = {
613 VoidTypeIndex, NaClMungedBitcode::AddBefore,
614 naclbitc::DEFINE_ABBREV, naclbitc::BLK_CODE_DEFINE_ABBREV, 2,
615 0, NaClBitCodeAbbrevOp::Array, // array
616 0, NaClBitCodeAbbrevOp::Array, // array
617 Terminator
618 };
619 CheckDumpEdits(
620 ARRAY(Edit),
621 "Error (Block 17): Array abbreviation must be second to last: 2: [65533,"
622 " 2, 0, 3, 0, 3]\n",
623 NoErrorRecoveryMessages,
624 ExpectedDumpedBitcode);
625 }
626
627 // Show what happens when an abbreviation is specified to only contain
628 // one operator, but is then followed with more than one operator.
629 TEST(NaClMungeWriteErrorTests, SpecifiesTooFewOperands) {
630 const uint64_t Edit[] = {
631 VoidTypeIndex, NaClMungedBitcode::AddBefore,
632 // Note: 1 at end of next line specified that the abbreviation
633 // should only have one operator.
634 naclbitc::DEFINE_ABBREV, naclbitc::BLK_CODE_DEFINE_ABBREV, 1,
635 1, 10, // lit(10)
636 1, 15, // lit(15)
637 Terminator
638 };
639 CheckDumpEdits(
640 ARRAY(Edit),
641 "Error (Block 17): Error: Too many values for number of operands (1):"
642 " 2: [65533, 1, 1, 10, 1, 15]\n",
643 NoErrorRecoveryMessages,
644 ExpectedDumpedBitcode);
645 }
646
647 // Show that the code checks if specifies too many operands for an
648 // abbreviation, based on the record size.
649 TEST(NaClMungeWriteErrorTests, SpecifiesTooManyOperands) {
650 // Insert bad abbreviation Vbr(36) into type block.
651 const uint64_t Edit[] = {
652 VoidTypeIndex, NaClMungedBitcode::AddBefore,
653 naclbitc::DEFINE_ABBREV, naclbitc::BLK_CODE_DEFINE_ABBREV, 3,
654 1, 10, // lit(10)
655 1, 15, // lit(15)
656 Terminator
657 };
658 CheckDumpEdits(
659 ARRAY(Edit),
660 "Error (Block 17): Malformed abbreviation found: 2: [65533, 3, 1, 10,"
661 " 1, 15]\n",
662 NoErrorRecoveryMessages,
663 ExpectedDumpedBitcode);
562 } 664 }
563 665
564 } // end of namespace naclmungetest 666 } // end of namespace naclmungetest
OLDNEW
« no previous file with comments | « lib/Bitcode/NaCl/TestUtils/NaClBitcodeMungeWriter.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698