| 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 |
| 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 // simpler write munger. |
| 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 simpler write munger instead |
| 136 // of the bitcode parser. Records is the records dumped by the write |
| 137 // 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 |