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