diff options
author | 2018-06-28 16:59:00 +0000 | |
---|---|---|
committer | 2018-06-28 16:59:00 +0000 | |
commit | d20a4d76c33cd6e609ad6b1b3cde09fdcbdde05c (patch) | |
tree | ccbf6e69ca17f4677186f4e148e1f9baf8bc7ae4 | |
parent | b5271dd44a30f498689e503340d3c8d01bf31f07 (diff) | |
parent | b095f022a9683a9123018c01e22595cf969fd88b (diff) |
Merge "Refactor DexFile ownership"
-rw-r--r-- | compiler/optimizing/optimizing_unit_test.h | 6 | ||||
-rw-r--r-- | libdexfile/dex/art_dex_file_loader.cc | 110 | ||||
-rw-r--r-- | libdexfile/dex/art_dex_file_loader.h | 10 | ||||
-rw-r--r-- | libdexfile/dex/compact_dex_file.cc | 16 | ||||
-rw-r--r-- | libdexfile/dex/compact_dex_file.h | 9 | ||||
-rw-r--r-- | libdexfile/dex/dex_file.cc | 96 | ||||
-rw-r--r-- | libdexfile/dex/dex_file.h | 87 | ||||
-rw-r--r-- | libdexfile/dex/dex_file_loader.cc | 92 | ||||
-rw-r--r-- | libdexfile/dex/dex_file_loader.h | 10 | ||||
-rw-r--r-- | libdexfile/dex/dex_file_verifier_test.cc | 5 | ||||
-rw-r--r-- | libdexfile/dex/standard_dex_file.h | 12 | ||||
-rw-r--r-- | runtime/class_linker_test.cc | 12 |
12 files changed, 261 insertions, 204 deletions
diff --git a/compiler/optimizing/optimizing_unit_test.h b/compiler/optimizing/optimizing_unit_test.h index a9bc5664c0..a627f65ed4 100644 --- a/compiler/optimizing/optimizing_unit_test.h +++ b/compiler/optimizing/optimizing_unit_test.h @@ -129,12 +129,10 @@ class OptimizingUnitTestHelper { // Create the dex file based on the fake data. Call the constructor so that we can use virtual // functions. Don't use the arena for the StandardDexFile otherwise the dex location leaks. dex_files_.emplace_back(new StandardDexFile( - dex_data, - sizeof(StandardDexFile::Header), + std::make_unique<NonOwningDexFileContainer>(dex_data, sizeof(StandardDexFile::Header)), "no_location", /*location_checksum*/ 0, - /*oat_dex_file*/ nullptr, - /*container*/ nullptr)); + /*oat_dex_file*/ nullptr)); return new (allocator) HGraph( allocator, diff --git a/libdexfile/dex/art_dex_file_loader.cc b/libdexfile/dex/art_dex_file_loader.cc index 392ce1e7f5..05986ecce3 100644 --- a/libdexfile/dex/art_dex_file_loader.cc +++ b/libdexfile/dex/art_dex_file_loader.cc @@ -71,6 +71,14 @@ class MemMapContainer : public DexFileContainer { } } + const uint8_t* Begin() OVERRIDE { + return mem_map_->Begin(); + } + + size_t Size() OVERRIDE { + return mem_map_->Size(); + } + private: std::unique_ptr<MemMap> mem_map_; DISALLOW_COPY_AND_ASSIGN(MemMapContainer); @@ -164,17 +172,14 @@ std::unique_ptr<const DexFile> ArtDexFileLoader::Open(const uint8_t* base, bool verify_checksum, std::string* error_msg) const { ScopedTrace trace(std::string("Open dex file from RAM ") + location); - return OpenCommon(base, - size, - /*data_base*/ nullptr, - /*data_size*/ 0u, + return OpenCommon(std::make_unique<NonOwningDexFileContainer>(base, size), + std::make_unique<EmptyDexFileContainer>(), location, location_checksum, oat_dex_file, verify, verify_checksum, error_msg, - /*container*/ nullptr, /*verify_result*/ nullptr); } @@ -194,18 +199,16 @@ std::unique_ptr<const DexFile> ArtDexFileLoader::Open(const std::string& locatio return nullptr; } - std::unique_ptr<DexFile> dex_file = OpenCommon(map->Begin(), - map->Size(), - /*data_base*/ nullptr, - /*data_size*/ 0u, - location, - location_checksum, - kNoOatDexFile, - verify, - verify_checksum, - error_msg, - std::make_unique<MemMapContainer>(std::move(map)), - /*verify_result*/ nullptr); + std::unique_ptr<DexFile> dex_file = + OpenCommon(std::make_unique<MemMapContainer>(std::move(map)), + std::make_unique<EmptyDexFileContainer>(), + location, + location_checksum, + kNoOatDexFile, + verify, + verify_checksum, + error_msg, + /*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", @@ -323,18 +326,16 @@ std::unique_ptr<const DexFile> ArtDexFileLoader::OpenFile(int fd, const DexFile::Header* dex_header = reinterpret_cast<const DexFile::Header*>(map->Begin()); - std::unique_ptr<DexFile> dex_file = OpenCommon(map->Begin(), - map->Size(), - /*data_base*/ nullptr, - /*data_size*/ 0u, - location, - dex_header->checksum_, - kNoOatDexFile, - verify, - verify_checksum, - error_msg, - std::make_unique<MemMapContainer>(std::move(map)), - /*verify_result*/ nullptr); + std::unique_ptr<DexFile> dex_file = + OpenCommon(std::make_unique<MemMapContainer>(std::move(map)), + std::make_unique<EmptyDexFileContainer>(), + location, + dex_header->checksum_, + kNoOatDexFile, + verify, + verify_checksum, + error_msg, + /*verify_result*/ nullptr); // Opening CompactDex is only supported from vdex files. if (dex_file != nullptr && dex_file->IsCompactDexFile()) { @@ -398,18 +399,16 @@ std::unique_ptr<const DexFile> ArtDexFileLoader::OpenOneDexFileFromZip( return nullptr; } VerifyResult verify_result; - std::unique_ptr<DexFile> dex_file = OpenCommon(map->Begin(), - map->Size(), - /*data_base*/ nullptr, - /*data_size*/ 0u, - location, - zip_entry->GetCrc32(), - kNoOatDexFile, - verify, - verify_checksum, - error_msg, - std::make_unique<MemMapContainer>(std::move(map)), - &verify_result); + std::unique_ptr<DexFile> dex_file = + OpenCommon(std::make_unique<MemMapContainer>(std::move(map)), + std::make_unique<EmptyDexFileContainer>(), + location, + zip_entry->GetCrc32(), + kNoOatDexFile, + verify, + verify_checksum, + error_msg, + &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()); @@ -506,29 +505,24 @@ bool ArtDexFileLoader::OpenAllDexFilesFromZip( } } -std::unique_ptr<DexFile> ArtDexFileLoader::OpenCommon(const uint8_t* base, - size_t size, - const uint8_t* data_base, - size_t data_size, - 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) { - std::unique_ptr<DexFile> dex_file = DexFileLoader::OpenCommon(base, - size, - data_base, - data_size, +std::unique_ptr<DexFile> ArtDexFileLoader::OpenCommon( + std::unique_ptr<DexFileContainer> main_section, + std::unique_ptr<DexFileContainer> data_section, + const std::string& location, + uint32_t location_checksum, + const OatDexFile* oat_dex_file, + bool verify, + bool verify_checksum, + std::string* error_msg, + VerifyResult* verify_result) { + std::unique_ptr<DexFile> dex_file = DexFileLoader::OpenCommon(std::move(main_section), + std::move(data_section), location, location_checksum, oat_dex_file, verify, verify_checksum, error_msg, - std::move(container), verify_result); // Check if this dex file is located in the framework directory. diff --git a/libdexfile/dex/art_dex_file_loader.h b/libdexfile/dex/art_dex_file_loader.h index a460aee60f..9f92b721a2 100644 --- a/libdexfile/dex/art_dex_file_loader.h +++ b/libdexfile/dex/art_dex_file_loader.h @@ -121,17 +121,17 @@ class ArtDexFileLoader : public DexFileLoader { std::string* error_msg, ZipOpenErrorCode* error_code) const; - static std::unique_ptr<DexFile> OpenCommon(const uint8_t* base, - size_t size, - const uint8_t* data_base, - size_t data_size, + // main_section points to the header and fixed-sized objects (ids, etc.) + // If not empty (Begin != nullptr) data_section points to the dex file's variable-sized + // objects such as strings, class_data_items, etc. + static std::unique_ptr<DexFile> OpenCommon(std::unique_ptr<DexFileContainer> main_section, + std::unique_ptr<DexFileContainer> data_section, 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); }; diff --git a/libdexfile/dex/compact_dex_file.cc b/libdexfile/dex/compact_dex_file.cc index 302b59ee91..4bd1675423 100644 --- a/libdexfile/dex/compact_dex_file.cc +++ b/libdexfile/dex/compact_dex_file.cc @@ -84,22 +84,16 @@ uint32_t CompactDexFile::CalculateChecksum() const { return CalculateChecksum(Begin(), Size(), DataBegin(), DataSize()); } -CompactDexFile::CompactDexFile(const uint8_t* base, - size_t size, - const uint8_t* data_begin, - size_t data_size, +CompactDexFile::CompactDexFile(std::unique_ptr<DexFileContainer> main_section, + std::unique_ptr<DexFileContainer> data_section, const std::string& location, uint32_t location_checksum, - const OatDexFile* oat_dex_file, - std::unique_ptr<DexFileContainer> container) - : DexFile(base, - size, - data_begin, - data_size, + const OatDexFile* oat_dex_file) + : DexFile(std::move(main_section), + std::move(data_section), location, location_checksum, oat_dex_file, - std::move(container), /*is_compact_dex*/ true), debug_info_offsets_(DataBegin() + GetHeader().debug_info_offsets_pos_, GetHeader().debug_info_base_, diff --git a/libdexfile/dex/compact_dex_file.h b/libdexfile/dex/compact_dex_file.h index affc9a20b0..ffaa9a7155 100644 --- a/libdexfile/dex/compact_dex_file.h +++ b/libdexfile/dex/compact_dex_file.h @@ -284,14 +284,11 @@ class CompactDexFile : public DexFile { virtual uint32_t CalculateChecksum() const OVERRIDE; private: - CompactDexFile(const uint8_t* base, - size_t size, - const uint8_t* data_begin, - size_t data_size, + CompactDexFile(std::unique_ptr<DexFileContainer> main_section, + std::unique_ptr<DexFileContainer> data_section, const std::string& location, uint32_t location_checksum, - const OatDexFile* oat_dex_file, - std::unique_ptr<DexFileContainer> container); + const OatDexFile* oat_dex_file); CompactOffsetTable::Accessor debug_info_offsets_; diff --git a/libdexfile/dex/dex_file.cc b/libdexfile/dex/dex_file.cc index f1f896058c..c2b478aded 100644 --- a/libdexfile/dex/dex_file.cc +++ b/libdexfile/dex/dex_file.cc @@ -73,61 +73,101 @@ uint32_t DexFile::ChecksumMemoryRange(const uint8_t* begin, size_t size) { } int DexFile::GetPermissions() const { - CHECK(container_.get() != nullptr); - return container_->GetPermissions(); + CHECK(main_section_ != nullptr); + return main_section_->GetPermissions(); } bool DexFile::IsReadOnly() const { - CHECK(container_.get() != nullptr); - return container_->IsReadOnly(); + CHECK(main_section_ != nullptr); + return main_section_->IsReadOnly(); } bool DexFile::EnableWrite() const { - CHECK(container_.get() != nullptr); - return container_->EnableWrite(); + CHECK(main_section_ != nullptr); + return main_section_->EnableWrite(); } bool DexFile::DisableWrite() const { - CHECK(container_.get() != nullptr); - return container_->DisableWrite(); + CHECK(main_section_ != nullptr); + return main_section_->DisableWrite(); } -DexFile::DexFile(const uint8_t* base, - size_t size, - const uint8_t* data_begin, - size_t data_size, +DexFile::DexFile(std::unique_ptr<DexFileContainer> main_section, + std::unique_ptr<DexFileContainer> data_section, const std::string& location, uint32_t location_checksum, const OatDexFile* oat_dex_file, - std::unique_ptr<DexFileContainer> container, bool is_compact_dex) - : begin_(base), - size_(size), - data_begin_(data_begin), - data_size_(data_size), + : main_section_(std::move(main_section)), location_(location), location_checksum_(location_checksum), - header_(reinterpret_cast<const Header*>(base)), - string_ids_(reinterpret_cast<const StringId*>(base + header_->string_ids_off_)), - type_ids_(reinterpret_cast<const TypeId*>(base + header_->type_ids_off_)), - field_ids_(reinterpret_cast<const FieldId*>(base + header_->field_ids_off_)), - method_ids_(reinterpret_cast<const MethodId*>(base + header_->method_ids_off_)), - proto_ids_(reinterpret_cast<const ProtoId*>(base + header_->proto_ids_off_)), - class_defs_(reinterpret_cast<const ClassDef*>(base + header_->class_defs_off_)), + header_(reinterpret_cast<const Header*>(main_section_->Begin())), + string_ids_(reinterpret_cast<const StringId*>(main_section_->Begin() + + header_->string_ids_off_)), + type_ids_(reinterpret_cast<const TypeId*>(main_section_->Begin() + header_->type_ids_off_)), + field_ids_(reinterpret_cast<const FieldId*>(main_section_->Begin() + + header_->field_ids_off_)), + method_ids_(reinterpret_cast<const MethodId*>(main_section_->Begin() + + header_->method_ids_off_)), + proto_ids_(reinterpret_cast<const ProtoId*>(main_section_->Begin() + + header_->proto_ids_off_)), + class_defs_(reinterpret_cast<const ClassDef*>(main_section_->Begin() + + header_->class_defs_off_)), method_handles_(nullptr), num_method_handles_(0), call_site_ids_(nullptr), num_call_site_ids_(0), oat_dex_file_(oat_dex_file), - container_(std::move(container)), is_compact_dex_(is_compact_dex), is_platform_dex_(false) { - CHECK(begin_ != nullptr) << GetLocation(); - CHECK_GT(size_, 0U) << GetLocation(); + CHECK(main_section_->Begin() != nullptr) << GetLocation(); + CHECK_GT(main_section_->Size(), 0U) << GetLocation(); // Check base (=header) alignment. // Must be 4-byte aligned to avoid undefined behavior when accessing // any of the sections via a pointer. - CHECK_ALIGNED(begin_, alignof(Header)); + CHECK_ALIGNED(main_section_->Begin(), alignof(Header)); + + data_section_ = std::move(data_section); + + InitializeSectionsFromMapList(); +} + +DexFile::DexFile(std::unique_ptr<DexFileContainer> main_section, + const std::string& location, + uint32_t location_checksum, + const OatDexFile* oat_dex_file, + bool is_compact_dex) + : main_section_(std::move(main_section)), + location_(location), + location_checksum_(location_checksum), + header_(reinterpret_cast<const Header*>(main_section_->Begin())), + string_ids_(reinterpret_cast<const StringId*>(main_section_->Begin() + + header_->string_ids_off_)), + type_ids_(reinterpret_cast<const TypeId*>(main_section_->Begin() + header_->type_ids_off_)), + field_ids_(reinterpret_cast<const FieldId*>(main_section_->Begin() + + header_->field_ids_off_)), + method_ids_(reinterpret_cast<const MethodId*>(main_section_->Begin() + + header_->method_ids_off_)), + proto_ids_(reinterpret_cast<const ProtoId*>(main_section_->Begin() + + header_->proto_ids_off_)), + class_defs_(reinterpret_cast<const ClassDef*>(main_section_->Begin() + + header_->class_defs_off_)), + method_handles_(nullptr), + num_method_handles_(0), + call_site_ids_(nullptr), + num_call_site_ids_(0), + oat_dex_file_(oat_dex_file), + is_compact_dex_(is_compact_dex), + is_platform_dex_(false) { + CHECK(main_section_->Begin() != nullptr) << GetLocation(); + CHECK_GT(main_section_->Size(), 0U) << GetLocation(); + // Check base (=header) alignment. + // Must be 4-byte aligned to avoid undefined behavior when accessing + // any of the sections via a pointer. + CHECK_ALIGNED(main_section_->Begin(), alignof(Header)); + + data_section_ = std::make_unique<NonOwningDexFileContainer>(main_section_->Begin(), + main_section_->Size()); InitializeSectionsFromMapList(); } diff --git a/libdexfile/dex/dex_file.h b/libdexfile/dex/dex_file.h index 67abdca148..c94c786699 100644 --- a/libdexfile/dex/dex_file.h +++ b/libdexfile/dex/dex_file.h @@ -56,11 +56,48 @@ class DexFileContainer { virtual bool IsReadOnly() = 0; virtual bool EnableWrite() = 0; virtual bool DisableWrite() = 0; + virtual const uint8_t* Begin() = 0; + virtual size_t Size() = 0; private: DISALLOW_COPY_AND_ASSIGN(DexFileContainer); }; +class EmptyDexFileContainer FINAL : public DexFileContainer { + public: + EmptyDexFileContainer() { } + ~EmptyDexFileContainer() { } + + int GetPermissions() OVERRIDE { return 0; } + bool IsReadOnly() OVERRIDE { return true; } + bool EnableWrite() OVERRIDE { return false; } + bool DisableWrite() OVERRIDE { return false; } + const uint8_t* Begin() OVERRIDE { return nullptr; } + size_t Size() OVERRIDE { return 0U; } + + private: + DISALLOW_COPY_AND_ASSIGN(EmptyDexFileContainer); +}; + +class NonOwningDexFileContainer FINAL : public DexFileContainer { + public: + NonOwningDexFileContainer(const uint8_t* begin, size_t size) : begin_(begin), size_(size) { } + ~NonOwningDexFileContainer() { } + + int GetPermissions() OVERRIDE { return 0; } + bool IsReadOnly() OVERRIDE { return true; } + bool EnableWrite() OVERRIDE { return false; } + bool DisableWrite() OVERRIDE { return false; } + const uint8_t* Begin() OVERRIDE { return begin_; } + size_t Size() OVERRIDE { return size_; } + + private: + const uint8_t* begin_; + size_t size_; + + DISALLOW_COPY_AND_ASSIGN(NonOwningDexFileContainer); +}; + // Dex file is the API that exposes native dex files (ordinary dex files) and CompactDex. // Originally, the dex file format used by ART was mostly the same as APKs. The only change was // quickened opcodes and layout optimizations. @@ -754,7 +791,7 @@ class DexFile { // Check that the offset is in bounds. // Note that although the specification says that 0 should be used if there // is no debug information, some applications incorrectly use 0xFFFFFFFF. - return (debug_info_off == 0 || debug_info_off >= data_size_) + return (debug_info_off == 0 || debug_info_off >= DataSize()) ? nullptr : DataBegin() + debug_info_off; } @@ -929,19 +966,19 @@ class DexFile { bool DisableWrite() const; const uint8_t* Begin() const { - return begin_; + return main_section_->Begin(); } size_t Size() const { - return size_; + return main_section_->Size(); } const uint8_t* DataBegin() const { - return data_begin_; + return data_section_->Begin(); } size_t DataSize() const { - return data_size_; + return data_section_->Size(); } template <typename T> @@ -1009,7 +1046,7 @@ class DexFile { } DexFileContainer* GetContainer() const { - return container_.get(); + return main_section_.get(); } // Changes the dex class data pointed to by data_ptr it to not have any hiddenapi flags. @@ -1021,14 +1058,25 @@ class DexFile { // First Dex format version supporting default methods. static const uint32_t kDefaultMethodsVersion = 37; - DexFile(const uint8_t* base, - size_t size, - const uint8_t* data_begin, - size_t data_size, + // For the two constructors, some notation needs explanation. + // Dex files consist of two sections: + // 1) "main" -- contains the header and fixed-sized objects (ids, etc.) + // 2) "data" -- contains variable-sized objects such as strings, class_data_items, etc. + // For StandardDexFile, both sections are addressed through one pointer. + // For CompactDexFile multiple dex files share one data section, but each has its + // own main section, and hence we need two pointers. + + DexFile(std::unique_ptr<DexFileContainer> main_section, + const std::string& location, + uint32_t location_checksum, + const OatDexFile* oat_dex_file, + bool is_compact_dex); + + DexFile(std::unique_ptr<DexFileContainer> main_section, + std::unique_ptr<DexFileContainer> data_section, const std::string& location, uint32_t location_checksum, const OatDexFile* oat_dex_file, - std::unique_ptr<DexFileContainer> container, bool is_compact_dex); // Top-level initializer that calls other Init methods. @@ -1040,17 +1088,11 @@ class DexFile { // Initialize section info for sections only found in map. Returns true on success. void InitializeSectionsFromMapList(); - // The base address of the memory mapping. - const uint8_t* const begin_; - - // The size of the underlying memory allocation in bytes. - const size_t size_; + // The container for the header and fixed portions. + std::unique_ptr<DexFileContainer> main_section_; - // The base address of the data section (same as Begin() for standard dex). - const uint8_t* const data_begin_; - - // The size of the data section. - const size_t data_size_; + // The container for the data section + std::unique_ptr<DexFileContainer> data_section_; // Typically the dex file name when available, alternatively some identifying string. // @@ -1098,9 +1140,6 @@ class DexFile { // null. mutable const OatDexFile* oat_dex_file_; - // Manages the underlying memory allocation. - std::unique_ptr<DexFileContainer> container_; - // If the dex file is a compact dex file. If false then the dex file is a standard dex file. const bool is_compact_dex_; diff --git a/libdexfile/dex/dex_file_loader.cc b/libdexfile/dex/dex_file_loader.cc index 457addf114..156f655150 100644 --- a/libdexfile/dex/dex_file_loader.cc +++ b/libdexfile/dex/dex_file_loader.cc @@ -54,8 +54,17 @@ class VectorContainer : public DexFileContainer { return false; } + uint8_t* Begin() OVERRIDE { + return vector_.data(); + } + + size_t Size() OVERRIDE { + return vector_.size(); + } + private: std::vector<uint8_t> vector_; + DISALLOW_COPY_AND_ASSIGN(VectorContainer); }; @@ -224,17 +233,14 @@ std::unique_ptr<const DexFile> DexFileLoader::Open(const uint8_t* base, bool verify, bool verify_checksum, std::string* error_msg) const { - return OpenCommon(base, - size, - /*data_base*/ nullptr, - /*data_size*/ 0, + return OpenCommon(std::make_unique<NonOwningDexFileContainer>(base, size), + std::make_unique<EmptyDexFileContainer>(), location, location_checksum, oat_dex_file, verify, verify_checksum, error_msg, - /*container*/ nullptr, /*verify_result*/ nullptr); } @@ -249,17 +255,14 @@ std::unique_ptr<const DexFile> DexFileLoader::OpenWithDataSection( bool verify, bool verify_checksum, std::string* error_msg) const { - return OpenCommon(base, - size, - data_base, - data_size, + return OpenCommon(std::make_unique<NonOwningDexFileContainer>(base, size), + std::make_unique<NonOwningDexFileContainer>(data_base, data_size), location, location_checksum, oat_dex_file, verify, verify_checksum, error_msg, - /*container*/ nullptr, /*verify_result*/ nullptr); } @@ -307,49 +310,47 @@ bool DexFileLoader::OpenAll( return false; } -std::unique_ptr<DexFile> DexFileLoader::OpenCommon(const uint8_t* base, - size_t size, - const uint8_t* data_base, - size_t data_size, +std::unique_ptr<DexFile> DexFileLoader::OpenCommon(std::unique_ptr<DexFileContainer> main_section, + std::unique_ptr<DexFileContainer> data_section, 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) { if (verify_result != nullptr) { *verify_result = VerifyResult::kVerifyNotAttempted; } std::unique_ptr<DexFile> dex_file; - if (size >= sizeof(StandardDexFile::Header) && StandardDexFile::IsMagicValid(base)) { - if (data_size != 0) { - CHECK_EQ(base, data_base) << "Unsupported for standard dex"; + if (main_section->Size() >= sizeof(StandardDexFile::Header) && + StandardDexFile::IsMagicValid(main_section->Begin())) { + if (data_section->Size() != 0) { + CHECK_EQ(main_section->Begin(), data_section->Begin()) << "Unsupported for standard dex"; } - dex_file.reset(new StandardDexFile(base, - size, + CHECK(main_section != nullptr); + CHECK(main_section->Begin() != nullptr); + dex_file.reset(new StandardDexFile(std::move(main_section), location, location_checksum, - oat_dex_file, - std::move(container))); - } else if (size >= sizeof(CompactDexFile::Header) && CompactDexFile::IsMagicValid(base)) { - if (data_base == nullptr) { + oat_dex_file)); + } else if (main_section->Size() >= sizeof(CompactDexFile::Header) && + CompactDexFile::IsMagicValid(main_section->Begin())) { + if (data_section->Begin() == nullptr) { // TODO: Is there a clean way to support both an explicit data section and reading the one // from the header. - CHECK_EQ(data_size, 0u); - const CompactDexFile::Header* const header = CompactDexFile::Header::At(base); - data_base = base + header->data_off_; - data_size = header->data_size_; + CHECK_EQ(data_section->Size(), 0u); + const CompactDexFile::Header* const header = + CompactDexFile::Header::At(main_section->Begin()); + data_section = + std::make_unique<NonOwningDexFileContainer>(main_section->Begin() + header->data_off_, + header->data_size_); } - dex_file.reset(new CompactDexFile(base, - size, - data_base, - data_size, + dex_file.reset(new CompactDexFile(std::move(main_section), + std::move(data_section), location, location_checksum, - oat_dex_file, - std::move(container))); + oat_dex_file)); // Disable verification for CompactDex input. verify = false; } else { @@ -409,19 +410,16 @@ std::unique_ptr<const DexFile> DexFileLoader::OpenOneDexFileFromZip( return nullptr; } VerifyResult verify_result; - std::unique_ptr<const DexFile> dex_file = OpenCommon( - map.data(), - map.size(), - /*data_base*/ nullptr, - /*data_size*/ 0u, - 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::make_unique<VectorContainer>(std::move(map)), + std::make_unique<EmptyDexFileContainer>(), + location, + zip_entry->GetCrc32(), + /*oat_dex_file*/ nullptr, + verify, + verify_checksum, + error_msg, + &verify_result); if (dex_file == nullptr) { if (verify_result == VerifyResult::kVerifyNotAttempted) { *error_code = ZipOpenErrorCode::kDexFileError; diff --git a/libdexfile/dex/dex_file_loader.h b/libdexfile/dex/dex_file_loader.h index 01532203eb..0bd6446b7b 100644 --- a/libdexfile/dex/dex_file_loader.h +++ b/libdexfile/dex/dex_file_loader.h @@ -161,17 +161,17 @@ class DexFileLoader { kVerifyFailed }; - static std::unique_ptr<DexFile> OpenCommon(const uint8_t* base, - size_t size, - const uint8_t* data_base, - size_t data_size, + // main_section points to the header and fixed-sized objects (ids, etc.) + // If not empty (Begin != nullptr) data_section points to the dex file's variable-sized + // objects such as strings, class_data_items, etc. + static std::unique_ptr<DexFile> OpenCommon(std::unique_ptr<DexFileContainer> main_section, + std::unique_ptr<DexFileContainer> data_section, 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: diff --git a/libdexfile/dex/dex_file_verifier_test.cc b/libdexfile/dex/dex_file_verifier_test.cc index c9bac0fef2..9d9f1bd025 100644 --- a/libdexfile/dex/dex_file_verifier_test.cc +++ b/libdexfile/dex/dex_file_verifier_test.cc @@ -56,7 +56,10 @@ static void FixUpChecksum(uint8_t* dex_file) { class DexFileVerifierTest : public testing::Test { protected: DexFile* GetDexFile(const uint8_t* dex_bytes, size_t length) { - return new StandardDexFile(dex_bytes, length, "tmp", 0, nullptr, nullptr); + return new StandardDexFile(std::make_unique<NonOwningDexFileContainer>(dex_bytes, length), + "tmp", + 0, + nullptr); } void VerifyModification(const char* dex_file_base64_content, diff --git a/libdexfile/dex/standard_dex_file.h b/libdexfile/dex/standard_dex_file.h index 999e5b99e9..0121d6039a 100644 --- a/libdexfile/dex/standard_dex_file.h +++ b/libdexfile/dex/standard_dex_file.h @@ -88,20 +88,14 @@ class StandardDexFile : public DexFile { } private: - StandardDexFile(const uint8_t* base, - size_t size, + StandardDexFile(std::unique_ptr<DexFileContainer> container, const std::string& location, uint32_t location_checksum, - const OatDexFile* oat_dex_file, - std::unique_ptr<DexFileContainer> container) - : DexFile(base, - size, - /*data_begin*/ base, - /*data_size*/ size, + const OatDexFile* oat_dex_file) + : DexFile(std::move(container), location, location_checksum, oat_dex_file, - std::move(container), /*is_compact_dex*/ false) {} friend class DexFileLoader; diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc index e40f1dbcdf..2a2aff1002 100644 --- a/runtime/class_linker_test.cc +++ b/runtime/class_linker_test.cc @@ -1521,12 +1521,12 @@ TEST_F(ClassLinkerTest, RegisterDexFileName) { dex_cache->SetLocation(location.Get()); const DexFile* old_dex_file = dex_cache->GetDexFile(); - std::unique_ptr<DexFile> dex_file(new StandardDexFile(old_dex_file->Begin(), - old_dex_file->Size(), - location->ToModifiedUtf8(), - 0u, - nullptr, - nullptr)); + std::unique_ptr<DexFile> dex_file( + new StandardDexFile(std::make_unique<NonOwningDexFileContainer>(old_dex_file->Begin(), + old_dex_file->Size()), + location->ToModifiedUtf8(), + 0u, + nullptr)); { WriterMutexLock mu(soa.Self(), *Locks::dex_lock_); // Check that inserting with a UTF16 name works. |