1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ART_RUNTIME_GC_SPACE_IMAGE_SPACE_H_ 18 #define ART_RUNTIME_GC_SPACE_IMAGE_SPACE_H_ 19 20 #include "gc/accounting/space_bitmap.h" 21 #include "image.h" 22 #include "image_space_loading_order.h" 23 #include "space.h" 24 25 namespace art { 26 27 template <typename T> class ArrayRef; 28 class DexFile; 29 enum class InstructionSet; 30 class OatFile; 31 32 namespace gc { 33 namespace space { 34 35 // An image space is a space backed with a memory mapped image. 36 class ImageSpace : public MemMapSpace { 37 public: GetType()38 SpaceType GetType() const override { 39 return kSpaceTypeImageSpace; 40 } 41 42 // The separator for boot image location components. 43 static constexpr char kComponentSeparator = ':'; 44 // The separator for profile filename. 45 static constexpr char kProfileSeparator = '!'; 46 47 // Load boot image spaces for specified boot class path, image location, instruction set, etc. 48 // 49 // On successful return, the loaded spaces are added to boot_image_spaces (which must be 50 // empty on entry) and `extra_reservation` is set to the requested reservation located 51 // after the end of the last loaded oat file. 52 // 53 // IMAGE LOCATION 54 // 55 // The "image location" is a colon-separated list that specifies one or more 56 // components by name and may also specify search paths for extensions 57 // corresponding to the remaining boot class path (BCP) extensions. 58 // 59 // The primary boot image can be specified as one of 60 // <path>/<base-name> 61 // <base-name> 62 // and the path of the first BCP component is used for the second form. 63 // 64 // Named extension specifications must correspond to an expansion of the 65 // <base-name> with a BCP component (for example boot.art with the BCP 66 // component name <jar-path>/framework.jar expands to boot-framework.art). 67 // They can be similarly specified as one of 68 // <ext-path>/<ext-name> 69 // <ext-name> 70 // and must be listed in the order of their corresponding BCP components. 71 // The specification may have a suffix with profile specification, one of 72 // !<ext-path>/<ext-name> 73 // !<ext-name> 74 // and this profile will be used to compile the extension when loading the 75 // boot image if the on-disk version is not acceptable (either not present 76 // or fails validation, presumably because it's out of date). The first 77 // extension specification that includes the profile specification also 78 // terminates the list of the boot image dependencies that each extension 79 // is compiled against. 80 // 81 // Search paths for remaining extensions can be specified after named 82 // components as one of 83 // <search-path>/* 84 // * 85 // where the second form means that the path of a particular BCP component 86 // should be used to search for that component's boot image extension. These 87 // paths will be searched in the specifed order. 88 // 89 // The actual filename shall be derived from the specified locations using 90 // `GetSystemImageFilename()` or `GetDalvikCacheFilename()`. 91 // 92 // Example image locations: 93 // /system/framework/boot.art 94 // - only primary boot image with full path. 95 // boot.art:boot-framework.art 96 // - primary and one extension, use BCP component paths. 97 // /apex/com.android.art/boot.art:* 98 // - primary with exact location, search for the rest based on BCP 99 // component paths. 100 // boot.art:/system/framework/* 101 // - primary based on BCP component path, search for extensions in 102 // /system/framework. 103 // /apex/com.android.art/boot.art:/system/framework/*:* 104 // - primary with exact location, search for extensions first in 105 // /system/framework, then in the corresponding BCP component path. 106 // /apex/com.android.art/boot.art:*:/system/framework/* 107 // - primary with exact location, search for extensions first in the 108 // corresponding BCP component path and then in /system/framework. 109 // /apex/com.android.art/boot.art:*:boot-framework.jar 110 // - invalid, named components may not follow search paths. 111 // boot.art:boot-framework.jar!/system/framework/framework.prof 112 // - primary and one extension, use BCP component paths; if extension 113 // is not found or broken compile it in memory using the specified 114 // profile file from the exact path. 115 // boot.art:boot-framework.jar:conscrypt.jar!conscrypt.prof 116 // - primary and two extensions, use BCP component paths; only the 117 // second extension has a profile file and can be compiled in memory 118 // when it is not found or broken, using the specified profile file 119 // in the BCP component path and it is compiled against the primary 120 // and first extension and only if the first extension is OK. 121 // boot.art:boot-framework.jar!framework.prof:conscrypt.jar!conscrypt.prof 122 // - primary and two extensions, use BCP component paths; if any 123 // extension is not found or broken compile it in memory using 124 // the specified profile file in the BCP component path, each 125 // extension is compiled only against the primary boot image. 126 static bool LoadBootImage( 127 const std::vector<std::string>& boot_class_path, 128 const std::vector<std::string>& boot_class_path_locations, 129 const std::string& image_location, 130 const InstructionSet image_isa, 131 ImageSpaceLoadingOrder order, 132 bool relocate, 133 bool executable, 134 bool is_zygote, 135 size_t extra_reservation_size, 136 /*out*/std::vector<std::unique_ptr<ImageSpace>>* boot_image_spaces, 137 /*out*/MemMap* extra_reservation) REQUIRES_SHARED(Locks::mutator_lock_); 138 139 // Try to open an existing app image space for an oat file, 140 // using the boot image spaces from the current Runtime. 141 static std::unique_ptr<ImageSpace> CreateFromAppImage(const char* image, 142 const OatFile* oat_file, 143 std::string* error_msg) 144 REQUIRES_SHARED(Locks::mutator_lock_); 145 // Try to open an existing app image space for an the oat file and given boot image spaces. 146 static std::unique_ptr<ImageSpace> CreateFromAppImage( 147 const char* image, 148 const OatFile* oat_file, 149 ArrayRef<ImageSpace* const> boot_image_spaces, 150 std::string* error_msg) REQUIRES_SHARED(Locks::mutator_lock_); 151 152 // Checks whether we have a primary boot image on the disk. 153 static bool IsBootClassPathOnDisk(InstructionSet image_isa); 154 155 // Give access to the OatFile. 156 const OatFile* GetOatFile() const; 157 158 // Releases the OatFile from the ImageSpace so it can be transfer to 159 // the caller, presumably the OatFileManager. 160 std::unique_ptr<const OatFile> ReleaseOatFile(); 161 162 void VerifyImageAllocations() 163 REQUIRES_SHARED(Locks::mutator_lock_); 164 GetImageHeader()165 const ImageHeader& GetImageHeader() const { 166 return *reinterpret_cast<ImageHeader*>(Begin()); 167 } 168 169 // Actual filename where image was loaded from. 170 // For example: /data/dalvik-cache/arm/system@framework@boot.art GetImageFilename()171 const std::string GetImageFilename() const { 172 return GetName(); 173 } 174 175 // Symbolic location for image. 176 // For example: /system/framework/boot.art GetImageLocation()177 const std::string GetImageLocation() const { 178 return image_location_; 179 } 180 GetProfileFile()181 const std::string GetProfileFile() const { 182 return profile_file_; 183 } 184 GetLiveBitmap()185 accounting::ContinuousSpaceBitmap* GetLiveBitmap() override { 186 return &live_bitmap_; 187 } 188 GetMarkBitmap()189 accounting::ContinuousSpaceBitmap* GetMarkBitmap() override { 190 // ImageSpaces have the same bitmap for both live and marked. This helps reduce the number of 191 // special cases to test against. 192 return &live_bitmap_; 193 } 194 195 void Dump(std::ostream& os) const override; 196 197 // Sweeping image spaces is a NOP. Sweep(bool,size_t *,size_t *)198 void Sweep(bool /* swap_bitmaps */, size_t* /* freed_objects */, size_t* /* freed_bytes */) { 199 } 200 CanMoveObjects()201 bool CanMoveObjects() const override { 202 return false; 203 } 204 205 // Returns the filename of the image corresponding to 206 // requested image_location, or the filename where a new image 207 // should be written if one doesn't exist. Looks for a generated 208 // image in the specified location and then in the dalvik-cache. 209 // 210 // Returns true if an image was found, false otherwise. 211 static bool FindImageFilename(const char* image_location, 212 InstructionSet image_isa, 213 std::string* system_location, 214 bool* has_system, 215 std::string* data_location, 216 bool* dalvik_cache_exists, 217 bool* has_data, 218 bool *is_global_cache); 219 220 // The leading character in an image checksum part of boot class path checkums. 221 static constexpr char kImageChecksumPrefix = 'i'; 222 // The leading character in a dex file checksum part of boot class path checkums. 223 static constexpr char kDexFileChecksumPrefix = 'd'; 224 225 // Returns the checksums for the boot image, extensions and extra boot class path dex files, 226 // based on the image spaces and boot class path dex files loaded in memory. 227 // The `image_spaces` must correspond to the head of the `boot_class_path`. 228 static std::string GetBootClassPathChecksums(ArrayRef<ImageSpace* const> image_spaces, 229 ArrayRef<const DexFile* const> boot_class_path); 230 231 // Returns whether the checksums are valid for the given boot class path, 232 // image location and ISA (may differ from the ISA of an initialized Runtime). 233 // The boot image and dex files do not need to be loaded in memory. 234 static bool VerifyBootClassPathChecksums(std::string_view oat_checksums, 235 std::string_view oat_boot_class_path, 236 const std::string& image_location, 237 ArrayRef<const std::string> boot_class_path_locations, 238 ArrayRef<const std::string> boot_class_path, 239 InstructionSet image_isa, 240 ImageSpaceLoadingOrder order, 241 /*out*/std::string* error_msg); 242 243 // Returns whether the oat checksums and boot class path description are valid 244 // for the given boot image spaces and boot class path. Used for boot image extensions. 245 static bool VerifyBootClassPathChecksums( 246 std::string_view oat_checksums, 247 std::string_view oat_boot_class_path, 248 ArrayRef<const std::unique_ptr<ImageSpace>> image_spaces, 249 ArrayRef<const std::string> boot_class_path_locations, 250 ArrayRef<const std::string> boot_class_path, 251 /*out*/std::string* error_msg); 252 253 // Expand a single image location to multi-image locations based on the dex locations. 254 static std::vector<std::string> ExpandMultiImageLocations( 255 ArrayRef<const std::string> dex_locations, 256 const std::string& image_location, 257 bool boot_image_extension = false); 258 259 // Returns true if the dex checksums in the given oat file match the 260 // checksums of the original dex files on disk. This is intended to be used 261 // to validate the boot image oat file, which may contain dex entries from 262 // multiple different (possibly multidex) dex files on disk. Prefer the 263 // OatFileAssistant for validating regular app oat files because the 264 // OatFileAssistant caches dex checksums that are reused to check both the 265 // oat and odex file. 266 // 267 // This function is exposed for testing purposes. 268 static bool ValidateOatFile(const OatFile& oat_file, std::string* error_msg); 269 270 // Return the end of the image which includes non-heap objects such as ArtMethods and ArtFields. GetImageEnd()271 uint8_t* GetImageEnd() const { 272 return Begin() + GetImageHeader().GetImageSize(); 273 } 274 275 void DumpSections(std::ostream& os) const; 276 277 // De-initialize the image-space by undoing the effects in Init(). 278 virtual ~ImageSpace(); 279 280 void DisablePreResolvedStrings() REQUIRES_SHARED(Locks::mutator_lock_); 281 void ReleaseMetadata() REQUIRES_SHARED(Locks::mutator_lock_); 282 283 protected: 284 // Tries to initialize an ImageSpace from the given image path, returning null on error. 285 // 286 // If validate_oat_file is false (for /system), do not verify that image's OatFile is up-to-date 287 // relative to its DexFile inputs. Otherwise (for /data), validate the inputs and generate the 288 // OatFile in /data/dalvik-cache if necessary. If the oat_file is null, it uses the oat file from 289 // the image. 290 static std::unique_ptr<ImageSpace> Init(const char* image_filename, 291 const char* image_location, 292 bool validate_oat_file, 293 const OatFile* oat_file, 294 std::string* error_msg) 295 REQUIRES_SHARED(Locks::mutator_lock_); 296 297 static Atomic<uint32_t> bitmap_index_; 298 299 accounting::ContinuousSpaceBitmap live_bitmap_; 300 301 ImageSpace(const std::string& name, 302 const char* image_location, 303 const char* profile_file, 304 MemMap&& mem_map, 305 accounting::ContinuousSpaceBitmap&& live_bitmap, 306 uint8_t* end); 307 308 // The OatFile associated with the image during early startup to 309 // reserve space contiguous to the image. It is later released to 310 // the ClassLinker during it's initialization. 311 std::unique_ptr<OatFile> oat_file_; 312 313 // There are times when we need to find the boot image oat file. As 314 // we release ownership during startup, keep a non-owned reference. 315 const OatFile* oat_file_non_owned_; 316 317 const std::string image_location_; 318 const std::string profile_file_; 319 320 friend class Space; 321 322 private: 323 class BootImageLayout; 324 class BootImageLoader; 325 template <typename ReferenceVisitor> 326 class ClassTableVisitor; 327 class RemapInternedStringsVisitor; 328 class Loader; 329 template <typename PatchObjectVisitor> 330 class PatchArtFieldVisitor; 331 template <PointerSize kPointerSize, typename PatchObjectVisitor, typename PatchCodeVisitor> 332 class PatchArtMethodVisitor; 333 template <PointerSize kPointerSize, typename HeapVisitor, typename NativeVisitor> 334 class PatchObjectVisitor; 335 336 DISALLOW_COPY_AND_ASSIGN(ImageSpace); 337 }; 338 339 } // namespace space 340 } // namespace gc 341 } // namespace art 342 343 #endif // ART_RUNTIME_GC_SPACE_IMAGE_SPACE_H_ 344