otapreopt.cpp revision 54e1a402610d7f392f7e421dcafcf6b017a99d88
173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe/* 273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ** Copyright 2016, The Android Open Source Project 373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ** 473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ** Licensed under the Apache License, Version 2.0 (the "License"); 573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ** you may not use this file except in compliance with the License. 673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ** You may obtain a copy of the License at 773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ** 873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ** http://www.apache.org/licenses/LICENSE-2.0 973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ** 1073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ** Unless required by applicable law or agreed to in writing, software 1173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ** distributed under the License is distributed on an "AS IS" BASIS, 1273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ** See the License for the specific language governing permissions and 1473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ** limitations under the License. 1573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe */ 1673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 1773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <algorithm> 1873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <inttypes.h> 1973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <random> 201842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe#include <regex> 2173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <selinux/android.h> 2273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <selinux/avc.h> 2373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <stdlib.h> 2473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <string.h> 2573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <sys/capability.h> 2673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <sys/prctl.h> 2773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <sys/stat.h> 2873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <sys/wait.h> 2973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 3073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <android-base/logging.h> 3173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <android-base/macros.h> 3273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <android-base/stringprintf.h> 336db8db9f3369c48de87f97f4d4636d446837fe32Andreas Gampe#include <android-base/strings.h> 3473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <cutils/fs.h> 3573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <cutils/properties.h> 3654e1a402610d7f392f7e421dcafcf6b017a99d88Andreas Gampe#include <dex2oat_return_codes.h> 377823e124e00576e20e47ec717cbe8bc89f0f2bf2Mark Salyzyn#include <log/log.h> 3873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <private/android_filesystem_config.h> 3973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 406c2c056193010cf93b4264810d462c120ce801c8Jeff Sharkey#include "dexopt.h" 41f3e30b936ef103dc0f3d8697e0f86ba82b49609eJeff Sharkey#include "file_parsing.h" 42f3e30b936ef103dc0f3d8697e0f86ba82b49609eJeff Sharkey#include "globals.h" 43f3e30b936ef103dc0f3d8697e0f86ba82b49609eJeff Sharkey#include "installd_deps.h" // Need to fill in requirements of commands. 44f3e30b936ef103dc0f3d8697e0f86ba82b49609eJeff Sharkey#include "otapreopt_utils.h" 45f3e30b936ef103dc0f3d8697e0f86ba82b49609eJeff Sharkey#include "system_properties.h" 46f3e30b936ef103dc0f3d8697e0f86ba82b49609eJeff Sharkey#include "utils.h" 476c2c056193010cf93b4264810d462c120ce801c8Jeff Sharkey 4873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#ifndef LOG_TAG 4973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#define LOG_TAG "otapreopt" 5073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#endif 5173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 5273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#define BUFFER_MAX 1024 /* input buffer for commands */ 5373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#define TOKEN_MAX 16 /* max number of arguments in buffer */ 5473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#define REPLY_MAX 256 /* largest reply allowed */ 5573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 5656f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampeusing android::base::EndsWith; 576db8db9f3369c48de87f97f4d4636d446837fe32Andreas Gampeusing android::base::Join; 586db8db9f3369c48de87f97f4d4636d446837fe32Andreas Gampeusing android::base::Split; 5956f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampeusing android::base::StartsWith; 6073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampeusing android::base::StringPrintf; 6173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 6273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampenamespace android { 6373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampenamespace installd { 6473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 6573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampetemplate<typename T> 6673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampestatic constexpr T RoundDown(T x, typename std::decay<T>::type n) { 6773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return DCHECK_CONSTEXPR(IsPowerOfTwo(n), , T(0))(x & -n); 6873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe} 6973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 7073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampetemplate<typename T> 7173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampestatic constexpr T RoundUp(T x, typename std::remove_reference<T>::type n) { 7273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return RoundDown(x + n - 1, n); 7373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe} 7473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 7573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampeclass OTAPreoptService { 7673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe public: 7773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // Main driver. Performs the following steps. 7873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // 7973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // 1) Parse options (read system properties etc from B partition). 8073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // 8173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // 2) Read in package data. 8273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // 8373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // 3) Prepare environment variables. 8473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // 8573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // 4) Prepare(compile) boot image, if necessary. 8673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // 8773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // 5) Run update. 8873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe int Main(int argc, char** argv) { 89d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (!ReadArguments(argc, argv)) { 90d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe LOG(ERROR) << "Failed reading command line."; 91d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return 1; 92d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 93d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 9473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (!ReadSystemProperties()) { 9573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe LOG(ERROR)<< "Failed reading system properties."; 96d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return 2; 9773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 9873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 9973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (!ReadEnvironment()) { 10073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe LOG(ERROR) << "Failed reading environment properties."; 101d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return 3; 10273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 10373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 104d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (!CheckAndInitializeInstalldGlobals()) { 105d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe LOG(ERROR) << "Failed initializing globals."; 106d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return 4; 10773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 10873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 10973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe PrepareEnvironment(); 11073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 111d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (!PrepareBootImage(/* force */ false)) { 11273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe LOG(ERROR) << "Failed preparing boot image."; 113d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return 5; 11473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 11573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 11673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe int dexopt_retcode = RunPreopt(); 11773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 11873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return dexopt_retcode; 11973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 12073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 121d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe int GetProperty(const char* key, char* value, const char* default_value) const { 12273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe const std::string* prop_value = system_properties_.GetProperty(key); 12373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (prop_value == nullptr) { 12473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (default_value == nullptr) { 12573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return 0; 12673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 12773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // Copy in the default value. 12873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe strncpy(value, default_value, kPropertyValueMax - 1); 12973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe value[kPropertyValueMax - 1] = 0; 13073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return strlen(default_value);// TODO: Need to truncate? 13173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 13273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe size_t size = std::min(kPropertyValueMax - 1, prop_value->length()); 13373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe strncpy(value, prop_value->data(), size); 13473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe value[size] = 0; 13573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return static_cast<int>(size); 13673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 13773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 138d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe std::string GetOTADataDirectory() const { 139d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return StringPrintf("%s/%s", GetOtaDirectoryPrefix().c_str(), target_slot_.c_str()); 140d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 141d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 142d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe const std::string& GetTargetSlot() const { 143d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return target_slot_; 144d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 145d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 14673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampeprivate: 147d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 14873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe bool ReadSystemProperties() { 1491842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe static constexpr const char* kPropertyFiles[] = { 1501842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe "/default.prop", "/system/build.prop" 1511842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe }; 1521842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe 1531842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe for (size_t i = 0; i < arraysize(kPropertyFiles); ++i) { 1541842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe if (!system_properties_.Load(kPropertyFiles[i])) { 1551842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe return false; 1561842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe } 1571842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe } 1581842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe 1591842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe return true; 16073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 16173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 16273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe bool ReadEnvironment() { 1631842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe // Parse the environment variables from init.environ.rc, which have the form 1641842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe // export NAME VALUE 1651842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe // For simplicity, don't respect string quotation. The values we are interested in can be 1661842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe // encoded without them. 1671842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe std::regex export_regex("\\s*export\\s+(\\S+)\\s+(\\S+)"); 1681842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe bool parse_result = ParseFile("/init.environ.rc", [&](const std::string& line) { 1691842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe std::smatch export_match; 1701842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe if (!std::regex_match(line, export_match, export_regex)) { 1711842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe return true; 1721842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe } 1731842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe 1741842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe if (export_match.size() != 3) { 1751842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe return true; 1761842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe } 1771842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe 1781842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe std::string name = export_match[1].str(); 1791842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe std::string value = export_match[2].str(); 1801842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe 1811842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe system_properties_.SetProperty(name, value); 1821842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe 1831842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe return true; 1841842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe }); 1851842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe if (!parse_result) { 18673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return false; 18773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 18873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 189d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (system_properties_.GetProperty(kAndroidDataPathPropertyName) == nullptr) { 190d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return false; 19173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 192d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe android_data_ = *system_properties_.GetProperty(kAndroidDataPathPropertyName); 193d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 194d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (system_properties_.GetProperty(kAndroidRootPathPropertyName) == nullptr) { 195d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return false; 196d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 197d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe android_root_ = *system_properties_.GetProperty(kAndroidRootPathPropertyName); 198d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 199d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (system_properties_.GetProperty(kBootClassPathPropertyName) == nullptr) { 200d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return false; 201d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 202d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe boot_classpath_ = *system_properties_.GetProperty(kBootClassPathPropertyName); 203d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 204d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (system_properties_.GetProperty(ASEC_MOUNTPOINT_ENV_NAME) == nullptr) { 205d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return false; 206d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 207d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe asec_mountpoint_ = *system_properties_.GetProperty(ASEC_MOUNTPOINT_ENV_NAME); 20873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 20973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return true; 21073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 21173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 212d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe const std::string& GetAndroidData() const { 213d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return android_data_; 214d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 215d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 216d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe const std::string& GetAndroidRoot() const { 217d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return android_root_; 218d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 219d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 220d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe const std::string GetOtaDirectoryPrefix() const { 221d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return GetAndroidData() + "/ota"; 222d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 223d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 224d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe bool CheckAndInitializeInstalldGlobals() { 225d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe // init_globals_from_data_and_root requires "ASEC_MOUNTPOINT" in the environment. We 226d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe // do not use any datapath that includes this, but we'll still have to set it. 227d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe CHECK(system_properties_.GetProperty(ASEC_MOUNTPOINT_ENV_NAME) != nullptr); 228d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe int result = setenv(ASEC_MOUNTPOINT_ENV_NAME, asec_mountpoint_.c_str(), 0); 229d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (result != 0) { 230d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe LOG(ERROR) << "Could not set ASEC_MOUNTPOINT environment variable"; 231d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return false; 232d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 233d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 234d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (!init_globals_from_data_and_root(GetAndroidData().c_str(), GetAndroidRoot().c_str())) { 235d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe LOG(ERROR) << "Could not initialize globals; exiting."; 236d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return false; 237d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 238d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 239d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe // This is different from the normal installd. We only do the base 240d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe // directory, the rest will be created on demand when each app is compiled. 241d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (access(GetOtaDirectoryPrefix().c_str(), R_OK) < 0) { 242d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe LOG(ERROR) << "Could not access " << GetOtaDirectoryPrefix(); 243d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return false; 244d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 245d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 246d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return true; 247d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 248d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 249d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe bool ReadArguments(int argc ATTRIBUTE_UNUSED, char** argv) { 250d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe // Expected command line: 251d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe // target-slot dexopt {DEXOPT_PARAMETERS} 252d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe // The DEXOPT_PARAMETERS are passed on to dexopt(), so we expect DEXOPT_PARAM_COUNT 253d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe // of them. We store them in package_parameters_ (size checks are done when 254d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe // parsing the special parameters and when copying into package_parameters_. 255d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 256548bdb930895d8fe6651eaada0bc5739ee5248c8Andreas Gampe static_assert(DEXOPT_PARAM_COUNT == ARRAY_SIZE(package_parameters_), 257548bdb930895d8fe6651eaada0bc5739ee5248c8Andreas Gampe "Unexpected dexopt param count"); 258d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 259d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe const char* target_slot_arg = argv[1]; 260d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (target_slot_arg == nullptr) { 261d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe LOG(ERROR) << "Missing parameters"; 262d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return false; 263d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 264d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe // Sanitize value. Only allow (a-zA-Z0-9_)+. 265d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe target_slot_ = target_slot_arg; 266fd12edaeab839f3f1f087cc75bd18b4d8af5b192Andreas Gampe if (!ValidateTargetSlotSuffix(target_slot_)) { 267fd12edaeab839f3f1f087cc75bd18b4d8af5b192Andreas Gampe LOG(ERROR) << "Target slot suffix not legal: " << target_slot_; 268fd12edaeab839f3f1f087cc75bd18b4d8af5b192Andreas Gampe return false; 269d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 270d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 271d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe // Check for "dexopt" next. 272d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (argv[2] == nullptr) { 273d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe LOG(ERROR) << "Missing parameters"; 274d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return false; 275d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 276d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (std::string("dexopt").compare(argv[2]) != 0) { 277d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe LOG(ERROR) << "Second parameter not dexopt: " << argv[2]; 278d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return false; 279d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 280d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 281d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe // Copy the rest into package_parameters_, but be careful about over- and underflow. 282d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe size_t index = 0; 283548bdb930895d8fe6651eaada0bc5739ee5248c8Andreas Gampe while (index < DEXOPT_PARAM_COUNT && 284d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe argv[index + 3] != nullptr) { 285d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe package_parameters_[index] = argv[index + 3]; 28673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe index++; 28773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 288d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (index != ARRAY_SIZE(package_parameters_) || argv[index + 3] != nullptr) { 28973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe LOG(ERROR) << "Wrong number of parameters"; 29073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return false; 29173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 29273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 29373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return true; 29473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 29573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 29673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe void PrepareEnvironment() { 297d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe environ_.push_back(StringPrintf("BOOTCLASSPATH=%s", boot_classpath_.c_str())); 298d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe environ_.push_back(StringPrintf("ANDROID_DATA=%s", GetOTADataDirectory().c_str())); 299d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe environ_.push_back(StringPrintf("ANDROID_ROOT=%s", android_root_.c_str())); 30073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 30173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe for (const std::string& e : environ_) { 30273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe putenv(const_cast<char*>(e.c_str())); 30373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 30473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 30573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 30673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // Ensure that we have the right boot image. The first time any app is 30773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // compiled, we'll try to generate it. 308d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe bool PrepareBootImage(bool force) const { 30973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (package_parameters_[kISAIndex] == nullptr) { 31073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe LOG(ERROR) << "Instruction set missing."; 31173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return false; 31273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 31373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe const char* isa = package_parameters_[kISAIndex]; 31473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 31573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // Check whether the file exists where expected. 316d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe std::string dalvik_cache = GetOTADataDirectory() + "/" + DALVIK_CACHE; 31773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe std::string isa_path = dalvik_cache + "/" + isa; 31873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe std::string art_path = isa_path + "/system@framework@boot.art"; 31973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe std::string oat_path = isa_path + "/system@framework@boot.oat"; 320d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe bool cleared = false; 321d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (access(art_path.c_str(), F_OK) == 0 && access(oat_path.c_str(), F_OK) == 0) { 322d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe // Files exist, assume everything is alright if not forced. Otherwise clean up. 323d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (!force) { 324d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return true; 325d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 326d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe ClearDirectory(isa_path); 327d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe cleared = true; 32873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 32973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 330d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe // Reset umask in otapreopt, so that we control the the access for the files we create. 331d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe umask(0); 332d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 33373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // Create the directories, if necessary. 33473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (access(dalvik_cache.c_str(), F_OK) != 0) { 335d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (!CreatePath(dalvik_cache)) { 336d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe PLOG(ERROR) << "Could not create dalvik-cache dir " << dalvik_cache; 33773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return false; 33873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 33973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 34073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (access(isa_path.c_str(), F_OK) != 0) { 341d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (!CreatePath(isa_path)) { 34273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe PLOG(ERROR) << "Could not create dalvik-cache isa dir"; 34373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return false; 34473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 34573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 34673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 3475709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe // Prepare to create. 348d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (!cleared) { 349d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe ClearDirectory(isa_path); 350d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 35173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 3529fb85b0667235ebfdea00ea345febc8f6eb203d2Andreas Gampe std::string preopted_boot_art_path = StringPrintf("/system/framework/%s/boot.art", isa); 3535709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe if (access(preopted_boot_art_path.c_str(), F_OK) == 0) { 3545709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe return PatchoatBootImage(art_path, isa); 3555709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe } else { 3565709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe // No preopted boot image. Try to compile. 357d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return Dex2oatBootImage(boot_classpath_, art_path, oat_path, isa); 3585709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe } 3595709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe } 3605709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe 361d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe static bool CreatePath(const std::string& path) { 362d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe // Create the given path. Use string processing instead of dirname, as dirname's need for 363d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe // a writable char buffer is painful. 364d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 365d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe // First, try to use the full path. 366d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (mkdir(path.c_str(), 0711) == 0) { 367d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return true; 368d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 369d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (errno != ENOENT) { 370d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe PLOG(ERROR) << "Could not create path " << path; 371d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return false; 372d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 373d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 374d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe // Now find the parent and try that first. 375d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe size_t last_slash = path.find_last_of('/'); 376d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (last_slash == std::string::npos || last_slash == 0) { 377d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe PLOG(ERROR) << "Could not create " << path; 378d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return false; 379d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 380d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 381d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (!CreatePath(path.substr(0, last_slash))) { 382d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return false; 383d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 384d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 385d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (mkdir(path.c_str(), 0711) == 0) { 386d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return true; 387d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 388d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe PLOG(ERROR) << "Could not create " << path; 389d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return false; 390d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 391d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 392d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe static void ClearDirectory(const std::string& dir) { 393d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe DIR* c_dir = opendir(dir.c_str()); 394d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (c_dir == nullptr) { 395d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe PLOG(WARNING) << "Unable to open " << dir << " to delete it's contents"; 396d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return; 397d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 398d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 399d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe for (struct dirent* de = readdir(c_dir); de != nullptr; de = readdir(c_dir)) { 400d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe const char* name = de->d_name; 401d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) { 402d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe continue; 403d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 404d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe // We only want to delete regular files and symbolic links. 405d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe std::string file = StringPrintf("%s/%s", dir.c_str(), name); 406d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (de->d_type != DT_REG && de->d_type != DT_LNK) { 407d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe LOG(WARNING) << "Unexpected file " 408d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe << file 409d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe << " of type " 410d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe << std::hex 411d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe << de->d_type 412d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe << " encountered."; 413d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } else { 414d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe // Try to unlink the file. 415d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (unlink(file.c_str()) != 0) { 416d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe PLOG(ERROR) << "Unable to unlink " << file; 417d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 418d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 419d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 420d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe CHECK_EQ(0, closedir(c_dir)) << "Unable to close directory."; 421d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 422d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 423d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe bool PatchoatBootImage(const std::string& art_path, const char* isa) const { 4245709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe // This needs to be kept in sync with ART, see art/runtime/gc/space/image_space.cc. 4255709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe 4265709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe std::vector<std::string> cmd; 4279fb85b0667235ebfdea00ea345febc8f6eb203d2Andreas Gampe cmd.push_back("/system/bin/patchoat"); 4285709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe 4295709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe cmd.push_back("--input-image-location=/system/framework/boot.art"); 4305709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe cmd.push_back(StringPrintf("--output-image-file=%s", art_path.c_str())); 4315709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe 4325709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe cmd.push_back(StringPrintf("--instruction-set=%s", isa)); 4335709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe 4345709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe int32_t base_offset = ChooseRelocationOffsetDelta(ART_BASE_ADDRESS_MIN_DELTA, 4355709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe ART_BASE_ADDRESS_MAX_DELTA); 436febf0bf33ca81edcdaab3625e2711fa58b398cc5Andreas Gampe cmd.push_back(StringPrintf("--base-offset-delta=%d", base_offset)); 4375709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe 4385709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe std::string error_msg; 4395709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe bool result = Exec(cmd, &error_msg); 4405709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe if (!result) { 4415709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe LOG(ERROR) << "Could not generate boot image: " << error_msg; 4425709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe } 4435709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe return result; 4445709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe } 4455709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe 4465709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe bool Dex2oatBootImage(const std::string& boot_cp, 4475709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe const std::string& art_path, 4485709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe const std::string& oat_path, 449d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe const char* isa) const { 45073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // This needs to be kept in sync with ART, see art/runtime/gc/space/image_space.cc. 45173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe std::vector<std::string> cmd; 4529fb85b0667235ebfdea00ea345febc8f6eb203d2Andreas Gampe cmd.push_back("/system/bin/dex2oat"); 45373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe cmd.push_back(StringPrintf("--image=%s", art_path.c_str())); 4546db8db9f3369c48de87f97f4d4636d446837fe32Andreas Gampe for (const std::string& boot_part : Split(boot_cp, ":")) { 45573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe cmd.push_back(StringPrintf("--dex-file=%s", boot_part.c_str())); 45673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 45773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe cmd.push_back(StringPrintf("--oat-file=%s", oat_path.c_str())); 45873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 45973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe int32_t base_offset = ChooseRelocationOffsetDelta(ART_BASE_ADDRESS_MIN_DELTA, 46073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ART_BASE_ADDRESS_MAX_DELTA); 46173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe cmd.push_back(StringPrintf("--base=0x%x", ART_BASE_ADDRESS + base_offset)); 46273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 46373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe cmd.push_back(StringPrintf("--instruction-set=%s", isa)); 46473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 46573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // These things are pushed by AndroidRuntime, see frameworks/base/core/jni/AndroidRuntime.cpp. 46673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe AddCompilerOptionFromSystemProperty("dalvik.vm.image-dex2oat-Xms", 46773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe "-Xms", 46873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe true, 46973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe cmd); 47073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe AddCompilerOptionFromSystemProperty("dalvik.vm.image-dex2oat-Xmx", 47173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe "-Xmx", 47273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe true, 47373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe cmd); 47473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe AddCompilerOptionFromSystemProperty("dalvik.vm.image-dex2oat-filter", 47573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe "--compiler-filter=", 47673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe false, 47773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe cmd); 4789fb85b0667235ebfdea00ea345febc8f6eb203d2Andreas Gampe cmd.push_back("--image-classes=/system/etc/preloaded-classes"); 47973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // TODO: Compiled-classes. 48073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe const std::string* extra_opts = 48173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe system_properties_.GetProperty("dalvik.vm.image-dex2oat-flags"); 48273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (extra_opts != nullptr) { 4836db8db9f3369c48de87f97f4d4636d446837fe32Andreas Gampe std::vector<std::string> extra_vals = Split(*extra_opts, " "); 48473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe cmd.insert(cmd.end(), extra_vals.begin(), extra_vals.end()); 48573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 48673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // TODO: Should we lower this? It's usually set close to max, because 48773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // normally there's not much else going on at boot. 48873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe AddCompilerOptionFromSystemProperty("dalvik.vm.image-dex2oat-threads", 48973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe "-j", 49073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe false, 49173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe cmd); 49273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe AddCompilerOptionFromSystemProperty( 49373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe StringPrintf("dalvik.vm.isa.%s.variant", isa).c_str(), 49473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe "--instruction-set-variant=", 49573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe false, 49673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe cmd); 49773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe AddCompilerOptionFromSystemProperty( 49873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe StringPrintf("dalvik.vm.isa.%s.features", isa).c_str(), 49973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe "--instruction-set-features=", 50073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe false, 50173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe cmd); 50273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 50373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe std::string error_msg; 50473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe bool result = Exec(cmd, &error_msg); 50573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (!result) { 50673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe LOG(ERROR) << "Could not generate boot image: " << error_msg; 50773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 50873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return result; 50973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 51073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 51173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe static const char* ParseNull(const char* arg) { 51273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return (strcmp(arg, "!") == 0) ? nullptr : arg; 51373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 51473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 515d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe bool ShouldSkipPreopt() const { 51656f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // There's one thing we have to be careful about: we may/will be asked to compile an app 51756f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // living in the system image. This may be a valid request - if the app wasn't compiled, 51856f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // e.g., if the system image wasn't large enough to include preopted files. However, the 51956f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // data we have is from the old system, so the driver (the OTA service) can't actually 52056f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // know. Thus, we will get requests for apps that have preopted components. To avoid 52156f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // duplication (we'd generate files that are not used and are *not* cleaned up), do two 52256f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // simple checks: 52356f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // 52456f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // 1) Does the apk_path start with the value of ANDROID_ROOT? (~in the system image) 52556f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // (For simplicity, assume the value of ANDROID_ROOT does not contain a symlink.) 52656f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // 52756f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // 2) If you replace the name in the apk_path with "oat," does the path exist? 52856f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // (=have a subdirectory for preopted files) 52956f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // 53056f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // If the answer to both is yes, skip the dexopt. 53156f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // 53256f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // Note: while one may think it's OK to call dexopt and it will fail (because APKs should 53356f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // be stripped), that's not true for APKs signed outside the build system (so the 53456f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // jar content must be exactly the same). 53556f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe 53656f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // (This is ugly as it's the only thing where we need to understand the contents 53756f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // of package_parameters_, but it beats postponing the decision or using the call- 53856f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // backs to do weird things.) 53956f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe constexpr size_t kApkPathIndex = 0; 54056f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe CHECK_GT(DEXOPT_PARAM_COUNT, kApkPathIndex); 54156f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe CHECK(package_parameters_[kApkPathIndex] != nullptr); 542d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (StartsWith(package_parameters_[kApkPathIndex], android_root_.c_str())) { 54356f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe const char* last_slash = strrchr(package_parameters_[kApkPathIndex], '/'); 54456f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe if (last_slash != nullptr) { 54556f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe std::string path(package_parameters_[kApkPathIndex], 54656f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe last_slash - package_parameters_[kApkPathIndex] + 1); 54756f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe CHECK(EndsWith(path, "/")); 54856f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe path = path + "oat"; 54956f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe if (access(path.c_str(), F_OK) == 0) { 550d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return true; 55156f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe } 55256f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe } 55356f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe } 55456f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe 555d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe // Another issue is unavailability of files in the new system. If the partition 556d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe // layout changes, otapreopt_chroot may not know about this. Then files from that 557d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe // partition will not be available and fail to build. This is problematic, as 558d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe // this tool will wipe the OTA artifact cache and try again (for robustness after 559d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe // a failed OTA with remaining cache artifacts). 560d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (access(package_parameters_[kApkPathIndex], F_OK) != 0) { 561d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe LOG(WARNING) << "Skipping preopt of non-existing package " 562d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe << package_parameters_[kApkPathIndex]; 563d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return true; 564d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 565d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 566d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return false; 567d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 568d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 569d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe int RunPreopt() { 570d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (ShouldSkipPreopt()) { 571d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return 0; 572d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 573d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 574d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe int dexopt_result = dexopt(package_parameters_); 575d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (dexopt_result == 0) { 576d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return 0; 577d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 578d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 579d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe // If the dexopt failed, we may have a stale boot image from a previous OTA run. 58054e1a402610d7f392f7e421dcafcf6b017a99d88Andreas Gampe // Then regenerate and retry. 58154e1a402610d7f392f7e421dcafcf6b017a99d88Andreas Gampe if (WEXITSTATUS(dexopt_result) != 58254e1a402610d7f392f7e421dcafcf6b017a99d88Andreas Gampe static_cast<int>(art::dex2oat::ReturnCode::kCreateRuntime)) { 58354e1a402610d7f392f7e421dcafcf6b017a99d88Andreas Gampe return dexopt_result; 58454e1a402610d7f392f7e421dcafcf6b017a99d88Andreas Gampe } 585d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 586d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (!PrepareBootImage(/* force */ true)) { 587d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe LOG(ERROR) << "Forced boot image creating failed. Original error return was " 588d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe << dexopt_result; 589d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return dexopt_result; 590d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 591d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 592d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe LOG(WARNING) << "Original dexopt failed, re-trying after boot image was regenerated."; 593548bdb930895d8fe6651eaada0bc5739ee5248c8Andreas Gampe return dexopt(package_parameters_); 59473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 59573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 59673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe //////////////////////////////////// 59773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // Helpers, mostly taken from ART // 59873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe //////////////////////////////////// 59973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 60073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // Wrapper on fork/execv to run a command in a subprocess. 601d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe static bool Exec(const std::vector<std::string>& arg_vector, std::string* error_msg) { 6026db8db9f3369c48de87f97f4d4636d446837fe32Andreas Gampe const std::string command_line = Join(arg_vector, ' '); 60373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 60473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe CHECK_GE(arg_vector.size(), 1U) << command_line; 60573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 60673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // Convert the args to char pointers. 60773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe const char* program = arg_vector[0].c_str(); 60873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe std::vector<char*> args; 60973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe for (size_t i = 0; i < arg_vector.size(); ++i) { 61073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe const std::string& arg = arg_vector[i]; 61173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe char* arg_str = const_cast<char*>(arg.c_str()); 61273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe CHECK(arg_str != nullptr) << i; 61373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe args.push_back(arg_str); 61473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 61573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe args.push_back(nullptr); 61673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 61773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // Fork and exec. 61873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe pid_t pid = fork(); 61973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (pid == 0) { 62073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // No allocation allowed between fork and exec. 62173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 62273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // Change process groups, so we don't get reaped by ProcessManager. 62373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe setpgid(0, 0); 62473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 62573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe execv(program, &args[0]); 62673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 62773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe PLOG(ERROR) << "Failed to execv(" << command_line << ")"; 62873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // _exit to avoid atexit handlers in child. 62973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe _exit(1); 63073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } else { 63173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (pid == -1) { 63273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe *error_msg = StringPrintf("Failed to execv(%s) because fork failed: %s", 63373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe command_line.c_str(), strerror(errno)); 63473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return false; 63573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 63673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 63773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // wait for subprocess to finish 63873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe int status; 63973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe pid_t got_pid = TEMP_FAILURE_RETRY(waitpid(pid, &status, 0)); 64073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (got_pid != pid) { 64173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe *error_msg = StringPrintf("Failed after fork for execv(%s) because waitpid failed: " 64273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe "wanted %d, got %d: %s", 64373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe command_line.c_str(), pid, got_pid, strerror(errno)); 64473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return false; 64573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 64673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { 64773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe *error_msg = StringPrintf("Failed execv(%s) because non-0 exit status", 64873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe command_line.c_str()); 64973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return false; 65073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 65173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 65273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return true; 65373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 65473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 65573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // Choose a random relocation offset. Taken from art/runtime/gc/image_space.cc. 65673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe static int32_t ChooseRelocationOffsetDelta(int32_t min_delta, int32_t max_delta) { 65773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe constexpr size_t kPageSize = PAGE_SIZE; 65873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe CHECK_EQ(min_delta % kPageSize, 0u); 65973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe CHECK_EQ(max_delta % kPageSize, 0u); 66073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe CHECK_LT(min_delta, max_delta); 66173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 66273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe std::default_random_engine generator; 66373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe generator.seed(GetSeed()); 66473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe std::uniform_int_distribution<int32_t> distribution(min_delta, max_delta); 66573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe int32_t r = distribution(generator); 66673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (r % 2 == 0) { 66773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe r = RoundUp(r, kPageSize); 66873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } else { 66973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe r = RoundDown(r, kPageSize); 67073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 67173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe CHECK_LE(min_delta, r); 67273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe CHECK_GE(max_delta, r); 67373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe CHECK_EQ(r % kPageSize, 0u); 67473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return r; 67573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 67673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 67773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe static uint64_t GetSeed() { 67873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#ifdef __BIONIC__ 67973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // Bionic exposes arc4random, use it. 68073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe uint64_t random_data; 68173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe arc4random_buf(&random_data, sizeof(random_data)); 68273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return random_data; 68373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#else 68473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#error "This is only supposed to run with bionic. Otherwise, implement..." 68573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#endif 68673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 68773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 68873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe void AddCompilerOptionFromSystemProperty(const char* system_property, 68973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe const char* prefix, 69073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe bool runtime, 691d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe std::vector<std::string>& out) const { 692d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe const std::string* value = system_properties_.GetProperty(system_property); 69373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (value != nullptr) { 69473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (runtime) { 69573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe out.push_back("--runtime-arg"); 69673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 69773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (prefix != nullptr) { 69873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe out.push_back(StringPrintf("%s%s", prefix, value->c_str())); 69973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } else { 70073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe out.push_back(*value); 70173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 70273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 70373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 70473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 705d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe static constexpr const char* kBootClassPathPropertyName = "BOOTCLASSPATH"; 706d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe static constexpr const char* kAndroidRootPathPropertyName = "ANDROID_ROOT"; 707d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe static constexpr const char* kAndroidDataPathPropertyName = "ANDROID_DATA"; 708d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe // The index of the instruction-set string inside the package parameters. Needed for 709d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe // some special-casing that requires knowledge of the instruction-set. 710d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe static constexpr size_t kISAIndex = 3; 711d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 71273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // Stores the system properties read out of the B partition. We need to use these properties 71373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // to compile, instead of the A properties we could get from init/get_property. 71473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe SystemProperties system_properties_; 71573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 716d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe // Some select properties that are always needed. 717d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe std::string target_slot_; 718d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe std::string android_root_; 719d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe std::string android_data_; 720d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe std::string boot_classpath_; 721d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe std::string asec_mountpoint_; 722d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 723548bdb930895d8fe6651eaada0bc5739ee5248c8Andreas Gampe const char* package_parameters_[DEXOPT_PARAM_COUNT]; 72473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 72573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // Store environment values we need to set. 72673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe std::vector<std::string> environ_; 72773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe}; 72873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 72973dae11162aa61396c06cbdb05b954764e944e02Andreas GampeOTAPreoptService gOps; 73073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 73173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe//////////////////////// 73273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe// Plug-in functions. // 73373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe//////////////////////// 73473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 73573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampeint get_property(const char *key, char *value, const char *default_value) { 73673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return gOps.GetProperty(key, value, default_value); 73773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe} 73873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 73973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe// Compute the output path of 74073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampebool calculate_oat_file_path(char path[PKG_PATH_MAX], const char *oat_dir, 74173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe const char *apk_path, 74273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe const char *instruction_set) { 7439c8f93a2a6ed6a764de7a617fe7a01657d0f4479Dan Austin const char *file_name_start; 7449c8f93a2a6ed6a764de7a617fe7a01657d0f4479Dan Austin const char *file_name_end; 74573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 74673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe file_name_start = strrchr(apk_path, '/'); 74773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (file_name_start == nullptr) { 74873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ALOGE("apk_path '%s' has no '/'s in it\n", apk_path); 74973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return false; 75073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 75173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe file_name_end = strrchr(file_name_start, '.'); 75273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (file_name_end == nullptr) { 75373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ALOGE("apk_path '%s' has no extension\n", apk_path); 75473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return false; 75573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 75673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 75773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // Calculate file_name 75873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe file_name_start++; // Move past '/', is valid as file_name_end is valid. 75973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe size_t file_name_len = file_name_end - file_name_start; 76073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe std::string file_name(file_name_start, file_name_len); 76173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 76273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // <apk_parent_dir>/oat/<isa>/<file_name>.odex.b 763d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe snprintf(path, 764d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe PKG_PATH_MAX, 765d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe "%s/%s/%s.odex.%s", 766d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe oat_dir, 767d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe instruction_set, 768d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe file_name.c_str(), 769d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe gOps.GetTargetSlot().c_str()); 77073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return true; 77173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe} 77273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 77373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe/* 77473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe * Computes the odex file for the given apk_path and instruction_set. 77573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe * /system/framework/whatever.jar -> /system/framework/oat/<isa>/whatever.odex 77673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe * 77773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe * Returns false if it failed to determine the odex file path. 77873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe */ 77973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampebool calculate_odex_file_path(char path[PKG_PATH_MAX], const char *apk_path, 78073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe const char *instruction_set) { 78173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe const char *path_end = strrchr(apk_path, '/'); 78273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (path_end == nullptr) { 78373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ALOGE("apk_path '%s' has no '/'s in it?!\n", apk_path); 78473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return false; 78573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 78673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe std::string path_component(apk_path, path_end - apk_path); 78773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 78873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe const char *name_begin = path_end + 1; 78973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe const char *extension_start = strrchr(name_begin, '.'); 79073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (extension_start == nullptr) { 79173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ALOGE("apk_path '%s' has no extension.\n", apk_path); 79273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return false; 79373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 79473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe std::string name_component(name_begin, extension_start - name_begin); 79573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 796d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe std::string new_path = StringPrintf("%s/oat/%s/%s.odex.%s", 79773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe path_component.c_str(), 79873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe instruction_set, 799d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe name_component.c_str(), 800d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe gOps.GetTargetSlot().c_str()); 801d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (new_path.length() >= PKG_PATH_MAX) { 802d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe LOG(ERROR) << "apk_path of " << apk_path << " is too long: " << new_path; 803d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return false; 804d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 80573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe strcpy(path, new_path.c_str()); 80673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return true; 80773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe} 80873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 80973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampebool create_cache_path(char path[PKG_PATH_MAX], 81073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe const char *src, 81173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe const char *instruction_set) { 81273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe size_t srclen = strlen(src); 81373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 81473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe /* demand that we are an absolute path */ 81573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if ((src == 0) || (src[0] != '/') || strstr(src,"..")) { 81673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return false; 81773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 81873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 81973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (srclen > PKG_PATH_MAX) { // XXX: PKG_NAME_MAX? 82073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return false; 82173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 82273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 82373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe std::string from_src = std::string(src + 1); 82473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe std::replace(from_src.begin(), from_src.end(), '/', '@'); 82573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 82673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe std::string assembled_path = StringPrintf("%s/%s/%s/%s%s", 827d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe gOps.GetOTADataDirectory().c_str(), 82873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe DALVIK_CACHE, 82973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe instruction_set, 83073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe from_src.c_str(), 831249c1796a2e62f8751348e5bafce9f40e6538cbaDavid Brazdil DALVIK_CACHE_POSTFIX); 83273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 83373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (assembled_path.length() + 1 > PKG_PATH_MAX) { 83473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return false; 83573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 83673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe strcpy(path, assembled_path.c_str()); 83773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 83873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return true; 83973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe} 84073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 84173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampestatic int log_callback(int type, const char *fmt, ...) { 84273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe va_list ap; 84373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe int priority; 84473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 84573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe switch (type) { 84673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe case SELINUX_WARNING: 84773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe priority = ANDROID_LOG_WARN; 84873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe break; 84973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe case SELINUX_INFO: 85073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe priority = ANDROID_LOG_INFO; 85173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe break; 85273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe default: 85373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe priority = ANDROID_LOG_ERROR; 85473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe break; 85573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 85673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe va_start(ap, fmt); 85773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe LOG_PRI_VA(priority, "SELinux", fmt, ap); 85873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe va_end(ap); 85973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return 0; 86073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe} 86173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 86273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampestatic int otapreopt_main(const int argc, char *argv[]) { 86373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe int selinux_enabled = (is_selinux_enabled() > 0); 86473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 86573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe setenv("ANDROID_LOG_TAGS", "*:v", 1); 86673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe android::base::InitLogging(argv); 86773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 86873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (argc < 2) { 86973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ALOGE("Expecting parameters"); 87073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe exit(1); 87173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 87273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 87373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe union selinux_callback cb; 87473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe cb.func_log = log_callback; 87573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe selinux_set_callback(SELINUX_CB_LOG, cb); 87673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 87773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (selinux_enabled && selinux_status_open(true) < 0) { 87873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ALOGE("Could not open selinux status; exiting.\n"); 87973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe exit(1); 88073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 88173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 88273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe int ret = android::installd::gOps.Main(argc, argv); 88373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 88473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return ret; 88573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe} 88673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 88773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe} // namespace installd 88873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe} // namespace android 88973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 89073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampeint main(const int argc, char *argv[]) { 89173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return android::installd::otapreopt_main(argc, argv); 89273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe} 893