• 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 "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:
~ObjectVisitor()39   virtual ~ObjectVisitor() {}
40 
41   virtual void Visit(mirror::Object* object) = 0;
42 };
43 
44 class PACKED(4) ImageSection {
45  public:
ImageSection()46   ImageSection() : offset_(0), size_(0) { }
ImageSection(uint32_t offset,uint32_t size)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 
Offset()51   uint32_t Offset() const {
52     return offset_;
53   }
54 
Size()55   uint32_t Size() const {
56     return size_;
57   }
58 
End()59   uint32_t End() const {
60     return Offset() + Size();
61   }
62 
Contains(uint64_t offset)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:
Block(StorageMode storage_mode,uint32_t data_offset,uint32_t data_size,uint32_t image_offset,uint32_t image_size)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 
GetStorageMode()101     StorageMode GetStorageMode() const {
102       return storage_mode_;
103     }
104 
GetDataSize()105     uint32_t GetDataSize() const {
106       return data_size_;
107     }
108 
GetImageSize()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 
ImageHeader()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 
GetImageReservationSize()145   uint32_t GetImageReservationSize() const {
146     return image_reservation_size_;
147   }
148 
GetComponentCount()149   uint32_t GetComponentCount() const {
150     return component_count_;
151   }
152 
GetImageBegin()153   uint8_t* GetImageBegin() const {
154     return reinterpret_cast<uint8_t*>(image_begin_);
155   }
156 
GetImageSize()157   size_t GetImageSize() const {
158     return image_size_;
159   }
160 
GetImageChecksum()161   uint32_t GetImageChecksum() const {
162     return image_checksum_;
163   }
164 
SetImageChecksum(uint32_t image_checksum)165   void SetImageChecksum(uint32_t image_checksum) {
166     image_checksum_ = image_checksum;
167   }
168 
GetOatChecksum()169   uint32_t GetOatChecksum() const {
170     return oat_checksum_;
171   }
172 
SetOatChecksum(uint32_t oat_checksum)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.
GetOatFileBegin()179   uint8_t* GetOatFileBegin() const {
180     return reinterpret_cast<uint8_t*>(oat_file_begin_);
181   }
182 
GetOatDataBegin()183   uint8_t* GetOatDataBegin() const {
184     return reinterpret_cast<uint8_t*>(oat_data_begin_);
185   }
186 
GetOatDataEnd()187   uint8_t* GetOatDataEnd() const {
188     return reinterpret_cast<uint8_t*>(oat_data_end_);
189   }
190 
GetOatFileEnd()191   uint8_t* GetOatFileEnd() const {
192     return reinterpret_cast<uint8_t*>(oat_file_end_);
193   }
194 
195   PointerSize GetPointerSize() const;
196 
GetPointerSizeUnchecked()197   uint32_t GetPointerSizeUnchecked() const {
198     return pointer_size_;
199   }
200 
GetOatLocationFromImageLocation(const std::string & image)201   static std::string GetOatLocationFromImageLocation(const std::string& image) {
202     return GetLocationFromImageLocation(image, "oat");
203   }
204 
GetVdexLocationFromImageLocation(const std::string & image)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 
NumberOfImageRoots(bool app_image ATTRIBUTE_UNUSED)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 
GetImageSection(ImageSections index)271   ImageSection& GetImageSection(ImageSections index) {
272     DCHECK_LT(static_cast<size_t>(index), kSectionCount);
273     return sections_[index];
274   }
275 
GetImageSection(ImageSections index)276   const ImageSection& GetImageSection(ImageSections index) const {
277     DCHECK_LT(static_cast<size_t>(index), kSectionCount);
278     return sections_[index];
279   }
280 
GetObjectsSection()281   const ImageSection& GetObjectsSection() const {
282     return GetImageSection(kSectionObjects);
283   }
284 
GetFieldsSection()285   const ImageSection& GetFieldsSection() const {
286     return GetImageSection(ImageHeader::kSectionArtFields);
287   }
288 
GetMethodsSection()289   const ImageSection& GetMethodsSection() const {
290     return GetImageSection(kSectionArtMethods);
291   }
292 
GetRuntimeMethodsSection()293   const ImageSection& GetRuntimeMethodsSection() const {
294     return GetImageSection(kSectionRuntimeMethods);
295   }
296 
GetImTablesSection()297   const ImageSection& GetImTablesSection() const {
298     return GetImageSection(kSectionImTables);
299   }
300 
GetIMTConflictTablesSection()301   const ImageSection& GetIMTConflictTablesSection() const {
302     return GetImageSection(kSectionIMTConflictTables);
303   }
304 
GetDexCacheArraysSection()305   const ImageSection& GetDexCacheArraysSection() const {
306     return GetImageSection(kSectionDexCacheArrays);
307   }
308 
GetInternedStringsSection()309   const ImageSection& GetInternedStringsSection() const {
310     return GetImageSection(kSectionInternedStrings);
311   }
312 
GetClassTableSection()313   const ImageSection& GetClassTableSection() const {
314     return GetImageSection(kSectionClassTable);
315   }
316 
GetImageStringReferenceOffsetsSection()317   const ImageSection& GetImageStringReferenceOffsetsSection() const {
318     return GetImageSection(kSectionStringReferenceOffsets);
319   }
320 
GetMetadataSection()321   const ImageSection& GetMetadataSection() const {
322     return GetImageSection(kSectionMetadata);
323   }
324 
GetImageBitmapSection()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 
GetBootImageBegin()341   uint32_t GetBootImageBegin() const {
342     return boot_image_begin_;
343   }
344 
GetBootImageSize()345   uint32_t GetBootImageSize() const {
346     return boot_image_size_;
347   }
348 
GetDataSize()349   uint64_t GetDataSize() const {
350     return data_size_;
351   }
352 
IsAppImage()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 
GetBlocks()390   IterationRange<const Block*> GetBlocks() const {
391     return GetBlocks(GetImageBegin());
392   }
393 
GetBlocks(const uint8_t * image_begin)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.
HasCompressedBlock()400   bool HasCompressedBlock() const {
401     return blocks_count_ != 0u;
402   }
403 
GetBlockCount()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 
GetLocationFromImageLocation(const std::string & image,const std::string & extension)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>
SetDexCacheStringNativeRefTag(T val)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>
SetDexCachePreResolvedStringNativeRefTag(T val)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>
HasDexCacheStringNativeRefTag(T val)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>
HasDexCachePreResolvedStringNativeRefTag(T val)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>
ClearDexCacheNativeRefTags(T val)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