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 // If we're starting with the global cache, and we're the zygote, try to see whether there are 387 // OTA artifacts from the A/B OTA preopting to move over. 388 // (It is structurally simpler to check this here, instead of complicating the compile/relocate 389 // logic below.) 390 const bool is_zygote = Runtime::Current()->IsZygote(); 391 if (is_global_cache && is_zygote) { 392 VLOG(startup) << "Checking for A/B OTA data."; 393 TryMoveOTAArtifacts(cache_filename, dalvik_cache_exists); 394 395 // Retry. There are two cases where the old info is outdated: 396 // * There wasn't a boot image before (e.g., some failure on boot), but now the OTA preopted 397 // image has been moved in-place. 398 // * There was a boot image before, and we tried to move the OTA preopted image, but a failure 399 // happened and there is no file anymore. 400 found_image = FindImageFilename(image_location, 401 image_isa, 402 &system_filename, 403 &has_system, 404 &cache_filename, 405 &dalvik_cache_exists, 406 &has_cache, 407 &is_global_cache); 408 } 409 410 if (is_zygote && !secondary_image) { 411 MarkZygoteStart(image_isa, Runtime::Current()->GetZygoteMaxFailedBoots()); 412 } 413 414 ImageSpace* space; 415 bool relocate = Runtime::Current()->ShouldRelocate(); 416 bool can_compile = Runtime::Current()->IsImageDex2OatEnabled(); 417 if (found_image) { 418 const std::string* image_filename; 419 bool is_system = false; 420 bool relocated_version_used = false; 421 if (relocate) { 422 if (!dalvik_cache_exists) { 423 *error_msg = StringPrintf("Requiring relocation for image '%s' at '%s' but we do not have " 424 "any dalvik_cache to find/place it in.", 425 image_location, system_filename.c_str()); 426 return nullptr; 427 } 428 if (has_system) { 429 if (has_cache && ChecksumsMatch(system_filename.c_str(), cache_filename.c_str())) { 430 // We already have a relocated version 431 image_filename = &cache_filename; 432 relocated_version_used = true; 433 } else { 434 // We cannot have a relocated version, Relocate the system one and use it. 435 436 std::string reason; 437 bool success; 438 439 // Check whether we are allowed to relocate. 440 if (!can_compile) { 441 reason = "Image dex2oat disabled by -Xnoimage-dex2oat."; 442 success = false; 443 } else if (!ImageCreationAllowed(is_global_cache, &reason)) { 444 // Whether we can write to the cache. 445 success = false; 446 } else if (secondary_image) { 447 if (is_zygote) { 448 // Secondary image is out of date. Clear cache and exit to let it retry from scratch. 449 LOG(ERROR) << "Cannot patch secondary image '" << image_location 450 << "', clearing dalvik_cache and restarting zygote."; 451 PruneDalvikCache(image_isa); 452 _exit(1); 453 } else { 454 reason = "Should not have to patch secondary image."; 455 success = false; 456 } 457 } else { 458 // Try to relocate. 459 success = RelocateImage(image_location, cache_filename.c_str(), image_isa, &reason); 460 } 461 462 if (success) { 463 relocated_version_used = true; 464 image_filename = &cache_filename; 465 } else { 466 *error_msg = StringPrintf("Unable to relocate image '%s' from '%s' to '%s': %s", 467 image_location, system_filename.c_str(), 468 cache_filename.c_str(), reason.c_str()); 469 // We failed to create files, remove any possibly garbage output. 470 // Since ImageCreationAllowed was true above, we are the zygote 471 // and therefore the only process expected to generate these for 472 // the device. 473 PruneDalvikCache(image_isa); 474 return nullptr; 475 } 476 } 477 } else { 478 CHECK(has_cache); 479 // We can just use cache's since it should be fine. This might or might not be relocated. 480 image_filename = &cache_filename; 481 } 482 } else { 483 if (has_system && has_cache) { 484 // Check they have the same cksum. If they do use the cache. Otherwise system. 485 if (ChecksumsMatch(system_filename.c_str(), cache_filename.c_str())) { 486 image_filename = &cache_filename; 487 relocated_version_used = true; 488 } else { 489 image_filename = &system_filename; 490 is_system = true; 491 } 492 } else if (has_system) { 493 image_filename = &system_filename; 494 is_system = true; 495 } else { 496 CHECK(has_cache); 497 image_filename = &cache_filename; 498 } 499 } 500 { 501 // Note that we must not use the file descriptor associated with 502 // ScopedFlock::GetFile to Init the image file. We want the file 503 // descriptor (and the associated exclusive lock) to be released when 504 // we leave Create. 505 ScopedFlock image_lock; 506 // Should this be a RDWR lock? This is only a defensive measure, as at 507 // this point the image should exist. 508 // However, only the zygote can write into the global dalvik-cache, so 509 // restrict to zygote processes, or any process that isn't using 510 // /data/dalvik-cache (which we assume to be allowed to write there). 511 const bool rw_lock = is_zygote || !is_global_cache; 512 image_lock.Init(image_filename->c_str(), 513 rw_lock ? (O_CREAT | O_RDWR) : O_RDONLY /* flags */, 514 true /* block */, 515 error_msg); 516 VLOG(startup) << "Using image file " << image_filename->c_str() << " for image location " 517 << image_location; 518 // If we are in /system we can assume the image is good. We can also 519 // assume this if we are using a relocated image (i.e. image checksum 520 // matches) since this is only different by the offset. We need this to 521 // make sure that host tests continue to work. 522 // Since we are the boot image, pass null since we load the oat file from the boot image oat 523 // file name. 524 space = ImageSpace::Init(image_filename->c_str(), 525 image_location, 526 !(is_system || relocated_version_used), 527 /* oat_file */nullptr, 528 error_msg); 529 } 530 if (space != nullptr) { 531 return space; 532 } 533 534 if (relocated_version_used) { 535 // Something is wrong with the relocated copy (even though checksums match). Cleanup. 536 // This can happen if the .oat is corrupt, since the above only checks the .art checksums. 537 // TODO: Check the oat file validity earlier. 538 *error_msg = StringPrintf("Attempted to use relocated version of %s at %s generated from %s " 539 "but image failed to load: %s", 540 image_location, cache_filename.c_str(), system_filename.c_str(), 541 error_msg->c_str()); 542 PruneDalvikCache(image_isa); 543 return nullptr; 544 } else if (is_system) { 545 // If the /system file exists, it should be up-to-date, don't try to generate it. 546 *error_msg = StringPrintf("Failed to load /system image '%s': %s", 547 image_filename->c_str(), error_msg->c_str()); 548 return nullptr; 549 } else { 550 // Otherwise, log a warning and fall through to GenerateImage. 551 LOG(WARNING) << *error_msg; 552 } 553 } 554 555 if (!can_compile) { 556 *error_msg = "Not attempting to compile image because -Xnoimage-dex2oat"; 557 return nullptr; 558 } else if (!dalvik_cache_exists) { 559 *error_msg = StringPrintf("No place to put generated image."); 560 return nullptr; 561 } else if (!ImageCreationAllowed(is_global_cache, error_msg)) { 562 return nullptr; 563 } else if (secondary_image) { 564 *error_msg = "Cannot compile a secondary image."; 565 return nullptr; 566 } else if (!GenerateImage(cache_filename, image_isa, error_msg)) { 567 *error_msg = StringPrintf("Failed to generate image '%s': %s", 568 cache_filename.c_str(), error_msg->c_str()); 569 // We failed to create files, remove any possibly garbage output. 570 // Since ImageCreationAllowed was true above, we are the zygote 571 // and therefore the only process expected to generate these for 572 // the device. 573 PruneDalvikCache(image_isa); 574 return nullptr; 575 } else { 576 // Check whether there is enough space left over after we have generated the image. 577 if (!CheckSpace(cache_filename, error_msg)) { 578 // No. Delete the generated image and try to run out of the dex files. 579 PruneDalvikCache(image_isa); 580 return nullptr; 581 } 582 583 // Note that we must not use the file descriptor associated with 584 // ScopedFlock::GetFile to Init the image file. We want the file 585 // descriptor (and the associated exclusive lock) to be released when 586 // we leave Create. 587 ScopedFlock image_lock; 588 image_lock.Init(cache_filename.c_str(), error_msg); 589 space = ImageSpace::Init(cache_filename.c_str(), image_location, true, nullptr, error_msg); 590 if (space == nullptr) { 591 *error_msg = StringPrintf("Failed to load generated image '%s': %s", 592 cache_filename.c_str(), error_msg->c_str()); 593 } 594 return space; 595 } 596 } 597 598 void ImageSpace::VerifyImageAllocations() { 599 uint8_t* current = Begin() + RoundUp(sizeof(ImageHeader), kObjectAlignment); 600 while (current < End()) { 601 CHECK_ALIGNED(current, kObjectAlignment); 602 auto* obj = reinterpret_cast<mirror::Object*>(current); 603 CHECK(obj->GetClass() != nullptr) << "Image object at address " << obj << " has null class"; 604 CHECK(live_bitmap_->Test(obj)) << PrettyTypeOf(obj); 605 if (kUseBakerOrBrooksReadBarrier) { 606 obj->AssertReadBarrierPointer(); 607 } 608 current += RoundUp(obj->SizeOf(), kObjectAlignment); 609 } 610 } 611 612 // Helper class for relocating from one range of memory to another. 613 class RelocationRange { 614 public: 615 RelocationRange() = default; 616 RelocationRange(const RelocationRange&) = default; 617 RelocationRange(uintptr_t source, uintptr_t dest, uintptr_t length) 618 : source_(source), 619 dest_(dest), 620 length_(length) {} 621 622 bool InSource(uintptr_t address) const { 623 return address - source_ < length_; 624 } 625 626 bool InDest(uintptr_t address) const { 627 return address - dest_ < length_; 628 } 629 630 // Translate a source address to the destination space. 631 uintptr_t ToDest(uintptr_t address) const { 632 DCHECK(InSource(address)); 633 return address + Delta(); 634 } 635 636 // Returns the delta between the dest from the source. 637 uintptr_t Delta() const { 638 return dest_ - source_; 639 } 640 641 uintptr_t Source() const { 642 return source_; 643 } 644 645 uintptr_t Dest() const { 646 return dest_; 647 } 648 649 uintptr_t Length() const { 650 return length_; 651 } 652 653 private: 654 const uintptr_t source_; 655 const uintptr_t dest_; 656 const uintptr_t length_; 657 }; 658 659 std::ostream& operator<<(std::ostream& os, const RelocationRange& reloc) { 660 return os << "(" << reinterpret_cast<const void*>(reloc.Source()) << "-" 661 << reinterpret_cast<const void*>(reloc.Source() + reloc.Length()) << ")->(" 662 << reinterpret_cast<const void*>(reloc.Dest()) << "-" 663 << reinterpret_cast<const void*>(reloc.Dest() + reloc.Length()) << ")"; 664 } 665 666 class FixupVisitor : public ValueObject { 667 public: 668 FixupVisitor(const RelocationRange& boot_image, 669 const RelocationRange& boot_oat, 670 const RelocationRange& app_image, 671 const RelocationRange& app_oat) 672 : boot_image_(boot_image), 673 boot_oat_(boot_oat), 674 app_image_(app_image), 675 app_oat_(app_oat) {} 676 677 // Return the relocated address of a heap object. 678 template <typename T> 679 ALWAYS_INLINE T* ForwardObject(T* src) const { 680 const uintptr_t uint_src = reinterpret_cast<uintptr_t>(src); 681 if (boot_image_.InSource(uint_src)) { 682 return reinterpret_cast<T*>(boot_image_.ToDest(uint_src)); 683 } 684 if (app_image_.InSource(uint_src)) { 685 return reinterpret_cast<T*>(app_image_.ToDest(uint_src)); 686 } 687 // Since we are fixing up the app image, there should only be pointers to the app image and 688 // boot image. 689 DCHECK(src == nullptr) << reinterpret_cast<const void*>(src); 690 return src; 691 } 692 693 // Return the relocated address of a code pointer (contained by an oat file). 694 ALWAYS_INLINE const void* ForwardCode(const void* src) const { 695 const uintptr_t uint_src = reinterpret_cast<uintptr_t>(src); 696 if (boot_oat_.InSource(uint_src)) { 697 return reinterpret_cast<const void*>(boot_oat_.ToDest(uint_src)); 698 } 699 if (app_oat_.InSource(uint_src)) { 700 return reinterpret_cast<const void*>(app_oat_.ToDest(uint_src)); 701 } 702 DCHECK(src == nullptr) << src; 703 return src; 704 } 705 706 // Must be called on pointers that already have been relocated to the destination relocation. 707 ALWAYS_INLINE bool IsInAppImage(mirror::Object* object) const { 708 return app_image_.InDest(reinterpret_cast<uintptr_t>(object)); 709 } 710 711 protected: 712 // Source section. 713 const RelocationRange boot_image_; 714 const RelocationRange boot_oat_; 715 const RelocationRange app_image_; 716 const RelocationRange app_oat_; 717 }; 718 719 // Adapt for mirror::Class::FixupNativePointers. 720 class FixupObjectAdapter : public FixupVisitor { 721 public: 722 template<typename... Args> 723 explicit FixupObjectAdapter(Args... args) : FixupVisitor(args...) {} 724 725 template <typename T> 726 T* operator()(T* obj) const { 727 return ForwardObject(obj); 728 } 729 }; 730 731 class FixupRootVisitor : public FixupVisitor { 732 public: 733 template<typename... Args> 734 explicit FixupRootVisitor(Args... args) : FixupVisitor(args...) {} 735 736 ALWAYS_INLINE void VisitRootIfNonNull(mirror::CompressedReference<mirror::Object>* root) const 737 SHARED_REQUIRES(Locks::mutator_lock_) { 738 if (!root->IsNull()) { 739 VisitRoot(root); 740 } 741 } 742 743 ALWAYS_INLINE void VisitRoot(mirror::CompressedReference<mirror::Object>* root) const 744 SHARED_REQUIRES(Locks::mutator_lock_) { 745 mirror::Object* ref = root->AsMirrorPtr(); 746 mirror::Object* new_ref = ForwardObject(ref); 747 if (ref != new_ref) { 748 root->Assign(new_ref); 749 } 750 } 751 }; 752 753 class FixupObjectVisitor : public FixupVisitor { 754 public: 755 template<typename... Args> 756 explicit FixupObjectVisitor(gc::accounting::ContinuousSpaceBitmap* visited, 757 const size_t pointer_size, 758 Args... args) 759 : FixupVisitor(args...), 760 pointer_size_(pointer_size), 761 visited_(visited) {} 762 763 // Fix up separately since we also need to fix up method entrypoints. 764 ALWAYS_INLINE void VisitRootIfNonNull( 765 mirror::CompressedReference<mirror::Object>* root ATTRIBUTE_UNUSED) const {} 766 767 ALWAYS_INLINE void VisitRoot(mirror::CompressedReference<mirror::Object>* root ATTRIBUTE_UNUSED) 768 const {} 769 770 ALWAYS_INLINE void operator()(mirror::Object* obj, 771 MemberOffset offset, 772 bool is_static ATTRIBUTE_UNUSED) const 773 NO_THREAD_SAFETY_ANALYSIS { 774 // There could be overlap between ranges, we must avoid visiting the same reference twice. 775 // Avoid the class field since we already fixed it up in FixupClassVisitor. 776 if (offset.Uint32Value() != mirror::Object::ClassOffset().Uint32Value()) { 777 // Space is not yet added to the heap, don't do a read barrier. 778 mirror::Object* ref = obj->GetFieldObject<mirror::Object, kVerifyNone, kWithoutReadBarrier>( 779 offset); 780 // Use SetFieldObjectWithoutWriteBarrier to avoid card marking since we are writing to the 781 // image. 782 obj->SetFieldObjectWithoutWriteBarrier<false, true, kVerifyNone>(offset, ForwardObject(ref)); 783 } 784 } 785 786 // Visit a pointer array and forward corresponding native data. Ignores pointer arrays in the 787 // boot image. Uses the bitmap to ensure the same array is not visited multiple times. 788 template <typename Visitor> 789 void UpdatePointerArrayContents(mirror::PointerArray* array, const Visitor& visitor) const 790 NO_THREAD_SAFETY_ANALYSIS { 791 DCHECK(array != nullptr); 792 DCHECK(visitor.IsInAppImage(array)); 793 // The bit for the array contents is different than the bit for the array. Since we may have 794 // already visited the array as a long / int array from walking the bitmap without knowing it 795 // was a pointer array. 796 static_assert(kObjectAlignment == 8u, "array bit may be in another object"); 797 mirror::Object* const contents_bit = reinterpret_cast<mirror::Object*>( 798 reinterpret_cast<uintptr_t>(array) + kObjectAlignment); 799 // If the bit is not set then the contents have not yet been updated. 800 if (!visited_->Test(contents_bit)) { 801 array->Fixup<kVerifyNone, kWithoutReadBarrier>(array, pointer_size_, visitor); 802 visited_->Set(contents_bit); 803 } 804 } 805 806 // java.lang.ref.Reference visitor. 807 void operator()(mirror::Class* klass ATTRIBUTE_UNUSED, mirror::Reference* ref) const 808 SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(Locks::heap_bitmap_lock_) { 809 mirror::Object* obj = ref->GetReferent<kWithoutReadBarrier>(); 810 ref->SetFieldObjectWithoutWriteBarrier<false, true, kVerifyNone>( 811 mirror::Reference::ReferentOffset(), 812 ForwardObject(obj)); 813 } 814 815 void operator()(mirror::Object* obj) const NO_THREAD_SAFETY_ANALYSIS { 816 if (visited_->Test(obj)) { 817 // Already visited. 818 return; 819 } 820 visited_->Set(obj); 821 822 // Handle class specially first since we need it to be updated to properly visit the rest of 823 // the instance fields. 824 { 825 mirror::Class* klass = obj->GetClass<kVerifyNone, kWithoutReadBarrier>(); 826 DCHECK(klass != nullptr) << "Null class in image"; 827 // No AsClass since our fields aren't quite fixed up yet. 828 mirror::Class* new_klass = down_cast<mirror::Class*>(ForwardObject(klass)); 829 if (klass != new_klass) { 830 obj->SetClass<kVerifyNone>(new_klass); 831 } 832 if (new_klass != klass && IsInAppImage(new_klass)) { 833 // Make sure the klass contents are fixed up since we depend on it to walk the fields. 834 operator()(new_klass); 835 } 836 } 837 838 obj->VisitReferences</*visit native roots*/false, kVerifyNone, kWithoutReadBarrier>( 839 *this, 840 *this); 841 // Note that this code relies on no circular dependencies. 842 // We want to use our own class loader and not the one in the image. 843 if (obj->IsClass<kVerifyNone, kWithoutReadBarrier>()) { 844 mirror::Class* as_klass = obj->AsClass<kVerifyNone, kWithoutReadBarrier>(); 845 FixupObjectAdapter visitor(boot_image_, boot_oat_, app_image_, app_oat_); 846 as_klass->FixupNativePointers<kVerifyNone, kWithoutReadBarrier>(as_klass, 847 pointer_size_, 848 visitor); 849 // Deal with the pointer arrays. Use the helper function since multiple classes can reference 850 // the same arrays. 851 mirror::PointerArray* const vtable = as_klass->GetVTable<kVerifyNone, kWithoutReadBarrier>(); 852 if (vtable != nullptr && IsInAppImage(vtable)) { 853 operator()(vtable); 854 UpdatePointerArrayContents(vtable, visitor); 855 } 856 mirror::IfTable* iftable = as_klass->GetIfTable<kVerifyNone, kWithoutReadBarrier>(); 857 // Ensure iftable arrays are fixed up since we need GetMethodArray to return the valid 858 // contents. 859 if (iftable != nullptr && IsInAppImage(iftable)) { 860 operator()(iftable); 861 for (int32_t i = 0, count = iftable->Count(); i < count; ++i) { 862 if (iftable->GetMethodArrayCount<kVerifyNone, kWithoutReadBarrier>(i) > 0) { 863 mirror::PointerArray* methods = 864 iftable->GetMethodArray<kVerifyNone, kWithoutReadBarrier>(i); 865 if (visitor.IsInAppImage(methods)) { 866 operator()(methods); 867 DCHECK(methods != nullptr); 868 UpdatePointerArrayContents(methods, visitor); 869 } 870 } 871 } 872 } 873 } 874 } 875 876 private: 877 const size_t pointer_size_; 878 gc::accounting::ContinuousSpaceBitmap* const visited_; 879 }; 880 881 class ForwardObjectAdapter { 882 public: 883 ALWAYS_INLINE ForwardObjectAdapter(const FixupVisitor* visitor) : visitor_(visitor) {} 884 885 template <typename T> 886 ALWAYS_INLINE T* operator()(T* src) const { 887 return visitor_->ForwardObject(src); 888 } 889 890 private: 891 const FixupVisitor* const visitor_; 892 }; 893 894 class ForwardCodeAdapter { 895 public: 896 ALWAYS_INLINE ForwardCodeAdapter(const FixupVisitor* visitor) 897 : visitor_(visitor) {} 898 899 template <typename T> 900 ALWAYS_INLINE T* operator()(T* src) const { 901 return visitor_->ForwardCode(src); 902 } 903 904 private: 905 const FixupVisitor* const visitor_; 906 }; 907 908 class FixupArtMethodVisitor : public FixupVisitor, public ArtMethodVisitor { 909 public: 910 template<typename... Args> 911 explicit FixupArtMethodVisitor(bool fixup_heap_objects, size_t pointer_size, Args... args) 912 : FixupVisitor(args...), 913 fixup_heap_objects_(fixup_heap_objects), 914 pointer_size_(pointer_size) {} 915 916 virtual void Visit(ArtMethod* method) NO_THREAD_SAFETY_ANALYSIS { 917 // TODO: Separate visitor for runtime vs normal methods. 918 if (UNLIKELY(method->IsRuntimeMethod())) { 919 ImtConflictTable* table = method->GetImtConflictTable(pointer_size_); 920 if (table != nullptr) { 921 ImtConflictTable* new_table = ForwardObject(table); 922 if (table != new_table) { 923 method->SetImtConflictTable(new_table, pointer_size_); 924 } 925 } 926 const void* old_code = method->GetEntryPointFromQuickCompiledCodePtrSize(pointer_size_); 927 const void* new_code = ForwardCode(old_code); 928 if (old_code != new_code) { 929 method->SetEntryPointFromQuickCompiledCodePtrSize(new_code, pointer_size_); 930 } 931 } else { 932 if (fixup_heap_objects_) { 933 method->UpdateObjectsForImageRelocation(ForwardObjectAdapter(this), pointer_size_); 934 } 935 method->UpdateEntrypoints<kWithoutReadBarrier>(ForwardCodeAdapter(this), pointer_size_); 936 } 937 } 938 939 private: 940 const bool fixup_heap_objects_; 941 const size_t pointer_size_; 942 }; 943 944 class FixupArtFieldVisitor : public FixupVisitor, public ArtFieldVisitor { 945 public: 946 template<typename... Args> 947 explicit FixupArtFieldVisitor(Args... args) : FixupVisitor(args...) {} 948 949 virtual void Visit(ArtField* field) NO_THREAD_SAFETY_ANALYSIS { 950 field->UpdateObjects(ForwardObjectAdapter(this)); 951 } 952 }; 953 954 // Relocate an image space mapped at target_base which possibly used to be at a different base 955 // address. Only needs a single image space, not one for both source and destination. 956 // In place means modifying a single ImageSpace in place rather than relocating from one ImageSpace 957 // to another. 958 static bool RelocateInPlace(ImageHeader& image_header, 959 uint8_t* target_base, 960 accounting::ContinuousSpaceBitmap* bitmap, 961 const OatFile* app_oat_file, 962 std::string* error_msg) { 963 DCHECK(error_msg != nullptr); 964 if (!image_header.IsPic()) { 965 if (image_header.GetImageBegin() == target_base) { 966 return true; 967 } 968 *error_msg = StringPrintf("Cannot relocate non-pic image for oat file %s", 969 (app_oat_file != nullptr) ? app_oat_file->GetLocation().c_str() : ""); 970 return false; 971 } 972 // Set up sections. 973 uint32_t boot_image_begin = 0; 974 uint32_t boot_image_end = 0; 975 uint32_t boot_oat_begin = 0; 976 uint32_t boot_oat_end = 0; 977 const size_t pointer_size = image_header.GetPointerSize(); 978 gc::Heap* const heap = Runtime::Current()->GetHeap(); 979 heap->GetBootImagesSize(&boot_image_begin, &boot_image_end, &boot_oat_begin, &boot_oat_end); 980 if (boot_image_begin == boot_image_end) { 981 *error_msg = "Can not relocate app image without boot image space"; 982 return false; 983 } 984 if (boot_oat_begin == boot_oat_end) { 985 *error_msg = "Can not relocate app image without boot oat file"; 986 return false; 987 } 988 const uint32_t boot_image_size = boot_image_end - boot_image_begin; 989 const uint32_t boot_oat_size = boot_oat_end - boot_oat_begin; 990 const uint32_t image_header_boot_image_size = image_header.GetBootImageSize(); 991 const uint32_t image_header_boot_oat_size = image_header.GetBootOatSize(); 992 if (boot_image_size != image_header_boot_image_size) { 993 *error_msg = StringPrintf("Boot image size %" PRIu64 " does not match expected size %" 994 PRIu64, 995 static_cast<uint64_t>(boot_image_size), 996 static_cast<uint64_t>(image_header_boot_image_size)); 997 return false; 998 } 999 if (boot_oat_size != image_header_boot_oat_size) { 1000 *error_msg = StringPrintf("Boot oat size %" PRIu64 " does not match expected size %" 1001 PRIu64, 1002 static_cast<uint64_t>(boot_oat_size), 1003 static_cast<uint64_t>(image_header_boot_oat_size)); 1004 return false; 1005 } 1006 TimingLogger logger(__FUNCTION__, true, false); 1007 RelocationRange boot_image(image_header.GetBootImageBegin(), 1008 boot_image_begin, 1009 boot_image_size); 1010 RelocationRange boot_oat(image_header.GetBootOatBegin(), 1011 boot_oat_begin, 1012 boot_oat_size); 1013 RelocationRange app_image(reinterpret_cast<uintptr_t>(image_header.GetImageBegin()), 1014 reinterpret_cast<uintptr_t>(target_base), 1015 image_header.GetImageSize()); 1016 // Use the oat data section since this is where the OatFile::Begin is. 1017 RelocationRange app_oat(reinterpret_cast<uintptr_t>(image_header.GetOatDataBegin()), 1018 // Not necessarily in low 4GB. 1019 reinterpret_cast<uintptr_t>(app_oat_file->Begin()), 1020 image_header.GetOatDataEnd() - image_header.GetOatDataBegin()); 1021 VLOG(image) << "App image " << app_image; 1022 VLOG(image) << "App oat " << app_oat; 1023 VLOG(image) << "Boot image " << boot_image; 1024 VLOG(image) << "Boot oat " << boot_oat; 1025 // True if we need to fixup any heap pointers, otherwise only code pointers. 1026 const bool fixup_image = boot_image.Delta() != 0 || app_image.Delta() != 0; 1027 const bool fixup_code = boot_oat.Delta() != 0 || app_oat.Delta() != 0; 1028 if (!fixup_image && !fixup_code) { 1029 // Nothing to fix up. 1030 return true; 1031 } 1032 ScopedDebugDisallowReadBarriers sddrb(Thread::Current()); 1033 // Need to update the image to be at the target base. 1034 const ImageSection& objects_section = image_header.GetImageSection(ImageHeader::kSectionObjects); 1035 uintptr_t objects_begin = reinterpret_cast<uintptr_t>(target_base + objects_section.Offset()); 1036 uintptr_t objects_end = reinterpret_cast<uintptr_t>(target_base + objects_section.End()); 1037 FixupObjectAdapter fixup_adapter(boot_image, boot_oat, app_image, app_oat); 1038 if (fixup_image) { 1039 // Two pass approach, fix up all classes first, then fix up non class-objects. 1040 // The visited bitmap is used to ensure that pointer arrays are not forwarded twice. 1041 std::unique_ptr<gc::accounting::ContinuousSpaceBitmap> visited_bitmap( 1042 gc::accounting::ContinuousSpaceBitmap::Create("Relocate bitmap", 1043 target_base, 1044 image_header.GetImageSize())); 1045 FixupObjectVisitor fixup_object_visitor(visited_bitmap.get(), 1046 pointer_size, 1047 boot_image, 1048 boot_oat, 1049 app_image, 1050 app_oat); 1051 TimingLogger::ScopedTiming timing("Fixup classes", &logger); 1052 // Fixup objects may read fields in the boot image, use the mutator lock here for sanity. Though 1053 // its probably not required. 1054 ScopedObjectAccess soa(Thread::Current()); 1055 timing.NewTiming("Fixup objects"); 1056 bitmap->VisitMarkedRange(objects_begin, objects_end, fixup_object_visitor); 1057 // Fixup image roots. 1058 CHECK(app_image.InSource(reinterpret_cast<uintptr_t>( 1059 image_header.GetImageRoots<kWithoutReadBarrier>()))); 1060 image_header.RelocateImageObjects(app_image.Delta()); 1061 CHECK_EQ(image_header.GetImageBegin(), target_base); 1062 // Fix up dex cache DexFile pointers. 1063 auto* dex_caches = image_header.GetImageRoot<kWithoutReadBarrier>(ImageHeader::kDexCaches)-> 1064 AsObjectArray<mirror::DexCache, kVerifyNone, kWithoutReadBarrier>(); 1065 for (int32_t i = 0, count = dex_caches->GetLength(); i < count; ++i) { 1066 mirror::DexCache* dex_cache = dex_caches->Get<kVerifyNone, kWithoutReadBarrier>(i); 1067 // Fix up dex cache pointers. 1068 GcRoot<mirror::String>* strings = dex_cache->GetStrings(); 1069 if (strings != nullptr) { 1070 GcRoot<mirror::String>* new_strings = fixup_adapter.ForwardObject(strings); 1071 if (strings != new_strings) { 1072 dex_cache->SetStrings(new_strings); 1073 } 1074 dex_cache->FixupStrings<kWithoutReadBarrier>(new_strings, fixup_adapter); 1075 } 1076 GcRoot<mirror::Class>* types = dex_cache->GetResolvedTypes(); 1077 if (types != nullptr) { 1078 GcRoot<mirror::Class>* new_types = fixup_adapter.ForwardObject(types); 1079 if (types != new_types) { 1080 dex_cache->SetResolvedTypes(new_types); 1081 } 1082 dex_cache->FixupResolvedTypes<kWithoutReadBarrier>(new_types, fixup_adapter); 1083 } 1084 ArtMethod** methods = dex_cache->GetResolvedMethods(); 1085 if (methods != nullptr) { 1086 ArtMethod** new_methods = fixup_adapter.ForwardObject(methods); 1087 if (methods != new_methods) { 1088 dex_cache->SetResolvedMethods(new_methods); 1089 } 1090 for (size_t j = 0, num = dex_cache->NumResolvedMethods(); j != num; ++j) { 1091 ArtMethod* orig = mirror::DexCache::GetElementPtrSize(new_methods, j, pointer_size); 1092 ArtMethod* copy = fixup_adapter.ForwardObject(orig); 1093 if (orig != copy) { 1094 mirror::DexCache::SetElementPtrSize(new_methods, j, copy, pointer_size); 1095 } 1096 } 1097 } 1098 ArtField** fields = dex_cache->GetResolvedFields(); 1099 if (fields != nullptr) { 1100 ArtField** new_fields = fixup_adapter.ForwardObject(fields); 1101 if (fields != new_fields) { 1102 dex_cache->SetResolvedFields(new_fields); 1103 } 1104 for (size_t j = 0, num = dex_cache->NumResolvedFields(); j != num; ++j) { 1105 ArtField* orig = mirror::DexCache::GetElementPtrSize(new_fields, j, pointer_size); 1106 ArtField* copy = fixup_adapter.ForwardObject(orig); 1107 if (orig != copy) { 1108 mirror::DexCache::SetElementPtrSize(new_fields, j, copy, pointer_size); 1109 } 1110 } 1111 } 1112 } 1113 } 1114 { 1115 // Only touches objects in the app image, no need for mutator lock. 1116 TimingLogger::ScopedTiming timing("Fixup methods", &logger); 1117 FixupArtMethodVisitor method_visitor(fixup_image, 1118 pointer_size, 1119 boot_image, 1120 boot_oat, 1121 app_image, 1122 app_oat); 1123 image_header.VisitPackedArtMethods(&method_visitor, target_base, pointer_size); 1124 } 1125 if (fixup_image) { 1126 { 1127 // Only touches objects in the app image, no need for mutator lock. 1128 TimingLogger::ScopedTiming timing("Fixup fields", &logger); 1129 FixupArtFieldVisitor field_visitor(boot_image, boot_oat, app_image, app_oat); 1130 image_header.VisitPackedArtFields(&field_visitor, target_base); 1131 } 1132 { 1133 TimingLogger::ScopedTiming timing("Fixup conflict tables", &logger); 1134 image_header.VisitPackedImtConflictTables(fixup_adapter, target_base, pointer_size); 1135 } 1136 // In the app image case, the image methods are actually in the boot image. 1137 image_header.RelocateImageMethods(boot_image.Delta()); 1138 const auto& class_table_section = image_header.GetImageSection(ImageHeader::kSectionClassTable); 1139 if (class_table_section.Size() > 0u) { 1140 // Note that we require that ReadFromMemory does not make an internal copy of the elements. 1141 // This also relies on visit roots not doing any verification which could fail after we update 1142 // the roots to be the image addresses. 1143 ScopedObjectAccess soa(Thread::Current()); 1144 WriterMutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_); 1145 ClassTable temp_table; 1146 temp_table.ReadFromMemory(target_base + class_table_section.Offset()); 1147 FixupRootVisitor root_visitor(boot_image, boot_oat, app_image, app_oat); 1148 temp_table.VisitRoots(root_visitor); 1149 } 1150 } 1151 if (VLOG_IS_ON(image)) { 1152 logger.Dump(LOG(INFO)); 1153 } 1154 return true; 1155 } 1156 1157 ImageSpace* ImageSpace::Init(const char* image_filename, 1158 const char* image_location, 1159 bool validate_oat_file, 1160 const OatFile* oat_file, 1161 std::string* error_msg) { 1162 CHECK(image_filename != nullptr); 1163 CHECK(image_location != nullptr); 1164 1165 TimingLogger logger(__PRETTY_FUNCTION__, true, VLOG_IS_ON(image)); 1166 VLOG(image) << "ImageSpace::Init entering image_filename=" << image_filename; 1167 1168 std::unique_ptr<File> file; 1169 { 1170 TimingLogger::ScopedTiming timing("OpenImageFile", &logger); 1171 file.reset(OS::OpenFileForReading(image_filename)); 1172 if (file == nullptr) { 1173 *error_msg = StringPrintf("Failed to open '%s'", image_filename); 1174 return nullptr; 1175 } 1176 } 1177 ImageHeader temp_image_header; 1178 ImageHeader* image_header = &temp_image_header; 1179 { 1180 TimingLogger::ScopedTiming timing("ReadImageHeader", &logger); 1181 bool success = file->ReadFully(image_header, sizeof(*image_header)); 1182 if (!success || !image_header->IsValid()) { 1183 *error_msg = StringPrintf("Invalid image header in '%s'", image_filename); 1184 return nullptr; 1185 } 1186 } 1187 // Check that the file is larger or equal to the header size + data size. 1188 const uint64_t image_file_size = static_cast<uint64_t>(file->GetLength()); 1189 if (image_file_size < sizeof(ImageHeader) + image_header->GetDataSize()) { 1190 *error_msg = StringPrintf("Image file truncated: %" PRIu64 " vs. %" PRIu64 ".", 1191 image_file_size, 1192 sizeof(ImageHeader) + image_header->GetDataSize()); 1193 return nullptr; 1194 } 1195 1196 if (oat_file != nullptr) { 1197 // If we have an oat file, check the oat file checksum. The oat file is only non-null for the 1198 // app image case. Otherwise, we open the oat file after the image and check the checksum there. 1199 const uint32_t oat_checksum = oat_file->GetOatHeader().GetChecksum(); 1200 const uint32_t image_oat_checksum = image_header->GetOatChecksum(); 1201 if (oat_checksum != image_oat_checksum) { 1202 *error_msg = StringPrintf("Oat checksum 0x%x does not match the image one 0x%x in image %s", 1203 oat_checksum, 1204 image_oat_checksum, 1205 image_filename); 1206 return nullptr; 1207 } 1208 } 1209 1210 if (VLOG_IS_ON(startup)) { 1211 LOG(INFO) << "Dumping image sections"; 1212 for (size_t i = 0; i < ImageHeader::kSectionCount; ++i) { 1213 const auto section_idx = static_cast<ImageHeader::ImageSections>(i); 1214 auto& section = image_header->GetImageSection(section_idx); 1215 LOG(INFO) << section_idx << " start=" 1216 << reinterpret_cast<void*>(image_header->GetImageBegin() + section.Offset()) << " " 1217 << section; 1218 } 1219 } 1220 1221 const auto& bitmap_section = image_header->GetImageSection(ImageHeader::kSectionImageBitmap); 1222 // The location we want to map from is the first aligned page after the end of the stored 1223 // (possibly compressed) data. 1224 const size_t image_bitmap_offset = RoundUp(sizeof(ImageHeader) + image_header->GetDataSize(), 1225 kPageSize); 1226 const size_t end_of_bitmap = image_bitmap_offset + bitmap_section.Size(); 1227 if (end_of_bitmap != image_file_size) { 1228 *error_msg = StringPrintf( 1229 "Image file size does not equal end of bitmap: size=%" PRIu64 " vs. %zu.", image_file_size, 1230 end_of_bitmap); 1231 return nullptr; 1232 } 1233 1234 // The preferred address to map the image, null specifies any address. If we manage to map the 1235 // image at the image begin, the amount of fixup work required is minimized. 1236 std::vector<uint8_t*> addresses(1, image_header->GetImageBegin()); 1237 if (image_header->IsPic()) { 1238 // Can also map at a random low_4gb address since we can relocate in-place. 1239 addresses.push_back(nullptr); 1240 } 1241 1242 // Note: The image header is part of the image due to mmap page alignment required of offset. 1243 std::unique_ptr<MemMap> map; 1244 std::string temp_error_msg; 1245 for (uint8_t* address : addresses) { 1246 TimingLogger::ScopedTiming timing("MapImageFile", &logger); 1247 // Only care about the error message for the last address in addresses. We want to avoid the 1248 // overhead of printing the process maps if we can relocate. 1249 std::string* out_error_msg = (address == addresses.back()) ? &temp_error_msg : nullptr; 1250 const ImageHeader::StorageMode storage_mode = image_header->GetStorageMode(); 1251 if (storage_mode == ImageHeader::kStorageModeUncompressed) { 1252 map.reset(MemMap::MapFileAtAddress(address, 1253 image_header->GetImageSize(), 1254 PROT_READ | PROT_WRITE, 1255 MAP_PRIVATE, 1256 file->Fd(), 1257 0, 1258 /*low_4gb*/true, 1259 /*reuse*/false, 1260 image_filename, 1261 /*out*/out_error_msg)); 1262 } else { 1263 if (storage_mode != ImageHeader::kStorageModeLZ4 && 1264 storage_mode != ImageHeader::kStorageModeLZ4HC) { 1265 *error_msg = StringPrintf("Invalid storage mode in image header %d", 1266 static_cast<int>(storage_mode)); 1267 return nullptr; 1268 } 1269 // Reserve output and decompress into it. 1270 map.reset(MemMap::MapAnonymous(image_location, 1271 address, 1272 image_header->GetImageSize(), 1273 PROT_READ | PROT_WRITE, 1274 /*low_4gb*/true, 1275 /*reuse*/false, 1276 /*out*/out_error_msg)); 1277 if (map != nullptr) { 1278 const size_t stored_size = image_header->GetDataSize(); 1279 const size_t decompress_offset = sizeof(ImageHeader); // Skip the header. 1280 std::unique_ptr<MemMap> temp_map(MemMap::MapFile(sizeof(ImageHeader) + stored_size, 1281 PROT_READ, 1282 MAP_PRIVATE, 1283 file->Fd(), 1284 /*offset*/0, 1285 /*low_4gb*/false, 1286 image_filename, 1287 out_error_msg)); 1288 if (temp_map == nullptr) { 1289 DCHECK(!out_error_msg->empty()); 1290 return nullptr; 1291 } 1292 memcpy(map->Begin(), image_header, sizeof(ImageHeader)); 1293 const uint64_t start = NanoTime(); 1294 // LZ4HC and LZ4 have same internal format, both use LZ4_decompress. 1295 TimingLogger::ScopedTiming timing2("LZ4 decompress image", &logger); 1296 const size_t decompressed_size = LZ4_decompress_safe( 1297 reinterpret_cast<char*>(temp_map->Begin()) + sizeof(ImageHeader), 1298 reinterpret_cast<char*>(map->Begin()) + decompress_offset, 1299 stored_size, 1300 map->Size() - decompress_offset); 1301 VLOG(image) << "Decompressing image took " << PrettyDuration(NanoTime() - start); 1302 if (decompressed_size + sizeof(ImageHeader) != image_header->GetImageSize()) { 1303 *error_msg = StringPrintf( 1304 "Decompressed size does not match expected image size %zu vs %zu", 1305 decompressed_size + sizeof(ImageHeader), 1306 image_header->GetImageSize()); 1307 return nullptr; 1308 } 1309 } 1310 } 1311 if (map != nullptr) { 1312 break; 1313 } 1314 } 1315 1316 if (map == nullptr) { 1317 DCHECK(!temp_error_msg.empty()); 1318 *error_msg = temp_error_msg; 1319 return nullptr; 1320 } 1321 DCHECK_EQ(0, memcmp(image_header, map->Begin(), sizeof(ImageHeader))); 1322 1323 std::unique_ptr<MemMap> image_bitmap_map(MemMap::MapFileAtAddress(nullptr, 1324 bitmap_section.Size(), 1325 PROT_READ, MAP_PRIVATE, 1326 file->Fd(), 1327 image_bitmap_offset, 1328 /*low_4gb*/false, 1329 /*reuse*/false, 1330 image_filename, 1331 error_msg)); 1332 if (image_bitmap_map == nullptr) { 1333 *error_msg = StringPrintf("Failed to map image bitmap: %s", error_msg->c_str()); 1334 return nullptr; 1335 } 1336 // Loaded the map, use the image header from the file now in case we patch it with 1337 // RelocateInPlace. 1338 image_header = reinterpret_cast<ImageHeader*>(map->Begin()); 1339 const uint32_t bitmap_index = bitmap_index_.FetchAndAddSequentiallyConsistent(1); 1340 std::string bitmap_name(StringPrintf("imagespace %s live-bitmap %u", 1341 image_filename, 1342 bitmap_index)); 1343 // Bitmap only needs to cover until the end of the mirror objects section. 1344 const ImageSection& image_objects = image_header->GetImageSection(ImageHeader::kSectionObjects); 1345 // We only want the mirror object, not the ArtFields and ArtMethods. 1346 uint8_t* const image_end = map->Begin() + image_objects.End(); 1347 std::unique_ptr<accounting::ContinuousSpaceBitmap> bitmap; 1348 { 1349 TimingLogger::ScopedTiming timing("CreateImageBitmap", &logger); 1350 bitmap.reset( 1351 accounting::ContinuousSpaceBitmap::CreateFromMemMap( 1352 bitmap_name, 1353 image_bitmap_map.release(), 1354 reinterpret_cast<uint8_t*>(map->Begin()), 1355 image_objects.End())); 1356 if (bitmap == nullptr) { 1357 *error_msg = StringPrintf("Could not create bitmap '%s'", bitmap_name.c_str()); 1358 return nullptr; 1359 } 1360 } 1361 { 1362 TimingLogger::ScopedTiming timing("RelocateImage", &logger); 1363 if (!RelocateInPlace(*image_header, 1364 map->Begin(), 1365 bitmap.get(), 1366 oat_file, 1367 error_msg)) { 1368 return nullptr; 1369 } 1370 } 1371 // We only want the mirror object, not the ArtFields and ArtMethods. 1372 std::unique_ptr<ImageSpace> space(new ImageSpace(image_filename, 1373 image_location, 1374 map.release(), 1375 bitmap.release(), 1376 image_end)); 1377 1378 // VerifyImageAllocations() will be called later in Runtime::Init() 1379 // as some class roots like ArtMethod::java_lang_reflect_ArtMethod_ 1380 // and ArtField::java_lang_reflect_ArtField_, which are used from 1381 // Object::SizeOf() which VerifyImageAllocations() calls, are not 1382 // set yet at this point. 1383 if (oat_file == nullptr) { 1384 TimingLogger::ScopedTiming timing("OpenOatFile", &logger); 1385 space->oat_file_.reset(space->OpenOatFile(image_filename, error_msg)); 1386 if (space->oat_file_ == nullptr) { 1387 DCHECK(!error_msg->empty()); 1388 return nullptr; 1389 } 1390 space->oat_file_non_owned_ = space->oat_file_.get(); 1391 } else { 1392 space->oat_file_non_owned_ = oat_file; 1393 } 1394 1395 if (validate_oat_file) { 1396 TimingLogger::ScopedTiming timing("ValidateOatFile", &logger); 1397 if (!space->ValidateOatFile(error_msg)) { 1398 DCHECK(!error_msg->empty()); 1399 return nullptr; 1400 } 1401 } 1402 1403 Runtime* runtime = Runtime::Current(); 1404 1405 // If oat_file is null, then it is the boot image space. Use oat_file_non_owned_ from the space 1406 // to set the runtime methods. 1407 CHECK_EQ(oat_file != nullptr, image_header->IsAppImage()); 1408 if (image_header->IsAppImage()) { 1409 CHECK_EQ(runtime->GetResolutionMethod(), 1410 image_header->GetImageMethod(ImageHeader::kResolutionMethod)); 1411 CHECK_EQ(runtime->GetImtConflictMethod(), 1412 image_header->GetImageMethod(ImageHeader::kImtConflictMethod)); 1413 CHECK_EQ(runtime->GetImtUnimplementedMethod(), 1414 image_header->GetImageMethod(ImageHeader::kImtUnimplementedMethod)); 1415 CHECK_EQ(runtime->GetCalleeSaveMethod(Runtime::kSaveAll), 1416 image_header->GetImageMethod(ImageHeader::kCalleeSaveMethod)); 1417 CHECK_EQ(runtime->GetCalleeSaveMethod(Runtime::kRefsOnly), 1418 image_header->GetImageMethod(ImageHeader::kRefsOnlySaveMethod)); 1419 CHECK_EQ(runtime->GetCalleeSaveMethod(Runtime::kRefsAndArgs), 1420 image_header->GetImageMethod(ImageHeader::kRefsAndArgsSaveMethod)); 1421 } else if (!runtime->HasResolutionMethod()) { 1422 runtime->SetInstructionSet(space->oat_file_non_owned_->GetOatHeader().GetInstructionSet()); 1423 runtime->SetResolutionMethod(image_header->GetImageMethod(ImageHeader::kResolutionMethod)); 1424 runtime->SetImtConflictMethod(image_header->GetImageMethod(ImageHeader::kImtConflictMethod)); 1425 runtime->SetImtUnimplementedMethod( 1426 image_header->GetImageMethod(ImageHeader::kImtUnimplementedMethod)); 1427 runtime->SetCalleeSaveMethod( 1428 image_header->GetImageMethod(ImageHeader::kCalleeSaveMethod), Runtime::kSaveAll); 1429 runtime->SetCalleeSaveMethod( 1430 image_header->GetImageMethod(ImageHeader::kRefsOnlySaveMethod), Runtime::kRefsOnly); 1431 runtime->SetCalleeSaveMethod( 1432 image_header->GetImageMethod(ImageHeader::kRefsAndArgsSaveMethod), Runtime::kRefsAndArgs); 1433 } 1434 1435 VLOG(image) << "ImageSpace::Init exiting " << *space.get(); 1436 if (VLOG_IS_ON(image)) { 1437 logger.Dump(LOG(INFO)); 1438 } 1439 return space.release(); 1440 } 1441 1442 OatFile* ImageSpace::OpenOatFile(const char* image_path, std::string* error_msg) const { 1443 const ImageHeader& image_header = GetImageHeader(); 1444 std::string oat_filename = ImageHeader::GetOatLocationFromImageLocation(image_path); 1445 1446 CHECK(image_header.GetOatDataBegin() != nullptr); 1447 1448 OatFile* oat_file = OatFile::Open(oat_filename, 1449 oat_filename, 1450 image_header.GetOatDataBegin(), 1451 image_header.GetOatFileBegin(), 1452 !Runtime::Current()->IsAotCompiler(), 1453 /*low_4gb*/false, 1454 nullptr, 1455 error_msg); 1456 if (oat_file == nullptr) { 1457 *error_msg = StringPrintf("Failed to open oat file '%s' referenced from image %s: %s", 1458 oat_filename.c_str(), GetName(), error_msg->c_str()); 1459 return nullptr; 1460 } 1461 uint32_t oat_checksum = oat_file->GetOatHeader().GetChecksum(); 1462 uint32_t image_oat_checksum = image_header.GetOatChecksum(); 1463 if (oat_checksum != image_oat_checksum) { 1464 *error_msg = StringPrintf("Failed to match oat file checksum 0x%x to expected oat checksum 0x%x" 1465 " in image %s", oat_checksum, image_oat_checksum, GetName()); 1466 return nullptr; 1467 } 1468 int32_t image_patch_delta = image_header.GetPatchDelta(); 1469 int32_t oat_patch_delta = oat_file->GetOatHeader().GetImagePatchDelta(); 1470 if (oat_patch_delta != image_patch_delta && !image_header.CompilePic()) { 1471 // We should have already relocated by this point. Bail out. 1472 *error_msg = StringPrintf("Failed to match oat file patch delta %d to expected patch delta %d " 1473 "in image %s", oat_patch_delta, image_patch_delta, GetName()); 1474 return nullptr; 1475 } 1476 1477 return oat_file; 1478 } 1479 1480 bool ImageSpace::ValidateOatFile(std::string* error_msg) const { 1481 CHECK(oat_file_.get() != nullptr); 1482 for (const OatFile::OatDexFile* oat_dex_file : oat_file_->GetOatDexFiles()) { 1483 const std::string& dex_file_location = oat_dex_file->GetDexFileLocation(); 1484 uint32_t dex_file_location_checksum; 1485 if (!DexFile::GetChecksum(dex_file_location.c_str(), &dex_file_location_checksum, error_msg)) { 1486 *error_msg = StringPrintf("Failed to get checksum of dex file '%s' referenced by image %s: " 1487 "%s", dex_file_location.c_str(), GetName(), error_msg->c_str()); 1488 return false; 1489 } 1490 if (dex_file_location_checksum != oat_dex_file->GetDexFileLocationChecksum()) { 1491 *error_msg = StringPrintf("ValidateOatFile found checksum mismatch between oat file '%s' and " 1492 "dex file '%s' (0x%x != 0x%x)", 1493 oat_file_->GetLocation().c_str(), dex_file_location.c_str(), 1494 oat_dex_file->GetDexFileLocationChecksum(), 1495 dex_file_location_checksum); 1496 return false; 1497 } 1498 } 1499 return true; 1500 } 1501 1502 const OatFile* ImageSpace::GetOatFile() const { 1503 return oat_file_non_owned_; 1504 } 1505 1506 std::unique_ptr<const OatFile> ImageSpace::ReleaseOatFile() { 1507 CHECK(oat_file_ != nullptr); 1508 return std::move(oat_file_); 1509 } 1510 1511 void ImageSpace::Dump(std::ostream& os) const { 1512 os << GetType() 1513 << " begin=" << reinterpret_cast<void*>(Begin()) 1514 << ",end=" << reinterpret_cast<void*>(End()) 1515 << ",size=" << PrettySize(Size()) 1516 << ",name=\"" << GetName() << "\"]"; 1517 } 1518 1519 void ImageSpace::CreateMultiImageLocations(const std::string& input_image_file_name, 1520 const std::string& boot_classpath, 1521 std::vector<std::string>* image_file_names) { 1522 DCHECK(image_file_names != nullptr); 1523 1524 std::vector<std::string> images; 1525 Split(boot_classpath, ':', &images); 1526 1527 // Add the rest into the list. We have to adjust locations, possibly: 1528 // 1529 // For example, image_file_name is /a/b/c/d/e.art 1530 // images[0] is f/c/d/e.art 1531 // ---------------------------------------------- 1532 // images[1] is g/h/i/j.art -> /a/b/h/i/j.art 1533 const std::string& first_image = images[0]; 1534 // Length of common suffix. 1535 size_t common = 0; 1536 while (common < input_image_file_name.size() && 1537 common < first_image.size() && 1538 *(input_image_file_name.end() - common - 1) == *(first_image.end() - common - 1)) { 1539 ++common; 1540 } 1541 // We want to replace the prefix of the input image with the prefix of the boot class path. 1542 // This handles the case where the image file contains @ separators. 1543 // Example image_file_name is oats/system@framework (at) boot.art 1544 // images[0] is .../arm/boot.art 1545 // means that the image name prefix will be oats/system@framework@ 1546 // so that the other images are openable. 1547 const size_t old_prefix_length = first_image.size() - common; 1548 const std::string new_prefix = input_image_file_name.substr( 1549 0, 1550 input_image_file_name.size() - common); 1551 1552 // Apply pattern to images[1] .. images[n]. 1553 for (size_t i = 1; i < images.size(); ++i) { 1554 const std::string& image = images[i]; 1555 CHECK_GT(image.length(), old_prefix_length); 1556 std::string suffix = image.substr(old_prefix_length); 1557 image_file_names->push_back(new_prefix + suffix); 1558 } 1559 } 1560 1561 ImageSpace* ImageSpace::CreateFromAppImage(const char* image, 1562 const OatFile* oat_file, 1563 std::string* error_msg) { 1564 return gc::space::ImageSpace::Init(image, 1565 image, 1566 /*validate_oat_file*/false, 1567 oat_file, 1568 /*out*/error_msg); 1569 } 1570 1571 void ImageSpace::DumpSections(std::ostream& os) const { 1572 const uint8_t* base = Begin(); 1573 const ImageHeader& header = GetImageHeader(); 1574 for (size_t i = 0; i < ImageHeader::kSectionCount; ++i) { 1575 auto section_type = static_cast<ImageHeader::ImageSections>(i); 1576 const ImageSection& section = header.GetImageSection(section_type); 1577 os << section_type << " " << reinterpret_cast<const void*>(base + section.Offset()) 1578 << "-" << reinterpret_cast<const void*>(base + section.End()) << "\n"; 1579 } 1580 } 1581 1582 } // namespace space 1583 } // namespace gc 1584 } // namespace art 1585