ART: Change access flag behavior in verifier

Note: this moves the miranda modifier to the upper 16 bit.

Bug: 16161620

(cherry picked from commit 7fc8f90b7160e879143be5cfd6ea3df866398884)

Change-Id: I2f591d53b7d1559171e70aaaf22225d94b4882f5
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 4474f1b..6a6286f 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -2792,8 +2792,7 @@
   if (kUseBakerOrBrooksReadBarrier) {
     klass->AssertReadBarrierPointer();
   }
-  uint32_t access_flags = dex_class_def.access_flags_;
-  // Make sure that none of our runtime-only flags are set.
+  uint32_t access_flags = dex_class_def.GetJavaAccessFlags();
   CHECK_EQ(access_flags & ~kAccJavaFlagsMask, 0U);
   klass->SetAccessFlags(access_flags);
   klass->SetClassLoader(class_loader);
@@ -2936,7 +2935,7 @@
   uint32_t field_idx = it.GetMemberIndex();
   dst->SetDexFieldIndex(field_idx);
   dst->SetDeclaringClass(klass.Get());
-  dst->SetAccessFlags(it.GetMemberAccessFlags());
+  dst->SetAccessFlags(it.GetFieldAccessFlags());
 }
 
 mirror::ArtMethod* ClassLinker::LoadMethod(Thread* self, const DexFile& dex_file,
@@ -2962,7 +2961,7 @@
   dst->SetDexCacheResolvedMethods(klass->GetDexCache()->GetResolvedMethods());
   dst->SetDexCacheResolvedTypes(klass->GetDexCache()->GetResolvedTypes());
 
-  uint32_t access_flags = it.GetMemberAccessFlags();
+  uint32_t access_flags = it.GetMethodAccessFlags();
 
   if (UNLIKELY(strcmp("finalize", method_name) == 0)) {
     // Set finalizable flag on declaring class.
diff --git a/runtime/dex_file.h b/runtime/dex_file.h
index 1cec264..c160253 100644
--- a/runtime/dex_file.h
+++ b/runtime/dex_file.h
@@ -201,6 +201,24 @@
     uint32_t class_data_off_;  // file offset to class_data_item
     uint32_t static_values_off_;  // file offset to EncodedArray
 
+    // Returns the valid access flags, that is, Java modifier bits relevant to the ClassDef type
+    // (class or interface). These are all in the lower 16b and do not contain runtime flags.
+    uint32_t GetJavaAccessFlags() const {
+      // Make sure that none of our runtime-only flags are set.
+      COMPILE_ASSERT((kAccValidClassFlags & kAccJavaFlagsMask) == kAccValidClassFlags,
+                     valid_class_flags_not_subset_of_java_flags);
+      COMPILE_ASSERT((kAccValidInterfaceFlags & kAccJavaFlagsMask) == kAccValidInterfaceFlags,
+                     valid_interface_flags_not_subset_of_java_flags);
+
+      if ((access_flags_ & kAccInterface) != 0) {
+        // Interface.
+        return access_flags_ & kAccValidInterfaceFlags;
+      } else {
+        // Class.
+        return access_flags_ & kAccValidClassFlags;
+      }
+    }
+
    private:
     DISALLOW_COPY_AND_ASSIGN(ClassDef);
   };
@@ -1112,7 +1130,7 @@
       return last_idx_ + method_.method_idx_delta_;
     }
   }
