• 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     kSectionInternedStrings,
262     kSectionClassTable,
263     kSectionStringReferenceOffsets,
264     kSectionMetadata,
265     kSectionImageBitmap,
266     kSectionCount,  // Number of elements in enum.
267   };
268 
NumberOfImageRoots(bool app_image ATTRIBUTE_UNUSED)269   static size_t NumberOfImageRoots(bool app_image ATTRIBUTE_UNUSED) {
270     // At the moment, boot image and app image have the same number of roots,
271     // though the meaning of the kSpecialRoots is different.
272     return kImageRootsMax;
273   }
274 
275   ArtMethod* GetImageMethod(ImageMethod index) const;
276 
277   static const char* GetImageSectionName(ImageSections index);
278 
GetImageSection(ImageSections index)279   ImageSection& GetImageSection(ImageSections index) {
280     DCHECK_LT(static_cast<size_t>(index), kSectionCount);
281     return sections_[index];
282   }
283 
GetImageSection(ImageSections index)284   const ImageSection& GetImageSection(ImageSections index) const {
285     DCHECK_LT(static_cast<size_t>(index), kSectionCount);
286     return sections_[index];
287   }
288 
GetObjectsSection()289   const ImageSection& GetObjectsSection() const {
290     return GetImageSection(kSectionObjects);
291   }
292 
GetFieldsSection()293   const ImageSection& GetFieldsSection() const {
294     return GetImageSection(ImageHeader::kSectionArtFields);
295   }
296 
GetMethodsSection()297   const ImageSection& GetMethodsSection() const {
298     return GetImageSection(kSectionArtMethods);
299   }
300 
GetRuntimeMethodsSection()301   const ImageSection& GetRuntimeMethodsSection() const {
302     return GetImageSection(kSectionRuntimeMethods);
303   }
304 
GetImTablesSection()305   const ImageSection& GetImTablesSection() const {
306     return GetImageSection(kSectionImTables);
307   }
308 
GetIMTConflictTablesSection()309   const ImageSection& GetIMTConflictTablesSection() const {
310     return GetImageSection(kSectionIMTConflictTables);
311   }
312 
GetInternedStringsSection()313   const ImageSection& GetInternedStringsSection() const {
314     return GetImageSection(kSectionInternedStrings);
315   }
316 
GetClassTableSection()317   const ImageSection& GetClassTableSection() const {
318     return GetImageSection(kSectionClassTable);
319   }
320 
GetImageStringReferenceOffsetsSection()321   const ImageSection& GetImageStringReferenceOffsetsSection() const {
322     return GetImageSection(kSectionStringReferenceOffsets);
323   }
324 
GetMetadataSection()325   const ImageSection& GetMetadataSection() const {
326     return GetImageSection(kSectionMetadata);
327   }
328 
GetImageBitmapSection()329   const ImageSection& GetImageBitmapSection() const {
330     return GetImageSection(kSectionImageBitmap);
331   }
332 
333   template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
334   ObjPtr<mirror::Object> GetImageRoot(ImageRoot image_root) const
335       REQUIRES_SHARED(Locks::mutator_lock_);
336 
337   template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
338   ObjPtr<mirror::ObjectArray<mirror::Object>> GetImageRoots() const
339       REQUIRES_SHARED(Locks::mutator_lock_);
340 
341   void RelocateImageReferences(int64_t delta);
342   void RelocateBootImageReferences(int64_t delta);
343 
GetBootImageBegin()344   uint32_t GetBootImageBegin() const {
345     return boot_image_begin_;
346   }
347 
GetBootImageSize()348   uint32_t GetBootImageSize() const {
349     return boot_image_size_;
350   }
351 
GetBootImageComponentCount()352   uint32_t GetBootImageComponentCount() const {
353     return boot_image_component_count_;
354   }
355 
GetBootImageChecksum()356   uint32_t GetBootImageChecksum() const {
357     return boot_image_checksum_;
358   }
359 
GetDataSize()360   uint64_t GetDataSize() const {
361     return data_size_;
362   }
363 
364   bool IsAppImage() const;
365 
366   uint32_t GetImageSpaceCount() const;
367 
368   // Visit mirror::Objects in the section starting at base.
369   // TODO: Delete base parameter if it is always equal to GetImageBegin.
370   void VisitObjects(ObjectVisitor* visitor,
371                     uint8_t* base,
372                     PointerSize pointer_size) const
373       REQUIRES_SHARED(Locks::mutator_lock_);
374 
375   // Visit ArtMethods in the section starting at base. Includes runtime methods.
376   // TODO: Delete base parameter if it is always equal to GetImageBegin.
377   // NO_THREAD_SAFETY_ANALYSIS for template visitor pattern.
378   template <typename Visitor>
379   void VisitPackedArtMethods(const Visitor& visitor,
380                              uint8_t* base,
381                              PointerSize pointer_size) const NO_THREAD_SAFETY_ANALYSIS;
382 
383   // Visit ArtMethods in the section starting at base.
384   // TODO: Delete base parameter if it is always equal to GetImageBegin.
385   // NO_THREAD_SAFETY_ANALYSIS for template visitor pattern.
386   template <typename Visitor>
387   void VisitPackedArtFields(const Visitor& visitor, uint8_t* base) const NO_THREAD_SAFETY_ANALYSIS;
388 
389   template <typename Visitor>
390   void VisitPackedImTables(const Visitor& visitor,
391                            uint8_t* base,
392                            PointerSize pointer_size) const;
393 
394   template <typename Visitor>
395   void VisitPackedImtConflictTables(const Visitor& visitor,
396                                     uint8_t* base,
397                                     PointerSize pointer_size) const;
398 
GetBlocks()399   IterationRange<const Block*> GetBlocks() const {
400     return GetBlocks(GetImageBegin());
401   }
402 
GetBlocks(const uint8_t * image_begin)403   IterationRange<const Block*> GetBlocks(const uint8_t* image_begin) const {
404     const Block* begin = reinterpret_cast<const Block*>(image_begin + blocks_offset_);
405     return {begin, begin + blocks_count_};
406   }
407 
408   // Return true if the image has any compressed blocks.
HasCompressedBlock()409   bool HasCompressedBlock() const {
410     return blocks_count_ != 0u;
411   }
412 
GetBlockCount()413   uint32_t GetBlockCount() const {
414     return blocks_count_;
415   }
416 
417  private:
418   static const uint8_t kImageMagic[4];
419   static const uint8_t kImageVersion[4];
420 
GetLocationFromImageLocation(const std::string & image,const std::string & extension)421   static std::string GetLocationFromImageLocation(const std::string& image,
422                                                   const std::string& extension) {
423     std::string filename = image;
424     if (filename.length() <= 3) {
425       filename += "." + extension;
426     } else {
427       filename.replace(filename.length() - 3, 3, extension);
428     }
429     return filename;
430   }
431 
432   uint8_t magic_[4];
433   uint8_t version_[4];
434 
435   // The total memory reservation size for the image.
436   // For boot image or boot image extension, the primary image includes the reservation
437   // for all image files and oat files, secondary images have the reservation set to 0.
438   // App images have reservation equal to `image_size_` rounded up to page size because
439   // their oat files are mmapped independently.
440   uint32_t image_reservation_size_ = 0u;
441 
442   // The number of components (jar files contributing to the image).
443   // For boot image or boot image extension, the primary image stores the total number
444   // of components, secondary images have this set to 0. App images have 1 component.
445   // The component count usually matches the total number of images (one image per component), but
446   // if multiple components are compiled with --single-image there will only be 1 image associated
447   // with those components.
448   uint32_t component_count_ = 0u;
449 
450   // Required base address for mapping the image.
451   uint32_t image_begin_ = 0u;
452 
453   // Image size, not page aligned.
454   uint32_t image_size_ = 0u;
455 
456   // Image file checksum (calculated with the checksum field set to 0).
457   uint32_t image_checksum_ = 0u;
458 
459   // Checksum of the oat file we link to for load time consistency check.
460   uint32_t oat_checksum_ = 0u;
461 
462   // Start address for oat file. Will be before oat_data_begin_ for .so files.
463   uint32_t oat_file_begin_ = 0u;
464 
465   // Required oat address expected by image Method::GetCode() pointers.
466   uint32_t oat_data_begin_ = 0u;
467 
468   // End of oat data address range for this image file.
469   uint32_t oat_data_end_ = 0u;
470 
471   // End of oat file address range. will be after oat_data_end_ for
472   // .so files. Used for positioning a following alloc spaces.
473   uint32_t oat_file_end_ = 0u;
474 
475   // Boot image begin and end (only applies to boot image extension and app image headers).
476   uint32_t boot_image_begin_ = 0u;
477   uint32_t boot_image_size_ = 0u;  // Includes heap (*.art) and code (.oat).
478 
479   // Number of boot image components that this image depends on and their composite checksum
480   // (only applies to boot image extension and app image headers).
481   uint32_t boot_image_component_count_ = 0u;
482   uint32_t boot_image_checksum_ = 0u;
483 
484   // Absolute address of an Object[] of objects needed to reinitialize from an image.
485   uint32_t image_roots_ = 0u;
486 
487   // Pointer size, this affects the size of the ArtMethods.
488   uint32_t pointer_size_ = 0u;
489 
490   // Image section sizes/offsets correspond to the uncompressed form.
491   ImageSection sections_[kSectionCount];
492 
493   // Image methods, may be inside of the boot image for app images.
494   uint64_t image_methods_[kImageMethodsCount];
495 
496   // Data size for the image data excluding the bitmap and the header. For compressed images, this
497   // is the compressed size in the file.
498   uint32_t data_size_ = 0u;
499 
500   // Image blocks, only used for compressed images.
501   uint32_t blocks_offset_ = 0u;
502   uint32_t blocks_count_ = 0u;
503 
504   friend class linker::ImageWriter;
505 };
506 
507 /*
508  * This type holds the information necessary to fix up AppImage string
509  * references.
510  *
511  * The first element indicates the location of a managed object with a field that needs fixing up.
512  * The second element of the pair is an object-relative offset to the field in question.
513  */
514 using AppImageReferenceOffsetInfo = std::pair<uint32_t, uint32_t>;
515 
516 std::ostream& operator<<(std::ostream& os, ImageHeader::ImageMethod method);
517 std::ostream& operator<<(std::ostream& os, ImageHeader::ImageRoot root);
518 std::ostream& operator<<(std::ostream& os, ImageHeader::ImageSections section);
519 std::ostream& operator<<(std::ostream& os, ImageHeader::StorageMode mode);
520 
521 std::ostream& operator<<(std::ostream& os, const ImageSection& section);
522 
523 }  // namespace art
524 
525 #endif  // ART_RUNTIME_IMAGE_H_
526