ART: Simple structural class check

Adds a simple check to class-loading when the embedded dex file in
an oat file and the dex file on the class path where we found the
class do not match.

We require that the number of methods and fields do not change, as
that will almost certainly mean that quickened and other compiled
offsets are wrong now. This is a reasonably lightweight change, but
we should investigate a full comparison including name and type of
members.

Bug: 17937814
Bug: 18708951

(cherry picked from commit 15a33b3f88546bce85dcb9d28caf200da51154d7)

Change-Id: Icb9638bebd369ab23822817f4a97c8dd8625fea5
diff --git a/runtime/dex_file.h b/runtime/dex_file.h
index 019c8e6..9b8f254 100644
--- a/runtime/dex_file.h
+++ b/runtime/dex_file.h
@@ -44,6 +44,7 @@
 }  // namespace mirror
 class ClassLinker;
 class MemMap;
+class OatFile;
 class Signature;
 template<class T> class Handle;
 class StringPiece;
@@ -391,8 +392,9 @@
   static std::unique_ptr<const DexFile> Open(const uint8_t* base, size_t size,
                                              const std::string& location,
                                              uint32_t location_checksum,
+                                             const OatFile* oat_file,
                                              std::string* error_msg) {
-    return OpenMemory(base, size, location, location_checksum, NULL, error_msg);
+    return OpenMemory(base, size, location, location_checksum, NULL, oat_file, error_msg);
   }
 
   // Open all classesXXX.dex files from a zip archive.
@@ -891,6 +893,10 @@
   //     the dex_location where it's file name part has been made canonical.
   static std::string GetDexCanonicalLocation(const char* dex_location);
 
+  const OatFile* GetOatFile() const {
+    return oat_file_;
+  }
+
  private:
   // Opens a .dex file
   static std::unique_ptr<const DexFile> OpenFile(int fd, const char* location,
@@ -927,12 +933,14 @@
                                                    const std::string& location,
                                                    uint32_t location_checksum,
                                                    MemMap* mem_map,
+                                                   const OatFile* oat_file,
                                                    std::string* error_msg);
 
   DexFile(const uint8_t* base, size_t size,
           const std::string& location,
           uint32_t location_checksum,
-          MemMap* mem_map);
+          MemMap* mem_map,
+          const OatFile* oat_file);
 
   // Top-level initializer that calls other Init methods.
   bool Init(std::string* error_msg);
@@ -1015,6 +1023,10 @@
   };
   typedef HashMap<const char*, const ClassDef*, UTF16EmptyFn, UTF16HashCmp, UTF16HashCmp> Index;
   mutable Atomic<Index*> class_def_index_;
+
+  // The oat file this dex file was loaded from. May be null in case the dex file is not coming
+  // from an oat file, e.g., directly from an apk.
+  const OatFile* oat_file_;
 };
 std::ostream& operator<<(std::ostream& os, const DexFile& dex_file);