xref: /aosp_15_r20/art/runtime/oat/image.h (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
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_OAT_IMAGE_H_
18 #define ART_RUNTIME_OAT_IMAGE_H_
19 
20 #include <string.h>
21 
22 #include "base/file_utils.h"
23 #include "base/iteration_range.h"
24 #include "base/macros.h"
25 #include "base/os.h"
26 #include "base/pointer_size.h"
27 #include "base/unix_file/fd_file.h"
28 #include "mirror/object.h"
29 #include "runtime_globals.h"
30 
31 namespace art HIDDEN {
32 
33 class ArtField;
34 class ArtMethod;
35 class ImageFileGuard;
36 
37 template <class MirrorType> class ObjPtr;
38 
39 namespace linker {
40 class ImageWriter;
41 }  // namespace linker
42 
43 class ObjectVisitor {
44  public:
~ObjectVisitor()45   virtual ~ObjectVisitor() {}
46 
47   virtual void Visit(mirror::Object* object) = 0;
48 };
49 
50 class PACKED(4) ImageSection {
51  public:
ImageSection()52   ImageSection() : offset_(0), size_(0) { }
ImageSection(uint32_t offset,uint32_t size)53   ImageSection(uint32_t offset, uint32_t size) : offset_(offset), size_(size) { }
54   ImageSection(const ImageSection& section) = default;
55   ImageSection& operator=(const ImageSection& section) = default;
56 
Offset()57   uint32_t Offset() const {
58     return offset_;
59   }
60 
Size()61   uint32_t Size() const {
62     return size_;
63   }
64 
End()65   uint32_t End() const {
66     return Offset() + Size();
67   }
68 
Contains(uint64_t offset)69   bool Contains(uint64_t offset) const {
70     return offset - offset_ < size_;
71   }
72 
73  private:
74   uint32_t offset_;
75   uint32_t size_;
76 };
77 
78 // Header of image files written by ImageWriter, read and validated by Space.
79 // Packed to object alignment since the first object follows directly after the header.
80 static_assert(kObjectAlignment == 8, "Alignment check");
81 class PACKED(8) ImageHeader {
82  public:
83   enum StorageMode : uint32_t {
84     kStorageModeUncompressed,
85     kStorageModeLZ4,
86     kStorageModeLZ4HC,
87     kStorageModeCount,  // Number of elements in enum.
88   };
89   static constexpr StorageMode kDefaultStorageMode = kStorageModeUncompressed;
90 
91   // Solid block of the image. May be compressed or uncompressed.
92   class PACKED(4) Block final {
93    public:
Block(StorageMode storage_mode,uint32_t data_offset,uint32_t data_size,uint32_t image_offset,uint32_t image_size)94     Block(StorageMode storage_mode,
95           uint32_t data_offset,
96           uint32_t data_size,
97           uint32_t image_offset,
98           uint32_t image_size)
99         : storage_mode_(storage_mode),
100           data_offset_(data_offset),
101           data_size_(data_size),
102           image_offset_(image_offset),
103           image_size_(image_size) {}
104 
105     bool Decompress(uint8_t* out_ptr, const uint8_t* in_ptr, std::string* error_msg) const;
106 
GetStorageMode()107     StorageMode GetStorageMode() const {
108       return storage_mode_;
109     }
110 
GetDataSize()111     uint32_t GetDataSize() const {
112       return data_size_;
113     }
114 
GetImageSize()115     uint32_t GetImageSize() const {
116       return image_size_;
117     }
118 
119    private:
120     // Storage method for the image, the image may be compressed.
121     StorageMode storage_mode_ = kDefaultStorageMode;
122 
123     // Compressed offset and size.
124     uint32_t data_offset_ = 0u;
125     uint32_t data_size_ = 0u;
126 
127     // Image offset and size (decompressed or mapped location).
128     uint32_t image_offset_ = 0u;
129     uint32_t image_size_ = 0u;
130   };
131 
ImageHeader()132   ImageHeader() {}
133   EXPORT ImageHeader(uint32_t image_reservation_size,
134                      uint32_t component_count,
135                      uint32_t image_begin,
136                      uint32_t image_size,
137                      ImageSection* sections,
138                      uint32_t image_roots,
139                      uint32_t oat_checksum,
140                      uint32_t oat_file_begin,
141                      uint32_t oat_data_begin,
142                      uint32_t oat_data_end,
143                      uint32_t oat_file_end,
144                      uint32_t boot_image_begin,
145                      uint32_t boot_image_size,
146                      uint32_t boot_image_component_count,
147                      uint32_t boot_image_checksum,
148                      PointerSize pointer_size);
149 
150   EXPORT bool IsValid() const;
151   EXPORT const char* GetMagic() const;
152 
GetImageReservationSize()153   uint32_t GetImageReservationSize() const {
154     return image_reservation_size_;
155   }
156 
GetComponentCount()157   uint32_t GetComponentCount() const {
158     return component_count_;
159   }
160 
GetImageBegin()161   uint8_t* GetImageBegin() const {
162     return reinterpret_cast<uint8_t*>(image_begin_);
163   }
164 
GetImageSize()165   size_t GetImageSize() const {
166     return image_size_;
167   }
168 
GetImageChecksum()169   uint32_t GetImageChecksum() const {
170     return image_checksum_;
171   }
172 
SetImageChecksum(uint32_t image_checksum)173   void SetImageChecksum(uint32_t image_checksum) {
174     image_checksum_ = image_checksum;
175   }
176 
GetOatChecksum()177   uint32_t GetOatChecksum() const {
178     return oat_checksum_;
179   }
180 
SetOatChecksum(uint32_t oat_checksum)181   void SetOatChecksum(uint32_t oat_checksum) {
182     oat_checksum_ = oat_checksum;
183   }
184 
185   // The location that the oat file was expected to be when the image was created. The actual
186   // oat file may be at a different location for application images.
GetOatFileBegin()187   uint8_t* GetOatFileBegin() const {
188     return reinterpret_cast<uint8_t*>(oat_file_begin_);
189   }
190 
GetOatDataBegin()191   uint8_t* GetOatDataBegin() const {
192     return reinterpret_cast<uint8_t*>(oat_data_begin_);
193   }
194 
GetOatDataEnd()195   uint8_t* GetOatDataEnd() const {
196     return reinterpret_cast<uint8_t*>(oat_data_end_);
197   }
198 
GetOatFileEnd()199   uint8_t* GetOatFileEnd() const {
200     return reinterpret_cast<uint8_t*>(oat_file_end_);
201   }
202 
203   EXPORT PointerSize GetPointerSize() const;
204 
GetOatLocationFromImageLocation(const std::string & image)205   static std::string GetOatLocationFromImageLocation(const std::string& image) {
206     return ReplaceFileExtension(image, kOatExtension);
207   }
208 
GetVdexLocationFromImageLocation(const std::string & image)209   static std::string GetVdexLocationFromImageLocation(const std::string& image) {
210     return ReplaceFileExtension(image, kVdexExtension);
211   }
212 
213   enum ImageMethod {
214     kResolutionMethod,
215     kImtConflictMethod,
216     kImtUnimplementedMethod,
217     kSaveAllCalleeSavesMethod,
218     kSaveRefsOnlyMethod,
219     kSaveRefsAndArgsMethod,
220     kSaveEverythingMethod,
221     kSaveEverythingMethodForClinit,
222     kSaveEverythingMethodForSuspendCheck,
223     kImageMethodsCount,  // Number of elements in enum.
224   };
225 
226   enum ImageRoot {
227     kDexCaches,
228     kClassRoots,
229     kSpecialRoots,                    // Different for boot image and app image, see aliases below.
230     kImageRootsMax,
231 
232     // Aliases.
233     kAppImageClassLoader = kSpecialRoots,   // The class loader used to build the app image.
234     kBootImageLiveObjects = kSpecialRoots,  // Array of boot image objects that must be kept live.
235     kAppImageOatHeader = kSpecialRoots,     // A byte array containing 1) a fake OatHeader to check
236                                             // if the image can be loaded against the current
237                                             // runtime, and 2) the dex checksums.
238   };
239 
240   enum BootImageLiveObjects {
241     kOomeWhenThrowingException,       // Pre-allocated OOME when throwing exception.
242     kOomeWhenThrowingOome,            // Pre-allocated OOME when throwing OOME.
243     kOomeWhenHandlingStackOverflow,   // Pre-allocated OOME when handling StackOverflowError.
244     kNoClassDefFoundError,            // Pre-allocated NoClassDefFoundError.
245     kClearedJniWeakSentinel,          // Pre-allocated sentinel for cleared weak JNI references.
246     kIntrinsicObjectsStart
247   };
248 
249   /*
250    * This describes the number and ordering of sections inside of Boot
251    * and App Images.  It is very important that changes to this struct
252    * are reflected in the compiler and loader.
253    *
254    * See:
255    *   - ImageWriter::ImageInfo::CreateImageSections()
256    *   - ImageWriter::Write()
257    *   - ImageWriter::AllocMemory()
258    */
259   enum ImageSections {
260     kSectionObjects,
261     kSectionArtFields,
262     kSectionArtMethods,
263     kSectionImTables,
264     kSectionIMTConflictTables,
265     kSectionRuntimeMethods,
266     kSectionJniStubMethods,
267     kSectionInternedStrings,
268     kSectionClassTable,
269     kSectionStringReferenceOffsets,
270     kSectionDexCacheArrays,
271     kSectionMetadata,
272     kSectionImageBitmap,
273     kSectionCount,  // Number of elements in enum.
274   };
275 
NumberOfImageRoots(bool app_image)276   static size_t NumberOfImageRoots([[maybe_unused]] bool app_image) {
277     // At the moment, boot image and app image have the same number of roots,
278     // though the meaning of the kSpecialRoots is different.
279     return kImageRootsMax;
280   }
281 
282   EXPORT ArtMethod* GetImageMethod(ImageMethod index) const;
283 
284   EXPORT static const char* GetImageSectionName(ImageSections index);
285 
GetImageSection(ImageSections index)286   ImageSection& GetImageSection(ImageSections index) {
287     DCHECK_LT(static_cast<size_t>(index), kSectionCount);
288     return sections_[index];
289   }
290 
GetImageSection(ImageSections index)291   const ImageSection& GetImageSection(ImageSections index) const {
292     DCHECK_LT(static_cast<size_t>(index), kSectionCount);
293     return sections_[index];
294   }
295 
GetObjectsSection()296   const ImageSection& GetObjectsSection() const {
297     return GetImageSection(kSectionObjects);
298   }
299 
GetFieldsSection()300   const ImageSection& GetFieldsSection() const {
301     return GetImageSection(ImageHeader::kSectionArtFields);
302   }
303 
GetMethodsSection()304   const ImageSection& GetMethodsSection() const {
305     return GetImageSection(kSectionArtMethods);
306   }
307 
GetRuntimeMethodsSection()308   const ImageSection& GetRuntimeMethodsSection() const {
309     return GetImageSection(kSectionRuntimeMethods);
310   }
311 
GetImTablesSection()312   const ImageSection& GetImTablesSection() const {
313     return GetImageSection(kSectionImTables);
314   }
315 
GetIMTConflictTablesSection()316   const ImageSection& GetIMTConflictTablesSection() const {
317     return GetImageSection(kSectionIMTConflictTables);
318   }
319 
GetInternedStringsSection()320   const ImageSection& GetInternedStringsSection() const {
321     return GetImageSection(kSectionInternedStrings);
322   }
323 
GetClassTableSection()324   const ImageSection& GetClassTableSection() const {
325     return GetImageSection(kSectionClassTable);
326   }
327 
GetImageStringReferenceOffsetsSection()328   const ImageSection& GetImageStringReferenceOffsetsSection() const {
329     return GetImageSection(kSectionStringReferenceOffsets);
330   }
331 
GetMetadataSection()332   const ImageSection& GetMetadataSection() const {
333     return GetImageSection(kSectionMetadata);
334   }
335 
GetJniStubMethodsSection()336   const ImageSection& GetJniStubMethodsSection() const {
337     return GetImageSection(kSectionJniStubMethods);
338   }
339 
GetImageBitmapSection()340   const ImageSection& GetImageBitmapSection() const {
341     return GetImageSection(kSectionImageBitmap);
342   }
343 
344   template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
345   ObjPtr<mirror::Object> GetImageRoot(ImageRoot image_root) const
346       REQUIRES_SHARED(Locks::mutator_lock_);
347 
348   template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
349   ObjPtr<mirror::ObjectArray<mirror::Object>> GetImageRoots() const
350       REQUIRES_SHARED(Locks::mutator_lock_);
351 
352   void RelocateImageReferences(int64_t delta);
353   void RelocateBootImageReferences(int64_t delta);
354 
GetBootImageBegin()355   uint32_t GetBootImageBegin() const {
356     return boot_image_begin_;
357   }
358 
GetBootImageSize()359   uint32_t GetBootImageSize() const {
360     return boot_image_size_;
361   }
362 
GetBootImageComponentCount()363   uint32_t GetBootImageComponentCount() const {
364     return boot_image_component_count_;
365   }
366 
GetBootImageChecksum()367   uint32_t GetBootImageChecksum() const {
368     return boot_image_checksum_;
369   }
370 
GetDataSize()371   uint64_t GetDataSize() const {
372     return data_size_;
373   }
374 
375   EXPORT bool IsAppImage() const;
376 
377   EXPORT uint32_t GetImageSpaceCount() const;
378 
379   // Visit mirror::Objects in the section starting at base.
380   // TODO: Delete base parameter if it is always equal to GetImageBegin.
381   EXPORT void VisitObjects(ObjectVisitor* visitor, uint8_t* base, PointerSize pointer_size) const
382       REQUIRES_SHARED(Locks::mutator_lock_);
383 
384   // Visit ArtMethods in the section starting at base. Includes runtime methods.
385   // TODO: Delete base parameter if it is always equal to GetImageBegin.
386   // NO_THREAD_SAFETY_ANALYSIS for template visitor pattern.
387   template <typename Visitor>
388   void VisitPackedArtMethods(const Visitor& visitor,
389                              uint8_t* base,
390                              PointerSize pointer_size) const NO_THREAD_SAFETY_ANALYSIS;
391 
392   // Visit ArtMethods in the section starting at base.
393   // TODO: Delete base parameter if it is always equal to GetImageBegin.
394   // NO_THREAD_SAFETY_ANALYSIS for template visitor pattern.
395   template <typename Visitor>
396   void VisitPackedArtFields(const Visitor& visitor, uint8_t* base) const NO_THREAD_SAFETY_ANALYSIS;
397 
398   template <typename Visitor>
399   void VisitPackedImTables(const Visitor& visitor,
400                            uint8_t* base,
401                            PointerSize pointer_size) const;
402 
403   template <typename Visitor>
404   void VisitPackedImtConflictTables(const Visitor& visitor,
405                                     uint8_t* base,
406                                     PointerSize pointer_size) const;
407 
408   template <bool kUpdate = false, typename Visitor>
409   void VisitJniStubMethods(const Visitor& visitor,
410                            uint8_t* base,
411                            PointerSize pointer_size) const REQUIRES_SHARED(Locks::mutator_lock_);
412 
GetBlocks()413   IterationRange<const Block*> GetBlocks() const {
414     return GetBlocks(GetImageBegin());
415   }
416 
GetBlocks(const uint8_t * image_begin)417   IterationRange<const Block*> GetBlocks(const uint8_t* image_begin) const {
418     const Block* begin = reinterpret_cast<const Block*>(image_begin + blocks_offset_);
419     return {begin, begin + blocks_count_};
420   }
421 
422   // Return true if the image has any compressed blocks.
HasCompressedBlock()423   bool HasCompressedBlock() const {
424     return blocks_count_ != 0u;
425   }
426 
GetBlockCount()427   uint32_t GetBlockCount() const {
428     return blocks_count_;
429   }
430 
431   // Helper for writing `data` and `bitmap_data` into `image_file`, following
432   // the information stored in this header and passed as arguments.
433   EXPORT bool WriteData(const ImageFileGuard& image_file,
434                         const uint8_t* data,
435                         const uint8_t* bitmap_data,
436                         ImageHeader::StorageMode image_storage_mode,
437                         uint32_t max_image_block_size,
438                         bool update_checksum,
439                         std::string* error_msg);
440 
441  private:
442   static const uint8_t kImageMagic[4];
443   static const uint8_t kImageVersion[4];
444 
445   uint8_t magic_[4];
446   uint8_t version_[4];
447 
448   // The total memory reservation size for the image.
449   // For boot image or boot image extension, the primary image includes the reservation
450   // for all image files and oat files, secondary images have the reservation set to 0.
451   // App images have reservation equal to `image_size_` rounded up to page size because
452   // their oat files are mmapped independently.
453   uint32_t image_reservation_size_ = 0u;
454 
455   // The number of components (jar files contributing to the image).
456   // For boot image or boot image extension, the primary image stores the total number
457   // of components, secondary images have this set to 0. App images have 1 component.
458   // The component count usually matches the total number of images (one image per component), but
459   // if multiple components are compiled with --single-image there will only be 1 image associated
460   // with those components.
461   uint32_t component_count_ = 0u;
462 
463   // Required base address for mapping the image.
464   uint32_t image_begin_ = 0u;
465 
466   // Image size, not page aligned.
467   uint32_t image_size_ = 0u;
468 
469   // Image file checksum (calculated with the checksum field set to 0).
470   uint32_t image_checksum_ = 0u;
471 
472   // Checksum of the oat file we link to for load time consistency check.
473   uint32_t oat_checksum_ = 0u;
474 
475   // Start address for oat file. Will be before oat_data_begin_ for .so files.
476   uint32_t oat_file_begin_ = 0u;
477 
478   // Required oat address expected by image Method::GetCode() pointers.
479   uint32_t oat_data_begin_ = 0u;
480 
481   // End of oat data address range for this image file.
482   uint32_t oat_data_end_ = 0u;
483 
484   // End of oat file address range. will be after oat_data_end_ for
485   // .so files. Used for positioning a following alloc spaces.
486   uint32_t oat_file_end_ = 0u;
487 
488   // Boot image begin and end (only applies to boot image extension and app image headers).
489   uint32_t boot_image_begin_ = 0u;
490   uint32_t boot_image_size_ = 0u;  // Includes heap (*.art) and code (.oat).
491 
492   // Number of boot image components that this image depends on and their composite checksum
493   // (only applies to boot image extension and app image headers).
494   uint32_t boot_image_component_count_ = 0u;
495   uint32_t boot_image_checksum_ = 0u;
496 
497   // Absolute address of an Object[] of objects needed to reinitialize from an image.
498   uint32_t image_roots_ = 0u;
499 
500   // Pointer size, this affects the size of the ArtMethods.
501   PointerSize pointer_size_;
502 
503   // Image section sizes/offsets correspond to the uncompressed form.
504   ImageSection sections_[kSectionCount];
505 
506   // Image methods, may be inside of the boot image for app images.
507   uint64_t image_methods_[kImageMethodsCount];
508 
509   // Data size for the image data excluding the bitmap and the header. For compressed images, this
510   // is the compressed size in the file.
511   uint32_t data_size_ = 0u;
512 
513   // Image blocks, only used for compressed images.
514   uint32_t blocks_offset_ = 0u;
515   uint32_t blocks_count_ = 0u;
516 
517   friend class linker::ImageWriter;
518   friend class RuntimeImageHelper;
519 };
520 
521 // Helper class that erases the image file if it isn't properly flushed and closed.
522 class ImageFileGuard {
523  public:
524   ImageFileGuard() noexcept = default;
525   ImageFileGuard(ImageFileGuard&& other) noexcept = default;
526   ImageFileGuard& operator=(ImageFileGuard&& other) noexcept = default;
527 
~ImageFileGuard()528   ~ImageFileGuard() {
529     if (image_file_ != nullptr) {
530       // Failure, erase the image file.
531       image_file_->Erase();
532     }
533   }
534 
reset(File * image_file)535   void reset(File* image_file) {
536     image_file_.reset(image_file);
537   }
538 
539   bool operator==(std::nullptr_t) {
540     return image_file_ == nullptr;
541   }
542 
543   bool operator!=(std::nullptr_t) {
544     return image_file_ != nullptr;
545   }
546 
547   File* operator->() const {
548     return image_file_.get();
549   }
550 
WriteHeaderAndClose(const std::string & image_filename,const ImageHeader * image_header,std::string * error_msg)551   bool WriteHeaderAndClose(const std::string& image_filename,
552                            const ImageHeader* image_header,
553                            std::string* error_msg) {
554     // The header is uncompressed since it contains whether the image is compressed or not.
555     if (!image_file_->PwriteFully(image_header, sizeof(ImageHeader), 0)) {
556       *error_msg = "Failed to write image file header "
557           + image_filename + ": " + std::string(strerror(errno));
558       return false;
559     }
560 
561     // FlushCloseOrErase() takes care of erasing, so the destructor does not need
562     // to do that whether the FlushCloseOrErase() succeeds or fails.
563     std::unique_ptr<File> image_file = std::move(image_file_);
564     if (image_file->FlushCloseOrErase() != 0) {
565       *error_msg = "Failed to flush and close image file "
566           + image_filename + ": " + std::string(strerror(errno));
567       return false;
568     }
569 
570     return true;
571   }
572 
573  private:
574   std::unique_ptr<File> image_file_;
575 };
576 
577 
578 /*
579  * This type holds the information necessary to fix up AppImage string
580  * references.
581  *
582  * The first element indicates the location of a managed object with a field that needs fixing up.
583  * The second element of the pair is an object-relative offset to the field in question.
584  */
585 using AppImageReferenceOffsetInfo = std::pair<uint32_t, uint32_t>;
586 
587 std::ostream& operator<<(std::ostream& os, ImageHeader::ImageMethod method);
588 std::ostream& operator<<(std::ostream& os, ImageHeader::ImageRoot root);
589 EXPORT std::ostream& operator<<(std::ostream& os, ImageHeader::ImageSections section);
590 EXPORT std::ostream& operator<<(std::ostream& os, ImageHeader::StorageMode mode);
591 
592 EXPORT std::ostream& operator<<(std::ostream& os, const ImageSection& section);
593 
594 // Wrapper over LZ4_decompress_safe() that checks if return value is negative. See b/242914915.
595 bool LZ4_decompress_safe_checked(const char* source,
596                                  char* dest,
597                                  int compressed_size,
598                                  int max_decompressed_size,
599                                  /*out*/ size_t* decompressed_size_checked,
600                                  /*out*/ std::string* error_msg);
601 
602 }  // namespace art
603 
604 #endif  // ART_RUNTIME_OAT_IMAGE_H_
605