diff options
| -rw-r--r-- | dexlayout/dex_writer.cc | 13 | ||||
| -rw-r--r-- | dexlayout/dexlayout.cc | 3 | ||||
| -rw-r--r-- | openjdkjvmti/Android.bp | 2 | ||||
| -rw-r--r-- | openjdkjvmti/fixed_up_dex_file.cc | 29 | ||||
| -rw-r--r-- | runtime/dex/dex_file_verifier.cc | 17 |
5 files changed, 51 insertions, 13 deletions
diff --git a/dexlayout/dex_writer.cc b/dexlayout/dex_writer.cc index a18a2cfd8a..489a6b15ba 100644 --- a/dexlayout/dex_writer.cc +++ b/dexlayout/dex_writer.cc @@ -774,9 +774,16 @@ uint32_t DexWriter::GenerateAndWriteMapItems(uint32_t offset) { void DexWriter::WriteHeader() { StandardDexFile::Header header; - static constexpr size_t kMagicAndVersionLen = - StandardDexFile::kDexMagicSize + StandardDexFile::kDexVersionLen; - std::copy_n(header_->Magic(), kMagicAndVersionLen, header.magic_); + if (CompactDexFile::IsMagicValid(header_->Magic())) { + StandardDexFile::WriteMagic(header.magic_); + // TODO: Should we write older versions based on the feature flags? + StandardDexFile::WriteCurrentVersion(header.magic_); + } else { + // Standard dex -> standard dex, just reuse the same header. + static constexpr size_t kMagicAndVersionLen = + StandardDexFile::kDexMagicSize + StandardDexFile::kDexVersionLen; + std::copy_n(header_->Magic(), kMagicAndVersionLen, header.magic_); + } header.checksum_ = header_->Checksum(); std::copy_n(header_->Signature(), DexFile::kSha1DigestSize, header.signature_); header.file_size_ = header_->FileSize(); diff --git a/dexlayout/dexlayout.cc b/dexlayout/dexlayout.cc index 47a3e943a5..000d1356b9 100644 --- a/dexlayout/dexlayout.cc +++ b/dexlayout/dexlayout.cc @@ -1912,7 +1912,8 @@ void DexLayout::ProcessDexFile(const char* file_name, if (do_layout) { LayoutOutputFile(dex_file); } - OutputDexFile(dex_file, do_layout); + // If we didn't set the offsets eagerly, we definitely need to compute them here. + OutputDexFile(dex_file, do_layout || !eagerly_assign_offsets); // Clear header before verifying to reduce peak RAM usage. const size_t file_size = header_->FileSize(); diff --git a/openjdkjvmti/Android.bp b/openjdkjvmti/Android.bp index 9ba7068176..0283999d54 100644 --- a/openjdkjvmti/Android.bp +++ b/openjdkjvmti/Android.bp @@ -68,6 +68,7 @@ art_cc_library { shared_libs: [ "libart", "libart-compiler", + "libart-dexlayout", ], } @@ -80,5 +81,6 @@ art_cc_library { shared_libs: [ "libartd", "libartd-compiler", + "libartd-dexlayout", ], } diff --git a/openjdkjvmti/fixed_up_dex_file.cc b/openjdkjvmti/fixed_up_dex_file.cc index ad928d9b37..da7d60ac2f 100644 --- a/openjdkjvmti/fixed_up_dex_file.cc +++ b/openjdkjvmti/fixed_up_dex_file.cc @@ -34,7 +34,9 @@ #include "dex/dex_file_loader.h" // Runtime includes. +#include "dex/compact_dex_level.h" #include "dex_to_dex_decompiler.h" +#include "dexlayout.h" #include "oat_file.h" #include "vdex_file.h" @@ -85,6 +87,33 @@ std::unique_ptr<FixedUpDexFile> FixedUpDexFile::Create(const art::DexFile& origi } DoDexUnquicken(*new_dex_file, original); + + if (original.IsCompactDexFile()) { + // Since we are supposed to return a standard dex, convert back using dexlayout. + art::Options options; + options.output_to_memmap_ = true; + options.compact_dex_level_ = art::CompactDexLevel::kCompactDexLevelNone; + options.update_checksum_ = true; + art::DexLayout dex_layout(options, nullptr, nullptr); + dex_layout.ProcessDexFile(new_dex_file->GetLocation().c_str(), new_dex_file.get(), 0); + std::unique_ptr<art::MemMap> mem_map(dex_layout.GetAndReleaseMemMap()); + + const uint32_t dex_file_size = + reinterpret_cast<const art::DexFile::Header*>(mem_map->Begin())->file_size_; + // Overwrite the dex file stored in data with the new result. + data.clear(); + data.insert(data.end(), mem_map->Begin(), mem_map->Begin() + dex_file_size); + new_dex_file = art::DexFileLoader::Open( + data.data(), + data.size(), + /*location*/"Unquickening_dexfile.dex", + /*location_checksum*/0, + /*oat_dex_file*/nullptr, + /*verify*/false, + /*verify_checksum*/false, + &error); + } + RecomputeDexChecksum(const_cast<art::DexFile*>(new_dex_file.get())); std::unique_ptr<FixedUpDexFile> ret(new FixedUpDexFile(std::move(new_dex_file), std::move(data))); return ret; diff --git a/runtime/dex/dex_file_verifier.cc b/runtime/dex/dex_file_verifier.cc index c2f772ef25..7265aad1ba 100644 --- a/runtime/dex/dex_file_verifier.cc +++ b/runtime/dex/dex_file_verifier.cc @@ -386,15 +386,14 @@ bool DexFileVerifier::CheckHeader() { return false; } - bool size_matches = false; - if (dex_file_->IsCompactDexFile()) { - size_matches = header_->header_size_ == sizeof(CompactDexFile::Header); - } else { - size_matches = header_->header_size_ == sizeof(StandardDexFile::Header); - } - - if (!size_matches) { - ErrorStringPrintf("Bad header size: %ud", header_->header_size_); + const uint32_t expected_header_size = dex_file_->IsCompactDexFile() + ? sizeof(CompactDexFile::Header) + : sizeof(StandardDexFile::Header); + + if (header_->header_size_ != expected_header_size) { + ErrorStringPrintf("Bad header size: %ud expected %ud", + header_->header_size_, + expected_header_size); return false; } |