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