summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dexlayout/dex_writer.cc13
-rw-r--r--dexlayout/dexlayout.cc3
-rw-r--r--openjdkjvmti/Android.bp2
-rw-r--r--openjdkjvmti/fixed_up_dex_file.cc29
-rw-r--r--runtime/dex/dex_file_verifier.cc17
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;
}