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 "globals.h"
     24 #include "mirror/object.h"
     25 
     26 namespace art {
     27 
     28 class ArtField;
     29 class ArtMethod;
     30 
     31 class ArtMethodVisitor {
     32  public:
     33   virtual ~ArtMethodVisitor() {}
     34 
     35   virtual void Visit(ArtMethod* method) = 0;
     36 };
     37 
     38 class ArtFieldVisitor {
     39  public:
     40   virtual ~ArtFieldVisitor() {}
     41 
     42   virtual void Visit(ArtField* method) = 0;
     43 };
     44 
     45 class PACKED(4) ImageSection {
     46  public:
     47   ImageSection() : offset_(0), size_(0) { }
     48   ImageSection(uint32_t offset, uint32_t size) : offset_(offset), size_(size) { }
     49   ImageSection(const ImageSection& section) = default;
     50   ImageSection& operator=(const ImageSection& section) = default;
     51 
     52   uint32_t Offset() const {
     53     return offset_;
     54   }
     55 
     56   uint32_t Size() const {
     57     return size_;
     58   }
     59 
     60   uint32_t End() const {
     61     return Offset() + Size();
     62   }
     63 
     64   bool Contains(uint64_t offset) const {
     65     return offset - offset_ < size_;
     66   }
     67 
     68  private:
     69   uint32_t offset_;
     70   uint32_t size_;
     71 };
     72 
     73 // header of image files written by ImageWriter, read and validated by Space.
     74 class PACKED(4) ImageHeader {
     75  public:
     76   enum StorageMode : uint32_t {
     77     kStorageModeUncompressed,
     78     kStorageModeLZ4,
     79     kStorageModeLZ4HC,
     80     kStorageModeCount,  // Number of elements in enum.
     81   };
     82   static constexpr StorageMode kDefaultStorageMode = kStorageModeUncompressed;
     83 
     84   ImageHeader()
     85       : image_begin_(0U),
     86         image_size_(0U),
     87         oat_checksum_(0U),
     88         oat_file_begin_(0U),
     89         oat_data_begin_(0U),
     90         oat_data_end_(0U),
     91         oat_file_end_(0U),
     92         boot_image_begin_(0U),
     93         boot_image_size_(0U),
     94         boot_oat_begin_(0U),
     95         boot_oat_size_(0U),
     96         patch_delta_(0),
     97         image_roots_(0U),
     98         pointer_size_(0U),
     99         compile_pic_(0),
    100         is_pic_(0),
    101         storage_mode_(kDefaultStorageMode),
    102         data_size_(0) {}
    103 
    104   ImageHeader(uint32_t image_begin,
    105               uint32_t image_size,
    106               ImageSection* sections,
    107               uint32_t image_roots,
    108               uint32_t oat_checksum,
    109               uint32_t oat_file_begin,
    110               uint32_t oat_data_begin,
    111               uint32_t oat_data_end,
    112               uint32_t oat_file_end,
    113               uint32_t boot_image_begin,
    114               uint32_t boot_image_size,
    115               uint32_t boot_oat_begin,
    116               uint32_t boot_oat_size,
    117               uint32_t pointer_size,
    118               bool compile_pic,
    119               bool is_pic,
    120               StorageMode storage_mode,
    121               size_t data_size);
    122 
    123   bool IsValid() const;
    124   const char* GetMagic() const;
    125 
    126   uint8_t* GetImageBegin() const {
    127     return reinterpret_cast<uint8_t*>(image_begin_);
    128   }
    129 
    130   size_t GetImageSize() const {
    131     return static_cast<uint32_t>(image_size_);
    132   }
    133 
    134   uint32_t GetOatChecksum() const {
    135     return oat_checksum_;
    136   }
    137 
    138   void SetOatChecksum(uint32_t oat_checksum) {
    139     oat_checksum_ = oat_checksum;
    140   }
    141 
    142   // The location that the oat file was expected to be when the image was created. The actual
    143   // oat file may be at a different location for application images.
    144   uint8_t* GetOatFileBegin() const {
    145     return reinterpret_cast<uint8_t*>(oat_file_begin_);
    146   }
    147 
    148   uint8_t* GetOatDataBegin() const {
    149     return reinterpret_cast<uint8_t*>(oat_data_begin_);
    150   }
    151 
    152   uint8_t* GetOatDataEnd() const {
    153     return reinterpret_cast<uint8_t*>(oat_data_end_);
    154   }
    155 
    156   uint8_t* GetOatFileEnd() const {
    157     return reinterpret_cast<uint8_t*>(oat_file_end_);
    158   }
    159 
    160   PointerSize GetPointerSize() const;
    161 
    162   uint32_t GetPointerSizeUnchecked() const {
    163     return pointer_size_;
    164   }
    165 
    166   off_t GetPatchDelta() const {
    167     return patch_delta_;
    168   }
    169 
    170   static std::string GetOatLocationFromImageLocation(const std::string& image) {
    171     return GetLocationFromImageLocation(image, "oat");
    172   }
    173 
    174   static std::string GetVdexLocationFromImageLocation(const std::string& image) {
    175     return GetLocationFromImageLocation(image, "vdex");
    176   }
    177 
    178   enum ImageMethod {
    179     kResolutionMethod,
    180     kImtConflictMethod,
    181     kImtUnimplementedMethod,
    182     kSaveAllCalleeSavesMethod,
    183     kSaveRefsOnlyMethod,
    184     kSaveRefsAndArgsMethod,
    185     kSaveEverythingMethod,
    186     kImageMethodsCount,  // Number of elements in enum.
    187   };
    188 
    189   enum ImageRoot {
    190     kDexCaches,
    191     kClassRoots,
    192     kClassLoader,  // App image only.
    193     kImageRootsMax,
    194   };
    195 
    196   enum ImageSections {
    197     kSectionObjects,
    198     kSectionArtFields,
    199     kSectionArtMethods,
    200     kSectionRuntimeMethods,
    201     kSectionImTables,
    202     kSectionIMTConflictTables,
    203     kSectionDexCacheArrays,
    204     kSectionInternedStrings,
    205     kSectionClassTable,
    206     kSectionImageBitmap,
    207     kSectionCount,  // Number of elements in enum.
    208   };
    209 
    210   static size_t NumberOfImageRoots(bool app_image) {
    211     return app_image ? kImageRootsMax : kImageRootsMax - 1u;
    212   }
    213 
    214   ArtMethod* GetImageMethod(ImageMethod index) const;
    215   void SetImageMethod(ImageMethod index, ArtMethod* method);
    216 
    217   const ImageSection& GetImageSection(ImageSections index) const;
    218 
    219   const ImageSection& GetMethodsSection() const {
    220     return GetImageSection(kSectionArtMethods);
    221   }
    222 
    223   const ImageSection& GetRuntimeMethodsSection() const {
    224     return GetImageSection(kSectionRuntimeMethods);
    225   }
    226 
    227   const ImageSection& GetFieldsSection() const {
    228     return GetImageSection(ImageHeader::kSectionArtFields);
    229   }
    230 
    231   template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
    232   mirror::Object* GetImageRoot(ImageRoot image_root) const
    233       REQUIRES_SHARED(Locks::mutator_lock_);
    234 
    235   template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
    236   mirror::ObjectArray<mirror::Object>* GetImageRoots() const
    237       REQUIRES_SHARED(Locks::mutator_lock_);
    238 
    239   void RelocateImage(off_t delta);
    240   void RelocateImageMethods(off_t delta);
    241   void RelocateImageObjects(off_t delta);
    242 
    243   bool CompilePic() const {
    244     return compile_pic_ != 0;
    245   }
    246 
    247   bool IsPic() const {
    248     return is_pic_ != 0;
    249   }
    250 
    251   uint32_t GetBootImageBegin() const {
    252     return boot_image_begin_;
    253   }
    254 
    255   uint32_t GetBootImageSize() const {
    256     return boot_image_size_;
    257   }
    258 
    259   uint32_t GetBootOatBegin() const {
    260     return boot_oat_begin_;
    261   }
    262 
    263   uint32_t GetBootOatSize() const {
    264     return boot_oat_size_;
    265   }
    266 
    267   StorageMode GetStorageMode() const {
    268     return storage_mode_;
    269   }
    270 
    271   uint64_t GetDataSize() const {
    272     return data_size_;
    273   }
    274 
    275   bool IsAppImage() const {
    276     // App images currently require a boot image, if the size is non zero then it is an app image
    277     // header.
    278     return boot_image_size_ != 0u;
    279   }
    280 
    281   // Visit ArtMethods in the section starting at base. Includes runtime methods.
    282   // TODO: Delete base parameter if it is always equal to GetImageBegin.
    283   void VisitPackedArtMethods(ArtMethodVisitor* visitor,
    284                              uint8_t* base,
    285                              PointerSize pointer_size) const;
    286 
    287   // Visit ArtMethods in the section starting at base.
    288   // TODO: Delete base parameter if it is always equal to GetImageBegin.
    289   void VisitPackedArtFields(ArtFieldVisitor* visitor, uint8_t* base) const;
    290 
    291   template <typename Visitor>
    292   void VisitPackedImTables(const Visitor& visitor,
    293                            uint8_t* base,
    294                            PointerSize pointer_size) const;
    295 
    296   template <typename Visitor>
    297   void VisitPackedImtConflictTables(const Visitor& visitor,
    298                                     uint8_t* base,
    299                                     PointerSize pointer_size) const;
    300 
    301  private:
    302   static const uint8_t kImageMagic[4];
    303   static const uint8_t kImageVersion[4];
    304 
    305   static std::string GetLocationFromImageLocation(const std::string& image,
    306                                                   const std::string& extension) {
    307     std::string filename = image;
    308     if (filename.length() <= 3) {
    309       filename += "." + extension;
    310     } else {
    311       filename.replace(filename.length() - 3, 3, extension);
    312     }
    313     return filename;
    314   }
    315 
    316   uint8_t magic_[4];
    317   uint8_t version_[4];
    318 
    319   // Required base address for mapping the image.
    320   uint32_t image_begin_;
    321 
    322   // Image size, not page aligned.
    323   uint32_t image_size_;
    324 
    325   // Checksum of the oat file we link to for load time sanity check.
    326   uint32_t oat_checksum_;
    327 
    328   // Start address for oat file. Will be before oat_data_begin_ for .so files.
    329   uint32_t oat_file_begin_;
    330 
    331   // Required oat address expected by image Method::GetCode() pointers.
    332   uint32_t oat_data_begin_;
    333 
    334   // End of oat data address range for this image file.
    335   uint32_t oat_data_end_;
    336 
    337   // End of oat file address range. will be after oat_data_end_ for
    338   // .so files. Used for positioning a following alloc spaces.
    339   uint32_t oat_file_end_;
    340 
    341   // Boot image begin and end (app image headers only).
    342   uint32_t boot_image_begin_;
    343   uint32_t boot_image_size_;
    344 
    345   // Boot oat begin and end (app image headers only).
    346   uint32_t boot_oat_begin_;
    347   uint32_t boot_oat_size_;
    348 
    349   // TODO: We should probably insert a boot image checksum for app images.
    350 
    351   // The total delta that this image has been patched.
    352   int32_t patch_delta_;
    353 
    354   // Absolute address of an Object[] of objects needed to reinitialize from an image.
    355   uint32_t image_roots_;
    356 
    357   // Pointer size, this affects the size of the ArtMethods.
    358   uint32_t pointer_size_;
    359 
    360   // Boolean (0 or 1) to denote if the image was compiled with --compile-pic option
    361   const uint32_t compile_pic_;
    362 
    363   // Boolean (0 or 1) to denote if the image can be mapped at a random address, this only refers to
    364   // the .art file. Currently, app oat files do not depend on their app image. There are no pointers
    365   // from the app oat code to the app image.
    366   const uint32_t is_pic_;
    367 
    368   // Image section sizes/offsets correspond to the uncompressed form.
    369   ImageSection sections_[kSectionCount];
    370 
    371   // Image methods, may be inside of the boot image for app images.
    372   uint64_t image_methods_[kImageMethodsCount];
    373 
    374   // Storage method for the image, the image may be compressed.
    375   StorageMode storage_mode_;
    376 
    377   // Data size for the image data excluding the bitmap and the header. For compressed images, this
    378   // is the compressed size in the file.
    379   uint32_t data_size_;
    380 
    381   friend class ImageWriter;
    382 };
    383 
    384 std::ostream& operator<<(std::ostream& os, const ImageHeader::ImageMethod& policy);
    385 std::ostream& operator<<(std::ostream& os, const ImageHeader::ImageRoot& policy);
    386 std::ostream& operator<<(std::ostream& os, const ImageHeader::ImageSections& section);
    387 std::ostream& operator<<(std::ostream& os, const ImageSection& section);
    388 std::ostream& operator<<(std::ostream& os, const ImageHeader::StorageMode& mode);
    389 
    390 }  // namespace art
    391 
    392 #endif  // ART_RUNTIME_IMAGE_H_
    393