diff options
-rw-r--r-- | patchoat/patchoat.cc | 7 | ||||
-rw-r--r-- | runtime/class_linker.cc | 3 | ||||
-rw-r--r-- | runtime/gc/space/image_space.cc | 57 | ||||
-rw-r--r-- | runtime/gc/space/image_space.h | 3 | ||||
-rw-r--r-- | runtime/native/dalvik_system_DexFile.cc | 4 | ||||
-rw-r--r-- | runtime/runtime.cc | 4 | ||||
-rw-r--r-- | runtime/utils.cc | 6 | ||||
-rw-r--r-- | runtime/utils.h | 3 |
8 files changed, 64 insertions, 23 deletions
diff --git a/patchoat/patchoat.cc b/patchoat/patchoat.cc index f89a4f7..50b4ece 100644 --- a/patchoat/patchoat.cc +++ b/patchoat/patchoat.cc @@ -79,9 +79,10 @@ static bool LocationToFilename(const std::string& location, InstructionSet isa, bool have_android_data = false; bool dalvik_cache_exists = false; + bool is_global_cache = false; std::string dalvik_cache; GetDalvikCache(GetInstructionSetString(isa), false, &dalvik_cache, - &have_android_data, &dalvik_cache_exists); + &have_android_data, &dalvik_cache_exists, &is_global_cache); std::string cache_filename; if (have_android_data && dalvik_cache_exists) { @@ -986,9 +987,11 @@ static int patchoat(int argc, char **argv) { std::string cache_filename; bool has_cache = false; bool has_android_data_unused = false; + bool is_global_cache = false; if (!gc::space::ImageSpace::FindImageFilename(patched_image_location.c_str(), isa, &system_filename, &has_system, &cache_filename, - &has_android_data_unused, &has_cache)) { + &has_android_data_unused, &has_cache, + &is_global_cache)) { Usage("Unable to determine image file for location %s", patched_image_location.c_str()); } if (has_cache) { diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index 1686c27..cb0fe0a 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -1323,8 +1323,9 @@ const OatFile* ClassLinker::OpenOatFileFromDexLocation(const std::string& dex_lo std::string dalvik_cache; bool have_android_data = false; bool have_dalvik_cache = false; + bool is_global_cache = false; GetDalvikCache(GetInstructionSetString(kRuntimeISA), false, &dalvik_cache, - &have_android_data, &have_dalvik_cache); + &have_android_data, &have_dalvik_cache, &is_global_cache); std::string cache_filename; if (have_dalvik_cache) { cache_filename = GetDalvikCacheFilenameOrDie(dex_location.c_str(), dalvik_cache.c_str()); diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc index 41c34c9..353d00c 100644 --- a/runtime/gc/space/image_space.cc +++ b/runtime/gc/space/image_space.cc @@ -125,7 +125,7 @@ static bool GenerateImage(const std::string& image_filename, InstructionSet imag } // We should clean up so we are more likely to have room for the image. if (Runtime::Current()->IsZygote()) { - LOG(INFO) << "Pruning dalvik-cache since we are relocating an image and will need to recompile"; + LOG(INFO) << "Pruning dalvik-cache since we are generating an image and will need to recompile"; PruneDexCache(image_isa); } @@ -177,7 +177,8 @@ bool ImageSpace::FindImageFilename(const char* image_location, bool* has_system, std::string* cache_filename, bool* dalvik_cache_exists, - bool* has_cache) { + bool* has_cache, + bool* is_global_cache) { *has_system = false; *has_cache = false; // image_location = /system/framework/boot.art @@ -192,7 +193,7 @@ bool ImageSpace::FindImageFilename(const char* image_location, *dalvik_cache_exists = false; std::string dalvik_cache; GetDalvikCache(GetInstructionSetString(image_isa), true, &dalvik_cache, - &have_android_data, dalvik_cache_exists); + &have_android_data, dalvik_cache_exists, is_global_cache); if (have_android_data && *dalvik_cache_exists) { // Always set output location even if it does not exist, @@ -285,8 +286,9 @@ ImageHeader* ImageSpace::ReadImageHeaderOrDie(const char* image_location, std::string cache_filename; bool has_cache = false; bool dalvik_cache_exists = false; + bool is_global_cache = false; if (FindImageFilename(image_location, image_isa, &system_filename, &has_system, - &cache_filename, &dalvik_cache_exists, &has_cache)) { + &cache_filename, &dalvik_cache_exists, &has_cache, &is_global_cache)) { if (Runtime::Current()->ShouldRelocate()) { if (has_system && has_cache) { std::unique_ptr<ImageHeader> sys_hdr(new ImageHeader); @@ -344,6 +346,21 @@ static bool ChecksumsMatch(const char* image_a, const char* image_b) { && hdr_a.GetOatChecksum() == hdr_b.GetOatChecksum(); } +static bool ImageCreationAllowed(bool is_global_cache, std::string* error_msg) { + // Anyone can write into a "local" cache. + if (!is_global_cache) { + return true; + } + + // Only the zygote is allowed to create the global boot image. + if (Runtime::Current()->IsZygote()) { + return true; + } + + *error_msg = "Only the zygote can create the global boot image."; + return false; +} + ImageSpace* ImageSpace::Create(const char* image_location, const InstructionSet image_isa, std::string* error_msg) { @@ -352,9 +369,10 @@ ImageSpace* ImageSpace::Create(const char* image_location, std::string cache_filename; bool has_cache = false; bool dalvik_cache_exists = false; + bool is_global_cache = true; const bool found_image = FindImageFilename(image_location, image_isa, &system_filename, &has_system, &cache_filename, &dalvik_cache_exists, - &has_cache); + &has_cache, &is_global_cache); ImageSpace* space; bool relocate = Runtime::Current()->ShouldRelocate(); @@ -377,18 +395,27 @@ ImageSpace* ImageSpace::Create(const char* image_location, relocated_version_used = true; } else { // We cannot have a relocated version, Relocate the system one and use it. - if (can_compile && RelocateImage(image_location, cache_filename.c_str(), image_isa, - error_msg)) { + + std::string reason; + bool success; + + // Check whether we are allowed to relocate. + if (!can_compile) { + reason = "Image dex2oat disabled by -Xnoimage-dex2oat."; + success = false; + } else if (!ImageCreationAllowed(is_global_cache, &reason)) { + // Whether we can write to the cache. + success = false; + } else { + // Try to relocate. + success = RelocateImage(image_location, cache_filename.c_str(), image_isa, &reason); + } + + if (success) { relocated_version_used = true; image_filename = &cache_filename; } else { - std::string reason; - if (can_compile) { - reason = StringPrintf(": %s", error_msg->c_str()); - } else { - reason = " because image dex2oat is disabled."; - } - *error_msg = StringPrintf("Unable to relocate image '%s' from '%s' to '%s'%s", + *error_msg = StringPrintf("Unable to relocate image '%s' from '%s' to '%s': %s", image_location, system_filename.c_str(), cache_filename.c_str(), reason.c_str()); return nullptr; @@ -460,6 +487,8 @@ ImageSpace* ImageSpace::Create(const char* image_location, } else if (!dalvik_cache_exists) { *error_msg = StringPrintf("No place to put generated image."); return nullptr; + } else if (!ImageCreationAllowed(is_global_cache, error_msg)) { + return nullptr; } else if (!GenerateImage(cache_filename, image_isa, error_msg)) { *error_msg = StringPrintf("Failed to generate image '%s': %s", cache_filename.c_str(), error_msg->c_str()); diff --git a/runtime/gc/space/image_space.h b/runtime/gc/space/image_space.h index 28ebca6..2586ece 100644 --- a/runtime/gc/space/image_space.h +++ b/runtime/gc/space/image_space.h @@ -110,7 +110,8 @@ class ImageSpace : public MemMapSpace { bool* has_system, std::string* data_location, bool* dalvik_cache_exists, - bool* has_data); + bool* has_data, + bool *is_global_cache); private: // Tries to initialize an ImageSpace from the given image path, diff --git a/runtime/native/dalvik_system_DexFile.cc b/runtime/native/dalvik_system_DexFile.cc index ff9dc38..003815e 100644 --- a/runtime/native/dalvik_system_DexFile.cc +++ b/runtime/native/dalvik_system_DexFile.cc @@ -504,7 +504,9 @@ static jbyte IsDexOptNeededInternal(JNIEnv* env, const char* filename, std::string cache_dir; bool have_android_data = false; bool dalvik_cache_exists = false; - GetDalvikCache(instruction_set, false, &cache_dir, &have_android_data, &dalvik_cache_exists); + bool is_global_cache = false; + GetDalvikCache(instruction_set, false, &cache_dir, &have_android_data, &dalvik_cache_exists, + &is_global_cache); std::string cache_filename; // was cache_location bool have_cache_filename = false; if (dalvik_cache_exists) { diff --git a/runtime/runtime.cc b/runtime/runtime.cc index de8634f..8386cc0 100644 --- a/runtime/runtime.cc +++ b/runtime/runtime.cc @@ -564,13 +564,15 @@ static bool OpenDexFilesFromImage(const std::vector<std::string>& dex_filenames, std::string cache_filename_unused; bool dalvik_cache_exists_unused; bool has_cache_unused; + bool is_global_cache_unused; bool found_image = gc::space::ImageSpace::FindImageFilename(image_location.c_str(), kRuntimeISA, &system_filename, &has_system, &cache_filename_unused, &dalvik_cache_exists_unused, - &has_cache_unused); + &has_cache_unused, + &is_global_cache_unused); *failures = 0; if (!found_image || !has_system) { return false; diff --git a/runtime/utils.cc b/runtime/utils.cc index 6135e5d..9157f6c 100644 --- a/runtime/utils.cc +++ b/runtime/utils.cc @@ -1232,13 +1232,14 @@ const char* GetAndroidDataSafe(std::string* error_msg) { } void GetDalvikCache(const char* subdir, const bool create_if_absent, std::string* dalvik_cache, - bool* have_android_data, bool* dalvik_cache_exists) { + bool* have_android_data, bool* dalvik_cache_exists, bool* is_global_cache) { CHECK(subdir != nullptr); std::string error_msg; const char* android_data = GetAndroidDataSafe(&error_msg); if (android_data == nullptr) { *have_android_data = false; *dalvik_cache_exists = false; + *is_global_cache = false; return; } else { *have_android_data = true; @@ -1246,7 +1247,8 @@ void GetDalvikCache(const char* subdir, const bool create_if_absent, std::string const std::string dalvik_cache_root(StringPrintf("%s/dalvik-cache/", android_data)); *dalvik_cache = dalvik_cache_root + subdir; *dalvik_cache_exists = OS::DirectoryExists(dalvik_cache->c_str()); - if (create_if_absent && !*dalvik_cache_exists && strcmp(android_data, "/data") != 0) { + *is_global_cache = strcmp(android_data, "/data") == 0; + if (create_if_absent && !*dalvik_cache_exists && !*is_global_cache) { // Don't create the system's /data/dalvik-cache/... because it needs special permissions. *dalvik_cache_exists = ((mkdir(dalvik_cache_root.c_str(), 0700) == 0 || errno == EEXIST) && (mkdir(dalvik_cache->c_str(), 0700) == 0 || errno == EEXIST)); diff --git a/runtime/utils.h b/runtime/utils.h index 50462b1..9ec6db1 100644 --- a/runtime/utils.h +++ b/runtime/utils.h @@ -449,8 +449,9 @@ std::string GetDalvikCacheOrDie(const char* subdir, bool create_if_absent = true // Return true if we found the dalvik cache and stored it in the dalvik_cache argument. // have_android_data will be set to true if we have an ANDROID_DATA that exists, // dalvik_cache_exists will be true if there is a dalvik-cache directory that is present. +// The flag is_global_cache tells whether this cache is /data/dalvik-cache. void GetDalvikCache(const char* subdir, bool create_if_absent, std::string* dalvik_cache, - bool* have_android_data, bool* dalvik_cache_exists); + bool* have_android_data, bool* dalvik_cache_exists, bool* is_global_cache); // Returns the absolute dalvik-cache path for a DexFile or OatFile. The path returned will be // rooted at cache_location. |