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