Refactor DexFile ownership
Avoid bare pointers in DexFileLoader APIs, which caused clang-tidy
issues and other problems.
Bug: none
Test: build and boot
Change-Id: Ic277bc83af1997774b42c55d3d631ec940b9c015
diff --git a/compiler/optimizing/optimizing_unit_test.h b/compiler/optimizing/optimizing_unit_test.h
index a9bc566..a627f65 100644
--- a/compiler/optimizing/optimizing_unit_test.h
+++ b/compiler/optimizing/optimizing_unit_test.h
@@ -129,12 +129,10 @@
// 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 392ce1e..05986ec 100644
--- a/libdexfile/dex/art_dex_file_loader.cc
+++ b/libdexfile/dex/art_dex_file_loader.cc
@@ -71,6 +71,14 @@
}
}
+ 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 @@
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 @@
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 @@
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 @@
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 @@
}
}
-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 a460aee..9f92b72 100644
--- a/libdexfile/dex/art_dex_file_loader.h
+++ b/libdexfile/dex/art_dex_file_loader.h
@@ -121,17 +121,17 @@
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 302b59e..4bd1675 100644
--- a/libdexfile/dex/compact_dex_file.cc
+++ b/libdexfile/dex/compact_dex_file.cc
@@ -84,22 +84,16 @@
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 affc9a2..ffaa9a7 100644
--- a/libdexfile/dex/compact_dex_file.h
+++ b/libdexfile/dex/compact_dex_file.h
@@ -284,14 +284,11 @@
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 f1f8960..c2b478a 100644
--- a/libdexfile/dex/dex_file.cc
+++ b/libdexfile/dex/dex_file.cc
@@ -73,61 +73,101 @@
}
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 67abdca..c94c786 100644
--- a/libdexfile/dex/dex_file.h
+++ b/libdexfile/dex/dex_file.h
@@ -56,11 +56,48 @@
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 @@
// 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 @@
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 @@
}
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 @@
// 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,
- std::unique_ptr<DexFileContainer> container,
+ 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,
bool is_compact_dex);
// Top-level initializer that calls other Init methods.
@@ -1040,17 +1088,11 @@
// 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 container for the header and fixed portions.
+ std::unique_ptr<DexFileContainer> main_section_;
- // The size of the underlying memory allocation in bytes.
- const size_t size_;
-
- // 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 @@
// 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 457addf..156f655 100644
--- a/libdexfile/dex/dex_file_loader.cc
+++ b/libdexfile/dex/dex_file_loader.cc
@@ -54,8 +54,17 @@
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 @@
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 @@
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 @@
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 @@
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 0153220..0bd6446 100644
--- a/libdexfile/dex/dex_file_loader.h
+++ b/libdexfile/dex/dex_file_loader.h
@@ -161,17 +161,17 @@
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 c9bac0f..9d9f1bd 100644
--- a/libdexfile/dex/dex_file_verifier_test.cc
+++ b/libdexfile/dex/dex_file_verifier_test.cc
@@ -56,7 +56,10 @@
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 999e5b9..0121d60 100644
--- a/libdexfile/dex/standard_dex_file.h
+++ b/libdexfile/dex/standard_dex_file.h
@@ -88,20 +88,14 @@
}
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 e40f1db..2a2aff1 100644
--- a/runtime/class_linker_test.cc
+++ b/runtime/class_linker_test.cc
@@ -1521,12 +1521,12 @@
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.