OLD | NEW |
---|---|
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 Loading... | |
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 |
OLD | NEW |