summaryrefslogtreecommitdiffstats
path: root/runtime/verifier
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/verifier')
-rw-r--r--runtime/verifier/method_verifier.cc96
-rw-r--r--runtime/verifier/method_verifier.h19
-rw-r--r--runtime/verifier/method_verifier_test.cc3
3 files changed, 63 insertions, 55 deletions
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index fa00c61017..9811926b16 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -74,50 +74,51 @@ void PcToRegisterLineTable::Init(RegisterTrackingMode mode, InstructionFlags* fl
}
MethodVerifier::FailureKind MethodVerifier::VerifyClass(const mirror::Class* klass,
- std::string& error,
- bool allow_soft_failures) {
+ bool allow_soft_failures,
+ std::string* error) {
if (klass->IsVerified()) {
return kNoFailure;
}
mirror::Class* super = klass->GetSuperClass();
if (super == NULL && StringPiece(ClassHelper(klass).GetDescriptor()) != "Ljava/lang/Object;") {
- error = "Verifier rejected class ";
- error += PrettyDescriptor(klass);
- error += " that has no super class";
+ *error = "Verifier rejected class ";
+ *error += PrettyDescriptor(klass);
+ *error += " that has no super class";
return kHardFailure;
}
if (super != NULL && super->IsFinal()) {
- error = "Verifier rejected class ";
- error += PrettyDescriptor(klass);
- error += " that attempts to sub-class final class ";
- error += PrettyDescriptor(super);
+ *error = "Verifier rejected class ";
+ *error += PrettyDescriptor(klass);
+ *error += " that attempts to sub-class final class ";
+ *error += PrettyDescriptor(super);
return kHardFailure;
}
ClassHelper kh(klass);
const DexFile& dex_file = kh.GetDexFile();
- uint32_t class_def_idx;
- if (!dex_file.FindClassDefIndex(kh.GetDescriptor(), class_def_idx)) {
- error = "Verifier rejected class ";
- error += PrettyDescriptor(klass);
- error += " that isn't present in dex file ";
- error += dex_file.GetLocation();
+ const DexFile::ClassDef* class_def = kh.GetClassDef();
+ if (class_def == NULL) {
+ *error = "Verifier rejected class ";
+ *error += PrettyDescriptor(klass);
+ *error += " that isn't present in dex file ";
+ *error += dex_file.GetLocation();
return kHardFailure;
}
return VerifyClass(&dex_file,
kh.GetDexCache(),
klass->GetClassLoader(),
- class_def_idx, error,
- allow_soft_failures);
+ class_def,
+ allow_soft_failures,
+ error);
}
MethodVerifier::FailureKind MethodVerifier::VerifyClass(const DexFile* dex_file,
mirror::DexCache* dex_cache,
mirror::ClassLoader* class_loader,
- uint32_t class_def_idx,
- std::string& error,
- bool allow_soft_failures) {
- const DexFile::ClassDef& class_def = dex_file->GetClassDef(class_def_idx);
- const byte* class_data = dex_file->GetClassData(class_def);
+ const DexFile::ClassDef* class_def,
+ bool allow_soft_failures,
+ std::string* error) {
+ DCHECK(class_def != nullptr);
+ const byte* class_data = dex_file->GetClassData(*class_def);
if (class_data == NULL) {
// empty class, probably a marker interface
return kNoFailure;
@@ -139,7 +140,7 @@ MethodVerifier::FailureKind MethodVerifier::VerifyClass(const DexFile* dex_file,
continue;
}
previous_direct_method_idx = method_idx;
- InvokeType type = it.GetMethodInvokeType(class_def);
+ InvokeType type = it.GetMethodInvokeType(*class_def);
mirror::ArtMethod* method =
linker->ResolveMethod(*dex_file, method_idx, dex_cache, class_loader, NULL, type);
if (method == NULL) {
@@ -151,7 +152,7 @@ MethodVerifier::FailureKind MethodVerifier::VerifyClass(const DexFile* dex_file,
dex_file,
dex_cache,
class_loader,
- class_def_idx,
+ class_def,
it.GetMethodCodeItem(),
method,
it.GetMemberAccessFlags(),
@@ -160,12 +161,12 @@ MethodVerifier::FailureKind MethodVerifier::VerifyClass(const DexFile* dex_file,
if (result == kHardFailure) {
hard_fail = true;
if (error_count > 0) {
- error += "\n";
+ *error += "\n";
}
- error = "Verifier rejected class ";
- error += PrettyDescriptor(dex_file->GetClassDescriptor(class_def));
- error += " due to bad method ";
- error += PrettyMethod(method_idx, *dex_file);
+ *error = "Verifier rejected class ";
+ *error += PrettyDescriptor(dex_file->GetClassDescriptor(*class_def));
+ *error += " due to bad method ";
+ *error += PrettyMethod(method_idx, *dex_file);
}
++error_count;
}
@@ -181,7 +182,7 @@ MethodVerifier::FailureKind MethodVerifier::VerifyClass(const DexFile* dex_file,
continue;
}
previous_virtual_method_idx = method_idx;
- InvokeType type = it.GetMethodInvokeType(class_def);
+ InvokeType type = it.GetMethodInvokeType(*class_def);
mirror::ArtMethod* method =
linker->ResolveMethod(*dex_file, method_idx, dex_cache, class_loader, NULL, type);
if (method == NULL) {
@@ -193,7 +194,7 @@ MethodVerifier::FailureKind MethodVerifier::VerifyClass(const DexFile* dex_file,
dex_file,
dex_cache,
class_loader,
- class_def_idx,
+ class_def,
it.GetMethodCodeItem(),
method,
it.GetMemberAccessFlags(),
@@ -202,12 +203,12 @@ MethodVerifier::FailureKind MethodVerifier::VerifyClass(const DexFile* dex_file,
if (result == kHardFailure) {
hard_fail = true;
if (error_count > 0) {
- error += "\n";
+ *error += "\n";
}
- error = "Verifier rejected class ";
- error += PrettyDescriptor(dex_file->GetClassDescriptor(class_def));
- error += " due to bad method ";
- error += PrettyMethod(method_idx, *dex_file);
+ *error = "Verifier rejected class ";
+ *error += PrettyDescriptor(dex_file->GetClassDescriptor(*class_def));
+ *error += " due to bad method ";
+ *error += PrettyMethod(method_idx, *dex_file);
}
++error_count;
}
@@ -224,7 +225,7 @@ MethodVerifier::FailureKind MethodVerifier::VerifyMethod(uint32_t method_idx,
const DexFile* dex_file,
mirror::DexCache* dex_cache,
mirror::ClassLoader* class_loader,
- uint32_t class_def_idx,
+ const DexFile::ClassDef* class_def,
const DexFile::CodeItem* code_item,
mirror::ArtMethod* method,
uint32_t method_access_flags,
@@ -232,7 +233,7 @@ MethodVerifier::FailureKind MethodVerifier::VerifyMethod(uint32_t method_idx,
MethodVerifier::FailureKind result = kNoFailure;
uint64_t start_ns = NanoTime();
- MethodVerifier verifier_(dex_file, dex_cache, class_loader, class_def_idx, code_item, method_idx,
+ MethodVerifier verifier_(dex_file, dex_cache, class_loader, class_def, code_item, method_idx,
method, method_access_flags, true, allow_soft_failures);
if (verifier_.Verify()) {
// Verification completed, however failures may be pending that didn't cause the verification
@@ -267,11 +268,12 @@ MethodVerifier::FailureKind MethodVerifier::VerifyMethod(uint32_t method_idx,
void MethodVerifier::VerifyMethodAndDump(std::ostream& os, uint32_t dex_method_idx,
const DexFile* dex_file, mirror::DexCache* dex_cache,
- mirror::ClassLoader* class_loader, uint32_t class_def_idx,
+ mirror::ClassLoader* class_loader,
+ const DexFile::ClassDef* class_def,
const DexFile::CodeItem* code_item,
mirror::ArtMethod* method,
uint32_t method_access_flags) {
- MethodVerifier verifier(dex_file, dex_cache, class_loader, class_def_idx, code_item,
+ MethodVerifier verifier(dex_file, dex_cache, class_loader, class_def, code_item,
dex_method_idx, method, method_access_flags, true, true);
verifier.Verify();
verifier.DumpFailures(os);
@@ -280,7 +282,8 @@ void MethodVerifier::VerifyMethodAndDump(std::ostream& os, uint32_t dex_method_i
}
MethodVerifier::MethodVerifier(const DexFile* dex_file, mirror::DexCache* dex_cache,
- mirror::ClassLoader* class_loader, uint32_t class_def_idx,
+ mirror::ClassLoader* class_loader,
+ const DexFile::ClassDef* class_def,
const DexFile::CodeItem* code_item,
uint32_t dex_method_idx, mirror::ArtMethod* method,
uint32_t method_access_flags, bool can_load_classes,
@@ -293,7 +296,7 @@ MethodVerifier::MethodVerifier(const DexFile* dex_file, mirror::DexCache* dex_ca
dex_file_(dex_file),
dex_cache_(dex_cache),
class_loader_(class_loader),
- class_def_idx_(class_def_idx),
+ class_def_(class_def),
code_item_(code_item),
declaring_class_(NULL),
interesting_dex_pc_(-1),
@@ -306,13 +309,14 @@ MethodVerifier::MethodVerifier(const DexFile* dex_file, mirror::DexCache* dex_ca
allow_soft_failures_(allow_soft_failures),
has_check_casts_(false),
has_virtual_or_interface_invokes_(false) {
+ DCHECK(class_def != NULL);
}
void MethodVerifier::FindLocksAtDexPc(mirror::ArtMethod* m, uint32_t dex_pc,
std::vector<uint32_t>& monitor_enter_dex_pcs) {
MethodHelper mh(m);
MethodVerifier verifier(&mh.GetDexFile(), mh.GetDexCache(), mh.GetClassLoader(),
- mh.GetClassDefIndex(), mh.GetCodeItem(), m->GetDexMethodIndex(),
+ &mh.GetClassDef(), mh.GetCodeItem(), m->GetDexMethodIndex(),
m, m->GetAccessFlags(), false, true);
verifier.interesting_dex_pc_ = dex_pc;
verifier.monitor_enter_dex_pcs_ = &monitor_enter_dex_pcs;
@@ -334,7 +338,7 @@ mirror::ArtField* MethodVerifier::FindAccessedFieldAtDexPc(mirror::ArtMethod* m,
uint32_t dex_pc) {
MethodHelper mh(m);
MethodVerifier verifier(&mh.GetDexFile(), mh.GetDexCache(), mh.GetClassLoader(),
- mh.GetClassDefIndex(), mh.GetCodeItem(), m->GetDexMethodIndex(),
+ &mh.GetClassDef(), mh.GetCodeItem(), m->GetDexMethodIndex(),
m, m->GetAccessFlags(), false, true);
return verifier.FindAccessedFieldAtDexPc(dex_pc);
}
@@ -362,7 +366,7 @@ mirror::ArtMethod* MethodVerifier::FindInvokedMethodAtDexPc(mirror::ArtMethod* m
uint32_t dex_pc) {
MethodHelper mh(m);
MethodVerifier verifier(&mh.GetDexFile(), mh.GetDexCache(), mh.GetClassLoader(),
- mh.GetClassDefIndex(), mh.GetCodeItem(), m->GetDexMethodIndex(),
+ &mh.GetClassDef(), mh.GetCodeItem(), m->GetDexMethodIndex(),
m, m->GetAccessFlags(), false, true);
return verifier.FindInvokedMethodAtDexPc(dex_pc);
}
@@ -448,7 +452,7 @@ std::ostream& MethodVerifier::Fail(VerifyError error) {
// marked as rejected to prevent it from being compiled.
case VERIFY_ERROR_BAD_CLASS_HARD: {
if (Runtime::Current()->IsCompiler()) {
- ClassReference ref(dex_file_, class_def_idx_);
+ ClassReference ref(dex_file_, dex_file_->GetIndexForClassDef(*class_def_));
AddRejectedClass(ref);
}
have_pending_hard_failure_ = true;
diff --git a/runtime/verifier/method_verifier.h b/runtime/verifier/method_verifier.h
index 70442fbc04..073a2f76be 100644
--- a/runtime/verifier/method_verifier.h
+++ b/runtime/verifier/method_verifier.h
@@ -145,17 +145,19 @@ class MethodVerifier {
};
/* Verify a class. Returns "kNoFailure" on success. */
- static FailureKind VerifyClass(const mirror::Class* klass, std::string& error,
- bool allow_soft_failures)
+ static FailureKind VerifyClass(const mirror::Class* klass, bool allow_soft_failures,
+ std::string* error)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
static FailureKind VerifyClass(const DexFile* dex_file, mirror::DexCache* dex_cache,
- mirror::ClassLoader* class_loader, uint32_t class_def_idx,
- std::string& error, bool allow_soft_failures)
+ mirror::ClassLoader* class_loader,
+ const DexFile::ClassDef* class_def,
+ bool allow_soft_failures, std::string* error)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
static void VerifyMethodAndDump(std::ostream& os, uint32_t method_idx, const DexFile* dex_file,
mirror::DexCache* dex_cache, mirror::ClassLoader* class_loader,
- uint32_t class_def_idx, const DexFile::CodeItem* code_item,
+ const DexFile::ClassDef* class_def,
+ const DexFile::CodeItem* code_item,
mirror::ArtMethod* method, uint32_t method_access_flags)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -222,7 +224,7 @@ class MethodVerifier {
}
MethodVerifier(const DexFile* dex_file, mirror::DexCache* dex_cache,
- mirror::ClassLoader* class_loader, uint32_t class_def_idx,
+ mirror::ClassLoader* class_loader, const DexFile::ClassDef* class_def,
const DexFile::CodeItem* code_item,
uint32_t method_idx, mirror::ArtMethod* method,
uint32_t access_flags, bool can_load_classes, bool allow_soft_failures)
@@ -262,7 +264,8 @@ class MethodVerifier {
*/
static FailureKind VerifyMethod(uint32_t method_idx, const DexFile* dex_file,
mirror::DexCache* dex_cache,
- mirror::ClassLoader* class_loader, uint32_t class_def_idx,
+ mirror::ClassLoader* class_loader,
+ const DexFile::ClassDef* class_def_idx,
const DexFile::CodeItem* code_item,
mirror::ArtMethod* method, uint32_t method_access_flags,
bool allow_soft_failures)
@@ -690,7 +693,7 @@ class MethodVerifier {
mirror::DexCache* dex_cache_ GUARDED_BY(Locks::mutator_lock_);
// The class loader for the declaring class of the method.
mirror::ClassLoader* class_loader_ GUARDED_BY(Locks::mutator_lock_);
- const uint32_t class_def_idx_; // The class def index of the declaring class of the method.
+ const DexFile::ClassDef* const class_def_; // The class def of the declaring class of the method.
const DexFile::CodeItem* const code_item_; // The code item containing the code for the method.
const RegType* declaring_class_; // Lazily computed reg type of the method's declaring class.
// Instruction widths and flags, one entry per code unit.
diff --git a/runtime/verifier/method_verifier_test.cc b/runtime/verifier/method_verifier_test.cc
index 611b7c06eb..a56abba3cf 100644
--- a/runtime/verifier/method_verifier_test.cc
+++ b/runtime/verifier/method_verifier_test.cc
@@ -34,7 +34,8 @@ class MethodVerifierTest : public CommonTest {
// Verify the class
std::string error_msg;
- ASSERT_TRUE(MethodVerifier::VerifyClass(klass, error_msg, true) == MethodVerifier::kNoFailure) << error_msg;
+ ASSERT_TRUE(MethodVerifier::VerifyClass(klass, true, &error_msg) == MethodVerifier::kNoFailure)
+ << error_msg;
}
void VerifyDexFile(const DexFile* dex)