Home | History | Annotate | Download | only in runtime
      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 "mirror/object.h"
     25 #include "runtime_globals.h"
     26 
     27 namespace art {
     28 
     29 class ArtField;
     30 class ArtMethod;
     31 template <class MirrorType> class ObjPtr;
     32 
     33 namespace linker {
     34 class ImageWriter;
     35 }  // namespace linker
     36 
     37 class ObjectVisitor {
     38  public:
     39   virtual ~ObjectVisitor() {}
     40 
     41   virtual void Visit(mirror::Object* object) = 0;
     42 };
     43 
     44 class PACKED(4) ImageSection {
     45  public:
     46   ImageSection() : offset_(0), size_(0) { }
     47   ImageSection(uint32_t offset, uint32_t size) : offset_(offset), size_(size) { }
     48   ImageSection(const ImageSection& section) = default;
     49   ImageSection& operator=(const ImageSection& section) = default;
     50 
     51   uint32_t Offset() const {
     52     return offset_;
     53   }
     54 
     55   uint32_t Size() const {
     56     return size_;
     57   }
     58 
     59   uint32_t End() const {
     60     return Offset() + Size();
     61   }
     62 
     63   bool Contains(uint64_t offset) const {
     64     return offset - offset_ < size_;
     65   }
     66 
     67  private:
     68   uint32_t offset_;
     69   uint32_t size_;
     70 };
     71 
     72 // Header of image files written by ImageWriter, read and validated by Space.
     73 // Packed to object alignment since the first object follows directly after the header.
     74 static_assert(kObjectAlignment == 8, "Alignment check");
     75 class PACKED(8) ImageHeader {
     76  public:
     77   enum StorageMode : uint32_t {
     78     kStorageModeUncompressed,
     79     kStorageModeLZ4,
     80     kStorageModeLZ4HC,
     81     kStorageModeCount,  // Number of elements in enum.
     82   };
     83   static constexpr StorageMode kDefaultStorageMode = kStorageModeUncompressed;
     84 
     85   // Solid block of the image. May be compressed or uncompressed.
     86   class PACKED(4) Block final {
     87    public:
     88     Block(StorageMode storage_mode,
     89           uint32_t data_offset,
     90           uint32_t data_size,
     91           uint32_t image_offset,
     92           uint32_t image_size)
     93         : storage_mode_(storage_mode),
     94           data_offset_(data_offset),
     95           data_size_(data_size),
     96           image_offset_(image_offset),
     97           image_size_(image_size) {}
     98 
     99     bool Decompress(uint8_t* out_ptr, const uint8_t* in_ptr, std::string* error_msg) const;
    100 
    101     StorageMode GetStorageMode() const {
    102       return storage_mode_;
    103     }
    104 
    105     uint32_t GetDataSize() const {
    106       return data_size_;
    107     }
    108 
    109     uint32_t GetImageSize() const {
    110       return image_size_;
    111     }
    112 
    113    private:
    114     // Storage method for the image, the image may be compressed.
    115     StorageMode storage_mode_ = kDefaultStorageMode;
    116 
    117     // Compressed offset and size.
    118     uint32_t data_offset_ = 0u;
    119     uint32_t data_size_ = 0u;
    120 
    121     // Image offset and size (decompressed or mapped location).
    122     uint32_t image_offset_ = 0u;
    123     uint32_t image_size_ = 0u;
    124   };
    125 
    126   ImageHeader() {}
    127   ImageHeader(uint32_t image_reservation_size,
    128               uint32_t component_count,
    129               uint32_t image_begin,
    130               uint32_t image_size,
    131               ImageSection* sections,
    132               uint32_t image_roots,
    133               uint32_t oat_checksum,
    134               uint32_t oat_file_begin,
    135               uint32_t oat_data_begin,
    136               uint32_t oat_data_end,
    137               uint32_t oat_file_end,
    138               uint32_t boot_image_begin,
    139               uint32_t boot_image_size,
    140               uint32_t pointer_size);
    141 
    142   bool IsValid() const;
    143   const char* GetMagic() const;
    144 
    145   uint32_t GetImageReservationSize() const {
    146     return image_reservation_size_;
    147   }
    148 
    149   uint32_t GetComponentCount() const {
    150     return component_count_;
    151   }
    152 
    153   uint8_t* GetImageBegin() const {
    154     return reinterpret_cast<uint8_t*>(image_begin_);
    155   }
    156 
    157   size_t GetImageSize() const {
    158     return image_size_;
    159   }
    160 
    161   uint32_t GetImageChecksum() const {
    162     return image_checksum_;
    163   }
    164 
    165   void SetImageChecksum(uint32_t image_checksum) {
    166     image_checksum_ = image_checksum;
    167   }
    168 
    169   uint32_t GetOatChecksum() const {
    170     return oat_checksum_;
    171   }
    172 
    173   void SetOatChecksum(uint32_t oat_checksum) {
    174     oat_checksum_ = oat_checksum;
    175   }
    176 
    177   // The location that the oat file was expected to be when the image was created. The actual
    178   // oat file may be at a different location for application images.
    179   uint8_t* GetOatFileBegin() const {
    180     return reinterpret_cast<uint8_t*>(oat_file_begin_);
    181   }
    182 
    183   uint8_t* GetOatDataBegin() const {
    184     return reinterpret_cast<uint8_t*>(oat_data_begin_);
    185   }
    186 
    187   uint8_t* GetOatDataEnd() const {
    188     return reinterpret_cast<uint8_t*>(oat_data_end_);
    189   }
    190 
    191   uint8_t* GetOatFileEnd() const {
    192     return reinterpret_cast<uint8_t*>(oat_file_end_);
    193   }
    194 
    195   PointerSize GetPointerSize() const;
    196 
    197   uint32_t GetPointerSizeUnchecked() const {
    198     return pointer_size_;
    199   }
    200 
    201   static std::string GetOatLocationFromImageLocation(const std::string& image) {
    202     return GetLocationFromImageLocation(image, "oat");
    203   }
    204 
    205   static std::string GetVdexLocationFromImageLocation(const std::string& image) {
    206     return GetLocationFromImageLocation(image, "vdex");
    207   }
    208 
    209   enum ImageMethod {
    210     kResolutionMethod,
    211     kImtConflictMethod,
    212     kImtUnimplementedMethod,
    213     kSaveAllCalleeSavesMethod,
    214     kSaveRefsOnlyMethod,
    215     kSaveRefsAndArgsMethod,
    216     kSaveEverythingMethod,
    217     kSaveEverythingMethodForClinit,
    218     kSaveEverythingMethodForSuspendCheck,
    219     kImageMethodsCount,  // Number of elements in enum.
    220   };
    221 
    222   enum ImageRoot {
    223     kDexCaches,
    224     kClassRoots,
    225     kOomeWhenThrowingException,       // Pre-allocated OOME when throwing exception.
    226     kOomeWhenThrowingOome,            // Pre-allocated OOME when throwing OOME.
    227     kOomeWhenHandlingStackOverflow,   // Pre-allocated OOME when handling StackOverflowError.
    228     kNoClassDefFoundError,            // Pre-allocated NoClassDefFoundError.
    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   };
    236 
    237   /*
    238    * This describes the number and ordering of sections inside of Boot
    239    * and App Images.  It is very important that changes to this struct
    240    * are reflected in the compiler and loader.
    241    *
    242    * See:
    243    *   - ImageWriter::ImageInfo::CreateImageSections()
    244    *   - ImageWriter::Write()
    245    *   - ImageWriter::AllocMemory()
    246    */
    247   enum ImageSections {
    248     kSectionObjects,
    249     kSectionArtFields,
    250     kSectionArtMethods,
    251     kSectionRuntimeMethods,
    252     kSectionImTables,
    253     kSectionIMTConflictTables,
    254     kSectionDexCacheArrays,
    255     kSectionInternedStrings,
    256     kSectionClassTable,
    257     kSectionStringReferenceOffsets,
    258     kSectionMetadata,
    259     kSectionImageBitmap,
    260     kSectionCount,  // Number of elements in enum.
    261   };
    262 
    263   static size_t NumberOfImageRoots(bool app_image ATTRIBUTE_UNUSED) {
    264     // At the moment, boot image and app image have the same number of roots,
    265     // though the meaning of the kSpecialRoots is different.
    266     return kImageRootsMax;
    267   }
    268 
    269   ArtMethod* GetImageMethod(ImageMethod index) const;
    270 
    271   ImageSection& GetImageSection(ImageSections index) {
    272     DCHECK_LT(static_cast<size_t>(index), kSectionCount);
    273     return sections_[index];
    274   }
    275 
    276   const ImageSection& GetImageSection(ImageSections index) const {
    277     DCHECK_LT(static_cast<size_t>(index), kSectionCount);
    278     return sections_[index];
    279   }
    280 
    281   const ImageSection& GetObjectsSection() const {
    282     return GetImageSection(kSectionObjects);
    283   }
    284 
    285   const ImageSection& GetFieldsSection() const {
    286     return GetImageSection(ImageHeader::kSectionArtFields);
    287   }
    288 
    289   const ImageSection& GetMethodsSection() const {
    290     return GetImageSection(kSectionArtMethods);
    291   }
    292 
    293   const ImageSection& GetRuntimeMethodsSection() const {
    294     return GetImageSection(kSectionRuntimeMethods);
    295   }
    296 
    297   const ImageSection& GetImTablesSection() const {
    298     return GetImageSection(kSectionImTables);
    299   }
    300 
    301   const ImageSection& GetIMTConflictTablesSection() const {
    302     return GetImageSection(kSectionIMTConflictTables);
    303   }
    304 
    305   const ImageSection& GetDexCacheArraysSection() const {
    306     return GetImageSection(kSectionDexCacheArrays);
    307   }
    308 
    309   const ImageSection& GetInternedStringsSection() const {
    310     return GetImageSection(kSectionInternedStrings);
    311   }
    312 
    313   const ImageSection& GetClassTableSection() const {
    314     return GetImageSection(kSectionClassTable);
    315   }
    316 
    317   const ImageSection& GetImageStringReferenceOffsetsSection() const {
    318     return GetImageSection(kSectionStringReferenceOffsets);
    319   }
    320 
    321   const ImageSection& GetMetadataSection() const {
    322     return GetImageSection(kSectionMetadata);
    323   }
    324 
    325   const ImageSection& GetImageBitmapSection() const {
    326     return GetImageSection(kSectionImageBitmap);
    327   }
    328 
    329   template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
    330   ObjPtr<mirror::Object> GetImageRoot(ImageRoot image_root) const
    331       REQUIRES_SHARED(Locks::mutator_lock_);
    332 
    333   template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
    334   ObjPtr<mirror::ObjectArray<mirror::Object>> GetImageRoots() const
    335       REQUIRES_SHARED(Locks::mutator_lock_);
    336 
    337   void RelocateImage(int64_t delta);
    338   void RelocateImageMethods(int64_t delta);
    339   void RelocateImageObjects(int64_t delta);
    340 
    341   uint32_t GetBootImageBegin() const {
    342     return boot_image_begin_;
    343   }
    344 
    345   uint32_t GetBootImageSize() const {
    346     return boot_image_size_;
    347   }
    348 
    349   uint64_t GetDataSize() const {
    350     return data_size_;
    351   }
    352 
    353   bool IsAppImage() const {
    354     // App images currently require a boot image, if the size is non zero then it is an app image
    355     // header.
    356     return boot_image_size_ != 0u;
    357   }
    358 
    359   // Visit mirror::Objects in the section starting at base.
    360   // TODO: Delete base parameter if it is always equal to GetImageBegin.
    361   void VisitObjects(ObjectVisitor* visitor,
    362                     uint8_t* base,
    363                     PointerSize pointer_size) const
    364       REQUIRES_SHARED(Locks::mutator_lock_);
    365 
    366   // Visit ArtMethods in the section starting at base. Includes runtime methods.
    367   // TODO: Delete base parameter if it is always equal to GetImageBegin.
    368   // NO_THREAD_SAFETY_ANALYSIS for template visitor pattern.
    369   template <typename Visitor>
    370   void VisitPackedArtMethods(const Visitor& visitor,
    371                              uint8_t* base,
    372                              PointerSize pointer_size) const NO_THREAD_SAFETY_ANALYSIS;
    373 
    374   // Visit ArtMethods in the section starting at base.
    375   // TODO: Delete base parameter if it is always equal to GetImageBegin.
    376   // NO_THREAD_SAFETY_ANALYSIS for template visitor pattern.
    377   template <typename Visitor>
    378   void VisitPackedArtFields(const Visitor& visitor, uint8_t* base) const NO_THREAD_SAFETY_ANALYSIS;
    379 
    380   template <typename Visitor>
    381   void VisitPackedImTables(const Visitor& visitor,
    382                            uint8_t* base,
    383                            PointerSize pointer_size) const;
    384 
    385   template <typename Visitor>
    386   void VisitPackedImtConflictTables(const Visitor& visitor,
    387                                     uint8_t* base,
    388                                     PointerSize pointer_size) const;
    389 
    390   IterationRange<const Block*> GetBlocks() const {
    391     return GetBlocks(GetImageBegin());
    392   }
    393 
    394   IterationRange<const Block*> GetBlocks(const uint8_t* image_begin) const {
    395     const Block* begin = reinterpret_cast<const Block*>(image_begin + blocks_offset_);
    396     return {begin, begin + blocks_count_};
    397   }
    398 
    399   // Return true if the image has any compressed blocks.
    400   bool HasCompressedBlock() const {
    401     return blocks_count_ != 0u;
    402   }
    403 
    404   uint32_t GetBlockCount() const {
    405     return blocks_count_;
    406   }
    407 
    408  private:
    409   static const uint8_t kImageMagic[4];
    410   static const uint8_t kImageVersion[4];
    411 
    412   static std::string GetLocationFromImageLocation(const std::string& image,
    413                                                   const std::string& extension) {
    414     std::string filename = image;
    415     if (filename.length() <= 3) {
    416       filename += "." + extension;
    417     } else {
    418       filename.replace(filename.length() - 3, 3, extension);
    419     }
    420     return filename;
    421   }
    422 
    423   uint8_t magic_[4];
    424   uint8_t version_[4];
    425 
    426   // The total memory reservation size for the image.
    427   // For boot image or boot image extension, the primary image includes the reservation
    428   // for all image files and oat files, secondary images have the reservation set to 0.
    429   // App images have reservation equal to `image_size_` rounded up to page size because
    430   // their oat files are mmapped independently.
    431   uint32_t image_reservation_size_ = 0u;
    432 
    433   // The number of components.
    434   // For boot image or boot image extension, the primary image stores the total number
    435   // of images, secondary images have this set to 0.
    436   // App images have 1 component.
    437   uint32_t component_count_ = 0u;
    438 
    439   // Required base address for mapping the image.
    440   uint32_t image_begin_ = 0u;
    441 
    442   // Image size, not page aligned.
    443   uint32_t image_size_ = 0u;
    444 
    445   // Image file checksum (calculated with the checksum field set to 0).
    446   uint32_t image_checksum_ = 0u;
    447 
    448   // Checksum of the oat file we link to for load time sanity check.
    449   uint32_t oat_checksum_ = 0u;
    450 
    451   // Start address for oat file. Will be before oat_data_begin_ for .so files.
    452   uint32_t oat_file_begin_ = 0u;
    453 
    454   // Required oat address expected by image Method::GetCode() pointers.
    455   uint32_t oat_data_begin_ = 0u;
    456 
    457   // End of oat data address range for this image file.
    458   uint32_t oat_data_end_ = 0u;
    459 
    460   // End of oat file address range. will be after oat_data_end_ for
    461   // .so files. Used for positioning a following alloc spaces.
    462   uint32_t oat_file_end_ = 0u;
    463 
    464   // Boot image begin and end (app image headers only).
    465   uint32_t boot_image_begin_ = 0u;
    466   uint32_t boot_image_size_ = 0u;  // Includes heap (*.art) and code (.oat).
    467 
    468   // Absolute address of an Object[] of objects needed to reinitialize from an image.
    469   uint32_t image_roots_ = 0u;
    470 
    471   // Pointer size, this affects the size of the ArtMethods.
    472   uint32_t pointer_size_ = 0u;
    473 
    474   // Image section sizes/offsets correspond to the uncompressed form.
    475   ImageSection sections_[kSectionCount];
    476 
    477   // Image methods, may be inside of the boot image for app images.
    478   uint64_t image_methods_[kImageMethodsCount];
    479 
    480   // Data size for the image data excluding the bitmap and the header. For compressed images, this
    481   // is the compressed size in the file.
    482   uint32_t data_size_ = 0u;
    483 
    484   // Image blocks, only used for compressed images.
    485   uint32_t blocks_offset_ = 0u;
    486   uint32_t blocks_count_ = 0u;
    487 
    488   friend class linker::ImageWriter;
    489 };
    490 
    491 /*
    492  * This type holds the information necessary to fix up AppImage string
    493  * references.
    494  *
    495  * The first element of the pair is an offset into the image space.  If the
    496  * offset is tagged (testable using HasDexCacheNativeRefTag) it indicates the location
    497  * of a DexCache object that has one or more native references to managed
    498  * strings that need to be fixed up.  In this case the second element has no
    499  * meaningful value.
    500  *
    501  * If the first element isn't tagged then it indicates the location of a
    502  * managed object with a field that needs fixing up.  In this case the second
    503  * element of the pair is an object-relative offset to the field in question.
    504  */
    505 typedef std::pair<uint32_t, uint32_t> AppImageReferenceOffsetInfo;
    506 
    507 /*
    508  * Tags the last bit.  Used by AppImage logic to differentiate between pointers
    509  * to managed objects and pointers to native reference arrays.
    510  */
    511 template<typename T>
    512 T SetDexCacheStringNativeRefTag(T val) {
    513   static_assert(std::is_integral<T>::value, "Expected integral type.");
    514 
    515   return val | 1u;
    516 }
    517 
    518 /*
    519  * Tags the second last bit.  Used by AppImage logic to differentiate between pointers
    520  * to managed objects and pointers to native reference arrays.
    521  */
    522 template<typename T>
    523 T SetDexCachePreResolvedStringNativeRefTag(T val) {
    524   static_assert(std::is_integral<T>::value, "Expected integral type.");
    525 
    526   return val | 2u;
    527 }
    528 
    529 /*
    530  * Retrieves the value of the last bit.  Used by AppImage logic to
    531  * differentiate between pointers to managed objects and pointers to native
    532  * reference arrays.
    533  */
    534 template<typename T>
    535 bool HasDexCacheStringNativeRefTag(T val) {
    536   static_assert(std::is_integral<T>::value, "Expected integral type.");
    537 
    538   return (val & 1u) != 0u;
    539 }
    540 
    541 /*
    542  * Retrieves the value of the second last bit.  Used by AppImage logic to
    543  * differentiate between pointers to managed objects and pointers to native
    544  * reference arrays.
    545  */
    546 template<typename T>
    547 bool HasDexCachePreResolvedStringNativeRefTag(T val) {
    548   static_assert(std::is_integral<T>::value, "Expected integral type.");
    549 
    550   return (val & 2u) != 0u;
    551 }
    552 
    553 /*
    554  * Sets the last bit of the value to 0.  Used by AppImage logic to
    555  * differentiate between pointers to managed objects and pointers to native
    556  * reference arrays.
    557  */
    558 template<typename T>
    559 T ClearDexCacheNativeRefTags(T val) {
    560   static_assert(std::is_integral<T>::value, "Expected integral type.");
    561 
    562   return val & ~3u;
    563 }
    564 
    565 std::ostream& operator<<(std::ostream& os, const ImageHeader::ImageMethod& policy);
    566 std::ostream& operator<<(std::ostream& os, const ImageHeader::ImageRoot& policy);
    567 std::ostream& operator<<(std::ostream& os, const ImageHeader::ImageSections& section);
    568 std::ostream& operator<<(std::ostream& os, const ImageSection& section);
    569 std::ostream& operator<<(std::ostream& os, const ImageHeader::StorageMode& mode);
    570 
    571 }  // namespace art
    572 
    573 #endif  // ART_RUNTIME_IMAGE_H_
    574