Various fixes to the verifier for cts-tests.
Change-Id: I812e7f1332ff1ce5a13d19433255098989531d1a
diff --git a/src/dex_verifier.cc b/src/dex_verifier.cc
index ec89241..16506ca 100644
--- a/src/dex_verifier.cc
+++ b/src/dex_verifier.cc
@@ -637,6 +637,14 @@
<< " but expected " << check_type;
return false;
}
+ if (check_type.IsLowHalf()) {
+ const RegType& src_type_h = GetRegisterType(vsrc + 1);
+ if (!src_type.CheckWidePair(src_type_h)) {
+ verifier_->Fail(VERIFY_ERROR_GENERIC) << "wide register v" << vsrc << " has type "
+ << src_type << "/" << src_type_h;
+ return false;
+ }
+ }
// The register at vsrc has a defined type, we know the lower-upper-bound, but this is less
// precise than the subtype in vsrc so leave it for reference types. For primitive types
// if they are a defined type then they are as precise as we can get, however, for constant
@@ -1485,9 +1493,9 @@
}
uint16_t registers_size = code_item_->registers_size_;
for (uint32_t idx = 0; idx < vA; idx++) {
- if (arg[idx] > registers_size) {
+ if (arg[idx] >= registers_size) {
Fail(VERIFY_ERROR_GENERIC) << "invalid reg index (" << arg[idx]
- << ") in non-range invoke (> " << registers_size << ")";
+ << ") in non-range invoke (>= " << registers_size << ")";
return false;
}
}
@@ -2157,19 +2165,31 @@
}
case Instruction::CMPL_FLOAT:
case Instruction::CMPG_FLOAT:
- work_line_->VerifyRegisterType(dec_insn.vB_, reg_types_.Float());
- work_line_->VerifyRegisterType(dec_insn.vC_, reg_types_.Float());
+ if (!work_line_->VerifyRegisterType(dec_insn.vB_, reg_types_.Float())) {
+ break;
+ }
+ if (!work_line_->VerifyRegisterType(dec_insn.vC_, reg_types_.Float())) {
+ break;
+ }
work_line_->SetRegisterType(dec_insn.vA_, reg_types_.Integer());
break;
case Instruction::CMPL_DOUBLE:
case Instruction::CMPG_DOUBLE:
- work_line_->VerifyRegisterType(dec_insn.vB_, reg_types_.Double());
- work_line_->VerifyRegisterType(dec_insn.vC_, reg_types_.Double());
+ if (!work_line_->VerifyRegisterType(dec_insn.vB_, reg_types_.Double())) {
+ break;
+ }
+ if (!work_line_->VerifyRegisterType(dec_insn.vC_, reg_types_.Double())) {
+ break;
+ }
work_line_->SetRegisterType(dec_insn.vA_, reg_types_.Integer());
break;
case Instruction::CMP_LONG:
- work_line_->VerifyRegisterType(dec_insn.vB_, reg_types_.Long());
- work_line_->VerifyRegisterType(dec_insn.vC_, reg_types_.Long());
+ if (!work_line_->VerifyRegisterType(dec_insn.vB_, reg_types_.Long())) {
+ break;
+ }
+ if (!work_line_->VerifyRegisterType(dec_insn.vC_, reg_types_.Long())) {
+ break;
+ }
work_line_->SetRegisterType(dec_insn.vA_, reg_types_.Integer());
break;
case Instruction::THROW: {
@@ -2196,24 +2216,29 @@
const RegType& array_type = work_line_->GetRegisterType(dec_insn.vA_);
/* array_type can be null if the reg type is Zero */
if (!array_type.IsZero()) {
- const RegType& component_type = reg_types_.GetComponentType(array_type,
- method_->GetDeclaringClass()->GetClassLoader());
- DCHECK(!component_type.IsUnknown());
- if (!array_type.IsArrayTypes() || component_type.IsNonZeroReferenceTypes()) {
- Fail(VERIFY_ERROR_GENERIC) << "invalid fill-array-data on " << array_type;
+ if (!array_type.IsArrayTypes()) {
+ Fail(VERIFY_ERROR_GENERIC) << "invalid fill-array-data with array type " << array_type;
} else {
- // Now verify if the element width in the table matches the element width declared in
- // the array
- const uint16_t* array_data = insns + (insns[1] | (((int32_t) insns[2]) << 16));
- if (array_data[0] != Instruction::kArrayDataSignature) {
- Fail(VERIFY_ERROR_GENERIC) << "invalid magic for array-data";
+ const RegType& component_type = reg_types_.GetComponentType(array_type,
+ method_->GetDeclaringClass()->GetClassLoader());
+ DCHECK(!component_type.IsUnknown());
+ if (component_type.IsNonZeroReferenceTypes()) {
+ Fail(VERIFY_ERROR_GENERIC) << "invalid fill-array-data with component type "
+ << component_type;
} else {
- size_t elem_width = Primitive::ComponentSize(component_type.GetPrimitiveType());
- // Since we don't compress the data in Dex, expect to see equal width of data stored
- // in the table and expected from the array class.
- if (array_data[1] != elem_width) {
- Fail(VERIFY_ERROR_GENERIC) << "array-data size mismatch (" << array_data[1]
- << " vs " << elem_width << ")";
+ // Now verify if the element width in the table matches the element width declared in
+ // the array
+ const uint16_t* array_data = insns + (insns[1] | (((int32_t) insns[2]) << 16));
+ if (array_data[0] != Instruction::kArrayDataSignature) {
+ Fail(VERIFY_ERROR_GENERIC) << "invalid magic for array-data";
+ } else {
+ size_t elem_width = Primitive::ComponentSize(component_type.GetPrimitiveType());
+ // Since we don't compress the data in Dex, expect to see equal width of data stored
+ // in the table and expected from the array class.
+ if (array_data[1] != elem_width) {
+ Fail(VERIFY_ERROR_GENERIC) << "array-data size mismatch (" << array_data[1]
+ << " vs " << elem_width << ")";
+ }
}
}
}
@@ -3587,8 +3612,6 @@
get_reg = dec_insn.arg_[ui];
if (!work_line_->VerifyRegisterType(get_reg, expected_type)) {
- Fail(VERIFY_ERROR_GENERIC) << "filled-new-array arg " << ui << "(" << get_reg
- << ") not valid";
return;
}
}