Refactor DexFileLoader
The first parameter of the Open methods specifies the data source,
that we intend to load the dex file(s) from. This creates large number
of overloads when multiplied by diversity of the other arguments.
Move the data source parameters to the constructor of DexFileLoader.
Specifically, the constructor just creates the right DexFileContainer,
and the rest of the loader is independent of the data source used.
This removes large amount of the overloads as well as large amount
of copy-pasted code. Majority of ArtDexFileLoader has been removed.
Bug: 266950186
Test: ./art/test.py -b --host --optimizing --64
Change-Id: I6580b49e65441eec93a7e0124be23bd8c859904a
diff --git a/dex2oat/dex2oat_test.cc b/dex2oat/dex2oat_test.cc
index 0099ba3..fd321e4 100644
--- a/dex2oat/dex2oat_test.cc
+++ b/dex2oat/dex2oat_test.cc
@@ -619,9 +619,9 @@
const char* location = dex_location.c_str();
std::string error_msg;
std::vector<std::unique_ptr<const DexFile>> dex_files;
- const ArtDexFileLoader dex_file_loader;
+ ArtDexFileLoader dex_file_loader(location);
ASSERT_TRUE(dex_file_loader.Open(
- location, location, /*verify=*/true, /*verify_checksum=*/true, &error_msg, &dex_files));
+ /*verify=*/true, /*verify_checksum=*/true, &error_msg, &dex_files));
EXPECT_EQ(dex_files.size(), 1U);
std::unique_ptr<const DexFile>& dex_file = dex_files[0];
@@ -811,9 +811,9 @@
const char* location = dex_location.c_str();
std::vector<std::unique_ptr<const DexFile>> dex_files;
- const ArtDexFileLoader dex_file_loader;
+ ArtDexFileLoader dex_file_loader(location);
ASSERT_TRUE(dex_file_loader.Open(
- location, location, /*verify=*/ true, /*verify_checksum=*/ true, &error_msg, &dex_files));
+ /*verify=*/true, /*verify_checksum=*/true, &error_msg, &dex_files));
EXPECT_EQ(dex_files.size(), 1U);
std::unique_ptr<const DexFile>& old_dex_file = dex_files[0];
diff --git a/dex2oat/linker/oat_writer.cc b/dex2oat/linker/oat_writer.cc
index 6b4b0ca..c2fa67e 100644
--- a/dex2oat/linker/oat_writer.cc
+++ b/dex2oat/linker/oat_writer.cc
@@ -462,11 +462,9 @@
bool OatWriter::AddDexFileSource(File&& dex_file_fd, const char* location) {
DCHECK(write_state_ == WriteState::kAddingDexFileSources);
std::string error_msg;
- const ArtDexFileLoader loader;
+ ArtDexFileLoader loader(dex_file_fd.Release(), location);
std::vector<std::unique_ptr<const DexFile>> dex_files;
- if (!loader.Open(dex_file_fd.Release(),
- location,
- /*verify=*/false,
+ if (!loader.Open(/*verify=*/false,
/*verify_checksum=*/false,
&error_msg,
&dex_files)) {
@@ -524,11 +522,8 @@
uint32_t location_checksum) {
DCHECK(write_state_ == WriteState::kAddingDexFileSources);
std::string error_msg;
- const ArtDexFileLoader loader;
- auto dex_file = loader.Open(data.data(),
- data.size(),
- location,
- location_checksum,
+ ArtDexFileLoader loader(data.data(), data.size(), location);
+ auto dex_file = loader.Open(location_checksum,
nullptr,
/*verify=*/false,
/*verify_checksum=*/false,
@@ -3187,7 +3182,8 @@
if (copy_dex_files == CopyOption::kOnlyIfCompressed) {
extract_dex_files_into_vdex_ = false;
for (OatDexFile& oat_dex_file : oat_dex_files_) {
- if (!oat_dex_file.GetDexFile()->GetContainer()->IsDirectMmap()) {
+ const DexFileContainer* container = oat_dex_file.GetDexFile()->GetContainer();
+ if (!(container->IsZip() && container->IsFileMap())) {
extract_dex_files_into_vdex_ = true;
break;
}
@@ -3468,7 +3464,6 @@
DCHECK_EQ(opened_dex_files_map->size(), 1u);
DCHECK(vdex_begin_ == opened_dex_files_map->front().Begin());
- const ArtDexFileLoader dex_file_loader;
std::vector<std::unique_ptr<const DexFile>> dex_files;
for (OatDexFile& oat_dex_file : oat_dex_files_) {
const uint8_t* raw_dex_file = vdex_begin_ + oat_dex_file.dex_file_offset_;
@@ -3490,10 +3485,9 @@
// Now, open the dex file.
std::string error_msg;
- dex_files.emplace_back(dex_file_loader.Open(raw_dex_file,
- oat_dex_file.dex_file_size_,
- oat_dex_file.GetLocation(),
- oat_dex_file.dex_file_location_checksum_,
+ ArtDexFileLoader dex_file_loader(
+ raw_dex_file, oat_dex_file.dex_file_size_, oat_dex_file.GetLocation());
+ dex_files.emplace_back(dex_file_loader.Open(oat_dex_file.dex_file_location_checksum_,
/* oat_dex_file */ nullptr,
verify,
verify,
diff --git a/dexdump/dexdump.cc b/dexdump/dexdump.cc
index 2ab98ec..7e4c1a6 100644
--- a/dexdump/dexdump.cc
+++ b/dexdump/dexdump.cc
@@ -1962,18 +1962,12 @@
LOG(ERROR) << "ReadFileToString failed";
return -1;
}
- const DexFileLoader dex_file_loader;
DexFileLoaderErrorCode error_code;
std::string error_msg;
std::vector<std::unique_ptr<const DexFile>> dex_files;
- if (!dex_file_loader.OpenAll(reinterpret_cast<const uint8_t*>(content.data()),
- content.size(),
- fileName,
- kVerify,
- kVerifyChecksum,
- &error_code,
- &error_msg,
- &dex_files)) {
+ DexFileLoader dex_file_loader(
+ reinterpret_cast<const uint8_t*>(content.data()), content.size(), fileName);
+ if (!dex_file_loader.Open(kVerify, kVerifyChecksum, &error_code, &error_msg, &dex_files)) {
// Display returned error message to user. Note that this error behavior
// differs from the error messages shown by the original Dalvik dexdump.
LOG(ERROR) << error_msg;
diff --git a/dexdump/dexdump_main.cc b/dexdump/dexdump_main.cc
index 0d46d6b..fed2ba7 100644
--- a/dexdump/dexdump_main.cc
+++ b/dexdump/dexdump_main.cc
@@ -22,13 +22,13 @@
* Also, ODEX files are no longer supported.
*/
-#include "dexdump.h"
-
+#include <android-base/logging.h>
+#include <base/mem_map.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
-#include <android-base/logging.h>
+#include "dexdump.h"
namespace art {
@@ -157,6 +157,7 @@
int main(int argc, char** argv) {
// Output all logging to stderr.
android::base::SetLogger(android::base::StderrLogger);
+ art::MemMap::Init();
return art::dexdumpDriver(argc, argv);
}
diff --git a/dexlayout/dexlayout.cc b/dexlayout/dexlayout.cc
index a35c652..d2d31ac 100644
--- a/dexlayout/dexlayout.cc
+++ b/dexlayout/dexlayout.cc
@@ -2009,17 +2009,15 @@
std::string location = "memory mapped file for " + std::string(file_name);
// Dex file verifier cannot handle compact dex.
bool verify = options_.compact_dex_level_ == CompactDexLevel::kCompactDexLevelNone;
- const ArtDexFileLoader dex_file_loader;
DexContainer::Section* const main_section = (*dex_container)->GetMainSection();
DexContainer::Section* const data_section = (*dex_container)->GetDataSection();
DCHECK_EQ(file_size, main_section->Size())
<< main_section->Size() << " " << data_section->Size();
auto container = std::make_unique<DexLoaderContainer>(
main_section->Begin(), main_section->End(), data_section->Begin(), data_section->End());
+ ArtDexFileLoader dex_file_loader(std::move(container), location);
std::unique_ptr<const DexFile> output_dex_file(
- dex_file_loader.Open(std::move(container),
- location,
- /* location_checksum= */ 0,
+ dex_file_loader.Open(/* location_checksum= */ 0,
/*oat_dex_file=*/nullptr,
verify,
/*verify_checksum=*/false,
@@ -2057,10 +2055,10 @@
// all of which are Zip archives with "classes.dex" inside.
const bool verify_checksum = !options_.ignore_bad_checksum_;
std::string error_msg;
- const ArtDexFileLoader dex_file_loader;
+ ArtDexFileLoader dex_file_loader(file_name);
std::vector<std::unique_ptr<const DexFile>> dex_files;
if (!dex_file_loader.Open(
- file_name, file_name, /* verify= */ true, verify_checksum, &error_msg, &dex_files)) {
+ /* verify= */ true, verify_checksum, &error_msg, &dex_files)) {
// Display returned error message to user. Note that this error behavior
// differs from the error messages shown by the original Dalvik dexdump.
LOG(ERROR) << error_msg;
diff --git a/dexlayout/dexlayout_test.cc b/dexlayout/dexlayout_test.cc
index 8d034b8..03df258 100644
--- a/dexlayout/dexlayout_test.cc
+++ b/dexlayout/dexlayout_test.cc
@@ -330,11 +330,9 @@
const std::string& out_profile) {
std::vector<std::unique_ptr<const DexFile>> dex_files;
std::string error_msg;
- const ArtDexFileLoader dex_file_loader;
- bool result = dex_file_loader.Open(input_dex.c_str(),
- input_dex,
- /*verify=*/ true,
- /*verify_checksum=*/ false,
+ ArtDexFileLoader dex_file_loader(input_dex);
+ bool result = dex_file_loader.Open(/*verify=*/true,
+ /*verify_checksum=*/false,
&error_msg,
&dex_files);
@@ -774,14 +772,15 @@
TEST_F(DexLayoutTest, ClassFilter) {
std::vector<std::unique_ptr<const DexFile>> dex_files;
std::string error_msg;
- const ArtDexFileLoader dex_file_loader;
const std::string input_jar = GetTestDexFileName("ManyMethods");
- CHECK(dex_file_loader.Open(input_jar.c_str(),
- input_jar.c_str(),
- /*verify=*/ true,
- /*verify_checksum=*/ true,
- &error_msg,
- &dex_files)) << error_msg;
+ {
+ ArtDexFileLoader dex_file_loader(input_jar);
+ CHECK(dex_file_loader.Open(/*verify=*/true,
+ /*verify_checksum=*/true,
+ &error_msg,
+ &dex_files))
+ << error_msg;
+ }
ASSERT_EQ(dex_files.size(), 1u);
for (const std::unique_ptr<const DexFile>& dex_file : dex_files) {
EXPECT_GT(dex_file->NumClassDefs(), 1u);
@@ -808,14 +807,12 @@
out->GetMainSection()->End(),
out->GetDataSection()->Begin(),
out->GetDataSection()->End());
- std::unique_ptr<const DexFile> output_dex_file(
- dex_file_loader.Open(std::move(container),
- dex_file->GetLocation().c_str(),
- /* location_checksum= */ 0,
- /*oat_dex_file=*/nullptr,
- /* verify= */ true,
- /*verify_checksum=*/false,
- &error_msg));
+ ArtDexFileLoader dex_file_loader(std::move(container), dex_file->GetLocation());
+ std::unique_ptr<const DexFile> output_dex_file(dex_file_loader.Open(/* location_checksum= */ 0,
+ /*oat_dex_file=*/nullptr,
+ /* verify= */ true,
+ /*verify_checksum=*/false,
+ &error_msg));
ASSERT_TRUE(output_dex_file != nullptr);
ASSERT_EQ(output_dex_file->NumClassDefs(), options.class_filter_.size());
diff --git a/dexlist/dexlist.cc b/dexlist/dexlist.cc
index 9ef9ae9..3603675 100644
--- a/dexlist/dexlist.cc
+++ b/dexlist/dexlist.cc
@@ -30,6 +30,7 @@
#include <android-base/file.h>
#include <android-base/logging.h>
+#include "base/mem_map.h"
#include "dex/class_accessor-inl.h"
#include "dex/code_item_accessors-inl.h"
#include "dex/dex_file-inl.h"
@@ -168,15 +169,10 @@
std::vector<std::unique_ptr<const DexFile>> dex_files;
DexFileLoaderErrorCode error_code;
std::string error_msg;
- const DexFileLoader dex_file_loader;
- if (!dex_file_loader.OpenAll(reinterpret_cast<const uint8_t*>(content.data()),
- content.size(),
- fileName,
- /*verify=*/ true,
- kVerifyChecksum,
- &error_code,
- &error_msg,
- &dex_files)) {
+ DexFileLoader dex_file_loader(
+ reinterpret_cast<const uint8_t*>(content.data()), content.size(), fileName);
+ if (!dex_file_loader.Open(
+ /*verify=*/true, kVerifyChecksum, &error_code, &error_msg, &dex_files)) {
LOG(ERROR) << error_msg;
return -1;
}
@@ -281,6 +277,7 @@
int main(int argc, char** argv) {
// Output all logging to stderr.
android::base::SetLogger(android::base::StderrLogger);
+ art::MemMap::Init();
return art::dexlistDriver(argc, argv);
}
diff --git a/libartbase/base/common_art_test.cc b/libartbase/base/common_art_test.cc
index c921f2e..02bfe6f 100644
--- a/libartbase/base/common_art_test.cc
+++ b/libartbase/base/common_art_test.cc
@@ -389,14 +389,9 @@
std::string error_msg;
MemMap::Init();
static constexpr bool kVerifyChecksum = true;
- const ArtDexFileLoader dex_file_loader;
std::string filename(IsHost() ? GetAndroidBuildTop() + location : location);
- if (!dex_file_loader.Open(filename.c_str(),
- std::string(location),
- /* verify= */ true,
- kVerifyChecksum,
- &error_msg,
- &dex_files)) {
+ ArtDexFileLoader dex_file_loader(filename.c_str(), std::string(location));
+ if (!dex_file_loader.Open(/* verify= */ true, kVerifyChecksum, &error_msg, &dex_files)) {
LOG(FATAL) << "Could not open .dex file '" << filename << "': " << error_msg << "\n";
UNREACHABLE();
}
@@ -516,14 +511,9 @@
static constexpr bool kVerify = true;
static constexpr bool kVerifyChecksum = true;
std::string error_msg;
- const ArtDexFileLoader dex_file_loader;
+ ArtDexFileLoader dex_file_loader(filename);
std::vector<std::unique_ptr<const DexFile>> dex_files;
- bool success = dex_file_loader.Open(filename,
- filename,
- kVerify,
- kVerifyChecksum,
- &error_msg,
- &dex_files);
+ bool success = dex_file_loader.Open(kVerify, kVerifyChecksum, &error_msg, &dex_files);
CHECK(success) << "Failed to open '" << filename << "': " << error_msg;
for (auto& dex_file : dex_files) {
CHECK(dex_file->IsReadOnly());
diff --git a/libartbase/base/common_art_test.h b/libartbase/base/common_art_test.h
index f4935cc..d7711f2 100644
--- a/libartbase/base/common_art_test.h
+++ b/libartbase/base/common_art_test.h
@@ -173,13 +173,12 @@
bool MutateDexFile(File* output_dex, const std::string& input_jar, const Mutator& mutator) {
std::vector<std::unique_ptr<const DexFile>> dex_files;
std::string error_msg;
- const ArtDexFileLoader dex_file_loader;
- CHECK(dex_file_loader.Open(input_jar.c_str(),
- input_jar.c_str(),
- /*verify*/ true,
+ ArtDexFileLoader dex_file_loader(input_jar);
+ CHECK(dex_file_loader.Open(/*verify*/ true,
/*verify_checksum*/ true,
&error_msg,
- &dex_files)) << error_msg;
+ &dex_files))
+ << error_msg;
EXPECT_EQ(dex_files.size(), 1u) << "Only one input dex is supported";
const std::unique_ptr<const DexFile>& dex = dex_files[0];
CHECK(dex->EnableWrite()) << "Failed to enable write";
diff --git a/libartbase/base/mem_map.cc b/libartbase/base/mem_map.cc
index d36756e..04c11ed 100644
--- a/libartbase/base/mem_map.cc
+++ b/libartbase/base/mem_map.cc
@@ -1021,6 +1021,8 @@
TargetMMapInit();
}
+bool MemMap::IsInitialized() { return mem_maps_lock_ != nullptr; }
+
void MemMap::Shutdown() {
if (mem_maps_lock_ == nullptr) {
// If MemMap::Shutdown is called more than once, there is no effect.
diff --git a/libartbase/base/mem_map.h b/libartbase/base/mem_map.h
index 3d74f8a..c174f24 100644
--- a/libartbase/base/mem_map.h
+++ b/libartbase/base/mem_map.h
@@ -316,6 +316,7 @@
// time after the first call to Init and before the first call to Shutodwn.
static void Init() REQUIRES(!MemMap::mem_maps_lock_);
static void Shutdown() REQUIRES(!MemMap::mem_maps_lock_);
+ static bool IsInitialized();
// If the map is PROT_READ, try to read each page of the map to check it is in fact readable (not
// faulting). This is used to diagnose a bug b/19894268 where mprotect doesn't seem to be working
diff --git a/libartbase/base/systrace.h b/libartbase/base/systrace.h
index 42975d7..6e5e0e0 100644
--- a/libartbase/base/systrace.h
+++ b/libartbase/base/systrace.h
@@ -60,6 +60,7 @@
}
explicit ScopedTrace(const std::string& name) : ScopedTrace(name.c_str()) {}
+ ScopedTrace(ScopedTrace&&) = default;
~ScopedTrace() {
ATraceEnd();
diff --git a/libartbase/base/zip_archive.cc b/libartbase/base/zip_archive.cc
index 70778e7..ba44096 100644
--- a/libartbase/base/zip_archive.cc
+++ b/libartbase/base/zip_archive.cc
@@ -253,6 +253,24 @@
return OpenFromFdInternal(fd, /*assume_ownership=*/false, filename, error_msg);
}
+ZipArchive* ZipArchive::OpenFromMemory(const uint8_t* data,
+ size_t size,
+ const char* filename,
+ std::string* error_msg) {
+ DCHECK(filename != nullptr);
+ DCHECK(data != nullptr);
+
+ ZipArchiveHandle handle;
+ const int32_t error = OpenArchiveFromMemory(data, size, filename, &handle);
+ if (error != 0) {
+ *error_msg = std::string(ErrorCodeString(error));
+ CloseArchive(handle);
+ return nullptr;
+ }
+
+ return new ZipArchive(handle);
+}
+
ZipArchive* ZipArchive::OpenFromFdInternal(int fd,
bool assume_ownership,
const char* filename,
diff --git a/libartbase/base/zip_archive.h b/libartbase/base/zip_archive.h
index 084bfd0..e740c9f 100644
--- a/libartbase/base/zip_archive.h
+++ b/libartbase/base/zip_archive.h
@@ -93,6 +93,10 @@
static ZipArchive* Open(const char* filename, std::string* error_msg);
static ZipArchive* OpenFromFd(int fd, const char* filename, std::string* error_msg);
static ZipArchive* OpenFromOwnedFd(int fd, const char* filename, std::string* error_msg);
+ static ZipArchive* OpenFromMemory(const uint8_t* data,
+ size_t size,
+ const char* filename,
+ std::string* error_msg);
ZipEntry* Find(const char* name, std::string* error_msg) const;
diff --git a/libdexfile/dex/art_dex_file_loader.cc b/libdexfile/dex/art_dex_file_loader.cc
index 53a85bc..3a15e90 100644
--- a/libdexfile/dex/art_dex_file_loader.cc
+++ b/libdexfile/dex/art_dex_file_loader.cc
@@ -37,67 +37,14 @@
namespace art {
-namespace {
-
-class MemMapContainer : public DexFileContainer {
- public:
- explicit MemMapContainer(MemMap&& mem_map, bool direct_mmap = false)
- : mem_map_(std::move(mem_map)), direct_mmap_(direct_mmap) {}
- ~MemMapContainer() override { }
-
- int GetPermissions() const {
- if (!mem_map_.IsValid()) {
- return 0;
- } else {
- return mem_map_.GetProtect();
- }
- }
-
- bool IsReadOnly() const override { return GetPermissions() == PROT_READ; }
-
- bool EnableWrite() override {
- CHECK(IsReadOnly());
- if (!mem_map_.IsValid()) {
- return false;
- } else {
- return mem_map_.Protect(PROT_READ | PROT_WRITE);
- }
- }
-
- bool DisableWrite() override {
- CHECK(!IsReadOnly());
- if (!mem_map_.IsValid()) {
- return false;
- } else {
- return mem_map_.Protect(PROT_READ);
- }
- }
-
- const uint8_t* Begin() const override { return mem_map_.Begin(); }
-
- const uint8_t* End() const override { return mem_map_.End(); }
-
- bool IsDirectMmap() override { return direct_mmap_; }
-
- private:
- MemMap mem_map_;
- bool direct_mmap_;
- DISALLOW_COPY_AND_ASSIGN(MemMapContainer);
-};
-
-} // namespace
-
using android::base::StringPrintf;
-static constexpr OatDexFile* kNoOatDexFile = nullptr;
-
-
bool ArtDexFileLoader::GetMultiDexChecksums(const char* filename,
std::vector<uint32_t>* checksums,
std::vector<std::string>* dex_locations,
std::string* error_msg,
int zip_fd,
- bool* zip_file_only_contains_uncompressed_dex) const {
+ bool* zip_file_only_contains_uncompressed_dex) {
CHECK(checksums != nullptr);
uint32_t magic;
@@ -154,459 +101,21 @@
return true;
}
if (IsMagicValid(magic)) {
- std::unique_ptr<const DexFile> dex_file(OpenFile(fd.Release(),
- filename,
- /* verify= */ false,
- /* verify_checksum= */ false,
- /* mmap_shared= */ false,
- error_msg));
- if (dex_file == nullptr) {
+ ArtDexFileLoader loader(fd.Release(), filename);
+ std::vector<std::unique_ptr<const DexFile>> dex_files;
+ if (!loader.Open(/* verify= */ false,
+ /* verify_checksum= */ false,
+ error_msg,
+ &dex_files)) {
return false;
}
- checksums->push_back(dex_file->GetHeader().checksum_);
+ for (auto& dex_file : dex_files) {
+ checksums->push_back(dex_file->GetHeader().checksum_);
+ }
return true;
}
*error_msg = StringPrintf("Expected valid zip or dex file: '%s'", filename);
return false;
}
-std::unique_ptr<const DexFile> ArtDexFileLoader::Open(const uint8_t* base,
- size_t size,
- const std::string& location,
- uint32_t location_checksum,
- const OatDexFile* oat_dex_file,
- bool verify,
- bool verify_checksum,
- std::string* error_msg) const {
- ScopedTrace trace(std::string("Open dex file from RAM ") + location);
- auto container = std::make_unique<MemoryDexFileContainer>(base, base + size);
- return OpenCommon(location,
- location_checksum,
- oat_dex_file,
- verify,
- verify_checksum,
- error_msg,
- std::move(container),
- /*verify_result=*/nullptr);
-}
-
-std::unique_ptr<const DexFile> ArtDexFileLoader::Open(std::unique_ptr<DexFileContainer> container,
- const std::string& location,
- uint32_t location_checksum,
- const OatDexFile* oat_dex_file,
- bool verify,
- bool verify_checksum,
- std::string* error_msg) const {
- ScopedTrace trace(std::string("Open dex file from ") + location);
- return OpenCommon(location,
- location_checksum,
- oat_dex_file,
- verify,
- verify_checksum,
- error_msg,
- std::move(container),
- /*verify_result=*/nullptr);
-}
-
-std::unique_ptr<const DexFile> ArtDexFileLoader::Open(const std::string& location,
- uint32_t location_checksum,
- MemMap&& map,
- bool verify,
- bool verify_checksum,
- std::string* error_msg) const {
- ScopedTrace trace(std::string("Open dex file from mapped-memory ") + location);
- CHECK(map.IsValid());
-
- size_t size = map.Size();
- if (size < sizeof(DexFile::Header)) {
- *error_msg = StringPrintf(
- "DexFile: failed to open dex file '%s' that is too short to have a header",
- location.c_str());
- return nullptr;
- }
-
- std::unique_ptr<DexFile> dex_file = OpenCommon(location,
- location_checksum,
- kNoOatDexFile,
- verify,
- verify_checksum,
- error_msg,
- std::make_unique<MemMapContainer>(std::move(map)),
- /*verify_result=*/nullptr);
- // Opening CompactDex is only supported from vdex files.
- if (dex_file != nullptr && dex_file->IsCompactDexFile()) {
- *error_msg = StringPrintf("Opening CompactDex file '%s' is only supported from vdex files",
- location.c_str());
- return nullptr;
- }
- return dex_file;
-}
-
-bool ArtDexFileLoader::Open(const char* filename,
- const std::string& location,
- bool verify,
- bool verify_checksum,
- std::string* error_msg,
- std::vector<std::unique_ptr<const DexFile>>* dex_files) const {
- uint32_t magic;
- File fd = OpenAndReadMagic(filename, &magic, error_msg);
- if (fd.Fd() == -1) {
- DCHECK(!error_msg->empty());
- return false;
- }
- return OpenWithMagic(
- magic, fd.Release(), location, verify, verify_checksum, error_msg, dex_files);
-}
-
-bool ArtDexFileLoader::Open(int fd,
- const std::string& location,
- bool verify,
- bool verify_checksum,
- std::string* error_msg,
- std::vector<std::unique_ptr<const DexFile>>* dex_files) const {
- uint32_t magic;
- if (!ReadMagicAndReset(fd, &magic, error_msg)) {
- DCHECK(!error_msg->empty());
- return false;
- }
- return OpenWithMagic(magic, fd, location, verify, verify_checksum, error_msg, dex_files);
-}
-
-bool ArtDexFileLoader::Open(const char* filename,
- int fd,
- const std::string& location,
- bool verify,
- bool verify_checksum,
- std::string* error_msg,
- std::vector<std::unique_ptr<const DexFile>>* dex_files) const {
- return fd == -1
- ? Open(filename, location, verify, verify_checksum, error_msg, dex_files)
- : Open(fd, location, verify, verify_checksum, error_msg, dex_files);
-}
-
-bool ArtDexFileLoader::OpenWithMagic(uint32_t magic,
- int fd,
- const std::string& location,
- bool verify,
- bool verify_checksum,
- std::string* error_msg,
- std::vector<std::unique_ptr<const DexFile>>* dex_files) const {
- ScopedTrace trace(std::string("Open dex file ") + std::string(location));
- DCHECK(dex_files != nullptr) << "DexFile::Open: out-param is nullptr";
- if (IsZipMagic(magic)) {
- return OpenZip(
- fd, location, verify, verify_checksum, /*allow_no_dex_files=*/false, error_msg, dex_files);
- }
- if (IsMagicValid(magic)) {
- std::unique_ptr<const DexFile> dex_file(OpenFile(fd,
- location,
- verify,
- verify_checksum,
- /* mmap_shared= */ false,
- error_msg));
- if (dex_file.get() != nullptr) {
- dex_files->push_back(std::move(dex_file));
- return true;
- } else {
- return false;
- }
- }
- *error_msg = StringPrintf("Expected valid zip or dex file: '%s'", location.c_str());
- return false;
-}
-
-std::unique_ptr<const DexFile> ArtDexFileLoader::OpenDex(int fd,
- const std::string& location,
- bool verify,
- bool verify_checksum,
- bool mmap_shared,
- std::string* error_msg) const {
- ScopedTrace trace("Open dex file " + std::string(location));
- return OpenFile(fd, location, verify, verify_checksum, mmap_shared, error_msg);
-}
-
-bool ArtDexFileLoader::OpenZip(int fd,
- const std::string& location,
- bool verify,
- bool verify_checksum,
- bool allow_no_dex_files,
- std::string* error_msg,
- std::vector<std::unique_ptr<const DexFile>>* dex_files) const {
- ScopedTrace trace("Dex file open Zip " + std::string(location));
- return OpenZipInternal(ZipArchive::OpenFromFd(fd, location.c_str(), error_msg),
- location,
- verify,
- verify_checksum,
- allow_no_dex_files,
- error_msg,
- dex_files);
-}
-
-bool ArtDexFileLoader::OpenZipFromOwnedFd(
- int fd,
- const std::string& location,
- bool verify,
- bool verify_checksum,
- bool allow_no_dex_files,
- std::string* error_msg,
- std::vector<std::unique_ptr<const DexFile>>* dex_files) const {
- ScopedTrace trace("Dex file open Zip " + std::string(location) + " (owned fd)");
- return OpenZipInternal(ZipArchive::OpenFromOwnedFd(fd, location.c_str(), error_msg),
- location,
- verify,
- verify_checksum,
- allow_no_dex_files,
- error_msg,
- dex_files);
-}
-
-bool ArtDexFileLoader::OpenZipInternal(
- ZipArchive* raw_zip_archive,
- const std::string& location,
- bool verify,
- bool verify_checksum,
- bool allow_no_dex_files,
- std::string* error_msg,
- std::vector<std::unique_ptr<const DexFile>>* dex_files) const {
- DCHECK(dex_files != nullptr) << "DexFile::OpenZip: out-param is nullptr";
- std::unique_ptr<ZipArchive> zip_archive(raw_zip_archive);
- if (zip_archive.get() == nullptr) {
- DCHECK(!error_msg->empty());
- return false;
- }
- return OpenAllDexFilesFromZip(
- *zip_archive, location, verify, verify_checksum, allow_no_dex_files, error_msg, dex_files);
-}
-
-std::unique_ptr<const DexFile> ArtDexFileLoader::OpenFile(int fd,
- const std::string& location,
- bool verify,
- bool verify_checksum,
- bool mmap_shared,
- std::string* error_msg) const {
- ScopedTrace trace(std::string("Open dex file ") + std::string(location));
- CHECK(!location.empty());
- MemMap map;
- {
- File delayed_close(fd, /* check_usage= */ false);
- struct stat sbuf;
- memset(&sbuf, 0, sizeof(sbuf));
- if (fstat(fd, &sbuf) == -1) {
- *error_msg = StringPrintf("DexFile: fstat '%s' failed: %s", location.c_str(),
- strerror(errno));
- return nullptr;
- }
- if (S_ISDIR(sbuf.st_mode)) {
- *error_msg = StringPrintf("Attempt to mmap directory '%s'", location.c_str());
- return nullptr;
- }
- size_t length = sbuf.st_size;
- map = MemMap::MapFile(length,
- PROT_READ,
- mmap_shared ? MAP_SHARED : MAP_PRIVATE,
- fd,
- 0,
- /*low_4gb=*/false,
- location.c_str(),
- error_msg);
- if (!map.IsValid()) {
- DCHECK(!error_msg->empty());
- return nullptr;
- }
- }
-
- const uint8_t* begin = map.Begin();
- size_t size = map.Size();
- if (size < sizeof(DexFile::Header)) {
- *error_msg = StringPrintf(
- "DexFile: failed to open dex file '%s' that is too short to have a header",
- location.c_str());
- return nullptr;
- }
-
- const DexFile::Header* dex_header = reinterpret_cast<const DexFile::Header*>(begin);
-
- std::unique_ptr<DexFile> dex_file = OpenCommon(location,
- dex_header->checksum_,
- kNoOatDexFile,
- verify,
- verify_checksum,
- error_msg,
- std::make_unique<MemMapContainer>(std::move(map)),
- /*verify_result=*/nullptr);
-
- // Opening CompactDex is only supported from vdex files.
- if (dex_file != nullptr && dex_file->IsCompactDexFile()) {
- *error_msg = StringPrintf("Opening CompactDex file '%s' is only supported from vdex files",
- location.c_str());
- return nullptr;
- }
- return dex_file;
-}
-
-std::unique_ptr<const DexFile> ArtDexFileLoader::OpenOneDexFileFromZip(
- const ZipArchive& zip_archive,
- const char* entry_name,
- const std::string& location,
- bool verify,
- bool verify_checksum,
- std::string* error_msg,
- DexFileLoaderErrorCode* error_code) const {
- ScopedTrace trace("Dex file open from Zip Archive " + std::string(location));
- CHECK(!location.empty());
- std::unique_ptr<ZipEntry> zip_entry(zip_archive.Find(entry_name, error_msg));
- if (zip_entry == nullptr) {
- *error_code = DexFileLoaderErrorCode::kEntryNotFound;
- return nullptr;
- }
- if (zip_entry->GetUncompressedLength() == 0) {
- *error_msg = StringPrintf("Dex file '%s' has zero length", location.c_str());
- *error_code = DexFileLoaderErrorCode::kDexFileError;
- return nullptr;
- }
-
- MemMap map;
- bool direct_mmap = false;
- if (zip_entry->IsUncompressed()) {
- if (!zip_entry->IsAlignedTo(alignof(DexFile::Header))) {
- // Do not mmap unaligned ZIP entries because
- // doing so would fail dex verification which requires 4 byte alignment.
- LOG(WARNING) << "Can't mmap dex file " << location << "!" << entry_name << " directly; "
- << "please zipalign to " << alignof(DexFile::Header) << " bytes. "
- << "Falling back to extracting file.";
- } else {
- // Map uncompressed files within zip as file-backed to avoid a dirty copy.
- map = zip_entry->MapDirectlyFromFile(location.c_str(), /*out*/error_msg);
- if (!map.IsValid()) {
- LOG(WARNING) << "Can't mmap dex file " << location << "!" << entry_name << " directly; "
- << "is your ZIP file corrupted? Falling back to extraction.";
- // Try again with Extraction which still has a chance of recovery.
- }
- direct_mmap = true;
- }
- }
-
- ScopedTrace map_extract_trace(StringPrintf("Mapped=%s Extracted=%s",
- map.IsValid() ? "true" : "false",
- map.IsValid() ? "false" : "true")); // this is redundant but much easier to read in traces.
-
- if (!map.IsValid()) {
- // Default path for compressed ZIP entries,
- // and fallback for stored ZIP entries.
- map = zip_entry->ExtractToMemMap(location.c_str(), entry_name, error_msg);
- }
-
- if (!map.IsValid()) {
- *error_msg = StringPrintf("Failed to extract '%s' from '%s': %s", entry_name, location.c_str(),
- error_msg->c_str());
- *error_code = DexFileLoaderErrorCode::kExtractToMemoryError;
- return nullptr;
- }
- VerifyResult verify_result;
- auto container = std::make_unique<MemMapContainer>(std::move(map), direct_mmap);
- std::unique_ptr<DexFile> dex_file = OpenCommon(location,
- zip_entry->GetCrc32(),
- kNoOatDexFile,
- verify,
- verify_checksum,
- error_msg,
- std::move(container),
- &verify_result);
- if (dex_file != nullptr && dex_file->IsCompactDexFile()) {
- *error_msg = StringPrintf("Opening CompactDex file '%s' is only supported from vdex files",
- location.c_str());
- return nullptr;
- }
- if (dex_file == nullptr) {
- if (verify_result == VerifyResult::kVerifyNotAttempted) {
- *error_code = DexFileLoaderErrorCode::kDexFileError;
- } else {
- *error_code = DexFileLoaderErrorCode::kVerifyError;
- }
- return nullptr;
- }
- if (!dex_file->DisableWrite()) {
- *error_msg = StringPrintf("Failed to make dex file '%s' read only", location.c_str());
- *error_code = DexFileLoaderErrorCode::kMakeReadOnlyError;
- return nullptr;
- }
- CHECK(dex_file->IsReadOnly()) << location;
- if (verify_result != VerifyResult::kVerifySucceeded) {
- *error_code = DexFileLoaderErrorCode::kVerifyError;
- return nullptr;
- }
- *error_code = DexFileLoaderErrorCode::kNoError;
- return dex_file;
-}
-
-// Technically we do not have a limitation with respect to the number of dex files that can be in a
-// multidex APK. However, it's bad practice, as each dex file requires its own tables for symbols
-// (types, classes, methods, ...) and dex caches. So warn the user that we open a zip with what
-// seems an excessive number.
-static constexpr size_t kWarnOnManyDexFilesThreshold = 100;
-
-bool ArtDexFileLoader::OpenAllDexFilesFromZip(
- const ZipArchive& zip_archive,
- const std::string& location,
- bool verify,
- bool verify_checksum,
- bool allow_no_dex_files,
- std::string* error_msg,
- std::vector<std::unique_ptr<const DexFile>>* dex_files) const {
- ScopedTrace trace("Dex file open from Zip " + std::string(location));
- DCHECK(dex_files != nullptr) << "DexFile::OpenFromZip: out-param is nullptr";
- DexFileLoaderErrorCode error_code;
- std::string local_error_msg;
- std::unique_ptr<const DexFile> dex_file(OpenOneDexFileFromZip(
- zip_archive, kClassesDex, location, verify, verify_checksum, &local_error_msg, &error_code));
- if (dex_file.get() == nullptr) {
- if (allow_no_dex_files && error_code == DexFileLoaderErrorCode::kEntryNotFound) {
- return true;
- }
- *error_msg = std::move(local_error_msg);
- return false;
- } else {
- // Had at least classes.dex.
- dex_files->push_back(std::move(dex_file));
-
- // Now try some more.
-
- // We could try to avoid std::string allocations by working on a char array directly. As we
- // do not expect a lot of iterations, this seems too involved and brittle.
-
- for (size_t i = 1;; ++i) {
- std::string name = GetMultiDexClassesDexName(i);
- std::string fake_location = GetMultiDexLocation(i, location.c_str());
- std::unique_ptr<const DexFile> next_dex_file(OpenOneDexFileFromZip(zip_archive,
- name.c_str(),
- fake_location,
- verify,
- verify_checksum,
- error_msg,
- &error_code));
- if (next_dex_file.get() == nullptr) {
- if (error_code != DexFileLoaderErrorCode::kEntryNotFound) {
- LOG(WARNING) << "Zip open failed: " << *error_msg;
- }
- break;
- } else {
- dex_files->push_back(std::move(next_dex_file));
- }
-
- if (i == kWarnOnManyDexFilesThreshold) {
- LOG(WARNING) << location << " has in excess of " << kWarnOnManyDexFilesThreshold
- << " dex files. Please consider coalescing and shrinking the number to "
- " avoid runtime overhead.";
- }
-
- if (i == std::numeric_limits<size_t>::max()) {
- LOG(ERROR) << "Overflow in number of dex files!";
- break;
- }
- }
-
- return true;
- }
-}
-
} // namespace art
diff --git a/libdexfile/dex/art_dex_file_loader.h b/libdexfile/dex/art_dex_file_loader.h
index 6f8b3c6..9806c46 100644
--- a/libdexfile/dex/art_dex_file_loader.h
+++ b/libdexfile/dex/art_dex_file_loader.h
@@ -36,6 +36,7 @@
// Class that is used to open dex files and deal with corresponding multidex and location logic.
class ArtDexFileLoader : public DexFileLoader {
public:
+ using DexFileLoader::DexFileLoader;
virtual ~ArtDexFileLoader() { }
// Returns the checksums of a file for comparison with GetLocationChecksum().
@@ -51,140 +52,12 @@
// locations.
//
// Return true if the checksums could be found, false otherwise.
- bool GetMultiDexChecksums(const char* filename,
- std::vector<uint32_t>* checksums,
- std::vector<std::string>* dex_locations,
- std::string* error_msg,
- int zip_fd = -1,
- bool* only_contains_uncompressed_dex = nullptr) const override;
-
- // Opens .dex file, backed by existing memory
- std::unique_ptr<const DexFile> Open(const uint8_t* base,
- size_t size,
- const std::string& location,
- uint32_t location_checksum,
- const OatDexFile* oat_dex_file,
- bool verify,
- bool verify_checksum,
- std::string* error_msg) const override;
-
- // Opens .dex file, backed by existing memory
- std::unique_ptr<const DexFile> Open(std::unique_ptr<DexFileContainer> container,
- const std::string& location,
- uint32_t location_checksum,
- const OatDexFile* oat_dex_file,
- bool verify,
- bool verify_checksum,
- std::string* error_msg) const;
-
- // Opens .dex file that has been memory-mapped by the caller.
- std::unique_ptr<const DexFile> Open(const std::string& location,
- uint32_t location_checkum,
- MemMap&& mem_map,
- bool verify,
- bool verify_checksum,
- std::string* error_msg) const;
-
- // Opens all .dex files found in the file, guessing the container format based on file magic.
- bool Open(const char* filename,
- const std::string& location,
- bool verify,
- bool verify_checksum,
- std::string* error_msg,
- std::vector<std::unique_ptr<const DexFile>>* dex_files) const;
- bool Open(int fd,
- const std::string& location,
- bool verify,
- bool verify_checksum,
- std::string* error_msg,
- std::vector<std::unique_ptr<const DexFile>>* dex_files) const;
- // Opens all .dex files found in the file, guessing the container format based on file magic.
- // If the fd is -1 then the dex files are opened using the filename; otherwise they are
- // opened using the fd.
- bool Open(const char* filename,
- int fd,
- const std::string& location,
- bool verify,
- bool verify_checksum,
- std::string* error_msg,
- std::vector<std::unique_ptr<const DexFile>>* dex_files) const;
-
- // Open a single dex file from an fd. This function closes the fd.
- std::unique_ptr<const DexFile> OpenDex(int fd,
- const std::string& location,
- bool verify,
- bool verify_checksum,
- bool mmap_shared,
- std::string* error_msg) const;
-
- // Opens dex files from within a .jar, .zip, or .apk file using its file descriptor. The file
- // descriptor ownership is taken over, i.e. will be closed by this class.
- // If the zip file doesn't contain any dex code and `allow_no_dex_files` is true, returns true and
- // keeps `dex_files` to be an empty vector; if the zip file doesn't contain any dex code and
- // `allow_no_dex_files` is false, returns false and sets the error message.
- bool OpenZip(int fd,
- const std::string& location,
- bool verify,
- bool verify_checksum,
- bool allow_no_dex_files,
- std::string* error_msg,
- std::vector<std::unique_ptr<const DexFile>>* dex_files) const;
-
- // Opens dex files from within a .jar, .zip, or .apk file using its file descriptor. The file
- // descriptor is assumed owned by the caller.
- // If the zip file doesn't contain any dex code and `allow_no_dex_files` is true, returns true and
- // keeps `dex_files` to be an empty vector; if the zip file doesn't contain any dex code and
- // `allow_no_dex_files` is false, returns false and sets the error message.
- bool OpenZipFromOwnedFd(int fd,
- const std::string& location,
- bool verify,
- bool verify_checksum,
- bool allow_no_dex_files,
- std::string* error_msg,
- std::vector<std::unique_ptr<const DexFile>>* dex_files) const;
-
- private:
- bool OpenWithMagic(uint32_t magic,
- int fd,
- const std::string& location,
- bool verify,
- bool verify_checksum,
- std::string* error_msg,
- std::vector<std::unique_ptr<const DexFile>>* dex_files) const;
-
- std::unique_ptr<const DexFile> OpenFile(int fd,
- const std::string& location,
- bool verify,
- bool verify_checksum,
- bool mmap_shared,
- std::string* error_msg) const;
-
- // Open all classesXXX.dex files from a zip archive.
- bool OpenAllDexFilesFromZip(const ZipArchive& zip_archive,
- const std::string& location,
- bool verify,
- bool verify_checksum,
- bool allow_no_dex_files,
- std::string* error_msg,
- std::vector<std::unique_ptr<const DexFile>>* dex_files) const;
-
- // Opens .dex file from the entry_name in a zip archive. error_code is undefined when non-null
- // return.
- std::unique_ptr<const DexFile> OpenOneDexFileFromZip(const ZipArchive& zip_archive,
- const char* entry_name,
- const std::string& location,
- bool verify,
- bool verify_checksum,
- std::string* error_msg,
- DexFileLoaderErrorCode* error_code) const;
-
- bool OpenZipInternal(ZipArchive* raw_zip_archive,
- const std::string& location,
- bool verify,
- bool verify_checksum,
- bool allow_no_dex_files,
- std::string* error_msg,
- std::vector<std::unique_ptr<const DexFile>>* dex_files) const;
+ static bool GetMultiDexChecksums(const char* filename,
+ std::vector<uint32_t>* checksums,
+ std::vector<std::string>* dex_locations,
+ std::string* error_msg,
+ int zip_fd = -1,
+ bool* only_contains_uncompressed_dex = nullptr);
};
} // namespace art
diff --git a/libdexfile/dex/art_dex_file_loader_test.cc b/libdexfile/dex/art_dex_file_loader_test.cc
index 477d8c5..833e73b 100644
--- a/libdexfile/dex/art_dex_file_loader_test.cc
+++ b/libdexfile/dex/art_dex_file_loader_test.cc
@@ -61,16 +61,14 @@
std::string zip_file = GetTestDexFileName("MultiDex");
File file(zip_file, O_RDONLY, /*check_usage=*/false);
ASSERT_GE(file.Fd(), 0);
- ArtDexFileLoader dex_file_loader;
std::vector<std::unique_ptr<const DexFile>> dex_files;
std::string error_msg;
- ASSERT_TRUE(dex_file_loader.OpenZip(file.Release(),
- zip_file,
- /*verify=*/false,
- /*verify_checksum=*/true,
- /*allow_no_dex_files=*/true,
- &error_msg,
- &dex_files))
+ ArtDexFileLoader dex_file_loader(file.Release(), zip_file);
+ ASSERT_TRUE(dex_file_loader.Open(/*verify=*/false,
+ /*verify_checksum=*/true,
+ /*allow_no_dex_files=*/true,
+ &error_msg,
+ &dex_files))
<< error_msg;
EXPECT_GT(dex_files.size(), 1);
}
@@ -79,16 +77,14 @@
std::string zip_file = GetTestDexFileName("MainEmptyUncompressed");
File file(zip_file, O_RDONLY, /*check_usage=*/false);
ASSERT_GE(file.Fd(), 0);
- ArtDexFileLoader dex_file_loader;
std::vector<std::unique_ptr<const DexFile>> dex_files;
std::string error_msg;
- ASSERT_TRUE(dex_file_loader.OpenZip(file.Release(),
- zip_file,
- /*verify=*/false,
- /*verify_checksum=*/true,
- /*allow_no_dex_files=*/true,
- &error_msg,
- &dex_files))
+ ArtDexFileLoader dex_file_loader(file.Release(), zip_file);
+ ASSERT_TRUE(dex_file_loader.Open(/*verify=*/false,
+ /*verify_checksum=*/true,
+ /*allow_no_dex_files=*/true,
+ &error_msg,
+ &dex_files))
<< error_msg;
EXPECT_EQ(dex_files.size(), 0);
}
@@ -102,11 +98,8 @@
std::vector<uint32_t> checksums;
std::vector<std::string> dex_locations;
std::string error_msg;
- const ArtDexFileLoader dex_file_loader;
- EXPECT_TRUE(dex_file_loader.GetMultiDexChecksums(GetLibCoreDexFileNames()[0].c_str(),
- &checksums,
- &dex_locations,
- &error_msg))
+ EXPECT_TRUE(ArtDexFileLoader::GetMultiDexChecksums(
+ GetLibCoreDexFileNames()[0].c_str(), &checksums, &dex_locations, &error_msg))
<< error_msg;
ASSERT_EQ(1U, checksums.size());
ASSERT_EQ(1U, dex_locations.size());
@@ -119,11 +112,9 @@
std::vector<uint32_t> checksums;
std::vector<std::string> dex_locations;
std::string multidex_file = GetTestDexFileName("MultiDex");
- const ArtDexFileLoader dex_file_loader;
- EXPECT_TRUE(dex_file_loader.GetMultiDexChecksums(multidex_file.c_str(),
- &checksums,
- &dex_locations,
- &error_msg)) << error_msg;
+ EXPECT_TRUE(ArtDexFileLoader::GetMultiDexChecksums(
+ multidex_file.c_str(), &checksums, &dex_locations, &error_msg))
+ << error_msg;
std::vector<std::unique_ptr<const DexFile>> dexes = OpenTestDexFiles("MultiDex");
ASSERT_EQ(2U, dexes.size());
@@ -144,8 +135,7 @@
std::vector<uint32_t> checksums;
std::vector<std::string> dex_locations;
std::string multidex_file = GetTestDexFileName("MainEmptyUncompressed");
- const ArtDexFileLoader dex_file_loader;
- EXPECT_TRUE(dex_file_loader.GetMultiDexChecksums(
+ EXPECT_TRUE(ArtDexFileLoader::GetMultiDexChecksums(
multidex_file.c_str(), &checksums, &dex_locations, &error_msg))
<< error_msg;
diff --git a/libdexfile/dex/code_item_accessors_test.cc b/libdexfile/dex/code_item_accessors_test.cc
index c5891f9..d43db70 100644
--- a/libdexfile/dex/code_item_accessors_test.cc
+++ b/libdexfile/dex/code_item_accessors_test.cc
@@ -40,12 +40,9 @@
StandardDexFile::WriteMagic(data->data());
StandardDexFile::WriteCurrentVersion(data->data());
}
- const DexFileLoader dex_file_loader;
+ DexFileLoader dex_file_loader(data->data(), data->size(), "location");
std::string error_msg;
- std::unique_ptr<const DexFile> dex(dex_file_loader.Open(data->data(),
- data->size(),
- "location",
- /*location_checksum=*/ 123,
+ std::unique_ptr<const DexFile> dex(dex_file_loader.Open(/*location_checksum=*/123,
/*oat_dex_file=*/nullptr,
/*verify=*/false,
/*verify_checksum=*/false,
diff --git a/libdexfile/dex/dex_file.h b/libdexfile/dex/dex_file.h
index c9a16ae..0cf5ae2 100644
--- a/libdexfile/dex/dex_file.h
+++ b/libdexfile/dex/dex_file.h
@@ -58,9 +58,14 @@
public:
DexFileContainer() { }
virtual ~DexFileContainer() {}
+
virtual bool IsReadOnly() const = 0;
+
+ // Make the underlying writeable. Return true on success (memory can be written).
virtual bool EnableWrite() = 0;
+ // Make the underlying read-only. Return true on success (memory is read-only now).
virtual bool DisableWrite() = 0;
+
virtual const uint8_t* Begin() const = 0;
virtual const uint8_t* End() const = 0;
size_t Size() const { return End() - Begin(); }
@@ -70,9 +75,12 @@
virtual const uint8_t* DataBegin() const { return nullptr; }
virtual const uint8_t* DataEnd() const { return nullptr; }
- virtual bool IsDirectMmap() { return false; }
+ bool IsZip() const { return is_zip_; }
+ void SetIsZip() { is_zip_ = true; }
+ virtual bool IsFileMap() const { return false; }
private:
+ bool is_zip_ = false;
DISALLOW_COPY_AND_ASSIGN(DexFileContainer);
};
diff --git a/libdexfile/dex/dex_file_loader.cc b/libdexfile/dex/dex_file_loader.cc
index 541d10b..942a4bc 100644
--- a/libdexfile/dex/dex_file_loader.cc
+++ b/libdexfile/dex/dex_file_loader.cc
@@ -16,20 +16,30 @@
#include "dex_file_loader.h"
+#include <sys/stat.h>
+
#include <memory>
#include "android-base/stringprintf.h"
+#include "base/bit_utils.h"
+#include "base/file_magic.h"
+#include "base/mem_map.h"
+#include "base/os.h"
#include "base/stl_util.h"
+#include "base/systrace.h"
+#include "base/unix_file/fd_file.h"
+#include "base/zip_archive.h"
#include "compact_dex_file.h"
#include "dex_file.h"
#include "dex_file_verifier.h"
#include "standard_dex_file.h"
-#include "ziparchive/zip_archive.h"
namespace art {
namespace {
+using android::base::StringPrintf;
+
class VectorContainer : public DexFileContainer {
public:
explicit VectorContainer(std::vector<uint8_t>&& vector) : vector_(std::move(vector)) { }
@@ -37,13 +47,9 @@
bool IsReadOnly() const override { return true; }
- bool EnableWrite() override {
- return false;
- }
+ bool EnableWrite() override { return true; }
- bool DisableWrite() override {
- return false;
- }
+ bool DisableWrite() override { return false; }
const uint8_t* Begin() const override { return vector_.data(); }
@@ -54,100 +60,53 @@
DISALLOW_COPY_AND_ASSIGN(VectorContainer);
};
+class MemMapContainer : public DexFileContainer {
+ public:
+ explicit MemMapContainer(MemMap&& mem_map, bool is_file_map = false)
+ : mem_map_(std::move(mem_map)), is_file_map_(is_file_map) {}
+
+ int GetPermissions() const {
+ if (!mem_map_.IsValid()) {
+ return 0;
+ } else {
+ return mem_map_.GetProtect();
+ }
+ }
+
+ bool IsReadOnly() const override { return GetPermissions() == PROT_READ; }
+
+ bool EnableWrite() override {
+ CHECK(IsReadOnly());
+ if (!mem_map_.IsValid()) {
+ return false;
+ } else {
+ return mem_map_.Protect(PROT_READ | PROT_WRITE);
+ }
+ }
+
+ bool DisableWrite() override {
+ CHECK(!IsReadOnly());
+ if (!mem_map_.IsValid()) {
+ return false;
+ } else {
+ return mem_map_.Protect(PROT_READ);
+ }
+ }
+
+ const uint8_t* Begin() const override { return mem_map_.Begin(); }
+
+ const uint8_t* End() const override { return mem_map_.End(); }
+
+ bool IsFileMap() const override { return is_file_map_; }
+
+ protected:
+ MemMap mem_map_;
+ bool is_file_map_;
+ DISALLOW_COPY_AND_ASSIGN(MemMapContainer);
+};
+
} // namespace
-using android::base::StringPrintf;
-
-class DexZipArchive;
-
-class DexZipEntry {
- public:
- // Extract this entry to memory.
- // Returns null on failure and sets error_msg.
- const std::vector<uint8_t> Extract(std::string* error_msg) {
- std::vector<uint8_t> map(GetUncompressedLength());
- if (map.size() == 0) {
- DCHECK(!error_msg->empty());
- return map;
- }
- const int32_t error = ExtractToMemory(handle_, zip_entry_, map.data(), map.size());
- if (error) {
- *error_msg = std::string(ErrorCodeString(error));
- }
- return map;
- }
-
- virtual ~DexZipEntry() {
- delete zip_entry_;
- }
-
- uint32_t GetUncompressedLength() {
- return zip_entry_->uncompressed_length;
- }
-
- uint32_t GetCrc32() {
- return zip_entry_->crc32;
- }
-
- private:
- DexZipEntry(ZipArchiveHandle handle,
- ::ZipEntry* zip_entry,
- const std::string& entry_name)
- : handle_(handle), zip_entry_(zip_entry), entry_name_(entry_name) {}
-
- ZipArchiveHandle handle_;
- ::ZipEntry* const zip_entry_;
- std::string const entry_name_;
-
- friend class DexZipArchive;
- DISALLOW_COPY_AND_ASSIGN(DexZipEntry);
-};
-
-class DexZipArchive {
- public:
- // return new DexZipArchive instance on success, null on error.
- static DexZipArchive* Open(const uint8_t* base, size_t size, std::string* error_msg) {
- ZipArchiveHandle handle;
- uint8_t* nonconst_base = const_cast<uint8_t*>(base);
- const int32_t error = OpenArchiveFromMemory(nonconst_base, size, "ZipArchiveMemory", &handle);
- if (error) {
- *error_msg = std::string(ErrorCodeString(error));
- CloseArchive(handle);
- return nullptr;
- }
- return new DexZipArchive(handle);
- }
-
- DexZipEntry* Find(const char* name, std::string* error_msg) const {
- DCHECK(name != nullptr);
- // Resist the urge to delete the space. <: is a bigraph sequence.
- std::unique_ptr< ::ZipEntry> zip_entry(new ::ZipEntry);
- const int32_t error = FindEntry(handle_, name, zip_entry.get());
- if (error) {
- *error_msg = std::string(ErrorCodeString(error));
- return nullptr;
- }
- return new DexZipEntry(handle_, zip_entry.release(), name);
- }
-
- ~DexZipArchive() {
- CloseArchive(handle_);
- }
-
-
- private:
- explicit DexZipArchive(ZipArchiveHandle handle) : handle_(handle) {}
- ZipArchiveHandle handle_;
-
- friend class DexZipEntry;
- DISALLOW_COPY_AND_ASSIGN(DexZipArchive);
-};
-
-static bool IsZipMagic(uint32_t magic) {
- return (('P' == ((magic >> 0) & 0xff)) &&
- ('K' == ((magic >> 8) & 0xff)));
-}
-
bool DexFileLoader::IsMagicValid(uint32_t magic) {
return IsMagicValid(reinterpret_cast<uint8_t*>(&magic));
}
@@ -205,91 +164,152 @@
}
// All of the implementations here should be independent of the runtime.
-// TODO: implement all the virtual methods.
-bool DexFileLoader::GetMultiDexChecksums(
- const char* filename ATTRIBUTE_UNUSED,
- std::vector<uint32_t>* checksums ATTRIBUTE_UNUSED,
- std::vector<std::string>* dex_locations ATTRIBUTE_UNUSED,
- std::string* error_msg,
- int zip_fd ATTRIBUTE_UNUSED,
- bool* zip_file_only_contains_uncompress_dex ATTRIBUTE_UNUSED) const {
- *error_msg = "UNIMPLEMENTED";
- return false;
-}
+DexFileLoader::DexFileLoader(const uint8_t* base, size_t size, const std::string& location)
+ : DexFileLoader(std::make_unique<MemoryDexFileContainer>(base, base + size), location) {}
-std::unique_ptr<const DexFile> DexFileLoader::Open(
- const std::string& location,
- uint32_t location_checksum,
- std::vector<uint8_t>&& memory,
- const OatDexFile* oat_dex_file,
- bool verify,
- bool verify_checksum,
- std::string* error_msg) {
- return OpenCommon(location,
- location_checksum,
- oat_dex_file,
- verify,
- verify_checksum,
- error_msg,
- std::make_unique<VectorContainer>(std::move(memory)),
- /*verify_result=*/nullptr);
-}
+DexFileLoader::DexFileLoader(std::vector<uint8_t>&& memory, const std::string& location)
+ : DexFileLoader(std::make_unique<VectorContainer>(std::move(memory)), location) {}
-std::unique_ptr<const DexFile> DexFileLoader::Open(const uint8_t* base,
- size_t size,
- const std::string& location,
- uint32_t location_checksum,
+DexFileLoader::DexFileLoader(MemMap&& mem_map, const std::string& location)
+ : DexFileLoader(std::make_unique<MemMapContainer>(std::move(mem_map)), location) {}
+
+std::unique_ptr<const DexFile> DexFileLoader::Open(uint32_t location_checksum,
const OatDexFile* oat_dex_file,
bool verify,
bool verify_checksum,
- std::string* error_msg) const {
- auto container = std::make_unique<MemoryDexFileContainer>(base, base + size);
- return OpenCommon(location,
- location_checksum,
- oat_dex_file,
- verify,
- verify_checksum,
- error_msg,
- std::move(container),
- /*verify_result=*/nullptr);
+ std::string* error_msg) {
+ ScopedTrace trace(std::string("Open dex file ") + location_);
+
+ uint32_t magic;
+ if (!InitAndReadMagic(&magic, error_msg) || !MapRootContainer(error_msg)) {
+ DCHECK(!error_msg->empty());
+ return {};
+ }
+ std::unique_ptr<const DexFile> dex_file = OpenCommon(std::move(root_container_),
+ location_,
+ location_checksum,
+ oat_dex_file,
+ verify,
+ verify_checksum,
+ error_msg,
+ nullptr);
+ return dex_file;
}
-bool DexFileLoader::OpenAll(
- const uint8_t* base,
- size_t size,
- const std::string& location,
- bool verify,
- bool verify_checksum,
- DexFileLoaderErrorCode* error_code,
- std::string* error_msg,
- std::vector<std::unique_ptr<const DexFile>>* dex_files) const {
+bool DexFileLoader::InitAndReadMagic(uint32_t* magic, std::string* error_msg) {
+ if (root_container_ != nullptr) {
+ if (root_container_->Size() < sizeof(uint32_t)) {
+ *error_msg = StringPrintf("Unable to open '%s' : Size is too small", location_.c_str());
+ return false;
+ }
+ *magic = *reinterpret_cast<const uint32_t*>(root_container_->Begin());
+ } else {
+ // Open the file if we have not been given the file-descriptor directly before.
+ if (!file_.has_value()) {
+ CHECK(!filename_.empty());
+ file_.emplace(filename_, O_RDONLY, /* check_usage= */ false);
+ if (file_->Fd() == -1) {
+ *error_msg = StringPrintf("Unable to open '%s' : %s", filename_.c_str(), strerror(errno));
+ return false;
+ }
+ }
+ if (!ReadMagicAndReset(file_->Fd(), magic, error_msg)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool DexFileLoader::MapRootContainer(std::string* error_msg) {
+ if (root_container_ != nullptr) {
+ return true;
+ }
+
+ CHECK(MemMap::IsInitialized());
+ CHECK(file_.has_value());
+ struct stat sbuf;
+ memset(&sbuf, 0, sizeof(sbuf));
+ if (fstat(file_->Fd(), &sbuf) == -1) {
+ *error_msg = StringPrintf("DexFile: fstat '%s' failed: %s", filename_.c_str(), strerror(errno));
+ return false;
+ }
+ if (S_ISDIR(sbuf.st_mode)) {
+ *error_msg = StringPrintf("Attempt to mmap directory '%s'", filename_.c_str());
+ return false;
+ }
+ MemMap map = MemMap::MapFile(sbuf.st_size,
+ PROT_READ,
+ MAP_PRIVATE,
+ file_->Fd(),
+ 0,
+ /*low_4gb=*/false,
+ filename_.c_str(),
+ error_msg);
+ if (!map.IsValid()) {
+ DCHECK(!error_msg->empty());
+ return false;
+ }
+ root_container_ = std::make_unique<MemMapContainer>(std::move(map));
+ return true;
+}
+
+bool DexFileLoader::Open(bool verify,
+ bool verify_checksum,
+ bool allow_no_dex_files,
+ DexFileLoaderErrorCode* error_code,
+ std::string* error_msg,
+ std::vector<std::unique_ptr<const DexFile>>* dex_files) {
+ ScopedTrace trace(std::string("Open dex file ") + location_);
+
DCHECK(dex_files != nullptr) << "DexFile::Open: out-param is nullptr";
- uint32_t magic = *reinterpret_cast<const uint32_t*>(base);
+
+ uint32_t magic;
+ if (!InitAndReadMagic(&magic, error_msg)) {
+ return false;
+ }
+
if (IsZipMagic(magic)) {
- std::unique_ptr<DexZipArchive> zip_archive(DexZipArchive::Open(base, size, error_msg));
+ std::unique_ptr<ZipArchive> zip_archive(
+ file_.has_value() ?
+ ZipArchive::OpenFromOwnedFd(file_->Fd(), location_.c_str(), error_msg) :
+ ZipArchive::OpenFromMemory(
+ root_container_->Begin(), root_container_->Size(), location_.c_str(), error_msg));
if (zip_archive.get() == nullptr) {
DCHECK(!error_msg->empty());
return false;
}
- return OpenAllDexFilesFromZip(*zip_archive.get(),
- location,
- verify,
- verify_checksum,
- error_code,
- error_msg,
- dex_files);
+ bool ok = OpenAllDexFilesFromZip(*zip_archive.get(),
+ location_,
+ verify,
+ verify_checksum,
+ allow_no_dex_files,
+ error_code,
+ error_msg,
+ dex_files);
+ return ok;
}
if (IsMagicValid(magic)) {
+ if (!MapRootContainer(error_msg)) {
+ return false;
+ }
+ const uint8_t* base = root_container_->Begin();
+ size_t size = root_container_->Size();
+ if (size < sizeof(DexFile::Header)) {
+ *error_msg =
+ StringPrintf("DexFile: failed to open dex file '%s' that is too short to have a header",
+ location_.c_str());
+ return false;
+ }
const DexFile::Header* dex_header = reinterpret_cast<const DexFile::Header*>(base);
- std::unique_ptr<const DexFile> dex_file(Open(base,
- size,
- location,
- dex_header->checksum_,
- /*oat_dex_file=*/ nullptr,
- verify,
- verify_checksum,
- error_msg));
+ std::unique_ptr<const DexFile> dex_file = OpenCommon(std::move(root_container_),
+ location_,
+ dex_header->checksum_,
+ /*oat_dex_file=*/nullptr,
+ verify,
+ verify_checksum,
+ error_msg,
+ nullptr);
if (dex_file.get() != nullptr) {
dex_files->push_back(std::move(dex_file));
return true;
@@ -301,13 +321,13 @@
return false;
}
-std::unique_ptr<DexFile> DexFileLoader::OpenCommon(const std::string& location,
+std::unique_ptr<DexFile> DexFileLoader::OpenCommon(std::unique_ptr<DexFileContainer> container,
+ const std::string& location,
uint32_t location_checksum,
const OatDexFile* oat_dex_file,
bool verify,
bool verify_checksum,
std::string* error_msg,
- std::unique_ptr<DexFileContainer> container,
VerifyResult* verify_result) {
CHECK(container != nullptr);
const uint8_t* base = container->Begin();
@@ -322,12 +342,8 @@
if (data_size != 0) {
CHECK_EQ(base, data_base) << "Unsupported for standard dex";
}
- dex_file.reset(new StandardDexFile(base,
- size,
- location,
- location_checksum,
- oat_dex_file,
- std::move(container)));
+ dex_file.reset(new StandardDexFile(
+ base, size, location, location_checksum, oat_dex_file, std::move(container)));
} else if (size >= sizeof(CompactDexFile::Header) && CompactDexFile::IsMagicValid(base)) {
if (data_base == nullptr) {
// TODO: Is there a clean way to support both an explicit data section and reading the one
@@ -351,24 +367,27 @@
*error_msg = "Invalid or truncated dex file";
}
if (dex_file == nullptr) {
- *error_msg = StringPrintf("Failed to open dex file '%s' from memory: %s", location.c_str(),
- error_msg->c_str());
+ *error_msg =
+ StringPrintf("Failed to open dex file '%s': %s", location.c_str(), error_msg->c_str());
return nullptr;
}
if (!dex_file->Init(error_msg)) {
dex_file.reset();
return nullptr;
}
- if (verify && !dex::Verify(dex_file.get(),
- dex_file->Begin(),
- dex_file->Size(),
- location.c_str(),
- verify_checksum,
- error_msg)) {
- if (verify_result != nullptr) {
- *verify_result = VerifyResult::kVerifyFailed;
+ if (verify) {
+ ScopedTrace trace(std::string("Verify dex file ") + location);
+ if (!dex::Verify(dex_file.get(),
+ dex_file->Begin(),
+ dex_file->Size(),
+ location.c_str(),
+ verify_checksum,
+ error_msg)) {
+ if (verify_result != nullptr) {
+ *verify_result = VerifyResult::kVerifyFailed;
+ }
+ return nullptr;
}
- return nullptr;
}
if (verify_result != nullptr) {
*verify_result = VerifyResult::kVerifySucceeded;
@@ -377,7 +396,7 @@
}
std::unique_ptr<const DexFile> DexFileLoader::OpenOneDexFileFromZip(
- const DexZipArchive& zip_archive,
+ const ZipArchive& zip_archive,
const char* entry_name,
const std::string& location,
bool verify,
@@ -385,7 +404,7 @@
DexFileLoaderErrorCode* error_code,
std::string* error_msg) const {
CHECK(!location.empty());
- std::unique_ptr<DexZipEntry> zip_entry(zip_archive.Find(entry_name, error_msg));
+ std::unique_ptr<ZipEntry> zip_entry(zip_archive.Find(entry_name, error_msg));
if (zip_entry == nullptr) {
*error_code = DexFileLoaderErrorCode::kEntryNotFound;
return nullptr;
@@ -396,23 +415,52 @@
return nullptr;
}
- std::vector<uint8_t> map(zip_entry->Extract(error_msg));
- if (map.size() == 0) {
+ CHECK(MemMap::IsInitialized());
+ MemMap map;
+ bool is_file_map = false;
+ if (file_.has_value() && zip_entry->IsUncompressed()) {
+ if (!zip_entry->IsAlignedTo(alignof(DexFile::Header))) {
+ // Do not mmap unaligned ZIP entries because
+ // doing so would fail dex verification which requires 4 byte alignment.
+ LOG(WARNING) << "Can't mmap dex file " << location << "!" << entry_name << " directly; "
+ << "please zipalign to " << alignof(DexFile::Header) << " bytes. "
+ << "Falling back to extracting file.";
+ } else {
+ // Map uncompressed files within zip as file-backed to avoid a dirty copy.
+ map = zip_entry->MapDirectlyFromFile(location.c_str(), /*out*/ error_msg);
+ if (!map.IsValid()) {
+ LOG(WARNING) << "Can't mmap dex file " << location << "!" << entry_name << " directly; "
+ << "is your ZIP file corrupted? Falling back to extraction.";
+ // Try again with Extraction which still has a chance of recovery.
+ }
+ is_file_map = true;
+ }
+ }
+ if (!map.IsValid()) {
+ ScopedTrace trace(std::string("Extract dex file ") + location);
+
+ // Default path for compressed ZIP entries,
+ // and fallback for stored ZIP entries.
+ map = zip_entry->ExtractToMemMap(location.c_str(), entry_name, error_msg);
+ }
+ if (!map.IsValid()) {
*error_msg = StringPrintf("Failed to extract '%s' from '%s': %s", entry_name, location.c_str(),
error_msg->c_str());
*error_code = DexFileLoaderErrorCode::kExtractToMemoryError;
return nullptr;
}
+ auto container = std::make_unique<MemMapContainer>(std::move(map), is_file_map);
+ container->SetIsZip();
+
VerifyResult verify_result;
- std::unique_ptr<const DexFile> dex_file =
- OpenCommon(location,
- zip_entry->GetCrc32(),
- /*oat_dex_file=*/nullptr,
- verify,
- verify_checksum,
- error_msg,
- std::make_unique<VectorContainer>(std::move(map)),
- &verify_result);
+ std::unique_ptr<const DexFile> dex_file = OpenCommon(std::move(container),
+ location,
+ zip_entry->GetCrc32(),
+ /*oat_dex_file=*/nullptr,
+ verify,
+ verify_checksum,
+ error_msg,
+ &verify_result);
if (verify_result != VerifyResult::kVerifySucceeded) {
if (verify_result == VerifyResult::kVerifyNotAttempted) {
*error_code = DexFileLoaderErrorCode::kDexFileError;
@@ -421,6 +469,12 @@
}
return nullptr;
}
+ if (!dex_file->DisableWrite()) {
+ *error_msg = StringPrintf("Failed to make dex file '%s' read only", location.c_str());
+ *error_code = DexFileLoaderErrorCode::kMakeReadOnlyError;
+ return nullptr;
+ }
+ CHECK(dex_file->IsReadOnly()) << location;
*error_code = DexFileLoaderErrorCode::kNoError;
return dex_file;
}
@@ -432,10 +486,11 @@
static constexpr size_t kWarnOnManyDexFilesThreshold = 100;
bool DexFileLoader::OpenAllDexFilesFromZip(
- const DexZipArchive& zip_archive,
+ const ZipArchive& zip_archive,
const std::string& location,
bool verify,
bool verify_checksum,
+ bool allow_no_dex_files,
DexFileLoaderErrorCode* error_code,
std::string* error_msg,
std::vector<std::unique_ptr<const DexFile>>* dex_files) const {
@@ -448,6 +503,9 @@
error_code,
error_msg));
if (*error_code != DexFileLoaderErrorCode::kNoError) {
+ if (allow_no_dex_files && *error_code == DexFileLoaderErrorCode::kEntryNotFound) {
+ return true;
+ }
return false;
} else {
// Had at least classes.dex.
diff --git a/libdexfile/dex/dex_file_loader.h b/libdexfile/dex/dex_file_loader.h
index ef45aa8..a2a29bc 100644
--- a/libdexfile/dex/dex_file_loader.h
+++ b/libdexfile/dex/dex_file_loader.h
@@ -18,18 +18,21 @@
#define ART_LIBDEXFILE_DEX_DEX_FILE_LOADER_H_
#include <cstdint>
+#include <functional>
#include <memory>
#include <string>
#include <vector>
+#include "base/os.h"
+#include "base/unix_file/fd_file.h"
+#include "dex_file.h"
+
namespace art {
-class DexFile;
-class DexFileContainer;
class MemMap;
class OatDexFile;
-
-class DexZipArchive;
+class ScopedTrace;
+class ZipArchive;
enum class DexFileLoaderErrorCode {
kNoError,
@@ -103,58 +106,90 @@
return (pos == std::string::npos) ? std::string() : location.substr(pos);
}
- virtual ~DexFileLoader() { }
+ DexFileLoader(const char* filename, int fd, const std::string& location)
+ : filename_(filename),
+ file_(fd == -1 ? std::optional<File>() : File(fd, /*check_usage=*/false)),
+ location_(location) {}
- // Returns the checksums of a file for comparison with GetLocationChecksum().
- // For .dex files, this is the single header checksum.
- // For zip files, this is the zip entry CRC32 checksum for classes.dex and
- // each additional multidex entry classes2.dex, classes3.dex, etc.
- // If a valid zip_fd is provided the file content will be read directly from
- // the descriptor and `filename` will be used as alias for error logging. If
- // zip_fd is -1, the method will try to open the `filename` and read the
- // content from it.
- //
- // The dex_locations vector will be populated with the corresponding multidex
- // locations.
- //
- // Return true if the checksums could be found, false otherwise.
- virtual bool GetMultiDexChecksums(const char* filename,
- std::vector<uint32_t>* checksums,
- std::vector<std::string>* dex_locations,
- std::string* error_msg,
- int zip_fd = -1,
- bool* zip_file_only_contains_uncompress_dex = nullptr) const;
+ DexFileLoader(std::unique_ptr<DexFileContainer>&& container, const std::string& location)
+ : root_container_(std::move(container)), location_(location) {}
- // Opens .dex file, backed by existing vector memory.
- static std::unique_ptr<const DexFile> Open(
- const std::string& location,
- uint32_t location_checksum,
- std::vector<uint8_t>&& memory,
- const OatDexFile* oat_dex_file,
- bool verify,
- bool verify_checksum,
- std::string* error_msg);
+ DexFileLoader(const uint8_t* base, size_t size, const std::string& location);
- // Opens .dex file, backed by existing memory.
- virtual std::unique_ptr<const DexFile> Open(const uint8_t* base,
- size_t size,
- const std::string& location,
- uint32_t location_checksum,
- const OatDexFile* oat_dex_file,
- bool verify,
- bool verify_checksum,
- std::string* error_msg) const;
+ DexFileLoader(std::vector<uint8_t>&& memory, const std::string& location);
- // Opens all .dex files found in the memory map, guessing the container format based on file
- // extension.
- virtual bool OpenAll(const uint8_t* base,
- size_t size,
- const std::string& location,
- bool verify,
- bool verify_checksum,
- DexFileLoaderErrorCode* error_code,
- std::string* error_msg,
- std::vector<std::unique_ptr<const DexFile>>* dex_files) const;
+ DexFileLoader(MemMap&& mem_map, const std::string& location);
+
+ DexFileLoader(int fd, const std::string& location)
+ : DexFileLoader(/*filename=*/location.c_str(), fd, location) {}
+
+ DexFileLoader(const char* filename, const std::string& location)
+ : DexFileLoader(filename, /*fd=*/-1, location) {}
+
+ explicit DexFileLoader(const std::string& location)
+ : DexFileLoader(location.c_str(), /*fd=*/-1, location) {}
+
+ virtual ~DexFileLoader() {}
+
+ std::unique_ptr<const DexFile> Open(uint32_t location_checksum,
+ const OatDexFile* oat_dex_file,
+ bool verify,
+ bool verify_checksum,
+ std::string* error_msg);
+
+ std::unique_ptr<const DexFile> Open(uint32_t location_checksum,
+ bool verify,
+ bool verify_checksum,
+ std::string* error_msg) {
+ return Open(location_checksum,
+ /*oat_dex_file=*/nullptr,
+ verify,
+ verify_checksum,
+ error_msg);
+ }
+
+ // Opens all .dex files, guessing the container format based on file extension.
+ bool Open(bool verify,
+ bool verify_checksum,
+ bool allow_no_dex_files,
+ DexFileLoaderErrorCode* error_code,
+ std::string* error_msg,
+ std::vector<std::unique_ptr<const DexFile>>* dex_files);
+
+ bool Open(bool verify,
+ bool verify_checksum,
+ DexFileLoaderErrorCode* error_code,
+ std::string* error_msg,
+ std::vector<std::unique_ptr<const DexFile>>* dex_files) {
+ return Open(verify,
+ verify_checksum,
+ /*allow_no_dex_files=*/false,
+ error_code,
+ error_msg,
+ dex_files);
+ }
+
+ bool Open(bool verify,
+ bool verify_checksum,
+ bool allow_no_dex_files,
+ std::string* error_msg,
+ std::vector<std::unique_ptr<const DexFile>>* dex_files) {
+ DexFileLoaderErrorCode error_code;
+ return Open(verify, verify_checksum, allow_no_dex_files, &error_code, error_msg, dex_files);
+ }
+
+ bool Open(bool verify,
+ bool verify_checksum,
+ std::string* error_msg,
+ std::vector<std::unique_ptr<const DexFile>>* dex_files) {
+ DexFileLoaderErrorCode error_code;
+ return Open(verify,
+ verify_checksum,
+ /*allow_no_dex_files=*/false,
+ &error_code,
+ error_msg,
+ dex_files);
+ }
protected:
enum class VerifyResult { // private
@@ -163,34 +198,47 @@
kVerifyFailed
};
- static std::unique_ptr<DexFile> OpenCommon(const std::string& location,
+ bool InitAndReadMagic(uint32_t* magic, std::string* error_msg);
+
+ // Ensure we have root container. If we are backed by a file, memory-map it.
+ // We can only do this for dex files since zip files might be too big to map.
+ bool MapRootContainer(std::string* error_msg);
+
+ static std::unique_ptr<DexFile> OpenCommon(std::unique_ptr<DexFileContainer> container,
+ const std::string& location,
uint32_t location_checksum,
const OatDexFile* oat_dex_file,
bool verify,
bool verify_checksum,
std::string* error_msg,
- std::unique_ptr<DexFileContainer> container,
VerifyResult* verify_result);
- private:
// Open all classesXXX.dex files from a zip archive.
- bool OpenAllDexFilesFromZip(const DexZipArchive& zip_archive,
+ bool OpenAllDexFilesFromZip(const ZipArchive& zip_archive,
const std::string& location,
bool verify,
bool verify_checksum,
+ bool allow_no_dex_files,
DexFileLoaderErrorCode* error_code,
std::string* error_msg,
std::vector<std::unique_ptr<const DexFile>>* dex_files) const;
// Opens .dex file from the entry_name in a zip archive. error_code is undefined when non-null
// return.
- std::unique_ptr<const DexFile> OpenOneDexFileFromZip(const DexZipArchive& zip_archive,
+ std::unique_ptr<const DexFile> OpenOneDexFileFromZip(const ZipArchive& zip_archive,
const char* entry_name,
const std::string& location,
bool verify,
bool verify_checksum,
DexFileLoaderErrorCode* error_code,
std::string* error_msg) const;
+
+ // The DexFileLoader can be backed either by file or by memory (i.e. DexFileContainer).
+ // We can not just mmap the file since APKs might be unreasonably large for 32-bit system.
+ std::string filename_;
+ std::optional<File> file_;
+ std::unique_ptr<DexFileContainer> root_container_;
+ const std::string location_;
};
} // namespace art
diff --git a/libdexfile/dex/dex_file_loader_test.cc b/libdexfile/dex/dex_file_loader_test.cc
index 30c60b1..381dfdc 100644
--- a/libdexfile/dex/dex_file_loader_test.cc
+++ b/libdexfile/dex/dex_file_loader_test.cc
@@ -217,15 +217,9 @@
// read dex file(s)
static constexpr bool kVerifyChecksum = true;
std::vector<std::unique_ptr<const DexFile>> tmp;
- const DexFileLoader dex_file_loader;
- bool success = dex_file_loader.OpenAll(dex_bytes->data(),
- dex_bytes->size(),
- location,
- /* verify= */ true,
- kVerifyChecksum,
- error_code,
- error_msg,
- dex_files);
+ DexFileLoader dex_file_loader(dex_bytes->data(), dex_bytes->size(), location);
+ bool success =
+ dex_file_loader.Open(/* verify= */ true, kVerifyChecksum, error_code, error_msg, dex_files);
return success;
}
@@ -251,11 +245,8 @@
DecodeDexFile(base64, dex_bytes);
std::string error_message;
- const DexFileLoader dex_file_loader;
- std::unique_ptr<const DexFile> dex_file(dex_file_loader.Open(dex_bytes->data(),
- dex_bytes->size(),
- location,
- location_checksum,
+ DexFileLoader dex_file_loader(dex_bytes->data(), dex_bytes->size(), location);
+ std::unique_ptr<const DexFile> dex_file(dex_file_loader.Open(location_checksum,
/* oat_dex_file= */ nullptr,
/* verify= */ true,
/* verify_checksum= */ true,
@@ -353,15 +344,9 @@
DexFileLoaderErrorCode error_code;
std::string error_msg;
std::vector<std::unique_ptr<const DexFile>> dex_files;
- const DexFileLoader dex_file_loader;
- ASSERT_FALSE(dex_file_loader.OpenAll(dex_bytes.data(),
- dex_bytes.size(),
- kLocationString,
- /* verify= */ true,
- kVerifyChecksum,
- &error_code,
- &error_msg,
- &dex_files));
+ DexFileLoader dex_file_loader(dex_bytes.data(), dex_bytes.size(), kLocationString);
+ ASSERT_FALSE(dex_file_loader.Open(
+ /* verify= */ true, kVerifyChecksum, &error_code, &error_msg, &dex_files));
}
TEST_F(DexFileLoaderTest, ZeroLengthDexRejected) {
@@ -372,15 +357,9 @@
DexFileLoaderErrorCode error_code;
std::string error_msg;
std::vector<std::unique_ptr<const DexFile>> dex_files;
- const DexFileLoader dex_file_loader;
- ASSERT_FALSE(dex_file_loader.OpenAll(dex_bytes.data(),
- dex_bytes.size(),
- kLocationString,
- /* verify= */ true,
- kVerifyChecksum,
- &error_code,
- &error_msg,
- &dex_files));
+ DexFileLoader dex_file_loader(dex_bytes.data(), dex_bytes.size(), kLocationString);
+ ASSERT_FALSE(dex_file_loader.Open(
+ /* verify= */ true, kVerifyChecksum, &error_code, &error_msg, &dex_files));
}
TEST_F(DexFileLoaderTest, GetMultiDexClassesDexName) {
diff --git a/libdexfile/dex/dex_file_verifier_test.cc b/libdexfile/dex/dex_file_verifier_test.cc
index 79e9c8b..ba0b24d 100644
--- a/libdexfile/dex/dex_file_verifier_test.cc
+++ b/libdexfile/dex/dex_file_verifier_test.cc
@@ -104,16 +104,13 @@
// read dex
std::vector<std::unique_ptr<const DexFile>> tmp;
- const DexFileLoader dex_file_loader;
+ DexFileLoader dex_file_loader(dex_bytes.get(), length, location);
DexFileLoaderErrorCode error_code;
- bool success = dex_file_loader.OpenAll(dex_bytes.get(),
- length,
- location,
- /* verify= */ true,
- /* verify_checksum= */ true,
- &error_code,
- error_msg,
- &tmp);
+ bool success = dex_file_loader.Open(/* verify= */ true,
+ /* verify_checksum= */ true,
+ &error_code,
+ error_msg,
+ &tmp);
CHECK(success) << *error_msg;
EXPECT_EQ(1U, tmp.size());
std::unique_ptr<const DexFile> dex_file = std::move(tmp[0]);
diff --git a/libdexfile/dex/test_dex_file_builder.h b/libdexfile/dex/test_dex_file_builder.h
index 283dd48..964f196 100644
--- a/libdexfile/dex/test_dex_file_builder.h
+++ b/libdexfile/dex/test_dex_file_builder.h
@@ -237,14 +237,12 @@
static constexpr bool kVerify = false;
static constexpr bool kVerifyChecksum = false;
std::string error_msg;
- std::unique_ptr<const DexFile> dex_file(DexFileLoader::Open(
- dex_location,
- location_checksum,
- std::move(dex_file_data),
- /*oat_dex_file=*/ nullptr,
- kVerify,
- kVerifyChecksum,
- &error_msg));
+ DexFileLoader dex_file_loader(std::move(dex_file_data), dex_location);
+ std::unique_ptr<const DexFile> dex_file(dex_file_loader.Open(location_checksum,
+ /*oat_dex_file=*/nullptr,
+ kVerify,
+ kVerifyChecksum,
+ &error_msg));
CHECK(dex_file != nullptr) << error_msg;
return dex_file;
}
diff --git a/libdexfile/external/dex_file_ext.cc b/libdexfile/external/dex_file_ext.cc
index 7c0bf2d..c7b1cbb 100644
--- a/libdexfile/external/dex_file_ext.cc
+++ b/libdexfile/external/dex_file_ext.cc
@@ -179,12 +179,9 @@
}
std::string loc_str(location);
- art::DexFileLoader loader;
std::string error_msg;
- std::unique_ptr<const art::DexFile> dex_file = loader.Open(static_cast<const uint8_t*>(address),
- size,
- loc_str,
- header->checksum_,
+ art::DexFileLoader loader(static_cast<const uint8_t*>(address), size, loc_str);
+ std::unique_ptr<const art::DexFile> dex_file = loader.Open(header->checksum_,
/*oat_dex_file=*/nullptr,
/*verify=*/false,
/*verify_checksum=*/false,
diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc
index 3561673..6f75fbd 100644
--- a/oatdump/oatdump.cc
+++ b/oatdump/oatdump.cc
@@ -660,16 +660,13 @@
DexContainer::Section* main_section = dex_container->GetMainSection();
CHECK_EQ(dex_container->GetDataSection()->Size(), 0u);
- const ArtDexFileLoader dex_file_loader;
- std::unique_ptr<const DexFile> dex(dex_file_loader.Open(
- main_section->Begin(),
- main_section->Size(),
- vdex_dex_file->GetLocation(),
- vdex_file->GetLocationChecksum(i),
- /*oat_dex_file=*/ nullptr,
- /*verify=*/ false,
- /*verify_checksum=*/ true,
- &error_msg));
+ ArtDexFileLoader dex_file_loader(
+ main_section->Begin(), main_section->Size(), vdex_dex_file->GetLocation());
+ std::unique_ptr<const DexFile> dex(dex_file_loader.Open(vdex_file->GetLocationChecksum(i),
+ /*oat_dex_file=*/nullptr,
+ /*verify=*/false,
+ /*verify_checksum=*/true,
+ &error_msg));
if (dex == nullptr) {
os << "Failed to load DexFile from layout container: " + error_msg;
success = false;
diff --git a/odrefresh/odrefresh.cc b/odrefresh/odrefresh.cc
index 601d21d..af5bfab 100644
--- a/odrefresh/odrefresh.cc
+++ b/odrefresh/odrefresh.cc
@@ -290,7 +290,6 @@
custom_generator) {
std::vector<T> components;
- ArtDexFileLoader loader;
for (const std::string& path : jars) {
std::string actual_path = RewriteParentDirectoryIfNeeded(path);
struct stat sb;
@@ -302,7 +301,8 @@
std::vector<uint32_t> checksums;
std::vector<std::string> dex_locations;
std::string error_msg;
- if (!loader.GetMultiDexChecksums(actual_path.c_str(), &checksums, &dex_locations, &error_msg)) {
+ if (!ArtDexFileLoader::GetMultiDexChecksums(
+ actual_path.c_str(), &checksums, &dex_locations, &error_msg)) {
LOG(ERROR) << "Failed to get multi-dex checksums: " << error_msg;
return {};
}
diff --git a/openjdkjvmti/ti_class.cc b/openjdkjvmti/ti_class.cc
index 37ceb37..3d44516 100644
--- a/openjdkjvmti/ti_class.cc
+++ b/openjdkjvmti/ti_class.cc
@@ -113,10 +113,8 @@
}
uint32_t checksum = reinterpret_cast<const art::DexFile::Header*>(map.Begin())->checksum_;
std::string map_name = map.GetName();
- const art::ArtDexFileLoader dex_file_loader;
- std::unique_ptr<const art::DexFile> dex_file(dex_file_loader.Open(map_name,
- checksum,
- std::move(map),
+ art::ArtDexFileLoader dex_file_loader(std::move(map), map_name);
+ std::unique_ptr<const art::DexFile> dex_file(dex_file_loader.Open(checksum,
/*verify=*/true,
/*verify_checksum=*/true,
&error_msg));
diff --git a/openjdkjvmti/ti_class_definition.cc b/openjdkjvmti/ti_class_definition.cc
index f1f5593..a9e7b31 100644
--- a/openjdkjvmti/ti_class_definition.cc
+++ b/openjdkjvmti/ti_class_definition.cc
@@ -172,10 +172,8 @@
if (dex_file.IsCompactDexFile()) {
std::string error_msg;
std::vector<std::unique_ptr<const art::DexFile>> dex_files;
- const art::ArtDexFileLoader dex_file_loader;
- if (!dex_file_loader.Open(dex_file.GetLocation().c_str(),
- dex_file.GetLocation().c_str(),
- /* verify= */ false,
+ art::ArtDexFileLoader dex_file_loader(dex_file.GetLocation());
+ if (!dex_file_loader.Open(/* verify= */ false,
/* verify_checksum= */ false,
&error_msg,
&dex_files)) {
diff --git a/openjdkjvmti/ti_redefine.cc b/openjdkjvmti/ti_redefine.cc
index d40964f..aafca47 100644
--- a/openjdkjvmti/ti_redefine.cc
+++ b/openjdkjvmti/ti_redefine.cc
@@ -725,10 +725,8 @@
}
std::string name = map.GetName();
uint32_t checksum = reinterpret_cast<const art::DexFile::Header*>(map.Begin())->checksum_;
- const art::ArtDexFileLoader dex_file_loader;
- std::unique_ptr<const art::DexFile> dex_file(dex_file_loader.Open(name,
- checksum,
- std::move(map),
+ art::ArtDexFileLoader dex_file_loader(std::move(map), name);
+ std::unique_ptr<const art::DexFile> dex_file(dex_file_loader.Open(checksum,
/*verify=*/true,
/*verify_checksum=*/true,
error_msg_));
diff --git a/openjdkjvmti/ti_search.cc b/openjdkjvmti/ti_search.cc
index 4d96732..2e98e0d 100644
--- a/openjdkjvmti/ti_search.cc
+++ b/openjdkjvmti/ti_search.cc
@@ -235,10 +235,8 @@
std::string error_msg;
std::vector<std::unique_ptr<const art::DexFile>> dex_files;
- const art::ArtDexFileLoader dex_file_loader;
- if (!dex_file_loader.Open(segment,
- segment,
- /* verify= */ true,
+ art::ArtDexFileLoader dex_file_loader(segment);
+ if (!dex_file_loader.Open(/* verify= */ true,
/* verify_checksum= */ true,
&error_msg,
&dex_files)) {
diff --git a/profman/profman.cc b/profman/profman.cc
index 55c8555..21efd45 100644
--- a/profman/profman.cc
+++ b/profman/profman.cc
@@ -607,34 +607,31 @@
static constexpr bool kVerifyChecksum = true;
for (size_t i = 0; i < dex_locations_.size(); ++i) {
std::string error_msg;
- const ArtDexFileLoader dex_file_loader;
std::vector<std::unique_ptr<const DexFile>> dex_files_for_location;
// We do not need to verify the apk for processing profiles.
if (use_apk_fd_list) {
- if (dex_file_loader.OpenZip(apks_fd_[i],
- dex_locations_[i],
- /*verify=*/false,
- kVerifyChecksum,
- /*allow_no_dex_files=*/true,
- &error_msg,
- &dex_files_for_location)) {
- } else {
- LOG(ERROR) << "OpenZip failed for '" << dex_locations_[i] << "' " << error_msg;
- return false;
- }
+ ArtDexFileLoader dex_file_loader(apks_fd_[i], dex_locations_[i]);
+ if (dex_file_loader.Open(/*verify=*/false,
+ kVerifyChecksum,
+ /*allow_no_dex_files=*/true,
+ &error_msg,
+ &dex_files_for_location)) {
+ } else {
+ LOG(ERROR) << "OpenZip failed for '" << dex_locations_[i] << "' " << error_msg;
+ return false;
+ }
} else {
File file(apk_files_[i], O_RDONLY, /*check_usage=*/false);
if (file.Fd() < 0) {
PLOG(ERROR) << "Unable to open '" << apk_files_[i] << "'";
return false;
}
- if (dex_file_loader.OpenZip(file.Release(),
- dex_locations_[i],
- /*verify=*/false,
- kVerifyChecksum,
- /*allow_no_dex_files=*/true,
- &error_msg,
- &dex_files_for_location)) {
+ ArtDexFileLoader dex_file_loader(file.Release(), dex_locations_[i]);
+ if (dex_file_loader.Open(/*verify=*/false,
+ kVerifyChecksum,
+ /*allow_no_dex_files=*/true,
+ &error_msg,
+ &dex_files_for_location)) {
} else {
LOG(ERROR) << "Open failed for '" << dex_locations_[i] << "' " << error_msg;
return false;
diff --git a/runtime/class_loader_context.cc b/runtime/class_loader_context.cc
index 722b8f7..074a819 100644
--- a/runtime/class_loader_context.cc
+++ b/runtime/class_loader_context.cc
@@ -438,7 +438,6 @@
// We may get resource-only apks which we cannot load.
// TODO(calin): Refine the dex opening interface to be able to tell if an archive contains
// no dex files. So that we can distinguish the real failures...
- const ArtDexFileLoader dex_file_loader;
std::vector<ClassLoaderInfo*> work_list;
if (class_loader_chain_ == nullptr) {
return true;
@@ -480,12 +479,12 @@
std::string error_msg;
if (only_read_checksums) {
bool zip_file_only_contains_uncompress_dex;
- if (!dex_file_loader.GetMultiDexChecksums(location.c_str(),
- &dex_checksums,
- &dex_locations,
- &error_msg,
- fd,
- &zip_file_only_contains_uncompress_dex)) {
+ if (!ArtDexFileLoader::GetMultiDexChecksums(location.c_str(),
+ &dex_checksums,
+ &dex_locations,
+ &error_msg,
+ fd,
+ &zip_file_only_contains_uncompress_dex)) {
LOG(WARNING) << "Could not get dex checksums for location " << location << ", fd=" << fd;
dex_files_state_ = kDexFilesOpenFailed;
}
@@ -495,11 +494,9 @@
// We don't need to do structural dex file verification, we only need to
// check the checksum, so pass false to verify.
size_t opened_dex_files_index = info->opened_dex_files.size();
- if (!dex_file_loader.Open(location.c_str(),
- fd,
- location.c_str(),
- /*verify=*/ false,
- /*verify_checksum=*/ true,
+ ArtDexFileLoader dex_file_loader(location.c_str(), fd, location);
+ if (!dex_file_loader.Open(/*verify=*/false,
+ /*verify_checksum=*/true,
&error_msg,
&info->opened_dex_files)) {
LOG(WARNING) << "Could not open dex files for location " << location << ", fd=" << fd;
diff --git a/runtime/common_runtime_test.cc b/runtime/common_runtime_test.cc
index 131d0d8..ee574bc 100644
--- a/runtime/common_runtime_test.cc
+++ b/runtime/common_runtime_test.cc
@@ -572,10 +572,8 @@
for (const std::string& dex : dexes) {
std::vector<std::unique_ptr<const DexFile>> dex_files;
std::string error_msg;
- const ArtDexFileLoader dex_file_loader;
- CHECK(dex_file_loader.Open(dex.c_str(),
- dex,
- /*verify*/ true,
+ ArtDexFileLoader dex_file_loader(dex);
+ CHECK(dex_file_loader.Open(/*verify*/ true,
/*verify_checksum*/ false,
&error_msg,
&dex_files))
diff --git a/runtime/common_runtime_test.h b/runtime/common_runtime_test.h
index 56e3225..85c48a2 100644
--- a/runtime/common_runtime_test.h
+++ b/runtime/common_runtime_test.h
@@ -88,13 +88,12 @@
bool MutateDexFile(File* output_dex, const std::string& input_jar, const Mutator& mutator) {
std::vector<std::unique_ptr<const DexFile>> dex_files;
std::string error_msg;
- const ArtDexFileLoader dex_file_loader;
- CHECK(dex_file_loader.Open(input_jar.c_str(),
- input_jar.c_str(),
- /*verify=*/ true,
- /*verify_checksum=*/ true,
+ ArtDexFileLoader dex_file_loader(input_jar);
+ CHECK(dex_file_loader.Open(/*verify=*/true,
+ /*verify_checksum=*/true,
&error_msg,
- &dex_files)) << error_msg;
+ &dex_files))
+ << error_msg;
EXPECT_EQ(dex_files.size(), 1u) << "Only one input dex is supported";
const std::unique_ptr<const DexFile>& dex = dex_files[0];
CHECK(dex->EnableWrite()) << "Failed to enable write";
diff --git a/runtime/dex2oat_environment_test.h b/runtime/dex2oat_environment_test.h
index deda75a..c7febcd 100644
--- a/runtime/dex2oat_environment_test.h
+++ b/runtime/dex2oat_environment_test.h
@@ -97,8 +97,6 @@
CommonRuntimeTest::SetUp();
Dex2oatScratchDirs::SetUp(android_data_);
- const ArtDexFileLoader dex_file_loader;
-
// Verify the environment is as we expect
std::vector<uint32_t> checksums;
std::vector<std::string> dex_locations;
@@ -109,7 +107,7 @@
<< "Expected dex file to be at: " << GetDexSrc1();
ASSERT_TRUE(OS::FileExists(GetResourceOnlySrc1().c_str()))
<< "Expected stripped dex file to be at: " << GetResourceOnlySrc1();
- ASSERT_TRUE(dex_file_loader.GetMultiDexChecksums(
+ ASSERT_TRUE(ArtDexFileLoader::GetMultiDexChecksums(
GetResourceOnlySrc1().c_str(), &checksums, &dex_locations, &error_msg))
<< "Expected stripped dex file to be stripped: " << GetResourceOnlySrc1();
ASSERT_TRUE(OS::FileExists(GetDexSrc2().c_str()))
@@ -119,21 +117,15 @@
// GetMultiDexSrc1, but a different secondary dex checksum.
static constexpr bool kVerifyChecksum = true;
std::vector<std::unique_ptr<const DexFile>> multi1;
- ASSERT_TRUE(dex_file_loader.Open(GetMultiDexSrc1().c_str(),
- GetMultiDexSrc1().c_str(),
- /* verify= */ true,
- kVerifyChecksum,
- &error_msg,
- &multi1)) << error_msg;
+ ArtDexFileLoader dex_file_loader1(GetMultiDexSrc1());
+ ASSERT_TRUE(dex_file_loader1.Open(/* verify= */ true, kVerifyChecksum, &error_msg, &multi1))
+ << error_msg;
ASSERT_GT(multi1.size(), 1u);
std::vector<std::unique_ptr<const DexFile>> multi2;
- ASSERT_TRUE(dex_file_loader.Open(GetMultiDexSrc2().c_str(),
- GetMultiDexSrc2().c_str(),
- /* verify= */ true,
- kVerifyChecksum,
- &error_msg,
- &multi2)) << error_msg;
+ ArtDexFileLoader dex_file_loader2(GetMultiDexSrc2());
+ ASSERT_TRUE(dex_file_loader2.Open(/* verify= */ true, kVerifyChecksum, &error_msg, &multi2))
+ << error_msg;
ASSERT_GT(multi2.size(), 1u);
ASSERT_EQ(multi1[0]->GetLocationChecksum(), multi2[0]->GetLocationChecksum());
diff --git a/runtime/dexopt_test.cc b/runtime/dexopt_test.cc
index 1f44a67..6ba7573 100644
--- a/runtime/dexopt_test.cc
+++ b/runtime/dexopt_test.cc
@@ -120,10 +120,9 @@
// doesn't get an empty profile and changes the filter to verify.
std::string error_msg;
std::vector<std::unique_ptr<const DexFile>> dex_files;
- const ArtDexFileLoader dex_file_loader;
+ ArtDexFileLoader dex_file_loader(dex_location);
ASSERT_TRUE(dex_file_loader.Open(
- dex_location.c_str(), dex_location.c_str(), /*verify=*/ false, /*verify_checksum=*/ false,
- &error_msg, &dex_files));
+ /*verify=*/false, /*verify_checksum=*/false, &error_msg, &dex_files));
EXPECT_GE(dex_files.size(), 1U);
std::unique_ptr<const DexFile>& dex_file = dex_files[0];
ProfileCompilationInfo info;
diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc
index 4860509..02ad72b 100644
--- a/runtime/gc/space/image_space.cc
+++ b/runtime/gc/space/image_space.cc
@@ -3420,7 +3420,6 @@
return false;
}
- const ArtDexFileLoader dex_file_loader;
size_t dex_file_index = 0;
for (const OatDexFile* oat_dex_file : oat_file.GetOatDexFiles()) {
// Skip multidex locations - These will be checked when we visit their
@@ -3437,7 +3436,7 @@
std::vector<uint32_t> checksums;
std::vector<std::string> dex_locations_ignored;
- if (!dex_file_loader.GetMultiDexChecksums(
+ if (!ArtDexFileLoader::GetMultiDexChecksums(
dex_file_location.c_str(), &checksums, &dex_locations_ignored, error_msg, dex_fd)) {
*error_msg = StringPrintf("ValidateOatFile failed to get checksums of dex file '%s' "
"referenced by oat file %s: %s",
diff --git a/runtime/hidden_api_test.cc b/runtime/hidden_api_test.cc
index a3d5db1..c2c40c5 100644
--- a/runtime/hidden_api_test.cc
+++ b/runtime/hidden_api_test.cc
@@ -63,12 +63,11 @@
/* out */ std::vector<std::unique_ptr<const DexFile>>* dex_files,
/* out */ ObjPtr<mirror::ClassLoader>* class_loader,
/* out */ std::string* error_msg) REQUIRES_SHARED(Locks::mutator_lock_) {
- if (!ArtDexFileLoader().Open(path.c_str(),
- path,
- /* verify= */ true,
- /* verify_checksum= */ true,
- error_msg,
- dex_files)) {
+ ArtDexFileLoader dex_file_loader(path);
+ if (!dex_file_loader.Open(/* verify= */ true,
+ /* verify_checksum= */ true,
+ error_msg,
+ dex_files)) {
return false;
}
diff --git a/runtime/oat_file.cc b/runtime/oat_file.cc
index de14835..ab26ee9 100644
--- a/runtime/oat_file.cc
+++ b/runtime/oat_file.cc
@@ -787,30 +787,24 @@
if (i == external_dex_files_.size()) {
std::vector<std::unique_ptr<const DexFile>> new_dex_files;
// No dex files, load it from location.
- const ArtDexFileLoader dex_file_loader;
bool loaded = false;
CHECK(zip_fd == -1 || dex_fds.empty()); // Allow only the supported combinations.
if (zip_fd != -1) {
- loaded = dex_file_loader.OpenZip(zip_fd,
- dex_file_location,
- /*verify=*/false,
- /*verify_checksum=*/false,
- /*allow_no_dex_files=*/false,
- error_msg,
- &new_dex_files);
+ ArtDexFileLoader dex_file_loader(zip_fd, dex_file_location);
+ loaded = dex_file_loader.Open(/*verify=*/false,
+ /*verify_checksum=*/false,
+ error_msg,
+ &new_dex_files);
} else if (dex_fd != -1) {
// Note that we assume dex_fds are backing by jars.
- loaded = dex_file_loader.OpenZipFromOwnedFd(dex_fd,
- dex_file_location,
- /*verify=*/false,
- /*verify_checksum=*/false,
- /*allow_no_dex_files=*/false,
- error_msg,
- &new_dex_files);
+ ArtDexFileLoader dex_file_loader(DupCloexec(dex_fd), dex_file_location);
+ loaded = dex_file_loader.Open(/*verify=*/false,
+ /*verify_checksum=*/false,
+ error_msg,
+ &new_dex_files);
} else {
- loaded = dex_file_loader.Open(dex_file_name.c_str(),
- dex_file_location,
- /*verify=*/false,
+ ArtDexFileLoader dex_file_loader(dex_file_name.c_str(), dex_file_location);
+ loaded = dex_file_loader.Open(/*verify=*/false,
/*verify_checksum=*/false,
error_msg,
&new_dex_files);
@@ -1806,20 +1800,16 @@
} else {
// No need for any verification when loading dex files as we already have
// a vdex file.
- const ArtDexFileLoader dex_file_loader;
bool loaded = false;
if (zip_fd != -1) {
- loaded = dex_file_loader.OpenZip(zip_fd,
- dex_location,
- /*verify=*/false,
- /*verify_checksum=*/false,
- /*allow_no_dex_files=*/false,
- error_msg,
- &oat_file->external_dex_files_);
+ ArtDexFileLoader dex_file_loader(zip_fd, dex_location);
+ loaded = dex_file_loader.Open(/*verify=*/false,
+ /*verify_checksum=*/false,
+ error_msg,
+ &oat_file->external_dex_files_);
} else {
- loaded = dex_file_loader.Open(dex_location.c_str(),
- dex_location,
- /*verify=*/false,
+ ArtDexFileLoader dex_file_loader(dex_location);
+ loaded = dex_file_loader.Open(/*verify=*/false,
/*verify_checksum=*/false,
error_msg,
&oat_file->external_dex_files_);
@@ -2250,15 +2240,9 @@
ScopedTrace trace(__PRETTY_FUNCTION__);
static constexpr bool kVerify = false;
static constexpr bool kVerifyChecksum = false;
- const ArtDexFileLoader dex_file_loader;
- return dex_file_loader.Open(dex_file_pointer_,
- FileSize(),
- dex_file_location_,
- dex_file_location_checksum_,
- this,
- kVerify,
- kVerifyChecksum,
- error_msg);
+ ArtDexFileLoader dex_file_loader(dex_file_pointer_, FileSize(), dex_file_location_);
+ return dex_file_loader.Open(
+ dex_file_location_checksum_, this, kVerify, kVerifyChecksum, error_msg);
}
uint32_t OatDexFile::GetOatClassOffset(uint16_t class_def_index) const {
diff --git a/runtime/oat_file_assistant.cc b/runtime/oat_file_assistant.cc
index 1b49ce9..d324a24 100644
--- a/runtime/oat_file_assistant.cc
+++ b/runtime/oat_file_assistant.cc
@@ -726,14 +726,13 @@
if (!required_dex_checksums_attempted_) {
required_dex_checksums_attempted_ = true;
std::vector<uint32_t> checksums;
- const ArtDexFileLoader dex_file_loader;
std::vector<std::string> dex_locations_ignored;
- if (dex_file_loader.GetMultiDexChecksums(dex_location_.c_str(),
- &checksums,
- &dex_locations_ignored,
- &cached_required_dex_checksums_error_,
- zip_fd_,
- &zip_file_only_contains_uncompressed_dex_)) {
+ if (ArtDexFileLoader::GetMultiDexChecksums(dex_location_.c_str(),
+ &checksums,
+ &dex_locations_ignored,
+ &cached_required_dex_checksums_error_,
+ zip_fd_,
+ &zip_file_only_contains_uncompressed_dex_)) {
if (checksums.empty()) {
// The only valid case here is for APKs without dex files.
VLOG(oat) << "No dex file found in " << dex_location_;
diff --git a/runtime/oat_file_assistant_context.cc b/runtime/oat_file_assistant_context.cc
index 4bd83b7..c3fb73d 100644
--- a/runtime/oat_file_assistant_context.cc
+++ b/runtime/oat_file_assistant_context.cc
@@ -158,8 +158,7 @@
std::vector<uint32_t> checksums;
std::vector<std::string> dex_locations;
- ArtDexFileLoader dex_file_loader;
- if (!dex_file_loader.GetMultiDexChecksums(
+ if (!ArtDexFileLoader::GetMultiDexChecksums(
runtime_options_->boot_class_path[bcp_index].c_str(),
&checksums,
&dex_locations,
diff --git a/runtime/oat_file_assistant_test.cc b/runtime/oat_file_assistant_test.cc
index 45f7631..baa3094 100644
--- a/runtime/oat_file_assistant_test.cc
+++ b/runtime/oat_file_assistant_test.cc
@@ -117,10 +117,8 @@
bool InsertNewBootClasspathEntry(const std::string& src, std::string* error_msg) {
std::vector<std::unique_ptr<const DexFile>> dex_files;
- ArtDexFileLoader dex_file_loader;
- if (!dex_file_loader.Open(src.c_str(),
- src,
- /*verify=*/true,
+ ArtDexFileLoader dex_file_loader(src);
+ if (!dex_file_loader.Open(/*verify=*/true,
/*verify_checksum=*/false,
error_msg,
&dex_files)) {
diff --git a/runtime/oat_file_manager.cc b/runtime/oat_file_manager.cc
index 71af566..7d68cca 100644
--- a/runtime/oat_file_manager.cc
+++ b/runtime/oat_file_manager.cc
@@ -450,10 +450,8 @@
if (dex_files.empty()) {
std::string error_msg;
static constexpr bool kVerifyChecksum = true;
- const ArtDexFileLoader dex_file_loader;
- if (!dex_file_loader.Open(dex_location,
- dex_location,
- Runtime::Current()->IsVerificationEnabled(),
+ ArtDexFileLoader dex_file_loader(dex_location);
+ if (!dex_file_loader.Open(Runtime::Current()->IsVerificationEnabled(),
kVerifyChecksum,
/*out*/ &error_msg,
&dex_files)) {
@@ -556,11 +554,10 @@
std::vector<std::unique_ptr<const DexFile>> dex_files;
for (size_t i = 0; i < dex_mem_maps.size(); ++i) {
static constexpr bool kVerifyChecksum = true;
- const ArtDexFileLoader dex_file_loader;
+ ArtDexFileLoader dex_file_loader(std::move(dex_mem_maps[i]),
+ DexFileLoader::GetMultiDexLocation(i, dex_location.c_str()));
std::unique_ptr<const DexFile> dex_file(dex_file_loader.Open(
- DexFileLoader::GetMultiDexLocation(i, dex_location.c_str()),
dex_headers[i]->checksum_,
- std::move(dex_mem_maps[i]),
/* verify= */ (vdex_file == nullptr) && Runtime::Current()->IsVerificationEnabled(),
kVerifyChecksum,
&error_msg));
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index 040d819..86c7772 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -1291,7 +1291,6 @@
std::vector<std::unique_ptr<const DexFile>>* dex_files) {
DCHECK(dex_files != nullptr) << "OpenDexFiles: out-param is nullptr";
size_t failure_count = 0;
- const ArtDexFileLoader dex_file_loader;
for (size_t i = 0; i < dex_filenames.size(); i++) {
const char* dex_filename = dex_filenames[i].c_str();
const char* dex_location = dex_locations[i].c_str();
@@ -1303,13 +1302,8 @@
continue;
}
bool verify = Runtime::Current()->IsVerificationEnabled();
- if (!dex_file_loader.Open(dex_filename,
- dex_fd,
- dex_location,
- verify,
- kVerifyChecksum,
- &error_msg,
- dex_files)) {
+ ArtDexFileLoader dex_file_loader(dex_filename, dex_fd, dex_location);
+ if (!dex_file_loader.Open(verify, kVerifyChecksum, &error_msg, dex_files)) {
LOG(WARNING) << "Failed to open .dex from file '" << dex_filename << "' / fd " << dex_fd
<< ": " << error_msg;
++failure_count;
diff --git a/runtime/sdk_checker.cc b/runtime/sdk_checker.cc
index 1dbe39c..9097dc6 100644
--- a/runtime/sdk_checker.cc
+++ b/runtime/sdk_checker.cc
@@ -30,16 +30,13 @@
std::vector<std::string> dex_file_paths;
Split(public_sdk, ':', &dex_file_paths);
- ArtDexFileLoader dex_loader;
-
std::unique_ptr<SdkChecker> sdk_checker(new SdkChecker());
for (const std::string& path : dex_file_paths) {
- if (!dex_loader.Open(path.c_str(),
- path,
- /*verify=*/ true,
- /*verify_checksum*/ false,
- error_msg,
- &sdk_checker->sdk_dex_files_)) {
+ DexFileLoader dex_file_loader(path);
+ if (!dex_file_loader.Open(/*verify=*/true,
+ /*verify_checksum*/ false,
+ error_msg,
+ &sdk_checker->sdk_dex_files_)) {
return nullptr;
}
}
diff --git a/runtime/vdex_file.cc b/runtime/vdex_file.cc
index 6ad8a0f..bdead55 100644
--- a/runtime/vdex_file.cc
+++ b/runtime/vdex_file.cc
@@ -215,7 +215,6 @@
bool VdexFile::OpenAllDexFiles(std::vector<std::unique_ptr<const DexFile>>* dex_files,
std::string* error_msg) const {
- const ArtDexFileLoader dex_file_loader;
size_t i = 0;
for (const uint8_t* dex_file_start = GetNextDexFileData(nullptr, i);
dex_file_start != nullptr;
@@ -224,10 +223,8 @@
// TODO: Supply the location information for a vdex file.
static constexpr char kVdexLocation[] = "";
std::string location = DexFileLoader::GetMultiDexLocation(i, kVdexLocation);
- std::unique_ptr<const DexFile> dex(dex_file_loader.Open(dex_file_start,
- size,
- location,
- GetLocationChecksum(i),
+ ArtDexFileLoader dex_file_loader(dex_file_start, size, location);
+ std::unique_ptr<const DexFile> dex(dex_file_loader.Open(GetLocationChecksum(i),
/*oat_dex_file=*/nullptr,
/*verify=*/false,
/*verify_checksum=*/false,
diff --git a/test/674-hiddenapi/hiddenapi.cc b/test/674-hiddenapi/hiddenapi.cc
index 5fa2532..f1b0c18 100644
--- a/test/674-hiddenapi/hiddenapi.cc
+++ b/test/674-hiddenapi/hiddenapi.cc
@@ -59,12 +59,10 @@
const jint int_index = static_cast<jint>(index);
opened_dex_files.push_back(std::vector<std::unique_ptr<const DexFile>>());
- ArtDexFileLoader dex_loader;
+ DexFileLoader dex_loader(path);
std::string error_msg;
- if (!dex_loader.Open(path,
- path,
- /* verify */ false,
+ if (!dex_loader.Open(/* verify */ false,
/* verify_checksum */ true,
&error_msg,
&opened_dex_files[index])) {
diff --git a/test/983-source-transform-verify/source_transform_art.cc b/test/983-source-transform-verify/source_transform_art.cc
index a1916a0..289874b 100644
--- a/test/983-source-transform-verify/source_transform_art.cc
+++ b/test/983-source-transform-verify/source_transform_art.cc
@@ -41,12 +41,9 @@
CHECK_LE(static_cast<jint>(header_file_size), class_data_len);
class_data_len = static_cast<jint>(header_file_size);
- const ArtDexFileLoader dex_file_loader;
+ ArtDexFileLoader dex_file_loader(class_data, class_data_len, "fake_location.dex");
std::string error;
- std::unique_ptr<const DexFile> dex(dex_file_loader.Open(class_data,
- class_data_len,
- "fake_location.dex",
- /*location_checksum*/ 0,
+ std::unique_ptr<const DexFile> dex(dex_file_loader.Open(/*location_checksum*/ 0,
/*oat_dex_file*/ nullptr,
/*verify*/ true,
/*verify_checksum*/ true,
diff --git a/tools/art_verifier/art_verifier.cc b/tools/art_verifier/art_verifier.cc
index 2f2562b..e68d2ca 100644
--- a/tools/art_verifier/art_verifier.cc
+++ b/tools/art_verifier/art_verifier.cc
@@ -42,11 +42,9 @@
bool LoadDexFile(const std::string& dex_filename,
std::vector<std::unique_ptr<const DexFile>>* dex_files) {
- const ArtDexFileLoader dex_file_loader;
+ ArtDexFileLoader dex_file_loader(dex_filename);
std::string error_msg;
- if (!dex_file_loader.Open(dex_filename.c_str(),
- dex_filename.c_str(),
- /* verify= */ true,
+ if (!dex_file_loader.Open(/* verify= */ true,
/* verify_checksum= */ true,
&error_msg,
dex_files)) {
diff --git a/tools/dexanalyze/dexanalyze.cc b/tools/dexanalyze/dexanalyze.cc
index f0ce4c4..0a3cd8c 100644
--- a/tools/dexanalyze/dexanalyze.cc
+++ b/tools/dexanalyze/dexanalyze.cc
@@ -14,20 +14,21 @@
* limitations under the License.
*/
+#include <android-base/file.h>
+
#include <cstdint>
#include <iostream>
#include <set>
#include <sstream>
-#include <android-base/file.h>
-
-#include "dexanalyze_bytecode.h"
-#include "dexanalyze_experiments.h"
-#include "dexanalyze_strings.h"
+#include "base/mem_map.h"
#include "dex/code_item_accessors-inl.h"
#include "dex/dex_file.h"
#include "dex/dex_file_loader.h"
#include "dex/dex_instruction-inl.h"
+#include "dexanalyze_bytecode.h"
+#include "dexanalyze_experiments.h"
+#include "dexanalyze_strings.h"
namespace art {
namespace dexanalyze {
@@ -207,15 +208,13 @@
return kExitCodeFailedToOpenFile;
}
std::vector<std::unique_ptr<const DexFile>> dex_files;
- const DexFileLoader dex_file_loader;
- if (!dex_file_loader.OpenAll(reinterpret_cast<const uint8_t*>(content.data()),
- content.size(),
- filename.c_str(),
- options.run_dex_file_verifier_,
- options.verify_checksum_,
- &error_code,
- &error_msg,
- &dex_files)) {
+ DexFileLoader dex_file_loader(
+ reinterpret_cast<const uint8_t*>(content.data()), content.size(), filename);
+ if (!dex_file_loader.Open(options.run_dex_file_verifier_,
+ options.verify_checksum_,
+ &error_code,
+ &error_msg,
+ &dex_files)) {
LOG(ERROR) << "OpenAll failed for " + filename << " with " << error_msg << std::endl;
return kExitCodeFailedToOpenDex;
}
@@ -240,6 +239,7 @@
} // namespace art
int main(int argc, char** argv) {
+ art::MemMap::Init();
return art::dexanalyze::DexAnalyze::Run(argc, argv);
}
diff --git a/tools/hiddenapi/hiddenapi.cc b/tools/hiddenapi/hiddenapi.cc
index c4e7d40..5c750af 100644
--- a/tools/hiddenapi/hiddenapi.cc
+++ b/tools/hiddenapi/hiddenapi.cc
@@ -246,8 +246,8 @@
class ClassPath final {
public:
- ClassPath(const std::vector<std::string>& dex_paths, bool open_writable, bool ignore_empty) {
- OpenDexFiles(dex_paths, open_writable, ignore_empty);
+ ClassPath(const std::vector<std::string>& dex_paths, bool ignore_empty) {
+ OpenDexFiles(dex_paths, ignore_empty);
}
template <typename Fn>
@@ -292,47 +292,18 @@
}
private:
- void OpenDexFiles(const std::vector<std::string>& dex_paths,
- bool open_writable,
- bool ignore_empty) {
- ArtDexFileLoader dex_loader;
+ void OpenDexFiles(const std::vector<std::string>& dex_paths, bool ignore_empty) {
std::string error_msg;
- if (open_writable) {
- for (const std::string& filename : dex_paths) {
- File fd(filename.c_str(), O_RDWR, /* check_usage= */ false);
- CHECK_NE(fd.Fd(), -1) << "Unable to open file '" << filename << "': " << strerror(errno);
-
- // Memory-map the dex file with MAP_SHARED flag so that changes in memory
- // propagate to the underlying file. We run dex file verification as if
- // the dex file was not in boot claass path to check basic assumptions,
- // such as that at most one of public/private/protected flag is set.
- // We do those checks here and skip them when loading the processed file
- // into boot class path.
- std::unique_ptr<const DexFile> dex_file(dex_loader.OpenDex(fd.Release(),
- /* location= */ filename,
- /* verify= */ true,
- /* verify_checksum= */ true,
- /* mmap_shared= */ true,
- &error_msg));
- CHECK(dex_file.get() != nullptr) << "Open failed for '" << filename << "' " << error_msg;
- CHECK(dex_file->IsStandardDexFile()) << "Expected a standard dex file '" << filename << "'";
- CHECK(dex_file->EnableWrite())
- << "Failed to enable write permission for '" << filename << "'";
- dex_files_.push_back(std::move(dex_file));
- }
- } else {
- for (const std::string& filename : dex_paths) {
- bool success = dex_loader.Open(filename.c_str(),
- /* location= */ filename,
- /* verify= */ true,
- /* verify_checksum= */ true,
- &error_msg,
- &dex_files_);
- // If requested ignore a jar with no classes.dex files.
- if (!success && ignore_empty && error_msg != "Entry not found") {
- CHECK(success) << "Open failed for '" << filename << "' " << error_msg;
- }
+ for (const std::string& filename : dex_paths) {
+ DexFileLoader dex_file_loader(filename);
+ bool success = dex_file_loader.Open(/* verify= */ true,
+ /* verify_checksum= */ true,
+ &error_msg,
+ &dex_files_);
+ // If requested ignore a jar with no classes.dex files.
+ if (!success && ignore_empty && error_msg != "Entry not found") {
+ CHECK(success) << "Open failed for '" << filename << "' " << error_msg;
}
}
}
@@ -781,11 +752,9 @@
void ReloadDex(const char* filename) {
std::string error_msg;
- ArtDexFileLoader loader;
+ ArtDexFileLoader loader(filename);
std::vector<std::unique_ptr<const DexFile>> dex_files;
- bool ok = loader.Open(filename,
- filename,
- /*verify*/ true,
+ bool ok = loader.Open(/*verify*/ true,
/*verify_checksum*/ true,
&error_msg,
&dex_files);
@@ -912,9 +881,7 @@
const std::string& input_path = boot_dex_paths_[i];
const std::string& output_path = output_dex_paths_[i];
- ClassPath boot_classpath({ input_path },
- /* open_writable= */ false,
- /* ignore_empty= */ false);
+ ClassPath boot_classpath({input_path}, /* ignore_empty= */ false);
DexFileEditor dex_editor;
for (const DexFile* input_dex : boot_classpath.GetDexFiles()) {
HiddenapiClassDataBuilder builder(*input_dex);
@@ -1032,9 +999,7 @@
std::set<std::string> unresolved;
// Open all dex files.
- ClassPath boot_classpath(boot_dex_paths_,
- /* open_writable= */ false,
- /* ignore_empty= */ false);
+ ClassPath boot_classpath(boot_dex_paths_, /* ignore_empty= */ false);
Hierarchy boot_hierarchy(boot_classpath, fragment_, verbose_);
// Mark all boot dex members private.
@@ -1043,9 +1008,7 @@
});
// Open all dependency API stub dex files.
- ClassPath dependency_classpath(dependency_stub_dex_paths_,
- /* open_writable= */ false,
- /* ignore_empty= */ false);
+ ClassPath dependency_classpath(dependency_stub_dex_paths_, /* ignore_empty= */ false);
// Mark all dependency API stub dex members as coming from the dependency.
dependency_classpath.ForEachDexMember([&](const DexMember& boot_member) {
@@ -1057,9 +1020,7 @@
// Ignore any empty stub jars as it just means that they provide no APIs
// for the current kind, e.g. framework-sdkextensions does not provide
// any public APIs.
- ClassPath stub_classpath(android::base::Split(cp_entry.first, ":"),
- /* open_writable= */ false,
- /* ignore_empty= */ true);
+ ClassPath stub_classpath(android::base::Split(cp_entry.first, ":"), /*ignore_empty=*/true);
Hierarchy stub_hierarchy(stub_classpath, fragment_, verbose_);
const ApiStubs::Kind stub_api = cp_entry.second;
diff --git a/tools/hiddenapi/hiddenapi_test.cc b/tools/hiddenapi/hiddenapi_test.cc
index f408c66..36e80c5 100644
--- a/tools/hiddenapi/hiddenapi_test.cc
+++ b/tools/hiddenapi/hiddenapi_test.cc
@@ -106,7 +106,6 @@
}
std::unique_ptr<const DexFile> OpenDex(const ScratchFile& file) {
- ArtDexFileLoader dex_loader;
std::string error_msg;
File fd(file.GetFilename(), O_RDONLY, /* check_usage= */ false);
@@ -115,9 +114,9 @@
UNREACHABLE();
}
- std::unique_ptr<const DexFile> dex_file(dex_loader.OpenDex(
- fd.Release(), /* location= */ file.GetFilename(), /* verify= */ true,
- /* verify_checksum= */ true, /* mmap_shared= */ false, &error_msg));
+ ArtDexFileLoader dex_loader(fd.Release(), file.GetFilename());
+ std::unique_ptr<const DexFile> dex_file(dex_loader.Open(
+ /* verify= */ true, /* verify_checksum= */ true, /* mmap_shared= */ false, &error_msg));
if (dex_file.get() == nullptr) {
LOG(FATAL) << "Open failed for '" << file.GetFilename() << "' " << error_msg;
UNREACHABLE();
diff --git a/tools/veridex/Android.bp b/tools/veridex/Android.bp
index d5f5162..7b120cf 100644
--- a/tools/veridex/Android.bp
+++ b/tools/veridex/Android.bp
@@ -40,6 +40,7 @@
static_libs: [
"libdexfile",
"libartbase",
+ "libartpalette",
"libbase",
"liblog",
"libz",
diff --git a/tools/veridex/veridex.cc b/tools/veridex/veridex.cc
index ae1c33e..2ef236d 100644
--- a/tools/veridex/veridex.cc
+++ b/tools/veridex/veridex.cc
@@ -19,6 +19,10 @@
#include <android-base/file.h>
#include <android-base/strings.h>
+#include <cstdlib>
+#include <sstream>
+
+#include "base/mem_map.h"
#include "dex/dex_file.h"
#include "dex/dex_file_loader.h"
#include "hidden_api.h"
@@ -26,9 +30,6 @@
#include "precise_hidden_api_finder.h"
#include "resolver.h"
-#include <cstdlib>
-#include <sstream>
-
namespace art {
static VeriClass z_(Primitive::Type::kPrimBoolean, 0, nullptr);
@@ -301,18 +302,13 @@
return false;
}
- const DexFileLoader dex_file_loader;
DexFileLoaderErrorCode error_code;
static constexpr bool kVerifyChecksum = true;
static constexpr bool kRunDexFileVerifier = true;
- if (!dex_file_loader.OpenAll(reinterpret_cast<const uint8_t*>(content.data()),
- content.size(),
- filename.c_str(),
- kRunDexFileVerifier,
- kVerifyChecksum,
- &error_code,
- error_msg,
- dex_files)) {
+ DexFileLoader dex_file_loader(
+ reinterpret_cast<const uint8_t*>(content.data()), content.size(), filename.c_str());
+ if (!dex_file_loader.Open(
+ kRunDexFileVerifier, kVerifyChecksum, &error_code, error_msg, dex_files)) {
if (error_code == DexFileLoaderErrorCode::kEntryNotFound) {
LOG(INFO) << "No .dex found, skipping analysis.";
return true;
@@ -343,5 +339,6 @@
} // namespace art
int main(int argc, char** argv) {
+ art::MemMap::Init();
return art::Veridex::Run(argc, argv);
}