From e225eab4a17dd8db7f9d8412e4edc04e330462bc Mon Sep 17 00:00:00 2001 From: Igor Murashkin Date: Wed, 29 Oct 2014 19:45:42 -0700 Subject: [PATCH] art: Fix classlinker and nopatchoat test for PIC case ClassLinker should not be checking oat data begin and the patch delta as part of the checksum verification (when PIC is enabled). Also update nopatchoat test since it needs to be parametric on whether PIC is used. (cherry-picked from AOSP master 230faa7c44ec1986d5fa93d205eb23cb8024e333) Bug: 18035729 (cherry picked from commit 5ef2990c2933152021633e6697d5325103649499) Change-Id: Ia0a601c657b813767114095c3b7577421e03bde4 --- runtime/class_linker.cc | 10 +++++++--- test/117-nopatchoat/expected.txt | 6 +++--- test/117-nopatchoat/nopatchoat.cc | 25 ++++++++++++++++++++++++- test/117-nopatchoat/src/Main.java | 9 ++++++++- 4 files changed, 42 insertions(+), 8 deletions(-) diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index b24ad4bbe..64f248439 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -1097,9 +1097,13 @@ bool ClassLinker::VerifyOatChecksums(const OatFile* oat_file, image_patch_delta = image_header->GetPatchDelta(); } const OatHeader& oat_header = oat_file->GetOatHeader(); - bool ret = ((oat_header.GetImageFileLocationOatChecksum() == image_oat_checksum) - && (oat_header.GetImagePatchDelta() == image_patch_delta) - && (oat_header.GetImageFileLocationOatDataBegin() == image_oat_data_begin)); + bool ret = (oat_header.GetImageFileLocationOatChecksum() == image_oat_checksum); + + // If the oat file is PIC, it doesn't care if/how image was relocated. Ignore these checks. + if (!oat_file->IsPic()) { + ret = ret && (oat_header.GetImagePatchDelta() == image_patch_delta) + && (oat_header.GetImageFileLocationOatDataBegin() == image_oat_data_begin); + } if (!ret) { *error_msg = StringPrintf("oat file '%s' mismatch (0x%x, %d, %d) with (0x%x, %" PRIdPTR ", %d)", oat_file->GetLocation().c_str(), diff --git a/test/117-nopatchoat/expected.txt b/test/117-nopatchoat/expected.txt index a1293aed6..5cc02d166 100644 --- a/test/117-nopatchoat/expected.txt +++ b/test/117-nopatchoat/expected.txt @@ -1,9 +1,9 @@ Run without dex2oat/patchoat -dex2oat & patchoat are disabled, has oat is true, has executable oat is false. +dex2oat & patchoat are disabled, has oat is true, has executable oat is expected. This is a function call Run with dexoat/patchoat -dex2oat & patchoat are enabled, has oat is true, has executable oat is true. +dex2oat & patchoat are enabled, has oat is true, has executable oat is expected. This is a function call Run default -dex2oat & patchoat are enabled, has oat is true, has executable oat is true. +dex2oat & patchoat are enabled, has oat is true, has executable oat is expected. This is a function call diff --git a/test/117-nopatchoat/nopatchoat.cc b/test/117-nopatchoat/nopatchoat.cc index 5994653dc..da276f2b5 100644 --- a/test/117-nopatchoat/nopatchoat.cc +++ b/test/117-nopatchoat/nopatchoat.cc @@ -24,18 +24,41 @@ namespace art { class NoPatchoatTest { public: - static bool hasExecutableOat(jclass cls) { + static const OatFile::OatDexFile* getOatDexFile(jclass cls) { ScopedObjectAccess soa(Thread::Current()); mirror::Class* klass = soa.Decode(cls); const DexFile& dex_file = klass->GetDexFile(); + const OatFile::OatDexFile* oat_dex_file = Runtime::Current()->GetClassLinker()->FindOpenedOatDexFileForDexFile(dex_file); + + return oat_dex_file; + } + + static bool hasExecutableOat(jclass cls) { + const OatFile::OatDexFile* oat_dex_file = getOatDexFile(cls); + return oat_dex_file != nullptr && oat_dex_file->GetOatFile()->IsExecutable(); } + + static bool isPic(jclass cls) { + const OatFile::OatDexFile* oat_dex_file = getOatDexFile(cls); + + if (oat_dex_file == nullptr) { + return false; + } + + const OatFile* oat_file = oat_dex_file->GetOatFile(); + return oat_file->IsPic(); + } }; extern "C" JNIEXPORT jboolean JNICALL Java_Main_hasExecutableOat(JNIEnv*, jclass cls) { return NoPatchoatTest::hasExecutableOat(cls); } +extern "C" JNIEXPORT jboolean JNICALL Java_Main_isPic(JNIEnv*, jclass cls) { + return NoPatchoatTest::isPic(cls); +} + } // namespace art diff --git a/test/117-nopatchoat/src/Main.java b/test/117-nopatchoat/src/Main.java index f3f91ce1a..7bc9dbb94 100644 --- a/test/117-nopatchoat/src/Main.java +++ b/test/117-nopatchoat/src/Main.java @@ -16,9 +16,14 @@ public class Main { public static void main(String[] args) { + boolean executable_correct = (isPic() ? + hasExecutableOat() == true : + hasExecutableOat() == isDex2OatEnabled()); + System.out.println( "dex2oat & patchoat are " + ((isDex2OatEnabled()) ? "enabled" : "disabled") + - ", has oat is " + hasOat() + ", has executable oat is " + hasExecutableOat() + "."); + ", has oat is " + hasOat() + ", has executable oat is " + ( + executable_correct ? "expected" : "not expected") + "."); if (!hasOat() && isDex2OatEnabled()) { throw new Error("Application with dex2oat enabled runs without an oat file"); @@ -42,6 +47,8 @@ public class Main { private native static boolean isDex2OatEnabled(); + private native static boolean isPic(); + private native static boolean hasOat(); private native static boolean hasExecutableOat(); -- 2.11.0