summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Gampe <agampe@google.com>2014-10-28 02:08:03 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2014-10-28 02:08:03 +0000
commit11bd683f6dbebe2f3d02fa383fc9dbc69a83ace8 (patch)
tree3b3df2099dc063f48676c92b94dc4532cfb7a9e6
parent79027f6204f77db4ba3bd3ceab1f07240fbbfdb3 (diff)
parent7ba649636c4475c3992fa15a57acd2546d69ff38 (diff)
downloadart-11bd683f6dbebe2f3d02fa383fc9dbc69a83ace8.zip
art-11bd683f6dbebe2f3d02fa383fc9dbc69a83ace8.tar.gz
art-11bd683f6dbebe2f3d02fa383fc9dbc69a83ace8.tar.bz2
Merge "ART: Add pic flag to oat header store"
-rw-r--r--dex2oat/dex2oat.cc27
-rw-r--r--runtime/class_linker.cc76
-rw-r--r--runtime/class_linker.h5
-rw-r--r--runtime/oat.h1
-rw-r--r--runtime/oat_file.cc8
-rw-r--r--runtime/oat_file.h2
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();