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