Add oatdump support for app images
Example usage on host:
oatdumpd --app-oat=art/plus32.odex --app-image=art/plus32.art
--image=art/oats/system@framework@boot.art --instruction-set=arm
TODO: Add to oatdump test.
Bug: 27408512
Bug: 22858531
(cherry picked from commit bcb6a72569a1401b36a3ad3b6aa4d13e29966cf0)
Change-Id: I9d1aa7eaa16795e5fbabc6974d245849e16b1d03
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index d51a1f7..52beb15 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -1462,6 +1462,64 @@
const bool forward_strings_;
};
+static std::unique_ptr<const DexFile> OpenOatDexFile(const OatFile* oat_file,
+ const char* location,
+ std::string* error_msg)
+ SHARED_REQUIRES(Locks::mutator_lock_) {
+ DCHECK(error_msg != nullptr);
+ std::unique_ptr<const DexFile> dex_file;
+ const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(location, nullptr);
+ if (oat_dex_file == nullptr) {
+ *error_msg = StringPrintf("Failed finding oat dex file for %s %s",
+ oat_file->GetLocation().c_str(),
+ location);
+ return std::unique_ptr<const DexFile>();
+ }
+ std::string inner_error_msg;
+ dex_file = oat_dex_file->OpenDexFile(&inner_error_msg);
+ if (dex_file == nullptr) {
+ *error_msg = StringPrintf("Failed to open dex file %s from within oat file %s error '%s'",
+ location,
+ oat_file->GetLocation().c_str(),
+ inner_error_msg.c_str());
+ return std::unique_ptr<const DexFile>();
+ }
+
+ if (dex_file->GetLocationChecksum() != oat_dex_file->GetDexFileLocationChecksum()) {
+ *error_msg = StringPrintf("Checksums do not match for %s: %x vs %x",
+ location,
+ dex_file->GetLocationChecksum(),
+ oat_dex_file->GetDexFileLocationChecksum());
+ return std::unique_ptr<const DexFile>();
+ }
+ return dex_file;
+}
+
+bool ClassLinker::OpenImageDexFiles(gc::space::ImageSpace* space,
+ std::vector<std::unique_ptr<const DexFile>>* out_dex_files,
+ std::string* error_msg) {
+ ScopedAssertNoThreadSuspension nts(Thread::Current(), __FUNCTION__);
+ const ImageHeader& header = space->GetImageHeader();
+ mirror::Object* dex_caches_object = header.GetImageRoot(ImageHeader::kDexCaches);
+ DCHECK(dex_caches_object != nullptr);
+ mirror::ObjectArray<mirror::DexCache>* dex_caches =
+ dex_caches_object->AsObjectArray<mirror::DexCache>();
+ const OatFile* oat_file = space->GetOatFile();
+ for (int32_t i = 0; i < dex_caches->GetLength(); i++) {
+ mirror::DexCache* dex_cache = dex_caches->Get(i);
+ std::string dex_file_location(dex_cache->GetLocation()->ToModifiedUtf8());
+ std::unique_ptr<const DexFile> dex_file = OpenOatDexFile(oat_file,
+ dex_file_location.c_str(),
+ error_msg);
+ if (dex_file == nullptr) {
+ return false;
+ }
+ dex_cache->SetDexFile(dex_file.get());
+ out_dex_files->push_back(std::move(dex_file));
+ }
+ return true;
+}
+
bool ClassLinker::AddImageSpace(
gc::space::ImageSpace* space,
Handle<mirror::ClassLoader> class_loader,
@@ -1528,29 +1586,10 @@
dex_location_path = dex_location_path.substr(0, pos + 1); // Keep trailing '/'
dex_file_location = dex_location_path + dex_file_location;
}
- const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(dex_file_location.c_str(),
- nullptr);
- if (oat_dex_file == nullptr) {
- *error_msg = StringPrintf("Failed finding oat dex file for %s %s",
- oat_file->GetLocation().c_str(),
- dex_file_location.c_str());
- return false;
- }
- std::string inner_error_msg;
- std::unique_ptr<const DexFile> dex_file = oat_dex_file->OpenDexFile(&inner_error_msg);
+ std::unique_ptr<const DexFile> dex_file = OpenOatDexFile(oat_file,
+ dex_file_location.c_str(),
+ error_msg);
if (dex_file == nullptr) {
- *error_msg = StringPrintf("Failed to open dex file %s from within oat file %s error '%s'",
- dex_file_location.c_str(),
- oat_file->GetLocation().c_str(),
- inner_error_msg.c_str());
- return false;
- }
-
- if (dex_file->GetLocationChecksum() != oat_dex_file->GetDexFileLocationChecksum()) {
- *error_msg = StringPrintf("Checksums do not match for %s: %x vs %x",
- dex_file_location.c_str(),
- dex_file->GetLocationChecksum(),
- oat_dex_file->GetDexFileLocationChecksum());
return false;
}