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 consistency 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, ImageHeader::ImageMethod method);
583 std::ostream& operator<<(std::ostream& os, ImageHeader::ImageRoot root);
584 std::ostream& operator<<(std::ostream& os, ImageHeader::ImageSections section);
585 std::ostream& operator<<(std::ostream& os, ImageHeader::StorageMode mode);
586
587 std::ostream& operator<<(std::ostream& os, const ImageSection& section);
588
589 } // namespace art
590
591 #endif // ART_RUNTIME_IMAGE_H_
592