summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author David Srbecky <dsrbecky@google.com> 2023-02-24 18:42:20 +0000
committer David Srbecky <dsrbecky@google.com> 2023-02-27 17:35:35 +0000
commit771b44f32420c613acdf2046777c6df7d68a2734 (patch)
treee916b85d9a7c9a3c495fdeef2f4c45e7178832be
parent2cc19b15b383fd29fffd9904bf678c2592a66889 (diff)
Refactor DataBegin() and DataEnd() calculation in DexFile.
In this context, the data range is defined as the memory region that most of the dex offsets are relative to. It is same as the whole dex file for standard dex, but special for compact dex. Push the calculation of this memory range into DexFile internals, since it will different for multidex in the future (where it will be the memory range of the whole mulitdex container). Bug: 266950186 Test: test.py -b --host --all-cdex_level --64 Change-Id: I1e4ad9af975fd15c24c1d89a5fc51c63ea562091
-rw-r--r--dexlayout/dexlayout.h8
-rw-r--r--libdexfile/dex/compact_dex_file.cc4
-rw-r--r--libdexfile/dex/compact_dex_file.h2
-rw-r--r--libdexfile/dex/dex_file.cc22
-rw-r--r--libdexfile/dex/dex_file.h34
-rw-r--r--libdexfile/dex/dex_file_loader.cc28
-rw-r--r--libdexfile/dex/standard_dex_file.h2
7 files changed, 41 insertions, 59 deletions
diff --git a/dexlayout/dexlayout.h b/dexlayout/dexlayout.h
index 767cad03a0..d8896b39e6 100644
--- a/dexlayout/dexlayout.h
+++ b/dexlayout/dexlayout.h
@@ -205,13 +205,11 @@ class DexLoaderContainer : public MemoryDexFileContainer {
const uint8_t* end,
const uint8_t* data_begin,
const uint8_t* data_end)
- : MemoryDexFileContainer(begin, end), data_begin_(data_begin), data_end_(data_end) {}
- const uint8_t* DataBegin() const override { return data_begin_; }
- const uint8_t* DataEnd() const override { return data_end_; }
+ : MemoryDexFileContainer(begin, end), data_(data_begin, data_end - data_begin) {}
+ ArrayRef<const uint8_t> Data() const override { return data_; }
private:
- const uint8_t* data_begin_;
- const uint8_t* data_end_;
+ ArrayRef<const uint8_t> data_;
};
} // namespace art
diff --git a/libdexfile/dex/compact_dex_file.cc b/libdexfile/dex/compact_dex_file.cc
index a14d4ecbd2..3bdb1b79e6 100644
--- a/libdexfile/dex/compact_dex_file.cc
+++ b/libdexfile/dex/compact_dex_file.cc
@@ -85,16 +85,12 @@ uint32_t CompactDexFile::CalculateChecksum() const {
CompactDexFile::CompactDexFile(const uint8_t* base,
size_t size,
- const uint8_t* data_begin,
- size_t data_size,
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,
location,
location_checksum,
oat_dex_file,
diff --git a/libdexfile/dex/compact_dex_file.h b/libdexfile/dex/compact_dex_file.h
index 6aa0030d13..3bd906facd 100644
--- a/libdexfile/dex/compact_dex_file.h
+++ b/libdexfile/dex/compact_dex_file.h
@@ -306,8 +306,6 @@ class CompactDexFile : public DexFile {
private:
CompactDexFile(const uint8_t* base,
size_t size,
- const uint8_t* data_begin,
- size_t data_size,
const std::string& location,
uint32_t location_checksum,
const OatDexFile* oat_dex_file,
diff --git a/libdexfile/dex/dex_file.cc b/libdexfile/dex/dex_file.cc
index 6ebb5b823c..7922bb17b0 100644
--- a/libdexfile/dex/dex_file.cc
+++ b/libdexfile/dex/dex_file.cc
@@ -91,8 +91,6 @@ bool DexFile::DisableWrite() const {
DexFile::DexFile(const uint8_t* base,
size_t size,
- const uint8_t* data_begin,
- size_t data_size,
const std::string& location,
uint32_t location_checksum,
const OatDexFile* oat_dex_file,
@@ -100,8 +98,7 @@ DexFile::DexFile(const uint8_t* base,
bool is_compact_dex)
: begin_(base),
size_(size),
- data_begin_(data_begin),
- data_size_(data_size),
+ data_(GetDataRange(base, size, container.get())),
location_(location),
location_checksum_(location_checksum),
header_(reinterpret_cast<const Header*>(base)),
@@ -173,6 +170,23 @@ bool DexFile::CheckMagicAndVersion(std::string* error_msg) const {
return true;
}
+ArrayRef<const uint8_t> DexFile::GetDataRange(const uint8_t* data,
+ size_t size,
+ DexFileContainer* container) {
+ if (size >= sizeof(CompactDexFile::Header) && CompactDexFile::IsMagicValid(data)) {
+ auto header = reinterpret_cast<const CompactDexFile::Header*>(data);
+ // TODO: Remove. This is a hack. See comment of the Data method.
+ ArrayRef<const uint8_t> separate_data = container->Data();
+ if (separate_data.size() > 0) {
+ return separate_data;
+ }
+ // Shared compact dex data is located at the end after all dex files.
+ data += header->data_off_;
+ size = header->data_size_;
+ }
+ return {data, size};
+}
+
void DexFile::InitializeSectionsFromMapList() {
static_assert(sizeof(MapList) <= sizeof(Header));
DCHECK_GE(DataSize(), sizeof(MapList));
diff --git a/libdexfile/dex/dex_file.h b/libdexfile/dex/dex_file.h
index 0cf5ae26f9..f2c0bc90b4 100644
--- a/libdexfile/dex/dex_file.h
+++ b/libdexfile/dex/dex_file.h
@@ -25,6 +25,7 @@
#include <string_view>
#include <vector>
+#include "base/array_ref.h"
#include "base/globals.h"
#include "base/macros.h"
#include "base/mman.h" // For the PROT_* and MAP_* constants.
@@ -72,8 +73,7 @@ class DexFileContainer {
// TODO: Remove. This is only used by dexlayout to override the data section of the dex header,
// and redirect it to intermediate memory buffer at completely unrelated memory location.
- virtual const uint8_t* DataBegin() const { return nullptr; }
- virtual const uint8_t* DataEnd() const { return nullptr; }
+ virtual ArrayRef<const uint8_t> Data() const { return {}; }
bool IsZip() const { return is_zip_; }
void SetIsZip() { is_zip_ = true; }
@@ -575,9 +575,8 @@ 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_)
- ? nullptr
- : DataBegin() + debug_info_off;
+ return (debug_info_off == 0 || debug_info_off >= DataSize()) ? nullptr :
+ DataBegin() + debug_info_off;
}
struct PositionInfo {
@@ -756,13 +755,13 @@ class DexFile {
return size_;
}
- const uint8_t* DataBegin() const {
- return data_begin_;
- }
+ static ArrayRef<const uint8_t> GetDataRange(const uint8_t* data,
+ size_t size,
+ DexFileContainer* container);
- size_t DataSize() const {
- return data_size_;
- }
+ const uint8_t* DataBegin() const { return data_.data(); }
+
+ size_t DataSize() const { return data_.size(); }
template <typename T>
const T* DataPointer(size_t offset) const {
@@ -852,8 +851,6 @@ class DexFile {
DexFile(const uint8_t* base,
size_t size,
- const uint8_t* data_begin,
- size_t data_size,
const std::string& location,
uint32_t location_checksum,
const OatDexFile* oat_dex_file,
@@ -875,11 +872,12 @@ class DexFile {
// 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_;
+ // Data memory range: Most dex offsets are relative to this memory range.
+ // Standard dex: same as (begin_, size_).
+ // Compact: shared data which is located after all non-shared data.
+ //
+ // This is different to the "data section" in the standard dex header.
+ ArrayRef<const uint8_t> const data_;
// Typically the dex file name when available, alternatively some identifying string.
//
diff --git a/libdexfile/dex/dex_file_loader.cc b/libdexfile/dex/dex_file_loader.cc
index 95e456ec40..5bf350c8c6 100644
--- a/libdexfile/dex/dex_file_loader.cc
+++ b/libdexfile/dex/dex_file_loader.cc
@@ -354,37 +354,16 @@ std::unique_ptr<DexFile> DexFileLoader::OpenCommon(std::unique_ptr<DexFileContai
CHECK(container != nullptr);
const uint8_t* base = container->Begin();
size_t size = container->Size();
- const uint8_t* data_base = container->DataBegin();
- size_t data_size = container->DataEnd() - container->DataBegin();
if (error_code != nullptr) {
*error_code = DexFileLoaderErrorCode::kDexFileError;
}
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";
- }
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
- // 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_;
- }
- dex_file.reset(new CompactDexFile(base,
- size,
- data_base,
- data_size,
- location,
- location_checksum,
- oat_dex_file,
- std::move(container)));
- // Disable verification for CompactDex input.
- verify = false;
+ dex_file.reset(new CompactDexFile(
+ base, size, location, location_checksum, oat_dex_file, std::move(container)));
} else {
*error_msg = "Invalid or truncated dex file";
}
@@ -397,7 +376,8 @@ std::unique_ptr<DexFile> DexFileLoader::OpenCommon(std::unique_ptr<DexFileContai
dex_file.reset();
return nullptr;
}
- if (verify) {
+ // NB: Dex verifier does not understand the compact dex format.
+ if (verify && !dex_file->IsCompactDexFile()) {
ScopedTrace trace(std::string("Verify dex file ") + location);
if (!dex::Verify(dex_file.get(),
dex_file->Begin(),
diff --git a/libdexfile/dex/standard_dex_file.h b/libdexfile/dex/standard_dex_file.h
index cbd9be967d..20874cee07 100644
--- a/libdexfile/dex/standard_dex_file.h
+++ b/libdexfile/dex/standard_dex_file.h
@@ -120,8 +120,6 @@ class StandardDexFile : public DexFile {
std::unique_ptr<DexFileContainer> container)
: DexFile(base,
size,
- /*data_begin*/ base,
- /*data_size*/ size,
location,
location_checksum,
oat_dex_file,