Revert "Revert "Don't embed the dex code in the oat file if dex is uncompressed.""
Bug: 63920015
Bug: 70854754
Test: oat_writer_test.cc, test.py
Revert was due to userdebug/user differences, which is fixed with:
https://googleplex-android-review.googlesource.com/#/c/platform/build/+/3434091/
This CL also fixes oatdump when the dex code is not in the .vdex file.
This reverts commit e166e67666bf4b23e4ed0a98f5e2bb3cae9cee7d.
Change-Id: Iec924be2ff8f03cf2ebe306e7a0018241f33beb0
diff --git a/runtime/oat_file.cc b/runtime/oat_file.cc
index c03dbcc..9fd9905 100644
--- a/runtime/oat_file.cc
+++ b/runtime/oat_file.cc
@@ -620,14 +620,6 @@
dex_file_location.c_str());
return false;
}
- if (UNLIKELY(dex_file_offset == 0U)) {
- *error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu for '%s' with zero dex "
- "file offset",
- GetLocation().c_str(),
- i,
- dex_file_location.c_str());
- return false;
- }
if (UNLIKELY(dex_file_offset > DexSize())) {
*error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu for '%s' with dex file "
"offset %u > %zu",
@@ -638,20 +630,45 @@
DexSize());
return false;
}
- if (UNLIKELY(DexSize() - dex_file_offset < sizeof(DexFile::Header))) {
- *error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu for '%s' with dex file "
- "offset %u of %zu but the size of dex file header is %zu",
- GetLocation().c_str(),
- i,
- dex_file_location.c_str(),
- dex_file_offset,
- DexSize(),
- sizeof(DexFile::Header));
- return false;
+ const uint8_t* dex_file_pointer = nullptr;
+ if (UNLIKELY(dex_file_offset == 0U)) {
+ if (uncompressed_dex_files_ == nullptr) {
+ uncompressed_dex_files_.reset(new std::vector<std::unique_ptr<const DexFile>>());
+ // No dex files, load it from location.
+ const ArtDexFileLoader dex_file_loader;
+ if (!dex_file_loader.Open(dex_file_location.c_str(),
+ dex_file_location,
+ /* verify */ false,
+ /* verify_checksum */ false,
+ error_msg,
+ uncompressed_dex_files_.get())) {
+ if (Runtime::Current() == nullptr) {
+ // If there's no runtime, we're running oatdump, so return
+ // a half constructed oat file that oatdump knows how to deal with.
+ LOG(WARNING) << "Could not find associated dex files of oat file. "
+ << "Oatdump will only dump the header.";
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+ dex_file_pointer = uncompressed_dex_files_.get()->at(i)->Begin();
+ } else {
+ if (UNLIKELY(DexSize() - dex_file_offset < sizeof(DexFile::Header))) {
+ *error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu for '%s' with dex file "
+ "offset %u of %zu but the size of dex file header is %zu",
+ GetLocation().c_str(),
+ i,
+ dex_file_location.c_str(),
+ dex_file_offset,
+ DexSize(),
+ sizeof(DexFile::Header));
+ return false;
+ }
+ dex_file_pointer = DexBegin() + dex_file_offset;
}
- const uint8_t* dex_file_pointer = DexBegin() + dex_file_offset;
-
const bool valid_magic = DexFileLoader::IsMagicValid(dex_file_pointer);
if (UNLIKELY(!valid_magic)) {
*error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu for '%s' with invalid "
@@ -672,7 +689,7 @@
return false;
}
const DexFile::Header* header = reinterpret_cast<const DexFile::Header*>(dex_file_pointer);
- if (DexSize() - dex_file_offset < header->file_size_) {
+ if (dex_file_offset != 0 && (DexSize() - dex_file_offset < header->file_size_)) {
*error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu for '%s' with dex file "
"offset %u and size %u truncated at %zu",
GetLocation().c_str(),
@@ -1297,13 +1314,15 @@
std::string OatFile::ResolveRelativeEncodedDexLocation(
const char* abs_dex_location, const std::string& rel_dex_location) {
- if (abs_dex_location != nullptr && rel_dex_location[0] != '/') {
+ // For host, we still do resolution as the rel_dex_location might be absolute
+ // for a target dex (for example /system/foo/foo.apk).
+ if (abs_dex_location != nullptr && (rel_dex_location[0] != '/' || !kIsTargetBuild)) {
// Strip :classes<N>.dex used for secondary multidex files.
std::string base = DexFileLoader::GetBaseLocation(rel_dex_location);
std::string multidex_suffix = DexFileLoader::GetMultiDexSuffix(rel_dex_location);
// Check if the base is a suffix of the provided abs_dex_location.
- std::string target_suffix = "/" + base;
+ std::string target_suffix = ((rel_dex_location[0] != '/') ? "/" : "") + base;
std::string abs_location(abs_dex_location);
if (abs_location.size() > target_suffix.size()) {
size_t pos = abs_location.size() - target_suffix.size();