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 
ImageSpace(const std::string & image_filename,const char * image_location,MemMap * mem_map,accounting::ContinuousSpaceBitmap * live_bitmap,uint8_t * end)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 
ChooseRelocationOffsetDelta(int32_t min_delta,int32_t max_delta)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 
ChooseRelocationOffsetDelta()91 static int32_t ChooseRelocationOffsetDelta() {
92   return ChooseRelocationOffsetDelta(ART_BASE_ADDRESS_MIN_DELTA, ART_BASE_ADDRESS_MAX_DELTA);
93 }
94 
GenerateImage(const std::string & image_filename,InstructionSet image_isa,std::string * error_msg)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 
FindImageFilenameImpl(const char * image_location,const InstructionSet image_isa,bool * has_system,std::string * system_filename,bool * dalvik_cache_exists,std::string * dalvik_cache,bool * is_global_cache,bool * has_cache,std::string * cache_filename)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 
FindImageFilename(const char * image_location,const InstructionSet image_isa,std::string * system_filename,bool * has_system,std::string * cache_filename,bool * dalvik_cache_exists,bool * has_cache,bool * is_global_cache)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 
ReadSpecificImageHeader(const char * filename,ImageHeader * image_header)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.
RelocateImage(const char * image_location,const char * dest_filename,InstructionSet isa,std::string * error_msg)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 
ReadSpecificImageHeader(const char * filename,std::string * error_msg)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 
ReadImageHeader(const char * image_location,const InstructionSet image_isa,std::string * error_msg)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 
ChecksumsMatch(const char * image_a,const char * image_b,std::string * error_msg)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 
CanWriteToDalvikCache(const InstructionSet isa)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 
ImageCreationAllowed(bool is_global_cache,const InstructionSet isa,std::string * error_msg)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 
VerifyImageAllocations()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;
RelocationRange(uintptr_t source,uintptr_t dest,uintptr_t length)423   RelocationRange(uintptr_t source, uintptr_t dest, uintptr_t length)
424       : source_(source),
425         dest_(dest),
426         length_(length) {}
427 
InSource(uintptr_t address) const428   bool InSource(uintptr_t address) const {
429     return address - source_ < length_;
430   }
431 
InDest(uintptr_t address) const432   bool InDest(uintptr_t address) const {
433     return address - dest_ < length_;
434   }
435 
436   // Translate a source address to the destination space.
ToDest(uintptr_t address) const437   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.
Delta() const443   uintptr_t Delta() const {
444     return dest_ - source_;
445   }
446 
Source() const447   uintptr_t Source() const {
448     return source_;
449   }
450 
Dest() const451   uintptr_t Dest() const {
452     return dest_;
453   }
454 
Length() const455   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 
operator <<(std::ostream & os,const RelocationRange & reloc)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:
Load(const char * image_location,const std::string & image_filename,bool is_zygote,bool is_global_cache,bool validate_oat_file,std::string * error_msg)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 
Init(const char * image_filename,const char * image_location,bool validate_oat_file,const OatFile * oat_file,std::string * error_msg)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:
LoadImageFile(const char * image_filename,const char * image_location,const ImageHeader & image_header,uint8_t * address,int fd,TimingLogger & logger,std::string * error_msg)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:
FixupVisitor(const RelocationRange & boot_image,const RelocationRange & boot_oat,const RelocationRange & app_image,const RelocationRange & app_oat)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>
ForwardObject(T * src) const844     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).
ForwardCode(const void * src) const859     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.
IsInAppImage(mirror::Object * object) const872     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>
FixupObjectAdapter(Args...args)888     explicit FixupObjectAdapter(Args... args) : FixupVisitor(args...) {}
889 
890     template <typename T>
operator ()(T * obj,void ** dest_addr ATTRIBUTE_UNUSED=nullptr) const891     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>
FixupRootVisitor(Args...args)899     explicit FixupRootVisitor(Args... args) : FixupVisitor(args...) {}
900 
VisitRootIfNonNull(mirror::CompressedReference<mirror::Object> * root) const901     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 
VisitRoot(mirror::CompressedReference<mirror::Object> * root) const908     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>
FixupObjectVisitor(gc::accounting::ContinuousSpaceBitmap * visited,const PointerSize pointer_size,Args...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.
VisitRootIfNonNull(mirror::CompressedReference<mirror::Object> * root ATTRIBUTE_UNUSED) const929     ALWAYS_INLINE void VisitRootIfNonNull(
930         mirror::CompressedReference<mirror::Object>* root ATTRIBUTE_UNUSED) const {}
931 
VisitRoot(mirror::CompressedReference<mirror::Object> * root ATTRIBUTE_UNUSED) const932     ALWAYS_INLINE void VisitRoot(mirror::CompressedReference<mirror::Object>* root ATTRIBUTE_UNUSED)
933         const {}
934 
operator ()(ObjPtr<mirror::Object> obj,MemberOffset offset,bool is_static ATTRIBUTE_UNUSED) const935     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>
UpdatePointerArrayContents(mirror::PointerArray * array,const Visitor & visitor) const954     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.
operator ()(ObjPtr<mirror::Class> klass ATTRIBUTE_UNUSED,ObjPtr<mirror::Reference> ref) const972     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 
operator ()(mirror::Object * obj) const981     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:
ForwardObjectAdapter(const FixupVisitor * visitor)1050     ALWAYS_INLINE explicit ForwardObjectAdapter(const FixupVisitor* visitor) : visitor_(visitor) {}
1051 
1052     template <typename T>
operator ()(T * src) const1053     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:
ForwardCodeAdapter(const FixupVisitor * visitor)1063     ALWAYS_INLINE explicit ForwardCodeAdapter(const FixupVisitor* visitor)
1064         : visitor_(visitor) {}
1065 
1066     template <typename T>
operator ()(T * src) const1067     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>
FixupArtMethodVisitor(bool fixup_heap_objects,PointerSize pointer_size,Args...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 
Visit(ArtMethod * method)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>
FixupArtFieldVisitor(Args...args)1114     explicit FixupArtFieldVisitor(Args... args) : FixupVisitor(args...) {}
1115 
Visit(ArtField * field)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.
RelocateInPlace(ImageHeader & image_header,uint8_t * target_base,accounting::ContinuousSpaceBitmap * bitmap,const OatFile * app_oat_file,std::string * error_msg)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 
OpenOatFile(const ImageSpace & image,const char * image_path,std::string * error_msg)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.
CheckSpace(const std::string & cache_filename,std::string * error_msg)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 
CreateBootImage(const char * image_location,const InstructionSet image_isa,bool secondary_image,std::string * error_msg)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 
LoadBootImage(const std::string & image_file_name,const InstructionSet image_instruction_set,std::vector<space::ImageSpace * > * boot_image_spaces,uint8_t ** oat_file_end)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 
~ImageSpace()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 
CreateFromAppImage(const char * image,const OatFile * oat_file,std::string * error_msg)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 
GetOatFile() const1731 const OatFile* ImageSpace::GetOatFile() const {
1732   return oat_file_non_owned_;
1733 }
1734 
ReleaseOatFile()1735 std::unique_ptr<const OatFile> ImageSpace::ReleaseOatFile() {
1736   CHECK(oat_file_ != nullptr);
1737   return std::move(oat_file_);
1738 }
1739 
Dump(std::ostream & os) const1740 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 
GetMultiImageBootClassPath(const std::vector<const char * > & dex_locations,const std::vector<const char * > & oat_filenames,const std::vector<const char * > & image_filenames)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 
ValidateOatFile(const OatFile & oat_file,std::string * error_msg)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 
ExtractMultiImageLocations(const std::string & input_image_file_name,const std::string & boot_classpath,std::vector<std::string> * image_file_names)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@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 
DumpSections(std::ostream & os) const1892 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