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