Fix checksum verification when opening DexFiles from OatFiles

Change-Id: Ic3d13f3d591c34f159bf0739536a1751c3e7dc75
diff --git a/src/dalvik_system_DexFile.cc b/src/dalvik_system_DexFile.cc
index 67cb49b..a255141 100644
--- a/src/dalvik_system_DexFile.cc
+++ b/src/dalvik_system_DexFile.cc
@@ -84,60 +84,22 @@
   if (sourceName.c_str() == NULL) {
     return 0;
   }
+  std::string source(sourceName.c_str());
   NullableScopedUtfChars outputName(env, javaOutputName);
   if (env->ExceptionCheck()) {
     return 0;
   }
   const DexFile* dex_file;
   if (outputName.c_str() == NULL) {
-    dex_file = Runtime::Current()->GetClassLinker()->FindDexFileFromDexLocation(sourceName.c_str());
-    if (dex_file == NULL) {
-      dex_file = DexFile::Open(sourceName.c_str(), "");
-    }
+    dex_file = Runtime::Current()->GetClassLinker()->FindDexFileInOatFileFromDexLocation(source);
   } else {
-    // Sanity check the arguments.
-    if (!IsValidZipFilename(sourceName.c_str()) || !IsValidDexFilename(outputName.c_str())) {
-      LOG(ERROR) << "Bad filenames extracting dex '" << outputName.c_str()
-                 << "' from zip '" << sourceName.c_str() << "'";
-      return 0;
-    }
-    // Generate the output oat file for the source dex file
-    ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
-    UniquePtr<File> file(OS::OpenFile(outputName.c_str(), true));
-    if (file.get() == NULL) {
-      LOG(WARNING) << "unable to create oat file: " << outputName.c_str();
-      jniThrowExceptionFmt(env, "java/io/IOException", "unable to create oat file: %s",
-                           outputName.c_str());
-      return 0;
-    }
-    if (!class_linker->GenerateOatFile(sourceName.c_str(), file->Fd(), outputName.c_str())) {
-      LOG(WARNING) << "unable to generate oat file: " << outputName.c_str();
-      jniThrowExceptionFmt(env, "java/io/IOException", "unable to generate oat file: %s",
-                           outputName.c_str());
-      return 0;
-    }
-    UniquePtr<OatFile> oat_file(OatFile::Open(outputName.c_str(), "", NULL));
-    if (oat_file.get() == NULL) {
-      LOG(WARNING) << "unable to open oat file: " << outputName.c_str();
-      jniThrowExceptionFmt(env, "java/io/IOException", "unable to open oat file: %s",
-                           outputName.c_str());
-      return 0;
-    }
-    const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(sourceName.c_str());
-    if (oat_dex_file == NULL) {
-      LOG(WARNING) << "unable to find dex file in oat file: " << outputName.c_str();
-      jniThrowExceptionFmt(env, "java/io/IOException", "unable to find dex file in oat file: %s",
-                           outputName.c_str());
-      return 0;
-    }
-    Runtime::Current()->GetClassLinker()->RegisterOatFile(*oat_file.release());
-    dex_file = oat_dex_file->OpenDexFile();
+    std::string output(outputName.c_str());
+    dex_file = Runtime::Current()->GetClassLinker()->FindOrCreateOatFileForDexLocation(source, output);
   }
-
   if (dex_file == NULL) {
-    LOG(WARNING) << "unable to open dex file: " << sourceName.c_str();
+    LOG(WARNING) << "Failed to open dex file: " << source;
     jniThrowExceptionFmt(env, "java/io/IOException", "unable to open dex file: %s",
-                         sourceName.c_str());
+                         source.c_str());
     return 0;
   }
   return static_cast<jint>(reinterpret_cast<uintptr_t>(dex_file));
@@ -236,10 +198,26 @@
     }
   }
 
-  const DexFile* dex_file = class_linker->FindDexFileFromDexLocation(filename.c_str());
-  if (dex_file == NULL) {
+  uint32_t location_checksum;
+  if (!DexFile::GetChecksum(filename.c_str(), location_checksum)) {
     return JNI_TRUE;
   }
+
+  std::string oat_filename(OatFile::DexFilenameToOatFilename(filename.c_str()));
+  const OatFile* oat_file(class_linker->FindOatFileFromOatLocation(oat_filename));
+  if (oat_file == NULL) {
+    return JNI_TRUE;
+  }
+
+  const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(filename.c_str());
+  if (oat_dex_file == NULL) {
+    return JNI_TRUE;
+  }
+
+  if (location_checksum != oat_dex_file->GetDexFileLocationChecksum()) {
+    return JNI_TRUE;
+  }
+
   return JNI_FALSE;
 }