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