| Index: src/trusted/validator_arm/validator_small_tests.cc
|
| diff --git a/src/trusted/validator_arm/validator_small_tests.cc b/src/trusted/validator_arm/validator_small_tests.cc
|
| index e58888ff2397f3a818f7afb2895d8d980d6b5f37..c9fa8df361251d7ebe69d7b0c7ca0f18926611c2 100644
|
| --- a/src/trusted/validator_arm/validator_small_tests.cc
|
| +++ b/src/trusted/validator_arm/validator_small_tests.cc
|
| @@ -520,23 +520,6 @@ TEST_F(ValidatorTests, ScaryUndefinedInstructions) {
|
| }
|
| }
|
|
|
| -TEST_F(ValidatorTests, LessScaryUndefinedInstructions) {
|
| - // These instructions are specified by ARM as *permanently* undefined, so we
|
| - // treat them as a reliable Illegal Instruction trap.
|
| -
|
| - static const AnnotatedInstruction perm_undefined[] = {
|
| - { 0xE7FFDEFE, "permanently undefined instruction produced by LLVM" },
|
| - };
|
| -
|
| - for (unsigned i = 0; i < NACL_ARRAY_SIZE(perm_undefined); i++) {
|
| - arm_inst program[] = { perm_undefined[i].inst };
|
| - validation_should_pass(program,
|
| - 1,
|
| - kDefaultBaseAddr,
|
| - perm_undefined[i].about);
|
| - }
|
| -}
|
| -
|
| TEST_F(ValidatorTests, PcRelativeFirstInst) {
|
| // Note: This tests the fix for issue 2771.
|
| static const arm_inst pcrel_boundary_tests[] = {
|
| @@ -1026,7 +1009,7 @@ TEST_F(ValidatorTests, CheckPushPcUnpredictable) {
|
| TEST_F(ValidatorTests, ConditionalBreakpoints) {
|
| ProblemSpy spy;
|
| arm_inst bkpt = 0xE1200070; // BKPT #0
|
| - arm_inst pool_head = nacl_arm_dec::kLiteralPoolHeadInstruction;
|
| + arm_inst pool_head = nacl_arm_dec::kLiteralPoolHead;
|
| for (Instruction::Condition cond = Instruction::EQ;
|
| cond < Instruction::AL;
|
| cond = Instruction::Next(cond)) {
|
| @@ -1040,12 +1023,55 @@ TEST_F(ValidatorTests, ConditionalBreakpoints) {
|
| }
|
|
|
| TEST_F(ValidatorTests, LiteralPoolHeadIsBreakpoint) {
|
| - EXPECT_EQ(nacl_arm_dec::kLiteralPoolHeadInstruction & 0xFFF000F0,
|
| + EXPECT_EQ(nacl_arm_dec::kLiteralPoolHead & 0xFFF000F0,
|
| 0xE1200070) // BKPT #0
|
| << ("the literal pool head should be a breakpoint: "
|
| "it needs to act as a roadblock");
|
| }
|
|
|
| +TEST_F(ValidatorTests, Breakpoint) {
|
| + EXPECT_EQ(nacl_arm_dec::kBreakpoint & 0xFFF000F0,
|
| + 0xE1200070) // BKPT #0
|
| + << ("the breakpoint instruction should be a breakpoint: "
|
| + "it needs to trap");
|
| +}
|
| +
|
| +TEST_F(ValidatorTests, HaltFill) {
|
| + EXPECT_EQ(nacl_arm_dec::kHaltFill & 0xFFF000F0,
|
| + 0xE7F000F0) // UDF #0
|
| + << ("the halt fill instruction should be UDF: "
|
| + "it needs to trap");
|
| +}
|
| +
|
| +TEST_F(ValidatorTests, AbortNow) {
|
| + EXPECT_EQ(nacl_arm_dec::kAbortNow & 0xFFF000F0,
|
| + 0xE7F000F0) // UDF #0
|
| + << ("the abort now instruction should be UDF: "
|
| + "it needs to trap");
|
| +}
|
| +
|
| +TEST_F(ValidatorTests, FailValidation) {
|
| + EXPECT_EQ(nacl_arm_dec::kFailValidation & 0xFFF000F0,
|
| + 0xE7F000F0) // UDF #0
|
| + << ("the fail validation instruction should be UDF: "
|
| + "it needs to trap");
|
| +}
|
| +
|
| +TEST_F(ValidatorTests, UDFAndBKPTValidateAsExpected) {
|
| + ProblemSpy spy;
|
| + for (uint32_t i = 0; i < 0xFFFF; ++i) {
|
| + arm_inst bkpt_inst = 0xE1200070 | ((i & 0xFFF0) << 4) | (i & 0xF);
|
| + arm_inst udf_inst = 0xE7F000F0 | ((i & 0xFFF0) << 4) | (i & 0xF);
|
| + EXPECT_EQ(validate(&bkpt_inst, 1, kDefaultBaseAddr, &spy),
|
| + ((bkpt_inst == nacl_arm_dec::kLiteralPoolHead) ||
|
| + (bkpt_inst == nacl_arm_dec::kBreakpoint)));
|
| + EXPECT_EQ(validate(&udf_inst, 1, kDefaultBaseAddr, &spy),
|
| + ((udf_inst == nacl_arm_dec::kHaltFill) ||
|
| + (udf_inst == nacl_arm_dec::kAbortNow)));
|
| + // Tautological note: kFailValidation should fail validation.
|
| + }
|
| +}
|
| +
|
| TEST_F(ValidatorTests, LiteralPoolHeadInstruction) {
|
| // Make sure that literal pools are handled properly: they should be preceded
|
| // by a special breakpoint instruction at the start of the bundle, and can
|
| @@ -1059,7 +1085,7 @@ TEST_F(ValidatorTests, LiteralPoolHeadInstruction) {
|
| literal_pool[0] = (literal_pool[0] & 0xFFF000F0) |
|
| (imm16 & 0xF) |
|
| ((imm16 & 0xFFF0) << 8);
|
| - if (literal_pool[0] == nacl_arm_dec::kLiteralPoolHeadInstruction) {
|
| + if (literal_pool[0] == nacl_arm_dec::kLiteralPoolHead) {
|
| validation_should_pass(literal_pool.data(),
|
| literal_pool.size(),
|
| kDefaultBaseAddr,
|
| @@ -1083,7 +1109,7 @@ TEST_F(ValidatorTests, LiteralPoolHeadPosition) {
|
| std::fill(literal_pool.begin(), literal_pool.end(), 0xEF000000); // SVC #0
|
| if (pos != literal_pool.size()) {
|
| // We do one iteration without a literal pool head at all.
|
| - literal_pool[pos] = nacl_arm_dec::kLiteralPoolHeadInstruction;
|
| + literal_pool[pos] = nacl_arm_dec::kLiteralPoolHead;
|
| }
|
| if (pos == 0) {
|
| validation_should_pass(literal_pool.data(),
|
| @@ -1108,7 +1134,7 @@ TEST_F(ValidatorTests, LiteralPoolBig) {
|
| for (size_t pos = 0; pos <= literal_pools.size(); ++pos) {
|
| std::fill(literal_pools.begin(), literal_pools.end(),
|
| 0xEF000000); // SVC #0
|
| - literal_pools[pos] = nacl_arm_dec::kLiteralPoolHeadInstruction;
|
| + literal_pools[pos] = nacl_arm_dec::kLiteralPoolHead;
|
| validation_should_fail(literal_pools.data(),
|
| literal_pools.size(),
|
| kDefaultBaseAddr,
|
| @@ -1133,7 +1159,7 @@ TEST_F(ValidatorTests, LiteralPoolBranch) {
|
| continue;
|
| }
|
| std::fill(code.begin(), code.end(), 0xE320F000); // NOP
|
| - code[bundle_pos] = nacl_arm_dec::kLiteralPoolHeadInstruction;
|
| + code[bundle_pos] = nacl_arm_dec::kLiteralPoolHead;
|
| for (size_t b_target = 0; b_target < code.size(); ++b_target) {
|
| // PC reads as current instruction address plus 8 (e.g. two instructions
|
| // ahead of b_pos).
|
|
|