ART: Add integrity check
Add access-flags setter DCHECK code similar to the getter. For now,
check that the verification-attempted flag is not removed.
Bug: 115834172
Test: m test-art-host
Change-Id: Ia1027126b2ff1a2a2e3c26f674a5f8dc8d2f0c0a
diff --git a/runtime/mirror/class-inl.h b/runtime/mirror/class-inl.h
index 185ae3b..679ca43 100644
--- a/runtime/mirror/class-inl.h
+++ b/runtime/mirror/class-inl.h
@@ -871,6 +871,9 @@
}
inline void Class::SetAccessFlags(uint32_t new_access_flags) {
+ if (kIsDebugBuild) {
+ SetAccessFlagsDCheck(new_access_flags);
+ }
// Called inside a transaction when setting pre-verified flag during boot image compilation.
if (Runtime::Current()->IsActiveTransaction()) {
SetField32<true>(AccessFlagsOffset(), new_access_flags);
diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc
index 83d76a9..8eff21c 100644
--- a/runtime/mirror/class.cc
+++ b/runtime/mirror/class.cc
@@ -1461,5 +1461,12 @@
template void Class::GetAccessFlagsDCheck<kVerifyWrites>();
template void Class::GetAccessFlagsDCheck<kVerifyAll>();
+void Class::SetAccessFlagsDCheck(uint32_t new_access_flags) {
+ uint32_t old_access_flags = GetField32<kVerifyNone>(AccessFlagsOffset());
+ // kAccVerificationAttempted is retained.
+ CHECK((old_access_flags & kAccVerificationAttempted) == 0 ||
+ (new_access_flags & kAccVerificationAttempted) != 0);
+}
+
} // namespace mirror
} // namespace art
diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h
index 66b1405..d5aa514 100644
--- a/runtime/mirror/class.h
+++ b/runtime/mirror/class.h
@@ -1306,6 +1306,8 @@
template<VerifyObjectFlags kVerifyFlags>
void GetAccessFlagsDCheck() REQUIRES_SHARED(Locks::mutator_lock_);
+ void SetAccessFlagsDCheck(uint32_t new_access_flags) REQUIRES_SHARED(Locks::mutator_lock_);
+
// Check that the pointer size matches the one in the class linker.
ALWAYS_INLINE static void CheckPointerSize(PointerSize pointer_size);