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 #include "image_space.h" 18 19 #include <lz4.h> 20 #include <random> 21 #include <sys/statvfs.h> 22 #include <sys/types.h> 23 #include <unistd.h> 24 25 #include "art_method.h" 26 #include "base/macros.h" 27 #include "base/stl_util.h" 28 #include "base/scoped_flock.h" 29 #include "base/systrace.h" 30 #include "base/time_utils.h" 31 #include "gc/accounting/space_bitmap-inl.h" 32 #include "image-inl.h" 33 #include "image_space_fs.h" 34 #include "mirror/class-inl.h" 35 #include "mirror/object-inl.h" 36 #include "oat_file.h" 37 #include "os.h" 38 #include "space-inl.h" 39 #include "utils.h" 40 41 namespace art { 42 namespace gc { 43 namespace space { 44 45 Atomic<uint32_t> ImageSpace::bitmap_index_(0); 46 47 ImageSpace::ImageSpace(const std::string& image_filename, 48 const char* image_location, 49 MemMap* mem_map, 50 accounting::ContinuousSpaceBitmap* live_bitmap, 51 uint8_t* end) 52 : MemMapSpace(image_filename, 53 mem_map, 54 mem_map->Begin(), 55 end, 56 end, 57 kGcRetentionPolicyNeverCollect), 58 oat_file_non_owned_(nullptr), 59 image_location_(image_location) { 60 DCHECK(live_bitmap != nullptr); 61 live_bitmap_.reset(live_bitmap); 62 } 63 64 static int32_t ChooseRelocationOffsetDelta(int32_t min_delta, int32_t max_delta) { 65 CHECK_ALIGNED(min_delta, kPageSize); 66 CHECK_ALIGNED(max_delta, kPageSize); 67 CHECK_LT(min_delta, max_delta); 68 69 int32_t r = GetRandomNumber<int32_t>(min_delta, max_delta); 70 if (r % 2 == 0) { 71 r = RoundUp(r, kPageSize); 72 } else { 73 r = RoundDown(r, kPageSize); 74 } 75 CHECK_LE(min_delta, r); 76 CHECK_GE(max_delta, r); 77 CHECK_ALIGNED(r, kPageSize); 78 return r; 79 } 80 81 static bool GenerateImage(const std::string& image_filename, InstructionSet image_isa, 82 std::string* error_msg) { 83 const std::string boot_class_path_string(Runtime::Current()->GetBootClassPathString()); 84 std::vector<std::string> boot_class_path; 85 Split(boot_class_path_string, ':', &boot_class_path); 86 if (boot_class_path.empty()) { 87 *error_msg = "Failed to generate image because no boot class path specified"; 88 return false; 89 } 90 // We should clean up so we are more likely to have room for the image. 91 if (Runtime::Current()->IsZygote()) { 92 LOG(INFO) << "Pruning dalvik-cache since we are generating an image and will need to recompile"; 93 PruneDalvikCache(image_isa); 94 } 95 96 std::vector<std::string> arg_vector; 97 98 std::string dex2oat(Runtime::Current()->GetCompilerExecutable()); 99 arg_vector.push_back(dex2oat); 100 101 std::string image_option_string("--image="); 102 image_option_string += image_filename; 103 arg_vector.push_back(image_option_string); 104 105 for (size_t i = 0; i < boot_class_path.size(); i++) { 106 arg_vector.push_back(std::string("--dex-file=") + boot_class_path[i]); 107 } 108 109 std::string oat_file_option_string("--oat-file="); 110 oat_file_option_string += ImageHeader::GetOatLocationFromImageLocation(image_filename); 111 arg_vector.push_back(oat_file_option_string); 112 113 // Note: we do not generate a fully debuggable boot image so we do not pass the 114 // compiler flag --debuggable here. 115 116 Runtime::Current()->AddCurrentRuntimeFeaturesAsDex2OatArguments(&arg_vector); 117 CHECK_EQ(image_isa, kRuntimeISA) 118 << "We should always be generating an image for the current isa."; 119 120 int32_t base_offset = ChooseRelocationOffsetDelta(ART_BASE_ADDRESS_MIN_DELTA, 121 ART_BASE_ADDRESS_MAX_DELTA); 122 LOG(INFO) << "Using an offset of 0x" << std::hex << base_offset << " from default " 123 << "art base address of 0x" << std::hex << ART_BASE_ADDRESS; 124 arg_vector.push_back(StringPrintf("--base=0x%x", ART_BASE_ADDRESS + base_offset)); 125 126 if (!kIsTargetBuild) { 127 arg_vector.push_back("--host"); 128 } 129 130 const std::vector<std::string>& compiler_options = Runtime::Current()->GetImageCompilerOptions(); 131 for (size_t i = 0; i < compiler_options.size(); ++i) { 132 arg_vector.push_back(compiler_options[i].c_str()); 133 } 134 135 std::string command_line(Join(arg_vector, ' ')); 136 LOG(INFO) << "GenerateImage: " << command_line; 137 return Exec(arg_vector, error_msg); 138 } 139 140 bool ImageSpace::FindImageFilename(const char* image_location, 141 const InstructionSet image_isa, 142 std::string* system_filename, 143 bool* has_system, 144 std::string* cache_filename, 145 bool* dalvik_cache_exists, 146 bool* has_cache, 147 bool* is_global_cache) { 148 *has_system = false; 149 *has_cache = false; 150 // image_location = /system/framework/boot.art 151 // system_image_location = /system/framework/<image_isa>/boot.art 152 std::string system_image_filename(GetSystemImageFilename(image_location, image_isa)); 153 if (OS::FileExists(system_image_filename.c_str())) { 154 *system_filename = system_image_filename; 155 *has_system = true; 156 } 157 158 bool have_android_data = false; 159 *dalvik_cache_exists = false; 160 std::string dalvik_cache; 161 GetDalvikCache(GetInstructionSetString(image_isa), true, &dalvik_cache, 162 &have_android_data, dalvik_cache_exists, is_global_cache); 163 164 if (have_android_data && *dalvik_cache_exists) { 165 // Always set output location even if it does not exist, 166 // so that the caller knows where to create the image. 167 // 168 // image_location = /system/framework/boot.art 169 // *image_filename = /data/dalvik-cache/<image_isa>/boot.art 170 std::string error_msg; 171 if (!GetDalvikCacheFilename(image_location, dalvik_cache.c_str(), cache_filename, &error_msg)) { 172 LOG(WARNING) << error_msg; 173 return *has_system; 174 } 175 *has_cache = OS::FileExists(cache_filename->c_str()); 176 } 177 return *has_system || *has_cache; 178 } 179 180 static bool ReadSpecificImageHeader(const char* filename, ImageHeader* image_header) { 181 std::unique_ptr<File> image_file(OS::OpenFileForReading(filename)); 182 if (image_file.get() == nullptr) { 183 return false; 184 } 185 const bool success = image_file->ReadFully(image_header, sizeof(ImageHeader)); 186 if (!success || !image_header->IsValid()) { 187 return false; 188 } 189 return true; 190 } 191 192 // Relocate the image at image_location to dest_filename and relocate it by a random amount. 193 static bool RelocateImage(const char* image_location, const char* dest_filename, 194 InstructionSet isa, std::string* error_msg) { 195 // We should clean up so we are more likely to have room for the image. 196 if (Runtime::Current()->IsZygote()) { 197 LOG(INFO) << "Pruning dalvik-cache since we are relocating an image and will need to recompile"; 198 PruneDalvikCache(isa); 199 } 200 201 std::string patchoat(Runtime::Current()->GetPatchoatExecutable()); 202 203 std::string input_image_location_arg("--input-image-location="); 204 input_image_location_arg += image_location; 205 206 std::string output_image_filename_arg("--output-image-file="); 207 output_image_filename_arg += dest_filename; 208 209 std::string instruction_set_arg("--instruction-set="); 210 instruction_set_arg += GetInstructionSetString(isa); 211 212 std::string base_offset_arg("--base-offset-delta="); 213 StringAppendF(&base_offset_arg, "%d", ChooseRelocationOffsetDelta(ART_BASE_ADDRESS_MIN_DELTA, 214 ART_BASE_ADDRESS_MAX_DELTA)); 215 216 std::vector<std::string> argv; 217 argv.push_back(patchoat); 218 219 argv.push_back(input_image_location_arg); 220 argv.push_back(output_image_filename_arg); 221 222 argv.push_back(instruction_set_arg); 223 argv.push_back(base_offset_arg); 224 225 std::string command_line(Join(argv, ' ')); 226 LOG(INFO) << "RelocateImage: " << command_line; 227 return Exec(argv, error_msg); 228 } 229 230 static ImageHeader* ReadSpecificImageHeader(const char* filename, std::string* error_msg) { 231 std::unique_ptr<ImageHeader> hdr(new ImageHeader); 232 if (!ReadSpecificImageHeader(filename, hdr.get())) { 233 *error_msg = StringPrintf("Unable to read image header for %s", filename); 234 return nullptr; 235 } 236 return hdr.release(); 237 } 238 239 ImageHeader* ImageSpace::ReadImageHeaderOrDie(const char* image_location, 240 const InstructionSet image_isa) { 241 std::string error_msg; 242 ImageHeader* image_header = ReadImageHeader(image_location, image_isa, &error_msg); 243 if (image_header == nullptr) { 244 LOG(FATAL) << error_msg; 245 } 246 return image_header; 247 } 248 249 ImageHeader* ImageSpace::ReadImageHeader(const char* image_location, 250 const InstructionSet image_isa, 251 std::string* error_msg) { 252 std::string system_filename; 253 bool has_system = false; 254 std::string cache_filename; 255 bool has_cache = false; 256 bool dalvik_cache_exists = false; 257 bool is_global_cache = false; 258 if (FindImageFilename(image_location, image_isa, &system_filename, &has_system, 259 &cache_filename, &dalvik_cache_exists, &has_cache, &is_global_cache)) { 260 if (Runtime::Current()->ShouldRelocate()) { 261 if (has_system && has_cache) { 262 std::unique_ptr<ImageHeader> sys_hdr(new ImageHeader); 263 std::unique_ptr<ImageHeader> cache_hdr(new ImageHeader); 264 if (!ReadSpecificImageHeader(system_filename.c_str(), sys_hdr.get())) { 265 *error_msg = StringPrintf("Unable to read image header for %s at %s", 266 image_location, system_filename.c_str()); 267 return nullptr; 268 } 269 if (!ReadSpecificImageHeader(cache_filename.c_str(), cache_hdr.get())) { 270 *error_msg = StringPrintf("Unable to read image header for %s at %s", 271 image_location, cache_filename.c_str()); 272 return nullptr; 273 } 274 if (sys_hdr->GetOatChecksum() != cache_hdr->GetOatChecksum()) { 275 *error_msg = StringPrintf("Unable to find a relocated version of image file %s", 276 image_location); 277 return nullptr; 278 } 279 return cache_hdr.release(); 280 } else if (!has_cache) { 281 *error_msg = StringPrintf("Unable to find a relocated version of image file %s", 282 image_location); 283 return nullptr; 284 } else if (!has_system && has_cache) { 285 // This can probably just use the cache one. 286 return ReadSpecificImageHeader(cache_filename.c_str(), error_msg); 287 } 288 } else { 289 // We don't want to relocate, Just pick the appropriate one if we have it and return. 290 if (has_system && has_cache) { 291 // We want the cache if the checksum matches, otherwise the system. 292 std::unique_ptr<ImageHeader> system(ReadSpecificImageHeader(system_filename.c_str(), 293 error_msg)); 294 std::unique_ptr<ImageHeader> cache(ReadSpecificImageHeader(cache_filename.c_str(), 295 error_msg)); 296 if (system.get() == nullptr || 297 (cache.get() != nullptr && cache->GetOatChecksum() == system->GetOatChecksum())) { 298 return cache.release(); 299 } else { 300 return system.release(); 301 } 302 } else if (has_system) { 303 return ReadSpecificImageHeader(system_filename.c_str(), error_msg); 304 } else if (has_cache) { 305 return ReadSpecificImageHeader(cache_filename.c_str(), error_msg); 306 } 307 } 308 } 309 310 *error_msg = StringPrintf("Unable to find image file for %s", image_location); 311 return nullptr; 312 } 313 314 static bool ChecksumsMatch(const char* image_a, const char* image_b) { 315 ImageHeader hdr_a; 316 ImageHeader hdr_b; 317 return ReadSpecificImageHeader(image_a, &hdr_a) && ReadSpecificImageHeader(image_b, &hdr_b) 318 && hdr_a.GetOatChecksum() == hdr_b.GetOatChecksum(); 319 } 320 321 static bool ImageCreationAllowed(bool is_global_cache, std::string* error_msg) { 322 // Anyone can write into a "local" cache. 323 if (!is_global_cache) { 324 return true; 325 } 326 327 // Only the zygote is allowed to create the global boot image. 328 if (Runtime::Current()->IsZygote()) { 329 return true; 330 } 331 332 *error_msg = "Only the zygote can create the global boot image."; 333 return false; 334 } 335 336 static constexpr uint64_t kLowSpaceValue = 50 * MB; 337 static constexpr uint64_t kTmpFsSentinelValue = 384 * MB; 338 339 // Read the free space of the cache partition and make a decision whether to keep the generated 340 // image. This is to try to mitigate situations where the system might run out of space later. 341 static bool CheckSpace(const std::string& cache_filename, std::string* error_msg) { 342 // Using statvfs vs statvfs64 because of b/18207376, and it is enough for all practical purposes. 343 struct statvfs buf; 344 345 int res = TEMP_FAILURE_RETRY(statvfs(cache_filename.c_str(), &buf)); 346 if (res != 0) { 347 // Could not stat. Conservatively tell the system to delete the image. 348 *error_msg = "Could not stat the filesystem, assuming low-memory situation."; 349 return false; 350 } 351 352 uint64_t fs_overall_size = buf.f_bsize * static_cast<uint64_t>(buf.f_blocks); 353 // Zygote is privileged, but other things are not. Use bavail. 354 uint64_t fs_free_size = buf.f_bsize * static_cast<uint64_t>(buf.f_bavail); 355 356 // Take the overall size as an indicator for a tmpfs, which is being used for the decryption 357 // environment. We do not want to fail quickening the boot image there, as it is beneficial 358 // for time-to-UI. 359 if (fs_overall_size > kTmpFsSentinelValue) { 360 if (fs_free_size < kLowSpaceValue) { 361 *error_msg = StringPrintf("Low-memory situation: only %4.2f megabytes available after image" 362 " generation, need at least %" PRIu64 ".", 363 static_cast<double>(fs_free_size) / MB, 364 kLowSpaceValue / MB); 365 return false; 366 } 367 } 368 return true; 369 } 370 371 ImageSpace* ImageSpace::CreateBootImage(const char* image_location, 372 const InstructionSet image_isa, 373 bool secondary_image, 374 std::string* error_msg) { 375 ScopedTrace trace(__FUNCTION__); 376 std::string system_filename; 377 bool has_system = false; 378 std::string cache_filename; 379 bool has_cache = false; 380 bool dalvik_cache_exists = false; 381 bool is_global_cache = true; 382 bool found_image = FindImageFilename(image_location, image_isa, &system_filename, 383 &has_system, &cache_filename, &dalvik_cache_exists, 384 &has_cache, &is_global_cache); 385 386 const bool is_zygote = Runtime::Current()->IsZygote(); 387 if (is_zygote && !secondary_image) { 388 MarkZygoteStart(image_isa, Runtime::Current()->GetZygoteMaxFailedBoots()); 389 } 390 391 ImageSpace* space; 392 bool relocate = Runtime::Current()->ShouldRelocate(); 393 bool can_compile = Runtime::Current()->IsImageDex2OatEnabled(); 394 if (found_image) { 395 const std::string* image_filename; 396 bool is_system = false; 397 bool relocated_version_used = false; 398 if (relocate) { 399 if (!dalvik_cache_exists) { 400 *error_msg = StringPrintf("Requiring relocation for image '%s' at '%s' but we do not have " 401 "any dalvik_cache to find/place it in.", 402 image_location, system_filename.c_str()); 403 return nullptr; 404 } 405 if (has_system) { 406 if (has_cache && ChecksumsMatch(system_filename.c_str(), cache_filename.c_str())) { 407 // We already have a relocated version 408 image_filename = &cache_filename; 409 relocated_version_used = true; 410 } else { 411 // We cannot have a relocated version, Relocate the system one and use it. 412 413 std::string reason; 414 bool success; 415 416 // Check whether we are allowed to relocate. 417 if (!can_compile) { 418 reason = "Image dex2oat disabled by -Xnoimage-dex2oat."; 419 success = false; 420 } else if (!ImageCreationAllowed(is_global_cache, &reason)) { 421 // Whether we can write to the cache. 422 success = false; 423 } else if (secondary_image) { 424 if (is_zygote) { 425 // Secondary image is out of date. Clear cache and exit to let it retry from scratch. 426 LOG(ERROR) << "Cannot patch secondary image '" << image_location 427 << "', clearing dalvik_cache and restarting zygote."; 428 PruneDalvikCache(image_isa); 429 _exit(1); 430 } else { 431 reason = "Should not have to patch secondary image."; 432 success = false; 433 } 434 } else { 435 // Try to relocate. 436 success = RelocateImage(image_location, cache_filename.c_str(), image_isa, &reason); 437 } 438 439 if (success) { 440 relocated_version_used = true; 441 image_filename = &cache_filename; 442 } else { 443 *error_msg = StringPrintf("Unable to relocate image '%s' from '%s' to '%s': %s", 444 image_location, system_filename.c_str(), 445 cache_filename.c_str(), reason.c_str()); 446 // We failed to create files, remove any possibly garbage output. 447 // Since ImageCreationAllowed was true above, we are the zygote 448 // and therefore the only process expected to generate these for 449 // the device. 450 PruneDalvikCache(image_isa); 451 return nullptr; 452 } 453 } 454 } else { 455 CHECK(has_cache); 456 // We can just use cache's since it should be fine. This might or might not be relocated. 457 image_filename = &cache_filename; 458 } 459 } else { 460 if (has_system && has_cache) { 461 // Check they have the same cksum. If they do use the cache. Otherwise system. 462 if (ChecksumsMatch(system_filename.c_str(), cache_filename.c_str())) { 463 image_filename = &cache_filename; 464 relocated_version_used = true; 465 } else { 466 image_filename = &system_filename; 467 is_system = true; 468 } 469 } else if (has_system) { 470 image_filename = &system_filename; 471 is_system = true; 472 } else { 473 CHECK(has_cache); 474 image_filename = &cache_filename; 475 } 476 } 477 { 478 // Note that we must not use the file descriptor associated with 479 // ScopedFlock::GetFile to Init the image file. We want the file 480 // descriptor (and the associated exclusive lock) to be released when 481 // we leave Create. 482 ScopedFlock image_lock; 483 // Should this be a RDWR lock? This is only a defensive measure, as at 484 // this point the image should exist. 485 // However, only the zygote can write into the global dalvik-cache, so 486 // restrict to zygote processes, or any process that isn't using 487 // /data/dalvik-cache (which we assume to be allowed to write there). 488 const bool rw_lock = is_zygote || !is_global_cache; 489 image_lock.Init(image_filename->c_str(), 490 rw_lock ? (O_CREAT | O_RDWR) : O_RDONLY /* flags */, 491 true /* block */, 492 error_msg); 493 VLOG(startup) << "Using image file " << image_filename->c_str() << " for image location " 494 << image_location; 495 // If we are in /system we can assume the image is good. We can also 496 // assume this if we are using a relocated image (i.e. image checksum 497 // matches) since this is only different by the offset. We need this to 498 // make sure that host tests continue to work. 499 // Since we are the boot image, pass null since we load the oat file from the boot image oat 500 // file name. 501 space = ImageSpace::Init(image_filename->c_str(), 502 image_location, 503 !(is_system || relocated_version_used), 504 /* oat_file */nullptr, 505 error_msg); 506 } 507 if (space != nullptr) { 508 // Check whether there is enough space left over in the data partition. Even if we can load 509 // the image, we need to be conservative, as some parts of the platform are not very tolerant 510 // of space constraints. 511 // ImageSpace doesn't know about the data partition per se, it relies on the FindImageFilename 512 // helper (which relies on GetDalvikCache). So for now, if we load an image out of /system, 513 // ignore the check (as it would test for free space in /system instead). 514 if (!is_system && !CheckSpace(*image_filename, error_msg)) { 515 // No. Delete the generated image and try to run out of the dex files. 516 PruneDalvikCache(image_isa); 517 return nullptr; 518 } 519 return space; 520 } 521 522 if (relocated_version_used) { 523 // Something is wrong with the relocated copy (even though checksums match). Cleanup. 524 // This can happen if the .oat is corrupt, since the above only checks the .art checksums. 525 // TODO: Check the oat file validity earlier. 526 *error_msg = StringPrintf("Attempted to use relocated version of %s at %s generated from %s " 527 "but image failed to load: %s", 528 image_location, cache_filename.c_str(), system_filename.c_str(), 529 error_msg->c_str()); 530 PruneDalvikCache(image_isa); 531 return nullptr; 532 } else if (is_system) { 533 // If the /system file exists, it should be up-to-date, don't try to generate it. 534 *error_msg = StringPrintf("Failed to load /system image '%s': %s", 535 image_filename->c_str(), error_msg->c_str()); 536 return nullptr; 537 } else { 538 // Otherwise, log a warning and fall through to GenerateImage. 539 LOG(WARNING) << *error_msg; 540 } 541 } 542 543 if (!can_compile) { 544 *error_msg = "Not attempting to compile image because -Xnoimage-dex2oat"; 545 return nullptr; 546 } else if (!dalvik_cache_exists) { 547 *error_msg = StringPrintf("No place to put generated image."); 548 return nullptr; 549 } else if (!ImageCreationAllowed(is_global_cache, error_msg)) { 550 return nullptr; 551 } else if (secondary_image) { 552 *error_msg = "Cannot compile a secondary image."; 553 return nullptr; 554 } else if (!GenerateImage(cache_filename, image_isa, error_msg)) { 555 *error_msg = StringPrintf("Failed to generate image '%s': %s", 556 cache_filename.c_str(), error_msg->c_str()); 557 // We failed to create files, remove any possibly garbage output. 558 // Since ImageCreationAllowed was true above, we are the zygote 559 // and therefore the only process expected to generate these for 560 // the device. 561 PruneDalvikCache(image_isa); 562 return nullptr; 563 } else { 564 // Check whether there is enough space left over after we have generated the image. 565 if (!CheckSpace(cache_filename, error_msg)) { 566 // No. Delete the generated image and try to run out of the dex files. 567 PruneDalvikCache(image_isa); 568 return nullptr; 569 } 570 571 // Note that we must not use the file descriptor associated with 572 // ScopedFlock::GetFile to Init the image file. We want the file 573 // descriptor (and the associated exclusive lock) to be released when 574 // we leave Create. 575 ScopedFlock image_lock; 576 image_lock.Init(cache_filename.c_str(), error_msg); 577 space = ImageSpace::Init(cache_filename.c_str(), image_location, true, nullptr, error_msg); 578 if (space == nullptr) { 579 *error_msg = StringPrintf("Failed to load generated image '%s': %s", 580 cache_filename.c_str(), error_msg->c_str()); 581 } 582 return space; 583 } 584 } 585 586 void ImageSpace::VerifyImageAllocations() { 587 uint8_t* current = Begin() + RoundUp(sizeof(ImageHeader), kObjectAlignment); 588 while (current < End()) { 589 CHECK_ALIGNED(current, kObjectAlignment); 590 auto* obj = reinterpret_cast<mirror::Object*>(current); 591 CHECK(obj->GetClass() != nullptr) << "Image object at address " << obj << " has null class"; 592 CHECK(live_bitmap_->Test(obj)) << PrettyTypeOf(obj); 593 if (kUseBakerOrBrooksReadBarrier) { 594 obj->AssertReadBarrierPointer(); 595 } 596 current += RoundUp(obj->SizeOf(), kObjectAlignment); 597 } 598 } 599 600 // Helper class for relocating from one range of memory to another. 601 class RelocationRange { 602 public: 603 RelocationRange() = default; 604 RelocationRange(const RelocationRange&) = default; 605 RelocationRange(uintptr_t source, uintptr_t dest, uintptr_t length) 606 : source_(source), 607 dest_(dest), 608 length_(length) {} 609 610 bool InSource(uintptr_t address) const { 611 return address - source_ < length_; 612 } 613 614 bool InDest(uintptr_t address) const { 615 return address - dest_ < length_; 616 } 617 618 // Translate a source address to the destination space. 619 uintptr_t ToDest(uintptr_t address) const { 620 DCHECK(InSource(address)); 621 return address + Delta(); 622 } 623 624 // Returns the delta between the dest from the source. 625 uintptr_t Delta() const { 626 return dest_ - source_; 627 } 628 629 uintptr_t Source() const { 630 return source_; 631 } 632 633 uintptr_t Dest() const { 634 return dest_; 635 } 636 637 uintptr_t Length() const { 638 return length_; 639 } 640 641 private: 642 const uintptr_t source_; 643 const uintptr_t dest_; 644 const uintptr_t length_; 645 }; 646 647 std::ostream& operator<<(std::ostream& os, const RelocationRange& reloc) { 648 return os << "(" << reinterpret_cast<const void*>(reloc.Source()) << "-" 649 << reinterpret_cast<const void*>(reloc.Source() + reloc.Length()) << ")->(" 650 << reinterpret_cast<const void*>(reloc.Dest()) << "-" 651 << reinterpret_cast<const void*>(reloc.Dest() + reloc.Length()) << ")"; 652 } 653 654 class FixupVisitor : public ValueObject { 655 public: 656 FixupVisitor(const RelocationRange& boot_image, 657 const RelocationRange& boot_oat, 658 const RelocationRange& app_image, 659 const RelocationRange& app_oat) 660 : boot_image_(boot_image), 661 boot_oat_(boot_oat), 662 app_image_(app_image), 663 app_oat_(app_oat) {} 664 665 // Return the relocated address of a heap object. 666 template <typename T> 667 ALWAYS_INLINE T* ForwardObject(T* src) const { 668 const uintptr_t uint_src = reinterpret_cast<uintptr_t>(src); 669 if (boot_image_.InSource(uint_src)) { 670 return reinterpret_cast<T*>(boot_image_.ToDest(uint_src)); 671 } 672 if (app_image_.InSource(uint_src)) { 673 return reinterpret_cast<T*>(app_image_.ToDest(uint_src)); 674 } 675 // Since we are fixing up the app image, there should only be pointers to the app image and 676 // boot image. 677 DCHECK(src == nullptr) << reinterpret_cast<const void*>(src); 678 return src; 679 } 680 681 // Return the relocated address of a code pointer (contained by an oat file). 682 ALWAYS_INLINE const void* ForwardCode(const void* src) const { 683 const uintptr_t uint_src = reinterpret_cast<uintptr_t>(src); 684 if (boot_oat_.InSource(uint_src)) { 685 return reinterpret_cast<const void*>(boot_oat_.ToDest(uint_src)); 686 } 687 if (app_oat_.InSource(uint_src)) { 688 return reinterpret_cast<const void*>(app_oat_.ToDest(uint_src)); 689 } 690 DCHECK(src == nullptr) << src; 691 return src; 692 } 693 694 // Must be called on pointers that already have been relocated to the destination relocation. 695 ALWAYS_INLINE bool IsInAppImage(mirror::Object* object) const { 696 return app_image_.InDest(reinterpret_cast<uintptr_t>(object)); 697 } 698 699 protected: 700 // Source section. 701 const RelocationRange boot_image_; 702 const RelocationRange boot_oat_; 703 const RelocationRange app_image_; 704 const RelocationRange app_oat_; 705 }; 706 707 // Adapt for mirror::Class::FixupNativePointers. 708 class FixupObjectAdapter : public FixupVisitor { 709 public: 710 template<typename... Args> 711 explicit FixupObjectAdapter(Args... args) : FixupVisitor(args...) {} 712 713 template <typename T> 714 T* operator()(T* obj) const { 715 return ForwardObject(obj); 716 } 717 }; 718 719 class FixupRootVisitor : public FixupVisitor { 720 public: 721 template<typename... Args> 722 explicit FixupRootVisitor(Args... args) : FixupVisitor(args...) {} 723 724 ALWAYS_INLINE void VisitRootIfNonNull(mirror::CompressedReference<mirror::Object>* root) const 725 SHARED_REQUIRES(Locks::mutator_lock_) { 726 if (!root->IsNull()) { 727 VisitRoot(root); 728 } 729 } 730 731 ALWAYS_INLINE void VisitRoot(mirror::CompressedReference<mirror::Object>* root) const 732 SHARED_REQUIRES(Locks::mutator_lock_) { 733 mirror::Object* ref = root->AsMirrorPtr(); 734 mirror::Object* new_ref = ForwardObject(ref); 735 if (ref != new_ref) { 736 root->Assign(new_ref); 737 } 738 } 739 }; 740 741 class FixupObjectVisitor : public FixupVisitor { 742 public: 743 template<typename... Args> 744 explicit FixupObjectVisitor(gc::accounting::ContinuousSpaceBitmap* visited, 745 const size_t pointer_size, 746 Args... args) 747 : FixupVisitor(args...), 748 pointer_size_(pointer_size), 749 visited_(visited) {} 750 751 // Fix up separately since we also need to fix up method entrypoints. 752 ALWAYS_INLINE void VisitRootIfNonNull( 753 mirror::CompressedReference<mirror::Object>* root ATTRIBUTE_UNUSED) const {} 754 755 ALWAYS_INLINE void VisitRoot(mirror::CompressedReference<mirror::Object>* root ATTRIBUTE_UNUSED) 756 const {} 757 758 ALWAYS_INLINE void operator()(mirror::Object* obj, 759 MemberOffset offset, 760 bool is_static ATTRIBUTE_UNUSED) const 761 NO_THREAD_SAFETY_ANALYSIS { 762 // There could be overlap between ranges, we must avoid visiting the same reference twice. 763 // Avoid the class field since we already fixed it up in FixupClassVisitor. 764 if (offset.Uint32Value() != mirror::Object::ClassOffset().Uint32Value()) { 765 // Space is not yet added to the heap, don't do a read barrier. 766 mirror::Object* ref = obj->GetFieldObject<mirror::Object, kVerifyNone, kWithoutReadBarrier>( 767 offset); 768 // Use SetFieldObjectWithoutWriteBarrier to avoid card marking since we are writing to the 769 // image. 770 obj->SetFieldObjectWithoutWriteBarrier<false, true, kVerifyNone>(offset, ForwardObject(ref)); 771 } 772 } 773 774 // Visit a pointer array and forward corresponding native data. Ignores pointer arrays in the 775 // boot image. Uses the bitmap to ensure the same array is not visited multiple times. 776 template <typename Visitor> 777 void UpdatePointerArrayContents(mirror::PointerArray* array, const Visitor& visitor) const 778 NO_THREAD_SAFETY_ANALYSIS { 779 DCHECK(array != nullptr); 780 DCHECK(visitor.IsInAppImage(array)); 781 // The bit for the array contents is different than the bit for the array. Since we may have 782 // already visited the array as a long / int array from walking the bitmap without knowing it 783 // was a pointer array. 784 static_assert(kObjectAlignment == 8u, "array bit may be in another object"); 785 mirror::Object* const contents_bit = reinterpret_cast<mirror::Object*>( 786 reinterpret_cast<uintptr_t>(array) + kObjectAlignment); 787 // If the bit is not set then the contents have not yet been updated. 788 if (!visited_->Test(contents_bit)) { 789 array->Fixup<kVerifyNone, kWithoutReadBarrier>(array, pointer_size_, visitor); 790 visited_->Set(contents_bit); 791 } 792 } 793 794 // java.lang.ref.Reference visitor. 795 void operator()(mirror::Class* klass ATTRIBUTE_UNUSED, mirror::Reference* ref) const 796 SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(Locks::heap_bitmap_lock_) { 797 mirror::Object* obj = ref->GetReferent<kWithoutReadBarrier>(); 798 ref->SetFieldObjectWithoutWriteBarrier<false, true, kVerifyNone>( 799 mirror::Reference::ReferentOffset(), 800 ForwardObject(obj)); 801 } 802 803 void operator()(mirror::Object* obj) const NO_THREAD_SAFETY_ANALYSIS { 804 if (visited_->Test(obj)) { 805 // Already visited. 806 return; 807 } 808 visited_->Set(obj); 809 810 // Handle class specially first since we need it to be updated to properly visit the rest of 811 // the instance fields. 812 { 813 mirror::Class* klass = obj->GetClass<kVerifyNone, kWithoutReadBarrier>(); 814 DCHECK(klass != nullptr) << "Null class in image"; 815 // No AsClass since our fields aren't quite fixed up yet. 816 mirror::Class* new_klass = down_cast<mirror::Class*>(ForwardObject(klass)); 817 if (klass != new_klass) { 818 obj->SetClass<kVerifyNone>(new_klass); 819 } 820 if (new_klass != klass && IsInAppImage(new_klass)) { 821 // Make sure the klass contents are fixed up since we depend on it to walk the fields. 822 operator()(new_klass); 823 } 824 } 825 826 obj->VisitReferences</*visit native roots*/false, kVerifyNone, kWithoutReadBarrier>( 827 *this, 828 *this); 829 // Note that this code relies on no circular dependencies. 830 // We want to use our own class loader and not the one in the image. 831 if (obj->IsClass<kVerifyNone, kWithoutReadBarrier>()) { 832 mirror::Class* as_klass = obj->AsClass<kVerifyNone, kWithoutReadBarrier>(); 833 FixupObjectAdapter visitor(boot_image_, boot_oat_, app_image_, app_oat_); 834 as_klass->FixupNativePointers<kVerifyNone, kWithoutReadBarrier>(as_klass, 835 pointer_size_, 836 visitor); 837 // Deal with the pointer arrays. Use the helper function since multiple classes can reference 838 // the same arrays. 839 mirror::PointerArray* const vtable = as_klass->GetVTable<kVerifyNone, kWithoutReadBarrier>(); 840 if (vtable != nullptr && IsInAppImage(vtable)) { 841 operator()(vtable); 842 UpdatePointerArrayContents(vtable, visitor); 843 } 844 mirror::IfTable* iftable = as_klass->GetIfTable<kVerifyNone, kWithoutReadBarrier>(); 845 // Ensure iftable arrays are fixed up since we need GetMethodArray to return the valid 846 // contents. 847 if (iftable != nullptr && IsInAppImage(iftable)) { 848 operator()(iftable); 849 for (int32_t i = 0, count = iftable->Count(); i < count; ++i) { 850 if (iftable->GetMethodArrayCount<kVerifyNone, kWithoutReadBarrier>(i) > 0) { 851 mirror::PointerArray* methods = 852 iftable->GetMethodArray<kVerifyNone, kWithoutReadBarrier>(i); 853 if (visitor.IsInAppImage(methods)) { 854 operator()(methods); 855 DCHECK(methods != nullptr); 856 UpdatePointerArrayContents(methods, visitor); 857 } 858 } 859 } 860 } 861 } 862 } 863 864 private: 865 const size_t pointer_size_; 866 gc::accounting::ContinuousSpaceBitmap* const visited_; 867 }; 868 869 class ForwardObjectAdapter { 870 public: 871 ALWAYS_INLINE ForwardObjectAdapter(const FixupVisitor* visitor) : visitor_(visitor) {} 872 873 template <typename T> 874 ALWAYS_INLINE T* operator()(T* src) const { 875 return visitor_->ForwardObject(src); 876 } 877 878 private: 879 const FixupVisitor* const visitor_; 880 }; 881 882 class ForwardCodeAdapter { 883 public: 884 ALWAYS_INLINE ForwardCodeAdapter(const FixupVisitor* visitor) 885 : visitor_(visitor) {} 886 887 template <typename T> 888 ALWAYS_INLINE T* operator()(T* src) const { 889 return visitor_->ForwardCode(src); 890 } 891 892 private: 893 const FixupVisitor* const visitor_; 894 }; 895 896 class FixupArtMethodVisitor : public FixupVisitor, public ArtMethodVisitor { 897 public: 898 template<typename... Args> 899 explicit FixupArtMethodVisitor(bool fixup_heap_objects, size_t pointer_size, Args... args) 900 : FixupVisitor(args...), 901 fixup_heap_objects_(fixup_heap_objects), 902 pointer_size_(pointer_size) {} 903 904 virtual void Visit(ArtMethod* method) NO_THREAD_SAFETY_ANALYSIS { 905 // TODO: Separate visitor for runtime vs normal methods. 906 if (UNLIKELY(method->IsRuntimeMethod())) { 907 ImtConflictTable* table = method->GetImtConflictTable(pointer_size_); 908 if (table != nullptr) { 909 ImtConflictTable* new_table = ForwardObject(table); 910 if (table != new_table) { 911 method->SetImtConflictTable(new_table, pointer_size_); 912 } 913 } 914 const void* old_code = method->GetEntryPointFromQuickCompiledCodePtrSize(pointer_size_); 915 const void* new_code = ForwardCode(old_code); 916 if (old_code != new_code) { 917 method->SetEntryPointFromQuickCompiledCodePtrSize(new_code, pointer_size_); 918 } 919 } else { 920 if (fixup_heap_objects_) { 921 method->UpdateObjectsForImageRelocation(ForwardObjectAdapter(this), pointer_size_); 922 } 923 method->UpdateEntrypoints<kWithoutReadBarrier>(ForwardCodeAdapter(this), pointer_size_); 924 } 925 } 926 927 private: 928 const bool fixup_heap_objects_; 929 const size_t pointer_size_; 930 }; 931 932 class FixupArtFieldVisitor : public FixupVisitor, public ArtFieldVisitor { 933 public: 934 template<typename... Args> 935 explicit FixupArtFieldVisitor(Args... args) : FixupVisitor(args...) {} 936 937 virtual void Visit(ArtField* field) NO_THREAD_SAFETY_ANALYSIS { 938 field->UpdateObjects(ForwardObjectAdapter(this)); 939 } 940 }; 941 942 // Relocate an image space mapped at target_base which possibly used to be at a different base 943 // address. Only needs a single image space, not one for both source and destination. 944 // In place means modifying a single ImageSpace in place rather than relocating from one ImageSpace 945 // to another. 946 static bool RelocateInPlace(ImageHeader& image_header, 947 uint8_t* target_base, 948 accounting::ContinuousSpaceBitmap* bitmap, 949 const OatFile* app_oat_file, 950 std::string* error_msg) { 951 DCHECK(error_msg != nullptr); 952 if (!image_header.IsPic()) { 953 if (image_header.GetImageBegin() == target_base) { 954 return true; 955 } 956 *error_msg = StringPrintf("Cannot relocate non-pic image for oat file %s", 957 (app_oat_file != nullptr) ? app_oat_file->GetLocation().c_str() : ""); 958 return false; 959 } 960 // Set up sections. 961 uint32_t boot_image_begin = 0; 962 uint32_t boot_image_end = 0; 963 uint32_t boot_oat_begin = 0; 964 uint32_t boot_oat_end = 0; 965 const size_t pointer_size = image_header.GetPointerSize(); 966 gc::Heap* const heap = Runtime::Current()->GetHeap(); 967 heap->GetBootImagesSize(&boot_image_begin, &boot_image_end, &boot_oat_begin, &boot_oat_end); 968 if (boot_image_begin == boot_image_end) { 969 *error_msg = "Can not relocate app image without boot image space"; 970 return false; 971 } 972 if (boot_oat_begin == boot_oat_end) { 973 *error_msg = "Can not relocate app image without boot oat file"; 974 return false; 975 } 976 const uint32_t boot_image_size = boot_image_end - boot_image_begin; 977 const uint32_t boot_oat_size = boot_oat_end - boot_oat_begin; 978 const uint32_t image_header_boot_image_size = image_header.GetBootImageSize(); 979 const uint32_t image_header_boot_oat_size = image_header.GetBootOatSize(); 980 if (boot_image_size != image_header_boot_image_size) { 981 *error_msg = StringPrintf("Boot image size %" PRIu64 " does not match expected size %" 982 PRIu64, 983 static_cast<uint64_t>(boot_image_size), 984 static_cast<uint64_t>(image_header_boot_image_size)); 985 return false; 986 } 987 if (boot_oat_size != image_header_boot_oat_size) { 988 *error_msg = StringPrintf("Boot oat size %" PRIu64 " does not match expected size %" 989 PRIu64, 990 static_cast<uint64_t>(boot_oat_size), 991 static_cast<uint64_t>(image_header_boot_oat_size)); 992 return false; 993 } 994 TimingLogger logger(__FUNCTION__, true, false); 995 RelocationRange boot_image(image_header.GetBootImageBegin(), 996 boot_image_begin, 997 boot_image_size); 998 RelocationRange boot_oat(image_header.GetBootOatBegin(), 999 boot_oat_begin, 1000 boot_oat_size); 1001 RelocationRange app_image(reinterpret_cast<uintptr_t>(image_header.GetImageBegin()), 1002 reinterpret_cast<uintptr_t>(target_base), 1003 image_header.GetImageSize()); 1004 // Use the oat data section since this is where the OatFile::Begin is. 1005 RelocationRange app_oat(reinterpret_cast<uintptr_t>(image_header.GetOatDataBegin()), 1006 // Not necessarily in low 4GB. 1007 reinterpret_cast<uintptr_t>(app_oat_file->Begin()), 1008 image_header.GetOatDataEnd() - image_header.GetOatDataBegin()); 1009 VLOG(image) << "App image " << app_image; 1010 VLOG(image) << "App oat " << app_oat; 1011 VLOG(image) << "Boot image " << boot_image; 1012 VLOG(image) << "Boot oat " << boot_oat; 1013 // True if we need to fixup any heap pointers, otherwise only code pointers. 1014 const bool fixup_image = boot_image.Delta() != 0 || app_image.Delta() != 0; 1015 const bool fixup_code = boot_oat.Delta() != 0 || app_oat.Delta() != 0; 1016 if (!fixup_image && !fixup_code) { 1017 // Nothing to fix up. 1018 return true; 1019 } 1020 ScopedDebugDisallowReadBarriers sddrb(Thread::Current()); 1021 // Need to update the image to be at the target base. 1022 const ImageSection& objects_section = image_header.GetImageSection(ImageHeader::kSectionObjects); 1023 uintptr_t objects_begin = reinterpret_cast<uintptr_t>(target_base + objects_section.Offset()); 1024 uintptr_t objects_end = reinterpret_cast<uintptr_t>(target_base + objects_section.End()); 1025 FixupObjectAdapter fixup_adapter(boot_image, boot_oat, app_image, app_oat); 1026 if (fixup_image) { 1027 // Two pass approach, fix up all classes first, then fix up non class-objects. 1028 // The visited bitmap is used to ensure that pointer arrays are not forwarded twice. 1029 std::unique_ptr<gc::accounting::ContinuousSpaceBitmap> visited_bitmap( 1030 gc::accounting::ContinuousSpaceBitmap::Create("Relocate bitmap", 1031 target_base, 1032 image_header.GetImageSize())); 1033 FixupObjectVisitor fixup_object_visitor(visited_bitmap.get(), 1034 pointer_size, 1035 boot_image, 1036 boot_oat, 1037 app_image, 1038 app_oat); 1039 TimingLogger::ScopedTiming timing("Fixup classes", &logger); 1040 // Fixup objects may read fields in the boot image, use the mutator lock here for sanity. Though 1041 // its probably not required. 1042 ScopedObjectAccess soa(Thread::Current()); 1043 timing.NewTiming("Fixup objects"); 1044 bitmap->VisitMarkedRange(objects_begin, objects_end, fixup_object_visitor); 1045 // Fixup image roots. 1046 CHECK(app_image.InSource(reinterpret_cast<uintptr_t>( 1047 image_header.GetImageRoots<kWithoutReadBarrier>()))); 1048 image_header.RelocateImageObjects(app_image.Delta()); 1049 CHECK_EQ(image_header.GetImageBegin(), target_base); 1050 // Fix up dex cache DexFile pointers. 1051 auto* dex_caches = image_header.GetImageRoot<kWithoutReadBarrier>(ImageHeader::kDexCaches)-> 1052 AsObjectArray<mirror::DexCache, kVerifyNone, kWithoutReadBarrier>(); 1053 for (int32_t i = 0, count = dex_caches->GetLength(); i < count; ++i) { 1054 mirror::DexCache* dex_cache = dex_caches->Get<kVerifyNone, kWithoutReadBarrier>(i); 1055 // Fix up dex cache pointers. 1056 GcRoot<mirror::String>* strings = dex_cache->GetStrings(); 1057 if (strings != nullptr) { 1058 GcRoot<mirror::String>* new_strings = fixup_adapter.ForwardObject(strings); 1059 if (strings != new_strings) { 1060 dex_cache->SetStrings(new_strings); 1061 } 1062 dex_cache->FixupStrings<kWithoutReadBarrier>(new_strings, fixup_adapter); 1063 } 1064 GcRoot<mirror::Class>* types = dex_cache->GetResolvedTypes(); 1065 if (types != nullptr) { 1066 GcRoot<mirror::Class>* new_types = fixup_adapter.ForwardObject(types); 1067 if (types != new_types) { 1068 dex_cache->SetResolvedTypes(new_types); 1069 } 1070 dex_cache->FixupResolvedTypes<kWithoutReadBarrier>(new_types, fixup_adapter); 1071 } 1072 ArtMethod** methods = dex_cache->GetResolvedMethods(); 1073 if (methods != nullptr) { 1074 ArtMethod** new_methods = fixup_adapter.ForwardObject(methods); 1075 if (methods != new_methods) { 1076 dex_cache->SetResolvedMethods(new_methods); 1077 } 1078 for (size_t j = 0, num = dex_cache->NumResolvedMethods(); j != num; ++j) { 1079 ArtMethod* orig = mirror::DexCache::GetElementPtrSize(new_methods, j, pointer_size); 1080 ArtMethod* copy = fixup_adapter.ForwardObject(orig); 1081 if (orig != copy) { 1082 mirror::DexCache::SetElementPtrSize(new_methods, j, copy, pointer_size); 1083 } 1084 } 1085 } 1086 ArtField** fields = dex_cache->GetResolvedFields(); 1087 if (fields != nullptr) { 1088 ArtField** new_fields = fixup_adapter.ForwardObject(fields); 1089 if (fields != new_fields) { 1090 dex_cache->SetResolvedFields(new_fields); 1091 } 1092 for (size_t j = 0, num = dex_cache->NumResolvedFields(); j != num; ++j) { 1093 ArtField* orig = mirror::DexCache::GetElementPtrSize(new_fields, j, pointer_size); 1094 ArtField* copy = fixup_adapter.ForwardObject(orig); 1095 if (orig != copy) { 1096 mirror::DexCache::SetElementPtrSize(new_fields, j, copy, pointer_size); 1097 } 1098 } 1099 } 1100 } 1101 } 1102 { 1103 // Only touches objects in the app image, no need for mutator lock. 1104 TimingLogger::ScopedTiming timing("Fixup methods", &logger); 1105 FixupArtMethodVisitor method_visitor(fixup_image, 1106 pointer_size, 1107 boot_image, 1108 boot_oat, 1109 app_image, 1110 app_oat); 1111 image_header.VisitPackedArtMethods(&method_visitor, target_base, pointer_size); 1112 } 1113 if (fixup_image) { 1114 { 1115 // Only touches objects in the app image, no need for mutator lock. 1116 TimingLogger::ScopedTiming timing("Fixup fields", &logger); 1117 FixupArtFieldVisitor field_visitor(boot_image, boot_oat, app_image, app_oat); 1118 image_header.VisitPackedArtFields(&field_visitor, target_base); 1119 } 1120 { 1121 TimingLogger::ScopedTiming timing("Fixup imt", &logger); 1122 image_header.VisitPackedImTables(fixup_adapter, target_base, pointer_size); 1123 } 1124 { 1125 TimingLogger::ScopedTiming timing("Fixup conflict tables", &logger); 1126 image_header.VisitPackedImtConflictTables(fixup_adapter, target_base, pointer_size); 1127 } 1128 // In the app image case, the image methods are actually in the boot image. 1129 image_header.RelocateImageMethods(boot_image.Delta()); 1130 const auto& class_table_section = image_header.GetImageSection(ImageHeader::kSectionClassTable); 1131 if (class_table_section.Size() > 0u) { 1132 // Note that we require that ReadFromMemory does not make an internal copy of the elements. 1133 // This also relies on visit roots not doing any verification which could fail after we update 1134 // the roots to be the image addresses. 1135 ScopedObjectAccess soa(Thread::Current()); 1136 WriterMutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_); 1137 ClassTable temp_table; 1138 temp_table.ReadFromMemory(target_base + class_table_section.Offset()); 1139 FixupRootVisitor root_visitor(boot_image, boot_oat, app_image, app_oat); 1140 temp_table.VisitRoots(root_visitor); 1141 } 1142 } 1143 if (VLOG_IS_ON(image)) { 1144 logger.Dump(LOG(INFO)); 1145 } 1146 return true; 1147 } 1148 1149 ImageSpace* ImageSpace::Init(const char* image_filename, 1150 const char* image_location, 1151 bool validate_oat_file, 1152 const OatFile* oat_file, 1153 std::string* error_msg) { 1154 CHECK(image_filename != nullptr); 1155 CHECK(image_location != nullptr); 1156 1157 TimingLogger logger(__PRETTY_FUNCTION__, true, VLOG_IS_ON(image)); 1158 VLOG(image) << "ImageSpace::Init entering image_filename=" << image_filename; 1159 1160 std::unique_ptr<File> file; 1161 { 1162 TimingLogger::ScopedTiming timing("OpenImageFile", &logger); 1163 file.reset(OS::OpenFileForReading(image_filename)); 1164 if (file == nullptr) { 1165 *error_msg = StringPrintf("Failed to open '%s'", image_filename); 1166 return nullptr; 1167 } 1168 } 1169 ImageHeader temp_image_header; 1170 ImageHeader* image_header = &temp_image_header; 1171 { 1172 TimingLogger::ScopedTiming timing("ReadImageHeader", &logger); 1173 bool success = file->ReadFully(image_header, sizeof(*image_header)); 1174 if (!success || !image_header->IsValid()) { 1175 *error_msg = StringPrintf("Invalid image header in '%s'", image_filename); 1176 return nullptr; 1177 } 1178 } 1179 // Check that the file is larger or equal to the header size + data size. 1180 const uint64_t image_file_size = static_cast<uint64_t>(file->GetLength()); 1181 if (image_file_size < sizeof(ImageHeader) + image_header->GetDataSize()) { 1182 *error_msg = StringPrintf("Image file truncated: %" PRIu64 " vs. %" PRIu64 ".", 1183 image_file_size, 1184 sizeof(ImageHeader) + image_header->GetDataSize()); 1185 return nullptr; 1186 } 1187 1188 if (oat_file != nullptr) { 1189 // If we have an oat file, check the oat file checksum. The oat file is only non-null for the 1190 // app image case. Otherwise, we open the oat file after the image and check the checksum there. 1191 const uint32_t oat_checksum = oat_file->GetOatHeader().GetChecksum(); 1192 const uint32_t image_oat_checksum = image_header->GetOatChecksum(); 1193 if (oat_checksum != image_oat_checksum) { 1194 *error_msg = StringPrintf("Oat checksum 0x%x does not match the image one 0x%x in image %s", 1195 oat_checksum, 1196 image_oat_checksum, 1197 image_filename); 1198 return nullptr; 1199 } 1200 } 1201 1202 if (VLOG_IS_ON(startup)) { 1203 LOG(INFO) << "Dumping image sections"; 1204 for (size_t i = 0; i < ImageHeader::kSectionCount; ++i) { 1205 const auto section_idx = static_cast<ImageHeader::ImageSections>(i); 1206 auto& section = image_header->GetImageSection(section_idx); 1207 LOG(INFO) << section_idx << " start=" 1208 << reinterpret_cast<void*>(image_header->GetImageBegin() + section.Offset()) << " " 1209 << section; 1210 } 1211 } 1212 1213 const auto& bitmap_section = image_header->GetImageSection(ImageHeader::kSectionImageBitmap); 1214 // The location we want to map from is the first aligned page after the end of the stored 1215 // (possibly compressed) data. 1216 const size_t image_bitmap_offset = RoundUp(sizeof(ImageHeader) + image_header->GetDataSize(), 1217 kPageSize); 1218 const size_t end_of_bitmap = image_bitmap_offset + bitmap_section.Size(); 1219 if (end_of_bitmap != image_file_size) { 1220 *error_msg = StringPrintf( 1221 "Image file size does not equal end of bitmap: size=%" PRIu64 " vs. %zu.", image_file_size, 1222 end_of_bitmap); 1223 return nullptr; 1224 } 1225 1226 // The preferred address to map the image, null specifies any address. If we manage to map the 1227 // image at the image begin, the amount of fixup work required is minimized. 1228 std::vector<uint8_t*> addresses(1, image_header->GetImageBegin()); 1229 if (image_header->IsPic()) { 1230 // Can also map at a random low_4gb address since we can relocate in-place. 1231 addresses.push_back(nullptr); 1232 } 1233 1234 // Note: The image header is part of the image due to mmap page alignment required of offset. 1235 std::unique_ptr<MemMap> map; 1236 std::string temp_error_msg; 1237 for (uint8_t* address : addresses) { 1238 TimingLogger::ScopedTiming timing("MapImageFile", &logger); 1239 // Only care about the error message for the last address in addresses. We want to avoid the 1240 // overhead of printing the process maps if we can relocate. 1241 std::string* out_error_msg = (address == addresses.back()) ? &temp_error_msg : nullptr; 1242 const ImageHeader::StorageMode storage_mode = image_header->GetStorageMode(); 1243 if (storage_mode == ImageHeader::kStorageModeUncompressed) { 1244 map.reset(MemMap::MapFileAtAddress(address, 1245 image_header->GetImageSize(), 1246 PROT_READ | PROT_WRITE, 1247 MAP_PRIVATE, 1248 file->Fd(), 1249 0, 1250 /*low_4gb*/true, 1251 /*reuse*/false, 1252 image_filename, 1253 /*out*/out_error_msg)); 1254 } else { 1255 if (storage_mode != ImageHeader::kStorageModeLZ4 && 1256 storage_mode != ImageHeader::kStorageModeLZ4HC) { 1257 *error_msg = StringPrintf("Invalid storage mode in image header %d", 1258 static_cast<int>(storage_mode)); 1259 return nullptr; 1260 } 1261 // Reserve output and decompress into it. 1262 map.reset(MemMap::MapAnonymous(image_location, 1263 address, 1264 image_header->GetImageSize(), 1265 PROT_READ | PROT_WRITE, 1266 /*low_4gb*/true, 1267 /*reuse*/false, 1268 /*out*/out_error_msg)); 1269 if (map != nullptr) { 1270 const size_t stored_size = image_header->GetDataSize(); 1271 const size_t decompress_offset = sizeof(ImageHeader); // Skip the header. 1272 std::unique_ptr<MemMap> temp_map(MemMap::MapFile(sizeof(ImageHeader) + stored_size, 1273 PROT_READ, 1274 MAP_PRIVATE, 1275 file->Fd(), 1276 /*offset*/0, 1277 /*low_4gb*/false, 1278 image_filename, 1279 out_error_msg)); 1280 if (temp_map == nullptr) { 1281 DCHECK(!out_error_msg->empty()); 1282 return nullptr; 1283 } 1284 memcpy(map->Begin(), image_header, sizeof(ImageHeader)); 1285 const uint64_t start = NanoTime(); 1286 // LZ4HC and LZ4 have same internal format, both use LZ4_decompress. 1287 TimingLogger::ScopedTiming timing2("LZ4 decompress image", &logger); 1288 const size_t decompressed_size = LZ4_decompress_safe( 1289 reinterpret_cast<char*>(temp_map->Begin()) + sizeof(ImageHeader), 1290 reinterpret_cast<char*>(map->Begin()) + decompress_offset, 1291 stored_size, 1292 map->Size() - decompress_offset); 1293 VLOG(image) << "Decompressing image took " << PrettyDuration(NanoTime() - start); 1294 if (decompressed_size + sizeof(ImageHeader) != image_header->GetImageSize()) { 1295 *error_msg = StringPrintf( 1296 "Decompressed size does not match expected image size %zu vs %zu", 1297 decompressed_size + sizeof(ImageHeader), 1298 image_header->GetImageSize()); 1299 return nullptr; 1300 } 1301 } 1302 } 1303 if (map != nullptr) { 1304 break; 1305 } 1306 } 1307 1308 if (map == nullptr) { 1309 DCHECK(!temp_error_msg.empty()); 1310 *error_msg = temp_error_msg; 1311 return nullptr; 1312 } 1313 DCHECK_EQ(0, memcmp(image_header, map->Begin(), sizeof(ImageHeader))); 1314 1315 std::unique_ptr<MemMap> image_bitmap_map(MemMap::MapFileAtAddress(nullptr, 1316 bitmap_section.Size(), 1317 PROT_READ, MAP_PRIVATE, 1318 file->Fd(), 1319 image_bitmap_offset, 1320 /*low_4gb*/false, 1321 /*reuse*/false, 1322 image_filename, 1323 error_msg)); 1324 if (image_bitmap_map == nullptr) { 1325 *error_msg = StringPrintf("Failed to map image bitmap: %s", error_msg->c_str()); 1326 return nullptr; 1327 } 1328 // Loaded the map, use the image header from the file now in case we patch it with 1329 // RelocateInPlace. 1330 image_header = reinterpret_cast<ImageHeader*>(map->Begin()); 1331 const uint32_t bitmap_index = bitmap_index_.FetchAndAddSequentiallyConsistent(1); 1332 std::string bitmap_name(StringPrintf("imagespace %s live-bitmap %u", 1333 image_filename, 1334 bitmap_index)); 1335 // Bitmap only needs to cover until the end of the mirror objects section. 1336 const ImageSection& image_objects = image_header->GetImageSection(ImageHeader::kSectionObjects); 1337 // We only want the mirror object, not the ArtFields and ArtMethods. 1338 uint8_t* const image_end = map->Begin() + image_objects.End(); 1339 std::unique_ptr<accounting::ContinuousSpaceBitmap> bitmap; 1340 { 1341 TimingLogger::ScopedTiming timing("CreateImageBitmap", &logger); 1342 bitmap.reset( 1343 accounting::ContinuousSpaceBitmap::CreateFromMemMap( 1344 bitmap_name, 1345 image_bitmap_map.release(), 1346 reinterpret_cast<uint8_t*>(map->Begin()), 1347 image_objects.End())); 1348 if (bitmap == nullptr) { 1349 *error_msg = StringPrintf("Could not create bitmap '%s'", bitmap_name.c_str()); 1350 return nullptr; 1351 } 1352 } 1353 { 1354 TimingLogger::ScopedTiming timing("RelocateImage", &logger); 1355 if (!RelocateInPlace(*image_header, 1356 map->Begin(), 1357 bitmap.get(), 1358 oat_file, 1359 error_msg)) { 1360 return nullptr; 1361 } 1362 } 1363 // We only want the mirror object, not the ArtFields and ArtMethods. 1364 std::unique_ptr<ImageSpace> space(new ImageSpace(image_filename, 1365 image_location, 1366 map.release(), 1367 bitmap.release(), 1368 image_end)); 1369 1370 // VerifyImageAllocations() will be called later in Runtime::Init() 1371 // as some class roots like ArtMethod::java_lang_reflect_ArtMethod_ 1372 // and ArtField::java_lang_reflect_ArtField_, which are used from 1373 // Object::SizeOf() which VerifyImageAllocations() calls, are not 1374 // set yet at this point. 1375 if (oat_file == nullptr) { 1376 TimingLogger::ScopedTiming timing("OpenOatFile", &logger); 1377 space->oat_file_.reset(space->OpenOatFile(image_filename, error_msg)); 1378 if (space->oat_file_ == nullptr) { 1379 DCHECK(!error_msg->empty()); 1380 return nullptr; 1381 } 1382 space->oat_file_non_owned_ = space->oat_file_.get(); 1383 } else { 1384 space->oat_file_non_owned_ = oat_file; 1385 } 1386 1387 if (validate_oat_file) { 1388 TimingLogger::ScopedTiming timing("ValidateOatFile", &logger); 1389 if (!space->ValidateOatFile(error_msg)) { 1390 DCHECK(!error_msg->empty()); 1391 return nullptr; 1392 } 1393 } 1394 1395 Runtime* runtime = Runtime::Current(); 1396 1397 // If oat_file is null, then it is the boot image space. Use oat_file_non_owned_ from the space 1398 // to set the runtime methods. 1399 CHECK_EQ(oat_file != nullptr, image_header->IsAppImage()); 1400 if (image_header->IsAppImage()) { 1401 CHECK_EQ(runtime->GetResolutionMethod(), 1402 image_header->GetImageMethod(ImageHeader::kResolutionMethod)); 1403 CHECK_EQ(runtime->GetImtConflictMethod(), 1404 image_header->GetImageMethod(ImageHeader::kImtConflictMethod)); 1405 CHECK_EQ(runtime->GetImtUnimplementedMethod(), 1406 image_header->GetImageMethod(ImageHeader::kImtUnimplementedMethod)); 1407 CHECK_EQ(runtime->GetCalleeSaveMethod(Runtime::kSaveAll), 1408 image_header->GetImageMethod(ImageHeader::kCalleeSaveMethod)); 1409 CHECK_EQ(runtime->GetCalleeSaveMethod(Runtime::kRefsOnly), 1410 image_header->GetImageMethod(ImageHeader::kRefsOnlySaveMethod)); 1411 CHECK_EQ(runtime->GetCalleeSaveMethod(Runtime::kRefsAndArgs), 1412 image_header->GetImageMethod(ImageHeader::kRefsAndArgsSaveMethod)); 1413 } else if (!runtime->HasResolutionMethod()) { 1414 runtime->SetInstructionSet(space->oat_file_non_owned_->GetOatHeader().GetInstructionSet()); 1415 runtime->SetResolutionMethod(image_header->GetImageMethod(ImageHeader::kResolutionMethod)); 1416 runtime->SetImtConflictMethod(image_header->GetImageMethod(ImageHeader::kImtConflictMethod)); 1417 runtime->SetImtUnimplementedMethod( 1418 image_header->GetImageMethod(ImageHeader::kImtUnimplementedMethod)); 1419 runtime->SetCalleeSaveMethod( 1420 image_header->GetImageMethod(ImageHeader::kCalleeSaveMethod), Runtime::kSaveAll); 1421 runtime->SetCalleeSaveMethod( 1422 image_header->GetImageMethod(ImageHeader::kRefsOnlySaveMethod), Runtime::kRefsOnly); 1423 runtime->SetCalleeSaveMethod( 1424 image_header->GetImageMethod(ImageHeader::kRefsAndArgsSaveMethod), Runtime::kRefsAndArgs); 1425 } 1426 1427 VLOG(image) << "ImageSpace::Init exiting " << *space.get(); 1428 if (VLOG_IS_ON(image)) { 1429 logger.Dump(LOG(INFO)); 1430 } 1431 return space.release(); 1432 } 1433 1434 OatFile* ImageSpace::OpenOatFile(const char* image_path, std::string* error_msg) const { 1435 const ImageHeader& image_header = GetImageHeader(); 1436 std::string oat_filename = ImageHeader::GetOatLocationFromImageLocation(image_path); 1437 1438 CHECK(image_header.GetOatDataBegin() != nullptr); 1439 1440 OatFile* oat_file = OatFile::Open(oat_filename, 1441 oat_filename, 1442 image_header.GetOatDataBegin(), 1443 image_header.GetOatFileBegin(), 1444 !Runtime::Current()->IsAotCompiler(), 1445 /*low_4gb*/false, 1446 nullptr, 1447 error_msg); 1448 if (oat_file == nullptr) { 1449 *error_msg = StringPrintf("Failed to open oat file '%s' referenced from image %s: %s", 1450 oat_filename.c_str(), GetName(), error_msg->c_str()); 1451 return nullptr; 1452 } 1453 uint32_t oat_checksum = oat_file->GetOatHeader().GetChecksum(); 1454 uint32_t image_oat_checksum = image_header.GetOatChecksum(); 1455 if (oat_checksum != image_oat_checksum) { 1456 *error_msg = StringPrintf("Failed to match oat file checksum 0x%x to expected oat checksum 0x%x" 1457 " in image %s", oat_checksum, image_oat_checksum, GetName()); 1458 return nullptr; 1459 } 1460 int32_t image_patch_delta = image_header.GetPatchDelta(); 1461 int32_t oat_patch_delta = oat_file->GetOatHeader().GetImagePatchDelta(); 1462 if (oat_patch_delta != image_patch_delta && !image_header.CompilePic()) { 1463 // We should have already relocated by this point. Bail out. 1464 *error_msg = StringPrintf("Failed to match oat file patch delta %d to expected patch delta %d " 1465 "in image %s", oat_patch_delta, image_patch_delta, GetName()); 1466 return nullptr; 1467 } 1468 1469 return oat_file; 1470 } 1471 1472 bool ImageSpace::ValidateOatFile(std::string* error_msg) const { 1473 CHECK(oat_file_.get() != nullptr); 1474 for (const OatFile::OatDexFile* oat_dex_file : oat_file_->GetOatDexFiles()) { 1475 const std::string& dex_file_location = oat_dex_file->GetDexFileLocation(); 1476 uint32_t dex_file_location_checksum; 1477 if (!DexFile::GetChecksum(dex_file_location.c_str(), &dex_file_location_checksum, error_msg)) { 1478 *error_msg = StringPrintf("Failed to get checksum of dex file '%s' referenced by image %s: " 1479 "%s", dex_file_location.c_str(), GetName(), error_msg->c_str()); 1480 return false; 1481 } 1482 if (dex_file_location_checksum != oat_dex_file->GetDexFileLocationChecksum()) { 1483 *error_msg = StringPrintf("ValidateOatFile found checksum mismatch between oat file '%s' and " 1484 "dex file '%s' (0x%x != 0x%x)", 1485 oat_file_->GetLocation().c_str(), dex_file_location.c_str(), 1486 oat_dex_file->GetDexFileLocationChecksum(), 1487 dex_file_location_checksum); 1488 return false; 1489 } 1490 } 1491 return true; 1492 } 1493 1494 const OatFile* ImageSpace::GetOatFile() const { 1495 return oat_file_non_owned_; 1496 } 1497 1498 std::unique_ptr<const OatFile> ImageSpace::ReleaseOatFile() { 1499 CHECK(oat_file_ != nullptr); 1500 return std::move(oat_file_); 1501 } 1502 1503 void ImageSpace::Dump(std::ostream& os) const { 1504 os << GetType() 1505 << " begin=" << reinterpret_cast<void*>(Begin()) 1506 << ",end=" << reinterpret_cast<void*>(End()) 1507 << ",size=" << PrettySize(Size()) 1508 << ",name=\"" << GetName() << "\"]"; 1509 } 1510 1511 void ImageSpace::CreateMultiImageLocations(const std::string& input_image_file_name, 1512 const std::string& boot_classpath, 1513 std::vector<std::string>* image_file_names) { 1514 DCHECK(image_file_names != nullptr); 1515 1516 std::vector<std::string> images; 1517 Split(boot_classpath, ':', &images); 1518 1519 // Add the rest into the list. We have to adjust locations, possibly: 1520 // 1521 // For example, image_file_name is /a/b/c/d/e.art 1522 // images[0] is f/c/d/e.art 1523 // ---------------------------------------------- 1524 // images[1] is g/h/i/j.art -> /a/b/h/i/j.art 1525 const std::string& first_image = images[0]; 1526 // Length of common suffix. 1527 size_t common = 0; 1528 while (common < input_image_file_name.size() && 1529 common < first_image.size() && 1530 *(input_image_file_name.end() - common - 1) == *(first_image.end() - common - 1)) { 1531 ++common; 1532 } 1533 // We want to replace the prefix of the input image with the prefix of the boot class path. 1534 // This handles the case where the image file contains @ separators. 1535 // Example image_file_name is oats/system@framework (at) boot.art 1536 // images[0] is .../arm/boot.art 1537 // means that the image name prefix will be oats/system@framework@ 1538 // so that the other images are openable. 1539 const size_t old_prefix_length = first_image.size() - common; 1540 const std::string new_prefix = input_image_file_name.substr( 1541 0, 1542 input_image_file_name.size() - common); 1543 1544 // Apply pattern to images[1] .. images[n]. 1545 for (size_t i = 1; i < images.size(); ++i) { 1546 const std::string& image = images[i]; 1547 CHECK_GT(image.length(), old_prefix_length); 1548 std::string suffix = image.substr(old_prefix_length); 1549 image_file_names->push_back(new_prefix + suffix); 1550 } 1551 } 1552 1553 ImageSpace* ImageSpace::CreateFromAppImage(const char* image, 1554 const OatFile* oat_file, 1555 std::string* error_msg) { 1556 return gc::space::ImageSpace::Init(image, 1557 image, 1558 /*validate_oat_file*/false, 1559 oat_file, 1560 /*out*/error_msg); 1561 } 1562 1563 void ImageSpace::DumpSections(std::ostream& os) const { 1564 const uint8_t* base = Begin(); 1565 const ImageHeader& header = GetImageHeader(); 1566 for (size_t i = 0; i < ImageHeader::kSectionCount; ++i) { 1567 auto section_type = static_cast<ImageHeader::ImageSections>(i); 1568 const ImageSection& section = header.GetImageSection(section_type); 1569 os << section_type << " " << reinterpret_cast<const void*>(base + section.Offset()) 1570 << "-" << reinterpret_cast<const void*>(base + section.End()) << "\n"; 1571 } 1572 } 1573 1574 } // namespace space 1575 } // namespace gc 1576 } // namespace art 1577