otapreopt.cpp revision ef21fd2b6b08d5faddaeabe83718d875d20a6abc
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> 19c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe#include <limits> 2073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <random> 211842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe#include <regex> 2273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <selinux/android.h> 2373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <selinux/avc.h> 2473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <stdlib.h> 2573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <string.h> 2673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <sys/capability.h> 2773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <sys/prctl.h> 2873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <sys/stat.h> 2973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <sys/wait.h> 3073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 3173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <android-base/logging.h> 3273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <android-base/macros.h> 3373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <android-base/stringprintf.h> 346db8db9f3369c48de87f97f4d4636d446837fe32Andreas Gampe#include <android-base/strings.h> 3573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <cutils/fs.h> 3673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <cutils/properties.h> 3754e1a402610d7f392f7e421dcafcf6b017a99d88Andreas Gampe#include <dex2oat_return_codes.h> 387823e124e00576e20e47ec717cbe8bc89f0f2bf2Mark Salyzyn#include <log/log.h> 3973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#include <private/android_filesystem_config.h> 4073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 416c2c056193010cf93b4264810d462c120ce801c8Jeff Sharkey#include "dexopt.h" 42f3e30b936ef103dc0f3d8697e0f86ba82b49609eJeff Sharkey#include "file_parsing.h" 43f3e30b936ef103dc0f3d8697e0f86ba82b49609eJeff Sharkey#include "globals.h" 44c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe#include "installd_constants.h" 45f3e30b936ef103dc0f3d8697e0f86ba82b49609eJeff Sharkey#include "installd_deps.h" // Need to fill in requirements of commands. 46f3e30b936ef103dc0f3d8697e0f86ba82b49609eJeff Sharkey#include "otapreopt_utils.h" 47f3e30b936ef103dc0f3d8697e0f86ba82b49609eJeff Sharkey#include "system_properties.h" 48f3e30b936ef103dc0f3d8697e0f86ba82b49609eJeff Sharkey#include "utils.h" 496c2c056193010cf93b4264810d462c120ce801c8Jeff Sharkey 5073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#ifndef LOG_TAG 5173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#define LOG_TAG "otapreopt" 5273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#endif 5373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 5473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#define BUFFER_MAX 1024 /* input buffer for commands */ 5573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#define TOKEN_MAX 16 /* max number of arguments in buffer */ 5673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#define REPLY_MAX 256 /* largest reply allowed */ 5773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 5856f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampeusing android::base::EndsWith; 596db8db9f3369c48de87f97f4d4636d446837fe32Andreas Gampeusing android::base::Join; 606db8db9f3369c48de87f97f4d4636d446837fe32Andreas Gampeusing android::base::Split; 6156f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampeusing android::base::StartsWith; 6273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampeusing android::base::StringPrintf; 6373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 6473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampenamespace android { 6573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampenamespace installd { 6673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 67ef21fd2b6b08d5faddaeabe83718d875d20a6abcAndreas Gampe// Check expected values for dexopt flags. If you need to change this: 68ef21fd2b6b08d5faddaeabe83718d875d20a6abcAndreas Gampe// 69ef21fd2b6b08d5faddaeabe83718d875d20a6abcAndreas Gampe// RUN AN A/B OTA TO MAKE SURE THINGS STILL WORK! 70ef21fd2b6b08d5faddaeabe83718d875d20a6abcAndreas Gampe// 71ef21fd2b6b08d5faddaeabe83718d875d20a6abcAndreas Gampe// You most likely need to increase the protocol version and all that entails! 72ef21fd2b6b08d5faddaeabe83718d875d20a6abcAndreas Gampe 73ef21fd2b6b08d5faddaeabe83718d875d20a6abcAndreas Gampestatic_assert(DEXOPT_PUBLIC == 1 << 1, "DEXOPT_PUBLIC unexpected."); 74ef21fd2b6b08d5faddaeabe83718d875d20a6abcAndreas Gampestatic_assert(DEXOPT_DEBUGGABLE == 1 << 2, "DEXOPT_DEBUGGABLE unexpected."); 75ef21fd2b6b08d5faddaeabe83718d875d20a6abcAndreas Gampestatic_assert(DEXOPT_BOOTCOMPLETE == 1 << 3, "DEXOPT_BOOTCOMPLETE unexpected."); 76ef21fd2b6b08d5faddaeabe83718d875d20a6abcAndreas Gampestatic_assert(DEXOPT_PROFILE_GUIDED == 1 << 4, "DEXOPT_PROFILE_GUIDED unexpected."); 77ef21fd2b6b08d5faddaeabe83718d875d20a6abcAndreas Gampestatic_assert(DEXOPT_SECONDARY_DEX == 1 << 5, "DEXOPT_SECONDARY_DEX unexpected."); 78ef21fd2b6b08d5faddaeabe83718d875d20a6abcAndreas Gampestatic_assert(DEXOPT_FORCE == 1 << 6, "DEXOPT_FORCE unexpected."); 79ef21fd2b6b08d5faddaeabe83718d875d20a6abcAndreas Gampestatic_assert(DEXOPT_STORAGE_CE == 1 << 7, "DEXOPT_STORAGE_CE unexpected."); 80ef21fd2b6b08d5faddaeabe83718d875d20a6abcAndreas Gampestatic_assert(DEXOPT_STORAGE_DE == 1 << 8, "DEXOPT_STORAGE_DE unexpected."); 81ef21fd2b6b08d5faddaeabe83718d875d20a6abcAndreas Gampe 82ef21fd2b6b08d5faddaeabe83718d875d20a6abcAndreas Gampestatic_assert(DEXOPT_MASK == 0x1fe, "DEXOPT_MASK unexpected."); 83ef21fd2b6b08d5faddaeabe83718d875d20a6abcAndreas Gampe 84ef21fd2b6b08d5faddaeabe83718d875d20a6abcAndreas Gampe 85ef21fd2b6b08d5faddaeabe83718d875d20a6abcAndreas Gampe 8673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampetemplate<typename T> 8773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampestatic constexpr T RoundDown(T x, typename std::decay<T>::type n) { 8873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return DCHECK_CONSTEXPR(IsPowerOfTwo(n), , T(0))(x & -n); 8973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe} 9073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 9173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampetemplate<typename T> 9273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampestatic constexpr T RoundUp(T x, typename std::remove_reference<T>::type n) { 9373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return RoundDown(x + n - 1, n); 9473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe} 9573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 9673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampeclass OTAPreoptService { 9773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe public: 9873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // Main driver. Performs the following steps. 9973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // 10073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // 1) Parse options (read system properties etc from B partition). 10173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // 10273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // 2) Read in package data. 10373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // 10473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // 3) Prepare environment variables. 10573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // 10673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // 4) Prepare(compile) boot image, if necessary. 10773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // 10873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // 5) Run update. 10973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe int Main(int argc, char** argv) { 110d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (!ReadArguments(argc, argv)) { 111d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe LOG(ERROR) << "Failed reading command line."; 112d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return 1; 113d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 114d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 11573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (!ReadSystemProperties()) { 11673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe LOG(ERROR)<< "Failed reading system properties."; 117d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return 2; 11873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 11973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 12073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (!ReadEnvironment()) { 12173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe LOG(ERROR) << "Failed reading environment properties."; 122d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return 3; 12373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 12473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 125d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (!CheckAndInitializeInstalldGlobals()) { 126d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe LOG(ERROR) << "Failed initializing globals."; 127d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return 4; 12873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 12973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 13073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe PrepareEnvironment(); 13173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 132d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (!PrepareBootImage(/* force */ false)) { 13373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe LOG(ERROR) << "Failed preparing boot image."; 134d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return 5; 13573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 13673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 13773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe int dexopt_retcode = RunPreopt(); 13873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 13973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return dexopt_retcode; 14073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 14173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 142d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe int GetProperty(const char* key, char* value, const char* default_value) const { 14373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe const std::string* prop_value = system_properties_.GetProperty(key); 14473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (prop_value == nullptr) { 14573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (default_value == nullptr) { 14673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return 0; 14773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 14873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // Copy in the default value. 14973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe strncpy(value, default_value, kPropertyValueMax - 1); 15073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe value[kPropertyValueMax - 1] = 0; 15173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return strlen(default_value);// TODO: Need to truncate? 15273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 15373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe size_t size = std::min(kPropertyValueMax - 1, prop_value->length()); 15473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe strncpy(value, prop_value->data(), size); 15573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe value[size] = 0; 15673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return static_cast<int>(size); 15773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 15873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 159d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe std::string GetOTADataDirectory() const { 160d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return StringPrintf("%s/%s", GetOtaDirectoryPrefix().c_str(), target_slot_.c_str()); 161d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 162d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 163d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe const std::string& GetTargetSlot() const { 164d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return target_slot_; 165d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 166d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 16773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampeprivate: 168d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 169c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe struct Parameters { 170c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe const char *apk_path; 171c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe uid_t uid; 172c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe const char *pkgName; 173c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe const char *instruction_set; 174c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe int dexopt_needed; 175c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe const char* oat_dir; 176c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe int dexopt_flags; 177c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe const char* compiler_filter; 178c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe const char* volume_uuid; 179c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe const char* shared_libraries; 180c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe const char* se_info; 181c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe }; 182c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 18373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe bool ReadSystemProperties() { 1841842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe static constexpr const char* kPropertyFiles[] = { 1851842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe "/default.prop", "/system/build.prop" 1861842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe }; 1871842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe 1881842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe for (size_t i = 0; i < arraysize(kPropertyFiles); ++i) { 1891842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe if (!system_properties_.Load(kPropertyFiles[i])) { 1901842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe return false; 1911842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe } 1921842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe } 1931842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe 1941842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe return true; 19573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 19673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 19773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe bool ReadEnvironment() { 1981842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe // Parse the environment variables from init.environ.rc, which have the form 1991842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe // export NAME VALUE 2001842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe // For simplicity, don't respect string quotation. The values we are interested in can be 2011842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe // encoded without them. 2021842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe std::regex export_regex("\\s*export\\s+(\\S+)\\s+(\\S+)"); 2031842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe bool parse_result = ParseFile("/init.environ.rc", [&](const std::string& line) { 2041842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe std::smatch export_match; 2051842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe if (!std::regex_match(line, export_match, export_regex)) { 2061842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe return true; 2071842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe } 2081842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe 2091842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe if (export_match.size() != 3) { 2101842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe return true; 2111842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe } 2121842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe 2131842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe std::string name = export_match[1].str(); 2141842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe std::string value = export_match[2].str(); 2151842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe 2161842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe system_properties_.SetProperty(name, value); 2171842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe 2181842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe return true; 2191842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe }); 2201842af3a4a8fccf71f5c569071518de14b3698acAndreas Gampe if (!parse_result) { 22173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return false; 22273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 22373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 224d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (system_properties_.GetProperty(kAndroidDataPathPropertyName) == nullptr) { 225d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return false; 22673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 227d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe android_data_ = *system_properties_.GetProperty(kAndroidDataPathPropertyName); 228d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 229d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (system_properties_.GetProperty(kAndroidRootPathPropertyName) == nullptr) { 230d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return false; 231d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 232d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe android_root_ = *system_properties_.GetProperty(kAndroidRootPathPropertyName); 233d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 234d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (system_properties_.GetProperty(kBootClassPathPropertyName) == nullptr) { 235d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return false; 236d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 237d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe boot_classpath_ = *system_properties_.GetProperty(kBootClassPathPropertyName); 238d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 239d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (system_properties_.GetProperty(ASEC_MOUNTPOINT_ENV_NAME) == nullptr) { 240d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return false; 241d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 242d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe asec_mountpoint_ = *system_properties_.GetProperty(ASEC_MOUNTPOINT_ENV_NAME); 24373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 24473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return true; 24573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 24673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 247d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe const std::string& GetAndroidData() const { 248d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return android_data_; 249d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 250d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 251d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe const std::string& GetAndroidRoot() const { 252d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return android_root_; 253d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 254d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 255d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe const std::string GetOtaDirectoryPrefix() const { 256d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return GetAndroidData() + "/ota"; 257d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 258d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 259d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe bool CheckAndInitializeInstalldGlobals() { 260d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe // init_globals_from_data_and_root requires "ASEC_MOUNTPOINT" in the environment. We 261d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe // do not use any datapath that includes this, but we'll still have to set it. 262d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe CHECK(system_properties_.GetProperty(ASEC_MOUNTPOINT_ENV_NAME) != nullptr); 263d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe int result = setenv(ASEC_MOUNTPOINT_ENV_NAME, asec_mountpoint_.c_str(), 0); 264d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (result != 0) { 265d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe LOG(ERROR) << "Could not set ASEC_MOUNTPOINT environment variable"; 266d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return false; 267d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 268d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 269d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (!init_globals_from_data_and_root(GetAndroidData().c_str(), GetAndroidRoot().c_str())) { 270d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe LOG(ERROR) << "Could not initialize globals; exiting."; 271d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return false; 272d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 273d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 274d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe // This is different from the normal installd. We only do the base 275d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe // directory, the rest will be created on demand when each app is compiled. 276d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (access(GetOtaDirectoryPrefix().c_str(), R_OK) < 0) { 277d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe LOG(ERROR) << "Could not access " << GetOtaDirectoryPrefix(); 278d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return false; 279d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 280d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 281d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return true; 282d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 283d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 284c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe bool ParseUInt(const char* in, uint32_t* out) { 285c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe char* end; 286c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe long long int result = strtoll(in, &end, 0); 287c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe if (in == end || *end != '\0') { 288c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe return false; 289c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe } 290c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe if (result < std::numeric_limits<uint32_t>::min() || 291c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe std::numeric_limits<uint32_t>::max() < result) { 292c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe return false; 293c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe } 294c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe *out = static_cast<uint32_t>(result); 295c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe return true; 296c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe } 297d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 298c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe bool ReadArguments(int argc, char** argv) { 299c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe // Expected command line: 300c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe // target-slot [version] dexopt {DEXOPT_PARAMETERS} 301d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 302d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe const char* target_slot_arg = argv[1]; 303d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (target_slot_arg == nullptr) { 304d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe LOG(ERROR) << "Missing parameters"; 305d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return false; 306d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 307d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe // Sanitize value. Only allow (a-zA-Z0-9_)+. 308d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe target_slot_ = target_slot_arg; 309fd12edaeab839f3f1f087cc75bd18b4d8af5b192Andreas Gampe if (!ValidateTargetSlotSuffix(target_slot_)) { 310fd12edaeab839f3f1f087cc75bd18b4d8af5b192Andreas Gampe LOG(ERROR) << "Target slot suffix not legal: " << target_slot_; 311fd12edaeab839f3f1f087cc75bd18b4d8af5b192Andreas Gampe return false; 312d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 313d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 314c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe // Check for version or "dexopt" next. 315c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe if (argv[2] == nullptr) { 316c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe LOG(ERROR) << "Missing parameters"; 317c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe return false; 318c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe } 319c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 320c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe if (std::string("dexopt").compare(argv[2]) == 0) { 321c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe // This is version 1 (N) or pre-versioning version 2. 322c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe constexpr int kV2ArgCount = 1 // "otapreopt" 323c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe + 1 // slot 324c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe + 1 // "dexopt" 325c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe + 1 // apk_path 326c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe + 1 // uid 327c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe + 1 // pkg 328c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe + 1 // isa 329c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe + 1 // dexopt_needed 330c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe + 1 // oat_dir 331c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe + 1 // dexopt_flags 332c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe + 1 // filter 333c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe + 1 // volume 334c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe + 1 // libs 335645e79cb279575b569bd308e7dfb09645e19d0ddAndreas Gampe + 1; // seinfo 336c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe if (argc == kV2ArgCount) { 337c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe return ReadArgumentsV2(argc, argv, false); 338c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe } else { 339c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe return ReadArgumentsV1(argc, argv); 340c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe } 341c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe } 342c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 343c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe uint32_t version; 344c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe if (!ParseUInt(argv[2], &version)) { 345c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe LOG(ERROR) << "Could not parse version: " << argv[2]; 346c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe return false; 347c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe } 348c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 349c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe switch (version) { 350c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe case 2: 351c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe return ReadArgumentsV2(argc, argv, true); 352c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 353c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe default: 354c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe LOG(ERROR) << "Unsupported version " << version; 355c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe return false; 356c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe } 357c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe } 358c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 359c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe bool ReadArgumentsV2(int argc ATTRIBUTE_UNUSED, char** argv, bool versioned) { 360c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe size_t dexopt_index = versioned ? 3 : 2; 361c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 362c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe // Check for "dexopt". 363c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe if (argv[dexopt_index] == nullptr) { 364c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe LOG(ERROR) << "Missing parameters"; 365c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe return false; 366c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe } 367c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe if (std::string("dexopt").compare(argv[dexopt_index]) != 0) { 368c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe LOG(ERROR) << "Expected \"dexopt\""; 369c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe return false; 370c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe } 371c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 372c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe size_t param_index = 0; 373c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe for (;; ++param_index) { 374c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe const char* param = argv[dexopt_index + 1 + param_index]; 375c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe if (param == nullptr) { 376c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe break; 377c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe } 378c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 379c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe switch (param_index) { 380c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe case 0: 381c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe package_parameters_.apk_path = param; 382c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe break; 383c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 384c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe case 1: 385c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe package_parameters_.uid = atoi(param); 386c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe break; 387c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 388c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe case 2: 389c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe package_parameters_.pkgName = param; 390c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe break; 391c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 392c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe case 3: 393c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe package_parameters_.instruction_set = param; 394c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe break; 395c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 396c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe case 4: 397c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe package_parameters_.dexopt_needed = atoi(param); 398c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe break; 399c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 400c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe case 5: 401c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe package_parameters_.oat_dir = param; 402c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe break; 403c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 404c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe case 6: 405c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe package_parameters_.dexopt_flags = atoi(param); 406c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe break; 407c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 408c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe case 7: 409c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe package_parameters_.compiler_filter = param; 410c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe break; 411c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 412c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe case 8: 413c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe package_parameters_.volume_uuid = ParseNull(param); 414c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe break; 415c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 416c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe case 9: 417c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe package_parameters_.shared_libraries = ParseNull(param); 418c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe break; 419c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 420c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe case 10: 421c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe package_parameters_.se_info = ParseNull(param); 422c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe break; 423c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 424c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe default: 425c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe LOG(ERROR) << "Too many arguments, got " << param; 426c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe return false; 427c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe } 428c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe } 429c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 430c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe if (param_index != 11) { 431c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe LOG(ERROR) << "Not enough parameters"; 432c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe return false; 433c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe } 434c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 435c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe return true; 436c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe } 437c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 438c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe static int ReplaceMask(int input, int old_mask, int new_mask) { 439c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe return (input & old_mask) != 0 ? new_mask : 0; 440c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe } 441c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 442c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe bool ReadArgumentsV1(int argc ATTRIBUTE_UNUSED, char** argv) { 443c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe // Check for "dexopt". 444d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (argv[2] == nullptr) { 445d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe LOG(ERROR) << "Missing parameters"; 446d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return false; 447d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 448d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (std::string("dexopt").compare(argv[2]) != 0) { 449c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe LOG(ERROR) << "Expected \"dexopt\""; 450d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return false; 451d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 452d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 453c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe size_t param_index = 0; 454c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe for (;; ++param_index) { 455c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe const char* param = argv[3 + param_index]; 456c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe if (param == nullptr) { 457c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe break; 458c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe } 459c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 460c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe switch (param_index) { 461c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe case 0: 462c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe package_parameters_.apk_path = param; 463c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe break; 464c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 465c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe case 1: 466c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe package_parameters_.uid = atoi(param); 467c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe break; 468c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 469c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe case 2: 470c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe package_parameters_.pkgName = param; 471c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe break; 472c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 473c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe case 3: 474c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe package_parameters_.instruction_set = param; 475c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe break; 476c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 477c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe case 4: { 478c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe // Version 1 had: 479c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe // DEXOPT_DEX2OAT_NEEDED = 1 480c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe // DEXOPT_PATCHOAT_NEEDED = 2 481c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe // DEXOPT_SELF_PATCHOAT_NEEDED = 3 482c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe // We will simply use DEX2OAT_FROM_SCRATCH. 483c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe package_parameters_.dexopt_needed = DEX2OAT_FROM_SCRATCH; 484c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe break; 485c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe } 486c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 487c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe case 5: 488c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe package_parameters_.oat_dir = param; 489c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe break; 490c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 491c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe case 6: { 492c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe // Version 1 had: 493c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe constexpr int OLD_DEXOPT_PUBLIC = 1 << 1; 4942520d44e664049f67f56795bedf5cc1d0494cc44Nicolas Geoffray // Note: DEXOPT_SAFEMODE has been removed. 4952520d44e664049f67f56795bedf5cc1d0494cc44Nicolas Geoffray // constexpr int OLD_DEXOPT_SAFEMODE = 1 << 2; 496c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe constexpr int OLD_DEXOPT_DEBUGGABLE = 1 << 3; 497c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe constexpr int OLD_DEXOPT_BOOTCOMPLETE = 1 << 4; 498c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe constexpr int OLD_DEXOPT_PROFILE_GUIDED = 1 << 5; 499c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe constexpr int OLD_DEXOPT_OTA = 1 << 6; 500c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe int input = atoi(param); 501c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe package_parameters_.dexopt_flags = 502c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe ReplaceMask(input, OLD_DEXOPT_PUBLIC, DEXOPT_PUBLIC) | 503c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe ReplaceMask(input, OLD_DEXOPT_DEBUGGABLE, DEXOPT_DEBUGGABLE) | 504c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe ReplaceMask(input, OLD_DEXOPT_BOOTCOMPLETE, DEXOPT_BOOTCOMPLETE) | 505c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe ReplaceMask(input, OLD_DEXOPT_PROFILE_GUIDED, DEXOPT_PROFILE_GUIDED) | 506c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe ReplaceMask(input, OLD_DEXOPT_OTA, 0); 507c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe break; 508c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe } 509c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 510c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe case 7: 511c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe package_parameters_.compiler_filter = param; 512c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe break; 513c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 514c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe case 8: 515c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe package_parameters_.volume_uuid = ParseNull(param); 516c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe break; 517c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 518c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe case 9: 519c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe package_parameters_.shared_libraries = ParseNull(param); 520c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe break; 521c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 522c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe default: 523c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe LOG(ERROR) << "Too many arguments, got " << param; 524c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe return false; 525c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe } 52673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 527c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 528c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe if (param_index != 10) { 529c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe LOG(ERROR) << "Not enough parameters"; 53073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return false; 53173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 53273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 533c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe // Set se_info to null. It is only relevant for secondary dex files, which we won't 534c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe // receive from a v1 A side. 535c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe package_parameters_.se_info = nullptr; 536c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe 53773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return true; 53873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 53973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 54073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe void PrepareEnvironment() { 541d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe environ_.push_back(StringPrintf("BOOTCLASSPATH=%s", boot_classpath_.c_str())); 542d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe environ_.push_back(StringPrintf("ANDROID_DATA=%s", GetOTADataDirectory().c_str())); 543d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe environ_.push_back(StringPrintf("ANDROID_ROOT=%s", android_root_.c_str())); 54473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 54573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe for (const std::string& e : environ_) { 54673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe putenv(const_cast<char*>(e.c_str())); 54773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 54873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 54973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 55073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // Ensure that we have the right boot image. The first time any app is 55173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // compiled, we'll try to generate it. 552d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe bool PrepareBootImage(bool force) const { 553c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe if (package_parameters_.instruction_set == nullptr) { 55473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe LOG(ERROR) << "Instruction set missing."; 55573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return false; 55673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 557c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe const char* isa = package_parameters_.instruction_set; 55873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 55973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // Check whether the file exists where expected. 560d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe std::string dalvik_cache = GetOTADataDirectory() + "/" + DALVIK_CACHE; 56173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe std::string isa_path = dalvik_cache + "/" + isa; 56273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe std::string art_path = isa_path + "/system@framework@boot.art"; 56373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe std::string oat_path = isa_path + "/system@framework@boot.oat"; 564d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe bool cleared = false; 565d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (access(art_path.c_str(), F_OK) == 0 && access(oat_path.c_str(), F_OK) == 0) { 566d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe // Files exist, assume everything is alright if not forced. Otherwise clean up. 567d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (!force) { 568d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return true; 569d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 570d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe ClearDirectory(isa_path); 571d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe cleared = true; 57273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 57373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 574d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe // Reset umask in otapreopt, so that we control the the access for the files we create. 575d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe umask(0); 576d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 57773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // Create the directories, if necessary. 57873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (access(dalvik_cache.c_str(), F_OK) != 0) { 579d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (!CreatePath(dalvik_cache)) { 580d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe PLOG(ERROR) << "Could not create dalvik-cache dir " << dalvik_cache; 58173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return false; 58273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 58373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 58473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (access(isa_path.c_str(), F_OK) != 0) { 585d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (!CreatePath(isa_path)) { 58673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe PLOG(ERROR) << "Could not create dalvik-cache isa dir"; 58773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return false; 58873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 58973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 59073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 5915709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe // Prepare to create. 592d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (!cleared) { 593d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe ClearDirectory(isa_path); 594d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 59573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 5969fb85b0667235ebfdea00ea345febc8f6eb203d2Andreas Gampe std::string preopted_boot_art_path = StringPrintf("/system/framework/%s/boot.art", isa); 5975709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe if (access(preopted_boot_art_path.c_str(), F_OK) == 0) { 5985709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe return PatchoatBootImage(art_path, isa); 5995709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe } else { 6005709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe // No preopted boot image. Try to compile. 601d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return Dex2oatBootImage(boot_classpath_, art_path, oat_path, isa); 6025709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe } 6035709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe } 6045709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe 605d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe static bool CreatePath(const std::string& path) { 606d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe // Create the given path. Use string processing instead of dirname, as dirname's need for 607d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe // a writable char buffer is painful. 608d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 609d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe // First, try to use the full path. 610d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (mkdir(path.c_str(), 0711) == 0) { 611d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return true; 612d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 613d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (errno != ENOENT) { 614d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe PLOG(ERROR) << "Could not create path " << path; 615d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return false; 616d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 617d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 618d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe // Now find the parent and try that first. 619d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe size_t last_slash = path.find_last_of('/'); 620d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (last_slash == std::string::npos || last_slash == 0) { 621d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe PLOG(ERROR) << "Could not create " << path; 622d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return false; 623d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 624d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 625d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (!CreatePath(path.substr(0, last_slash))) { 626d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return false; 627d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 628d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 629d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (mkdir(path.c_str(), 0711) == 0) { 630d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return true; 631d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 632d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe PLOG(ERROR) << "Could not create " << path; 633d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return false; 634d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 635d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 636d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe static void ClearDirectory(const std::string& dir) { 637d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe DIR* c_dir = opendir(dir.c_str()); 638d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (c_dir == nullptr) { 639d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe PLOG(WARNING) << "Unable to open " << dir << " to delete it's contents"; 640d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return; 641d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 642d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 643d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe for (struct dirent* de = readdir(c_dir); de != nullptr; de = readdir(c_dir)) { 644d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe const char* name = de->d_name; 645d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) { 646d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe continue; 647d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 648d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe // We only want to delete regular files and symbolic links. 649d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe std::string file = StringPrintf("%s/%s", dir.c_str(), name); 650d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (de->d_type != DT_REG && de->d_type != DT_LNK) { 651d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe LOG(WARNING) << "Unexpected file " 652d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe << file 653d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe << " of type " 654d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe << std::hex 655d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe << de->d_type 656d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe << " encountered."; 657d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } else { 658d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe // Try to unlink the file. 659d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (unlink(file.c_str()) != 0) { 660d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe PLOG(ERROR) << "Unable to unlink " << file; 661d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 662d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 663d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 664d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe CHECK_EQ(0, closedir(c_dir)) << "Unable to close directory."; 665d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 666d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 667d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe bool PatchoatBootImage(const std::string& art_path, const char* isa) const { 6685709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe // This needs to be kept in sync with ART, see art/runtime/gc/space/image_space.cc. 6695709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe 6705709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe std::vector<std::string> cmd; 6719fb85b0667235ebfdea00ea345febc8f6eb203d2Andreas Gampe cmd.push_back("/system/bin/patchoat"); 6725709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe 6735709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe cmd.push_back("--input-image-location=/system/framework/boot.art"); 6745709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe cmd.push_back(StringPrintf("--output-image-file=%s", art_path.c_str())); 6755709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe 6765709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe cmd.push_back(StringPrintf("--instruction-set=%s", isa)); 6775709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe 6785709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe int32_t base_offset = ChooseRelocationOffsetDelta(ART_BASE_ADDRESS_MIN_DELTA, 6795709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe ART_BASE_ADDRESS_MAX_DELTA); 680febf0bf33ca81edcdaab3625e2711fa58b398cc5Andreas Gampe cmd.push_back(StringPrintf("--base-offset-delta=%d", base_offset)); 6815709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe 6825709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe std::string error_msg; 6835709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe bool result = Exec(cmd, &error_msg); 6845709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe if (!result) { 6855709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe LOG(ERROR) << "Could not generate boot image: " << error_msg; 6865709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe } 6875709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe return result; 6885709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe } 6895709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe 6905709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe bool Dex2oatBootImage(const std::string& boot_cp, 6915709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe const std::string& art_path, 6925709b5758d75085aeab121db94e8d6dbafe0b7aeAndreas Gampe const std::string& oat_path, 693d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe const char* isa) const { 69473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // This needs to be kept in sync with ART, see art/runtime/gc/space/image_space.cc. 69573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe std::vector<std::string> cmd; 6969fb85b0667235ebfdea00ea345febc8f6eb203d2Andreas Gampe cmd.push_back("/system/bin/dex2oat"); 69773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe cmd.push_back(StringPrintf("--image=%s", art_path.c_str())); 6986db8db9f3369c48de87f97f4d4636d446837fe32Andreas Gampe for (const std::string& boot_part : Split(boot_cp, ":")) { 69973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe cmd.push_back(StringPrintf("--dex-file=%s", boot_part.c_str())); 70073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 70173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe cmd.push_back(StringPrintf("--oat-file=%s", oat_path.c_str())); 70273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 70373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe int32_t base_offset = ChooseRelocationOffsetDelta(ART_BASE_ADDRESS_MIN_DELTA, 70473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ART_BASE_ADDRESS_MAX_DELTA); 70573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe cmd.push_back(StringPrintf("--base=0x%x", ART_BASE_ADDRESS + base_offset)); 70673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 70773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe cmd.push_back(StringPrintf("--instruction-set=%s", isa)); 70873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 70973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // These things are pushed by AndroidRuntime, see frameworks/base/core/jni/AndroidRuntime.cpp. 71073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe AddCompilerOptionFromSystemProperty("dalvik.vm.image-dex2oat-Xms", 71173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe "-Xms", 71273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe true, 71373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe cmd); 71473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe AddCompilerOptionFromSystemProperty("dalvik.vm.image-dex2oat-Xmx", 71573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe "-Xmx", 71673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe true, 71773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe cmd); 71873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe AddCompilerOptionFromSystemProperty("dalvik.vm.image-dex2oat-filter", 71973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe "--compiler-filter=", 72073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe false, 72173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe cmd); 7229fb85b0667235ebfdea00ea345febc8f6eb203d2Andreas Gampe cmd.push_back("--image-classes=/system/etc/preloaded-classes"); 72373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // TODO: Compiled-classes. 72473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe const std::string* extra_opts = 72573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe system_properties_.GetProperty("dalvik.vm.image-dex2oat-flags"); 72673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (extra_opts != nullptr) { 7276db8db9f3369c48de87f97f4d4636d446837fe32Andreas Gampe std::vector<std::string> extra_vals = Split(*extra_opts, " "); 72873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe cmd.insert(cmd.end(), extra_vals.begin(), extra_vals.end()); 72973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 73073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // TODO: Should we lower this? It's usually set close to max, because 73173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // normally there's not much else going on at boot. 73273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe AddCompilerOptionFromSystemProperty("dalvik.vm.image-dex2oat-threads", 73373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe "-j", 73473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe false, 73573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe cmd); 73673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe AddCompilerOptionFromSystemProperty( 73773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe StringPrintf("dalvik.vm.isa.%s.variant", isa).c_str(), 73873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe "--instruction-set-variant=", 73973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe false, 74073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe cmd); 74173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe AddCompilerOptionFromSystemProperty( 74273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe StringPrintf("dalvik.vm.isa.%s.features", isa).c_str(), 74373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe "--instruction-set-features=", 74473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe false, 74573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe cmd); 74673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 74773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe std::string error_msg; 74873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe bool result = Exec(cmd, &error_msg); 74973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (!result) { 75073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe LOG(ERROR) << "Could not generate boot image: " << error_msg; 75173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 75273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return result; 75373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 75473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 75573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe static const char* ParseNull(const char* arg) { 75612375069e753adea6c123fca7706b1018d358c92Andreas Gampe // b/38186355. Revert soon. 75712375069e753adea6c123fca7706b1018d358c92Andreas Gampe if (strcmp(arg, "!null") == 0) { 75812375069e753adea6c123fca7706b1018d358c92Andreas Gampe return nullptr; 75912375069e753adea6c123fca7706b1018d358c92Andreas Gampe } 76073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return (strcmp(arg, "!") == 0) ? nullptr : arg; 76173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 76273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 763d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe bool ShouldSkipPreopt() const { 76456f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // There's one thing we have to be careful about: we may/will be asked to compile an app 76556f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // living in the system image. This may be a valid request - if the app wasn't compiled, 76656f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // e.g., if the system image wasn't large enough to include preopted files. However, the 76756f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // data we have is from the old system, so the driver (the OTA service) can't actually 76856f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // know. Thus, we will get requests for apps that have preopted components. To avoid 76956f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // duplication (we'd generate files that are not used and are *not* cleaned up), do two 77056f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // simple checks: 77156f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // 77256f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // 1) Does the apk_path start with the value of ANDROID_ROOT? (~in the system image) 77356f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // (For simplicity, assume the value of ANDROID_ROOT does not contain a symlink.) 77456f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // 77556f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // 2) If you replace the name in the apk_path with "oat," does the path exist? 77656f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // (=have a subdirectory for preopted files) 77756f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // 77856f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // If the answer to both is yes, skip the dexopt. 77956f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // 78056f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // Note: while one may think it's OK to call dexopt and it will fail (because APKs should 78156f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // be stripped), that's not true for APKs signed outside the build system (so the 78256f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // jar content must be exactly the same). 78356f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe 78456f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // (This is ugly as it's the only thing where we need to understand the contents 78556f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // of package_parameters_, but it beats postponing the decision or using the call- 78656f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe // backs to do weird things.) 787c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe const char* apk_path = package_parameters_.apk_path; 788c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe CHECK(apk_path != nullptr); 789c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe if (StartsWith(apk_path, android_root_.c_str())) { 790c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe const char* last_slash = strrchr(apk_path, '/'); 79156f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe if (last_slash != nullptr) { 792c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe std::string path(apk_path, last_slash - apk_path + 1); 79356f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe CHECK(EndsWith(path, "/")); 79456f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe path = path + "oat"; 79556f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe if (access(path.c_str(), F_OK) == 0) { 796d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return true; 79756f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe } 79856f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe } 79956f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe } 80056f79f96207c9c0101a5ca0237a8da631d93d5c5Andreas Gampe 801d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe // Another issue is unavailability of files in the new system. If the partition 802d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe // layout changes, otapreopt_chroot may not know about this. Then files from that 803d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe // partition will not be available and fail to build. This is problematic, as 804d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe // this tool will wipe the OTA artifact cache and try again (for robustness after 805d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe // a failed OTA with remaining cache artifacts). 806c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe if (access(apk_path, F_OK) != 0) { 807c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe LOG(WARNING) << "Skipping preopt of non-existing package " << apk_path; 808d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return true; 809d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 810d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 811d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return false; 812d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 813d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 814b39d2f093242fe03772b540c031e914e857b9dc2Andreas Gampe // Run dexopt with the parameters of package_parameters_. 815b39d2f093242fe03772b540c031e914e857b9dc2Andreas Gampe int Dexopt() { 816b39d2f093242fe03772b540c031e914e857b9dc2Andreas Gampe return dexopt(package_parameters_.apk_path, 817b39d2f093242fe03772b540c031e914e857b9dc2Andreas Gampe package_parameters_.uid, 818b39d2f093242fe03772b540c031e914e857b9dc2Andreas Gampe package_parameters_.pkgName, 819b39d2f093242fe03772b540c031e914e857b9dc2Andreas Gampe package_parameters_.instruction_set, 820b39d2f093242fe03772b540c031e914e857b9dc2Andreas Gampe package_parameters_.dexopt_needed, 821b39d2f093242fe03772b540c031e914e857b9dc2Andreas Gampe package_parameters_.oat_dir, 822b39d2f093242fe03772b540c031e914e857b9dc2Andreas Gampe package_parameters_.dexopt_flags, 823b39d2f093242fe03772b540c031e914e857b9dc2Andreas Gampe package_parameters_.compiler_filter, 824b39d2f093242fe03772b540c031e914e857b9dc2Andreas Gampe package_parameters_.volume_uuid, 825b39d2f093242fe03772b540c031e914e857b9dc2Andreas Gampe package_parameters_.shared_libraries, 826b39d2f093242fe03772b540c031e914e857b9dc2Andreas Gampe package_parameters_.se_info); 827b39d2f093242fe03772b540c031e914e857b9dc2Andreas Gampe } 828b39d2f093242fe03772b540c031e914e857b9dc2Andreas Gampe 829d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe int RunPreopt() { 830d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (ShouldSkipPreopt()) { 831d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return 0; 832d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 833d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 834b39d2f093242fe03772b540c031e914e857b9dc2Andreas Gampe int dexopt_result = Dexopt(); 835d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (dexopt_result == 0) { 836d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return 0; 837d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 838d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 839d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe // If the dexopt failed, we may have a stale boot image from a previous OTA run. 84054e1a402610d7f392f7e421dcafcf6b017a99d88Andreas Gampe // Then regenerate and retry. 841b39d2f093242fe03772b540c031e914e857b9dc2Andreas Gampe if (WEXITSTATUS(dexopt_result) == 84254e1a402610d7f392f7e421dcafcf6b017a99d88Andreas Gampe static_cast<int>(art::dex2oat::ReturnCode::kCreateRuntime)) { 843b39d2f093242fe03772b540c031e914e857b9dc2Andreas Gampe if (!PrepareBootImage(/* force */ true)) { 844b39d2f093242fe03772b540c031e914e857b9dc2Andreas Gampe LOG(ERROR) << "Forced boot image creating failed. Original error return was " 845b39d2f093242fe03772b540c031e914e857b9dc2Andreas Gampe << dexopt_result; 846b39d2f093242fe03772b540c031e914e857b9dc2Andreas Gampe return dexopt_result; 847b39d2f093242fe03772b540c031e914e857b9dc2Andreas Gampe } 848b39d2f093242fe03772b540c031e914e857b9dc2Andreas Gampe 849b39d2f093242fe03772b540c031e914e857b9dc2Andreas Gampe int dexopt_result_boot_image_retry = Dexopt(); 850b39d2f093242fe03772b540c031e914e857b9dc2Andreas Gampe if (dexopt_result_boot_image_retry == 0) { 851b39d2f093242fe03772b540c031e914e857b9dc2Andreas Gampe return 0; 852b39d2f093242fe03772b540c031e914e857b9dc2Andreas Gampe } 85354e1a402610d7f392f7e421dcafcf6b017a99d88Andreas Gampe } 854d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 855b39d2f093242fe03772b540c031e914e857b9dc2Andreas Gampe // If this was a profile-guided run, we may have profile version issues. Try to downgrade, 856b39d2f093242fe03772b540c031e914e857b9dc2Andreas Gampe // if possible. 857b39d2f093242fe03772b540c031e914e857b9dc2Andreas Gampe if ((package_parameters_.dexopt_flags & DEXOPT_PROFILE_GUIDED) == 0) { 858d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return dexopt_result; 859d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 860d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 861b39d2f093242fe03772b540c031e914e857b9dc2Andreas Gampe LOG(WARNING) << "Downgrading compiler filter in an attempt to progress compilation"; 862b39d2f093242fe03772b540c031e914e857b9dc2Andreas Gampe package_parameters_.dexopt_flags &= ~DEXOPT_PROFILE_GUIDED; 863b39d2f093242fe03772b540c031e914e857b9dc2Andreas Gampe return Dexopt(); 86473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 86573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 86673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe //////////////////////////////////// 86773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // Helpers, mostly taken from ART // 86873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe //////////////////////////////////// 86973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 87073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // Wrapper on fork/execv to run a command in a subprocess. 871d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe static bool Exec(const std::vector<std::string>& arg_vector, std::string* error_msg) { 8726db8db9f3369c48de87f97f4d4636d446837fe32Andreas Gampe const std::string command_line = Join(arg_vector, ' '); 87373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 87473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe CHECK_GE(arg_vector.size(), 1U) << command_line; 87573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 87673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // Convert the args to char pointers. 87773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe const char* program = arg_vector[0].c_str(); 87873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe std::vector<char*> args; 87973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe for (size_t i = 0; i < arg_vector.size(); ++i) { 88073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe const std::string& arg = arg_vector[i]; 88173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe char* arg_str = const_cast<char*>(arg.c_str()); 88273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe CHECK(arg_str != nullptr) << i; 88373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe args.push_back(arg_str); 88473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 88573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe args.push_back(nullptr); 88673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 88773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // Fork and exec. 88873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe pid_t pid = fork(); 88973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (pid == 0) { 89073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // No allocation allowed between fork and exec. 89173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 89273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // Change process groups, so we don't get reaped by ProcessManager. 89373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe setpgid(0, 0); 89473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 89573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe execv(program, &args[0]); 89673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 89773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe PLOG(ERROR) << "Failed to execv(" << command_line << ")"; 89873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // _exit to avoid atexit handlers in child. 89973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe _exit(1); 90073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } else { 90173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (pid == -1) { 90273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe *error_msg = StringPrintf("Failed to execv(%s) because fork failed: %s", 90373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe command_line.c_str(), strerror(errno)); 90473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return false; 90573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 90673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 90773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // wait for subprocess to finish 90873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe int status; 90973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe pid_t got_pid = TEMP_FAILURE_RETRY(waitpid(pid, &status, 0)); 91073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (got_pid != pid) { 91173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe *error_msg = StringPrintf("Failed after fork for execv(%s) because waitpid failed: " 91273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe "wanted %d, got %d: %s", 91373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe command_line.c_str(), pid, got_pid, strerror(errno)); 91473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return false; 91573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 91673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { 91773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe *error_msg = StringPrintf("Failed execv(%s) because non-0 exit status", 91873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe command_line.c_str()); 91973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return false; 92073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 92173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 92273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return true; 92373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 92473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 92573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // Choose a random relocation offset. Taken from art/runtime/gc/image_space.cc. 92673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe static int32_t ChooseRelocationOffsetDelta(int32_t min_delta, int32_t max_delta) { 92773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe constexpr size_t kPageSize = PAGE_SIZE; 92873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe CHECK_EQ(min_delta % kPageSize, 0u); 92973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe CHECK_EQ(max_delta % kPageSize, 0u); 93073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe CHECK_LT(min_delta, max_delta); 93173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 93273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe std::default_random_engine generator; 93373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe generator.seed(GetSeed()); 93473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe std::uniform_int_distribution<int32_t> distribution(min_delta, max_delta); 93573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe int32_t r = distribution(generator); 93673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (r % 2 == 0) { 93773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe r = RoundUp(r, kPageSize); 93873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } else { 93973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe r = RoundDown(r, kPageSize); 94073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 94173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe CHECK_LE(min_delta, r); 94273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe CHECK_GE(max_delta, r); 94373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe CHECK_EQ(r % kPageSize, 0u); 94473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return r; 94573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 94673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 94773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe static uint64_t GetSeed() { 94873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#ifdef __BIONIC__ 94973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // Bionic exposes arc4random, use it. 95073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe uint64_t random_data; 95173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe arc4random_buf(&random_data, sizeof(random_data)); 95273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return random_data; 95373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#else 95473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#error "This is only supposed to run with bionic. Otherwise, implement..." 95573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe#endif 95673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 95773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 95873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe void AddCompilerOptionFromSystemProperty(const char* system_property, 95973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe const char* prefix, 96073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe bool runtime, 961d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe std::vector<std::string>& out) const { 962d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe const std::string* value = system_properties_.GetProperty(system_property); 96373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (value != nullptr) { 96473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (runtime) { 96573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe out.push_back("--runtime-arg"); 96673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 96773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (prefix != nullptr) { 96873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe out.push_back(StringPrintf("%s%s", prefix, value->c_str())); 96973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } else { 97073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe out.push_back(*value); 97173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 97273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 97373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 97473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 975d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe static constexpr const char* kBootClassPathPropertyName = "BOOTCLASSPATH"; 976d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe static constexpr const char* kAndroidRootPathPropertyName = "ANDROID_ROOT"; 977d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe static constexpr const char* kAndroidDataPathPropertyName = "ANDROID_DATA"; 978d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe // The index of the instruction-set string inside the package parameters. Needed for 979d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe // some special-casing that requires knowledge of the instruction-set. 980d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe static constexpr size_t kISAIndex = 3; 981d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 98273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // Stores the system properties read out of the B partition. We need to use these properties 98373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // to compile, instead of the A properties we could get from init/get_property. 98473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe SystemProperties system_properties_; 98573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 986d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe // Some select properties that are always needed. 987d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe std::string target_slot_; 988d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe std::string android_root_; 989d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe std::string android_data_; 990d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe std::string boot_classpath_; 991d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe std::string asec_mountpoint_; 992d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe 993c4ced4f015ef5ba66cc89440c89369190448a4e0Andreas Gampe Parameters package_parameters_; 99473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 99573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // Store environment values we need to set. 99673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe std::vector<std::string> environ_; 99773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe}; 99873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 99973dae11162aa61396c06cbdb05b954764e944e02Andreas GampeOTAPreoptService gOps; 100073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 100173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe//////////////////////// 100273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe// Plug-in functions. // 100373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe//////////////////////// 100473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 100573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampeint get_property(const char *key, char *value, const char *default_value) { 100673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return gOps.GetProperty(key, value, default_value); 100773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe} 100873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 100973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe// Compute the output path of 101073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampebool calculate_oat_file_path(char path[PKG_PATH_MAX], const char *oat_dir, 101173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe const char *apk_path, 101273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe const char *instruction_set) { 10139c8f93a2a6ed6a764de7a617fe7a01657d0f4479Dan Austin const char *file_name_start; 10149c8f93a2a6ed6a764de7a617fe7a01657d0f4479Dan Austin const char *file_name_end; 101573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 101673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe file_name_start = strrchr(apk_path, '/'); 101773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (file_name_start == nullptr) { 101873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ALOGE("apk_path '%s' has no '/'s in it\n", apk_path); 101973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return false; 102073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 102173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe file_name_end = strrchr(file_name_start, '.'); 102273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (file_name_end == nullptr) { 102373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ALOGE("apk_path '%s' has no extension\n", apk_path); 102473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return false; 102573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 102673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 102773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // Calculate file_name 102873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe file_name_start++; // Move past '/', is valid as file_name_end is valid. 102973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe size_t file_name_len = file_name_end - file_name_start; 103073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe std::string file_name(file_name_start, file_name_len); 103173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 103273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // <apk_parent_dir>/oat/<isa>/<file_name>.odex.b 1033d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe snprintf(path, 1034d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe PKG_PATH_MAX, 1035d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe "%s/%s/%s.odex.%s", 1036d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe oat_dir, 1037d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe instruction_set, 1038d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe file_name.c_str(), 1039d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe gOps.GetTargetSlot().c_str()); 104073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return true; 104173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe} 104273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 104373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe/* 104473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe * Computes the odex file for the given apk_path and instruction_set. 104573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe * /system/framework/whatever.jar -> /system/framework/oat/<isa>/whatever.odex 104673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe * 104773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe * Returns false if it failed to determine the odex file path. 104873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe */ 104973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampebool calculate_odex_file_path(char path[PKG_PATH_MAX], const char *apk_path, 105073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe const char *instruction_set) { 105173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe const char *path_end = strrchr(apk_path, '/'); 105273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (path_end == nullptr) { 105373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ALOGE("apk_path '%s' has no '/'s in it?!\n", apk_path); 105473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return false; 105573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 105673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe std::string path_component(apk_path, path_end - apk_path); 105773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 105873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe const char *name_begin = path_end + 1; 105973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe const char *extension_start = strrchr(name_begin, '.'); 106073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (extension_start == nullptr) { 106173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ALOGE("apk_path '%s' has no extension.\n", apk_path); 106273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return false; 106373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 106473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe std::string name_component(name_begin, extension_start - name_begin); 106573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 1066d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe std::string new_path = StringPrintf("%s/oat/%s/%s.odex.%s", 106773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe path_component.c_str(), 106873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe instruction_set, 1069d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe name_component.c_str(), 1070d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe gOps.GetTargetSlot().c_str()); 1071d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe if (new_path.length() >= PKG_PATH_MAX) { 1072d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe LOG(ERROR) << "apk_path of " << apk_path << " is too long: " << new_path; 1073d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe return false; 1074d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe } 107573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe strcpy(path, new_path.c_str()); 107673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return true; 107773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe} 107873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 107973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampebool create_cache_path(char path[PKG_PATH_MAX], 108073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe const char *src, 108173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe const char *instruction_set) { 108273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe size_t srclen = strlen(src); 108373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 108473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe /* demand that we are an absolute path */ 108573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if ((src == 0) || (src[0] != '/') || strstr(src,"..")) { 108673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return false; 108773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 108873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 108973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (srclen > PKG_PATH_MAX) { // XXX: PKG_NAME_MAX? 109073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return false; 109173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 109273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 109373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe std::string from_src = std::string(src + 1); 109473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe std::replace(from_src.begin(), from_src.end(), '/', '@'); 109573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 109673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe std::string assembled_path = StringPrintf("%s/%s/%s/%s%s", 1097d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampe gOps.GetOTADataDirectory().c_str(), 109873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe DALVIK_CACHE, 109973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe instruction_set, 110073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe from_src.c_str(), 1101249c1796a2e62f8751348e5bafce9f40e6538cbaDavid Brazdil DALVIK_CACHE_POSTFIX); 110273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 110373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (assembled_path.length() + 1 > PKG_PATH_MAX) { 110473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return false; 110573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 110673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe strcpy(path, assembled_path.c_str()); 110773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 110873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return true; 110973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe} 111073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 111173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampestatic int log_callback(int type, const char *fmt, ...) { 111273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe va_list ap; 111373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe int priority; 111473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 111573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe switch (type) { 111673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe case SELINUX_WARNING: 111773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe priority = ANDROID_LOG_WARN; 111873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe break; 111973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe case SELINUX_INFO: 112073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe priority = ANDROID_LOG_INFO; 112173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe break; 112273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe default: 112373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe priority = ANDROID_LOG_ERROR; 112473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe break; 112573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 112673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe va_start(ap, fmt); 112773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe LOG_PRI_VA(priority, "SELinux", fmt, ap); 112873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe va_end(ap); 112973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return 0; 113073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe} 113173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 113273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampestatic int otapreopt_main(const int argc, char *argv[]) { 113373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe int selinux_enabled = (is_selinux_enabled() > 0); 113473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 113573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe setenv("ANDROID_LOG_TAGS", "*:v", 1); 113673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe android::base::InitLogging(argv); 113773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 113873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (argc < 2) { 113973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ALOGE("Expecting parameters"); 114073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe exit(1); 114173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 114273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 114373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe union selinux_callback cb; 114473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe cb.func_log = log_callback; 114573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe selinux_set_callback(SELINUX_CB_LOG, cb); 114673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 114773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (selinux_enabled && selinux_status_open(true) < 0) { 114873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ALOGE("Could not open selinux status; exiting.\n"); 114973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe exit(1); 115073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 115173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 115273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe int ret = android::installd::gOps.Main(argc, argv); 115373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 115473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return ret; 115573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe} 115673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 115773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe} // namespace installd 115873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe} // namespace android 115973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 116073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampeint main(const int argc, char *argv[]) { 116173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return android::installd::otapreopt_main(argc, argv); 116273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe} 1163