diff options
-rw-r--r-- | runtime/verifier/method_verifier.cc | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc index e5dcbb0ac4..9d1f6f4de1 100644 --- a/runtime/verifier/method_verifier.cc +++ b/runtime/verifier/method_verifier.cc @@ -1334,6 +1334,31 @@ bool MethodVerifier::CodeFlowVerifyMethod() { insn_flags_[insn_idx].ClearChanged(); } + // When we're in compiler mode, do not accept quickened instructions. + // We explicitly iterate over *all* instructions to check code that may be unreachable and + // missed by the loop above. + if (Runtime::Current() != nullptr && Runtime::Current()->IsCompiler()) { + uint32_t insn_idx = 0; + for (; insn_idx < insns_size; insn_idx += insn_flags_[insn_idx].GetLengthInCodeUnits()) { + const Instruction* inst = Instruction::At(insns + insn_idx); + switch (inst->Opcode()) { + case Instruction::IGET_QUICK: + case Instruction::IGET_WIDE_QUICK: + case Instruction::IGET_OBJECT_QUICK: + case Instruction::IPUT_QUICK: + case Instruction::IPUT_WIDE_QUICK: + case Instruction::IPUT_OBJECT_QUICK: + case Instruction::INVOKE_VIRTUAL_QUICK: + case Instruction::INVOKE_VIRTUAL_RANGE_QUICK: + Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Quickened instructions not allowed. "; + return false; + + default: + break; + } + } + } + if (gDebugVerify) { /* * Scan for dead code. There's nothing "evil" about dead code |