diff options
author | Andreas Gampe <agampe@google.com> | 2014-10-28 02:08:03 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2014-10-28 02:08:03 +0000 |
commit | 11bd683f6dbebe2f3d02fa383fc9dbc69a83ace8 (patch) | |
tree | 3b3df2099dc063f48676c92b94dc4532cfb7a9e6 | |
parent | 79027f6204f77db4ba3bd3ceab1f07240fbbfdb3 (diff) | |
parent | 7ba649636c4475c3992fa15a57acd2546d69ff38 (diff) | |
download | art-11bd683f6dbebe2f3d02fa383fc9dbc69a83ace8.zip art-11bd683f6dbebe2f3d02fa383fc9dbc69a83ace8.tar.gz art-11bd683f6dbebe2f3d02fa383fc9dbc69a83ace8.tar.bz2 |
Merge "ART: Add pic flag to oat header store"
-rw-r--r-- | dex2oat/dex2oat.cc | 27 | ||||
-rw-r--r-- | runtime/class_linker.cc | 76 | ||||
-rw-r--r-- | runtime/class_linker.h | 5 | ||||
-rw-r--r-- | runtime/oat.h | 1 | ||||
-rw-r--r-- | runtime/oat_file.cc | 8 | ||||
-rw-r--r-- | runtime/oat_file.h | 2 |
6 files changed, 65 insertions, 54 deletions
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc index 98712cd..1eb5718 100644 --- a/dex2oat/dex2oat.cc +++ b/dex2oat/dex2oat.cc @@ -774,7 +774,7 @@ void ParseDouble(const std::string& option, char after_char, *parsed_value = value; } -static int dex2oat(int argc, char** argv) { +static void b13564922() { #if defined(__linux__) && defined(__arm__) int major, minor; struct utsname uts; @@ -792,6 +792,10 @@ static int dex2oat(int argc, char** argv) { } } #endif +} + +static int dex2oat(int argc, char** argv) { + b13564922(); original_argc = argc; original_argv = argv; @@ -1414,17 +1418,20 @@ static int dex2oat(int argc, char** argv) { new SafeMap<std::string, std::string>()); // Insert some compiler things. - std::ostringstream oss; - for (int i = 0; i < argc; ++i) { - if (i > 0) { - oss << ' '; + { + std::ostringstream oss; + for (int i = 0; i < argc; ++i) { + if (i > 0) { + oss << ' '; + } + oss << argv[i]; } - oss << argv[i]; + key_value_store->Put(OatHeader::kDex2OatCmdLineKey, oss.str()); + oss.str(""); // Reset. + oss << kRuntimeISA; + key_value_store->Put(OatHeader::kDex2OatHostKey, oss.str()); + key_value_store->Put(OatHeader::kPicKey, compile_pic ? "true" : "false"); } - key_value_store->Put(OatHeader::kDex2OatCmdLineKey, oss.str()); - oss.str(""); // Reset. - oss << kRuntimeISA; - key_value_store->Put(OatHeader::kDex2OatHostKey, oss.str()); dex2oat->Compile(boot_image_option, dex_files, diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index 3513a6f..1676eaf 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -1345,11 +1345,11 @@ const OatFile* ClassLinker::OpenOatFileFromDexLocation(const std::string& dex_lo bool odex_checksum_verified = false; bool have_system_odex = false; { - // There is a high probability that these both these oat files map similar/the same address + // There is a high probability that both these oat files map similar/the same address // spaces so we must scope them like this so they each gets its turn. std::unique_ptr<OatFile> odex_oat_file(OatFile::Open(odex_filename, odex_filename, nullptr, executable, &odex_error_msg)); - if (odex_oat_file.get() != nullptr && CheckOatFile(odex_oat_file.get(), isa, + if (odex_oat_file.get() != nullptr && CheckOatFile(runtime, odex_oat_file.get(), isa, &odex_checksum_verified, &odex_error_msg)) { return odex_oat_file.release(); @@ -1371,7 +1371,7 @@ const OatFile* ClassLinker::OpenOatFileFromDexLocation(const std::string& dex_lo if (have_dalvik_cache) { std::unique_ptr<OatFile> cache_oat_file(OatFile::Open(cache_filename, cache_filename, nullptr, executable, &cache_error_msg)); - if (cache_oat_file.get() != nullptr && CheckOatFile(cache_oat_file.get(), isa, + if (cache_oat_file.get() != nullptr && CheckOatFile(runtime, cache_oat_file.get(), isa, &cache_checksum_verified, &cache_error_msg)) { return cache_oat_file.release(); @@ -1465,13 +1465,15 @@ const OatFile* ClassLinker::PatchAndRetrieveOat(const std::string& input_oat, const std::string& image_location, InstructionSet isa, std::string* error_msg) { - if (!Runtime::Current()->GetHeap()->HasImageSpace()) { + Runtime* runtime = Runtime::Current(); + DCHECK(runtime != nullptr); + if (!runtime->GetHeap()->HasImageSpace()) { // We don't have an image space so there is no point in trying to patchoat. LOG(WARNING) << "Patching of oat file '" << input_oat << "' not attempted because we are " << "running without an image. Attempting to use oat file for interpretation."; return GetInterpretedOnlyOat(input_oat, isa, error_msg); } - if (!Runtime::Current()->IsDex2OatEnabled()) { + if (!runtime->IsDex2OatEnabled()) { // We don't have dex2oat so we can assume we don't have patchoat either. We should just use the // input_oat but make sure we only do interpretation on it's dex files. LOG(WARNING) << "Patching of oat file '" << input_oat << "' not attempted due to dex2oat being " @@ -1479,7 +1481,7 @@ const OatFile* ClassLinker::PatchAndRetrieveOat(const std::string& input_oat, return GetInterpretedOnlyOat(input_oat, isa, error_msg); } Locks::mutator_lock_->AssertNotHeld(Thread::Current()); // Avoid starving GC. - std::string patchoat(Runtime::Current()->GetPatchoatExecutable()); + std::string patchoat(runtime->GetPatchoatExecutable()); std::string isa_arg("--instruction-set="); isa_arg += GetInstructionSetString(isa); @@ -1502,9 +1504,10 @@ const OatFile* ClassLinker::PatchAndRetrieveOat(const std::string& input_oat, bool success = Exec(argv, error_msg); if (success) { std::unique_ptr<OatFile> output(OatFile::Open(output_oat, output_oat, nullptr, - !Runtime::Current()->IsCompiler(), error_msg)); + !runtime->IsCompiler(), error_msg)); bool checksum_verified = false; - if (output.get() != nullptr && CheckOatFile(output.get(), isa, &checksum_verified, error_msg)) { + if (output.get() != nullptr && CheckOatFile(runtime, output.get(), isa, &checksum_verified, + error_msg)) { return output.release(); } else if (output.get() != nullptr) { *error_msg = StringPrintf("Patching of oat file '%s' succeeded " @@ -1515,7 +1518,7 @@ const OatFile* ClassLinker::PatchAndRetrieveOat(const std::string& input_oat, "but was unable to open output file '%s': %s", input_oat.c_str(), output_oat.c_str(), error_msg->c_str()); } - } else if (!Runtime::Current()->IsCompiler()) { + } else if (!runtime->IsCompiler()) { // patchoat failed which means we probably don't have enough room to place the output oat file, // instead of failing we should just run the interpreter from the dex files in the input oat. LOG(WARNING) << "Patching of oat file '" << input_oat << "' failed. Attempting to use oat file " @@ -1529,27 +1532,9 @@ const OatFile* ClassLinker::PatchAndRetrieveOat(const std::string& input_oat, return nullptr; } -int32_t ClassLinker::GetRequiredDelta(const OatFile* oat_file, InstructionSet isa) { - Runtime* runtime = Runtime::Current(); - int32_t real_patch_delta; - const gc::space::ImageSpace* image_space = runtime->GetHeap()->GetImageSpace(); - CHECK(image_space != nullptr); - if (isa == Runtime::Current()->GetInstructionSet()) { - const ImageHeader& image_header = image_space->GetImageHeader(); - real_patch_delta = image_header.GetPatchDelta(); - } else { - std::unique_ptr<ImageHeader> image_header(gc::space::ImageSpace::ReadImageHeaderOrDie( - image_space->GetImageLocation().c_str(), isa)); - real_patch_delta = image_header->GetPatchDelta(); - } - const OatHeader& oat_header = oat_file->GetOatHeader(); - return real_patch_delta - oat_header.GetImagePatchDelta(); -} - -bool ClassLinker::CheckOatFile(const OatFile* oat_file, InstructionSet isa, +bool ClassLinker::CheckOatFile(const Runtime* runtime, const OatFile* oat_file, InstructionSet isa, bool* checksum_verified, std::string* error_msg) { - Runtime* runtime = Runtime::Current(); const gc::space::ImageSpace* image_space = runtime->GetHeap()->GetImageSpace(); if (image_space == nullptr) { *error_msg = "No image space present"; @@ -1581,19 +1566,30 @@ bool ClassLinker::CheckOatFile(const OatFile* oat_file, InstructionSet isa, real_image_checksum, oat_image_checksum); } - void* oat_image_oat_offset = - reinterpret_cast<void*>(oat_header.GetImageFileLocationOatDataBegin()); - bool offset_verified = oat_image_oat_offset == real_image_oat_offset; - if (!offset_verified) { - StringAppendF(&compound_msg, " Oat Image oat offset incorrect (expected 0x%p, received 0x%p)", - real_image_oat_offset, oat_image_oat_offset); - } + bool offset_verified; + bool patch_delta_verified; + + if (!oat_file->IsPic()) { + // If an oat file is not PIC, we need to check that the image is at the expected location and + // patched in the same way. + void* oat_image_oat_offset = + reinterpret_cast<void*>(oat_header.GetImageFileLocationOatDataBegin()); + offset_verified = oat_image_oat_offset == real_image_oat_offset; + if (!offset_verified) { + StringAppendF(&compound_msg, " Oat Image oat offset incorrect (expected 0x%p, received 0x%p)", + real_image_oat_offset, oat_image_oat_offset); + } - int32_t oat_patch_delta = oat_header.GetImagePatchDelta(); - bool patch_delta_verified = oat_patch_delta == real_patch_delta; - if (!patch_delta_verified) { - StringAppendF(&compound_msg, " Oat image patch delta incorrect (expected 0x%x, received 0x%x)", - real_patch_delta, oat_patch_delta); + int32_t oat_patch_delta = oat_header.GetImagePatchDelta(); + patch_delta_verified = oat_patch_delta == real_patch_delta; + if (!patch_delta_verified) { + StringAppendF(&compound_msg, " Oat image patch delta incorrect (expected 0x%x, " + "received 0x%x)", real_patch_delta, oat_patch_delta); + } + } else { + // If an oat file is PIC, we ignore offset and patching delta. + offset_verified = true; + patch_delta_verified = true; } bool ret = (*checksum_verified && offset_verified && patch_delta_verified); diff --git a/runtime/class_linker.h b/runtime/class_linker.h index 51cd730..8034d62 100644 --- a/runtime/class_linker.h +++ b/runtime/class_linker.h @@ -50,8 +50,8 @@ namespace mirror { template<class T> class Handle; class InternTable; template<class T> class ObjectLock; +class Runtime; class ScopedObjectAccessAlreadyRunnable; -template<class T> class Handle; template<size_t kNumReferences> class PACKED(4) StackHandleScope; typedef bool (ClassVisitor)(mirror::Class* c, void* arg); @@ -631,9 +631,8 @@ class ClassLinker { std::string* error_msg) LOCKS_EXCLUDED(Locks::mutator_lock_); - bool CheckOatFile(const OatFile* oat_file, InstructionSet isa, + bool CheckOatFile(const Runtime* runtime, const OatFile* oat_file, InstructionSet isa, bool* checksum_verified, std::string* error_msg); - int32_t GetRequiredDelta(const OatFile* oat_file, InstructionSet isa); // Note: will not register the oat file. const OatFile* FindOatFileInOatLocationForDexFile(const char* dex_location, diff --git a/runtime/oat.h b/runtime/oat.h index 92b98b1..5de4403 100644 --- a/runtime/oat.h +++ b/runtime/oat.h @@ -35,6 +35,7 @@ class PACKED(4) OatHeader { static constexpr const char* kImageLocationKey = "image-location"; static constexpr const char* kDex2OatCmdLineKey = "dex2oat-cmdline"; static constexpr const char* kDex2OatHostKey = "dex2oat-host"; + static constexpr const char* kPicKey = "pic"; static OatHeader* Create(InstructionSet instruction_set, const InstructionSetFeatures* instruction_set_features, diff --git a/runtime/oat_file.cc b/runtime/oat_file.cc index 03a398e..0f0e33c 100644 --- a/runtime/oat_file.cc +++ b/runtime/oat_file.cc @@ -72,7 +72,7 @@ OatFile* OatFile::Open(const std::string& filename, bool executable, std::string* error_msg) { CHECK(!filename.empty()) << location; - CheckLocation(filename); + CheckLocation(location); std::unique_ptr<OatFile> ret; if (kUsePortableCompiler && executable) { // If we are using PORTABLE, use dlopen to deal with relocations. @@ -592,4 +592,10 @@ void OatFile::OatMethod::LinkMethod(mirror::ArtMethod* method) const { method->SetNativeGcMap(GetNativeGcMap()); // Used by native methods in work around JNI mode. } +bool OatFile::IsPic() const { + const char* pic_string = GetOatHeader().GetStoreValueByKey(OatHeader::kPicKey); + return (pic_string != nullptr && strncmp(pic_string, "true", 5) == 0); + // TODO: Check against oat_patches. b/18144996 +} + } // namespace art diff --git a/runtime/oat_file.h b/runtime/oat_file.h index 734b9b3..ad6871d 100644 --- a/runtime/oat_file.h +++ b/runtime/oat_file.h @@ -72,6 +72,8 @@ class OatFile { return is_executable_; } + bool IsPic() const; + ElfFile* GetElfFile() const { CHECK_NE(reinterpret_cast<uintptr_t>(elf_file_.get()), reinterpret_cast<uintptr_t>(nullptr)) << "Cannot get an elf file from " << GetLocation(); |