1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2011 The Android Open Source Project 3*795d594fSAndroid Build Coastguard Worker * 4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*795d594fSAndroid Build Coastguard Worker * 8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*795d594fSAndroid Build Coastguard Worker * 10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*795d594fSAndroid Build Coastguard Worker * limitations under the License. 15*795d594fSAndroid Build Coastguard Worker */ 16*795d594fSAndroid Build Coastguard Worker 17*795d594fSAndroid Build Coastguard Worker #ifndef ART_RUNTIME_GC_SPACE_IMAGE_SPACE_H_ 18*795d594fSAndroid Build Coastguard Worker #define ART_RUNTIME_GC_SPACE_IMAGE_SPACE_H_ 19*795d594fSAndroid Build Coastguard Worker 20*795d594fSAndroid Build Coastguard Worker #include "android-base/unique_fd.h" 21*795d594fSAndroid Build Coastguard Worker #include "base/array_ref.h" 22*795d594fSAndroid Build Coastguard Worker #include "gc/accounting/space_bitmap.h" 23*795d594fSAndroid Build Coastguard Worker #include "oat/image.h" 24*795d594fSAndroid Build Coastguard Worker #include "runtime.h" 25*795d594fSAndroid Build Coastguard Worker #include "space.h" 26*795d594fSAndroid Build Coastguard Worker 27*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN { 28*795d594fSAndroid Build Coastguard Worker 29*795d594fSAndroid Build Coastguard Worker class DexFile; 30*795d594fSAndroid Build Coastguard Worker enum class InstructionSet; 31*795d594fSAndroid Build Coastguard Worker class OatFile; 32*795d594fSAndroid Build Coastguard Worker class OatHeader; 33*795d594fSAndroid Build Coastguard Worker 34*795d594fSAndroid Build Coastguard Worker namespace gc { 35*795d594fSAndroid Build Coastguard Worker namespace space { 36*795d594fSAndroid Build Coastguard Worker 37*795d594fSAndroid Build Coastguard Worker // An image space is a space backed with a memory mapped image. 38*795d594fSAndroid Build Coastguard Worker class ImageSpace : public MemMapSpace { 39*795d594fSAndroid Build Coastguard Worker public: GetType()40*795d594fSAndroid Build Coastguard Worker SpaceType GetType() const override { 41*795d594fSAndroid Build Coastguard Worker return kSpaceTypeImageSpace; 42*795d594fSAndroid Build Coastguard Worker } 43*795d594fSAndroid Build Coastguard Worker 44*795d594fSAndroid Build Coastguard Worker // The separator for boot image location components. 45*795d594fSAndroid Build Coastguard Worker static constexpr char kComponentSeparator = ':'; 46*795d594fSAndroid Build Coastguard Worker // The separator for profile filename. 47*795d594fSAndroid Build Coastguard Worker static constexpr char kProfileSeparator = '!'; 48*795d594fSAndroid Build Coastguard Worker 49*795d594fSAndroid Build Coastguard Worker // Load boot image spaces for specified boot class path, image location, instruction set, etc. 50*795d594fSAndroid Build Coastguard Worker // 51*795d594fSAndroid Build Coastguard Worker // On successful return, the loaded spaces are added to boot_image_spaces (which must be 52*795d594fSAndroid Build Coastguard Worker // empty on entry) and `extra_reservation` is set to the requested reservation located 53*795d594fSAndroid Build Coastguard Worker // after the end of the last loaded oat file. 54*795d594fSAndroid Build Coastguard Worker // 55*795d594fSAndroid Build Coastguard Worker // IMAGE LOCATION 56*795d594fSAndroid Build Coastguard Worker // 57*795d594fSAndroid Build Coastguard Worker // The "image location" is a colon-separated list that specifies one or more 58*795d594fSAndroid Build Coastguard Worker // components by name and may also specify search paths for extensions 59*795d594fSAndroid Build Coastguard Worker // corresponding to the remaining boot class path (BCP) extensions. 60*795d594fSAndroid Build Coastguard Worker // 61*795d594fSAndroid Build Coastguard Worker // The primary boot image can be specified as one of 62*795d594fSAndroid Build Coastguard Worker // <path>/<base-name> 63*795d594fSAndroid Build Coastguard Worker // <base-name> 64*795d594fSAndroid Build Coastguard Worker // and the path of the first BCP component is used for the second form. 65*795d594fSAndroid Build Coastguard Worker // The specification may be followed by one or more profile specifications, where each profile 66*795d594fSAndroid Build Coastguard Worker // specification is one of 67*795d594fSAndroid Build Coastguard Worker // !<profile-path>/<profile-name> 68*795d594fSAndroid Build Coastguard Worker // !<profile-name> 69*795d594fSAndroid Build Coastguard Worker // and the profiles will be used to compile the primary boot image when loading the boot image if 70*795d594fSAndroid Build Coastguard Worker // the on-disk version is not acceptable (either not present or fails validation, presumably 71*795d594fSAndroid Build Coastguard Worker // because it's out of date). The primary boot image is compiled with no dependency. 72*795d594fSAndroid Build Coastguard Worker // 73*795d594fSAndroid Build Coastguard Worker // Named extension specifications must correspond to an expansion of the 74*795d594fSAndroid Build Coastguard Worker // <base-name> with a BCP component (for example boot.art with the BCP 75*795d594fSAndroid Build Coastguard Worker // component name <jar-path>/framework.jar expands to boot-framework.art). 76*795d594fSAndroid Build Coastguard Worker // They can be similarly specified as one of 77*795d594fSAndroid Build Coastguard Worker // <ext-path>/<ext-name> 78*795d594fSAndroid Build Coastguard Worker // <ext-name> 79*795d594fSAndroid Build Coastguard Worker // and must be listed in the order of their corresponding BCP components. 80*795d594fSAndroid Build Coastguard Worker // Similarly, the specification may be followed by one or more profile specifications, where each 81*795d594fSAndroid Build Coastguard Worker // profile specification is one of 82*795d594fSAndroid Build Coastguard Worker // !<profile-path>/<profile-name> 83*795d594fSAndroid Build Coastguard Worker // !<profile-name> 84*795d594fSAndroid Build Coastguard Worker // and the profiles will be used to compile the extension when loading the boot image if the 85*795d594fSAndroid Build Coastguard Worker // on-disk version is not acceptable (either not present or fails validation, presumably because 86*795d594fSAndroid Build Coastguard Worker // it's out of date). The primary boot image (i.e., the first element in "image location") is the 87*795d594fSAndroid Build Coastguard Worker // dependency that each extension is compiled against. 88*795d594fSAndroid Build Coastguard Worker // 89*795d594fSAndroid Build Coastguard Worker // Search paths for remaining extensions can be specified after named 90*795d594fSAndroid Build Coastguard Worker // components as one of 91*795d594fSAndroid Build Coastguard Worker // <search-path>/* 92*795d594fSAndroid Build Coastguard Worker // * 93*795d594fSAndroid Build Coastguard Worker // where the second form means that the path of a particular BCP component 94*795d594fSAndroid Build Coastguard Worker // should be used to search for that component's boot image extension. 95*795d594fSAndroid Build Coastguard Worker // 96*795d594fSAndroid Build Coastguard Worker // The actual filename shall be derived from the specified locations using 97*795d594fSAndroid Build Coastguard Worker // `GetSystemImageFilename()`. 98*795d594fSAndroid Build Coastguard Worker // 99*795d594fSAndroid Build Coastguard Worker // Example image locations: 100*795d594fSAndroid Build Coastguard Worker // /system/framework/boot.art 101*795d594fSAndroid Build Coastguard Worker // - only primary boot image with full path. 102*795d594fSAndroid Build Coastguard Worker // /data/misc/apexdata/com.android.art/dalvik-cache/boot.art!/apex/com.android.art/etc/boot-image.prof!/system/etc/boot-image.prof 103*795d594fSAndroid Build Coastguard Worker // - only primary boot image with full path; if the primary boot image is not found or 104*795d594fSAndroid Build Coastguard Worker // broken, compile it in memory using two specified profile files at the exact paths. 105*795d594fSAndroid Build Coastguard Worker // boot.art:boot-framework.art 106*795d594fSAndroid Build Coastguard Worker // - primary and one extension, use BCP component paths. 107*795d594fSAndroid Build Coastguard Worker // /apex/com.android.art/boot.art:* 108*795d594fSAndroid Build Coastguard Worker // - primary with exact location, search for the rest based on BCP 109*795d594fSAndroid Build Coastguard Worker // component paths. 110*795d594fSAndroid Build Coastguard Worker // boot.art:/system/framework/* 111*795d594fSAndroid Build Coastguard Worker // - primary based on BCP component path, search for extensions in 112*795d594fSAndroid Build Coastguard Worker // /system/framework. 113*795d594fSAndroid Build Coastguard Worker // /apex/com.android.art/boot.art:/system/framework/*:* 114*795d594fSAndroid Build Coastguard Worker // - primary with exact location, search for extensions first in 115*795d594fSAndroid Build Coastguard Worker // /system/framework, then in the corresponding BCP component path. 116*795d594fSAndroid Build Coastguard Worker // /apex/com.android.art/boot.art:*:/system/framework/* 117*795d594fSAndroid Build Coastguard Worker // - primary with exact location, search for extensions first in the 118*795d594fSAndroid Build Coastguard Worker // corresponding BCP component path and then in /system/framework. 119*795d594fSAndroid Build Coastguard Worker // /apex/com.android.art/boot.art:*:boot-framework.jar 120*795d594fSAndroid Build Coastguard Worker // - invalid, named components may not follow search paths. 121*795d594fSAndroid Build Coastguard Worker // boot.art:boot-framework.jar!/system/framework/framework.prof 122*795d594fSAndroid Build Coastguard Worker // - primary and one extension, use BCP component paths; if extension 123*795d594fSAndroid Build Coastguard Worker // is not found or broken compile it in memory using the specified 124*795d594fSAndroid Build Coastguard Worker // profile file from the exact path. 125*795d594fSAndroid Build Coastguard Worker // boot.art:boot-framework.jar:conscrypt.jar!conscrypt.prof 126*795d594fSAndroid Build Coastguard Worker // - primary and two extensions, use BCP component paths; only the 127*795d594fSAndroid Build Coastguard Worker // second extension has a profile file and can be compiled in memory 128*795d594fSAndroid Build Coastguard Worker // when it is not found or broken, using the specified profile file 129*795d594fSAndroid Build Coastguard Worker // in the BCP component path and it is compiled against the primary 130*795d594fSAndroid Build Coastguard Worker // and first extension and only if the first extension is OK. 131*795d594fSAndroid Build Coastguard Worker // boot.art:boot-framework.jar!framework.prof:conscrypt.jar!conscrypt.prof 132*795d594fSAndroid Build Coastguard Worker // - primary and two extensions, use BCP component paths; if any 133*795d594fSAndroid Build Coastguard Worker // extension is not found or broken compile it in memory using 134*795d594fSAndroid Build Coastguard Worker // the specified profile file in the BCP component path, each 135*795d594fSAndroid Build Coastguard Worker // extension is compiled only against the primary boot image. 136*795d594fSAndroid Build Coastguard Worker static bool LoadBootImage(const std::vector<std::string>& boot_class_path, 137*795d594fSAndroid Build Coastguard Worker const std::vector<std::string>& boot_class_path_locations, 138*795d594fSAndroid Build Coastguard Worker ArrayRef<File> boot_class_path_files, 139*795d594fSAndroid Build Coastguard Worker ArrayRef<File> boot_class_path_image_files, 140*795d594fSAndroid Build Coastguard Worker ArrayRef<File> boot_class_path_vdex_files, 141*795d594fSAndroid Build Coastguard Worker ArrayRef<File> boot_class_path_oat_files, 142*795d594fSAndroid Build Coastguard Worker const std::vector<std::string>& image_locations, 143*795d594fSAndroid Build Coastguard Worker const InstructionSet image_isa, 144*795d594fSAndroid Build Coastguard Worker bool relocate, 145*795d594fSAndroid Build Coastguard Worker bool executable, 146*795d594fSAndroid Build Coastguard Worker size_t extra_reservation_size, 147*795d594fSAndroid Build Coastguard Worker bool allow_in_memory_compilation, 148*795d594fSAndroid Build Coastguard Worker const std::string& apex_versions, 149*795d594fSAndroid Build Coastguard Worker /*out*/ std::vector<std::unique_ptr<ImageSpace>>* boot_image_spaces, 150*795d594fSAndroid Build Coastguard Worker /*out*/ MemMap* extra_reservation) 151*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 152*795d594fSAndroid Build Coastguard Worker 153*795d594fSAndroid Build Coastguard Worker // Try to open an existing app image space for an oat file, 154*795d594fSAndroid Build Coastguard Worker // using the boot image spaces from the current Runtime. 155*795d594fSAndroid Build Coastguard Worker EXPORT static std::unique_ptr<ImageSpace> CreateFromAppImage(const char* image, 156*795d594fSAndroid Build Coastguard Worker const OatFile* oat_file, 157*795d594fSAndroid Build Coastguard Worker std::string* error_msg) 158*795d594fSAndroid Build Coastguard Worker REQUIRES(!Locks::mutator_lock_); 159*795d594fSAndroid Build Coastguard Worker // Try to open an existing app image space for an the oat file and given boot image spaces. 160*795d594fSAndroid Build Coastguard Worker static std::unique_ptr<ImageSpace> CreateFromAppImage( 161*795d594fSAndroid Build Coastguard Worker const char* image, 162*795d594fSAndroid Build Coastguard Worker const OatFile* oat_file, 163*795d594fSAndroid Build Coastguard Worker ArrayRef<ImageSpace* const> boot_image_spaces, 164*795d594fSAndroid Build Coastguard Worker std::string* error_msg) REQUIRES(!Locks::mutator_lock_); 165*795d594fSAndroid Build Coastguard Worker 166*795d594fSAndroid Build Coastguard Worker // Checks whether we have a primary boot image on the disk. 167*795d594fSAndroid Build Coastguard Worker static bool IsBootClassPathOnDisk(InstructionSet image_isa); 168*795d594fSAndroid Build Coastguard Worker 169*795d594fSAndroid Build Coastguard Worker // Give access to the OatFile. 170*795d594fSAndroid Build Coastguard Worker EXPORT const OatFile* GetOatFile() const; 171*795d594fSAndroid Build Coastguard Worker 172*795d594fSAndroid Build Coastguard Worker // Releases the OatFile from the ImageSpace so it can be transfer to 173*795d594fSAndroid Build Coastguard Worker // the caller, presumably the OatFileManager. 174*795d594fSAndroid Build Coastguard Worker std::unique_ptr<const OatFile> ReleaseOatFile(); 175*795d594fSAndroid Build Coastguard Worker 176*795d594fSAndroid Build Coastguard Worker void VerifyImageAllocations() 177*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 178*795d594fSAndroid Build Coastguard Worker GetImageHeader()179*795d594fSAndroid Build Coastguard Worker const ImageHeader& GetImageHeader() const { 180*795d594fSAndroid Build Coastguard Worker return *reinterpret_cast<ImageHeader*>(Begin()); 181*795d594fSAndroid Build Coastguard Worker } 182*795d594fSAndroid Build Coastguard Worker 183*795d594fSAndroid Build Coastguard Worker // Actual filename where image was loaded from. 184*795d594fSAndroid Build Coastguard Worker // For example: /system/framework/arm64/boot.art GetImageFilename()185*795d594fSAndroid Build Coastguard Worker const std::string GetImageFilename() const { 186*795d594fSAndroid Build Coastguard Worker return GetName(); 187*795d594fSAndroid Build Coastguard Worker } 188*795d594fSAndroid Build Coastguard Worker 189*795d594fSAndroid Build Coastguard Worker // Symbolic location for image. 190*795d594fSAndroid Build Coastguard Worker // For example: /system/framework/boot.art GetImageLocation()191*795d594fSAndroid Build Coastguard Worker const std::string GetImageLocation() const { 192*795d594fSAndroid Build Coastguard Worker return image_location_; 193*795d594fSAndroid Build Coastguard Worker } 194*795d594fSAndroid Build Coastguard Worker GetProfileFiles()195*795d594fSAndroid Build Coastguard Worker const std::vector<std::string>& GetProfileFiles() const { return profile_files_; } 196*795d594fSAndroid Build Coastguard Worker GetLiveBitmap()197*795d594fSAndroid Build Coastguard Worker accounting::ContinuousSpaceBitmap* GetLiveBitmap() override { 198*795d594fSAndroid Build Coastguard Worker return &live_bitmap_; 199*795d594fSAndroid Build Coastguard Worker } 200*795d594fSAndroid Build Coastguard Worker GetMarkBitmap()201*795d594fSAndroid Build Coastguard Worker accounting::ContinuousSpaceBitmap* GetMarkBitmap() override { 202*795d594fSAndroid Build Coastguard Worker // ImageSpaces have the same bitmap for both live and marked. This helps reduce the number of 203*795d594fSAndroid Build Coastguard Worker // special cases to test against. 204*795d594fSAndroid Build Coastguard Worker return &live_bitmap_; 205*795d594fSAndroid Build Coastguard Worker } 206*795d594fSAndroid Build Coastguard Worker 207*795d594fSAndroid Build Coastguard Worker // Compute the number of components in the image (contributing jar files). GetComponentCount()208*795d594fSAndroid Build Coastguard Worker size_t GetComponentCount() const { 209*795d594fSAndroid Build Coastguard Worker return GetImageHeader().GetComponentCount(); 210*795d594fSAndroid Build Coastguard Worker } 211*795d594fSAndroid Build Coastguard Worker 212*795d594fSAndroid Build Coastguard Worker void Dump(std::ostream& os) const override; 213*795d594fSAndroid Build Coastguard Worker 214*795d594fSAndroid Build Coastguard Worker // Sweeping image spaces is a NOP. Sweep(bool,size_t *,size_t *)215*795d594fSAndroid Build Coastguard Worker void Sweep(bool /* swap_bitmaps */, size_t* /* freed_objects */, size_t* /* freed_bytes */) { 216*795d594fSAndroid Build Coastguard Worker } 217*795d594fSAndroid Build Coastguard Worker CanMoveObjects()218*795d594fSAndroid Build Coastguard Worker bool CanMoveObjects() const override { 219*795d594fSAndroid Build Coastguard Worker return false; 220*795d594fSAndroid Build Coastguard Worker } 221*795d594fSAndroid Build Coastguard Worker 222*795d594fSAndroid Build Coastguard Worker // Returns the filename of the image corresponding to 223*795d594fSAndroid Build Coastguard Worker // requested image_location, or the filename where a new image 224*795d594fSAndroid Build Coastguard Worker // should be written if one doesn't exist. Looks for a generated 225*795d594fSAndroid Build Coastguard Worker // image in the specified location. 226*795d594fSAndroid Build Coastguard Worker // 227*795d594fSAndroid Build Coastguard Worker // Returns true if an image was found, false otherwise. 228*795d594fSAndroid Build Coastguard Worker static bool FindImageFilename(const char* image_location, 229*795d594fSAndroid Build Coastguard Worker InstructionSet image_isa, 230*795d594fSAndroid Build Coastguard Worker std::string* system_location, 231*795d594fSAndroid Build Coastguard Worker bool* has_system); 232*795d594fSAndroid Build Coastguard Worker 233*795d594fSAndroid Build Coastguard Worker // The leading character in an image checksum part of boot class path checksums. 234*795d594fSAndroid Build Coastguard Worker static constexpr char kImageChecksumPrefix = 'i'; 235*795d594fSAndroid Build Coastguard Worker // The leading character in a dex file checksum part of boot class path checksums. 236*795d594fSAndroid Build Coastguard Worker static constexpr char kDexFileChecksumPrefix = 'd'; 237*795d594fSAndroid Build Coastguard Worker 238*795d594fSAndroid Build Coastguard Worker // Returns the checksums for the boot image, extensions and extra boot class path dex files, 239*795d594fSAndroid Build Coastguard Worker // based on the image spaces and boot class path dex files loaded in memory. 240*795d594fSAndroid Build Coastguard Worker // The `image_spaces` must correspond to the head of the `boot_class_path`. 241*795d594fSAndroid Build Coastguard Worker EXPORT static std::string GetBootClassPathChecksums( 242*795d594fSAndroid Build Coastguard Worker ArrayRef<ImageSpace* const> image_spaces, ArrayRef<const DexFile* const> boot_class_path); 243*795d594fSAndroid Build Coastguard Worker 244*795d594fSAndroid Build Coastguard Worker // Returns the total number of components (jar files) associated with the image spaces. 245*795d594fSAndroid Build Coastguard Worker static size_t GetNumberOfComponents(ArrayRef<gc::space::ImageSpace* const> image_spaces); 246*795d594fSAndroid Build Coastguard Worker 247*795d594fSAndroid Build Coastguard Worker // Returns whether the oat checksums and boot class path description are valid 248*795d594fSAndroid Build Coastguard Worker // for the given boot image spaces and boot class path. Used for boot image extensions. 249*795d594fSAndroid Build Coastguard Worker static bool VerifyBootClassPathChecksums( 250*795d594fSAndroid Build Coastguard Worker std::string_view oat_checksums, 251*795d594fSAndroid Build Coastguard Worker std::string_view oat_boot_class_path, 252*795d594fSAndroid Build Coastguard Worker ArrayRef<const std::unique_ptr<ImageSpace>> image_spaces, 253*795d594fSAndroid Build Coastguard Worker ArrayRef<const std::string> boot_class_path_locations, 254*795d594fSAndroid Build Coastguard Worker ArrayRef<const std::string> boot_class_path, 255*795d594fSAndroid Build Coastguard Worker /*out*/std::string* error_msg); 256*795d594fSAndroid Build Coastguard Worker 257*795d594fSAndroid Build Coastguard Worker // Expand a single image location to multi-image locations based on the dex locations. 258*795d594fSAndroid Build Coastguard Worker EXPORT static std::vector<std::string> ExpandMultiImageLocations( 259*795d594fSAndroid Build Coastguard Worker ArrayRef<const std::string> dex_locations, 260*795d594fSAndroid Build Coastguard Worker const std::string& image_location, 261*795d594fSAndroid Build Coastguard Worker bool boot_image_extension = false); 262*795d594fSAndroid Build Coastguard Worker 263*795d594fSAndroid Build Coastguard Worker // Returns true if the APEX versions in the OAT header match the given APEX versions. 264*795d594fSAndroid Build Coastguard Worker static bool ValidateApexVersions(const OatHeader& oat_header, 265*795d594fSAndroid Build Coastguard Worker const std::string& apex_versions, 266*795d594fSAndroid Build Coastguard Worker const std::string& file_location, 267*795d594fSAndroid Build Coastguard Worker std::string* error_msg); 268*795d594fSAndroid Build Coastguard Worker 269*795d594fSAndroid Build Coastguard Worker // Returns true if the dex checksums in the given oat file match the 270*795d594fSAndroid Build Coastguard Worker // checksums of the original dex files on disk. This is intended to be used 271*795d594fSAndroid Build Coastguard Worker // to validate the boot image oat file, which may contain dex entries from 272*795d594fSAndroid Build Coastguard Worker // multiple different (possibly multidex) dex files on disk. Prefer the 273*795d594fSAndroid Build Coastguard Worker // OatFileAssistant for validating regular app oat files because the 274*795d594fSAndroid Build Coastguard Worker // OatFileAssistant caches dex checksums that are reused to check both the 275*795d594fSAndroid Build Coastguard Worker // oat and odex file. 276*795d594fSAndroid Build Coastguard Worker // 277*795d594fSAndroid Build Coastguard Worker // This function is exposed for testing purposes. 278*795d594fSAndroid Build Coastguard Worker // 279*795d594fSAndroid Build Coastguard Worker // Calling this function requires an active runtime. 280*795d594fSAndroid Build Coastguard Worker static bool ValidateOatFile(const OatFile& oat_file, std::string* error_msg); 281*795d594fSAndroid Build Coastguard Worker 282*795d594fSAndroid Build Coastguard Worker // Same as above, but allows to use `dex_filenames` and `dex_fds` to find the dex files instead of 283*795d594fSAndroid Build Coastguard Worker // using the dex filenames in the header of the oat file, and also takes `apex_versions` from the 284*795d594fSAndroid Build Coastguard Worker // input. This overload is useful when the actual dex filenames are different from what's in the 285*795d594fSAndroid Build Coastguard Worker // header (e.g., when we run dex2oat on host), when the runtime can only access files through FDs 286*795d594fSAndroid Build Coastguard Worker // (e.g., when we run dex2oat on target in a restricted SELinux domain), or when there is no 287*795d594fSAndroid Build Coastguard Worker // active runtime. 288*795d594fSAndroid Build Coastguard Worker // 289*795d594fSAndroid Build Coastguard Worker // Calling this function does not require an active runtime. 290*795d594fSAndroid Build Coastguard Worker static bool ValidateOatFile(const OatFile& oat_file, 291*795d594fSAndroid Build Coastguard Worker std::string* error_msg, 292*795d594fSAndroid Build Coastguard Worker ArrayRef<const std::string> dex_filenames, 293*795d594fSAndroid Build Coastguard Worker ArrayRef<File> dex_files, 294*795d594fSAndroid Build Coastguard Worker const std::string& apex_versions); 295*795d594fSAndroid Build Coastguard Worker 296*795d594fSAndroid Build Coastguard Worker // Return the end of the image which includes non-heap objects such as ArtMethods and ArtFields. GetImageEnd()297*795d594fSAndroid Build Coastguard Worker uint8_t* GetImageEnd() const { 298*795d594fSAndroid Build Coastguard Worker return Begin() + GetImageHeader().GetImageSize(); 299*795d594fSAndroid Build Coastguard Worker } 300*795d594fSAndroid Build Coastguard Worker 301*795d594fSAndroid Build Coastguard Worker void DumpSections(std::ostream& os) const; 302*795d594fSAndroid Build Coastguard Worker 303*795d594fSAndroid Build Coastguard Worker // De-initialize the image-space by undoing the effects in Init(). 304*795d594fSAndroid Build Coastguard Worker virtual ~ImageSpace(); 305*795d594fSAndroid Build Coastguard Worker 306*795d594fSAndroid Build Coastguard Worker void ReleaseMetadata() REQUIRES_SHARED(Locks::mutator_lock_); 307*795d594fSAndroid Build Coastguard Worker 308*795d594fSAndroid Build Coastguard Worker static void AppendImageChecksum(uint32_t component_count, 309*795d594fSAndroid Build Coastguard Worker uint32_t checksum, 310*795d594fSAndroid Build Coastguard Worker /*inout*/ std::string* checksums); 311*795d594fSAndroid Build Coastguard Worker 312*795d594fSAndroid Build Coastguard Worker static size_t CheckAndCountBCPComponents(std::string_view oat_boot_class_path, 313*795d594fSAndroid Build Coastguard Worker ArrayRef<const std::string> boot_class_path, 314*795d594fSAndroid Build Coastguard Worker /*out*/ std::string* error_msg); 315*795d594fSAndroid Build Coastguard Worker 316*795d594fSAndroid Build Coastguard Worker // Helper class to find the primary boot image and boot image extensions 317*795d594fSAndroid Build Coastguard Worker // and determine the boot image layout. 318*795d594fSAndroid Build Coastguard Worker class BootImageLayout { 319*795d594fSAndroid Build Coastguard Worker public: 320*795d594fSAndroid Build Coastguard Worker // Description of a "chunk" of the boot image, i.e. either primary boot image 321*795d594fSAndroid Build Coastguard Worker // or a boot image extension, used in conjunction with the boot class path to 322*795d594fSAndroid Build Coastguard Worker // load boot image components. 323*795d594fSAndroid Build Coastguard Worker struct ImageChunk { 324*795d594fSAndroid Build Coastguard Worker std::string base_location; 325*795d594fSAndroid Build Coastguard Worker std::string base_filename; 326*795d594fSAndroid Build Coastguard Worker std::vector<std::string> profile_files; 327*795d594fSAndroid Build Coastguard Worker size_t start_index; 328*795d594fSAndroid Build Coastguard Worker uint32_t component_count; 329*795d594fSAndroid Build Coastguard Worker uint32_t image_space_count; 330*795d594fSAndroid Build Coastguard Worker uint32_t reservation_size; 331*795d594fSAndroid Build Coastguard Worker uint32_t checksum; 332*795d594fSAndroid Build Coastguard Worker uint32_t boot_image_component_count; 333*795d594fSAndroid Build Coastguard Worker uint32_t boot_image_checksum; 334*795d594fSAndroid Build Coastguard Worker uint32_t boot_image_size; 335*795d594fSAndroid Build Coastguard Worker 336*795d594fSAndroid Build Coastguard Worker // The following file descriptors hold the memfd files for extensions compiled 337*795d594fSAndroid Build Coastguard Worker // in memory and described by the above fields. We want to use them to mmap() 338*795d594fSAndroid Build Coastguard Worker // the contents and then close them while treating the ImageChunk description 339*795d594fSAndroid Build Coastguard Worker // as immutable (const), so make these fields explicitly mutable. 340*795d594fSAndroid Build Coastguard Worker mutable android::base::unique_fd art_fd; 341*795d594fSAndroid Build Coastguard Worker mutable android::base::unique_fd vdex_fd; 342*795d594fSAndroid Build Coastguard Worker mutable android::base::unique_fd oat_fd; 343*795d594fSAndroid Build Coastguard Worker }; 344*795d594fSAndroid Build Coastguard Worker 345*795d594fSAndroid Build Coastguard Worker // Creates an instance. 346*795d594fSAndroid Build Coastguard Worker // `apex_versions` is created from `Runtime::GetApexVersions` and must outlive this instance. BootImageLayout(ArrayRef<const std::string> image_locations,ArrayRef<const std::string> boot_class_path,ArrayRef<const std::string> boot_class_path_locations,ArrayRef<File> boot_class_path_files,ArrayRef<File> boot_class_path_image_files,ArrayRef<File> boot_class_path_vdex_files,ArrayRef<File> boot_class_path_oat_files,const std::string * apex_versions)347*795d594fSAndroid Build Coastguard Worker BootImageLayout(ArrayRef<const std::string> image_locations, 348*795d594fSAndroid Build Coastguard Worker ArrayRef<const std::string> boot_class_path, 349*795d594fSAndroid Build Coastguard Worker ArrayRef<const std::string> boot_class_path_locations, 350*795d594fSAndroid Build Coastguard Worker ArrayRef<File> boot_class_path_files, 351*795d594fSAndroid Build Coastguard Worker ArrayRef<File> boot_class_path_image_files, 352*795d594fSAndroid Build Coastguard Worker ArrayRef<File> boot_class_path_vdex_files, 353*795d594fSAndroid Build Coastguard Worker ArrayRef<File> boot_class_path_oat_files, 354*795d594fSAndroid Build Coastguard Worker const std::string* apex_versions) 355*795d594fSAndroid Build Coastguard Worker : image_locations_(image_locations), 356*795d594fSAndroid Build Coastguard Worker boot_class_path_(boot_class_path), 357*795d594fSAndroid Build Coastguard Worker boot_class_path_locations_(boot_class_path_locations), 358*795d594fSAndroid Build Coastguard Worker boot_class_path_files_(boot_class_path_files), 359*795d594fSAndroid Build Coastguard Worker boot_class_path_image_files_(boot_class_path_image_files), 360*795d594fSAndroid Build Coastguard Worker boot_class_path_vdex_files_(boot_class_path_vdex_files), 361*795d594fSAndroid Build Coastguard Worker boot_class_path_oat_files_(boot_class_path_oat_files), 362*795d594fSAndroid Build Coastguard Worker apex_versions_(*apex_versions) {} 363*795d594fSAndroid Build Coastguard Worker 364*795d594fSAndroid Build Coastguard Worker std::string GetPrimaryImageLocation(); 365*795d594fSAndroid Build Coastguard Worker 366*795d594fSAndroid Build Coastguard Worker bool LoadFromSystem(InstructionSet image_isa, 367*795d594fSAndroid Build Coastguard Worker bool allow_in_memory_compilation, 368*795d594fSAndroid Build Coastguard Worker /*out*/ std::string* error_msg); 369*795d594fSAndroid Build Coastguard Worker GetChunks()370*795d594fSAndroid Build Coastguard Worker ArrayRef<const ImageChunk> GetChunks() const { return ArrayRef<const ImageChunk>(chunks_); } 371*795d594fSAndroid Build Coastguard Worker GetBaseAddress()372*795d594fSAndroid Build Coastguard Worker uint32_t GetBaseAddress() const { return base_address_; } 373*795d594fSAndroid Build Coastguard Worker GetNextBcpIndex()374*795d594fSAndroid Build Coastguard Worker size_t GetNextBcpIndex() const { return next_bcp_index_; } 375*795d594fSAndroid Build Coastguard Worker GetTotalComponentCount()376*795d594fSAndroid Build Coastguard Worker size_t GetTotalComponentCount() const { return total_component_count_; } 377*795d594fSAndroid Build Coastguard Worker GetTotalReservationSize()378*795d594fSAndroid Build Coastguard Worker size_t GetTotalReservationSize() const { return total_reservation_size_; } 379*795d594fSAndroid Build Coastguard Worker 380*795d594fSAndroid Build Coastguard Worker private: 381*795d594fSAndroid Build Coastguard Worker struct NamedComponentLocation { 382*795d594fSAndroid Build Coastguard Worker std::string base_location; 383*795d594fSAndroid Build Coastguard Worker size_t bcp_index; 384*795d594fSAndroid Build Coastguard Worker std::vector<std::string> profile_filenames; 385*795d594fSAndroid Build Coastguard Worker }; 386*795d594fSAndroid Build Coastguard Worker ExpandLocationImpl(const std::string & location,size_t bcp_index,bool boot_image_extension)387*795d594fSAndroid Build Coastguard Worker std::string ExpandLocationImpl(const std::string& location, 388*795d594fSAndroid Build Coastguard Worker size_t bcp_index, 389*795d594fSAndroid Build Coastguard Worker bool boot_image_extension) { 390*795d594fSAndroid Build Coastguard Worker std::vector<std::string> expanded = ExpandMultiImageLocations( 391*795d594fSAndroid Build Coastguard Worker ArrayRef<const std::string>(boot_class_path_).SubArray(bcp_index, 1u), 392*795d594fSAndroid Build Coastguard Worker location, 393*795d594fSAndroid Build Coastguard Worker boot_image_extension); 394*795d594fSAndroid Build Coastguard Worker DCHECK_EQ(expanded.size(), 1u); 395*795d594fSAndroid Build Coastguard Worker return expanded[0]; 396*795d594fSAndroid Build Coastguard Worker } 397*795d594fSAndroid Build Coastguard Worker ExpandLocation(const std::string & location,size_t bcp_index)398*795d594fSAndroid Build Coastguard Worker std::string ExpandLocation(const std::string& location, size_t bcp_index) { 399*795d594fSAndroid Build Coastguard Worker if (bcp_index == 0u) { 400*795d594fSAndroid Build Coastguard Worker DCHECK_EQ(location, 401*795d594fSAndroid Build Coastguard Worker ExpandLocationImpl(location, bcp_index, /*boot_image_extension=*/false)); 402*795d594fSAndroid Build Coastguard Worker return location; 403*795d594fSAndroid Build Coastguard Worker } else { 404*795d594fSAndroid Build Coastguard Worker return ExpandLocationImpl(location, bcp_index, /*boot_image_extension=*/true); 405*795d594fSAndroid Build Coastguard Worker } 406*795d594fSAndroid Build Coastguard Worker } 407*795d594fSAndroid Build Coastguard Worker GetBcpComponentPath(size_t bcp_index)408*795d594fSAndroid Build Coastguard Worker std::string GetBcpComponentPath(size_t bcp_index) { 409*795d594fSAndroid Build Coastguard Worker DCHECK_LE(bcp_index, boot_class_path_.size()); 410*795d594fSAndroid Build Coastguard Worker size_t bcp_slash_pos = boot_class_path_[bcp_index].rfind('/'); 411*795d594fSAndroid Build Coastguard Worker DCHECK_NE(bcp_slash_pos, std::string::npos); 412*795d594fSAndroid Build Coastguard Worker return boot_class_path_[bcp_index].substr(0u, bcp_slash_pos + 1u); 413*795d594fSAndroid Build Coastguard Worker } 414*795d594fSAndroid Build Coastguard Worker 415*795d594fSAndroid Build Coastguard Worker bool VerifyImageLocation(ArrayRef<const std::string> components, 416*795d594fSAndroid Build Coastguard Worker /*out*/ size_t* named_components_count, 417*795d594fSAndroid Build Coastguard Worker /*out*/ std::string* error_msg); 418*795d594fSAndroid Build Coastguard Worker 419*795d594fSAndroid Build Coastguard Worker bool MatchNamedComponents( 420*795d594fSAndroid Build Coastguard Worker ArrayRef<const std::string> named_components, 421*795d594fSAndroid Build Coastguard Worker /*out*/ std::vector<NamedComponentLocation>* named_component_locations, 422*795d594fSAndroid Build Coastguard Worker /*out*/ std::string* error_msg); 423*795d594fSAndroid Build Coastguard Worker 424*795d594fSAndroid Build Coastguard Worker bool ValidateBootImageChecksum(const char* file_description, 425*795d594fSAndroid Build Coastguard Worker const ImageHeader& header, 426*795d594fSAndroid Build Coastguard Worker /*out*/ std::string* error_msg); 427*795d594fSAndroid Build Coastguard Worker 428*795d594fSAndroid Build Coastguard Worker bool ValidateHeader(const ImageHeader& header, 429*795d594fSAndroid Build Coastguard Worker size_t bcp_index, 430*795d594fSAndroid Build Coastguard Worker const char* file_description, 431*795d594fSAndroid Build Coastguard Worker /*out*/ std::string* error_msg); 432*795d594fSAndroid Build Coastguard Worker 433*795d594fSAndroid Build Coastguard Worker bool ValidateOatFile(const std::string& base_location, 434*795d594fSAndroid Build Coastguard Worker const std::string& base_filename, 435*795d594fSAndroid Build Coastguard Worker size_t bcp_index, 436*795d594fSAndroid Build Coastguard Worker size_t component_count, 437*795d594fSAndroid Build Coastguard Worker /*out*/ std::string* error_msg); 438*795d594fSAndroid Build Coastguard Worker 439*795d594fSAndroid Build Coastguard Worker bool ReadHeader(const std::string& base_location, 440*795d594fSAndroid Build Coastguard Worker const std::string& base_filename, 441*795d594fSAndroid Build Coastguard Worker size_t bcp_index, 442*795d594fSAndroid Build Coastguard Worker /*out*/ std::string* error_msg); 443*795d594fSAndroid Build Coastguard Worker 444*795d594fSAndroid Build Coastguard Worker // Compiles a consecutive subsequence of bootclasspath dex files, whose contents are included in 445*795d594fSAndroid Build Coastguard Worker // the profiles specified by `profile_filenames`, starting from `bcp_index`. 446*795d594fSAndroid Build Coastguard Worker bool CompileBootclasspathElements(const std::string& base_location, 447*795d594fSAndroid Build Coastguard Worker const std::string& base_filename, 448*795d594fSAndroid Build Coastguard Worker size_t bcp_index, 449*795d594fSAndroid Build Coastguard Worker const std::vector<std::string>& profile_filenames, 450*795d594fSAndroid Build Coastguard Worker ArrayRef<const std::string> dependencies, 451*795d594fSAndroid Build Coastguard Worker /*out*/ std::string* error_msg); 452*795d594fSAndroid Build Coastguard Worker 453*795d594fSAndroid Build Coastguard Worker // Returns true if a least one chuck has been loaded. 454*795d594fSAndroid Build Coastguard Worker template <typename FilenameFn> 455*795d594fSAndroid Build Coastguard Worker bool Load(FilenameFn&& filename_fn, 456*795d594fSAndroid Build Coastguard Worker bool allow_in_memory_compilation, 457*795d594fSAndroid Build Coastguard Worker /*out*/ std::string* error_msg); 458*795d594fSAndroid Build Coastguard Worker 459*795d594fSAndroid Build Coastguard Worker ArrayRef<const std::string> image_locations_; 460*795d594fSAndroid Build Coastguard Worker ArrayRef<const std::string> boot_class_path_; 461*795d594fSAndroid Build Coastguard Worker ArrayRef<const std::string> boot_class_path_locations_; 462*795d594fSAndroid Build Coastguard Worker ArrayRef<File> boot_class_path_files_; 463*795d594fSAndroid Build Coastguard Worker ArrayRef<File> boot_class_path_image_files_; 464*795d594fSAndroid Build Coastguard Worker ArrayRef<File> boot_class_path_vdex_files_; 465*795d594fSAndroid Build Coastguard Worker ArrayRef<File> boot_class_path_oat_files_; 466*795d594fSAndroid Build Coastguard Worker 467*795d594fSAndroid Build Coastguard Worker std::vector<ImageChunk> chunks_; 468*795d594fSAndroid Build Coastguard Worker uint32_t base_address_ = 0u; 469*795d594fSAndroid Build Coastguard Worker size_t next_bcp_index_ = 0u; 470*795d594fSAndroid Build Coastguard Worker size_t total_component_count_ = 0u; 471*795d594fSAndroid Build Coastguard Worker size_t total_reservation_size_ = 0u; 472*795d594fSAndroid Build Coastguard Worker const std::string& apex_versions_; 473*795d594fSAndroid Build Coastguard Worker }; 474*795d594fSAndroid Build Coastguard Worker 475*795d594fSAndroid Build Coastguard Worker protected: 476*795d594fSAndroid Build Coastguard Worker // Tries to initialize an ImageSpace from the given image path, returning null on error. 477*795d594fSAndroid Build Coastguard Worker // 478*795d594fSAndroid Build Coastguard Worker // If validate_oat_file is false (for /system), do not verify that image's OatFile is up-to-date 479*795d594fSAndroid Build Coastguard Worker // relative to its DexFile inputs. Otherwise, validate `oat_file` and abandon it if the validation 480*795d594fSAndroid Build Coastguard Worker // fails. If the oat_file is null, it uses the oat file from the image. 481*795d594fSAndroid Build Coastguard Worker static std::unique_ptr<ImageSpace> Init(const char* image_filename, 482*795d594fSAndroid Build Coastguard Worker const char* image_location, 483*795d594fSAndroid Build Coastguard Worker bool validate_oat_file, 484*795d594fSAndroid Build Coastguard Worker const OatFile* oat_file, 485*795d594fSAndroid Build Coastguard Worker std::string* error_msg) 486*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 487*795d594fSAndroid Build Coastguard Worker 488*795d594fSAndroid Build Coastguard Worker static Atomic<uint32_t> bitmap_index_; 489*795d594fSAndroid Build Coastguard Worker 490*795d594fSAndroid Build Coastguard Worker accounting::ContinuousSpaceBitmap live_bitmap_; 491*795d594fSAndroid Build Coastguard Worker 492*795d594fSAndroid Build Coastguard Worker ImageSpace(const std::string& name, 493*795d594fSAndroid Build Coastguard Worker const char* image_location, 494*795d594fSAndroid Build Coastguard Worker const std::vector<std::string>& profile_files, 495*795d594fSAndroid Build Coastguard Worker MemMap&& mem_map, 496*795d594fSAndroid Build Coastguard Worker accounting::ContinuousSpaceBitmap&& live_bitmap, 497*795d594fSAndroid Build Coastguard Worker uint8_t* end); 498*795d594fSAndroid Build Coastguard Worker 499*795d594fSAndroid Build Coastguard Worker // The OatFile associated with the image during early startup to 500*795d594fSAndroid Build Coastguard Worker // reserve space contiguous to the image. It is later released to 501*795d594fSAndroid Build Coastguard Worker // the ClassLinker during it's initialization. 502*795d594fSAndroid Build Coastguard Worker std::unique_ptr<OatFile> oat_file_; 503*795d594fSAndroid Build Coastguard Worker 504*795d594fSAndroid Build Coastguard Worker // There are times when we need to find the boot image oat file. As 505*795d594fSAndroid Build Coastguard Worker // we release ownership during startup, keep a non-owned reference. 506*795d594fSAndroid Build Coastguard Worker const OatFile* oat_file_non_owned_; 507*795d594fSAndroid Build Coastguard Worker 508*795d594fSAndroid Build Coastguard Worker const std::string image_location_; 509*795d594fSAndroid Build Coastguard Worker const std::vector<std::string> profile_files_; 510*795d594fSAndroid Build Coastguard Worker 511*795d594fSAndroid Build Coastguard Worker friend class Space; 512*795d594fSAndroid Build Coastguard Worker 513*795d594fSAndroid Build Coastguard Worker private: 514*795d594fSAndroid Build Coastguard Worker class BootImageLoader; 515*795d594fSAndroid Build Coastguard Worker template <typename ReferenceVisitor> 516*795d594fSAndroid Build Coastguard Worker class ClassTableVisitor; 517*795d594fSAndroid Build Coastguard Worker class RemapInternedStringsVisitor; 518*795d594fSAndroid Build Coastguard Worker class Loader; 519*795d594fSAndroid Build Coastguard Worker template <typename PatchObjectVisitor> 520*795d594fSAndroid Build Coastguard Worker class PatchArtFieldVisitor; 521*795d594fSAndroid Build Coastguard Worker template <PointerSize kPointerSize, typename PatchObjectVisitor, typename PatchCodeVisitor> 522*795d594fSAndroid Build Coastguard Worker class PatchArtMethodVisitor; 523*795d594fSAndroid Build Coastguard Worker template <PointerSize kPointerSize, typename HeapVisitor, typename NativeVisitor> 524*795d594fSAndroid Build Coastguard Worker class PatchObjectVisitor; 525*795d594fSAndroid Build Coastguard Worker 526*795d594fSAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(ImageSpace); 527*795d594fSAndroid Build Coastguard Worker }; 528*795d594fSAndroid Build Coastguard Worker 529*795d594fSAndroid Build Coastguard Worker } // namespace space 530*795d594fSAndroid Build Coastguard Worker } // namespace gc 531*795d594fSAndroid Build Coastguard Worker } // namespace art 532*795d594fSAndroid Build Coastguard Worker 533*795d594fSAndroid Build Coastguard Worker #endif // ART_RUNTIME_GC_SPACE_IMAGE_SPACE_H_ 534