cmdline.h revision 57b34294758e9c00993913ebe43c7ee4698a5cc6
13774335b08076117d6950cd472cdd59a167470b5Igor Murashkin/* 23774335b08076117d6950cd472cdd59a167470b5Igor Murashkin * Copyright (C) 2014 The Android Open Source Project 33774335b08076117d6950cd472cdd59a167470b5Igor Murashkin * 43774335b08076117d6950cd472cdd59a167470b5Igor Murashkin * Licensed under the Apache License, Version 2.0 (the "License"); 53774335b08076117d6950cd472cdd59a167470b5Igor Murashkin * you may not use this file except in compliance with the License. 63774335b08076117d6950cd472cdd59a167470b5Igor Murashkin * You may obtain a copy of the License at 73774335b08076117d6950cd472cdd59a167470b5Igor Murashkin * 83774335b08076117d6950cd472cdd59a167470b5Igor Murashkin * http://www.apache.org/licenses/LICENSE-2.0 93774335b08076117d6950cd472cdd59a167470b5Igor Murashkin * 103774335b08076117d6950cd472cdd59a167470b5Igor Murashkin * Unless required by applicable law or agreed to in writing, software 113774335b08076117d6950cd472cdd59a167470b5Igor Murashkin * distributed under the License is distributed on an "AS IS" BASIS, 123774335b08076117d6950cd472cdd59a167470b5Igor Murashkin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133774335b08076117d6950cd472cdd59a167470b5Igor Murashkin * See the License for the specific language governing permissions and 143774335b08076117d6950cd472cdd59a167470b5Igor Murashkin * limitations under the License. 153774335b08076117d6950cd472cdd59a167470b5Igor Murashkin */ 163774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 173774335b08076117d6950cd472cdd59a167470b5Igor Murashkin#ifndef ART_CMDLINE_CMDLINE_H_ 183774335b08076117d6950cd472cdd59a167470b5Igor Murashkin#define ART_CMDLINE_CMDLINE_H_ 193774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 203774335b08076117d6950cd472cdd59a167470b5Igor Murashkin#include <stdio.h> 213774335b08076117d6950cd472cdd59a167470b5Igor Murashkin#include <stdlib.h> 223774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 233774335b08076117d6950cd472cdd59a167470b5Igor Murashkin#include <fstream> 243774335b08076117d6950cd472cdd59a167470b5Igor Murashkin#include <iostream> 253774335b08076117d6950cd472cdd59a167470b5Igor Murashkin#include <string> 263774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 273774335b08076117d6950cd472cdd59a167470b5Igor Murashkin#include "runtime.h" 283774335b08076117d6950cd472cdd59a167470b5Igor Murashkin#include "base/stringpiece.h" 293774335b08076117d6950cd472cdd59a167470b5Igor Murashkin#include "noop_compiler_callbacks.h" 303774335b08076117d6950cd472cdd59a167470b5Igor Murashkin#include "base/logging.h" 313774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 323774335b08076117d6950cd472cdd59a167470b5Igor Murashkin#if !defined(NDEBUG) 333774335b08076117d6950cd472cdd59a167470b5Igor Murashkin#define DBG_LOG LOG(INFO) 343774335b08076117d6950cd472cdd59a167470b5Igor Murashkin#else 353774335b08076117d6950cd472cdd59a167470b5Igor Murashkin#define DBG_LOG LOG(DEBUG) 363774335b08076117d6950cd472cdd59a167470b5Igor Murashkin#endif 373774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 383774335b08076117d6950cd472cdd59a167470b5Igor Murashkinnamespace art { 393774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 403774335b08076117d6950cd472cdd59a167470b5Igor Murashkin// TODO: Move to <runtime/utils.h> and remove all copies of this function. 413774335b08076117d6950cd472cdd59a167470b5Igor Murashkinstatic bool LocationToFilename(const std::string& location, InstructionSet isa, 423774335b08076117d6950cd472cdd59a167470b5Igor Murashkin std::string* filename) { 433774335b08076117d6950cd472cdd59a167470b5Igor Murashkin bool has_system = false; 443774335b08076117d6950cd472cdd59a167470b5Igor Murashkin bool has_cache = false; 453774335b08076117d6950cd472cdd59a167470b5Igor Murashkin // image_location = /system/framework/boot.art 463774335b08076117d6950cd472cdd59a167470b5Igor Murashkin // system_image_filename = /system/framework/<image_isa>/boot.art 473774335b08076117d6950cd472cdd59a167470b5Igor Murashkin std::string system_filename(GetSystemImageFilename(location.c_str(), isa)); 483774335b08076117d6950cd472cdd59a167470b5Igor Murashkin if (OS::FileExists(system_filename.c_str())) { 493774335b08076117d6950cd472cdd59a167470b5Igor Murashkin has_system = true; 503774335b08076117d6950cd472cdd59a167470b5Igor Murashkin } 513774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 523774335b08076117d6950cd472cdd59a167470b5Igor Murashkin bool have_android_data = false; 533774335b08076117d6950cd472cdd59a167470b5Igor Murashkin bool dalvik_cache_exists = false; 543774335b08076117d6950cd472cdd59a167470b5Igor Murashkin bool is_global_cache = false; 553774335b08076117d6950cd472cdd59a167470b5Igor Murashkin std::string dalvik_cache; 563774335b08076117d6950cd472cdd59a167470b5Igor Murashkin GetDalvikCache(GetInstructionSetString(isa), false, &dalvik_cache, 573774335b08076117d6950cd472cdd59a167470b5Igor Murashkin &have_android_data, &dalvik_cache_exists, &is_global_cache); 583774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 593774335b08076117d6950cd472cdd59a167470b5Igor Murashkin std::string cache_filename; 603774335b08076117d6950cd472cdd59a167470b5Igor Murashkin if (have_android_data && dalvik_cache_exists) { 613774335b08076117d6950cd472cdd59a167470b5Igor Murashkin // Always set output location even if it does not exist, 623774335b08076117d6950cd472cdd59a167470b5Igor Murashkin // so that the caller knows where to create the image. 633774335b08076117d6950cd472cdd59a167470b5Igor Murashkin // 643774335b08076117d6950cd472cdd59a167470b5Igor Murashkin // image_location = /system/framework/boot.art 653774335b08076117d6950cd472cdd59a167470b5Igor Murashkin // *image_filename = /data/dalvik-cache/<image_isa>/boot.art 663774335b08076117d6950cd472cdd59a167470b5Igor Murashkin std::string error_msg; 673774335b08076117d6950cd472cdd59a167470b5Igor Murashkin if (GetDalvikCacheFilename(location.c_str(), dalvik_cache.c_str(), 683774335b08076117d6950cd472cdd59a167470b5Igor Murashkin &cache_filename, &error_msg)) { 693774335b08076117d6950cd472cdd59a167470b5Igor Murashkin has_cache = true; 703774335b08076117d6950cd472cdd59a167470b5Igor Murashkin } 713774335b08076117d6950cd472cdd59a167470b5Igor Murashkin } 723774335b08076117d6950cd472cdd59a167470b5Igor Murashkin if (has_system) { 733774335b08076117d6950cd472cdd59a167470b5Igor Murashkin *filename = system_filename; 743774335b08076117d6950cd472cdd59a167470b5Igor Murashkin return true; 753774335b08076117d6950cd472cdd59a167470b5Igor Murashkin } else if (has_cache) { 763774335b08076117d6950cd472cdd59a167470b5Igor Murashkin *filename = cache_filename; 773774335b08076117d6950cd472cdd59a167470b5Igor Murashkin return true; 783774335b08076117d6950cd472cdd59a167470b5Igor Murashkin } else { 793774335b08076117d6950cd472cdd59a167470b5Igor Murashkin return false; 803774335b08076117d6950cd472cdd59a167470b5Igor Murashkin } 813774335b08076117d6950cd472cdd59a167470b5Igor Murashkin} 823774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 833774335b08076117d6950cd472cdd59a167470b5Igor Murashkinstatic Runtime* StartRuntime(const char* boot_image_location, 843774335b08076117d6950cd472cdd59a167470b5Igor Murashkin InstructionSet instruction_set) { 853774335b08076117d6950cd472cdd59a167470b5Igor Murashkin CHECK(boot_image_location != nullptr); 863774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 873774335b08076117d6950cd472cdd59a167470b5Igor Murashkin RuntimeOptions options; 883774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 893774335b08076117d6950cd472cdd59a167470b5Igor Murashkin // We are more like a compiler than a run-time. We don't want to execute code. 903774335b08076117d6950cd472cdd59a167470b5Igor Murashkin { 913774335b08076117d6950cd472cdd59a167470b5Igor Murashkin static NoopCompilerCallbacks callbacks; 923774335b08076117d6950cd472cdd59a167470b5Igor Murashkin options.push_back(std::make_pair("compilercallbacks", &callbacks)); 933774335b08076117d6950cd472cdd59a167470b5Igor Murashkin } 943774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 953774335b08076117d6950cd472cdd59a167470b5Igor Murashkin // Boot image location. 963774335b08076117d6950cd472cdd59a167470b5Igor Murashkin { 973774335b08076117d6950cd472cdd59a167470b5Igor Murashkin std::string boot_image_option; 983774335b08076117d6950cd472cdd59a167470b5Igor Murashkin boot_image_option += "-Ximage:"; 993774335b08076117d6950cd472cdd59a167470b5Igor Murashkin boot_image_option += boot_image_location; 1003774335b08076117d6950cd472cdd59a167470b5Igor Murashkin options.push_back(std::make_pair(boot_image_option.c_str(), nullptr)); 1013774335b08076117d6950cd472cdd59a167470b5Igor Murashkin } 1023774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 1033774335b08076117d6950cd472cdd59a167470b5Igor Murashkin // Instruction set. 1043774335b08076117d6950cd472cdd59a167470b5Igor Murashkin options.push_back( 1053774335b08076117d6950cd472cdd59a167470b5Igor Murashkin std::make_pair("imageinstructionset", 1063774335b08076117d6950cd472cdd59a167470b5Igor Murashkin reinterpret_cast<const void*>(GetInstructionSetString(instruction_set)))); 1073774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 1083774335b08076117d6950cd472cdd59a167470b5Igor Murashkin if (!Runtime::Create(options, false)) { 1093774335b08076117d6950cd472cdd59a167470b5Igor Murashkin fprintf(stderr, "Failed to create runtime\n"); 1103774335b08076117d6950cd472cdd59a167470b5Igor Murashkin return nullptr; 1113774335b08076117d6950cd472cdd59a167470b5Igor Murashkin } 1123774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 1133774335b08076117d6950cd472cdd59a167470b5Igor Murashkin // Runtime::Create acquired the mutator_lock_ that is normally given away when we Runtime::Start, 1143774335b08076117d6950cd472cdd59a167470b5Igor Murashkin // give it away now and then switch to a more manageable ScopedObjectAccess. 1153774335b08076117d6950cd472cdd59a167470b5Igor Murashkin Thread::Current()->TransitionFromRunnableToSuspended(kNative); 1163774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 1173774335b08076117d6950cd472cdd59a167470b5Igor Murashkin return Runtime::Current(); 1183774335b08076117d6950cd472cdd59a167470b5Igor Murashkin} 1193774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 1203774335b08076117d6950cd472cdd59a167470b5Igor Murashkinstruct CmdlineArgs { 1213774335b08076117d6950cd472cdd59a167470b5Igor Murashkin enum ParseStatus { 1223774335b08076117d6950cd472cdd59a167470b5Igor Murashkin kParseOk, // Parse successful. Do not set the error message. 1233774335b08076117d6950cd472cdd59a167470b5Igor Murashkin kParseUnknownArgument, // Unknown argument. Do not set the error message. 1243774335b08076117d6950cd472cdd59a167470b5Igor Murashkin kParseError, // Parse ok, but failed elsewhere. Print the set error message. 1253774335b08076117d6950cd472cdd59a167470b5Igor Murashkin }; 1263774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 1273774335b08076117d6950cd472cdd59a167470b5Igor Murashkin bool Parse(int argc, char** argv) { 1283774335b08076117d6950cd472cdd59a167470b5Igor Murashkin // Skip over argv[0]. 1293774335b08076117d6950cd472cdd59a167470b5Igor Murashkin argv++; 1303774335b08076117d6950cd472cdd59a167470b5Igor Murashkin argc--; 1313774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 1323774335b08076117d6950cd472cdd59a167470b5Igor Murashkin if (argc == 0) { 1333774335b08076117d6950cd472cdd59a167470b5Igor Murashkin fprintf(stderr, "No arguments specified\n"); 1343774335b08076117d6950cd472cdd59a167470b5Igor Murashkin PrintUsage(); 1353774335b08076117d6950cd472cdd59a167470b5Igor Murashkin return false; 1363774335b08076117d6950cd472cdd59a167470b5Igor Murashkin } 1373774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 1383774335b08076117d6950cd472cdd59a167470b5Igor Murashkin std::string error_msg; 1393774335b08076117d6950cd472cdd59a167470b5Igor Murashkin for (int i = 0; i < argc; i++) { 1403774335b08076117d6950cd472cdd59a167470b5Igor Murashkin const StringPiece option(argv[i]); 1413774335b08076117d6950cd472cdd59a167470b5Igor Murashkin if (option.starts_with("--boot-image=")) { 1423774335b08076117d6950cd472cdd59a167470b5Igor Murashkin boot_image_location_ = option.substr(strlen("--boot-image=")).data(); 1433774335b08076117d6950cd472cdd59a167470b5Igor Murashkin } else if (option.starts_with("--instruction-set=")) { 1443774335b08076117d6950cd472cdd59a167470b5Igor Murashkin StringPiece instruction_set_str = option.substr(strlen("--instruction-set=")).data(); 1453774335b08076117d6950cd472cdd59a167470b5Igor Murashkin instruction_set_ = GetInstructionSetFromString(instruction_set_str.data()); 1463774335b08076117d6950cd472cdd59a167470b5Igor Murashkin if (instruction_set_ == kNone) { 1473774335b08076117d6950cd472cdd59a167470b5Igor Murashkin fprintf(stderr, "Unsupported instruction set %s\n", instruction_set_str.data()); 1483774335b08076117d6950cd472cdd59a167470b5Igor Murashkin PrintUsage(); 1493774335b08076117d6950cd472cdd59a167470b5Igor Murashkin return false; 1503774335b08076117d6950cd472cdd59a167470b5Igor Murashkin } 1513774335b08076117d6950cd472cdd59a167470b5Igor Murashkin } else if (option.starts_with("--output=")) { 1523774335b08076117d6950cd472cdd59a167470b5Igor Murashkin output_name_ = option.substr(strlen("--output=")).ToString(); 1533774335b08076117d6950cd472cdd59a167470b5Igor Murashkin const char* filename = output_name_.c_str(); 1543774335b08076117d6950cd472cdd59a167470b5Igor Murashkin out_.reset(new std::ofstream(filename)); 1553774335b08076117d6950cd472cdd59a167470b5Igor Murashkin if (!out_->good()) { 1563774335b08076117d6950cd472cdd59a167470b5Igor Murashkin fprintf(stderr, "Failed to open output filename %s\n", filename); 1573774335b08076117d6950cd472cdd59a167470b5Igor Murashkin PrintUsage(); 1583774335b08076117d6950cd472cdd59a167470b5Igor Murashkin return false; 1593774335b08076117d6950cd472cdd59a167470b5Igor Murashkin } 1603774335b08076117d6950cd472cdd59a167470b5Igor Murashkin os_ = out_.get(); 1613774335b08076117d6950cd472cdd59a167470b5Igor Murashkin } else { 1623774335b08076117d6950cd472cdd59a167470b5Igor Murashkin ParseStatus parse_status = ParseCustom(option, &error_msg); 1633774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 1643774335b08076117d6950cd472cdd59a167470b5Igor Murashkin if (parse_status == kParseUnknownArgument) { 1653774335b08076117d6950cd472cdd59a167470b5Igor Murashkin fprintf(stderr, "Unknown argument %s\n", option.data()); 1663774335b08076117d6950cd472cdd59a167470b5Igor Murashkin } 1673774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 1683774335b08076117d6950cd472cdd59a167470b5Igor Murashkin if (parse_status != kParseOk) { 1693774335b08076117d6950cd472cdd59a167470b5Igor Murashkin fprintf(stderr, "%s\n", error_msg.c_str()); 1703774335b08076117d6950cd472cdd59a167470b5Igor Murashkin PrintUsage(); 1713774335b08076117d6950cd472cdd59a167470b5Igor Murashkin return false; 1723774335b08076117d6950cd472cdd59a167470b5Igor Murashkin } 1733774335b08076117d6950cd472cdd59a167470b5Igor Murashkin } 1743774335b08076117d6950cd472cdd59a167470b5Igor Murashkin } 1753774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 1763774335b08076117d6950cd472cdd59a167470b5Igor Murashkin DBG_LOG << "will call parse checks"; 1773774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 1783774335b08076117d6950cd472cdd59a167470b5Igor Murashkin { 1793774335b08076117d6950cd472cdd59a167470b5Igor Murashkin ParseStatus checks_status = ParseChecks(&error_msg); 1803774335b08076117d6950cd472cdd59a167470b5Igor Murashkin if (checks_status != kParseOk) { 1813774335b08076117d6950cd472cdd59a167470b5Igor Murashkin fprintf(stderr, "%s\n", error_msg.c_str()); 1823774335b08076117d6950cd472cdd59a167470b5Igor Murashkin PrintUsage(); 1833774335b08076117d6950cd472cdd59a167470b5Igor Murashkin return false; 1843774335b08076117d6950cd472cdd59a167470b5Igor Murashkin } 1853774335b08076117d6950cd472cdd59a167470b5Igor Murashkin } 1863774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 1873774335b08076117d6950cd472cdd59a167470b5Igor Murashkin return true; 1883774335b08076117d6950cd472cdd59a167470b5Igor Murashkin } 1893774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 1903774335b08076117d6950cd472cdd59a167470b5Igor Murashkin virtual std::string GetUsage() const { 1913774335b08076117d6950cd472cdd59a167470b5Igor Murashkin std::string usage; 1923774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 1933774335b08076117d6950cd472cdd59a167470b5Igor Murashkin usage += // Required. 1943774335b08076117d6950cd472cdd59a167470b5Igor Murashkin " --boot-image=<file.art>: provide the image location for the boot class path.\n" 1953774335b08076117d6950cd472cdd59a167470b5Igor Murashkin " Do not include the arch as part of the name, it is added automatically.\n" 1963774335b08076117d6950cd472cdd59a167470b5Igor Murashkin " Example: --boot-image=/system/framework/boot.art\n" 1973774335b08076117d6950cd472cdd59a167470b5Igor Murashkin "\n"; 1983774335b08076117d6950cd472cdd59a167470b5Igor Murashkin usage += StringPrintf( // Optional. 19957b34294758e9c00993913ebe43c7ee4698a5cc6Andreas Gampe " --instruction-set=(arm|arm64|mips|mips64|x86|x86_64): for locating the image\n" 2003774335b08076117d6950cd472cdd59a167470b5Igor Murashkin " file based on the image location set.\n" 2013774335b08076117d6950cd472cdd59a167470b5Igor Murashkin " Example: --instruction-set=x86\n" 2023774335b08076117d6950cd472cdd59a167470b5Igor Murashkin " Default: %s\n" 2033774335b08076117d6950cd472cdd59a167470b5Igor Murashkin "\n", 2043774335b08076117d6950cd472cdd59a167470b5Igor Murashkin GetInstructionSetString(kRuntimeISA)); 2053774335b08076117d6950cd472cdd59a167470b5Igor Murashkin usage += // Optional. 2063774335b08076117d6950cd472cdd59a167470b5Igor Murashkin " --output=<file> may be used to send the output to a file.\n" 2073774335b08076117d6950cd472cdd59a167470b5Igor Murashkin " Example: --output=/tmp/oatdump.txt\n" 2083774335b08076117d6950cd472cdd59a167470b5Igor Murashkin "\n"; 2093774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 2103774335b08076117d6950cd472cdd59a167470b5Igor Murashkin return usage; 2113774335b08076117d6950cd472cdd59a167470b5Igor Murashkin } 2123774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 2133774335b08076117d6950cd472cdd59a167470b5Igor Murashkin // Specified by --boot-image. 2143774335b08076117d6950cd472cdd59a167470b5Igor Murashkin const char* boot_image_location_ = nullptr; 2153774335b08076117d6950cd472cdd59a167470b5Igor Murashkin // Specified by --instruction-set. 2163774335b08076117d6950cd472cdd59a167470b5Igor Murashkin InstructionSet instruction_set_ = kRuntimeISA; 2173774335b08076117d6950cd472cdd59a167470b5Igor Murashkin // Specified by --output. 2183774335b08076117d6950cd472cdd59a167470b5Igor Murashkin std::ostream* os_ = &std::cout; 2193774335b08076117d6950cd472cdd59a167470b5Igor Murashkin std::unique_ptr<std::ofstream> out_; // If something besides cout is used 2203774335b08076117d6950cd472cdd59a167470b5Igor Murashkin std::string output_name_; 2213774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 2223774335b08076117d6950cd472cdd59a167470b5Igor Murashkin virtual ~CmdlineArgs() {} 2233774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 224c24f3990db5845691016b935df3d9382b6762f0fAndreas Gampe bool ParseCheckBootImage(std::string* error_msg) { 2253774335b08076117d6950cd472cdd59a167470b5Igor Murashkin if (boot_image_location_ == nullptr) { 2263774335b08076117d6950cd472cdd59a167470b5Igor Murashkin *error_msg = "--boot-image must be specified"; 227c24f3990db5845691016b935df3d9382b6762f0fAndreas Gampe return false; 2283774335b08076117d6950cd472cdd59a167470b5Igor Murashkin } 2293774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 2303774335b08076117d6950cd472cdd59a167470b5Igor Murashkin DBG_LOG << "boot image location: " << boot_image_location_; 2313774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 2323774335b08076117d6950cd472cdd59a167470b5Igor Murashkin // Checks for --boot-image location. 2333774335b08076117d6950cd472cdd59a167470b5Igor Murashkin { 2343774335b08076117d6950cd472cdd59a167470b5Igor Murashkin std::string boot_image_location = boot_image_location_; 2353774335b08076117d6950cd472cdd59a167470b5Igor Murashkin size_t file_name_idx = boot_image_location.rfind("/"); 2363774335b08076117d6950cd472cdd59a167470b5Igor Murashkin if (file_name_idx == std::string::npos) { // Prevent a InsertIsaDirectory check failure. 2373774335b08076117d6950cd472cdd59a167470b5Igor Murashkin *error_msg = "Boot image location must have a / in it"; 238c24f3990db5845691016b935df3d9382b6762f0fAndreas Gampe return false; 2393774335b08076117d6950cd472cdd59a167470b5Igor Murashkin } 2403774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 2413774335b08076117d6950cd472cdd59a167470b5Igor Murashkin // Don't let image locations with the 'arch' in it through, since it's not a location. 2423774335b08076117d6950cd472cdd59a167470b5Igor Murashkin // This prevents a common error "Could not create an image space..." when initing the Runtime. 2433774335b08076117d6950cd472cdd59a167470b5Igor Murashkin if (file_name_idx != std::string::npos) { 2443774335b08076117d6950cd472cdd59a167470b5Igor Murashkin std::string no_file_name = boot_image_location.substr(0, file_name_idx); 2453774335b08076117d6950cd472cdd59a167470b5Igor Murashkin size_t ancestor_dirs_idx = no_file_name.rfind("/"); 2463774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 2473774335b08076117d6950cd472cdd59a167470b5Igor Murashkin std::string parent_dir_name; 2483774335b08076117d6950cd472cdd59a167470b5Igor Murashkin if (ancestor_dirs_idx != std::string::npos) { 2493774335b08076117d6950cd472cdd59a167470b5Igor Murashkin parent_dir_name = no_file_name.substr(ancestor_dirs_idx + 1); 2503774335b08076117d6950cd472cdd59a167470b5Igor Murashkin } else { 2513774335b08076117d6950cd472cdd59a167470b5Igor Murashkin parent_dir_name = no_file_name; 2523774335b08076117d6950cd472cdd59a167470b5Igor Murashkin } 2533774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 2543774335b08076117d6950cd472cdd59a167470b5Igor Murashkin DBG_LOG << "boot_image_location parent_dir_name was " << parent_dir_name; 2553774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 2563774335b08076117d6950cd472cdd59a167470b5Igor Murashkin if (GetInstructionSetFromString(parent_dir_name.c_str()) != kNone) { 2573774335b08076117d6950cd472cdd59a167470b5Igor Murashkin *error_msg = "Do not specify the architecture as part of the boot image location"; 258c24f3990db5845691016b935df3d9382b6762f0fAndreas Gampe return false; 2593774335b08076117d6950cd472cdd59a167470b5Igor Murashkin } 2603774335b08076117d6950cd472cdd59a167470b5Igor Murashkin } 2613774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 2623774335b08076117d6950cd472cdd59a167470b5Igor Murashkin // Check that the boot image location points to a valid file name. 2633774335b08076117d6950cd472cdd59a167470b5Igor Murashkin std::string file_name; 2643774335b08076117d6950cd472cdd59a167470b5Igor Murashkin if (!LocationToFilename(boot_image_location, instruction_set_, &file_name)) { 2653774335b08076117d6950cd472cdd59a167470b5Igor Murashkin *error_msg = StringPrintf("No corresponding file for location '%s' exists", 2663774335b08076117d6950cd472cdd59a167470b5Igor Murashkin file_name.c_str()); 267c24f3990db5845691016b935df3d9382b6762f0fAndreas Gampe return false; 2683774335b08076117d6950cd472cdd59a167470b5Igor Murashkin } 2693774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 2703774335b08076117d6950cd472cdd59a167470b5Igor Murashkin DBG_LOG << "boot_image_filename does exist: " << file_name; 2713774335b08076117d6950cd472cdd59a167470b5Igor Murashkin } 2723774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 273c24f3990db5845691016b935df3d9382b6762f0fAndreas Gampe return true; 2743774335b08076117d6950cd472cdd59a167470b5Igor Murashkin } 2753774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 2763774335b08076117d6950cd472cdd59a167470b5Igor Murashkin void PrintUsage() { 2773774335b08076117d6950cd472cdd59a167470b5Igor Murashkin fprintf(stderr, "%s", GetUsage().c_str()); 2783774335b08076117d6950cd472cdd59a167470b5Igor Murashkin } 279c24f3990db5845691016b935df3d9382b6762f0fAndreas Gampe 280c24f3990db5845691016b935df3d9382b6762f0fAndreas Gampe protected: 281c24f3990db5845691016b935df3d9382b6762f0fAndreas Gampe virtual ParseStatus ParseCustom(const StringPiece& option ATTRIBUTE_UNUSED, 282c24f3990db5845691016b935df3d9382b6762f0fAndreas Gampe std::string* error_msg ATTRIBUTE_UNUSED) { 283c24f3990db5845691016b935df3d9382b6762f0fAndreas Gampe return kParseUnknownArgument; 284c24f3990db5845691016b935df3d9382b6762f0fAndreas Gampe } 285c24f3990db5845691016b935df3d9382b6762f0fAndreas Gampe 286c24f3990db5845691016b935df3d9382b6762f0fAndreas Gampe virtual ParseStatus ParseChecks(std::string* error_msg ATTRIBUTE_UNUSED) { 287c24f3990db5845691016b935df3d9382b6762f0fAndreas Gampe return kParseOk; 288c24f3990db5845691016b935df3d9382b6762f0fAndreas Gampe } 2893774335b08076117d6950cd472cdd59a167470b5Igor Murashkin}; 2903774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 2913774335b08076117d6950cd472cdd59a167470b5Igor Murashkintemplate <typename Args = CmdlineArgs> 2923774335b08076117d6950cd472cdd59a167470b5Igor Murashkinstruct CmdlineMain { 2933774335b08076117d6950cd472cdd59a167470b5Igor Murashkin int Main(int argc, char** argv) { 2943774335b08076117d6950cd472cdd59a167470b5Igor Murashkin InitLogging(argv); 2953774335b08076117d6950cd472cdd59a167470b5Igor Murashkin std::unique_ptr<Args> args = std::unique_ptr<Args>(CreateArguments()); 2963774335b08076117d6950cd472cdd59a167470b5Igor Murashkin args_ = args.get(); 2973774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 2983774335b08076117d6950cd472cdd59a167470b5Igor Murashkin DBG_LOG << "Try to parse"; 2993774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 3003774335b08076117d6950cd472cdd59a167470b5Igor Murashkin if (args_ == nullptr || !args_->Parse(argc, argv)) { 3013774335b08076117d6950cd472cdd59a167470b5Igor Murashkin return EXIT_FAILURE; 3023774335b08076117d6950cd472cdd59a167470b5Igor Murashkin } 3033774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 3043774335b08076117d6950cd472cdd59a167470b5Igor Murashkin bool needs_runtime = NeedsRuntime(); 305c24f3990db5845691016b935df3d9382b6762f0fAndreas Gampe std::unique_ptr<Runtime> runtime; 306c24f3990db5845691016b935df3d9382b6762f0fAndreas Gampe 3073774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 3083774335b08076117d6950cd472cdd59a167470b5Igor Murashkin if (needs_runtime) { 309c24f3990db5845691016b935df3d9382b6762f0fAndreas Gampe std::string error_msg; 310c24f3990db5845691016b935df3d9382b6762f0fAndreas Gampe if (!args_->ParseCheckBootImage(&error_msg)) { 311c24f3990db5845691016b935df3d9382b6762f0fAndreas Gampe fprintf(stderr, "%s\n", error_msg.c_str()); 312c24f3990db5845691016b935df3d9382b6762f0fAndreas Gampe args_->PrintUsage(); 313c24f3990db5845691016b935df3d9382b6762f0fAndreas Gampe return EXIT_FAILURE; 314c24f3990db5845691016b935df3d9382b6762f0fAndreas Gampe } 315c24f3990db5845691016b935df3d9382b6762f0fAndreas Gampe runtime.reset(CreateRuntime(args.get())); 316c24f3990db5845691016b935df3d9382b6762f0fAndreas Gampe if (runtime == nullptr) { 317c24f3990db5845691016b935df3d9382b6762f0fAndreas Gampe return EXIT_FAILURE; 318c24f3990db5845691016b935df3d9382b6762f0fAndreas Gampe } 3193774335b08076117d6950cd472cdd59a167470b5Igor Murashkin if (!ExecuteWithRuntime(runtime.get())) { 3203774335b08076117d6950cd472cdd59a167470b5Igor Murashkin return EXIT_FAILURE; 3213774335b08076117d6950cd472cdd59a167470b5Igor Murashkin } 3223774335b08076117d6950cd472cdd59a167470b5Igor Murashkin } else { 3233774335b08076117d6950cd472cdd59a167470b5Igor Murashkin if (!ExecuteWithoutRuntime()) { 3243774335b08076117d6950cd472cdd59a167470b5Igor Murashkin return EXIT_FAILURE; 3253774335b08076117d6950cd472cdd59a167470b5Igor Murashkin } 3263774335b08076117d6950cd472cdd59a167470b5Igor Murashkin } 3273774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 3283774335b08076117d6950cd472cdd59a167470b5Igor Murashkin if (!ExecuteCommon()) { 3293774335b08076117d6950cd472cdd59a167470b5Igor Murashkin return EXIT_FAILURE; 3303774335b08076117d6950cd472cdd59a167470b5Igor Murashkin } 3313774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 3323774335b08076117d6950cd472cdd59a167470b5Igor Murashkin return EXIT_SUCCESS; 3333774335b08076117d6950cd472cdd59a167470b5Igor Murashkin } 3343774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 3353774335b08076117d6950cd472cdd59a167470b5Igor Murashkin // Override this function to create your own arguments. 3363774335b08076117d6950cd472cdd59a167470b5Igor Murashkin // Usually will want to return a subtype of CmdlineArgs. 3373774335b08076117d6950cd472cdd59a167470b5Igor Murashkin virtual Args* CreateArguments() { 3383774335b08076117d6950cd472cdd59a167470b5Igor Murashkin return new Args(); 3393774335b08076117d6950cd472cdd59a167470b5Igor Murashkin } 3403774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 3413774335b08076117d6950cd472cdd59a167470b5Igor Murashkin // Override this function to do something else with the runtime. 3423774335b08076117d6950cd472cdd59a167470b5Igor Murashkin virtual bool ExecuteWithRuntime(Runtime* runtime) { 3433774335b08076117d6950cd472cdd59a167470b5Igor Murashkin CHECK(runtime != nullptr); 3443774335b08076117d6950cd472cdd59a167470b5Igor Murashkin // Do nothing 3453774335b08076117d6950cd472cdd59a167470b5Igor Murashkin return true; 3463774335b08076117d6950cd472cdd59a167470b5Igor Murashkin } 3473774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 3483774335b08076117d6950cd472cdd59a167470b5Igor Murashkin // Does the code execution need a runtime? Sometimes it doesn't. 3493774335b08076117d6950cd472cdd59a167470b5Igor Murashkin virtual bool NeedsRuntime() { 3503774335b08076117d6950cd472cdd59a167470b5Igor Murashkin return true; 3513774335b08076117d6950cd472cdd59a167470b5Igor Murashkin } 3523774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 3533774335b08076117d6950cd472cdd59a167470b5Igor Murashkin // Do execution without having created a runtime. 3543774335b08076117d6950cd472cdd59a167470b5Igor Murashkin virtual bool ExecuteWithoutRuntime() { 3553774335b08076117d6950cd472cdd59a167470b5Igor Murashkin return true; 3563774335b08076117d6950cd472cdd59a167470b5Igor Murashkin } 3573774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 3583774335b08076117d6950cd472cdd59a167470b5Igor Murashkin // Continue execution after ExecuteWith[out]Runtime 3593774335b08076117d6950cd472cdd59a167470b5Igor Murashkin virtual bool ExecuteCommon() { 3603774335b08076117d6950cd472cdd59a167470b5Igor Murashkin return true; 3613774335b08076117d6950cd472cdd59a167470b5Igor Murashkin } 3623774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 3633774335b08076117d6950cd472cdd59a167470b5Igor Murashkin virtual ~CmdlineMain() {} 3643774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 3653774335b08076117d6950cd472cdd59a167470b5Igor Murashkin protected: 3663774335b08076117d6950cd472cdd59a167470b5Igor Murashkin Args* args_ = nullptr; 3673774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 3683774335b08076117d6950cd472cdd59a167470b5Igor Murashkin private: 369c24f3990db5845691016b935df3d9382b6762f0fAndreas Gampe Runtime* CreateRuntime(CmdlineArgs* args) { 3703774335b08076117d6950cd472cdd59a167470b5Igor Murashkin CHECK(args != nullptr); 3713774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 372c24f3990db5845691016b935df3d9382b6762f0fAndreas Gampe return StartRuntime(args->boot_image_location_, args->instruction_set_); 3733774335b08076117d6950cd472cdd59a167470b5Igor Murashkin } 3743774335b08076117d6950cd472cdd59a167470b5Igor Murashkin}; 3753774335b08076117d6950cd472cdd59a167470b5Igor Murashkin} // namespace art 3763774335b08076117d6950cd472cdd59a167470b5Igor Murashkin 3773774335b08076117d6950cd472cdd59a167470b5Igor Murashkin#endif // ART_CMDLINE_CMDLINE_H_ 378