runtime: Add -Xverify:softfail and ART_TEST_INTERPRETER_ACCESS_CHECKS
Use ART_TEST_INTERPRETER_ACCESS_CHECKS=true to run all the tests through
the interpreter with access checks enabled. The normal interpreter tests
do not currently enable access checks, which means that a large part of
the interpreter codebase is untested.
The verifier will force every class into a soft fail mode if
-Xverify:softfail is used, thereby ensuring that if used along with the
interpreter (-Xint) that the interpret is always in access checks mode.
This is used alongside with --compile-filter=verify-at-runtime to
prevent the AOT compiler from putting down any code.
Change-Id: I35a10ed8c43d76fa96133cf01fdad497da387200
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 5798c04..8f7862a 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -3040,6 +3040,18 @@
mirror::Class::SetStatus(klass, mirror::Class::kStatusVerifyingAtRuntime, self);
}
+ // Skip verification if we are forcing a soft fail.
+ // This has to be before the normal verification enabled check,
+ // since technically verification is disabled in this mode.
+ if (UNLIKELY(Runtime::Current()->IsVerificationSoftFail())) {
+ // Force verification to be a 'soft failure'.
+ mirror::Class::SetStatus(klass, mirror::Class::kStatusVerified, self);
+ // As this is a fake verified status, make sure the methods are _not_ marked preverified
+ // later.
+ klass->SetPreverified();
+ return;
+ }
+
// Skip verification if disabled.
if (!Runtime::Current()->IsVerificationEnabled()) {
mirror::Class::SetStatus(klass, mirror::Class::kStatusVerified, self);
diff --git a/runtime/parsed_options.cc b/runtime/parsed_options.cc
index d08af71..7772354 100644
--- a/runtime/parsed_options.cc
+++ b/runtime/parsed_options.cc
@@ -244,10 +244,11 @@
.AppendValues()
.IntoKey(M::ImageCompilerOptions)
.Define("-Xverify:_")
- .WithType<bool>()
- .WithValueMap({{"none", false},
- {"remote", true},
- {"all", true}})
+ .WithType<verifier::VerifyMode>()
+ .WithValueMap({{"none", verifier::VerifyMode::kNone},
+ {"remote", verifier::VerifyMode::kEnable},
+ {"all", verifier::VerifyMode::kEnable},
+ {"softfail", verifier::VerifyMode::kSoftFail}})
.IntoKey(M::Verify)
.Define("-XX:NativeBridge=_")
.WithType<std::string>()
@@ -686,7 +687,7 @@
UsageMessage(stream, " -esa\n");
UsageMessage(stream, " -dsa\n");
UsageMessage(stream, " (-enablesystemassertions, -disablesystemassertions)\n");
- UsageMessage(stream, " -Xverify:{none,remote,all}\n");
+ UsageMessage(stream, " -Xverify:{none,remote,all,softfail}\n");
UsageMessage(stream, " -Xrs\n");
UsageMessage(stream, " -Xint:portable, -Xint:fast, -Xint:jit\n");
UsageMessage(stream, " -Xdexopt:{none,verified,all,full}\n");
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index 3b0ca9e..c5aece5 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -185,7 +185,7 @@
system_class_loader_(nullptr),
dump_gc_performance_on_shutdown_(false),
preinitialization_transaction_(nullptr),
- verify_(false),
+ verify_(verifier::VerifyMode::kNone),
allow_dex_file_fallback_(true),
target_sdk_version_(0),
implicit_null_checks_(false),
@@ -1757,4 +1757,12 @@
imt_unimplemented_method_ = method;
}
+bool Runtime::IsVerificationEnabled() const {
+ return verify_ == verifier::VerifyMode::kEnable;
+}
+
+bool Runtime::IsVerificationSoftFail() const {
+ return verify_ == verifier::VerifyMode::kSoftFail;
+}
+
} // namespace art
diff --git a/runtime/runtime.h b/runtime/runtime.h
index 9ee96a3..806292f 100644
--- a/runtime/runtime.h
+++ b/runtime/runtime.h
@@ -64,6 +64,7 @@
} // namespace mirror
namespace verifier {
class MethodVerifier;
+ enum class VerifyMode : int8_t;
} // namespace verifier
class ArenaPool;
class ArtMethod;
@@ -500,9 +501,8 @@
return !implicit_so_checks_;
}
- bool IsVerificationEnabled() const {
- return verify_;
- }
+ bool IsVerificationEnabled() const;
+ bool IsVerificationSoftFail() const;
bool IsDexFileFallbackEnabled() const {
return allow_dex_file_fallback_;
@@ -700,8 +700,8 @@
// Transaction used for pre-initializing classes at compilation time.
Transaction* preinitialization_transaction_;
- // If false, verification is disabled. True by default.
- bool verify_;
+ // If kNone, verification is disabled. kEnable by default.
+ verifier::VerifyMode verify_;
// If true, the runtime may use dex files directly with the interpreter if an oat file is not
// available/usable.
diff --git a/runtime/runtime_options.def b/runtime/runtime_options.def
index dc4c0c7..9922c5f 100644
--- a/runtime/runtime_options.def
+++ b/runtime/runtime_options.def
@@ -106,7 +106,8 @@
CompilerOptions) // -Xcompiler-option ...
RUNTIME_OPTIONS_KEY (std::vector<std::string>, \
ImageCompilerOptions) // -Ximage-compiler-option ...
-RUNTIME_OPTIONS_KEY (bool, Verify, true)
+RUNTIME_OPTIONS_KEY (verifier::VerifyMode, \
+ Verify, verifier::VerifyMode::kEnable)
RUNTIME_OPTIONS_KEY (std::string, NativeBridge)
RUNTIME_OPTIONS_KEY (unsigned int, ZygoteMaxFailedBoots, 10)
RUNTIME_OPTIONS_KEY (Unit, NoDexFileFallback)
diff --git a/runtime/runtime_options.h b/runtime/runtime_options.h
index 7e59000..88ac00a 100644
--- a/runtime/runtime_options.h
+++ b/runtime/runtime_options.h
@@ -32,6 +32,7 @@
#include "gc/space/large_object_space.h"
#include "profiler_options.h"
#include "arch/instruction_set.h"
+#include "verifier/verify_mode.h"
#include <stdio.h>
#include <stdarg.h>
diff --git a/runtime/verifier/verify_mode.h b/runtime/verifier/verify_mode.h
new file mode 100644
index 0000000..bea4378
--- /dev/null
+++ b/runtime/verifier/verify_mode.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_RUNTIME_VERIFIER_VERIFY_MODE_H_
+#define ART_RUNTIME_VERIFIER_VERIFY_MODE_H_
+
+#include <stdint.h>
+
+namespace art {
+namespace verifier {
+
+// The mode that the verifier should run as.
+enum class VerifyMode : int8_t {
+ kNone, // Everything is assumed verified.
+ kEnable, // Standard verification, try pre-verifying at compile-time.
+ kSoftFail, // Force a soft fail, punting to the interpreter with access checks.
+};
+
+} // namespace verifier
+} // namespace art
+
+#endif // ART_RUNTIME_VERIFIER_VERIFY_MODE_H_