diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/class_linker.cc | 96 | ||||
| -rw-r--r-- | src/class_linker.h | 13 | ||||
| -rw-r--r-- | src/native/dalvik_system_DexFile.cc | 36 |
3 files changed, 83 insertions, 62 deletions
diff --git a/src/class_linker.cc b/src/class_linker.cc index a904800d62..990fb629cc 100644 --- a/src/class_linker.cc +++ b/src/class_linker.cc @@ -742,38 +742,58 @@ const DexFile* ClassLinker::FindOrCreateOatFileForDexLocation(const std::string& return oat_dex_file->OpenDexFile(); } -const DexFile* ClassLinker::VerifyOatFileChecksums(const OatFile* oat_file, - const std::string& dex_location, - uint32_t dex_location_checksum) { - Runtime* runtime = Runtime::Current(); - const ImageHeader& image_header = runtime->GetHeap()->GetImageSpace()->GetImageHeader(); - uint32_t image_checksum = image_header.GetOatChecksum(); - bool image_check = (oat_file->GetOatHeader().GetImageFileLocationChecksum() == image_checksum); - - const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(dex_location); - CHECK(oat_dex_file != NULL) << oat_file->GetLocation() << " " << dex_location; - bool dex_check = (dex_location_checksum == oat_dex_file->GetDexFileLocationChecksum()); - - if (image_check && dex_check) { - RegisterOatFileLocked(*oat_file); - return oat_file->GetOatDexFile(dex_location)->OpenDexFile(); - } - - if (!image_check) { - std::string image_file(image_header.GetImageRoot( - ImageHeader::kOatLocation)->AsString()->ToModifiedUtf8()); - LOG(WARNING) << ".oat file " << oat_file->GetLocation() - << " checksum ( " << std::hex << oat_dex_file->GetDexFileLocationChecksum() - << ") mismatch with " << image_file - << " (" << std::hex << image_checksum << ")"; - } - if (!dex_check) { - LOG(WARNING) << ".oat file " << oat_file->GetLocation() - << " checksum ( " << std::hex << oat_dex_file->GetDexFileLocationChecksum() - << ") mismatch with " << dex_location - << " (" << std::hex << dex_location_checksum << ")"; - } - return NULL; +bool ClassLinker::VerifyOatFileChecksums(const OatFile* oat_file, + const std::string& dex_location, + uint32_t dex_location_checksum) { + Runtime* runtime = Runtime::Current(); + const ImageHeader& image_header = runtime->GetHeap()->GetImageSpace()->GetImageHeader(); + uint32_t image_checksum = image_header.GetOatChecksum(); + bool image_check = (oat_file->GetOatHeader().GetImageFileLocationChecksum() == image_checksum); + + const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(dex_location); + if (oat_dex_file == NULL) { + LOG(ERROR) << ".oat file " << oat_file->GetLocation() + << " does not contain contents for " << dex_location; + std::vector<const OatFile::OatDexFile*> oat_dex_files = oat_file->GetOatDexFiles(); + for (size_t i = 0; i < oat_dex_files.size(); i++) { + const OatFile::OatDexFile* oat_dex_file = oat_dex_files[i]; + LOG(ERROR) << ".oat file " << oat_file->GetLocation() + << " contains contents for " << oat_dex_file->GetDexFileLocation(); + } + return false; + } + bool dex_check = (dex_location_checksum == oat_dex_file->GetDexFileLocationChecksum()); + + if (image_check && dex_check) { + return true; + } + + if (!image_check) { + std::string image_file(image_header.GetImageRoot( + ImageHeader::kOatLocation)->AsString()->ToModifiedUtf8()); + LOG(WARNING) << ".oat file " << oat_file->GetLocation() + << " checksum ( " << std::hex << oat_dex_file->GetDexFileLocationChecksum() + << ") mismatch with " << image_file + << " (" << std::hex << image_checksum << ")"; + } + if (!dex_check) { + LOG(WARNING) << ".oat file " << oat_file->GetLocation() + << " checksum ( " << std::hex << oat_dex_file->GetDexFileLocationChecksum() + << ") mismatch with " << dex_location + << " (" << std::hex << dex_location_checksum << ")"; + } + return false; +} + +const DexFile* ClassLinker::VerifyAndOpenDexFileFromOatFile(const OatFile* oat_file, + const std::string& dex_location, + uint32_t dex_location_checksum) { + bool verified = VerifyOatFileChecksums(oat_file, dex_location, dex_location_checksum); + if (!verified) { + return NULL; + } + RegisterOatFileLocked(*oat_file); + return oat_file->GetOatDexFile(dex_location)->OpenDexFile(); } const DexFile* ClassLinker::FindDexFileInOatFileFromDexLocation(const std::string& dex_location) { @@ -798,9 +818,9 @@ const DexFile* ClassLinker::FindDexFileInOatFileFromDexLocation(const std::strin RegisterOatFileLocked(*oat_file); return oat_dex_file->OpenDexFile(); } - const DexFile* dex_file = VerifyOatFileChecksums(oat_file, - dex_location, - dex_location_checksum); + const DexFile* dex_file = VerifyAndOpenDexFileFromOatFile(oat_file, + dex_location, + dex_location_checksum); if (dex_file != NULL) { return dex_file; } @@ -815,9 +835,9 @@ const DexFile* ClassLinker::FindDexFileInOatFileFromDexLocation(const std::strin LOG(WARNING) << "Failed to compute checksum: " << dex_location; return NULL; } - const DexFile* dex_file = VerifyOatFileChecksums(oat_file, - dex_location, - dex_location_checksum); + const DexFile* dex_file = VerifyAndOpenDexFileFromOatFile(oat_file, + dex_location, + dex_location_checksum); if (dex_file != NULL) { return dex_file; } diff --git a/src/class_linker.h b/src/class_linker.h index 26ce31e174..8e474dfa61 100644 --- a/src/class_linker.h +++ b/src/class_linker.h @@ -251,6 +251,11 @@ class ClassLinker { const DexFile* FindDexFileInOatFileFromDexLocation(const std::string& location); + // Returns true if oat file contains the dex file with the given location and checksum + static bool VerifyOatFileChecksums(const OatFile* oat_file, + const std::string& dex_location, + uint32_t dex_location_checksum); + // TODO: replace this with multiple methods that allocate the correct managed type. template <class T> ObjectArray<T>* AllocObjectArray(size_t length) { @@ -402,10 +407,10 @@ class ClassLinker { const OatFile* FindOpenedOatFileForDexFile(const DexFile& dex_file); const OatFile* FindOpenedOatFileFromDexLocation(const std::string& dex_location); const OatFile* FindOpenedOatFileFromOatLocation(const std::string& oat_location); - const DexFile* VerifyOatFileChecksums(const OatFile* oat_file, - const std::string& dex_location, - uint32_t dex_location_checksum) - EXCLUSIVE_LOCKS_REQUIRED(dex_lock_); + const DexFile* VerifyAndOpenDexFileFromOatFile(const OatFile* oat_file, + const std::string& dex_location, + uint32_t dex_location_checksum) + EXCLUSIVE_LOCKS_REQUIRED(dex_lock_); Method* CreateProxyConstructor(SirtRef<Class>& klass, Class* proxy_class); Method* CreateProxyMethod(SirtRef<Class>& klass, SirtRef<Method>& prototype); diff --git a/src/native/dalvik_system_DexFile.cc b/src/native/dalvik_system_DexFile.cc index 3bf0ea562f..ef38f00561 100644 --- a/src/native/dalvik_system_DexFile.cc +++ b/src/native/dalvik_system_DexFile.cc @@ -192,17 +192,26 @@ static jboolean DexFile_isDexOptNeeded(JNIEnv* env, jclass, jstring javaFilename } } - // If we have an oat file next to the dex file, assume up-to-date. - // A user build looks like this, and it will have no classes.dex in - // the input for checksum validation. + // Check if we have an oat file next to the dex file. std::string oat_filename(OatFile::DexFilenameToOatFilename(filename.c_str())); UniquePtr<const OatFile> oat_file( OatFile::Open(oat_filename, oat_filename, NULL, OatFile::kRelocNone)); if (oat_file.get() != NULL && oat_file->GetOatDexFile(filename.c_str()) != NULL) { - if (debug_logging) { - LOG(INFO) << "DexFile_isDexOptNeeded ignoring precompiled file: " << filename.c_str(); + uint32_t location_checksum; + // If we have no classes.dex checksum such as in a user build, assume up-to-date. + if (!DexFile::GetChecksum(filename.c_str(), location_checksum)) { + if (debug_logging) { + LOG(INFO) << "DexFile_isDexOptNeeded ignoring precompiled stripped file: " << filename.c_str(); + } + return JNI_FALSE; + } + if (ClassLinker::VerifyOatFileChecksums(oat_file.get(), filename.c_str(), location_checksum)) { + if (debug_logging) { + LOG(INFO) << "DexFile_isDexOptNeeded precompiled file " << oat_filename + << " is up-to-date checksum compared to " << filename.c_str(); + } + return JNI_FALSE; } - return JNI_FALSE; } // Check if we have an oat file in the cache @@ -223,26 +232,13 @@ static jboolean DexFile_isDexOptNeeded(JNIEnv* env, jclass, jstring javaFilename return JNI_TRUE; } - const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(filename.c_str()); - if (oat_dex_file == NULL) { - LOG(ERROR) << "DexFile_isDexOptNeeded cache file " << cache_location - << " does not contain contents for " << filename.c_str(); - std::vector<const OatFile::OatDexFile*> oat_dex_files = oat_file->GetOatDexFiles(); - for (size_t i = 0; i < oat_dex_files.size(); i++) { - const OatFile::OatDexFile* oat_dex_file = oat_dex_files[i]; - LOG(ERROR) << "DexFile_isDexOptNeeded cache file " << cache_location - << " contains contents for " << oat_dex_file->GetDexFileLocation(); - } - return JNI_TRUE; - } - uint32_t location_checksum; if (!DexFile::GetChecksum(filename.c_str(), location_checksum)) { LOG(ERROR) << "DexFile_isDexOptNeeded failed to compute checksum of " << filename.c_str(); return JNI_TRUE; } - if (location_checksum != oat_dex_file->GetDexFileLocationChecksum()) { + if (!ClassLinker::VerifyOatFileChecksums(oat_file.get(), filename.c_str(), location_checksum)) { LOG(INFO) << "DexFile_isDexOptNeeded cache file " << cache_location << " has out-of-date checksum compared to " << filename.c_str(); return JNI_TRUE; |