summaryrefslogtreecommitdiff
path: root/libartbase/base/file_utils.cc
diff options
context:
space:
mode:
author Jiakai Zhang <jiakaiz@google.com> 2023-03-06 19:16:48 +0000
committer Nicolas Geoffray <ngeoffray@google.com> 2023-03-16 16:07:43 +0000
commit7da3956e3ff5c96ffd56d5e52057a230536a2d46 (patch)
tree5750407a3ef6e15a304ff5294fcdd200df030faa /libartbase/base/file_utils.cc
parentbbb7177a0b9a82a330a03966d708538d2768ffa1 (diff)
Revert^4 "Add the mainline framework boot image extensio...
Revert submission 2465993-boot-image-mainline-revert Reason for revert: Relanding the changes Reverted changes: /q/submissionid:2465993-boot-image-mainline-revert Change-Id: I5dd81f74c08faccd1643c2b01826e6a76cbb10c5
Diffstat (limited to 'libartbase/base/file_utils.cc')
-rw-r--r--libartbase/base/file_utils.cc128
1 files changed, 106 insertions, 22 deletions
diff --git a/libartbase/base/file_utils.cc b/libartbase/base/file_utils.cc
index 239628978e..d2afbcc009 100644
--- a/libartbase/base/file_utils.cc
+++ b/libartbase/base/file_utils.cc
@@ -40,6 +40,7 @@
#include <memory>
#include <sstream>
+#include <vector>
#include "android-base/file.h"
#include "android-base/logging.h"
@@ -50,6 +51,7 @@
#include "base/os.h"
#include "base/stl_util.h"
#include "base/unix_file/fd_file.h"
+#include "base/utils.h"
#if defined(__APPLE__)
#include <crt_externs.h>
@@ -78,6 +80,7 @@ static constexpr const char* kAndroidConscryptRootEnvVar = "ANDROID_CONSCRYPT_RO
static constexpr const char* kAndroidI18nRootEnvVar = "ANDROID_I18N_ROOT";
static constexpr const char* kApexDefaultPath = "/apex/";
static constexpr const char* kArtApexDataEnvVar = "ART_APEX_DATA";
+static constexpr const char* kBootImageStem = "boot";
// Get the "root" directory containing the "lib" directory where this instance
// of the libartbase library (which contains `GetRootContainingLibartbase`) is
@@ -298,10 +301,82 @@ std::string GetPrebuiltPrimaryBootImageDir() {
return GetPrebuiltPrimaryBootImageDir(android_root);
}
-std::string GetDefaultBootImageLocation(const std::string& android_root,
- bool deny_art_apex_data_files) {
+std::string GetFirstMainlineFrameworkLibraryFilename(std::string* error_msg) {
+ const char* env_bcp = getenv("BOOTCLASSPATH");
+ const char* env_dex2oat_bcp = getenv("DEX2OATBOOTCLASSPATH");
+ if (env_bcp == nullptr || env_dex2oat_bcp == nullptr) {
+ *error_msg = "BOOTCLASSPATH and DEX2OATBOOTCLASSPATH must not be empty";
+ return "";
+ }
+
+ // DEX2OATBOOTCLASSPATH contains core libraries and framework libraries. We used to only compile
+ // those libraries. Now we compile mainline framework libraries as well, and we have repurposed
+ // DEX2OATBOOTCLASSPATH to indicate the separation between mainline framework libraries and other
+ // libraries.
+ std::string_view mainline_bcp(env_bcp);
+ if (!android::base::ConsumePrefix(&mainline_bcp, env_dex2oat_bcp)) {
+ *error_msg = "DEX2OATBOOTCLASSPATH must be a prefix of BOOTCLASSPATH";
+ return "";
+ }
+
+ std::vector<std::string_view> mainline_bcp_jars;
+ Split(mainline_bcp, ':', &mainline_bcp_jars);
+ if (mainline_bcp_jars.empty()) {
+ *error_msg = "No mainline framework library found";
+ return "";
+ }
+
+ return std::string(mainline_bcp_jars[0]);
+}
+
+static std::string GetFirstMainlineFrameworkLibraryName(std::string* error_msg) {
+ std::string filename = GetFirstMainlineFrameworkLibraryFilename(error_msg);
+ if (filename.empty()) {
+ return "";
+ }
+
+ std::string jar_name = android::base::Basename(filename);
+
+ std::string_view library_name(jar_name);
+ if (!android::base::ConsumeSuffix(&library_name, ".jar")) {
+ *error_msg = "Invalid mainline framework jar: " + jar_name;
+ return "";
+ }
+
+ return std::string(library_name);
+}
+
+// Returns true when no error occurs, even if the extension doesn't exist.
+static bool MaybeAppendBootImageMainlineExtension(const std::string& android_root,
+ /*inout*/ std::string* location,
+ /*out*/ std::string* error_msg) {
+ if (!kIsTargetAndroid) {
+ return true;
+ }
+ // Due to how the runtime determines the mapping between boot images and bootclasspath jars, the
+ // name of the boot image extension must be in the format of
+ // `<primary-boot-image-stem>-<first-library-name>.art`.
+ std::string library_name = GetFirstMainlineFrameworkLibraryName(error_msg);
+ if (library_name.empty()) {
+ return false;
+ }
+ std::string mainline_extension_location = StringPrintf(
+ "%s/framework/%s-%s.art", android_root.c_str(), kBootImageStem, library_name.c_str());
+ std::string mainline_extension_path =
+ GetSystemImageFilename(mainline_extension_location.c_str(), kRuntimeISA);
+ if (!OS::FileExists(mainline_extension_path.c_str(), /*check_file_type=*/true)) {
+ // This is expected when the ART module is preloaded on an old source tree that doesn't
+ // dexpreopt mainline BCP jars, so it shouldn't be considered as an error.
+ return true;
+ }
+ *location += ":" + mainline_extension_location;
+ return true;
+}
+
+std::string GetDefaultBootImageLocationSafe(const std::string& android_root,
+ bool deny_art_apex_data_files,
+ std::string* error_msg) {
constexpr static const char* kEtcBootImageProf = "etc/boot-image.prof";
- constexpr static const char* kBootImageStem = "boot";
constexpr static const char* kMinimalBootImageStem = "boot_minimal";
// If an update for the ART module has been been installed, a single boot image for the entire
@@ -347,28 +422,37 @@ std::string GetDefaultBootImageLocation(const std::string& android_root,
PLOG(ERROR) << "Minimal boot image check failed, could not stat: " << boot_image_filename;
}
}
- // Boot image consists of two parts:
+
+ // Boot image consists of three parts:
// - the primary boot image (contains the Core Libraries)
- // - the boot image extensions (contains framework libraries)
- // Typically "/apex/com.android.art/javalib/boot.art!/apex/com.android.art/etc/boot-image.prof:
- // /system/framework/boot-framework.art!/system/etc/boot-image.prof".
- return StringPrintf("%s/%s.art!%s/%s:%s/framework/%s-framework.art!%s/%s",
- GetPrebuiltPrimaryBootImageDir(android_root).c_str(),
- kBootImageStem,
- kAndroidArtApexDefaultPath,
- kEtcBootImageProf,
- android_root.c_str(),
- kBootImageStem,
- android_root.c_str(),
- kEtcBootImageProf);
-}
-
-std::string GetDefaultBootImageLocation(std::string* error_msg) {
- std::string android_root = GetAndroidRootSafe(error_msg);
- if (android_root.empty()) {
+ // - the boot image framework extension (contains framework libraries)
+ // - the boot image mainline extension (contains mainline framework libraries)
+ // Typically "/system/framework/boot.art!/apex/com.android.art/etc/boot-image.prof:
+ // /system/framework/boot-framework.art!/system/etc/boot-image.prof:
+ // /system/framework/boot-framework-adservices.art".
+
+ std::string location = StringPrintf("%s/%s.art!%s/%s:%s/framework/%s-framework.art!%s/%s",
+ GetPrebuiltPrimaryBootImageDir(android_root).c_str(),
+ kBootImageStem,
+ kAndroidArtApexDefaultPath,
+ kEtcBootImageProf,
+ android_root.c_str(),
+ kBootImageStem,
+ android_root.c_str(),
+ kEtcBootImageProf);
+ if (!MaybeAppendBootImageMainlineExtension(android_root, &location, error_msg)) {
return "";
}
- return GetDefaultBootImageLocation(android_root, /*deny_art_apex_data_files=*/false);
+ return location;
+}
+
+std::string GetDefaultBootImageLocation(const std::string& android_root,
+ bool deny_art_apex_data_files) {
+ std::string error_msg;
+ std::string location =
+ GetDefaultBootImageLocationSafe(android_root, deny_art_apex_data_files, &error_msg);
+ CHECK(!location.empty()) << error_msg;
+ return location;
}
std::string GetJitZygoteBootImageLocation() {