• 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 boot_image_component_count,
141               uint32_t boot_image_checksum,
142               uint32_t pointer_size);
143 
144   bool IsValid() const;
145   const char* GetMagic() const;
146 
GetImageReservationSize()147   uint32_t GetImageReservationSize() const {
148     return image_reservation_size_;
149   }
150 
GetComponentCount()151   uint32_t GetComponentCount() const {
152     return component_count_;
153   }
154 
GetImageBegin()155   uint8_t* GetImageBegin() const {
156     return reinterpret_cast<uint8_t*>(image_begin_);
157   }
158 
GetImageSize()159   size_t GetImageSize() const {
160     return image_size_;
161   }
162 
GetImageChecksum()163   uint32_t GetImageChecksum() const {
164     return image_checksum_;
165   }
166 
SetImageChecksum(uint32_t image_checksum)167   void SetImageChecksum(uint32_t image_checksum) {
168     image_checksum_ = image_checksum;
169   }
170 
GetOatChecksum()171   uint32_t GetOatChecksum() const {
172     return oat_checksum_;
173   }
174 
SetOatChecksum(uint32_t oat_checksum)175   void SetOatChecksum(uint32_t oat_checksum) {
176     oat_checksum_ = oat_checksum;
177   }
178 
179   // The location that the oat file was expected to be when the image was created. The actual
180   // oat file may be at a different location for application images.
GetOatFileBegin()181   uint8_t* GetOatFileBegin() const {
182     return reinterpret_cast<uint8_t*>(oat_file_begin_);
183   }
184 
GetOatDataBegin()185   uint8_t* GetOatDataBegin() const {
186     return reinterpret_cast<uint8_t*>(oat_data_begin_);
187   }
188 
GetOatDataEnd()189   uint8_t* GetOatDataEnd() const {
190     return reinterpret_cast<uint8_t*>(oat_data_end_);
191   }
192 
GetOatFileEnd()193   uint8_t* GetOatFileEnd() const {
194     return reinterpret_cast<uint8_t*>(oat_file_end_);
195   }
196 
197   PointerSize GetPointerSize() const;
198 
GetPointerSizeUnchecked()199   uint32_t GetPointerSizeUnchecked() const {
200     return pointer_size_;
201   }
202 
GetOatLocationFromImageLocation(const std::string & image)203   static std::string GetOatLocationFromImageLocation(const std::string& image) {
204     return GetLocationFromImageLocation(image, "oat");
205   }
206 
GetVdexLocationFromImageLocation(const std::string & image)207   static std::string GetVdexLocationFromImageLocation(const std::string& image) {
208     return GetLocationFromImageLocation(image, "vdex");
209   }
210 
211   enum ImageMethod {
212     kResolutionMethod,
213     kImtConflictMethod,
214     kImtUnimplementedMethod,
215     kSaveAllCalleeSavesMethod,
216     kSaveRefsOnlyMethod,
217     kSaveRefsAndArgsMethod,
218     kSaveEverythingMethod,
219     kSaveEverythingMethodForClinit,
220     kSaveEverythingMethodForSuspendCheck,
221     kImageMethodsCount,  // Number of elements in enum.
222   };
223 
224   enum ImageRoot {
225     kDexCaches,
226     kClassRoots,
227     kSpecialRoots,                    // Different for boot image and app image, see aliases below.
228     kImageRootsMax,
229 
230     // Aliases.
231     kAppImageClassLoader = kSpecialRoots,   // The class loader used to build the app image.
232     kBootImageLiveObjects = kSpecialRoots,  // Array of boot image objects that must be kept live.
233   };
234 
235   enum BootImageLiveObjects {
236     kOomeWhenThrowingException,       // Pre-allocated OOME when throwing exception.
237     kOomeWhenThrowingOome,            // Pre-allocated OOME when throwing OOME.
238     kOomeWhenHandlingStackOverflow,   // Pre-allocated OOME when handling StackOverflowError.
239     kNoClassDefFoundError,            // Pre-allocated NoClassDefFoundError.
240     kClearedJniWeakSentinel,          // Pre-allocated sentinel for cleared weak JNI references.
241     kIntrinsicObjectsStart
242   };
243 
244   /*
245    * This describes the number and ordering of sections inside of Boot
246    * and App Images.  It is very important that changes to this struct
247    * are reflected in the compiler and loader.
248    *
249    * See:
250    *   - ImageWriter::ImageInfo::CreateImageSections()
251    *   - ImageWriter::Write()
252    *   - ImageWriter::AllocMemory()
253    */
254   enum ImageSections {
255     kSectionObjects,
256     kSectionArtFields,
257     kSectionArtMethods,
258     kSectionRuntimeMethods,
259     kSectionImTables,
260     kSectionIMTConflictTables,
261     kSectionDexCacheArrays,
262     kSectionInternedStrings,
263     kSectionClassTable,
264     kSectionStringReferenceOffsets,
265     kSectionMetadata,
266     kSectionImageBitmap,
267     kSectionCount,  // Number of elements in enum.
268   };
269 
NumberOfImageRoots(bool app_image ATTRIBUTE_UNUSED)270   static size_t NumberOfImageRoots(bool app_image ATTRIBUTE_UNUSED) {
271     // At the moment, boot image and app image have the same number of roots,
272     // though the meaning of the kSpecialRoots is different.
273     return kImageRootsMax;
274   }
275 
276   ArtMethod* GetImageMethod(ImageMethod index) const;
277 
GetImageSection(ImageSections index)278   ImageSection& GetImageSection(ImageSections index) {
279     DCHECK_LT(static_cast<size_t>(index), kSectionCount);
280     return sections_[index];
281   }
282 
GetImageSection(ImageSections index)283   const ImageSection& GetImageSection(ImageSections index) const {
284     DCHECK_LT(static_cast<size_t>(index), kSectionCount);
285     return sections_[index];
286   }
287 
GetObjectsSection()288   const ImageSection& GetObjectsSection() const {
289     return GetImageSection(kSectionObjects);
290   }
291 
GetFieldsSection()292   const ImageSection& GetFieldsSection() const {
293     return GetImageSection(ImageHeader::kSectionArtFields);
294   }
295 
GetMethodsSection()296   const ImageSection& GetMethodsSection() const {
297     return GetImageSection(kSectionArtMethods);
298   }
299 
GetRuntimeMethodsSection()300   const ImageSection& GetRuntimeMethodsSection() const {
301     return GetImageSection(kSectionRuntimeMethods);
302   }
303 
GetImTablesSection()304   const ImageSection& GetImTablesSection() const {
305     return GetImageSection(kSectionImTables);
306   }
307 
GetIMTConflictTablesSection()308   const ImageSection& GetIMTConflictTablesSection() const {
309     return GetImageSection(kSectionIMTConflictTables);
310   }
311 
GetDexCacheArraysSection()312   const ImageSection& GetDexCacheArraysSection() const {
313     return GetImageSection(kSectionDexCacheArrays);
314   }
315 
GetInternedStringsSection()316   const ImageSection& GetInternedStringsSection() const {
317     return GetImageSection(kSectionInternedStrings);
318   }
319 
GetClassTableSection()320   const ImageSection& GetClassTableSection() const {
321     return GetImageSection(kSectionClassTable);
322   }
323 
GetImageStringReferenceOffsetsSection()324   const ImageSection& GetImageStringReferenceOffsetsSection() const {
325     return GetImageSection(kSectionStringReferenceOffsets);
326   }
327 
GetMetadataSection()328   const ImageSection& GetMetadataSection() const {
329     return GetImageSection(kSectionMetadata);
330   }
331 
GetImageBitmapSection()332   const ImageSection& GetImageBitmapSection() const {
333     return GetImageSection(kSectionImageBitmap);
334   }
335 
336   template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
337   ObjPtr<mirror::Object> GetImageRoot(ImageRoot image_root) const
338       REQUIRES_SHARED(Locks::mutator_lock_);
339 
340   template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
341   ObjPtr<mirror::ObjectArray<mirror::Object>> GetImageRoots() const
342       REQUIRES_SHARED(Locks::mutator_lock_);
343 
344   void RelocateImageReferences(int64_t delta);
345   void RelocateBootImageReferences(int64_t delta);
346 
GetBootImageBegin()347   uint32_t GetBootImageBegin() const {
348     return boot_image_begin_;
349   }
350 
GetBootImageSize()351   uint32_t GetBootImageSize() const {
352     return boot_image_size_;
353   }
354 
GetBootImageComponentCount()355   uint32_t GetBootImageComponentCount() const {
356     return boot_image_component_count_;
357   }
358 
GetBootImageChecksum()359   uint32_t GetBootImageChecksum() const {
360     return boot_image_checksum_;
361   }
362 
GetDataSize()363   uint64_t GetDataSize() const {
364     return data_size_;
365   }
366 
367   bool IsAppImage() const;
368 
369   uint32_t GetImageSpaceCount() const;
370 
371   // Visit mirror::Objects in the section starting at base.
372   // TODO: Delete base parameter if it is always equal to GetImageBegin.
373   void VisitObjects(ObjectVisitor* visitor,
374                     uint8_t* base,
375                     PointerSize pointer_size) const
376       REQUIRES_SHARED(Locks::mutator_lock_);
377 
378   // Visit ArtMethods in the section starting at base. Includes runtime methods.
379   // TODO: Delete base parameter if it is always equal to GetImageBegin.
380   // NO_THREAD_SAFETY_ANALYSIS for template visitor pattern.
381   template <typename Visitor>
382   void VisitPackedArtMethods(const Visitor& visitor,
383                              uint8_t* base,
384                              PointerSize pointer_size) const NO_THREAD_SAFETY_ANALYSIS;
385 
386   // Visit ArtMethods in the section starting at base.
387   // TODO: Delete base parameter if it is always equal to GetImageBegin.
388   // NO_THREAD_SAFETY_ANALYSIS for template visitor pattern.
389   template <typename Visitor>
390   void VisitPackedArtFields(const Visitor& visitor, uint8_t* base) const NO_THREAD_SAFETY_ANALYSIS;
391 
392   template <typename Visitor>
393   void VisitPackedImTables(const Visitor& visitor,
394                            uint8_t* base,
395                            PointerSize pointer_size) const;
396 
397   template <typename Visitor>
398   void VisitPackedImtConflictTables(const Visitor& visitor,
399                                     uint8_t* base,
400                                     PointerSize pointer_size) const;
401 
GetBlocks()402   IterationRange<const Block*> GetBlocks() const {
403     return GetBlocks(GetImageBegin());
404   }
405 
GetBlocks(const uint8_t * image_begin)406   IterationRange<const Block*> GetBlocks(const uint8_t* image_begin) const {
407     const Block* begin = reinterpret_cast<const Block*>(image_begin + blocks_offset_);
408     return {begin, begin + blocks_count_};
409   }
410 
411   // Return true if the image has any compressed blocks.
HasCompressedBlock()412   bool HasCompressedBlock() const {
413     return blocks_count_ != 0u;
414   }
415 
GetBlockCount()416   uint32_t GetBlockCount() const {
417     return blocks_count_;
418   }
419 
420  private:
421   static const uint8_t kImageMagic[4];
422   static const uint8_t kImageVersion[4];
423 
GetLocationFromImageLocation(const std::string & image,const std::string & extension)424   static std::string GetLocationFromImageLocation(const std::string& image,
425                                                   const std::string& extension) {
426     std::string filename = image;
427     if (filename.length() <= 3) {
428       filename += "." + extension;
429     } else {
430       filename.replace(filename.length() - 3, 3, extension);
431     }
432     return filename;
433   }
434 
435   uint8_t magic_[4];
436   uint8_t version_[4];
437 
438   // The total memory reservation size for the image.
439   // For boot image or boot image extension, the primary image includes the reservation
440   // for all image files and oat files, secondary images have the reservation set to 0.
441   // App images have reservation equal to `image_size_` rounded up to page size because
442   // their oat files are mmapped independently.
443   uint32_t image_reservation_size_ = 0u;
444 
445   // The number of components.
446   // For boot image or boot image extension, the primary image stores the total number
447   // of images, secondary images have this set to 0.
448   // App images have 1 component.
449   uint32_t component_count_ = 0u;
450 
451   // Required base address for mapping the image.
452   uint32_t image_begin_ = 0u;
453 
454   // Image size, not page aligned.
455   uint32_t image_size_ = 0u;
456 
457   // Image file checksum (calculated with the checksum field set to 0).
458   uint32_t image_checksum_ = 0u;
459 
460   // Checksum of the oat file we link to for load time sanity check.
461   uint32_t oat_checksum_ = 0u;
462 
463   // Start address for oat file. Will be before oat_data_begin_ for .so files.
464   uint32_t oat_file_begin_ = 0u;
465 
466   // Required oat address expected by image Method::GetCode() pointers.
467   uint32_t oat_data_begin_ = 0u;
468 
469   // End of oat data address range for this image file.
470   uint32_t oat_data_end_ = 0u;
471 
472   // End of oat file address range. will be after oat_data_end_ for
473   // .so files. Used for positioning a following alloc spaces.
474   uint32_t oat_file_end_ = 0u;
475 
476   // Boot image begin and end (only applies to boot image extension and app image headers).
477   uint32_t boot_image_begin_ = 0u;
478   uint32_t boot_image_size_ = 0u;  // Includes heap (*.art) and code (.oat).
479 
480   // Number of boot image components that this image depends on and their composite checksum
481   // (only applies to boot image extension and app image headers).
482   uint32_t boot_image_component_count_ = 0u;
483   uint32_t boot_image_checksum_ = 0u;
484 
485   // Absolute address of an Object[] of objects needed to reinitialize from an image.
486   uint32_t image_roots_ = 0u;
487 
488   // Pointer size, this affects the size of the ArtMethods.
489   uint32_t pointer_size_ = 0u;
490 
491   // Image section sizes/offsets correspond to the uncompressed form.
492   ImageSection sections_[kSectionCount];
493 
494   // Image methods, may be inside of the boot image for app images.
495   uint64_t image_methods_[kImageMethodsCount];
496 
497   // Data size for the image data excluding the bitmap and the header. For compressed images, this
498   // is the compressed size in the file.
499   uint32_t data_size_ = 0u;
500 
501   // Image blocks, only used for compressed images.
502   uint32_t blocks_offset_ = 0u;
503   uint32_t blocks_count_ = 0u;
504 
505   friend class linker::ImageWriter;
506 };
507 
508 /*
509  * This type holds the information necessary to fix up AppImage string
510  * references.
511  *
512  * The first element of the pair is an offset into the image space.  If the
513  * offset is tagged (testable using HasDexCacheNativeRefTag) it indicates the location
514  * of a DexCache object that has one or more native references to managed
515  * strings that need to be fixed up.  In this case the second element has no
516  * meaningful value.
517  *
518  * If the first element isn't tagged then it indicates the location of a
519  * managed object with a field that needs fixing up.  In this case the second
520  * element of the pair is an object-relative offset to the field in question.
521  */
522 typedef std::pair<uint32_t, uint32_t> AppImageReferenceOffsetInfo;
523 
524 /*
525  * Tags the last bit.  Used by AppImage logic to differentiate between pointers
526  * to managed objects and pointers to native reference arrays.
527  */
528 template<typename T>
SetDexCacheStringNativeRefTag(T val)529 T SetDexCacheStringNativeRefTag(T val) {
530   static_assert(std::is_integral<T>::value, "Expected integral type.");
531 
532   return val | 1u;
533 }
534 
535 /*
536  * Tags the second last bit.  Used by AppImage logic to differentiate between pointers
537  * to managed objects and pointers to native reference arrays.
538  */
539 template<typename T>
SetDexCachePreResolvedStringNativeRefTag(T val)540 T SetDexCachePreResolvedStringNativeRefTag(T val) {
541   static_assert(std::is_integral<T>::value, "Expected integral type.");
542 
543   return val | 2u;
544 }
545 
546 /*
547  * Retrieves the value of the last bit.  Used by AppImage logic to
548  * differentiate between pointers to managed objects and pointers to native
549  * reference arrays.
550  */
551 template<typename T>
HasDexCacheStringNativeRefTag(T val)552 bool HasDexCacheStringNativeRefTag(T val) {
553   static_assert(std::is_integral<T>::value, "Expected integral type.");
554 
555   return (val & 1u) != 0u;
556 }
557 
558 /*
559  * Retrieves the value of the second last bit.  Used by AppImage logic to
560  * differentiate between pointers to managed objects and pointers to native
561  * reference arrays.
562  */
563 template<typename T>
HasDexCachePreResolvedStringNativeRefTag(T val)564 bool HasDexCachePreResolvedStringNativeRefTag(T val) {
565   static_assert(std::is_integral<T>::value, "Expected integral type.");
566 
567   return (val & 2u) != 0u;
568 }
569 
570 /*
571  * Sets the last bit of the value to 0.  Used by AppImage logic to
572  * differentiate between pointers to managed objects and pointers to native
573  * reference arrays.
574  */
575 template<typename T>
ClearDexCacheNativeRefTags(T val)576 T ClearDexCacheNativeRefTags(T val) {
577   static_assert(std::is_integral<T>::value, "Expected integral type.");
578 
579   return val & ~3u;
580 }
581 
582 std::ostream& operator<<(std::ostream& os, const ImageHeader::ImageMethod& method);
583 std::ostream& operator<<(std::ostream& os, const ImageHeader::ImageRoot& root);
584 std::ostream& operator<<(std::ostream& os, const ImageHeader::ImageSections& section);
585 std::ostream& operator<<(std::ostream& os, const ImageSection& section);
586 std::ostream& operator<<(std::ostream& os, const ImageHeader::StorageMode& mode);
587 
588 }  // namespace art
589 
590 #endif  // ART_RUNTIME_IMAGE_H_
591