summaryrefslogtreecommitdiff
path: root/runtime
diff options
context:
space:
mode:
Diffstat (limited to 'runtime')
-rw-r--r--runtime/class_linker.cc10
-rw-r--r--runtime/gc/space/image_space.cc40
-rw-r--r--runtime/gc/space/image_space.h10
-rw-r--r--runtime/oat/oat.cc2
-rw-r--r--runtime/oat/oat.h9
-rw-r--r--runtime/oat/oat_file.cc9
-rw-r--r--runtime/oat/oat_file.h6
-rw-r--r--runtime/oat/oat_file_assistant.cc5
8 files changed, 64 insertions, 27 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 009d705caf..b14eaae51b 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -2240,8 +2240,16 @@ bool ClassLinker::AddImageSpace(gc::space::ImageSpace* space,
return false;
}
+ const char* oat_apex_versions =
+ oat_header->GetStoreValueByKeyUnsafe(OatHeader::kApexVersionsKey);
+ if (oat_apex_versions == nullptr) {
+ *error_msg = StringPrintf("Missing apex versions in special root in runtime image '%s'",
+ space->GetImageLocation().c_str());
+ return false;
+ }
+
// Validate the apex versions.
- if (!gc::space::ImageSpace::ValidateApexVersions(*oat_header,
+ if (!gc::space::ImageSpace::ValidateApexVersions(oat_apex_versions,
runtime->GetApexVersions(),
space->GetImageLocation(),
error_msg)) {
diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc
index 97512bc79c..f557f3c8a9 100644
--- a/runtime/gc/space/image_space.cc
+++ b/runtime/gc/space/image_space.cc
@@ -26,6 +26,7 @@
#include <optional>
#include <random>
#include <string>
+#include <string_view>
#include <vector>
#include "android-base/logging.h"
@@ -3415,31 +3416,39 @@ void ImageSpace::Dump(std::ostream& os) const {
<< ",name=\"" << GetName() << "\"]";
}
-bool ImageSpace::ValidateApexVersions(const OatHeader& oat_header,
- const std::string& apex_versions,
- const std::string& file_location,
+bool ImageSpace::ValidateApexVersions(const OatFile& oat_file,
+ std::string_view runtime_apex_versions,
std::string* error_msg) {
// For a boot image, the key value store only exists in the first OAT file. Skip other OAT files.
- if (oat_header.GetKeyValueStoreSize() == 0) {
+ if (oat_file.GetOatHeader().GetKeyValueStoreSize() == 0) {
return true;
}
- const char* oat_apex_versions = oat_header.GetStoreValueByKey(OatHeader::kApexVersionsKey);
- if (oat_apex_versions == nullptr) {
+ std::optional<std::string_view> oat_apex_versions = oat_file.GetApexVersions();
+ if (!oat_apex_versions.has_value()) {
*error_msg = StringPrintf("ValidateApexVersions failed to get APEX versions from oat file '%s'",
- file_location.c_str());
+ oat_file.GetLocation().c_str());
return false;
}
+
+ return ValidateApexVersions(
+ *oat_apex_versions, runtime_apex_versions, oat_file.GetLocation(), error_msg);
+}
+
+bool ImageSpace::ValidateApexVersions(std::string_view oat_apex_versions,
+ std::string_view runtime_apex_versions,
+ const std::string& file_location,
+ std::string* error_msg) {
// For a boot image, it can be generated from a subset of the bootclasspath.
// For an app image, some dex files get compiled with a subset of the bootclasspath.
// For such cases, the OAT APEX versions will be a prefix of the runtime APEX versions.
- if (!apex_versions.starts_with(oat_apex_versions)) {
- *error_msg = StringPrintf(
- "ValidateApexVersions found APEX versions mismatch between oat file '%s' and the runtime "
- "(Oat file: '%s', Runtime: '%s')",
- file_location.c_str(),
+ if (!runtime_apex_versions.starts_with(oat_apex_versions)) {
+ *error_msg = ART_FORMAT(
+ "ValidateApexVersions found APEX versions mismatch between oat file '{}' and the runtime "
+ "(Oat file: '{}', Runtime: '{}')",
+ file_location,
oat_apex_versions,
- apex_versions.c_str());
+ runtime_apex_versions);
return false;
}
return true;
@@ -3455,10 +3464,7 @@ bool ImageSpace::ValidateOatFile(const OatFile& oat_file,
ArrayRef<const std::string> dex_filenames,
ArrayRef<File> dex_files,
const std::string& apex_versions) {
- if (!ValidateApexVersions(oat_file.GetOatHeader(),
- apex_versions,
- oat_file.GetLocation(),
- error_msg)) {
+ if (!ValidateApexVersions(oat_file, apex_versions, error_msg)) {
return false;
}
diff --git a/runtime/gc/space/image_space.h b/runtime/gc/space/image_space.h
index 266b1d5925..4d0ce8181e 100644
--- a/runtime/gc/space/image_space.h
+++ b/runtime/gc/space/image_space.h
@@ -260,9 +260,13 @@ class ImageSpace : public MemMapSpace {
const std::string& image_location,
bool boot_image_extension = false);
- // Returns true if the APEX versions in the OAT header match the given APEX versions.
- static bool ValidateApexVersions(const OatHeader& oat_header,
- const std::string& apex_versions,
+ // Returns true if the APEX versions of the OAT file match the given APEX versions.
+ static bool ValidateApexVersions(const OatFile& oat_file,
+ std::string_view runtime_apex_versions,
+ std::string* error_msg);
+
+ static bool ValidateApexVersions(std::string_view oat_apex_versions,
+ std::string_view runtime_apex_versions,
const std::string& file_location,
std::string* error_msg);
diff --git a/runtime/oat/oat.cc b/runtime/oat/oat.cc
index 840825cea8..9882b0fa51 100644
--- a/runtime/oat/oat.cc
+++ b/runtime/oat/oat.cc
@@ -373,7 +373,7 @@ const uint8_t* OatHeader::GetKeyValueStore() const {
return key_value_store_;
}
-const char* OatHeader::GetStoreValueByKey(const char* key) const {
+const char* OatHeader::GetStoreValueByKeyUnsafe(const char* key) const {
std::string_view key_view(key);
uint32_t offset = 0;
diff --git a/runtime/oat/oat.h b/runtime/oat/oat.h
index 0061c90da9..2069b569e3 100644
--- a/runtime/oat/oat.h
+++ b/runtime/oat/oat.h
@@ -164,7 +164,14 @@ class EXPORT PACKED(4) OatHeader {
uint32_t GetKeyValueStoreSize() const;
const uint8_t* GetKeyValueStore() const;
- const char* GetStoreValueByKey(const char* key) const;
+ const char* GetStoreValueByKeyUnsafe(const char* key) const;
+
+ const char* GetStoreValueByKey(const char* key) const {
+ // Do not get apex versions from the oat header directly. Use `OatFile::GetApexVersions`
+ // instead.
+ DCHECK_NE(std::string_view(key), kApexVersionsKey);
+ return GetStoreValueByKeyUnsafe(key);
+ }
// Returns the next key-value pair, at the given offset. On success, updates `offset`.
// The expected use case is to start the iteration with an offset initialized to zero and
diff --git a/runtime/oat/oat_file.cc b/runtime/oat/oat_file.cc
index 1ecad4abf9..3f72401f43 100644
--- a/runtime/oat/oat_file.cc
+++ b/runtime/oat/oat_file.cc
@@ -2586,4 +2586,13 @@ bool OatFile::IsBackedByVdexOnly() const {
return oat_dex_files_storage_.size() >= 1 && oat_dex_files_storage_[0]->IsBackedByVdexOnly();
}
+std::optional<std::string_view> OatFile::GetApexVersions() const {
+ if (override_apex_versions_.has_value()) {
+ return override_apex_versions_;
+ }
+ const char* oat_apex_versions =
+ GetOatHeader().GetStoreValueByKeyUnsafe(OatHeader::kApexVersionsKey);
+ return oat_apex_versions != nullptr ? std::make_optional(oat_apex_versions) : std::nullopt;
+}
+
} // namespace art
diff --git a/runtime/oat/oat_file.h b/runtime/oat/oat_file.h
index 9e66e1d4a7..53f1d173d1 100644
--- a/runtime/oat/oat_file.h
+++ b/runtime/oat/oat_file.h
@@ -19,6 +19,7 @@
#include <list>
#include <memory>
+#include <optional>
#include <string>
#include <string_view>
#include <vector>
@@ -426,6 +427,8 @@ class OatFile {
// Returns the mapping info of `dex_file` if found in the BcpBssInfo, or nullptr otherwise.
const BssMappingInfo* FindBcpMappingInfo(const DexFile* dex_file) const;
+ std::optional<std::string_view> GetApexVersions() const;
+
protected:
OatFile(const std::string& filename, bool executable);
@@ -518,6 +521,9 @@ class OatFile {
// by the `dex_filenames` parameter, in case the OatFile does not embed the dex code.
std::vector<std::unique_ptr<const DexFile>> external_dex_files_;
+ // If set, overrides the APEX versions in the header.
+ std::optional<std::string> override_apex_versions_ = std::nullopt;
+
friend class gc::collector::FakeOatFile; // For modifying begin_ and end_.
friend class OatClass;
friend class art::OatDexFile;
diff --git a/runtime/oat/oat_file_assistant.cc b/runtime/oat/oat_file_assistant.cc
index f5d6832cff..8df8459589 100644
--- a/runtime/oat/oat_file_assistant.cc
+++ b/runtime/oat/oat_file_assistant.cc
@@ -491,10 +491,7 @@ OatFileAssistant::OatStatus OatFileAssistant::GivenOatFileStatus(const OatFile&
return kOatBootImageOutOfDate;
}
if (!gc::space::ImageSpace::ValidateApexVersions(
- file.GetOatHeader(),
- GetOatFileAssistantContext()->GetApexVersions(),
- file.GetLocation(),
- error_msg)) {
+ file, GetOatFileAssistantContext()->GetApexVersions(), error_msg)) {
return kOatBootImageOutOfDate;
}
}