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