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

Unified Diff: unittests/Bitcode/NaClMungeWriteErrorTests.cpp

Issue 1157273004: Check for invalid abbreviation operators in munged bitcode. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-llvm.git@master
Patch Set: Fix nits. Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « lib/Bitcode/NaCl/TestUtils/NaClBitcodeMungeWriter.cpp ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: unittests/Bitcode/NaClMungeWriteErrorTests.cpp
diff --git a/unittests/Bitcode/NaClMungeWriteErrorTests.cpp b/unittests/Bitcode/NaClMungeWriteErrorTests.cpp
index fa2bec420b3ab7b8370658ca5cf446c3afe08eac..3fdcce26d5d376fb54764258fcbff90a0642a5ca 100644
--- a/unittests/Bitcode/NaClMungeWriteErrorTests.cpp
+++ b/unittests/Bitcode/NaClMungeWriteErrorTests.cpp
@@ -37,8 +37,13 @@ const uint64_t BitcodeRecords[] = {
0, naclbitc::BLK_CODE_EXIT, Terminator
};
+// Indices to records in bitcode.
+const uint64_t VoidTypeIndex = 3; // Index for "@t0 = void".
+const uint64_t RetVoidIndex = 9; // return void;
+const uint64_t LastExitBlockIndex = 11;
+
// Expected output when bitcode records are dumped.
-const char* ExpectedDump =
+const char *ExpectedDumpedBitcode =
" 0:0|<65532, 80, 69, 88, 69, 1, 0,|Magic Number: 'PEXE' (80, 69, "
"88, 69)\n"
" | 8, 0, 17, 0, 4, 0, 2, 0, 0, |PNaCl Version: 2\n"
@@ -60,121 +65,243 @@ const char* ExpectedDump =
" 64:0|0: <65534> |}\n"
;
-// Edit to change void type with an illegal abbreviation index.
-const uint64_t VoidTypeIndex = 3; // Index for "@t0 = void".
-const uint64_t AbbrevIndex4VoidTypeEdit[] = {
- VoidTypeIndex, NaClMungedBitcode::Replace,
- 4, naclbitc::TYPE_CODE_VOID, Terminator,
-};
+const char *UnableToContinue =
+ "Error: Unable to generate bitcode file due to write errors\n";
-// Edit to add local abbreviation for "ret void", and then use on that
-// instruction.
-const uint64_t RetVoidIndex = 9; // return void;
-const uint64_t UseLocalRetVoidAbbrevEdits[] = {
- RetVoidIndex, NaClMungedBitcode::AddBefore,
- 2, naclbitc::BLK_CODE_DEFINE_ABBREV, 1, 1,
- naclbitc::FUNC_CODE_INST_RET, Terminator,
- RetVoidIndex, NaClMungedBitcode::Replace,
- 4, naclbitc::FUNC_CODE_INST_RET, Terminator
-};
+const char *NoErrorRecoveryMessages = "";
+
+// Runs write munging tests on BitcodeRecords with the given Edits. It
+// then parses the written bitcode. ErrorMessages is the expected
+// error messages logged by the write munging, when no error recovery
+// is allowed. ErrorRecoveryMessages are messages, in addition to
+// ErrorMessages, when the writer applies error recovery.
+void CheckParseEdits(const uint64_t *Edits, size_t EditsSize,
+ std::string ErrorMessages,
+ std::string ErrorRecoveryMessages) {
+ NaClParseBitcodeMunger Munger(ARRAY_TERM(BitcodeRecords));
+ EXPECT_FALSE(Munger.runTest(Edits, EditsSize, true));
+ std::string BadResults(ErrorMessages);
+ BadResults.append(UnableToContinue);
+ EXPECT_EQ(BadResults, Munger.getTestResults());
+
+ Munger.setTryToRecoverOnWrite(true);
+ EXPECT_TRUE(Munger.runTest(Edits, EditsSize, true));
+ std::string GoodResults(ErrorMessages);
+ GoodResults.append(ErrorRecoveryMessages);
+ GoodResults.append("Successful parse!\n");
+ EXPECT_EQ(GoodResults, Munger.getTestResults());
+}
+
+// Same as CheckParseEdits, but also runs the bitcode dumper on the
+// 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.
+// bitcode.
+void CheckDumpEdits(const uint64_t *Edits, size_t EditsSize,
+ std::string ErrorMessages,
+ std::string ErrorRecoveryMessages,
+ std::string DumpedBitcode) {
+ NaClObjDumpMunger Munger(ARRAY_TERM(BitcodeRecords));
+ EXPECT_FALSE(Munger.runTest(Edits, EditsSize));
+ std::string BadResults(ErrorMessages);
+ BadResults.append(UnableToContinue);
+ EXPECT_EQ(BadResults, Munger.getTestResults());
+
+ Munger.setTryToRecoverOnWrite(true);
+ EXPECT_TRUE(Munger.runTest(Edits, EditsSize));
+ std::string GoodResults(ErrorMessages);
+ GoodResults.append(ErrorRecoveryMessages);
+ GoodResults.append(DumpedBitcode);
+ EXPECT_EQ(GoodResults, Munger.getTestResults());
+
+ // Verify that we can also parse the bitcode.
+ CheckParseEdits(Edits, EditsSize, ErrorMessages, ErrorRecoveryMessages);
+}
+
+// Same as ExpectedDumpedBitcode, but is just the records dumped by the
+// simplier write munger.
jvoung (off chromium) 2015/05/29 16:43:25 simplier -> simpler
Karl 2015/05/29 20:02:16 Done.
+const char *ExpectedRecords =
+ " 1: [65535, 8, 2]\n"
+ " 1: [65535, 17, 3]\n"
+ " 3: [1, 2]\n"
+ " 3: [2]\n"
+ " 3: [21, 0, 0]\n"
+ " 0: [65534]\n"
+ " 3: [8, 1, 0, 0, 0]\n"
+ " 1: [65535, 12, 2]\n"
+ " 3: [1, 1]\n"
+ " 3: [10]\n"
+ " 0: [65534]\n"
+ " 0: [65534]\n";
+
+// 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.
+// 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.
+// write munger. This should be used in cases where the written munged
+// records is not valid bitcode.
+void CheckWriteEdits(const uint64_t *Edits, size_t EditsSize,
+ std::string ExpectedErrorMessage,
+ std::string ErrorRecoveryMessages,
+ std::string Records) {
+ NaClWriteMunger Munger(ARRAY_TERM(BitcodeRecords));
+ EXPECT_FALSE(Munger.runTest(Edits, EditsSize));
+ std::string BadResults(ExpectedErrorMessage);
+ BadResults.append(UnableToContinue);
+ EXPECT_EQ(BadResults, Munger.getTestResults());
+
+ Munger.setTryToRecoverOnWrite(true);
+ EXPECT_TRUE(Munger.runTest(Edits, EditsSize));
+ std::string GoodResults(ExpectedErrorMessage);
+ GoodResults.append(ErrorRecoveryMessages);
+ GoodResults.append(Records);
+ EXPECT_EQ(GoodResults, Munger.getTestResults());
+}
// Show that we can dump the bitcode records
TEST(NaClMungeWriteErrorTests, DumpBitcodeRecords) {
NaClObjDumpMunger Munger(ARRAY_TERM(BitcodeRecords));
EXPECT_TRUE(Munger.runTest());
- EXPECT_EQ(ExpectedDump, Munger.getTestResults());
+ EXPECT_EQ(ExpectedDumpedBitcode, Munger.getTestResults());
}
+// Edit to change void type with an illegal abbreviation index.
+const uint64_t AbbrevIndex4VoidTypeEdit[] = {
+ VoidTypeIndex, NaClMungedBitcode::Replace,
+ 4, naclbitc::TYPE_CODE_VOID, Terminator,
+};
+
// Show that by default, one can't write a bad abbreviation index.
TEST(NaClMungeWriteErrorTests, CantWriteBadAbbrevIndex) {
+ CheckDumpEdits(
+ ARRAY(AbbrevIndex4VoidTypeEdit),
+ "Error (Block 17): Uses illegal abbreviation index: 4: [2]\n",
+ NoErrorRecoveryMessages,
+ ExpectedDumpedBitcode);
+}
+
+// Show that writing out an illegal abbreviation index, causes the
+// parser to fail.
+TEST(MyNaClMungerWriteErrorTests, DieOnWriteBadAbbreviationIndex) {
NaClWriteMunger Munger(ARRAY_TERM(BitcodeRecords));
- EXPECT_FALSE(Munger.runTest(ARRAY(AbbrevIndex4VoidTypeEdit)));
- EXPECT_EQ(
- "Error (Block 17): Uses illegal abbreviation index: 4: [2]\n"
- "Error: Unable to generate bitcode file due to write errors\n",
- Munger.getTestResults());
+ Munger.setWriteBadAbbrevIndex(true);
+ Munger.setRunAsDeathTest(true);
+ EXPECT_DEATH(
+ Munger.runTest(ARRAY(AbbrevIndex4VoidTypeEdit)),
+ ".*"
+ // Report problem while writing.
+ "Error \\(Block 17\\)\\: Uses illegal abbreviation index\\: 4\\: \\[2\\]"
+ ".*"
+ // Corresponding error while parsing.
+ "Fatal\\(35\\:0)\\: Invalid abbreviation \\# 4 defined for record"
+ ".*"
+ // Output of report_fatal_error.
+ "LLVM ERROR\\: Unable to continue"
+ ".*");
}
-// Show that we use more local abbreviations than specified in the
+// Show what happens when we use more local abbreviations than specified in the
// corresponding enclosing block.
TEST(NaClMungeWriteErrorTests, CantWriteTooManyLocalAbbreviations) {
- NaClWriteMunger Munger(ARRAY_TERM(BitcodeRecords));
- Munger.munge(ARRAY(UseLocalRetVoidAbbrevEdits));
- EXPECT_EQ(
- " 1: [65535, 8, 2]\n"
- " 1: [65535, 17, 3]\n"
- " 3: [1, 2]\n"
- " 3: [2]\n"
- " 3: [21, 0, 0]\n"
- " 0: [65534]\n"
- " 3: [8, 1, 0, 0, 0]\n"
- " 1: [65535, 12, 2]\n" // Only allows 2 bits for abbrevs.
- " 3: [1, 1]\n"
- " 2: [65533, 1, 1, 10]\n" // defines abbev 4:
- " 4: [10]\n" // can't use, 4 can't fit in two bits.
- " 0: [65534]\n"
- " 0: [65534]\n",
- stringify(Munger));
+ // Edit to add local abbreviation for "ret void", and then use on that
+ // instruction.
+ const uint64_t UseLocalRetVoidAbbrevEdits[] = {
+ RetVoidIndex, NaClMungedBitcode::AddBefore,
+ 2, naclbitc::BLK_CODE_DEFINE_ABBREV, 1, 1,
+ naclbitc::FUNC_CODE_INST_RET, Terminator,
+ RetVoidIndex, NaClMungedBitcode::Replace,
+ 4, naclbitc::FUNC_CODE_INST_RET, Terminator
+ };
- EXPECT_FALSE(Munger.runTest());
- EXPECT_EQ(
- "Error (Block 12): Uses illegal abbreviation index: 4: [10]\n"
- "Error: Unable to generate bitcode file due to write errors\n",
- Munger.getTestResults());
+ CheckDumpEdits(
+ ARRAY(UseLocalRetVoidAbbrevEdits),
+ "Error (Block 12): Uses illegal abbreviation index: 4: [10]\n",
+ NoErrorRecoveryMessages,
+ " 0:0|<65532, 80, 69, 88, 69, 1, 0,|Magic Number: 'PEXE'"
+ " (80, 69, 88, 69)\n"
+ " | 8, 0, 17, 0, 4, 0, 2, 0, 0, |PNaCl Version: 2\n"
+ " | 0> |\n"
+ " 16:0|1: <65535, 8, 2> |module { // BlockID = 8\n"
+ " 24:0| 1: <65535, 17, 3> | types { // BlockID = 17\n"
+ " 32:0| 3: <1, 2> | count 2;\n"
+ " 34:5| 3: <2> | @t0 = void;\n"
+ " 36:4| 3: <21, 0, 0> | @t1 = void ();\n"
+ " 39:7| 0: <65534> | }\n"
+ " 44:0| 3: <8, 1, 0, 0, 0> | define external void @f0();\n"
+ // Block only specifies 2 bits for abbreviations (i.e. limit = 3).
+ " 48:6| 1: <65535, 12, 2> | function void @f0() { \n"
+ " | | // BlockID"
+ " = 12\n"
+ " 56:0| 3: <1, 1> | blocks 1;\n"
+ // Added abbreviation. Defines abbreviation index 4.
+ " 58:4| 2: <65533, 1, 1, 10> | %a0 = abbrev <10>;\n"
+ " | | %b0:\n"
+ // Repaired abbreviation index of 4 (now 3).
+ " 60:4| 3: <10> | ret void;\n"
+ " 62:2| 0: <65534> | }\n"
+ " 64:0|0: <65534> |}\n");
}
// Show what happens when there are more enter blocks then exit blocks.
TEST(NaClMungeWriteErrorTests, CantWriteTooManyEnterBlocks) {
- NaClWriteMunger Munger(ARRAY_TERM(BitcodeRecords));
- // Remove all but first two records (i.e. two enter blocks).
- NaClMungedBitcode &MungedBitcode = Munger.getMungedBitcode();
- for (size_t i = 2; i < MungedBitcode.getBaseRecords().size(); ++i) {
- MungedBitcode.remove(i);
- }
-
- EXPECT_FALSE(Munger.runTest());
- EXPECT_EQ(
+ // Remove all records except the first two records in BitcodeRecords.
+ const uint64_t Edits[] = {
+ 2, NaClMungedBitcode::Remove,
+ 3, NaClMungedBitcode::Remove,
+ 4, NaClMungedBitcode::Remove,
+ 5, NaClMungedBitcode::Remove,
+ 6, NaClMungedBitcode::Remove,
+ 7, NaClMungedBitcode::Remove,
+ 8, NaClMungedBitcode::Remove,
+ 9, NaClMungedBitcode::Remove,
+ 10, NaClMungedBitcode::Remove,
+ 11, NaClMungedBitcode::Remove
+ };
+ CheckDumpEdits(
+ ARRAY(Edits),
"Error (Block 17): Missing close block.\n"
- "Error (Block 8): Missing close block.\n"
- "Error: Unable to generate bitcode file due to write errors\n",
- Munger.getTestResults());
+ "Error (Block 8): Missing close block.\n",
+ NoErrorRecoveryMessages,
+ " 0:0|<65532, 80, 69, 88, 69, 1, 0,|Magic Number: 'PEXE' (80, 69,"
+ " 88, 69)\n"
+ " | 8, 0, 17, 0, 4, 0, 2, 0, 0, |PNaCl Version: 2\n"
+ " | 0> |\n"
+ " 16:0|1: <65535, 8, 2> |module { // BlockID = 8\n"
+ " 24:0| 1: <65535, 17, 3> | types { // BlockID = 17\n"
+ " 32:0| 0: <65534> | }\n"
+ " 36:0|0: <65534> |}\n");
}
// Show what happens when there are fewer enter blocks than exit
// blocks.
TEST(NaClMungeWriteErrorTests, CantWriteTooManyExitBlocks) {
- NaClWriteMunger Munger(ARRAY_TERM(BitcodeRecords));
- // Add two exit blocks.
- NaClMungedBitcode &MungedBitcode = Munger.getMungedBitcode();
- NaClRecordVector Values;
- NaClBitcodeAbbrevRecord Record(0, naclbitc::BLK_CODE_EXIT, Values);
- for (size_t i = 0; i < 2; ++i)
- MungedBitcode.addAfter(MungedBitcode.getBaseRecords().size() - 1, Record);
-
- EXPECT_FALSE(Munger.runTest());
- EXPECT_EQ(
- "Error (Block unknown): Extraneous exit block: 0: [65534]\n"
- "Error: Unable to generate bitcode file due to write errors\n",
- Munger.getTestResults());
+ // Add two blocks to the end of BitcodeRecords.
+ const uint64_t Edits[] = {
+ LastExitBlockIndex, NaClMungedBitcode::AddAfter,
+ naclbitc::END_BLOCK, naclbitc::BLK_CODE_EXIT, Terminator,
+ LastExitBlockIndex, NaClMungedBitcode::AddAfter,
+ naclbitc::END_BLOCK, naclbitc::BLK_CODE_EXIT, Terminator
+ };
+ CheckDumpEdits(
+ ARRAY(Edits),
+ "Error (Block unknown): Extraneous exit block: 0: [65534]\n",
+ "Error (Block unknown): Extraneous exit block: 0: [65534]\n",
+ ExpectedDumpedBitcode);
}
// Show that an error occurs when writing a bitcode record that isn't
// in any block.
TEST(NaClMungeWriteErrorTests, CantWriteRecordOutsideBlock) {
- NaClWriteMunger Munger(ARRAY_TERM(BitcodeRecords));
- NaClMungedBitcode &MungedBitcode = Munger.getMungedBitcode();
- NaClRecordVector Values;
- Values.push_back(4);
- NaClBitcodeAbbrevRecord Record(naclbitc::UNABBREV_RECORD,
- naclbitc::MODULE_CODE_VERSION,
- Values);
-
- MungedBitcode.addAfter(MungedBitcode.getBaseRecords().size() - 1, Record);
- EXPECT_FALSE(Munger.runTest());
- EXPECT_EQ(
- "Error (Block unknown): Record outside block: 3: [1, 4]\n"
- "Error: Unable to generate bitcode file due to write errors\n",
- Munger.getTestResults());
+ const uint64_t Edit[] = {
+ LastExitBlockIndex, NaClMungedBitcode::AddAfter,
+ naclbitc::UNABBREV_RECORD, naclbitc::MODULE_CODE_VERSION, 4, Terminator
+ };
+ std::string Records(ExpectedRecords);
+ Records.append(
+ " 1: [65535, 4294967295, 3]\n"
+ " 3: [1, 4]\n"
+ " 0: [65534]\n");
+ CheckWriteEdits(
+ ARRAY(Edit),
+ "Error (Block unknown): Record outside block: 3: [1, 4]\n",
+ "Error (Block unknown): Missing close block.\n",
+ Records);
}
// Show that no error occurs if we write out the maximum allowable
@@ -189,7 +316,7 @@ TEST(NaClMungerWriteErrorTests, CanWriteBlockWithMaxLimit) {
NaClWriteMunger Munger(ARRAY_TERM(BitcodeRecords));
EXPECT_TRUE(Munger.runTest(ARRAY(Edit)));
EXPECT_EQ(
- " 1: [65535, 8, 32]\n"
+ " 1: [65535, 8, 32]\n" // Max abbreviation bit limit (32).
" 1: [65535, 17, 3]\n"
" 3: [1, 2]\n"
" 3: [2]\n"
@@ -213,13 +340,31 @@ TEST(NaClMungerWriteErrorTests, CantWriteBlockWithBadBitLimit) {
1, naclbitc::BLK_CODE_ENTER, naclbitc::MODULE_BLOCK_ID,
naclbitc::MaxAbbrevWidth + 1, Terminator
};
- NaClWriteMunger Munger(ARRAY_TERM(BitcodeRecords));
- EXPECT_FALSE(Munger.runTest(ARRAY(Edit)));
- EXPECT_EQ(
+ CheckDumpEdits(
+ ARRAY(Edit),
"Error (Block unknown): Block index bit limit 33 invalid. Must be in"
- " [2..32]: 1: [65535, 8, 33]\n"
- "Error: Unable to generate bitcode file due to write errors\n",
- Munger.getTestResults());
+ " [2..32]: 1: [65535, 8, 33]\n",
+ "",
+ " 0:0|<65532, 80, 69, 88, 69, 1, 0,|Magic Number: 'PEXE' (80, 69,"
+ " 88, 69)\n"
+ " | 8, 0, 17, 0, 4, 0, 2, 0, 0, |PNaCl Version: 2\n"
+ " | 0> |\n"
+ // Corrected bitsize from 33 to 32.
+ " 16:0|1: <65535, 8, 32> |module { // BlockID = 8\n"
+ " 24:0| 1: <65535, 17, 3> | types { // BlockID = 17\n"
+ " 36:0| 3: <1, 2> | count 2;\n"
+ " 38:5| 3: <2> | @t0 = void;\n"
+ " 40:4| 3: <21, 0, 0> | @t1 = void ();\n"
+ " 43:7| 0: <65534> | }\n"
+ " 48:0| 3: <8, 1, 0, 0, 0> | define external void @f0();\n"
+ " 56:4| 1: <65535, 12, 2> | function void @f0() { \n"
+ " | | // BlockID"
+ " = 12\n"
+ " 68:0| 3: <1, 1> | blocks 1;\n"
+ " | | %b0:\n"
+ " 70:4| 3: <10> | ret void;\n"
+ " 72:2| 0: <65534> | }\n"
+ " 76:0|0: <65534> |}\n");
}
// Show that we can't write an enter block with a very large block id.
@@ -229,33 +374,24 @@ TEST(NaClMungerWriteErrorTests, CantWriteBlockWithLargeBlockID) {
0, NaClMungedBitcode::Replace,
1, naclbitc::BLK_CODE_ENTER, (uint64_t)1 << 33, 2, Terminator
};
- NaClWriteMunger Munger(ARRAY_TERM(BitcodeRecords));
- EXPECT_FALSE(Munger.runTest(ARRAY(Edit)));
- EXPECT_EQ(
+ CheckWriteEdits(
+ ARRAY(Edit),
"Error (Block unknown): Block id must be <= 4294967295: 1:"
- " [65535, 8589934592, 2]\n"
- "Error: Unable to generate bitcode file due to write errors\n",
- Munger.getTestResults());
-}
-
-// Show that writing successfully writes out an illegal abbreviation
-// index, and then the parser fails to parse that illegal abbreviation.
-TEST(MyNaClMungerWriteErrorTests, DieOnWriteBadAbbreviationIndex) {
- NaClWriteMunger Munger(ARRAY_TERM(BitcodeRecords));
- Munger.setWriteBadAbbrevIndex(true);
- Munger.setRunAsDeathTest(true);
- EXPECT_DEATH(
- Munger.runTest(ARRAY(AbbrevIndex4VoidTypeEdit)),
- ".*"
- // Report problem while writing.
- "Error \\(Block 17\\)\\: Uses illegal abbreviation index\\: 4\\: \\[2\\]"
- ".*"
- // Corresponding error while parsing.
- "Fatal\\(35\\:0)\\: Invalid abbreviation \\# 4 defined for record"
- ".*"
- // Output of report_fatal_error.
- "LLVM ERROR\\: Unable to continue"
- ".*");
+ " [65535, 8589934592, 2]\n",
+ "",
+ // Note that the maximum block ID is used for recovery.
+ " 1: [65535, 4294967295, 2]\n"
+ " 1: [65535, 17, 3]\n"
+ " 3: [1, 2]\n"
+ " 3: [2]\n"
+ " 3: [21, 0, 0]\n"
+ " 0: [65534]\n"
+ " 3: [8, 1, 0, 0, 0]\n"
+ " 1: [65535, 12, 2]\n"
+ " 3: [1, 1]\n"
+ " 3: [10]\n"
+ " 0: [65534]\n"
+ " 0: [65534]\n");
}
// Show that we check that the abbreviation actually applies to the
@@ -269,59 +405,45 @@ TEST(NaClMungeWriteErrorsTests, TestMismatchedAbbreviation) {
// 3) Apply the bad abbreviation to record "ret"
const uint64_t FunctionEnterIndex = 7;
const uint64_t Edits[] {
+ // Upped abbreviation index bits to 3
FunctionEnterIndex, NaClMungedBitcode::Replace,
1, naclbitc::BLK_CODE_ENTER, naclbitc::FUNCTION_BLOCK_ID, 3, Terminator,
+ // abbrev 4: [9]
RetVoidIndex, NaClMungedBitcode::AddBefore,
2, naclbitc::BLK_CODE_DEFINE_ABBREV, 1, 1,
naclbitc::FUNC_CODE_INST_RET - 1, Terminator,
+ // "ret" with bad abbreviation (4).
RetVoidIndex, NaClMungedBitcode::Replace,
4, naclbitc::FUNC_CODE_INST_RET, Terminator
};
- NaClWriteMunger Munger(ARRAY_TERM(BitcodeRecords));
- Munger.munge(ARRAY(Edits));
- EXPECT_EQ(
- " 1: [65535, 8, 2]\n"
- " 1: [65535, 17, 3]\n"
- " 3: [1, 2]\n"
- " 3: [2]\n"
- " 3: [21, 0, 0]\n"
- " 0: [65534]\n"
- " 3: [8, 1, 0, 0, 0]\n"
- " 1: [65535, 12, 3]\n" // Upped abbreviation index bits to 3
- " 3: [1, 1]\n"
- " 2: [65533, 1, 1, 9]\n" // added abbrev 4: [9]
- " 4: [10]\n" // "ret" with bad abbreviation.
- " 0: [65534]\n"
- " 0: [65534]\n",
- stringify(Munger));
-
- // Show detected error
- EXPECT_FALSE(Munger.runTest());
- EXPECT_EQ(
- "Error (Block 12): Abbreviation doesn't apply to record: 4: [10]\n"
- "Error: Unable to generate bitcode file due to write errors\n",
- Munger.getTestResults());
-
- // Show that the writer can recover.
- Munger.setTryToRecoverOnWrite(true);
- EXPECT_TRUE(Munger.runTest(ARRAY(Edits)));
- EXPECT_EQ(
- "Error (Block 12): Abbreviation doesn't apply to record: 4: [10]\n"
- " 1: [65535, 8, 2]\n"
- " 1: [65535, 17, 3]\n"
- " 3: [1, 2]\n"
- " 3: [2]\n"
- " 3: [21, 0, 0]\n"
- " 0: [65534]\n"
- " 3: [8, 1, 0, 0, 0]\n"
- " 1: [65535, 12, 3]\n"
- " 3: [1, 1]\n"
- " 2: [65533, 1, 1, 9]\n"
- " 3: [10]\n" // Implicit repair here.
- " 0: [65534]\n"
- " 0: [65534]\n",
- Munger.getTestResults());
+ CheckDumpEdits(
+ ARRAY(Edits),
+ "Error (Block 12): Abbreviation doesn't apply to record: 4: [10]\n",
+ "",
+ " 0:0|<65532, 80, 69, 88, 69, 1, 0,|Magic Number: 'PEXE' (80, 69,"
+ " 88, 69)\n"
+ " | 8, 0, 17, 0, 4, 0, 2, 0, 0, |PNaCl Version: 2\n"
+ " | 0> |\n"
+ " 16:0|1: <65535, 8, 2> |module { // BlockID = 8\n"
+ " 24:0| 1: <65535, 17, 3> | types { // BlockID = 17\n"
+ " 32:0| 3: <1, 2> | count 2;\n"
+ " 34:5| 3: <2> | @t0 = void;\n"
+ " 36:4| 3: <21, 0, 0> | @t1 = void ();\n"
+ " 39:7| 0: <65534> | }\n"
+ " 44:0| 3: <8, 1, 0, 0, 0> | define external void @f0();\n"
+ // Upped abbreviation index bits to 3
+ " 48:6| 1: <65535, 12, 3> | function void @f0() { \n"
+ " | | // BlockID"
+ " = 12\n"
+ " 56:0| 3: <1, 1> | blocks 1;\n"
+ // added abbrev 4: [9]
+ " 58:5| 2: <65533, 1, 1, 9> | %a0 = abbrev <9>;\n"
+ " | | %b0:\n"
+ // Implicit repair of abbreviation index (from 4 to 3: the default abbrev)
+ " 60:6| 3: <10> | ret void;\n"
+ " 62:5| 0: <65534> | }\n"
+ " 64:0|0: <65534> |}\n");
}
// Show that we recognize when an abbreviation definition record is
@@ -341,34 +463,31 @@ TEST(NaClMungeWriteErrorsTests, TestWritingMalformedAbbreviation) {
naclbitc::FUNC_CODE_INST_RET, Terminator,
};
- // Show that the error is detected.
- NaClWriteMunger Munger(ARRAY_TERM(BitcodeRecords));
- EXPECT_FALSE(Munger.runTest(ARRAY(Edits)));
- EXPECT_EQ(
- "Error (Block 12): Error: Bad abbreviation operand encoding 10:"
- " 2: [65533, 1, 10]\n"
- "Error: Unable to generate bitcode file due to write errors\n",
- Munger.getTestResults());
-
- // Show that the writer can recover.
- Munger.setTryToRecoverOnWrite(true);
- EXPECT_TRUE(Munger.runTest(ARRAY(Edits)));
- EXPECT_EQ(
- "Error (Block 12): Error: Bad abbreviation operand encoding 10: "
- "2: [65533, 1, 10]\n"
- " 1: [65535, 8, 2]\n"
- " 1: [65535, 17, 3]\n"
- " 3: [1, 2]\n"
- " 3: [2]\n"
- " 3: [21, 0, 0]\n"
- " 0: [65534]\n"
- " 3: [8, 1, 0, 0, 0]\n"
- " 1: [65535, 12, 3]\n" // Note: not followed by abbreviation def.
- " 3: [1, 1]\n"
- " 3: [10]\n"
- " 0: [65534]\n"
- " 0: [65534]\n",
- Munger.getTestResults());
+ CheckDumpEdits(
+ ARRAY(Edits),
+ "Error (Block 12): Bad abbreviation operand encoding 10:"
+ " 2: [65533, 1, 10]\n",
+ "",
+ " 0:0|<65532, 80, 69, 88, 69, 1, 0,|Magic Number: 'PEXE' (80, 69,"
+ " 88, 69)\n"
+ " | 8, 0, 17, 0, 4, 0, 2, 0, 0, |PNaCl Version: 2\n"
+ " | 0> |\n"
+ " 16:0|1: <65535, 8, 2> |module { // BlockID = 8\n"
+ " 24:0| 1: <65535, 17, 3> | types { // BlockID = 17\n"
+ " 32:0| 3: <1, 2> | count 2;\n"
+ " 34:5| 3: <2> | @t0 = void;\n"
+ " 36:4| 3: <21, 0, 0> | @t1 = void ();\n"
+ " 39:7| 0: <65534> | }\n"
+ " 44:0| 3: <8, 1, 0, 0, 0> | define external void @f0();\n"
+ // Edit to change number of abbrev bits to 3.
+ " 48:6| 1: <65535, 12, 3> | function void @f0() { \n"
+ " | | // BlockID"
+ " = 12\n"
+ " 56:0| 3: <1, 1> | blocks 1;\n"
+ " | | %b0:\n"
+ " 58:5| 3: <10> | ret void;\n"
+ " 60:4| 0: <65534> | }\n"
+ " 64:0|0: <65534> |}\n");
}
// Show how we deal with additional abbreviations defined for a block,
@@ -392,66 +511,14 @@ TEST(NaClMungedWriteErrorTests, TestRemovingAbbrevWithMultAbbrevs) {
5, naclbitc::FUNC_CODE_INST_RET, Terminator
};
- Munger.setTryToRecoverOnWrite(true);
- EXPECT_TRUE(Munger.runTest(ARRAY(Edits)));
- EXPECT_EQ(
- "Error (Block 12): Error: Bad abbreviation operand encoding 9:"
- " 2: [65533, 1, 9]\n"
+ CheckDumpEdits(
+ ARRAY(Edits),
+ "Error (Block 12): Bad abbreviation operand encoding 9:"
+ " 2: [65533, 1, 9]\n",
"Error (Block 12): Ignoring abbreviation: 2: [65533, 1, 1, 10]\n"
- "Error (Block 12): Uses illegal abbreviation index: 5: [10]\n"
- " 1: [65535, 8, 2]\n"
- " 1: [65535, 17, 3]\n"
- " 3: [1, 2]\n"
- " 3: [2]\n"
- " 3: [21, 0, 0]\n"
- " 0: [65534]\n"
- " 3: [8, 1, 0, 0, 0]\n"
- " 1: [65535, 12, 3]\n"
- " 3: [1, 1]\n"
- " 3: [10]\n" // Abbreviation index 5 replaced with default.
- " 0: [65534]\n"
- " 0: [65534]\n",
- Munger.getTestResults());
-}
-
-// Show that error recovery works when writing an illegal abbreviation
-// index. Show success by parsing fixed bitcode.
-TEST(NaClMungeWriteErrorTests, RecoverWhenParsingBadAbbrevIndex) {
- NaClParseBitcodeMunger Munger(ARRAY_TERM(BitcodeRecords));
- Munger.setTryToRecoverOnWrite(true);
- EXPECT_TRUE(
- Munger.runTest(ARRAY(AbbrevIndex4VoidTypeEdit), true));
- EXPECT_EQ(
- "Error (Block 17): Uses illegal abbreviation index: 4: [2]\n"
- "Successful parse!\n",
- Munger.getTestResults());
-}
-
-// Show that error recovery works when writing an illegal abbreviation
-// index. Show success by Dumping fixed bitcode.
-TEST(NaClMungeWriteErrorTests, RecoverWhenParsingBadAbbreviationIndex) {
- NaClObjDumpMunger Munger(ARRAY_TERM(BitcodeRecords));
- Munger.setTryToRecoverOnWrite(true);
- EXPECT_TRUE(Munger.runTest(ARRAY(AbbrevIndex4VoidTypeEdit)));
- std::string Results(
- "Error (Block 17): Uses illegal abbreviation index: 4: [2]\n");
- Results.append(ExpectedDump);
- EXPECT_EQ(Results, Munger.getTestResults());
-}
-
-// Show that error recovery works when writing too many locally
-// defined abbreviations for the corresponding number of bits defined
-// in the corresponding enter block. Show success by dumping the fixed
-// bitcode.
-TEST(NaClMungeWriteErrorTests, RecoverTooManyLocalAbbreviations) {
- NaClObjDumpMunger Munger(ARRAY_TERM(BitcodeRecords));
- Munger.setTryToRecoverOnWrite(true);
- Munger.munge(ARRAY(UseLocalRetVoidAbbrevEdits));
- EXPECT_TRUE(Munger.runTest());
- EXPECT_EQ(
- "Error (Block 12): Uses illegal abbreviation index: 4: [10]\n"
- " 0:0|<65532, 80, 69, 88, 69, 1, 0,|Magic Number: 'PEXE'"
- " (80, 69, 88, 69)\n"
+ "Error (Block 12): Uses illegal abbreviation index: 5: [10]\n",
+ " 0:0|<65532, 80, 69, 88, 69, 1, 0,|Magic Number: 'PEXE' (80, 69,"
+ " 88, 69)\n"
" | 8, 0, 17, 0, 4, 0, 2, 0, 0, |PNaCl Version: 2\n"
" | 0> |\n"
" 16:0|1: <65535, 8, 2> |module { // BlockID = 8\n"
@@ -461,104 +528,139 @@ TEST(NaClMungeWriteErrorTests, RecoverTooManyLocalAbbreviations) {
" 36:4| 3: <21, 0, 0> | @t1 = void ();\n"
" 39:7| 0: <65534> | }\n"
" 44:0| 3: <8, 1, 0, 0, 0> | define external void @f0();\n"
- // Block only specifies 2 bits for abbreviations (i.e. limit = 3).
- " 48:6| 1: <65535, 12, 2> | function void @f0() { \n"
+ // Edit to change number of abbrev bits to 3.
+ " 48:6| 1: <65535, 12, 3> | function void @f0() { \n"
" | | // BlockID"
" = 12\n"
" 56:0| 3: <1, 1> | blocks 1;\n"
- // Added abbreviation. Defines abbreviation index 4.
- " 58:4| 2: <65533, 1, 1, 10> | %a0 = abbrev <10>;\n"
" | | %b0:\n"
- // Repaired abbreviation index of 4 (now 3).
- " 60:4| 3: <10> | ret void;\n"
- " 62:2| 0: <65534> | }\n"
- " 64:0|0: <65534> |}\n",
- Munger.getTestResults());
+ " 58:5| 3: <10> | ret void;\n"
+ " 60:4| 0: <65534> | }\n"
+ " 64:0|0: <65534> |}\n");
}
-// Show that error recovery works when writing and there are more
-// enter blocks than exit blocks. Show success by dumping fixed
-// bitcode.
-TEST(NaClMungeWriteErrorTests, RecoverTooManyEnterBlocks) {
- NaClObjDumpMunger Munger(ARRAY_TERM(BitcodeRecords));
- // Remove all but first two records (i.e. two enter blocks).
- NaClMungedBitcode &MungedBitcode = Munger.getMungedBitcode();
- for (size_t i = 2; i < MungedBitcode.getBaseRecords().size(); ++i) {
- MungedBitcode.remove(i);
- }
+// Show that inserting an abbreviation with a bad fixed width is dealt with.
+TEST(NaClMungeWriteErrorTests, InvalidFixedAbbreviationSize) {
+ // Insert bad abbreviation Fixed(36) into type block.
+ assert(36 > naclbitc::MaxAbbrevWidth);
+ const uint64_t Edit[] = {
+ VoidTypeIndex, NaClMungedBitcode::AddBefore,
+ naclbitc::DEFINE_ABBREV, naclbitc::BLK_CODE_DEFINE_ABBREV, 1,
+ 0, NaClBitCodeAbbrevOp::Fixed, 36, Terminator
+ };
+ CheckDumpEdits(
+ ARRAY(Edit),
+ "Error (Block 17): Invalid abbreviation Fixed(36) in: 2: [65533, 1, 0,"
+ " 1, 36]\n",
+ NoErrorRecoveryMessages,
+ ExpectedDumpedBitcode);
+}
- Munger.setTryToRecoverOnWrite(true);
- EXPECT_TRUE(Munger.runTest());
- EXPECT_EQ(
- "Error (Block 17): Missing close block.\n"
- "Error (Block 8): Missing close block.\n"
- " 0:0|<65532, 80, 69, 88, 69, 1, 0,|Magic Number: 'PEXE' (80, 69,"
- " 88, 69)\n"
- " | 8, 0, 17, 0, 4, 0, 2, 0, 0, |PNaCl Version: 2\n"
- " | 0> |\n"
- " 16:0|1: <65535, 8, 2> |module { // BlockID = 8\n"
- " 24:0| 1: <65535, 17, 3> | types { // BlockID = 17\n"
- " 32:0| 0: <65534> | }\n"
- " 36:0|0: <65534> |}\n",
- Munger.getTestResults());
+// Show that inserting an abbreviation with a bad vbr width is dealt with.
+TEST(NaClMungeWriteErrorTests, InvalidVbrAbbreviationSize) {
+ // Insert bad abbreviation Vbr(36) into type block.
+ assert(36 > naclbitc::MaxAbbrevWidth);
+ const uint64_t Edit[] = {
+ VoidTypeIndex, NaClMungedBitcode::AddBefore,
+ naclbitc::DEFINE_ABBREV, naclbitc::BLK_CODE_DEFINE_ABBREV, 1,
+ 0, NaClBitCodeAbbrevOp::VBR, 36, Terminator
+ };
+ CheckDumpEdits(
+ ARRAY(Edit),
+ "Error (Block 17): Invalid abbreviation VBR(36) in: 2: [65533, 1, 0,"
+ " 2, 36]\n",
+ NoErrorRecoveryMessages,
+ ExpectedDumpedBitcode);
}
-// Show that error recovery works when writing and there are fewer
-// enter blocks than exit blocks. Show success by dumping the fixed
-// bitcode.
-TEST(NaClMungeWriteErrorTests, RecoverTooManyExitBlocks) {
- NaClObjDumpMunger Munger(ARRAY_TERM(BitcodeRecords));
- // Add two exit blocks.
- NaClMungedBitcode &MungedBitcode = Munger.getMungedBitcode();
- NaClRecordVector Values;
- NaClBitcodeAbbrevRecord Record(0, naclbitc::BLK_CODE_EXIT, Values);
- for (size_t i = 0; i < 2; ++i)
- MungedBitcode.addAfter(MungedBitcode.getBaseRecords().size() - 1, Record);
+// Show that the array operator can't appear last.
+TEST(NaClMungeWriteErrorTests, InvalidArrayAbbreviationLast) {
+ const uint64_t Edit[] = {
+ VoidTypeIndex, NaClMungedBitcode::AddBefore,
+ naclbitc::DEFINE_ABBREV, naclbitc::BLK_CODE_DEFINE_ABBREV, 1,
+ 0, NaClBitCodeAbbrevOp::Array, Terminator
+ };
+ CheckDumpEdits(
+ ARRAY(Edit),
+ "Error (Block 17): Array abbreviation must be second to last: 2: [65533,"
+ " 1, 0, 3]\n",
+ NoErrorRecoveryMessages,
+ ExpectedDumpedBitcode);
+}
- Munger.setTryToRecoverOnWrite(true);
- EXPECT_TRUE(Munger.runTest());
- std::string Results(
- "Error (Block unknown): Extraneous exit block: 0: [65534]\n"
- "Error (Block unknown): Extraneous exit block: 0: [65534]\n");
- Results.append(ExpectedDump);
- EXPECT_EQ(
- Results,
- Munger.getTestResults());
+// Show that the array operator can't appear before the second to last
+// operand.
+TEST(NaClMungeWriteErrorTests, InvalidArrayAbbreviationTooEarly) {
+ const uint64_t Edit[] = {
+ VoidTypeIndex, NaClMungedBitcode::AddBefore,
+ naclbitc::DEFINE_ABBREV, naclbitc::BLK_CODE_DEFINE_ABBREV, 3,
+ 0, NaClBitCodeAbbrevOp::Array, // array
+ 1, 15, // lit(15)
+ 1, 10, // lit(10)
+ Terminator
+ };
+ CheckDumpEdits(
+ ARRAY(Edit),
+ "Error (Block 17): Array abbreviation must be second to last: 2: [65533,"
+ " 3, 0, 3, 1, 15, 1, 10]\n",
+ NoErrorRecoveryMessages,
+ ExpectedDumpedBitcode);
}
-// Show that error recovery works when writing a bitcode record that
-// isn't in any block. Show success by showing fixed bitcode records.
-TEST(NaClMungeWriteErrorTests, RecoverWriteRecordOutsideBlock) {
- NaClWriteMunger Munger(ARRAY_TERM(BitcodeRecords));
- NaClMungedBitcode &MungedBitcode = Munger.getMungedBitcode();
- NaClRecordVector Values;
- Values.push_back(4);
- NaClBitcodeAbbrevRecord Record(naclbitc::UNABBREV_RECORD,
- naclbitc::MODULE_CODE_VERSION,
- Values);
- MungedBitcode.addAfter(MungedBitcode.getBaseRecords().size() - 1, Record);
+// Show that the array operator can't appear as last two operators.
+TEST(NaClMungeWriteErrorTests, InvalidArrayAbbreviationLastTwo) {
+ const uint64_t Edit[] = {
+ VoidTypeIndex, NaClMungedBitcode::AddBefore,
+ naclbitc::DEFINE_ABBREV, naclbitc::BLK_CODE_DEFINE_ABBREV, 2,
+ 0, NaClBitCodeAbbrevOp::Array, // array
+ 0, NaClBitCodeAbbrevOp::Array, // array
+ Terminator
+ };
+ CheckDumpEdits(
+ ARRAY(Edit),
+ "Error (Block 17): Array abbreviation must be second to last: 2: [65533,"
+ " 2, 0, 3, 0, 3]\n",
+ NoErrorRecoveryMessages,
+ ExpectedDumpedBitcode);
+}
- Munger.setTryToRecoverOnWrite(true);
- EXPECT_TRUE(Munger.runTest());
- EXPECT_EQ(
- "Error (Block unknown): Record outside block: 3: [1, 4]\n"
- "Error (Block unknown): Missing close block.\n"
- " 1: [65535, 8, 2]\n"
- " 1: [65535, 17, 3]\n"
- " 3: [1, 2]\n"
- " 3: [2]\n"
- " 3: [21, 0, 0]\n"
- " 0: [65534]\n"
- " 3: [8, 1, 0, 0, 0]\n"
- " 1: [65535, 12, 2]\n"
- " 3: [1, 1]\n"
- " 3: [10]\n"
- " 0: [65534]\n"
- " 0: [65534]\n"
- " 1: [65535, 4294967295, 3]\n"
- " 3: [1, 4]\n"
- " 0: [65534]\n",
- Munger.getTestResults());
+// Show what happens when an abbreviation is specified to only contain
+// one operator, but is then followed with more than one operator.
+TEST(NaClMungeWriteErrorTests, SpecifiesTooFewOperands) {
+ const uint64_t Edit[] = {
+ VoidTypeIndex, NaClMungedBitcode::AddBefore,
+ // Note: 1 at end of next line specified that the abbreviation
+ // should only have one operator.
+ naclbitc::DEFINE_ABBREV, naclbitc::BLK_CODE_DEFINE_ABBREV, 1,
+ 1, 10, // lit(10)
+ 1, 15, // lit(15)
+ Terminator
+ };
+ CheckDumpEdits(
+ ARRAY(Edit),
+ "Error (Block 17): Error: Too many values for number of operands (1):"
+ " 2: [65533, 1, 1, 10, 1, 15]\n",
+ NoErrorRecoveryMessages,
+ ExpectedDumpedBitcode);
+}
+
+// Show that the code checks if specifies too many operands for an
+// abbreviation, based on the record size.
+TEST(NaClMungeWriteErrorTests, SpecifiesTooManyOperands) {
+ // Insert bad abbreviation Vbr(36) into type block.
+ const uint64_t Edit[] = {
+ VoidTypeIndex, NaClMungedBitcode::AddBefore,
+ naclbitc::DEFINE_ABBREV, naclbitc::BLK_CODE_DEFINE_ABBREV, 3,
+ 1, 10, // lit(10)
+ 1, 15, // lit(15)
+ Terminator
+ };
+ CheckDumpEdits(
+ ARRAY(Edit),
+ "Error (Block 17): Malformed abbreviation found: 2: [65533, 3, 1, 10,"
+ " 1, 15]\n",
+ NoErrorRecoveryMessages,
+ ExpectedDumpedBitcode);
}
} // end of namespace naclmungetest
« no previous file with comments | « lib/Bitcode/NaCl/TestUtils/NaClBitcodeMungeWriter.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698