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 "android-base/stringprintf.h" 26 #include "android-base/strings.h" 27 28 #include "art_field-inl.h" 29 #include "art_method-inl.h" 30 #include "base/callee_save_type.h" 31 #include "base/enums.h" 32 #include "base/macros.h" 33 #include "base/stl_util.h" 34 #include "base/scoped_flock.h" 35 #include "base/systrace.h" 36 #include "base/time_utils.h" 37 #include "exec_utils.h" 38 #include "gc/accounting/space_bitmap-inl.h" 39 #include "image-inl.h" 40 #include "image_space_fs.h" 41 #include "mirror/class-inl.h" 42 #include "mirror/object-inl.h" 43 #include "mirror/object-refvisitor-inl.h" 44 #include "oat_file.h" 45 #include "os.h" 46 #include "runtime.h" 47 #include "space-inl.h" 48 #include "utils.h" 49 50 namespace art { 51 namespace gc { 52 namespace space { 53 54 using android::base::StringAppendF; 55 using android::base::StringPrintf; 56 57 Atomic<uint32_t> ImageSpace::bitmap_index_(0); 58 59 ImageSpace::ImageSpace(const std::string& image_filename, 60 const char* image_location, 61 MemMap* mem_map, 62 accounting::ContinuousSpaceBitmap* live_bitmap, 63 uint8_t* end) 64 : MemMapSpace(image_filename, 65 mem_map, 66 mem_map->Begin(), 67 end, 68 end, 69 kGcRetentionPolicyNeverCollect), 70 oat_file_non_owned_(nullptr), 71 image_location_(image_location) { 72 DCHECK(live_bitmap != nullptr); 73 live_bitmap_.reset(live_bitmap); 74 } 75 76 static int32_t ChooseRelocationOffsetDelta(int32_t min_delta, int32_t max_delta) { 77 CHECK_ALIGNED(min_delta, kPageSize); 78 CHECK_ALIGNED(max_delta, kPageSize); 79 CHECK_LT(min_delta, max_delta); 80 81 int32_t r = GetRandomNumber<int32_t>(min_delta, max_delta); 82 if (r % 2 == 0) { 83 r = RoundUp(r, kPageSize); 84 } else { 85 r = RoundDown(r, kPageSize); 86 } 87 CHECK_LE(min_delta, r); 88 CHECK_GE(max_delta, r); 89 CHECK_ALIGNED(r, kPageSize); 90 return r; 91 } 92 93 static int32_t ChooseRelocationOffsetDelta() { 94 return ChooseRelocationOffsetDelta(ART_BASE_ADDRESS_MIN_DELTA, ART_BASE_ADDRESS_MAX_DELTA); 95 } 96 97 static bool GenerateImage(const std::string& image_filename, 98 InstructionSet image_isa, 99 std::string* error_msg) { 100 const std::string boot_class_path_string(Runtime::Current()->GetBootClassPathString()); 101 std::vector<std::string> boot_class_path; 102 Split(boot_class_path_string, ':', &boot_class_path); 103 if (boot_class_path.empty()) { 104 *error_msg = "Failed to generate image because no boot class path specified"; 105 return false; 106 } 107 // We should clean up so we are more likely to have room for the image. 108 if (Runtime::Current()->IsZygote()) { 109 LOG(INFO) << "Pruning dalvik-cache since we are generating an image and will need to recompile"; 110 PruneDalvikCache(image_isa); 111 } 112 113 std::vector<std::string> arg_vector; 114 115 std::string dex2oat(Runtime::Current()->GetCompilerExecutable()); 116 arg_vector.push_back(dex2oat); 117 118 std::string image_option_string("--image="); 119 image_option_string += image_filename; 120 arg_vector.push_back(image_option_string); 121 122 for (size_t i = 0; i < boot_class_path.size(); i++) { 123 arg_vector.push_back(std::string("--dex-file=") + boot_class_path[i]); 124 } 125 126 std::string oat_file_option_string("--oat-file="); 127 oat_file_option_string += ImageHeader::GetOatLocationFromImageLocation(image_filename); 128 arg_vector.push_back(oat_file_option_string); 129 130 // Note: we do not generate a fully debuggable boot image so we do not pass the 131 // compiler flag --debuggable here. 132 133 Runtime::Current()->AddCurrentRuntimeFeaturesAsDex2OatArguments(&arg_vector); 134 CHECK_EQ(image_isa, kRuntimeISA) 135 << "We should always be generating an image for the current isa."; 136 137 int32_t base_offset = ChooseRelocationOffsetDelta(); 138 LOG(INFO) << "Using an offset of 0x" << std::hex << base_offset << " from default " 139 << "art base address of 0x" << std::hex << ART_BASE_ADDRESS; 140 arg_vector.push_back(StringPrintf("--base=0x%x", ART_BASE_ADDRESS + base_offset)); 141 142 if (!kIsTargetBuild) { 143 arg_vector.push_back("--host"); 144 } 145 146 const std::vector<std::string>& compiler_options = Runtime::Current()->GetImageCompilerOptions(); 147 for (size_t i = 0; i < compiler_options.size(); ++i) { 148 arg_vector.push_back(compiler_options[i].c_str()); 149 } 150 151 std::string command_line(android::base::Join(arg_vector, ' ')); 152 LOG(INFO) << "GenerateImage: " << command_line; 153 return Exec(arg_vector, error_msg); 154 } 155 156 static bool FindImageFilenameImpl(const char* image_location, 157 const InstructionSet image_isa, 158 bool* has_system, 159 std::string* system_filename, 160 bool* dalvik_cache_exists, 161 std::string* dalvik_cache, 162 bool* is_global_cache, 163 bool* has_cache, 164 std::string* cache_filename) { 165 DCHECK(dalvik_cache != nullptr); 166 167 *has_system = false; 168 *has_cache = false; 169 // image_location = /system/framework/boot.art 170 // system_image_location = /system/framework/<image_isa>/boot.art 171 std::string system_image_filename(GetSystemImageFilename(image_location, image_isa)); 172 if (OS::FileExists(system_image_filename.c_str())) { 173 *system_filename = system_image_filename; 174 *has_system = true; 175 } 176 177 bool have_android_data = false; 178 *dalvik_cache_exists = false; 179 GetDalvikCache(GetInstructionSetString(image_isa), 180 true, 181 dalvik_cache, 182 &have_android_data, 183 dalvik_cache_exists, 184 is_global_cache); 185 186 if (have_android_data && *dalvik_cache_exists) { 187 // Always set output location even if it does not exist, 188 // so that the caller knows where to create the image. 189 // 190 // image_location = /system/framework/boot.art 191 // *image_filename = /data/dalvik-cache/<image_isa>/boot.art 192 std::string error_msg; 193 if (!GetDalvikCacheFilename(image_location, 194 dalvik_cache->c_str(), 195 cache_filename, 196 &error_msg)) { 197 LOG(WARNING) << error_msg; 198 return *has_system; 199 } 200 *has_cache = OS::FileExists(cache_filename->c_str()); 201 } 202 return *has_system || *has_cache; 203 } 204 205 bool ImageSpace::FindImageFilename(const char* image_location, 206 const InstructionSet image_isa, 207 std::string* system_filename, 208 bool* has_system, 209 std::string* cache_filename, 210 bool* dalvik_cache_exists, 211 bool* has_cache, 212 bool* is_global_cache) { 213 std::string dalvik_cache_unused; 214 return FindImageFilenameImpl(image_location, 215 image_isa, 216 has_system, 217 system_filename, 218 dalvik_cache_exists, 219 &dalvik_cache_unused, 220 is_global_cache, 221 has_cache, 222 cache_filename); 223 } 224 225 static bool ReadSpecificImageHeader(const char* filename, ImageHeader* image_header) { 226 std::unique_ptr<File> image_file(OS::OpenFileForReading(filename)); 227 if (image_file.get() == nullptr) { 228 return false; 229 } 230 const bool success = image_file->ReadFully(image_header, sizeof(ImageHeader)); 231 if (!success || !image_header->IsValid()) { 232 return false; 233 } 234 return true; 235 } 236 237 // Relocate the image at image_location to dest_filename and relocate it by a random amount. 238 static bool RelocateImage(const char* image_location, 239 const char* dest_filename, 240 InstructionSet isa, 241 std::string* error_msg) { 242 // We should clean up so we are more likely to have room for the image. 243 if (Runtime::Current()->IsZygote()) { 244 LOG(INFO) << "Pruning dalvik-cache since we are relocating an image and will need to recompile"; 245 PruneDalvikCache(isa); 246 } 247 248 std::string patchoat(Runtime::Current()->GetPatchoatExecutable()); 249 250 std::string input_image_location_arg("--input-image-location="); 251 input_image_location_arg += image_location; 252 253 std::string output_image_filename_arg("--output-image-file="); 254 output_image_filename_arg += dest_filename; 255 256 std::string instruction_set_arg("--instruction-set="); 257 instruction_set_arg += GetInstructionSetString(isa); 258 259 std::string base_offset_arg("--base-offset-delta="); 260 StringAppendF(&base_offset_arg, "%d", ChooseRelocationOffsetDelta()); 261 262 std::vector<std::string> argv; 263 argv.push_back(patchoat); 264 265 argv.push_back(input_image_location_arg); 266 argv.push_back(output_image_filename_arg); 267 268 argv.push_back(instruction_set_arg); 269 argv.push_back(base_offset_arg); 270 271 std::string command_line(android::base::Join(argv, ' ')); 272 LOG(INFO) << "RelocateImage: " << command_line; 273 return Exec(argv, error_msg); 274 } 275 276 static ImageHeader* ReadSpecificImageHeader(const char* filename, std::string* error_msg) { 277 std::unique_ptr<ImageHeader> hdr(new ImageHeader); 278 if (!ReadSpecificImageHeader(filename, hdr.get())) { 279 *error_msg = StringPrintf("Unable to read image header for %s", filename); 280 return nullptr; 281 } 282 return hdr.release(); 283 } 284 285 ImageHeader* ImageSpace::ReadImageHeader(const char* image_location, 286 const InstructionSet image_isa, 287 std::string* error_msg) { 288 std::string system_filename; 289 bool has_system = false; 290 std::string cache_filename; 291 bool has_cache = false; 292 bool dalvik_cache_exists = false; 293 bool is_global_cache = false; 294 if (FindImageFilename(image_location, image_isa, &system_filename, &has_system, 295 &cache_filename, &dalvik_cache_exists, &has_cache, &is_global_cache)) { 296 if (Runtime::Current()->ShouldRelocate()) { 297 if (has_system && has_cache) { 298 std::unique_ptr<ImageHeader> sys_hdr(new ImageHeader); 299 std::unique_ptr<ImageHeader> cache_hdr(new ImageHeader); 300 if (!ReadSpecificImageHeader(system_filename.c_str(), sys_hdr.get())) { 301 *error_msg = StringPrintf("Unable to read image header for %s at %s", 302 image_location, system_filename.c_str()); 303 return nullptr; 304 } 305 if (!ReadSpecificImageHeader(cache_filename.c_str(), cache_hdr.get())) { 306 *error_msg = StringPrintf("Unable to read image header for %s at %s", 307 image_location, cache_filename.c_str()); 308 return nullptr; 309 } 310 if (sys_hdr->GetOatChecksum() != cache_hdr->GetOatChecksum()) { 311 *error_msg = StringPrintf("Unable to find a relocated version of image file %s", 312 image_location); 313 return nullptr; 314 } 315 return cache_hdr.release(); 316 } else if (!has_cache) { 317 *error_msg = StringPrintf("Unable to find a relocated version of image file %s", 318 image_location); 319 return nullptr; 320 } else if (!has_system && has_cache) { 321 // This can probably just use the cache one. 322 return ReadSpecificImageHeader(cache_filename.c_str(), error_msg); 323 } 324 } else { 325 // We don't want to relocate, Just pick the appropriate one if we have it and return. 326 if (has_system && has_cache) { 327 // We want the cache if the checksum matches, otherwise the system. 328 std::unique_ptr<ImageHeader> system(ReadSpecificImageHeader(system_filename.c_str(), 329 error_msg)); 330 std::unique_ptr<ImageHeader> cache(ReadSpecificImageHeader(cache_filename.c_str(), 331 error_msg)); 332 if (system.get() == nullptr || 333 (cache.get() != nullptr && cache->GetOatChecksum() == system->GetOatChecksum())) { 334 return cache.release(); 335 } else { 336 return system.release(); 337 } 338 } else if (has_system) { 339 return ReadSpecificImageHeader(system_filename.c_str(), error_msg); 340 } else if (has_cache) { 341 return ReadSpecificImageHeader(cache_filename.c_str(), error_msg); 342 } 343 } 344 } 345 346 *error_msg = StringPrintf("Unable to find image file for %s", image_location); 347 return nullptr; 348 } 349 350 static bool ChecksumsMatch(const char* image_a, const char* image_b, std::string* error_msg) { 351 DCHECK(error_msg != nullptr); 352 353 ImageHeader hdr_a; 354 ImageHeader hdr_b; 355 356 if (!ReadSpecificImageHeader(image_a, &hdr_a)) { 357 *error_msg = StringPrintf("Cannot read header of %s", image_a); 358 return false; 359 } 360 if (!ReadSpecificImageHeader(image_b, &hdr_b)) { 361 *error_msg = StringPrintf("Cannot read header of %s", image_b); 362 return false; 363 } 364 365 if (hdr_a.GetOatChecksum() != hdr_b.GetOatChecksum()) { 366 *error_msg = StringPrintf("Checksum mismatch: %u(%s) vs %u(%s)", 367 hdr_a.GetOatChecksum(), 368 image_a, 369 hdr_b.GetOatChecksum(), 370 image_b); 371 return false; 372 } 373 374 return true; 375 } 376 377 static bool CanWriteToDalvikCache(const InstructionSet isa) { 378 const std::string dalvik_cache = GetDalvikCache(GetInstructionSetString(isa)); 379 if (access(dalvik_cache.c_str(), O_RDWR) == 0) { 380 return true; 381 } else if (errno != EACCES) { 382 PLOG(WARNING) << "CanWriteToDalvikCache returned error other than EACCES"; 383 } 384 return false; 385 } 386 387 static bool ImageCreationAllowed(bool is_global_cache, 388 const InstructionSet isa, 389 std::string* error_msg) { 390 // Anyone can write into a "local" cache. 391 if (!is_global_cache) { 392 return true; 393 } 394 395 // Only the zygote running as root is allowed to create the global boot image. 396 // If the zygote is running as non-root (and cannot write to the dalvik-cache), 397 // then image creation is not allowed.. 398 if (Runtime::Current()->IsZygote()) { 399 return CanWriteToDalvikCache(isa); 400 } 401 402 *error_msg = "Only the zygote can create the global boot image."; 403 return false; 404 } 405 406 void ImageSpace::VerifyImageAllocations() { 407 uint8_t* current = Begin() + RoundUp(sizeof(ImageHeader), kObjectAlignment); 408 while (current < End()) { 409 CHECK_ALIGNED(current, kObjectAlignment); 410 auto* obj = reinterpret_cast<mirror::Object*>(current); 411 CHECK(obj->GetClass() != nullptr) << "Image object at address " << obj << " has null class"; 412 CHECK(live_bitmap_->Test(obj)) << obj->PrettyTypeOf(); 413 if (kUseBakerReadBarrier) { 414 obj->AssertReadBarrierState(); 415 } 416 current += RoundUp(obj->SizeOf(), kObjectAlignment); 417 } 418 } 419 420 // Helper class for relocating from one range of memory to another. 421 class RelocationRange { 422 public: 423 RelocationRange() = default; 424 RelocationRange(const RelocationRange&) = default; 425 RelocationRange(uintptr_t source, uintptr_t dest, uintptr_t length) 426 : source_(source), 427 dest_(dest), 428 length_(length) {} 429 430 bool InSource(uintptr_t address) const { 431 return address - source_ < length_; 432 } 433 434 bool InDest(uintptr_t address) const { 435 return address - dest_ < length_; 436 } 437 438 // Translate a source address to the destination space. 439 uintptr_t ToDest(uintptr_t address) const { 440 DCHECK(InSource(address)); 441 return address + Delta(); 442 } 443 444 // Returns the delta between the dest from the source. 445 uintptr_t Delta() const { 446 return dest_ - source_; 447 } 448 449 uintptr_t Source() const { 450 return source_; 451 } 452 453 uintptr_t Dest() const { 454 return dest_; 455 } 456 457 uintptr_t Length() const { 458 return length_; 459 } 460 461 private: 462 const uintptr_t source_; 463 const uintptr_t dest_; 464 const uintptr_t length_; 465 }; 466 467 std::ostream& operator<<(std::ostream& os, const RelocationRange& reloc) { 468 return os << "(" << reinterpret_cast<const void*>(reloc.Source()) << "-" 469 << reinterpret_cast<const void*>(reloc.Source() + reloc.Length()) << ")->(" 470 << reinterpret_cast<const void*>(reloc.Dest()) << "-" 471 << reinterpret_cast<const void*>(reloc.Dest() + reloc.Length()) << ")"; 472 } 473 474 // Helper class encapsulating loading, so we can access private ImageSpace members (this is a 475 // friend class), but not declare functions in the header. 476 class ImageSpaceLoader { 477 public: 478 static std::unique_ptr<ImageSpace> Load(const char* image_location, 479 const std::string& image_filename, 480 bool is_zygote, 481 bool is_global_cache, 482 bool validate_oat_file, 483 std::string* error_msg) 484 REQUIRES_SHARED(Locks::mutator_lock_) { 485 // Should this be a RDWR lock? This is only a defensive measure, as at 486 // this point the image should exist. 487 // However, only the zygote can write into the global dalvik-cache, so 488 // restrict to zygote processes, or any process that isn't using 489 // /data/dalvik-cache (which we assume to be allowed to write there). 490 const bool rw_lock = is_zygote || !is_global_cache; 491 492 // Note that we must not use the file descriptor associated with 493 // ScopedFlock::GetFile to Init the image file. We want the file 494 // descriptor (and the associated exclusive lock) to be released when 495 // we leave Create. 496 ScopedFlock image = LockedFile::Open(image_filename.c_str(), 497 rw_lock ? (O_CREAT | O_RDWR) : O_RDONLY /* flags */, 498 true /* block */, 499 error_msg); 500 501 VLOG(startup) << "Using image file " << image_filename.c_str() << " for image location " 502 << image_location; 503 // If we are in /system we can assume the image is good. We can also 504 // assume this if we are using a relocated image (i.e. image checksum 505 // matches) since this is only different by the offset. We need this to 506 // make sure that host tests continue to work. 507 // Since we are the boot image, pass null since we load the oat file from the boot image oat 508 // file name. 509 return Init(image_filename.c_str(), 510 image_location, 511 validate_oat_file, 512 /* oat_file */nullptr, 513 error_msg); 514 } 515 516 static std::unique_ptr<ImageSpace> Init(const char* image_filename, 517 const char* image_location, 518 bool validate_oat_file, 519 const OatFile* oat_file, 520 std::string* error_msg) 521 REQUIRES_SHARED(Locks::mutator_lock_) { 522 CHECK(image_filename != nullptr); 523 CHECK(image_location != nullptr); 524 525 TimingLogger logger(__PRETTY_FUNCTION__, true, VLOG_IS_ON(image)); 526 VLOG(image) << "ImageSpace::Init entering image_filename=" << image_filename; 527 528 std::unique_ptr<File> file; 529 { 530 TimingLogger::ScopedTiming timing("OpenImageFile", &logger); 531 file.reset(OS::OpenFileForReading(image_filename)); 532 if (file == nullptr) { 533 *error_msg = StringPrintf("Failed to open '%s'", image_filename); 534 return nullptr; 535 } 536 } 537 ImageHeader temp_image_header; 538 ImageHeader* image_header = &temp_image_header; 539 { 540 TimingLogger::ScopedTiming timing("ReadImageHeader", &logger); 541 bool success = file->ReadFully(image_header, sizeof(*image_header)); 542 if (!success || !image_header->IsValid()) { 543 *error_msg = StringPrintf("Invalid image header in '%s'", image_filename); 544 return nullptr; 545 } 546 } 547 // Check that the file is larger or equal to the header size + data size. 548 const uint64_t image_file_size = static_cast<uint64_t>(file->GetLength()); 549 if (image_file_size < sizeof(ImageHeader) + image_header->GetDataSize()) { 550 *error_msg = StringPrintf("Image file truncated: %" PRIu64 " vs. %" PRIu64 ".", 551 image_file_size, 552 sizeof(ImageHeader) + image_header->GetDataSize()); 553 return nullptr; 554 } 555 556 if (oat_file != nullptr) { 557 // If we have an oat file, check the oat file checksum. The oat file is only non-null for the 558 // app image case. Otherwise, we open the oat file after the image and check the checksum there. 559 const uint32_t oat_checksum = oat_file->GetOatHeader().GetChecksum(); 560 const uint32_t image_oat_checksum = image_header->GetOatChecksum(); 561 if (oat_checksum != image_oat_checksum) { 562 *error_msg = StringPrintf("Oat checksum 0x%x does not match the image one 0x%x in image %s", 563 oat_checksum, 564 image_oat_checksum, 565 image_filename); 566 return nullptr; 567 } 568 } 569 570 if (VLOG_IS_ON(startup)) { 571 LOG(INFO) << "Dumping image sections"; 572 for (size_t i = 0; i < ImageHeader::kSectionCount; ++i) { 573 const auto section_idx = static_cast<ImageHeader::ImageSections>(i); 574 auto& section = image_header->GetImageSection(section_idx); 575 LOG(INFO) << section_idx << " start=" 576 << reinterpret_cast<void*>(image_header->GetImageBegin() + section.Offset()) << " " 577 << section; 578 } 579 } 580 581 const auto& bitmap_section = image_header->GetImageSection(ImageHeader::kSectionImageBitmap); 582 // The location we want to map from is the first aligned page after the end of the stored 583 // (possibly compressed) data. 584 const size_t image_bitmap_offset = RoundUp(sizeof(ImageHeader) + image_header->GetDataSize(), 585 kPageSize); 586 const size_t end_of_bitmap = image_bitmap_offset + bitmap_section.Size(); 587 if (end_of_bitmap != image_file_size) { 588 *error_msg = StringPrintf( 589 "Image file size does not equal end of bitmap: size=%" PRIu64 " vs. %zu.", image_file_size, 590 end_of_bitmap); 591 return nullptr; 592 } 593 594 std::unique_ptr<MemMap> map; 595 596 // GetImageBegin is the preferred address to map the image. If we manage to map the 597 // image at the image begin, the amount of fixup work required is minimized. 598 // If it is pic we will retry with error_msg for the failure case. Pass a null error_msg to 599 // avoid reading proc maps for a mapping failure and slowing everything down. 600 map.reset(LoadImageFile(image_filename, 601 image_location, 602 *image_header, 603 image_header->GetImageBegin(), 604 file->Fd(), 605 logger, 606 image_header->IsPic() ? nullptr : error_msg)); 607 // If the header specifies PIC mode, we can also map at a random low_4gb address since we can 608 // relocate in-place. 609 if (map == nullptr && image_header->IsPic()) { 610 map.reset(LoadImageFile(image_filename, 611 image_location, 612 *image_header, 613 /* address */ nullptr, 614 file->Fd(), 615 logger, 616 error_msg)); 617 } 618 // Were we able to load something and continue? 619 if (map == nullptr) { 620 DCHECK(!error_msg->empty()); 621 return nullptr; 622 } 623 DCHECK_EQ(0, memcmp(image_header, map->Begin(), sizeof(ImageHeader))); 624 625 std::unique_ptr<MemMap> image_bitmap_map(MemMap::MapFileAtAddress(nullptr, 626 bitmap_section.Size(), 627 PROT_READ, MAP_PRIVATE, 628 file->Fd(), 629 image_bitmap_offset, 630 /*low_4gb*/false, 631 /*reuse*/false, 632 image_filename, 633 error_msg)); 634 if (image_bitmap_map == nullptr) { 635 *error_msg = StringPrintf("Failed to map image bitmap: %s", error_msg->c_str()); 636 return nullptr; 637 } 638 // Loaded the map, use the image header from the file now in case we patch it with 639 // RelocateInPlace. 640 image_header = reinterpret_cast<ImageHeader*>(map->Begin()); 641 const uint32_t bitmap_index = ImageSpace::bitmap_index_.FetchAndAddSequentiallyConsistent(1); 642 std::string bitmap_name(StringPrintf("imagespace %s live-bitmap %u", 643 image_filename, 644 bitmap_index)); 645 // Bitmap only needs to cover until the end of the mirror objects section. 646 const ImageSection& image_objects = image_header->GetImageSection(ImageHeader::kSectionObjects); 647 // We only want the mirror object, not the ArtFields and ArtMethods. 648 uint8_t* const image_end = map->Begin() + image_objects.End(); 649 std::unique_ptr<accounting::ContinuousSpaceBitmap> bitmap; 650 { 651 TimingLogger::ScopedTiming timing("CreateImageBitmap", &logger); 652 bitmap.reset( 653 accounting::ContinuousSpaceBitmap::CreateFromMemMap( 654 bitmap_name, 655 image_bitmap_map.release(), 656 reinterpret_cast<uint8_t*>(map->Begin()), 657 // Make sure the bitmap is aligned to card size instead of just bitmap word size. 658 RoundUp(image_objects.End(), gc::accounting::CardTable::kCardSize))); 659 if (bitmap == nullptr) { 660 *error_msg = StringPrintf("Could not create bitmap '%s'", bitmap_name.c_str()); 661 return nullptr; 662 } 663 } 664 { 665 TimingLogger::ScopedTiming timing("RelocateImage", &logger); 666 if (!RelocateInPlace(*image_header, 667 map->Begin(), 668 bitmap.get(), 669 oat_file, 670 error_msg)) { 671 return nullptr; 672 } 673 } 674 // We only want the mirror object, not the ArtFields and ArtMethods. 675 std::unique_ptr<ImageSpace> space(new ImageSpace(image_filename, 676 image_location, 677 map.release(), 678 bitmap.release(), 679 image_end)); 680 681 // VerifyImageAllocations() will be called later in Runtime::Init() 682 // as some class roots like ArtMethod::java_lang_reflect_ArtMethod_ 683 // and ArtField::java_lang_reflect_ArtField_, which are used from 684 // Object::SizeOf() which VerifyImageAllocations() calls, are not 685 // set yet at this point. 686 if (oat_file == nullptr) { 687 TimingLogger::ScopedTiming timing("OpenOatFile", &logger); 688 space->oat_file_ = OpenOatFile(*space, image_filename, error_msg); 689 if (space->oat_file_ == nullptr) { 690 DCHECK(!error_msg->empty()); 691 return nullptr; 692 } 693 space->oat_file_non_owned_ = space->oat_file_.get(); 694 } else { 695 space->oat_file_non_owned_ = oat_file; 696 } 697 698 if (validate_oat_file) { 699 TimingLogger::ScopedTiming timing("ValidateOatFile", &logger); 700 CHECK(space->oat_file_ != nullptr); 701 if (!ImageSpace::ValidateOatFile(*space->oat_file_, error_msg)) { 702 DCHECK(!error_msg->empty()); 703 return nullptr; 704 } 705 } 706 707 Runtime* runtime = Runtime::Current(); 708 709 // If oat_file is null, then it is the boot image space. Use oat_file_non_owned_ from the space 710 // to set the runtime methods. 711 CHECK_EQ(oat_file != nullptr, image_header->IsAppImage()); 712 if (image_header->IsAppImage()) { 713 CHECK_EQ(runtime->GetResolutionMethod(), 714 image_header->GetImageMethod(ImageHeader::kResolutionMethod)); 715 CHECK_EQ(runtime->GetImtConflictMethod(), 716 image_header->GetImageMethod(ImageHeader::kImtConflictMethod)); 717 CHECK_EQ(runtime->GetImtUnimplementedMethod(), 718 image_header->GetImageMethod(ImageHeader::kImtUnimplementedMethod)); 719 CHECK_EQ(runtime->GetCalleeSaveMethod(CalleeSaveType::kSaveAllCalleeSaves), 720 image_header->GetImageMethod(ImageHeader::kSaveAllCalleeSavesMethod)); 721 CHECK_EQ(runtime->GetCalleeSaveMethod(CalleeSaveType::kSaveRefsOnly), 722 image_header->GetImageMethod(ImageHeader::kSaveRefsOnlyMethod)); 723 CHECK_EQ(runtime->GetCalleeSaveMethod(CalleeSaveType::kSaveRefsAndArgs), 724 image_header->GetImageMethod(ImageHeader::kSaveRefsAndArgsMethod)); 725 CHECK_EQ(runtime->GetCalleeSaveMethod(CalleeSaveType::kSaveEverything), 726 image_header->GetImageMethod(ImageHeader::kSaveEverythingMethod)); 727 } else if (!runtime->HasResolutionMethod()) { 728 runtime->SetInstructionSet(space->oat_file_non_owned_->GetOatHeader().GetInstructionSet()); 729 runtime->SetResolutionMethod(image_header->GetImageMethod(ImageHeader::kResolutionMethod)); 730 runtime->SetImtConflictMethod(image_header->GetImageMethod(ImageHeader::kImtConflictMethod)); 731 runtime->SetImtUnimplementedMethod( 732 image_header->GetImageMethod(ImageHeader::kImtUnimplementedMethod)); 733 runtime->SetCalleeSaveMethod( 734 image_header->GetImageMethod(ImageHeader::kSaveAllCalleeSavesMethod), 735 CalleeSaveType::kSaveAllCalleeSaves); 736 runtime->SetCalleeSaveMethod( 737 image_header->GetImageMethod(ImageHeader::kSaveRefsOnlyMethod), 738 CalleeSaveType::kSaveRefsOnly); 739 runtime->SetCalleeSaveMethod( 740 image_header->GetImageMethod(ImageHeader::kSaveRefsAndArgsMethod), 741 CalleeSaveType::kSaveRefsAndArgs); 742 runtime->SetCalleeSaveMethod( 743 image_header->GetImageMethod(ImageHeader::kSaveEverythingMethod), 744 CalleeSaveType::kSaveEverything); 745 } 746 747 VLOG(image) << "ImageSpace::Init exiting " << *space.get(); 748 if (VLOG_IS_ON(image)) { 749 logger.Dump(LOG_STREAM(INFO)); 750 } 751 return space; 752 } 753 754 private: 755 static MemMap* LoadImageFile(const char* image_filename, 756 const char* image_location, 757 const ImageHeader& image_header, 758 uint8_t* address, 759 int fd, 760 TimingLogger& logger, 761 std::string* error_msg) { 762 TimingLogger::ScopedTiming timing("MapImageFile", &logger); 763 const ImageHeader::StorageMode storage_mode = image_header.GetStorageMode(); 764 if (storage_mode == ImageHeader::kStorageModeUncompressed) { 765 return MemMap::MapFileAtAddress(address, 766 image_header.GetImageSize(), 767 PROT_READ | PROT_WRITE, 768 MAP_PRIVATE, 769 fd, 770 0, 771 /*low_4gb*/true, 772 /*reuse*/false, 773 image_filename, 774 error_msg); 775 } 776 777 if (storage_mode != ImageHeader::kStorageModeLZ4 && 778 storage_mode != ImageHeader::kStorageModeLZ4HC) { 779 if (error_msg != nullptr) { 780 *error_msg = StringPrintf("Invalid storage mode in image header %d", 781 static_cast<int>(storage_mode)); 782 } 783 return nullptr; 784 } 785 786 // Reserve output and decompress into it. 787 std::unique_ptr<MemMap> map(MemMap::MapAnonymous(image_location, 788 address, 789 image_header.GetImageSize(), 790 PROT_READ | PROT_WRITE, 791 /*low_4gb*/true, 792 /*reuse*/false, 793 error_msg)); 794 if (map != nullptr) { 795 const size_t stored_size = image_header.GetDataSize(); 796 const size_t decompress_offset = sizeof(ImageHeader); // Skip the header. 797 std::unique_ptr<MemMap> temp_map(MemMap::MapFile(sizeof(ImageHeader) + stored_size, 798 PROT_READ, 799 MAP_PRIVATE, 800 fd, 801 /*offset*/0, 802 /*low_4gb*/false, 803 image_filename, 804 error_msg)); 805 if (temp_map == nullptr) { 806 DCHECK(error_msg == nullptr || !error_msg->empty()); 807 return nullptr; 808 } 809 memcpy(map->Begin(), &image_header, sizeof(ImageHeader)); 810 const uint64_t start = NanoTime(); 811 // LZ4HC and LZ4 have same internal format, both use LZ4_decompress. 812 TimingLogger::ScopedTiming timing2("LZ4 decompress image", &logger); 813 const size_t decompressed_size = LZ4_decompress_safe( 814 reinterpret_cast<char*>(temp_map->Begin()) + sizeof(ImageHeader), 815 reinterpret_cast<char*>(map->Begin()) + decompress_offset, 816 stored_size, 817 map->Size() - decompress_offset); 818 const uint64_t time = NanoTime() - start; 819 // Add one 1 ns to prevent possible divide by 0. 820 VLOG(image) << "Decompressing image took " << PrettyDuration(time) << " (" 821 << PrettySize(static_cast<uint64_t>(map->Size()) * MsToNs(1000) / (time + 1)) 822 << "/s)"; 823 if (decompressed_size + sizeof(ImageHeader) != image_header.GetImageSize()) { 824 if (error_msg != nullptr) { 825 *error_msg = StringPrintf( 826 "Decompressed size does not match expected image size %zu vs %zu", 827 decompressed_size + sizeof(ImageHeader), 828 image_header.GetImageSize()); 829 } 830 return nullptr; 831 } 832 } 833 834 return map.release(); 835 } 836 837 class FixupVisitor : public ValueObject { 838 public: 839 FixupVisitor(const RelocationRange& boot_image, 840 const RelocationRange& boot_oat, 841 const RelocationRange& app_image, 842 const RelocationRange& app_oat) 843 : boot_image_(boot_image), 844 boot_oat_(boot_oat), 845 app_image_(app_image), 846 app_oat_(app_oat) {} 847 848 // Return the relocated address of a heap object. 849 template <typename T> 850 ALWAYS_INLINE T* ForwardObject(T* src) const { 851 const uintptr_t uint_src = reinterpret_cast<uintptr_t>(src); 852 if (boot_image_.InSource(uint_src)) { 853 return reinterpret_cast<T*>(boot_image_.ToDest(uint_src)); 854 } 855 if (app_image_.InSource(uint_src)) { 856 return reinterpret_cast<T*>(app_image_.ToDest(uint_src)); 857 } 858 // Since we are fixing up the app image, there should only be pointers to the app image and 859 // boot image. 860 DCHECK(src == nullptr) << reinterpret_cast<const void*>(src); 861 return src; 862 } 863 864 // Return the relocated address of a code pointer (contained by an oat file). 865 ALWAYS_INLINE const void* ForwardCode(const void* src) const { 866 const uintptr_t uint_src = reinterpret_cast<uintptr_t>(src); 867 if (boot_oat_.InSource(uint_src)) { 868 return reinterpret_cast<const void*>(boot_oat_.ToDest(uint_src)); 869 } 870 if (app_oat_.InSource(uint_src)) { 871 return reinterpret_cast<const void*>(app_oat_.ToDest(uint_src)); 872 } 873 DCHECK(src == nullptr) << src; 874 return src; 875 } 876 877 // Must be called on pointers that already have been relocated to the destination relocation. 878 ALWAYS_INLINE bool IsInAppImage(mirror::Object* object) const { 879 return app_image_.InDest(reinterpret_cast<uintptr_t>(object)); 880 } 881 882 protected: 883 // Source section. 884 const RelocationRange boot_image_; 885 const RelocationRange boot_oat_; 886 const RelocationRange app_image_; 887 const RelocationRange app_oat_; 888 }; 889 890 // Adapt for mirror::Class::FixupNativePointers. 891 class FixupObjectAdapter : public FixupVisitor { 892 public: 893 template<typename... Args> 894 explicit FixupObjectAdapter(Args... args) : FixupVisitor(args...) {} 895 896 template <typename T> 897 T* operator()(T* obj, void** dest_addr ATTRIBUTE_UNUSED = nullptr) const { 898 return ForwardObject(obj); 899 } 900 }; 901 902 class FixupRootVisitor : public FixupVisitor { 903 public: 904 template<typename... Args> 905 explicit FixupRootVisitor(Args... args) : FixupVisitor(args...) {} 906 907 ALWAYS_INLINE void VisitRootIfNonNull(mirror::CompressedReference<mirror::Object>* root) const 908 REQUIRES_SHARED(Locks::mutator_lock_) { 909 if (!root->IsNull()) { 910 VisitRoot(root); 911 } 912 } 913 914 ALWAYS_INLINE void VisitRoot(mirror::CompressedReference<mirror::Object>* root) const 915 REQUIRES_SHARED(Locks::mutator_lock_) { 916 mirror::Object* ref = root->AsMirrorPtr(); 917 mirror::Object* new_ref = ForwardObject(ref); 918 if (ref != new_ref) { 919 root->Assign(new_ref); 920 } 921 } 922 }; 923 924 class FixupObjectVisitor : public FixupVisitor { 925 public: 926 template<typename... Args> 927 explicit FixupObjectVisitor(gc::accounting::ContinuousSpaceBitmap* visited, 928 const PointerSize pointer_size, 929 Args... args) 930 : FixupVisitor(args...), 931 pointer_size_(pointer_size), 932 visited_(visited) {} 933 934 // Fix up separately since we also need to fix up method entrypoints. 935 ALWAYS_INLINE void VisitRootIfNonNull( 936 mirror::CompressedReference<mirror::Object>* root ATTRIBUTE_UNUSED) const {} 937 938 ALWAYS_INLINE void VisitRoot(mirror::CompressedReference<mirror::Object>* root ATTRIBUTE_UNUSED) 939 const {} 940 941 ALWAYS_INLINE void operator()(ObjPtr<mirror::Object> obj, 942 MemberOffset offset, 943 bool is_static ATTRIBUTE_UNUSED) const 944 NO_THREAD_SAFETY_ANALYSIS { 945 // There could be overlap between ranges, we must avoid visiting the same reference twice. 946 // Avoid the class field since we already fixed it up in FixupClassVisitor. 947 if (offset.Uint32Value() != mirror::Object::ClassOffset().Uint32Value()) { 948 // Space is not yet added to the heap, don't do a read barrier. 949 mirror::Object* ref = obj->GetFieldObject<mirror::Object, kVerifyNone, kWithoutReadBarrier>( 950 offset); 951 // Use SetFieldObjectWithoutWriteBarrier to avoid card marking since we are writing to the 952 // image. 953 obj->SetFieldObjectWithoutWriteBarrier<false, true, kVerifyNone>(offset, ForwardObject(ref)); 954 } 955 } 956 957 // Visit a pointer array and forward corresponding native data. Ignores pointer arrays in the 958 // boot image. Uses the bitmap to ensure the same array is not visited multiple times. 959 template <typename Visitor> 960 void UpdatePointerArrayContents(mirror::PointerArray* array, const Visitor& visitor) const 961 NO_THREAD_SAFETY_ANALYSIS { 962 DCHECK(array != nullptr); 963 DCHECK(visitor.IsInAppImage(array)); 964 // The bit for the array contents is different than the bit for the array. Since we may have 965 // already visited the array as a long / int array from walking the bitmap without knowing it 966 // was a pointer array. 967 static_assert(kObjectAlignment == 8u, "array bit may be in another object"); 968 mirror::Object* const contents_bit = reinterpret_cast<mirror::Object*>( 969 reinterpret_cast<uintptr_t>(array) + kObjectAlignment); 970 // If the bit is not set then the contents have not yet been updated. 971 if (!visited_->Test(contents_bit)) { 972 array->Fixup<kVerifyNone, kWithoutReadBarrier>(array, pointer_size_, visitor); 973 visited_->Set(contents_bit); 974 } 975 } 976 977 // java.lang.ref.Reference visitor. 978 void operator()(ObjPtr<mirror::Class> klass ATTRIBUTE_UNUSED, 979 ObjPtr<mirror::Reference> ref) const 980 REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(Locks::heap_bitmap_lock_) { 981 mirror::Object* obj = ref->GetReferent<kWithoutReadBarrier>(); 982 ref->SetFieldObjectWithoutWriteBarrier<false, true, kVerifyNone>( 983 mirror::Reference::ReferentOffset(), 984 ForwardObject(obj)); 985 } 986 987 void operator()(mirror::Object* obj) const 988 NO_THREAD_SAFETY_ANALYSIS { 989 if (visited_->Test(obj)) { 990 // Already visited. 991 return; 992 } 993 visited_->Set(obj); 994 995 // Handle class specially first since we need it to be updated to properly visit the rest of 996 // the instance fields. 997 { 998 mirror::Class* klass = obj->GetClass<kVerifyNone, kWithoutReadBarrier>(); 999 DCHECK(klass != nullptr) << "Null class in image"; 1000 // No AsClass since our fields aren't quite fixed up yet. 1001 mirror::Class* new_klass = down_cast<mirror::Class*>(ForwardObject(klass)); 1002 if (klass != new_klass) { 1003 obj->SetClass<kVerifyNone>(new_klass); 1004 } 1005 if (new_klass != klass && IsInAppImage(new_klass)) { 1006 // Make sure the klass contents are fixed up since we depend on it to walk the fields. 1007 operator()(new_klass); 1008 } 1009 } 1010 1011 if (obj->IsClass()) { 1012 mirror::Class* klass = obj->AsClass<kVerifyNone, kWithoutReadBarrier>(); 1013 // Fixup super class before visiting instance fields which require 1014 // information from their super class to calculate offsets. 1015 mirror::Class* super_class = klass->GetSuperClass<kVerifyNone, kWithoutReadBarrier>(); 1016 if (super_class != nullptr) { 1017 mirror::Class* new_super_class = down_cast<mirror::Class*>(ForwardObject(super_class)); 1018 if (new_super_class != super_class && IsInAppImage(new_super_class)) { 1019 // Recursively fix all dependencies. 1020 operator()(new_super_class); 1021 } 1022 } 1023 } 1024 1025 obj->VisitReferences</*visit native roots*/false, kVerifyNone, kWithoutReadBarrier>( 1026 *this, 1027 *this); 1028 // Note that this code relies on no circular dependencies. 1029 // We want to use our own class loader and not the one in the image. 1030 if (obj->IsClass<kVerifyNone, kWithoutReadBarrier>()) { 1031 mirror::Class* as_klass = obj->AsClass<kVerifyNone, kWithoutReadBarrier>(); 1032 FixupObjectAdapter visitor(boot_image_, boot_oat_, app_image_, app_oat_); 1033 as_klass->FixupNativePointers<kVerifyNone, kWithoutReadBarrier>(as_klass, 1034 pointer_size_, 1035 visitor); 1036 // Deal with the pointer arrays. Use the helper function since multiple classes can reference 1037 // the same arrays. 1038 mirror::PointerArray* const vtable = as_klass->GetVTable<kVerifyNone, kWithoutReadBarrier>(); 1039 if (vtable != nullptr && IsInAppImage(vtable)) { 1040 operator()(vtable); 1041 UpdatePointerArrayContents(vtable, visitor); 1042 } 1043 mirror::IfTable* iftable = as_klass->GetIfTable<kVerifyNone, kWithoutReadBarrier>(); 1044 // Ensure iftable arrays are fixed up since we need GetMethodArray to return the valid 1045 // contents. 1046 if (IsInAppImage(iftable)) { 1047 operator()(iftable); 1048 for (int32_t i = 0, count = iftable->Count(); i < count; ++i) { 1049 if (iftable->GetMethodArrayCount<kVerifyNone, kWithoutReadBarrier>(i) > 0) { 1050 mirror::PointerArray* methods = 1051 iftable->GetMethodArray<kVerifyNone, kWithoutReadBarrier>(i); 1052 if (visitor.IsInAppImage(methods)) { 1053 operator()(methods); 1054 DCHECK(methods != nullptr); 1055 UpdatePointerArrayContents(methods, visitor); 1056 } 1057 } 1058 } 1059 } 1060 } 1061 } 1062 1063 private: 1064 const PointerSize pointer_size_; 1065 gc::accounting::ContinuousSpaceBitmap* const visited_; 1066 }; 1067 1068 class ForwardObjectAdapter { 1069 public: 1070 ALWAYS_INLINE explicit ForwardObjectAdapter(const FixupVisitor* visitor) : visitor_(visitor) {} 1071 1072 template <typename T> 1073 ALWAYS_INLINE T* operator()(T* src) const { 1074 return visitor_->ForwardObject(src); 1075 } 1076 1077 private: 1078 const FixupVisitor* const visitor_; 1079 }; 1080 1081 class ForwardCodeAdapter { 1082 public: 1083 ALWAYS_INLINE explicit ForwardCodeAdapter(const FixupVisitor* visitor) 1084 : visitor_(visitor) {} 1085 1086 template <typename T> 1087 ALWAYS_INLINE T* operator()(T* src) const { 1088 return visitor_->ForwardCode(src); 1089 } 1090 1091 private: 1092 const FixupVisitor* const visitor_; 1093 }; 1094 1095 class FixupArtMethodVisitor : public FixupVisitor, public ArtMethodVisitor { 1096 public: 1097 template<typename... Args> 1098 explicit FixupArtMethodVisitor(bool fixup_heap_objects, PointerSize pointer_size, Args... args) 1099 : FixupVisitor(args...), 1100 fixup_heap_objects_(fixup_heap_objects), 1101 pointer_size_(pointer_size) {} 1102 1103 virtual void Visit(ArtMethod* method) NO_THREAD_SAFETY_ANALYSIS { 1104 // TODO: Separate visitor for runtime vs normal methods. 1105 if (UNLIKELY(method->IsRuntimeMethod())) { 1106 ImtConflictTable* table = method->GetImtConflictTable(pointer_size_); 1107 if (table != nullptr) { 1108 ImtConflictTable* new_table = ForwardObject(table); 1109 if (table != new_table) { 1110 method->SetImtConflictTable(new_table, pointer_size_); 1111 } 1112 } 1113 const void* old_code = method->GetEntryPointFromQuickCompiledCodePtrSize(pointer_size_); 1114 const void* new_code = ForwardCode(old_code); 1115 if (old_code != new_code) { 1116 method->SetEntryPointFromQuickCompiledCodePtrSize(new_code, pointer_size_); 1117 } 1118 } else { 1119 if (fixup_heap_objects_) { 1120 method->UpdateObjectsForImageRelocation(ForwardObjectAdapter(this), pointer_size_); 1121 } 1122 method->UpdateEntrypoints<kWithoutReadBarrier>(ForwardCodeAdapter(this), pointer_size_); 1123 } 1124 } 1125 1126 private: 1127 const bool fixup_heap_objects_; 1128 const PointerSize pointer_size_; 1129 }; 1130 1131 class FixupArtFieldVisitor : public FixupVisitor, public ArtFieldVisitor { 1132 public: 1133 template<typename... Args> 1134 explicit FixupArtFieldVisitor(Args... args) : FixupVisitor(args...) {} 1135 1136 virtual void Visit(ArtField* field) NO_THREAD_SAFETY_ANALYSIS { 1137 field->UpdateObjects(ForwardObjectAdapter(this)); 1138 } 1139 }; 1140 1141 // Relocate an image space mapped at target_base which possibly used to be at a different base 1142 // address. Only needs a single image space, not one for both source and destination. 1143 // In place means modifying a single ImageSpace in place rather than relocating from one ImageSpace 1144 // to another. 1145 static bool RelocateInPlace(ImageHeader& image_header, 1146 uint8_t* target_base, 1147 accounting::ContinuousSpaceBitmap* bitmap, 1148 const OatFile* app_oat_file, 1149 std::string* error_msg) { 1150 DCHECK(error_msg != nullptr); 1151 if (!image_header.IsPic()) { 1152 if (image_header.GetImageBegin() == target_base) { 1153 return true; 1154 } 1155 *error_msg = StringPrintf("Cannot relocate non-pic image for oat file %s", 1156 (app_oat_file != nullptr) ? app_oat_file->GetLocation().c_str() : ""); 1157 return false; 1158 } 1159 // Set up sections. 1160 uint32_t boot_image_begin = 0; 1161 uint32_t boot_image_end = 0; 1162 uint32_t boot_oat_begin = 0; 1163 uint32_t boot_oat_end = 0; 1164 const PointerSize pointer_size = image_header.GetPointerSize(); 1165 gc::Heap* const heap = Runtime::Current()->GetHeap(); 1166 heap->GetBootImagesSize(&boot_image_begin, &boot_image_end, &boot_oat_begin, &boot_oat_end); 1167 if (boot_image_begin == boot_image_end) { 1168 *error_msg = "Can not relocate app image without boot image space"; 1169 return false; 1170 } 1171 if (boot_oat_begin == boot_oat_end) { 1172 *error_msg = "Can not relocate app image without boot oat file"; 1173 return false; 1174 } 1175 const uint32_t boot_image_size = boot_image_end - boot_image_begin; 1176 const uint32_t boot_oat_size = boot_oat_end - boot_oat_begin; 1177 const uint32_t image_header_boot_image_size = image_header.GetBootImageSize(); 1178 const uint32_t image_header_boot_oat_size = image_header.GetBootOatSize(); 1179 if (boot_image_size != image_header_boot_image_size) { 1180 *error_msg = StringPrintf("Boot image size %" PRIu64 " does not match expected size %" 1181 PRIu64, 1182 static_cast<uint64_t>(boot_image_size), 1183 static_cast<uint64_t>(image_header_boot_image_size)); 1184 return false; 1185 } 1186 if (boot_oat_size != image_header_boot_oat_size) { 1187 *error_msg = StringPrintf("Boot oat size %" PRIu64 " does not match expected size %" 1188 PRIu64, 1189 static_cast<uint64_t>(boot_oat_size), 1190 static_cast<uint64_t>(image_header_boot_oat_size)); 1191 return false; 1192 } 1193 TimingLogger logger(__FUNCTION__, true, false); 1194 RelocationRange boot_image(image_header.GetBootImageBegin(), 1195 boot_image_begin, 1196 boot_image_size); 1197 RelocationRange boot_oat(image_header.GetBootOatBegin(), 1198 boot_oat_begin, 1199 boot_oat_size); 1200 RelocationRange app_image(reinterpret_cast<uintptr_t>(image_header.GetImageBegin()), 1201 reinterpret_cast<uintptr_t>(target_base), 1202 image_header.GetImageSize()); 1203 // Use the oat data section since this is where the OatFile::Begin is. 1204 RelocationRange app_oat(reinterpret_cast<uintptr_t>(image_header.GetOatDataBegin()), 1205 // Not necessarily in low 4GB. 1206 reinterpret_cast<uintptr_t>(app_oat_file->Begin()), 1207 image_header.GetOatDataEnd() - image_header.GetOatDataBegin()); 1208 VLOG(image) << "App image " << app_image; 1209 VLOG(image) << "App oat " << app_oat; 1210 VLOG(image) << "Boot image " << boot_image; 1211 VLOG(image) << "Boot oat " << boot_oat; 1212 // True if we need to fixup any heap pointers, otherwise only code pointers. 1213 const bool fixup_image = boot_image.Delta() != 0 || app_image.Delta() != 0; 1214 const bool fixup_code = boot_oat.Delta() != 0 || app_oat.Delta() != 0; 1215 if (!fixup_image && !fixup_code) { 1216 // Nothing to fix up. 1217 return true; 1218 } 1219 ScopedDebugDisallowReadBarriers sddrb(Thread::Current()); 1220 // Need to update the image to be at the target base. 1221 const ImageSection& objects_section = image_header.GetImageSection(ImageHeader::kSectionObjects); 1222 uintptr_t objects_begin = reinterpret_cast<uintptr_t>(target_base + objects_section.Offset()); 1223 uintptr_t objects_end = reinterpret_cast<uintptr_t>(target_base + objects_section.End()); 1224 FixupObjectAdapter fixup_adapter(boot_image, boot_oat, app_image, app_oat); 1225 if (fixup_image) { 1226 // Two pass approach, fix up all classes first, then fix up non class-objects. 1227 // The visited bitmap is used to ensure that pointer arrays are not forwarded twice. 1228 std::unique_ptr<gc::accounting::ContinuousSpaceBitmap> visited_bitmap( 1229 gc::accounting::ContinuousSpaceBitmap::Create("Relocate bitmap", 1230 target_base, 1231 image_header.GetImageSize())); 1232 FixupObjectVisitor fixup_object_visitor(visited_bitmap.get(), 1233 pointer_size, 1234 boot_image, 1235 boot_oat, 1236 app_image, 1237 app_oat); 1238 TimingLogger::ScopedTiming timing("Fixup classes", &logger); 1239 // Fixup objects may read fields in the boot image, use the mutator lock here for sanity. Though 1240 // its probably not required. 1241 ScopedObjectAccess soa(Thread::Current()); 1242 timing.NewTiming("Fixup objects"); 1243 bitmap->VisitMarkedRange(objects_begin, objects_end, fixup_object_visitor); 1244 // Fixup image roots. 1245 CHECK(app_image.InSource(reinterpret_cast<uintptr_t>( 1246 image_header.GetImageRoots<kWithoutReadBarrier>()))); 1247 image_header.RelocateImageObjects(app_image.Delta()); 1248 CHECK_EQ(image_header.GetImageBegin(), target_base); 1249 // Fix up dex cache DexFile pointers. 1250 auto* dex_caches = image_header.GetImageRoot<kWithoutReadBarrier>(ImageHeader::kDexCaches)-> 1251 AsObjectArray<mirror::DexCache, kVerifyNone, kWithoutReadBarrier>(); 1252 for (int32_t i = 0, count = dex_caches->GetLength(); i < count; ++i) { 1253 mirror::DexCache* dex_cache = dex_caches->Get<kVerifyNone, kWithoutReadBarrier>(i); 1254 // Fix up dex cache pointers. 1255 mirror::StringDexCacheType* strings = dex_cache->GetStrings(); 1256 if (strings != nullptr) { 1257 mirror::StringDexCacheType* new_strings = fixup_adapter.ForwardObject(strings); 1258 if (strings != new_strings) { 1259 dex_cache->SetStrings(new_strings); 1260 } 1261 dex_cache->FixupStrings<kWithoutReadBarrier>(new_strings, fixup_adapter); 1262 } 1263 mirror::TypeDexCacheType* types = dex_cache->GetResolvedTypes(); 1264 if (types != nullptr) { 1265 mirror::TypeDexCacheType* new_types = fixup_adapter.ForwardObject(types); 1266 if (types != new_types) { 1267 dex_cache->SetResolvedTypes(new_types); 1268 } 1269 dex_cache->FixupResolvedTypes<kWithoutReadBarrier>(new_types, fixup_adapter); 1270 } 1271 mirror::MethodDexCacheType* methods = dex_cache->GetResolvedMethods(); 1272 if (methods != nullptr) { 1273 mirror::MethodDexCacheType* new_methods = fixup_adapter.ForwardObject(methods); 1274 if (methods != new_methods) { 1275 dex_cache->SetResolvedMethods(new_methods); 1276 } 1277 for (size_t j = 0, num = dex_cache->NumResolvedMethods(); j != num; ++j) { 1278 auto pair = mirror::DexCache::GetNativePairPtrSize(new_methods, j, pointer_size); 1279 ArtMethod* orig = pair.object; 1280 ArtMethod* copy = fixup_adapter.ForwardObject(orig); 1281 if (orig != copy) { 1282 pair.object = copy; 1283 mirror::DexCache::SetNativePairPtrSize(new_methods, j, pair, pointer_size); 1284 } 1285 } 1286 } 1287 mirror::FieldDexCacheType* fields = dex_cache->GetResolvedFields(); 1288 if (fields != nullptr) { 1289 mirror::FieldDexCacheType* new_fields = fixup_adapter.ForwardObject(fields); 1290 if (fields != new_fields) { 1291 dex_cache->SetResolvedFields(new_fields); 1292 } 1293 for (size_t j = 0, num = dex_cache->NumResolvedFields(); j != num; ++j) { 1294 mirror::FieldDexCachePair orig = 1295 mirror::DexCache::GetNativePairPtrSize(new_fields, j, pointer_size); 1296 mirror::FieldDexCachePair copy(fixup_adapter.ForwardObject(orig.object), orig.index); 1297 if (orig.object != copy.object) { 1298 mirror::DexCache::SetNativePairPtrSize(new_fields, j, copy, pointer_size); 1299 } 1300 } 1301 } 1302 1303 mirror::MethodTypeDexCacheType* method_types = dex_cache->GetResolvedMethodTypes(); 1304 if (method_types != nullptr) { 1305 mirror::MethodTypeDexCacheType* new_method_types = 1306 fixup_adapter.ForwardObject(method_types); 1307 if (method_types != new_method_types) { 1308 dex_cache->SetResolvedMethodTypes(new_method_types); 1309 } 1310 dex_cache->FixupResolvedMethodTypes<kWithoutReadBarrier>(new_method_types, fixup_adapter); 1311 } 1312 GcRoot<mirror::CallSite>* call_sites = dex_cache->GetResolvedCallSites(); 1313 if (call_sites != nullptr) { 1314 GcRoot<mirror::CallSite>* new_call_sites = fixup_adapter.ForwardObject(call_sites); 1315 if (call_sites != new_call_sites) { 1316 dex_cache->SetResolvedCallSites(new_call_sites); 1317 } 1318 dex_cache->FixupResolvedCallSites<kWithoutReadBarrier>(new_call_sites, fixup_adapter); 1319 } 1320 } 1321 } 1322 { 1323 // Only touches objects in the app image, no need for mutator lock. 1324 TimingLogger::ScopedTiming timing("Fixup methods", &logger); 1325 FixupArtMethodVisitor method_visitor(fixup_image, 1326 pointer_size, 1327 boot_image, 1328 boot_oat, 1329 app_image, 1330 app_oat); 1331 image_header.VisitPackedArtMethods(&method_visitor, target_base, pointer_size); 1332 } 1333 if (fixup_image) { 1334 { 1335 // Only touches objects in the app image, no need for mutator lock. 1336 TimingLogger::ScopedTiming timing("Fixup fields", &logger); 1337 FixupArtFieldVisitor field_visitor(boot_image, boot_oat, app_image, app_oat); 1338 image_header.VisitPackedArtFields(&field_visitor, target_base); 1339 } 1340 { 1341 TimingLogger::ScopedTiming timing("Fixup imt", &logger); 1342 image_header.VisitPackedImTables(fixup_adapter, target_base, pointer_size); 1343 } 1344 { 1345 TimingLogger::ScopedTiming timing("Fixup conflict tables", &logger); 1346 image_header.VisitPackedImtConflictTables(fixup_adapter, target_base, pointer_size); 1347 } 1348 // In the app image case, the image methods are actually in the boot image. 1349 image_header.RelocateImageMethods(boot_image.Delta()); 1350 const auto& class_table_section = image_header.GetImageSection(ImageHeader::kSectionClassTable); 1351 if (class_table_section.Size() > 0u) { 1352 // Note that we require that ReadFromMemory does not make an internal copy of the elements. 1353 // This also relies on visit roots not doing any verification which could fail after we update 1354 // the roots to be the image addresses. 1355 ScopedObjectAccess soa(Thread::Current()); 1356 WriterMutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_); 1357 ClassTable temp_table; 1358 temp_table.ReadFromMemory(target_base + class_table_section.Offset()); 1359 FixupRootVisitor root_visitor(boot_image, boot_oat, app_image, app_oat); 1360 temp_table.VisitRoots(root_visitor); 1361 } 1362 } 1363 if (VLOG_IS_ON(image)) { 1364 logger.Dump(LOG_STREAM(INFO)); 1365 } 1366 return true; 1367 } 1368 1369 static std::unique_ptr<OatFile> OpenOatFile(const ImageSpace& image, 1370 const char* image_path, 1371 std::string* error_msg) { 1372 const ImageHeader& image_header = image.GetImageHeader(); 1373 std::string oat_filename = ImageHeader::GetOatLocationFromImageLocation(image_path); 1374 1375 CHECK(image_header.GetOatDataBegin() != nullptr); 1376 1377 std::unique_ptr<OatFile> oat_file(OatFile::Open(oat_filename, 1378 oat_filename, 1379 image_header.GetOatDataBegin(), 1380 image_header.GetOatFileBegin(), 1381 !Runtime::Current()->IsAotCompiler(), 1382 /*low_4gb*/false, 1383 nullptr, 1384 error_msg)); 1385 if (oat_file == nullptr) { 1386 *error_msg = StringPrintf("Failed to open oat file '%s' referenced from image %s: %s", 1387 oat_filename.c_str(), 1388 image.GetName(), 1389 error_msg->c_str()); 1390 return nullptr; 1391 } 1392 uint32_t oat_checksum = oat_file->GetOatHeader().GetChecksum(); 1393 uint32_t image_oat_checksum = image_header.GetOatChecksum(); 1394 if (oat_checksum != image_oat_checksum) { 1395 *error_msg = StringPrintf("Failed to match oat file checksum 0x%x to expected oat checksum 0x%x" 1396 " in image %s", 1397 oat_checksum, 1398 image_oat_checksum, 1399 image.GetName()); 1400 return nullptr; 1401 } 1402 int32_t image_patch_delta = image_header.GetPatchDelta(); 1403 int32_t oat_patch_delta = oat_file->GetOatHeader().GetImagePatchDelta(); 1404 if (oat_patch_delta != image_patch_delta && !image_header.CompilePic()) { 1405 // We should have already relocated by this point. Bail out. 1406 *error_msg = StringPrintf("Failed to match oat file patch delta %d to expected patch delta %d " 1407 "in image %s", 1408 oat_patch_delta, 1409 image_patch_delta, 1410 image.GetName()); 1411 return nullptr; 1412 } 1413 1414 return oat_file; 1415 } 1416 }; 1417 1418 static constexpr uint64_t kLowSpaceValue = 50 * MB; 1419 static constexpr uint64_t kTmpFsSentinelValue = 384 * MB; 1420 1421 // Read the free space of the cache partition and make a decision whether to keep the generated 1422 // image. This is to try to mitigate situations where the system might run out of space later. 1423 static bool CheckSpace(const std::string& cache_filename, std::string* error_msg) { 1424 // Using statvfs vs statvfs64 because of b/18207376, and it is enough for all practical purposes. 1425 struct statvfs buf; 1426 1427 int res = TEMP_FAILURE_RETRY(statvfs(cache_filename.c_str(), &buf)); 1428 if (res != 0) { 1429 // Could not stat. Conservatively tell the system to delete the image. 1430 *error_msg = "Could not stat the filesystem, assuming low-memory situation."; 1431 return false; 1432 } 1433 1434 uint64_t fs_overall_size = buf.f_bsize * static_cast<uint64_t>(buf.f_blocks); 1435 // Zygote is privileged, but other things are not. Use bavail. 1436 uint64_t fs_free_size = buf.f_bsize * static_cast<uint64_t>(buf.f_bavail); 1437 1438 // Take the overall size as an indicator for a tmpfs, which is being used for the decryption 1439 // environment. We do not want to fail quickening the boot image there, as it is beneficial 1440 // for time-to-UI. 1441 if (fs_overall_size > kTmpFsSentinelValue) { 1442 if (fs_free_size < kLowSpaceValue) { 1443 *error_msg = StringPrintf("Low-memory situation: only %4.2f megabytes available, need at " 1444 "least %" PRIu64 ".", 1445 static_cast<double>(fs_free_size) / MB, 1446 kLowSpaceValue / MB); 1447 return false; 1448 } 1449 } 1450 return true; 1451 } 1452 1453 std::unique_ptr<ImageSpace> ImageSpace::CreateBootImage(const char* image_location, 1454 const InstructionSet image_isa, 1455 bool secondary_image, 1456 std::string* error_msg) { 1457 ScopedTrace trace(__FUNCTION__); 1458 1459 // Step 0: Extra zygote work. 1460 1461 // Step 0.a: If we're the zygote, mark boot. 1462 const bool is_zygote = Runtime::Current()->IsZygote(); 1463 if (is_zygote && !secondary_image && CanWriteToDalvikCache(image_isa)) { 1464 MarkZygoteStart(image_isa, Runtime::Current()->GetZygoteMaxFailedBoots()); 1465 } 1466 1467 // Step 0.b: If we're the zygote, check for free space, and prune the cache preemptively, 1468 // if necessary. While the runtime may be fine (it is pretty tolerant to 1469 // out-of-disk-space situations), other parts of the platform are not. 1470 // 1471 // The advantage of doing this proactively is that the later steps are simplified, 1472 // i.e., we do not need to code retries. 1473 std::string system_filename; 1474 bool has_system = false; 1475 std::string cache_filename; 1476 bool has_cache = false; 1477 bool dalvik_cache_exists = false; 1478 bool is_global_cache = true; 1479 std::string dalvik_cache; 1480 bool found_image = FindImageFilenameImpl(image_location, 1481 image_isa, 1482 &has_system, 1483 &system_filename, 1484 &dalvik_cache_exists, 1485 &dalvik_cache, 1486 &is_global_cache, 1487 &has_cache, 1488 &cache_filename); 1489 1490 if (is_zygote && dalvik_cache_exists) { 1491 DCHECK(!dalvik_cache.empty()); 1492 std::string local_error_msg; 1493 if (!CheckSpace(dalvik_cache, &local_error_msg)) { 1494 LOG(WARNING) << local_error_msg << " Preemptively pruning the dalvik cache."; 1495 PruneDalvikCache(image_isa); 1496 1497 // Re-evaluate the image. 1498 found_image = FindImageFilenameImpl(image_location, 1499 image_isa, 1500 &has_system, 1501 &system_filename, 1502 &dalvik_cache_exists, 1503 &dalvik_cache, 1504 &is_global_cache, 1505 &has_cache, 1506 &cache_filename); 1507 } 1508 } 1509 1510 // Collect all the errors. 1511 std::vector<std::string> error_msgs; 1512 1513 // Step 1: Check if we have an existing and relocated image. 1514 1515 // Step 1.a: Have files in system and cache. Then they need to match. 1516 if (found_image && has_system && has_cache) { 1517 std::string local_error_msg; 1518 // Check that the files are matching. 1519 if (ChecksumsMatch(system_filename.c_str(), cache_filename.c_str(), &local_error_msg)) { 1520 std::unique_ptr<ImageSpace> relocated_space = 1521 ImageSpaceLoader::Load(image_location, 1522 cache_filename, 1523 is_zygote, 1524 is_global_cache, 1525 /* validate_oat_file */ false, 1526 &local_error_msg); 1527 if (relocated_space != nullptr) { 1528 return relocated_space; 1529 } 1530 } 1531 error_msgs.push_back(local_error_msg); 1532 } 1533 1534 // Step 1.b: Only have a cache file. 1535 if (found_image && !has_system && has_cache) { 1536 std::string local_error_msg; 1537 std::unique_ptr<ImageSpace> cache_space = 1538 ImageSpaceLoader::Load(image_location, 1539 cache_filename, 1540 is_zygote, 1541 is_global_cache, 1542 /* validate_oat_file */ true, 1543 &local_error_msg); 1544 if (cache_space != nullptr) { 1545 return cache_space; 1546 } 1547 error_msgs.push_back(local_error_msg); 1548 } 1549 1550 // Step 2: We have an existing image in /system. 1551 1552 // Step 2.a: We are not required to relocate it. Then we can use it directly. 1553 bool relocate = Runtime::Current()->ShouldRelocate(); 1554 1555 if (found_image && has_system && !relocate) { 1556 std::string local_error_msg; 1557 std::unique_ptr<ImageSpace> system_space = 1558 ImageSpaceLoader::Load(image_location, 1559 system_filename, 1560 is_zygote, 1561 is_global_cache, 1562 /* validate_oat_file */ false, 1563 &local_error_msg); 1564 if (system_space != nullptr) { 1565 return system_space; 1566 } 1567 error_msgs.push_back(local_error_msg); 1568 } 1569 1570 // Step 2.b: We require a relocated image. Then we must patch it. This step fails if this is a 1571 // secondary image. 1572 if (found_image && has_system && relocate) { 1573 std::string local_error_msg; 1574 if (!Runtime::Current()->IsImageDex2OatEnabled()) { 1575 local_error_msg = "Patching disabled."; 1576 } else if (secondary_image) { 1577 local_error_msg = "Cannot patch a secondary image."; 1578 } else if (ImageCreationAllowed(is_global_cache, image_isa, &local_error_msg)) { 1579 bool patch_success = 1580 RelocateImage(image_location, cache_filename.c_str(), image_isa, &local_error_msg); 1581 if (patch_success) { 1582 std::unique_ptr<ImageSpace> patched_space = 1583 ImageSpaceLoader::Load(image_location, 1584 cache_filename, 1585 is_zygote, 1586 is_global_cache, 1587 /* validate_oat_file */ false, 1588 &local_error_msg); 1589 if (patched_space != nullptr) { 1590 return patched_space; 1591 } 1592 } 1593 } 1594 error_msgs.push_back(StringPrintf("Cannot relocate image %s to %s: %s", 1595 image_location, 1596 cache_filename.c_str(), 1597 local_error_msg.c_str())); 1598 } 1599 1600 // Step 3: We do not have an existing image in /system, so generate an image into the dalvik 1601 // cache. This step fails if this is a secondary image. 1602 if (!has_system) { 1603 std::string local_error_msg; 1604 if (!Runtime::Current()->IsImageDex2OatEnabled()) { 1605 local_error_msg = "Image compilation disabled."; 1606 } else if (secondary_image) { 1607 local_error_msg = "Cannot compile a secondary image."; 1608 } else if (ImageCreationAllowed(is_global_cache, image_isa, &local_error_msg)) { 1609 bool compilation_success = GenerateImage(cache_filename, image_isa, &local_error_msg); 1610 if (compilation_success) { 1611 std::unique_ptr<ImageSpace> compiled_space = 1612 ImageSpaceLoader::Load(image_location, 1613 cache_filename, 1614 is_zygote, 1615 is_global_cache, 1616 /* validate_oat_file */ false, 1617 &local_error_msg); 1618 if (compiled_space != nullptr) { 1619 return compiled_space; 1620 } 1621 } 1622 } 1623 error_msgs.push_back(StringPrintf("Cannot compile image to %s: %s", 1624 cache_filename.c_str(), 1625 local_error_msg.c_str())); 1626 } 1627 1628 // We failed. Prune the cache the free up space, create a compound error message and return no 1629 // image. 1630 PruneDalvikCache(image_isa); 1631 1632 std::ostringstream oss; 1633 bool first = true; 1634 for (const auto& msg : error_msgs) { 1635 if (!first) { 1636 oss << "\n "; 1637 } 1638 oss << msg; 1639 } 1640 *error_msg = oss.str(); 1641 1642 return nullptr; 1643 } 1644 1645 bool ImageSpace::LoadBootImage(const std::string& image_file_name, 1646 const InstructionSet image_instruction_set, 1647 std::vector<space::ImageSpace*>* boot_image_spaces, 1648 uint8_t** oat_file_end) { 1649 DCHECK(boot_image_spaces != nullptr); 1650 DCHECK(boot_image_spaces->empty()); 1651 DCHECK(oat_file_end != nullptr); 1652 DCHECK_NE(image_instruction_set, InstructionSet::kNone); 1653 1654 if (image_file_name.empty()) { 1655 return false; 1656 } 1657 1658 // For code reuse, handle this like a work queue. 1659 std::vector<std::string> image_file_names; 1660 image_file_names.push_back(image_file_name); 1661 1662 bool error = false; 1663 uint8_t* oat_file_end_tmp = *oat_file_end; 1664 1665 for (size_t index = 0; index < image_file_names.size(); ++index) { 1666 std::string& image_name = image_file_names[index]; 1667 std::string error_msg; 1668 std::unique_ptr<space::ImageSpace> boot_image_space_uptr = CreateBootImage( 1669 image_name.c_str(), 1670 image_instruction_set, 1671 index > 0, 1672 &error_msg); 1673 if (boot_image_space_uptr != nullptr) { 1674 space::ImageSpace* boot_image_space = boot_image_space_uptr.release(); 1675 boot_image_spaces->push_back(boot_image_space); 1676 // Oat files referenced by image files immediately follow them in memory, ensure alloc space 1677 // isn't going to get in the middle 1678 uint8_t* oat_file_end_addr = boot_image_space->GetImageHeader().GetOatFileEnd(); 1679 CHECK_GT(oat_file_end_addr, boot_image_space->End()); 1680 oat_file_end_tmp = AlignUp(oat_file_end_addr, kPageSize); 1681 1682 if (index == 0) { 1683 // If this was the first space, check whether there are more images to load. 1684 const OatFile* boot_oat_file = boot_image_space->GetOatFile(); 1685 if (boot_oat_file == nullptr) { 1686 continue; 1687 } 1688 1689 const OatHeader& boot_oat_header = boot_oat_file->GetOatHeader(); 1690 const char* boot_classpath = 1691 boot_oat_header.GetStoreValueByKey(OatHeader::kBootClassPathKey); 1692 if (boot_classpath == nullptr) { 1693 continue; 1694 } 1695 1696 ExtractMultiImageLocations(image_file_name, boot_classpath, &image_file_names); 1697 } 1698 } else { 1699 error = true; 1700 LOG(ERROR) << "Could not create image space with image file '" << image_file_name << "'. " 1701 << "Attempting to fall back to imageless running. Error was: " << error_msg 1702 << "\nAttempted image: " << image_name; 1703 break; 1704 } 1705 } 1706 1707 if (error) { 1708 // Remove already loaded spaces. 1709 for (space::Space* loaded_space : *boot_image_spaces) { 1710 delete loaded_space; 1711 } 1712 boot_image_spaces->clear(); 1713 return false; 1714 } 1715 1716 *oat_file_end = oat_file_end_tmp; 1717 return true; 1718 } 1719 1720 ImageSpace::~ImageSpace() { 1721 Runtime* runtime = Runtime::Current(); 1722 if (runtime == nullptr) { 1723 return; 1724 } 1725 1726 if (GetImageHeader().IsAppImage()) { 1727 // This image space did not modify resolution method then in Init. 1728 return; 1729 } 1730 1731 if (!runtime->HasResolutionMethod()) { 1732 // Another image space has already unloaded the below methods. 1733 return; 1734 } 1735 1736 runtime->ClearInstructionSet(); 1737 runtime->ClearResolutionMethod(); 1738 runtime->ClearImtConflictMethod(); 1739 runtime->ClearImtUnimplementedMethod(); 1740 runtime->ClearCalleeSaveMethods(); 1741 } 1742 1743 std::unique_ptr<ImageSpace> ImageSpace::CreateFromAppImage(const char* image, 1744 const OatFile* oat_file, 1745 std::string* error_msg) { 1746 return ImageSpaceLoader::Init(image, 1747 image, 1748 /*validate_oat_file*/false, 1749 oat_file, 1750 /*out*/error_msg); 1751 } 1752 1753 const OatFile* ImageSpace::GetOatFile() const { 1754 return oat_file_non_owned_; 1755 } 1756 1757 std::unique_ptr<const OatFile> ImageSpace::ReleaseOatFile() { 1758 CHECK(oat_file_ != nullptr); 1759 return std::move(oat_file_); 1760 } 1761 1762 void ImageSpace::Dump(std::ostream& os) const { 1763 os << GetType() 1764 << " begin=" << reinterpret_cast<void*>(Begin()) 1765 << ",end=" << reinterpret_cast<void*>(End()) 1766 << ",size=" << PrettySize(Size()) 1767 << ",name=\"" << GetName() << "\"]"; 1768 } 1769 1770 std::string ImageSpace::GetMultiImageBootClassPath( 1771 const std::vector<const char*>& dex_locations, 1772 const std::vector<const char*>& oat_filenames, 1773 const std::vector<const char*>& image_filenames) { 1774 DCHECK_GT(oat_filenames.size(), 1u); 1775 // If the image filename was adapted (e.g., for our tests), we need to change this here, 1776 // too, but need to strip all path components (they will be re-established when loading). 1777 std::ostringstream bootcp_oss; 1778 bool first_bootcp = true; 1779 for (size_t i = 0; i < dex_locations.size(); ++i) { 1780 if (!first_bootcp) { 1781 bootcp_oss << ":"; 1782 } 1783 1784 std::string dex_loc = dex_locations[i]; 1785 std::string image_filename = image_filenames[i]; 1786 1787 // Use the dex_loc path, but the image_filename name (without path elements). 1788 size_t dex_last_slash = dex_loc.rfind('/'); 1789 1790 // npos is max(size_t). That makes this a bit ugly. 1791 size_t image_last_slash = image_filename.rfind('/'); 1792 size_t image_last_at = image_filename.rfind('@'); 1793 size_t image_last_sep = (image_last_slash == std::string::npos) 1794 ? image_last_at 1795 : (image_last_at == std::string::npos) 1796 ? std::string::npos 1797 : std::max(image_last_slash, image_last_at); 1798 // Note: whenever image_last_sep == npos, +1 overflow means using the full string. 1799 1800 if (dex_last_slash == std::string::npos) { 1801 dex_loc = image_filename.substr(image_last_sep + 1); 1802 } else { 1803 dex_loc = dex_loc.substr(0, dex_last_slash + 1) + 1804 image_filename.substr(image_last_sep + 1); 1805 } 1806 1807 // Image filenames already end with .art, no need to replace. 1808 1809 bootcp_oss << dex_loc; 1810 first_bootcp = false; 1811 } 1812 return bootcp_oss.str(); 1813 } 1814 1815 bool ImageSpace::ValidateOatFile(const OatFile& oat_file, std::string* error_msg) { 1816 for (const OatFile::OatDexFile* oat_dex_file : oat_file.GetOatDexFiles()) { 1817 const std::string& dex_file_location = oat_dex_file->GetDexFileLocation(); 1818 1819 // Skip multidex locations - These will be checked when we visit their 1820 // corresponding primary non-multidex location. 1821 if (DexFile::IsMultiDexLocation(dex_file_location.c_str())) { 1822 continue; 1823 } 1824 1825 std::vector<uint32_t> checksums; 1826 if (!DexFile::GetMultiDexChecksums(dex_file_location.c_str(), &checksums, error_msg)) { 1827 *error_msg = StringPrintf("ValidateOatFile failed to get checksums of dex file '%s' " 1828 "referenced by oat file %s: %s", 1829 dex_file_location.c_str(), 1830 oat_file.GetLocation().c_str(), 1831 error_msg->c_str()); 1832 return false; 1833 } 1834 CHECK(!checksums.empty()); 1835 if (checksums[0] != oat_dex_file->GetDexFileLocationChecksum()) { 1836 *error_msg = StringPrintf("ValidateOatFile found checksum mismatch between oat file " 1837 "'%s' and dex file '%s' (0x%x != 0x%x)", 1838 oat_file.GetLocation().c_str(), 1839 dex_file_location.c_str(), 1840 oat_dex_file->GetDexFileLocationChecksum(), 1841 checksums[0]); 1842 return false; 1843 } 1844 1845 // Verify checksums for any related multidex entries. 1846 for (size_t i = 1; i < checksums.size(); i++) { 1847 std::string multi_dex_location = DexFile::GetMultiDexLocation(i, dex_file_location.c_str()); 1848 const OatFile::OatDexFile* multi_dex = oat_file.GetOatDexFile(multi_dex_location.c_str(), 1849 nullptr, 1850 error_msg); 1851 if (multi_dex == nullptr) { 1852 *error_msg = StringPrintf("ValidateOatFile oat file '%s' is missing entry '%s'", 1853 oat_file.GetLocation().c_str(), 1854 multi_dex_location.c_str()); 1855 return false; 1856 } 1857 1858 if (checksums[i] != multi_dex->GetDexFileLocationChecksum()) { 1859 *error_msg = StringPrintf("ValidateOatFile found checksum mismatch between oat file " 1860 "'%s' and dex file '%s' (0x%x != 0x%x)", 1861 oat_file.GetLocation().c_str(), 1862 multi_dex_location.c_str(), 1863 multi_dex->GetDexFileLocationChecksum(), 1864 checksums[i]); 1865 return false; 1866 } 1867 } 1868 } 1869 return true; 1870 } 1871 1872 void ImageSpace::ExtractMultiImageLocations(const std::string& input_image_file_name, 1873 const std::string& boot_classpath, 1874 std::vector<std::string>* image_file_names) { 1875 DCHECK(image_file_names != nullptr); 1876 1877 std::vector<std::string> images; 1878 Split(boot_classpath, ':', &images); 1879 1880 // Add the rest into the list. We have to adjust locations, possibly: 1881 // 1882 // For example, image_file_name is /a/b/c/d/e.art 1883 // images[0] is f/c/d/e.art 1884 // ---------------------------------------------- 1885 // images[1] is g/h/i/j.art -> /a/b/h/i/j.art 1886 const std::string& first_image = images[0]; 1887 // Length of common suffix. 1888 size_t common = 0; 1889 while (common < input_image_file_name.size() && 1890 common < first_image.size() && 1891 *(input_image_file_name.end() - common - 1) == *(first_image.end() - common - 1)) { 1892 ++common; 1893 } 1894 // We want to replace the prefix of the input image with the prefix of the boot class path. 1895 // This handles the case where the image file contains @ separators. 1896 // Example image_file_name is oats/system@framework (at) boot.art 1897 // images[0] is .../arm/boot.art 1898 // means that the image name prefix will be oats/system@framework@ 1899 // so that the other images are openable. 1900 const size_t old_prefix_length = first_image.size() - common; 1901 const std::string new_prefix = input_image_file_name.substr( 1902 0, 1903 input_image_file_name.size() - common); 1904 1905 // Apply pattern to images[1] .. images[n]. 1906 for (size_t i = 1; i < images.size(); ++i) { 1907 const std::string& image = images[i]; 1908 CHECK_GT(image.length(), old_prefix_length); 1909 std::string suffix = image.substr(old_prefix_length); 1910 image_file_names->push_back(new_prefix + suffix); 1911 } 1912 } 1913 1914 void ImageSpace::DumpSections(std::ostream& os) const { 1915 const uint8_t* base = Begin(); 1916 const ImageHeader& header = GetImageHeader(); 1917 for (size_t i = 0; i < ImageHeader::kSectionCount; ++i) { 1918 auto section_type = static_cast<ImageHeader::ImageSections>(i); 1919 const ImageSection& section = header.GetImageSection(section_type); 1920 os << section_type << " " << reinterpret_cast<const void*>(base + section.Offset()) 1921 << "-" << reinterpret_cast<const void*>(base + section.End()) << "\n"; 1922 } 1923 } 1924 1925 } // namespace space 1926 } // namespace gc 1927 } // namespace art 1928