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/bit_utils.h" 23 #include "base/enums.h" 24 #include "globals.h" 25 #include "mirror/object.h" 26 27 namespace art { 28 29 class ArtField; 30 class ArtMethod; 31 32 namespace linker { 33 class ImageWriter; 34 } // namespace linker 35 36 class ObjectVisitor { 37 public: 38 virtual ~ObjectVisitor() {} 39 40 virtual void Visit(mirror::Object* object) = 0; 41 }; 42 43 class ArtMethodVisitor { 44 public: 45 virtual ~ArtMethodVisitor() {} 46 47 virtual void Visit(ArtMethod* method) = 0; 48 }; 49 50 class ArtFieldVisitor { 51 public: 52 virtual ~ArtFieldVisitor() {} 53 54 virtual void Visit(ArtField* method) = 0; 55 }; 56 57 class PACKED(4) ImageSection { 58 public: 59 ImageSection() : offset_(0), size_(0) { } 60 ImageSection(uint32_t offset, uint32_t size) : offset_(offset), size_(size) { } 61 ImageSection(const ImageSection& section) = default; 62 ImageSection& operator=(const ImageSection& section) = default; 63 64 uint32_t Offset() const { 65 return offset_; 66 } 67 68 uint32_t Size() const { 69 return size_; 70 } 71 72 uint32_t End() const { 73 return Offset() + Size(); 74 } 75 76 bool Contains(uint64_t offset) const { 77 return offset - offset_ < size_; 78 } 79 80 private: 81 uint32_t offset_; 82 uint32_t size_; 83 }; 84 85 // header of image files written by ImageWriter, read and validated by Space. 86 class PACKED(4) ImageHeader { 87 public: 88 enum StorageMode : uint32_t { 89 kStorageModeUncompressed, 90 kStorageModeLZ4, 91 kStorageModeLZ4HC, 92 kStorageModeCount, // Number of elements in enum. 93 }; 94 static constexpr StorageMode kDefaultStorageMode = kStorageModeUncompressed; 95 96 ImageHeader() 97 : image_begin_(0U), 98 image_size_(0U), 99 oat_checksum_(0U), 100 oat_file_begin_(0U), 101 oat_data_begin_(0U), 102 oat_data_end_(0U), 103 oat_file_end_(0U), 104 boot_image_begin_(0U), 105 boot_image_size_(0U), 106 boot_oat_begin_(0U), 107 boot_oat_size_(0U), 108 patch_delta_(0), 109 image_roots_(0U), 110 pointer_size_(0U), 111 compile_pic_(0), 112 is_pic_(0), 113 storage_mode_(kDefaultStorageMode), 114 data_size_(0) {} 115 116 ImageHeader(uint32_t image_begin, 117 uint32_t image_size, 118 ImageSection* sections, 119 uint32_t image_roots, 120 uint32_t oat_checksum, 121 uint32_t oat_file_begin, 122 uint32_t oat_data_begin, 123 uint32_t oat_data_end, 124 uint32_t oat_file_end, 125 uint32_t boot_image_begin, 126 uint32_t boot_image_size, 127 uint32_t boot_oat_begin, 128 uint32_t boot_oat_size, 129 uint32_t pointer_size, 130 bool compile_pic, 131 bool is_pic, 132 StorageMode storage_mode, 133 size_t data_size); 134 135 bool IsValid() const; 136 const char* GetMagic() const; 137 138 uint8_t* GetImageBegin() const { 139 return reinterpret_cast<uint8_t*>(image_begin_); 140 } 141 142 size_t GetImageSize() const { 143 return static_cast<uint32_t>(image_size_); 144 } 145 146 uint32_t GetOatChecksum() const { 147 return oat_checksum_; 148 } 149 150 void SetOatChecksum(uint32_t oat_checksum) { 151 oat_checksum_ = oat_checksum; 152 } 153 154 // The location that the oat file was expected to be when the image was created. The actual 155 // oat file may be at a different location for application images. 156 uint8_t* GetOatFileBegin() const { 157 return reinterpret_cast<uint8_t*>(oat_file_begin_); 158 } 159 160 uint8_t* GetOatDataBegin() const { 161 return reinterpret_cast<uint8_t*>(oat_data_begin_); 162 } 163 164 uint8_t* GetOatDataEnd() const { 165 return reinterpret_cast<uint8_t*>(oat_data_end_); 166 } 167 168 uint8_t* GetOatFileEnd() const { 169 return reinterpret_cast<uint8_t*>(oat_file_end_); 170 } 171 172 PointerSize GetPointerSize() const; 173 174 uint32_t GetPointerSizeUnchecked() const { 175 return pointer_size_; 176 } 177 178 off_t GetPatchDelta() const { 179 return patch_delta_; 180 } 181 182 void SetPatchDelta(off_t patch_delta) { 183 patch_delta_ = patch_delta; 184 } 185 186 static std::string GetOatLocationFromImageLocation(const std::string& image) { 187 return GetLocationFromImageLocation(image, "oat"); 188 } 189 190 static std::string GetVdexLocationFromImageLocation(const std::string& image) { 191 return GetLocationFromImageLocation(image, "vdex"); 192 } 193 194 enum ImageMethod { 195 kResolutionMethod, 196 kImtConflictMethod, 197 kImtUnimplementedMethod, 198 kSaveAllCalleeSavesMethod, 199 kSaveRefsOnlyMethod, 200 kSaveRefsAndArgsMethod, 201 kSaveEverythingMethod, 202 kSaveEverythingMethodForClinit, 203 kSaveEverythingMethodForSuspendCheck, 204 kImageMethodsCount, // Number of elements in enum. 205 }; 206 207 enum ImageRoot { 208 kDexCaches, 209 kClassRoots, 210 kClassLoader, // App image only. 211 kImageRootsMax, 212 }; 213 214 enum ImageSections { 215 kSectionObjects, 216 kSectionArtFields, 217 kSectionArtMethods, 218 kSectionRuntimeMethods, 219 kSectionImTables, 220 kSectionIMTConflictTables, 221 kSectionDexCacheArrays, 222 kSectionInternedStrings, 223 kSectionClassTable, 224 kSectionImageBitmap, 225 kSectionCount, // Number of elements in enum. 226 }; 227 228 static size_t NumberOfImageRoots(bool app_image) { 229 return app_image ? kImageRootsMax : kImageRootsMax - 1u; 230 } 231 232 ArtMethod* GetImageMethod(ImageMethod index) const; 233 void SetImageMethod(ImageMethod index, ArtMethod* method); 234 235 const ImageSection& GetImageSection(ImageSections index) const { 236 DCHECK_LT(static_cast<size_t>(index), kSectionCount); 237 return sections_[index]; 238 } 239 240 const ImageSection& GetObjectsSection() const { 241 return GetImageSection(kSectionObjects); 242 } 243 244 const ImageSection& GetFieldsSection() const { 245 return GetImageSection(ImageHeader::kSectionArtFields); 246 } 247 248 const ImageSection& GetMethodsSection() const { 249 return GetImageSection(kSectionArtMethods); 250 } 251 252 const ImageSection& GetRuntimeMethodsSection() const { 253 return GetImageSection(kSectionRuntimeMethods); 254 } 255 256 const ImageSection& GetImTablesSection() const { 257 return GetImageSection(kSectionImTables); 258 } 259 260 const ImageSection& GetIMTConflictTablesSection() const { 261 return GetImageSection(kSectionIMTConflictTables); 262 } 263 264 const ImageSection& GetDexCacheArraysSection() const { 265 return GetImageSection(kSectionDexCacheArrays); 266 } 267 268 const ImageSection& GetInternedStringsSection() const { 269 return GetImageSection(kSectionInternedStrings); 270 } 271 272 const ImageSection& GetClassTableSection() const { 273 return GetImageSection(kSectionClassTable); 274 } 275 276 const ImageSection& GetImageBitmapSection() const { 277 return GetImageSection(kSectionImageBitmap); 278 } 279 280 template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier> 281 mirror::Object* GetImageRoot(ImageRoot image_root) const 282 REQUIRES_SHARED(Locks::mutator_lock_); 283 284 template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier> 285 mirror::ObjectArray<mirror::Object>* GetImageRoots() const 286 REQUIRES_SHARED(Locks::mutator_lock_); 287 288 void RelocateImage(off_t delta); 289 void RelocateImageMethods(off_t delta); 290 void RelocateImageObjects(off_t delta); 291 292 bool CompilePic() const { 293 return compile_pic_ != 0; 294 } 295 296 bool IsPic() const { 297 return is_pic_ != 0; 298 } 299 300 uint32_t GetBootImageBegin() const { 301 return boot_image_begin_; 302 } 303 304 uint32_t GetBootImageSize() const { 305 return boot_image_size_; 306 } 307 308 uint32_t GetBootOatBegin() const { 309 return boot_oat_begin_; 310 } 311 312 uint32_t GetBootOatSize() const { 313 return boot_oat_size_; 314 } 315 316 StorageMode GetStorageMode() const { 317 return storage_mode_; 318 } 319 320 uint64_t GetDataSize() const { 321 return data_size_; 322 } 323 324 bool IsAppImage() const { 325 // App images currently require a boot image, if the size is non zero then it is an app image 326 // header. 327 return boot_image_size_ != 0u; 328 } 329 330 uint32_t GetBootImageConstantTablesOffset() const { 331 // Interned strings table and class table for boot image are mmapped read only. 332 DCHECK(!IsAppImage()); 333 const ImageSection& interned_strings = GetInternedStringsSection(); 334 DCHECK_ALIGNED(interned_strings.Offset(), kPageSize); 335 return interned_strings.Offset(); 336 } 337 338 uint32_t GetBootImageConstantTablesSize() const { 339 uint32_t start_offset = GetBootImageConstantTablesOffset(); 340 const ImageSection& class_table = GetClassTableSection(); 341 DCHECK_LE(start_offset, class_table.Offset()); 342 size_t tables_size = class_table.Offset() + class_table.Size() - start_offset; 343 return RoundUp(tables_size, kPageSize); 344 } 345 346 // Visit mirror::Objects in the section starting at base. 347 // TODO: Delete base parameter if it is always equal to GetImageBegin. 348 void VisitObjects(ObjectVisitor* visitor, 349 uint8_t* base, 350 PointerSize pointer_size) const 351 REQUIRES_SHARED(Locks::mutator_lock_); 352 353 // Visit ArtMethods in the section starting at base. Includes runtime methods. 354 // TODO: Delete base parameter if it is always equal to GetImageBegin. 355 void VisitPackedArtMethods(ArtMethodVisitor* visitor, 356 uint8_t* base, 357 PointerSize pointer_size) const; 358 359 // Visit ArtMethods in the section starting at base. 360 // TODO: Delete base parameter if it is always equal to GetImageBegin. 361 void VisitPackedArtFields(ArtFieldVisitor* visitor, uint8_t* base) const; 362 363 template <typename Visitor> 364 void VisitPackedImTables(const Visitor& visitor, 365 uint8_t* base, 366 PointerSize pointer_size) const; 367 368 template <typename Visitor> 369 void VisitPackedImtConflictTables(const Visitor& visitor, 370 uint8_t* base, 371 PointerSize pointer_size) const; 372 373 private: 374 static const uint8_t kImageMagic[4]; 375 static const uint8_t kImageVersion[4]; 376 377 static std::string GetLocationFromImageLocation(const std::string& image, 378 const std::string& extension) { 379 std::string filename = image; 380 if (filename.length() <= 3) { 381 filename += "." + extension; 382 } else { 383 filename.replace(filename.length() - 3, 3, extension); 384 } 385 return filename; 386 } 387 388 uint8_t magic_[4]; 389 uint8_t version_[4]; 390 391 // Required base address for mapping the image. 392 uint32_t image_begin_; 393 394 // Image size, not page aligned. 395 uint32_t image_size_; 396 397 // Checksum of the oat file we link to for load time sanity check. 398 uint32_t oat_checksum_; 399 400 // Start address for oat file. Will be before oat_data_begin_ for .so files. 401 uint32_t oat_file_begin_; 402 403 // Required oat address expected by image Method::GetCode() pointers. 404 uint32_t oat_data_begin_; 405 406 // End of oat data address range for this image file. 407 uint32_t oat_data_end_; 408 409 // End of oat file address range. will be after oat_data_end_ for 410 // .so files. Used for positioning a following alloc spaces. 411 uint32_t oat_file_end_; 412 413 // Boot image begin and end (app image headers only). 414 uint32_t boot_image_begin_; 415 uint32_t boot_image_size_; 416 417 // Boot oat begin and end (app image headers only). 418 uint32_t boot_oat_begin_; 419 uint32_t boot_oat_size_; 420 421 // TODO: We should probably insert a boot image checksum for app images. 422 423 // The total delta that this image has been patched. 424 int32_t patch_delta_; 425 426 // Absolute address of an Object[] of objects needed to reinitialize from an image. 427 uint32_t image_roots_; 428 429 // Pointer size, this affects the size of the ArtMethods. 430 uint32_t pointer_size_; 431 432 // Boolean (0 or 1) to denote if the image was compiled with --compile-pic option 433 const uint32_t compile_pic_; 434 435 // Boolean (0 or 1) to denote if the image can be mapped at a random address, this only refers to 436 // the .art file. Currently, app oat files do not depend on their app image. There are no pointers 437 // from the app oat code to the app image. 438 const uint32_t is_pic_; 439 440 // Image section sizes/offsets correspond to the uncompressed form. 441 ImageSection sections_[kSectionCount]; 442 443 // Image methods, may be inside of the boot image for app images. 444 uint64_t image_methods_[kImageMethodsCount]; 445 446 // Storage method for the image, the image may be compressed. 447 StorageMode storage_mode_; 448 449 // Data size for the image data excluding the bitmap and the header. For compressed images, this 450 // is the compressed size in the file. 451 uint32_t data_size_; 452 453 friend class linker::ImageWriter; 454 }; 455 456 std::ostream& operator<<(std::ostream& os, const ImageHeader::ImageMethod& policy); 457 std::ostream& operator<<(std::ostream& os, const ImageHeader::ImageRoot& policy); 458 std::ostream& operator<<(std::ostream& os, const ImageHeader::ImageSections& section); 459 std::ostream& operator<<(std::ostream& os, const ImageSection& section); 460 std::ostream& operator<<(std::ostream& os, const ImageHeader::StorageMode& mode); 461 462 } // namespace art 463 464 #endif // ART_RUNTIME_IMAGE_H_ 465