summaryrefslogtreecommitdiff
path: root/runtime/oat_file.cc
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/oat_file.cc')
-rw-r--r--runtime/oat_file.cc237
1 files changed, 110 insertions, 127 deletions
diff --git a/runtime/oat_file.cc b/runtime/oat_file.cc
index 63778c7b0b..558441aa18 100644
--- a/runtime/oat_file.cc
+++ b/runtime/oat_file.cc
@@ -50,6 +50,7 @@
#include "base/systrace.h"
#include "base/unix_file/fd_file.h"
#include "base/utils.h"
+#include "class_loader_context.h"
#include "dex/art_dex_file_loader.h"
#include "dex/dex_file.h"
#include "dex/dex_file_loader.h"
@@ -282,7 +283,7 @@ bool OatFileBase::LoadVdex(const std::string& vdex_filename,
std::string* error_msg) {
vdex_ = VdexFile::OpenAtAddress(vdex_begin_,
vdex_end_ - vdex_begin_,
- /*mmap_reuse=*/ vdex_begin_ != nullptr,
+ /*mmap_reuse=*/vdex_begin_ != nullptr,
vdex_filename,
writable,
low_4gb,
@@ -307,16 +308,15 @@ bool OatFileBase::LoadVdex(int vdex_fd,
if (rc == -1) {
PLOG(WARNING) << "Failed getting length of vdex file";
} else {
- vdex_ = VdexFile::OpenAtAddress(
- vdex_begin_,
- vdex_end_ - vdex_begin_,
- /*mmap_reuse=*/ vdex_begin_ != nullptr,
- vdex_fd,
- s.st_size,
- vdex_filename,
- writable,
- low_4gb,
- error_msg);
+ vdex_ = VdexFile::OpenAtAddress(vdex_begin_,
+ vdex_end_ - vdex_begin_,
+ /*mmap_reuse=*/vdex_begin_ != nullptr,
+ vdex_fd,
+ s.st_size,
+ vdex_filename,
+ writable,
+ low_4gb,
+ error_msg);
if (vdex_.get() == nullptr) {
*error_msg = "Failed opening vdex file.";
return false;
@@ -445,7 +445,7 @@ static bool ReadIndexBssMapping(OatFile* oat_file,
UNLIKELY(oat_file->Size() - index_bss_mapping_offset <
IndexBssMapping::ComputeSize(index_bss_mapping->size())))) {
*error_msg = StringPrintf("In oat file '%s' found OatDexFile #%zu for '%s' with unaligned or "
- " truncated %s bss mapping, offset %u of %zu, length %zu",
+ "truncated %s bss mapping, offset %u of %zu, length %zu",
oat_file->GetLocation().c_str(),
dex_file_index,
dex_file_location.c_str(),
@@ -465,15 +465,25 @@ static bool ComputeAndCheckTypeLookupTableData(const DexFile::Header& header,
const VdexFile* vdex_file,
const uint8_t** type_lookup_table_data,
std::string* error_msg) {
- if (type_lookup_table_start == nullptr ||
- reinterpret_cast<const uint32_t*>(type_lookup_table_start)[0] == 0) {
+ if (type_lookup_table_start == nullptr) {
*type_lookup_table_data = nullptr;
return true;
}
- *type_lookup_table_data = type_lookup_table_start + sizeof(uint32_t);
- size_t expected_table_size = TypeLookupTable::RawDataLength(header.class_defs_size_);
+ if (UNLIKELY(!vdex_file->Contains(type_lookup_table_start, sizeof(uint32_t)))) {
+ *error_msg =
+ StringPrintf("In vdex file '%s' found invalid type lookup table start %p of size %zu "
+ "not in [%p, %p]",
+ vdex_file->GetName().c_str(),
+ type_lookup_table_start,
+ sizeof(uint32_t),
+ vdex_file->Begin(),
+ vdex_file->End());
+ return false;
+ }
+
size_t found_size = reinterpret_cast<const uint32_t*>(type_lookup_table_start)[0];
+ size_t expected_table_size = TypeLookupTable::RawDataLength(header.class_defs_size_);
if (UNLIKELY(found_size != expected_table_size)) {
*error_msg =
StringPrintf("In vdex file '%s' unexpected type lookup table size: found %zu, expected %zu",
@@ -482,20 +492,20 @@ static bool ComputeAndCheckTypeLookupTableData(const DexFile::Header& header,
expected_table_size);
return false;
}
- if (UNLIKELY(!vdex_file->Contains(*type_lookup_table_data))) {
- *error_msg =
- StringPrintf("In vdex file '%s' found invalid type lookup table pointer %p not in [%p, %p]",
- vdex_file->GetName().c_str(),
- type_lookup_table_data,
- vdex_file->Begin(),
- vdex_file->End());
- return false;
+
+ if (found_size == 0) {
+ *type_lookup_table_data = nullptr;
+ return true;
}
- if (UNLIKELY(!vdex_file->Contains(*type_lookup_table_data + expected_table_size - 1))) {
+
+ *type_lookup_table_data = type_lookup_table_start + sizeof(uint32_t);
+ if (UNLIKELY(!vdex_file->Contains(*type_lookup_table_data, found_size))) {
*error_msg =
- StringPrintf("In vdex file '%s' found overflowing type lookup table %p not in [%p, %p]",
+ StringPrintf("In vdex file '%s' found invalid type lookup table data %p of size %zu "
+ "not in [%p, %p]",
vdex_file->GetName().c_str(),
- type_lookup_table_data + expected_table_size,
+ type_lookup_table_data,
+ found_size,
vdex_file->Begin(),
vdex_file->End());
return false;
@@ -514,6 +524,16 @@ bool OatFileBase::Setup(const std::vector<const DexFile*>& dex_files, std::strin
uint32_t i = 0;
const uint8_t* type_lookup_table_start = nullptr;
for (const DexFile* dex_file : dex_files) {
+ // Defensively verify external dex file checksum. `OatFileAssistant`
+ // expects this check to happen during oat file setup when the oat file
+ // does not contain dex code.
+ if (dex_file->GetLocationChecksum() != vdex_->GetLocationChecksum(i)) {
+ *error_msg = StringPrintf("Dex checksum does not match for %s, dex has %d, vdex has %d",
+ dex_file->GetLocation().c_str(),
+ dex_file->GetLocationChecksum(),
+ vdex_->GetLocationChecksum(i));
+ return false;
+ }
std::string dex_location = dex_file->GetLocation();
std::string canonical_location = DexFileLoader::GetDexCanonicalLocation(dex_location.c_str());
@@ -767,29 +787,25 @@ bool OatFileBase::Setup(int zip_fd,
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,
- 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,
- 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,
- /*verify_checksum=*/ 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);
}
@@ -828,7 +844,9 @@ bool OatFileBase::Setup(int zip_fd,
external_dex_files_.push_back(std::move(dex_file));
}
}
- // Defensively verify external dex file checksum.
+ // Defensively verify external dex file checksum. `OatFileAssistant`
+ // expects this check to happen during oat file setup when the oat file
+ // does not contain dex code.
if (dex_file_checksum != external_dex_files_[i]->GetLocationChecksum()) {
*error_msg = StringPrintf("In oat file '%s', dex file checksum 0x%08x does not match"
" checksum 0x%08x of external dex file '%s'",
@@ -1672,7 +1690,7 @@ bool ElfOatFile::ElfFileOpen(File* file,
ScopedTrace trace(__PRETTY_FUNCTION__);
elf_file_.reset(ElfFile::Open(file,
writable,
- /*program_header_only=*/ true,
+ /*program_header_only=*/true,
low_4gb,
error_msg));
if (elf_file_ == nullptr) {
@@ -1687,15 +1705,16 @@ bool ElfOatFile::ElfFileOpen(File* file,
class OatFileBackedByVdex final : public OatFileBase {
public:
explicit OatFileBackedByVdex(const std::string& filename)
- : OatFileBase(filename, /*executable=*/ false) {}
+ : OatFileBase(filename, /*executable=*/false) {}
static OatFileBackedByVdex* Open(const std::vector<const DexFile*>& dex_files,
std::unique_ptr<VdexFile>&& vdex_file,
- const std::string& location) {
+ const std::string& location,
+ ClassLoaderContext* context) {
std::unique_ptr<OatFileBackedByVdex> oat_file(new OatFileBackedByVdex(location));
// SetVdex will take ownership of the VdexFile.
oat_file->SetVdex(vdex_file.release());
- oat_file->SetupHeader(dex_files.size());
+ oat_file->SetupHeader(dex_files.size(), context);
// Initialize OatDexFiles.
std::string error_msg;
if (!oat_file->Setup(dex_files, &error_msg)) {
@@ -1708,6 +1727,7 @@ class OatFileBackedByVdex final : public OatFileBase {
static OatFileBackedByVdex* Open(int zip_fd,
std::unique_ptr<VdexFile>&& unique_vdex_file,
const std::string& dex_location,
+ ClassLoaderContext* context,
std::string* error_msg) {
VdexFile* vdex_file = unique_vdex_file.get();
std::unique_ptr<OatFileBackedByVdex> oat_file(new OatFileBackedByVdex(vdex_file->GetName()));
@@ -1719,21 +1739,25 @@ class OatFileBackedByVdex final : public OatFileBase {
for (const uint8_t* dex_file_start = vdex_file->GetNextDexFileData(nullptr, i);
dex_file_start != nullptr;
dex_file_start = vdex_file->GetNextDexFileData(dex_file_start, ++i)) {
- const DexFile::Header* header = reinterpret_cast<const DexFile::Header*>(dex_file_start);
- if (UNLIKELY(!vdex_file->Contains(dex_file_start))) {
+ if (UNLIKELY(!vdex_file->Contains(dex_file_start, sizeof(DexFile::Header)))) {
*error_msg =
- StringPrintf("In vdex file '%s' found invalid dex file pointer %p not in [%p, %p]",
+ StringPrintf("In vdex file '%s' found invalid dex header %p of size %zu "
+ "not in [%p, %p]",
dex_location.c_str(),
dex_file_start,
+ sizeof(DexFile::Header),
vdex_file->Begin(),
vdex_file->End());
return nullptr;
}
- if (UNLIKELY(!vdex_file->Contains(dex_file_start + header->file_size_ - 1))) {
+ const DexFile::Header* header = reinterpret_cast<const DexFile::Header*>(dex_file_start);
+ if (UNLIKELY(!vdex_file->Contains(dex_file_start, header->file_size_))) {
*error_msg =
- StringPrintf("In vdex file '%s' found overflowing dex file %p not in [%p, %p]",
+ StringPrintf("In vdex file '%s' found invalid dex file pointer %p of size %d "
+ "not in [%p, %p]",
dex_location.c_str(),
- dex_file_start + header->file_size_,
+ dex_file_start,
+ header->file_size_,
vdex_file->Begin(),
vdex_file->End());
return nullptr;
@@ -1772,31 +1796,28 @@ class OatFileBackedByVdex final : public OatFileBase {
oat_file->oat_dex_files_.Put(canonical_key, oat_dex_file);
}
}
- oat_file->SetupHeader(oat_file->oat_dex_files_storage_.size());
+ oat_file->SetupHeader(oat_file->oat_dex_files_storage_.size(), context);
} 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,
- 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,
- /*verify_checksum=*/ false,
+ ArtDexFileLoader dex_file_loader(dex_location);
+ loaded = dex_file_loader.Open(/*verify=*/false,
+ /*verify_checksum=*/false,
error_msg,
&oat_file->external_dex_files_);
}
if (!loaded) {
return nullptr;
}
- oat_file->SetupHeader(oat_file->external_dex_files_.size());
+ oat_file->SetupHeader(oat_file->external_dex_files_.size(), context);
if (!oat_file->Setup(MakeNonOwningPointerVector(oat_file->external_dex_files_), error_msg)) {
return nullptr;
}
@@ -1805,7 +1826,7 @@ class OatFileBackedByVdex final : public OatFileBase {
return oat_file.release();
}
- void SetupHeader(size_t number_of_dex_files) {
+ void SetupHeader(size_t number_of_dex_files, ClassLoaderContext* context) {
DCHECK(!IsExecutable());
// Create a fake OatHeader with a key store to help debugging.
@@ -1813,9 +1834,13 @@ class OatFileBackedByVdex final : public OatFileBase {
InstructionSetFeatures::FromCppDefines();
SafeMap<std::string, std::string> store;
store.Put(OatHeader::kCompilerFilter, CompilerFilter::NameOfFilter(CompilerFilter::kVerify));
- store.Put(OatHeader::kCompilationReasonKey, "vdex");
+ store.Put(OatHeader::kCompilationReasonKey, kReasonVdex);
store.Put(OatHeader::kConcurrentCopying,
- kUseReadBarrier ? OatHeader::kTrueValue : OatHeader::kFalseValue);
+ gUseReadBarrier ? OatHeader::kTrueValue : OatHeader::kFalseValue);
+ if (context != nullptr) {
+ store.Put(OatHeader::kClassPathKey, context->EncodeContextForOatFile(""));
+ }
+
oat_header_.reset(OatHeader::Create(kRuntimeISA,
isa_features.get(),
number_of_dex_files,
@@ -1899,7 +1924,7 @@ OatFile* OatFile::Open(int zip_fd,
vdex_filename,
oat_filename,
oat_location,
- /*writable=*/ false,
+ /*writable=*/false,
executable,
low_4gb,
dex_filenames,
@@ -1907,17 +1932,6 @@ OatFile* OatFile::Open(int zip_fd,
reservation,
error_msg);
if (with_dlopen != nullptr) {
- Runtime* runtime = Runtime::Current();
- // The runtime might not be available at this point if we're running
- // dex2oat or oatdump.
- if (runtime != nullptr) {
- size_t madvise_size_limit = runtime->GetMadviseWillNeedSizeOdex();
- Runtime::MadviseFileForRange(madvise_size_limit,
- with_dlopen->Size(),
- with_dlopen->Begin(),
- with_dlopen->End(),
- oat_location);
- }
return with_dlopen;
}
if (kPrintDlOpenErrorMessage) {
@@ -1940,7 +1954,7 @@ OatFile* OatFile::Open(int zip_fd,
vdex_filename,
oat_filename,
oat_location,
- /*writable=*/ false,
+ /*writable=*/false,
executable,
low_4gb,
dex_filenames,
@@ -1969,7 +1983,7 @@ OatFile* OatFile::Open(int zip_fd,
oat_fd,
vdex_location,
oat_location,
- /*writable=*/ false,
+ /*writable=*/false,
executable,
low_4gb,
dex_filenames,
@@ -1981,17 +1995,19 @@ OatFile* OatFile::Open(int zip_fd,
OatFile* OatFile::OpenFromVdex(const std::vector<const DexFile*>& dex_files,
std::unique_ptr<VdexFile>&& vdex_file,
- const std::string& location) {
+ const std::string& location,
+ ClassLoaderContext* context) {
CheckLocation(location);
- return OatFileBackedByVdex::Open(dex_files, std::move(vdex_file), location);
+ return OatFileBackedByVdex::Open(dex_files, std::move(vdex_file), location, context);
}
OatFile* OatFile::OpenFromVdex(int zip_fd,
std::unique_ptr<VdexFile>&& vdex_file,
const std::string& location,
+ ClassLoaderContext* context,
std::string* error_msg) {
CheckLocation(location);
- return OatFileBackedByVdex::Open(zip_fd, std::move(vdex_file), location, error_msg);
+ return OatFileBackedByVdex::Open(zip_fd, std::move(vdex_file), location, context, error_msg);
}
OatFile::OatFile(const std::string& location, bool is_executable)
@@ -2224,15 +2240,9 @@ std::unique_ptr<const DexFile> OatDexFile::OpenDexFile(std::string* error_msg) c
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 {
@@ -2252,7 +2262,7 @@ OatFile::OatClass OatDexFile::GetOatClass(uint16_t class_def_index) const {
return OatFile::OatClass(oat_file_,
ClassStatus::kNotReady,
/* type= */ OatClassType::kNoneCompiled,
- /* bitmap_size= */ 0u,
+ /* num_methods= */ 0u,
/* bitmap_pointer= */ nullptr,
/* methods_pointer= */ nullptr);
}
@@ -2341,34 +2351,6 @@ const dex::ClassDef* OatDexFile::FindClassDef(const DexFile& dex_file,
return nullptr;
}
-// Madvise the dex file based on the state we are moving to.
-void OatDexFile::MadviseDexFileAtLoad(const DexFile& dex_file) {
- Runtime* const runtime = Runtime::Current();
- const bool low_ram = runtime->GetHeap()->IsLowMemoryMode();
- // TODO(b/196052575): Revisit low-ram madvise behavior in light of vdex/odex/art madvise hints.
- if (!low_ram) {
- return;
- }
- if (runtime->MAdviseRandomAccess()) {
- // Default every dex file to MADV_RANDOM when its loaded by default for low ram devices.
- // Other devices have enough page cache to get performance benefits from loading more pages
- // into the page cache.
- DexLayoutSection::MadviseLargestPageAlignedRegion(dex_file.Begin(),
- dex_file.Begin() + dex_file.Size(),
- MADV_RANDOM);
- }
- const OatDexFile* oat_dex_file = dex_file.GetOatDexFile();
- if (oat_dex_file != nullptr) {
- // Should always be there.
- const DexLayoutSections* const sections = oat_dex_file->GetDexLayoutSections();
- if (sections != nullptr) {
- sections->MadviseAtLoad(&dex_file);
- } else {
- DCHECK(oat_dex_file->IsBackedByVdexOnly());
- }
- }
-}
-
OatFile::OatClass::OatClass(const OatFile* oat_file,
ClassStatus status,
OatClassType type,
@@ -2448,7 +2430,8 @@ CompilerFilter::Filter OatFile::GetCompilerFilter() const {
}
std::string OatFile::GetClassLoaderContext() const {
- return GetOatHeader().GetStoreValueByKey(OatHeader::kClassPathKey);
+ const char* value = GetOatHeader().GetStoreValueByKey(OatHeader::kClassPathKey);
+ return (value == nullptr) ? "" : value;
}
const char* OatFile::GetCompilationReason() const {