| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2012 The Native Client Authors. All rights reserved. | 2 * Copyright (c) 2012 The Native Client Authors. All rights reserved. |
| 3 * Use of this source code is governed by a BSD-style license that can be | 3 * Use of this source code is governed by a BSD-style license that can be |
| 4 * found in the LICENSE file. | 4 * found in the LICENSE file. |
| 5 */ | 5 */ |
| 6 | 6 |
| 7 #ifndef NACL_TRUSTED_BUT_NOT_TCB | 7 #ifndef NACL_TRUSTED_BUT_NOT_TCB |
| 8 #error This file is not meant for use in the TCB | 8 #error This file is not meant for use in the TCB |
| 9 #endif | 9 #endif |
| 10 | 10 |
| (...skipping 502 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 513 << undefined_insts[i].about; | 513 << undefined_insts[i].about; |
| 514 EXPECT_EQ(nacl_arm_dec::UNDEFINED, spy.GetSafetyLevel(first)) | 514 EXPECT_EQ(nacl_arm_dec::UNDEFINED, spy.GetSafetyLevel(first)) |
| 515 << "Instruction must be flagged as UNDEFINED: " | 515 << "Instruction must be flagged as UNDEFINED: " |
| 516 << undefined_insts[i].about; | 516 << undefined_insts[i].about; |
| 517 EXPECT_EQ(nacl_arm_val::kProblemUnsafe, first.problem()) | 517 EXPECT_EQ(nacl_arm_val::kProblemUnsafe, first.problem()) |
| 518 << "Instruction must be marked unsafe: " | 518 << "Instruction must be marked unsafe: " |
| 519 << undefined_insts[i].about; | 519 << undefined_insts[i].about; |
| 520 } | 520 } |
| 521 } | 521 } |
| 522 | 522 |
| 523 TEST_F(ValidatorTests, LessScaryUndefinedInstructions) { | |
| 524 // These instructions are specified by ARM as *permanently* undefined, so we | |
| 525 // treat them as a reliable Illegal Instruction trap. | |
| 526 | |
| 527 static const AnnotatedInstruction perm_undefined[] = { | |
| 528 { 0xE7FFDEFE, "permanently undefined instruction produced by LLVM" }, | |
| 529 }; | |
| 530 | |
| 531 for (unsigned i = 0; i < NACL_ARRAY_SIZE(perm_undefined); i++) { | |
| 532 arm_inst program[] = { perm_undefined[i].inst }; | |
| 533 validation_should_pass(program, | |
| 534 1, | |
| 535 kDefaultBaseAddr, | |
| 536 perm_undefined[i].about); | |
| 537 } | |
| 538 } | |
| 539 | |
| 540 TEST_F(ValidatorTests, PcRelativeFirstInst) { | 523 TEST_F(ValidatorTests, PcRelativeFirstInst) { |
| 541 // Note: This tests the fix for issue 2771. | 524 // Note: This tests the fix for issue 2771. |
| 542 static const arm_inst pcrel_boundary_tests[] = { | 525 static const arm_inst pcrel_boundary_tests[] = { |
| 543 0xe59f0000, // ldr r0, [pc, #0] | 526 0xe59f0000, // ldr r0, [pc, #0] |
| 544 0xe320f000, // nop {0} | 527 0xe320f000, // nop {0} |
| 545 0xe320f000, // nop {0} | 528 0xe320f000, // nop {0} |
| 546 0xe320f000, // nop {0}" | 529 0xe320f000, // nop {0}" |
| 547 }; | 530 }; |
| 548 validation_should_pass(pcrel_boundary_tests, | 531 validation_should_pass(pcrel_boundary_tests, |
| 549 NACL_ARRAY_SIZE(pcrel_boundary_tests), | 532 NACL_ARRAY_SIZE(pcrel_boundary_tests), |
| (...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1039 } | 1022 } |
| 1040 } | 1023 } |
| 1041 | 1024 |
| 1042 TEST_F(ValidatorTests, LiteralPoolHeadIsBreakpoint) { | 1025 TEST_F(ValidatorTests, LiteralPoolHeadIsBreakpoint) { |
| 1043 EXPECT_EQ(nacl_arm_dec::kLiteralPoolHeadInstruction & 0xFFF000F0, | 1026 EXPECT_EQ(nacl_arm_dec::kLiteralPoolHeadInstruction & 0xFFF000F0, |
| 1044 0xE1200070) // BKPT #0 | 1027 0xE1200070) // BKPT #0 |
| 1045 << ("the literal pool head should be a breakpoint: " | 1028 << ("the literal pool head should be a breakpoint: " |
| 1046 "it needs to act as a roadblock"); | 1029 "it needs to act as a roadblock"); |
| 1047 } | 1030 } |
| 1048 | 1031 |
| 1032 TEST_F(ValidatorTests, Breakpoint) { |
| 1033 EXPECT_EQ(nacl_arm_dec::kBreakpoint & 0xFFF000F0, |
| 1034 0xE1200070) // BKPT #0 |
| 1035 << ("the breakpoint instruction should be a breakpoint: " |
| 1036 "it needs to trap"); |
| 1037 } |
| 1038 |
| 1039 TEST_F(ValidatorTests, HaltFill) { |
| 1040 EXPECT_EQ(nacl_arm_dec::kHaltFill & 0xFFF000F0, |
| 1041 0xE7F000F0) // UDF #0 |
| 1042 << ("the halt fill instruction should be UDF: " |
| 1043 "it needs to trap"); |
| 1044 } |
| 1045 |
| 1046 TEST_F(ValidatorTests, AbortNow) { |
| 1047 EXPECT_EQ(nacl_arm_dec::kAbortNow & 0xFFF000F0, |
| 1048 0xE7F000F0) // UDF #0 |
| 1049 << ("the abort now instruction should be UDF: " |
| 1050 "it needs to trap"); |
| 1051 } |
| 1052 |
| 1053 TEST_F(ValidatorTests, FailValidation) { |
| 1054 EXPECT_EQ(nacl_arm_dec::kFailValidation & 0xFFF000F0, |
| 1055 0xE7F000F0) // UDF #0 |
| 1056 << ("the fail validation instruction should be UDF: " |
| 1057 "it needs to trap"); |
| 1058 } |
| 1059 |
| 1060 TEST_F(ValidatorTests, UDFAndBKPTValidateAsExpected) { |
| 1061 ProblemSpy spy; |
| 1062 for (uint32_t i = 0; i < 0xFFFF; ++i) { |
| 1063 arm_inst bkpt_inst = 0xE1200070 | ((i & 0xFFF0) << 4) | (i & 0xF); |
| 1064 arm_inst udf_inst = 0xE7F000F0 | ((i & 0xFFF0) << 4) | (i & 0xF); |
| 1065 EXPECT_EQ(validate(&bkpt_inst, 1, kDefaultBaseAddr, &spy), |
| 1066 ((bkpt_inst == nacl_arm_dec::kLiteralPoolHeadInstruction) || |
| 1067 (bkpt_inst == nacl_arm_dec::kBreakpoint))); |
| 1068 EXPECT_EQ(validate(&udf_inst, 1, kDefaultBaseAddr, &spy), |
| 1069 ((udf_inst == nacl_arm_dec::kHaltFill) || |
| 1070 (udf_inst == nacl_arm_dec::kAbortNow))); |
| 1071 // Tautological note: kFailValidation should fail validation. |
| 1072 } |
| 1073 } |
| 1074 |
| 1049 TEST_F(ValidatorTests, LiteralPoolHeadInstruction) { | 1075 TEST_F(ValidatorTests, LiteralPoolHeadInstruction) { |
| 1050 // Make sure that literal pools are handled properly: they should be preceded | 1076 // Make sure that literal pools are handled properly: they should be preceded |
| 1051 // by a special breakpoint instruction at the start of the bundle, and can | 1077 // by a special breakpoint instruction at the start of the bundle, and can |
| 1052 // then contain any bits that would otherwise look malicious. | 1078 // then contain any bits that would otherwise look malicious. |
| 1053 // Each literal pool bundle has to start with such a literal pool head. | 1079 // Each literal pool bundle has to start with such a literal pool head. |
| 1054 vector<arm_inst> literal_pool(_validator.InstructionsPerBundle(), | 1080 vector<arm_inst> literal_pool(_validator.InstructionsPerBundle(), |
| 1055 0xEF000000); // SVC #0 | 1081 0xEF000000); // SVC #0 |
| 1056 literal_pool[0] = 0xE1200070; // BKPT #0 | 1082 literal_pool[0] = 0xE1200070; // BKPT #0 |
| 1057 // Try out all BKPT encodings, and make sure only one of them works. | 1083 // Try out all BKPT encodings, and make sure only one of them works. |
| 1058 for (uint32_t imm16 = 0; imm16 <= 0xFFFF; ++imm16) { | 1084 for (uint32_t imm16 = 0; imm16 <= 0xFFFF; ++imm16) { |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1158 } | 1184 } |
| 1159 } | 1185 } |
| 1160 | 1186 |
| 1161 }; // anonymous namespace | 1187 }; // anonymous namespace |
| 1162 | 1188 |
| 1163 // Test driver function. | 1189 // Test driver function. |
| 1164 int main(int argc, char *argv[]) { | 1190 int main(int argc, char *argv[]) { |
| 1165 testing::InitGoogleTest(&argc, argv); | 1191 testing::InitGoogleTest(&argc, argv); |
| 1166 return RUN_ALL_TESTS(); | 1192 return RUN_ALL_TESTS(); |
| 1167 } | 1193 } |
| OLD | NEW |