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