-  uint32_t GetMemberAccessFlags() const {
+  uint32_t GetRawMemberAccessFlags() const {
     if (pos_ < EndOfInstanceFieldsPos()) {
       return field_.access_flags_;
     } else {
@@ -1120,18 +1138,30 @@
       return method_.access_flags_;
     }
   }
+  uint32_t GetFieldAccessFlags() const {
+    return GetRawMemberAccessFlags() & kAccValidFieldFlags;
+  }
+  uint32_t GetMethodAccessFlags() const {
+    return GetRawMemberAccessFlags() & kAccValidMethodFlags;
+  }
+  bool MemberIsNative() const {
+    return GetRawMemberAccessFlags() & kAccNative;
+  }
+  bool MemberIsFinal() const {
+    return GetRawMemberAccessFlags() & kAccFinal;
+  }
   InvokeType GetMethodInvokeType(const DexFile::ClassDef& class_def) const {
     if (HasNextDirectMethod()) {
-      if ((GetMemberAccessFlags() & kAccStatic) != 0) {
+      if ((GetRawMemberAccessFlags() & kAccStatic) != 0) {
         return kStatic;
       } else {
         return kDirect;
       }
     } else {
-      DCHECK_EQ(GetMemberAccessFlags() & kAccStatic, 0U);
+      DCHECK_EQ(GetRawMemberAccessFlags() & kAccStatic, 0U);
       if ((class_def.access_flags_ & kAccInterface) != 0) {
         return kInterface;
-      } else if ((GetMemberAccessFlags() & kAccConstructor) != 0) {
+      } else if ((GetRawMemberAccessFlags() & kAccConstructor) != 0) {
         return kSuper;
       } else {
         return kVirtual;
diff --git a/runtime/dex_file_verifier.cc b/runtime/dex_file_verifier.cc
index 976cac9..9eba92f 100644
--- a/runtime/dex_file_verifier.cc
+++ b/runtime/dex_file_verifier.cc
@@ -456,9 +456,7 @@
     return false;
   }
 
-  uint32_t access_field_mask = kAccPublic | kAccPrivate | kAccProtected | kAccStatic |
-      kAccFinal | kAccVolatile | kAccTransient | kAccSynthetic | kAccEnum;
-  if (UNLIKELY((access_flags & ~access_field_mask) != 0)) {
+  if (UNLIKELY((access_flags & ~kAccJavaFlagsMask) != 0)) {
     ErrorStringPrintf("Bad class_data_item field access_flags %x", access_flags);
     return false;
   }
@@ -482,9 +480,8 @@
     return false;
   }
 
-  uint32_t access_method_mask = kAccPublic | kAccPrivate | kAccProtected | kAccStatic |
-      kAccFinal | kAccSynchronized | kAccBridge | kAccVarargs | kAccNative | kAccAbstract |
-      kAccStrict | kAccSynthetic | kAccConstructor | kAccDeclaredSynchronized;
+  constexpr uint32_t access_method_mask = kAccJavaFlagsMask | kAccConstructor |
+      kAccDeclaredSynchronized;
   if (UNLIKELY(((access_flags & ~access_method_mask) != 0) ||
                (is_synchronized && !allow_synchronized))) {
     ErrorStringPrintf("Bad class_data_item method access_flags %x", access_flags);
@@ -686,24 +683,26 @@
 bool DexFileVerifier::CheckIntraClassDataItem() {
   ClassDataItemIterator it(*dex_file_, ptr_);
 
+  // These calls use the raw access flags to check whether the whole dex field is valid.
+
   for (; it.HasNextStaticField(); it.Next()) {
-    if (!CheckClassDataItemField(it.GetMemberIndex(), it.GetMemberAccessFlags(), true)) {
+    if (!CheckClassDataItemField(it.GetMemberIndex(), it.GetRawMemberAccessFlags(), true)) {
       return false;
     }
   }
   for (; it.HasNextInstanceField(); it.Next()) {
-    if (!CheckClassDataItemField(it.GetMemberIndex(), it.GetMemberAccessFlags(), false)) {
+    if (!CheckClassDataItemField(it.GetMemberIndex(), it.GetRawMemberAccessFlags(), false)) {
       return false;
     }
   }
   for (; it.HasNextDirectMethod(); it.Next()) {
-    if (!CheckClassDataItemMethod(it.GetMemberIndex(), it.GetMemberAccessFlags(),
+    if (!CheckClassDataItemMethod(it.GetMemberIndex(), it.GetRawMemberAccessFlags(),
         it.GetMethodCodeItemOffset(), true)) {
       return false;
     }
   }
   for (; it.HasNextVirtualMethod(); it.Next()) {
-    if (!CheckClassDataItemMethod(it.GetMemberIndex(), it.GetMemberAccessFlags(),
+    if (!CheckClassDataItemMethod(it.GetMemberIndex(), it.GetRawMemberAccessFlags(),
         it.GetMethodCodeItemOffset(), false)) {
       return false;
     }
diff --git a/runtime/image.cc b/runtime/image.cc
index 93ec27d..478b486 100644
--- a/runtime/image.cc
+++ b/runtime/image.cc
@@ -24,7 +24,7 @@
 namespace art {
 
 const byte ImageHeader::kImageMagic[] = { 'a', 'r', 't', '\n' };
-const byte ImageHeader::kImageVersion[] = { '0', '0', '8', '\0' };
+const byte ImageHeader::kImageVersion[] = { '0', '0', '9', '\0' };
 
 ImageHeader::ImageHeader(uint32_t image_begin,
                          uint32_t image_size,
diff --git a/runtime/modifiers.h b/runtime/modifiers.h
index 2814ed8..23c18f8 100644
--- a/runtime/modifiers.h
+++ b/runtime/modifiers.h
@@ -19,48 +19,77 @@
 
 #include <stdint.h>
 
-static const uint32_t kAccPublic = 0x0001;  // class, field, method, ic
-static const uint32_t kAccPrivate = 0x0002;  // field, method, ic
-static const uint32_t kAccProtected = 0x0004;  // field, method, ic
-static const uint32_t kAccStatic = 0x0008;  // field, method, ic
-static const uint32_t kAccFinal = 0x0010;  // class, field, method, ic
-static const uint32_t kAccSynchronized = 0x0020;  // method (only allowed on natives)
-static const uint32_t kAccSuper = 0x0020;  // class (not used in dex)
-static const uint32_t kAccVolatile = 0x0040;  // field
-static const uint32_t kAccBridge = 0x0040;  // method (1.5)
-static const uint32_t kAccTransient = 0x0080;  // field
-static const uint32_t kAccVarargs = 0x0080;  // method (1.5)
-static const uint32_t kAccNative = 0x0100;  // method
-static const uint32_t kAccInterface = 0x0200;  // class, ic
-static const uint32_t kAccAbstract = 0x0400;  // class, method, ic
-static const uint32_t kAccStrict = 0x0800;  // method
-static const uint32_t kAccSynthetic = 0x1000;  // class, field, method, ic
-static const uint32_t kAccAnnotation = 0x2000;  // class, ic (1.5)
-static const uint32_t kAccEnum = 0x4000;  // class, field, ic (1.5)
+static constexpr uint32_t kAccPublic =       0x0001;  // class, field, method, ic
+static constexpr uint32_t kAccPrivate =      0x0002;  // field, method, ic
+static constexpr uint32_t kAccProtected =    0x0004;  // field, method, ic
+static constexpr uint32_t kAccStatic =       0x0008;  // field, method, ic
+static constexpr uint32_t kAccFinal =        0x0010;  // class, field, method, ic
+static constexpr uint32_t kAccSynchronized = 0x0020;  // method (only allowed on natives)
+static constexpr uint32_t kAccSuper =        0x0020;  // class (not used in dex)
+static constexpr uint32_t kAccVolatile =     0x0040;  // field
+static constexpr uint32_t kAccBridge =       0x0040;  // method (1.5)
+static constexpr uint32_t kAccTransient =    0x0080;  // field
+static constexpr uint32_t kAccVarargs =      0x0080;  // method (1.5)
+static constexpr uint32_t kAccNative =       0x0100;  // method
+static constexpr uint32_t kAccInterface =    0x0200;  // class, ic
+static constexpr uint32_t kAccAbstract =     0x0400;  // class, method, ic
+static constexpr uint32_t kAccStrict =       0x0800;  // method
+static constexpr uint32_t kAccSynthetic =    0x1000;  // class, field, method, ic
+static constexpr uint32_t kAccAnnotation =   0x2000;  // class, ic (1.5)
+static constexpr uint32_t kAccEnum =         0x4000;  // class, field, ic (1.5)
 
-static const uint32_t kAccMiranda = 0x8000;  // method
+static constexpr uint32_t kAccJavaFlagsMask = 0xffff;  // bits set from Java sources (low 16)
 
-static const uint32_t kAccJavaFlagsMask = 0xffff;  // bits set from Java sources (low 16)
-
-static const uint32_t kAccConstructor = 0x00010000;  // method (dex only) <init> and <clinit>
-static const uint32_t kAccDeclaredSynchronized = 0x00020000;  // method (dex only)
-static const uint32_t kAccClassIsProxy = 0x00040000;  // class (dex only)
-static const uint32_t kAccPreverified = 0x00080000;  // class (runtime), method (dex only)
-static const uint32_t kAccFastNative = 0x0080000;  // method (dex only)
-static const uint32_t kAccPortableCompiled = 0x0100000;  // method (dex only)
+static constexpr uint32_t kAccConstructor =          0x00010000;  // method (dex only) <(cl)init>
+static constexpr uint32_t kAccDeclaredSynchronized = 0x00020000;  // method (dex only)
+static constexpr uint32_t kAccClassIsProxy =         0x00040000;  // class  (dex only)
+static constexpr uint32_t kAccPreverified =          0x00080000;  // class (runtime),
+                                                                  // method (dex only)
+static constexpr uint32_t kAccFastNative =           0x00080000;  // method (dex only)
+static constexpr uint32_t kAccPortableCompiled =     0x00100000;  // method (dex only)
+static constexpr uint32_t kAccMiranda =              0x00200000;  // method (dex only)
 
 // Special runtime-only flags.
 // Note: if only kAccClassIsReference is set, we have a soft reference.
-static const uint32_t kAccClassIsFinalizable        = 0x80000000;  // class/ancestor overrides finalize()
-static const uint32_t kAccClassIsReference          = 0x08000000;  // class is a soft/weak/phantom ref
-static const uint32_t kAccClassIsWeakReference      = 0x04000000;  // class is a weak reference
-static const uint32_t kAccClassIsFinalizerReference = 0x02000000;  // class is a finalizer reference
-static const uint32_t kAccClassIsPhantomReference   = 0x01000000;  // class is a phantom reference
 
-static const uint32_t kAccReferenceFlagsMask = (kAccClassIsReference
-                                                | kAccClassIsWeakReference
-                                                | kAccClassIsFinalizerReference
-                                                | kAccClassIsPhantomReference);
+// class/ancestor overrides finalize()
+static constexpr uint32_t kAccClassIsFinalizable        = 0x80000000;
+// class is a soft/weak/phantom ref
+static constexpr uint32_t kAccClassIsReference          = 0x08000000;
+// class is a weak reference
+static constexpr uint32_t kAccClassIsWeakReference      = 0x04000000;
+// class is a finalizer reference
+static constexpr uint32_t kAccClassIsFinalizerReference = 0x02000000;
+// class is a phantom reference
+static constexpr uint32_t kAccClassIsPhantomReference   = 0x01000000;
+
+static constexpr uint32_t kAccReferenceFlagsMask = (kAccClassIsReference
+                                                  | kAccClassIsWeakReference
+                                                  | kAccClassIsFinalizerReference
+                                                  | kAccClassIsPhantomReference);
+
+// Valid (meaningful) bits for a field.
+static constexpr uint32_t kAccValidFieldFlags = kAccPublic | kAccPrivate | kAccProtected |
+    kAccStatic | kAccFinal | kAccVolatile | kAccTransient | kAccSynthetic | kAccEnum;
+
+// Valid (meaningful) bits for a method.
+static constexpr uint32_t kAccValidMethodFlags = kAccPublic | kAccPrivate | kAccProtected |
+    kAccStatic | kAccFinal | kAccSynchronized | kAccBridge | kAccVarargs | kAccNative |
+    kAccAbstract | kAccStrict | kAccSynthetic | kAccMiranda | kAccConstructor |
+    kAccDeclaredSynchronized;
+
+// Valid (meaningful) bits for a class (not interface).
+// Note 1. These are positive bits. Other bits may have to be zero.
+// Note 2. Inner classes can expose more access flags to Java programs. That is handled by libcore.
+static constexpr uint32_t kAccValidClassFlags = kAccPublic | kAccFinal | kAccSuper |
+    kAccAbstract | kAccSynthetic | kAccEnum;
+
+// Valid (meaningful) bits for an interface.
+// Note 1. Annotations are interfaces.
+// Note 2. These are positive bits. Other bits may have to be zero.
+// Note 3. Inner classes can expose more access flags to Java programs. That is handled by libcore.
+static constexpr uint32_t kAccValidInterfaceFlags = kAccPublic | kAccInterface |
+    kAccAbstract | kAccSynthetic | kAccAnnotation;
 
 #endif  // ART_RUNTIME_MODIFIERS_H_
 
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index b799588..0de1e76 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -175,7 +175,7 @@
                                                       class_def,
                                                       it.GetMethodCodeItem(),
                                                       h_method,
-                                                      it.GetMemberAccessFlags(),
+                                                      it.GetMethodAccessFlags(),
                                                       allow_soft_failures,
                                                       false);
     if (result != kNoFailure) {
@@ -223,7 +223,7 @@
                                                       class_def,
                                                       it.GetMethodCodeItem(),
                                                       h_method,
-                                                      it.GetMemberAccessFlags(),
+                                                      it.GetMethodAccessFlags(),
                                                       allow_soft_failures,
                                                       false);
     if (result != kNoFailure) {