166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler/*
266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler * Copyright (C) 2014 The Android Open Source Project
366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler *
466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler * Licensed under the Apache License, Version 2.0 (the "License");
566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler * you may not use this file except in compliance with the License.
666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler * You may obtain a copy of the License at
766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler *
866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler *      http://www.apache.org/licenses/LICENSE-2.0
966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler *
1066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler * Unless required by applicable law or agreed to in writing, software
1166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler * distributed under the License is distributed on an "AS IS" BASIS,
1266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler * See the License for the specific language governing permissions and
1466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler * limitations under the License.
1566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler */
1666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
1766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include "oat_file_assistant.h"
1866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
1966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include <fcntl.h>
2066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#ifdef __linux__
2166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include <sys/sendfile.h>
2266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#else
2366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include <sys/socket.h>
2466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#endif
2566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include <sys/types.h>
2666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include <sys/stat.h>
2766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include <unistd.h>
2866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
2966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include <set>
3066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
3166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include "base/logging.h"
3266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include "base/stringprintf.h"
33cd7e7f78b8e97c1f6419f3f44e0d5fdc6eddfdc6Narayan Kamath#include "compiler_filter.h"
3466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include "class_linker.h"
3566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include "gc/heap.h"
3666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include "gc/space/image_space.h"
3766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include "image.h"
3866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include "oat.h"
3966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include "os.h"
4066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include "runtime.h"
41fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier#include "scoped_thread_state_change.h"
4266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include "ScopedFd.h"
4366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include "utils.h"
4466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
4566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlernamespace art {
4666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
47cd7e7f78b8e97c1f6419f3f44e0d5fdc6eddfdc6Narayan Kamathstd::ostream& operator << (std::ostream& stream, const OatFileAssistant::OatStatus status) {
48cd7e7f78b8e97c1f6419f3f44e0d5fdc6eddfdc6Narayan Kamath  switch (status) {
49cd7e7f78b8e97c1f6419f3f44e0d5fdc6eddfdc6Narayan Kamath    case OatFileAssistant::kOatOutOfDate:
50cd7e7f78b8e97c1f6419f3f44e0d5fdc6eddfdc6Narayan Kamath      stream << "kOatOutOfDate";
51cd7e7f78b8e97c1f6419f3f44e0d5fdc6eddfdc6Narayan Kamath      break;
52cd7e7f78b8e97c1f6419f3f44e0d5fdc6eddfdc6Narayan Kamath    case OatFileAssistant::kOatUpToDate:
53cd7e7f78b8e97c1f6419f3f44e0d5fdc6eddfdc6Narayan Kamath      stream << "kOatUpToDate";
54cd7e7f78b8e97c1f6419f3f44e0d5fdc6eddfdc6Narayan Kamath      break;
55cd7e7f78b8e97c1f6419f3f44e0d5fdc6eddfdc6Narayan Kamath    case OatFileAssistant::kOatNeedsRelocation:
56cd7e7f78b8e97c1f6419f3f44e0d5fdc6eddfdc6Narayan Kamath      stream << "kOatNeedsRelocation";
57cd7e7f78b8e97c1f6419f3f44e0d5fdc6eddfdc6Narayan Kamath      break;
58cd7e7f78b8e97c1f6419f3f44e0d5fdc6eddfdc6Narayan Kamath    default:
59cd7e7f78b8e97c1f6419f3f44e0d5fdc6eddfdc6Narayan Kamath      UNREACHABLE();
60cd7e7f78b8e97c1f6419f3f44e0d5fdc6eddfdc6Narayan Kamath  }
61cd7e7f78b8e97c1f6419f3f44e0d5fdc6eddfdc6Narayan Kamath
62cd7e7f78b8e97c1f6419f3f44e0d5fdc6eddfdc6Narayan Kamath  return stream;
63cd7e7f78b8e97c1f6419f3f44e0d5fdc6eddfdc6Narayan Kamath}
64cd7e7f78b8e97c1f6419f3f44e0d5fdc6eddfdc6Narayan Kamath
6566d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerOatFileAssistant::OatFileAssistant(const char* dex_location,
6666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler                                   const InstructionSet isa,
6729d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe                                   bool profile_changed,
6866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler                                   bool load_executable)
6929d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe    : OatFileAssistant(dex_location, nullptr, isa, profile_changed, load_executable)
70b077e15d2d11b7c81aacbcd4a46c2b1e9c9ba20dCalin Juravle{ }
7166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
7266d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerOatFileAssistant::OatFileAssistant(const char* dex_location,
7366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler                                   const char* oat_location,
7466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler                                   const InstructionSet isa,
7529d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe                                   bool profile_changed,
7666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler                                   bool load_executable)
7729d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe    : isa_(isa), profile_changed_(profile_changed), load_executable_(load_executable) {
78740eec92a7f63e8ddff1e007ae624d548a4e5a16Richard Uhler  CHECK(dex_location != nullptr) << "OatFileAssistant: null dex location";
79740eec92a7f63e8ddff1e007ae624d548a4e5a16Richard Uhler  dex_location_.assign(dex_location);
80740eec92a7f63e8ddff1e007ae624d548a4e5a16Richard Uhler
8166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  if (load_executable_ && isa != kRuntimeISA) {
8266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    LOG(WARNING) << "OatFileAssistant: Load executable specified, "
8366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      << "but isa is not kRuntimeISA. Will not attempt to load executable.";
8466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    load_executable_ = false;
8566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
8666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
8766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // If the user gave a target oat location, save that as the cached oat
8866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // location now so we won't try to construct the default location later.
8966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  if (oat_location != nullptr) {
9066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    cached_oat_file_name_ = std::string(oat_location);
9166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    cached_oat_file_name_attempted_ = true;
9266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    cached_oat_file_name_found_ = true;
9366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
9466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
9566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
9666d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerOatFileAssistant::~OatFileAssistant() {
9766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Clean up the lock file.
98581f4e9065b9b7f788315d3ea1a45e51ae168589Richard Uhler  if (flock_.HasFile()) {
9966fdcbdb1fde4bf65da5e801ba76a8e65391635bVladimir Marko    unlink(flock_.GetFile()->GetPath().c_str());
10066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
10166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
10266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
10366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerbool OatFileAssistant::IsInBootClassPath() {
10466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Note: We check the current boot class path, regardless of the ISA
10566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // specified by the user. This is okay, because the boot class path should
10666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // be the same for all ISAs.
10766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // TODO: Can we verify the boot class path is the same for all ISAs?
10866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Runtime* runtime = Runtime::Current();
10966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  ClassLinker* class_linker = runtime->GetClassLinker();
11066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  const auto& boot_class_path = class_linker->GetBootClassPath();
11166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  for (size_t i = 0; i < boot_class_path.size(); i++) {
112740eec92a7f63e8ddff1e007ae624d548a4e5a16Richard Uhler    if (boot_class_path[i]->GetLocation() == dex_location_) {
11366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      VLOG(oat) << "Dex location " << dex_location_ << " is in boot class path";
11466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      return true;
11566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    }
11666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
11766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  return false;
11866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
11966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
12066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerbool OatFileAssistant::Lock(std::string* error_msg) {
12166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  CHECK(error_msg != nullptr);
122581f4e9065b9b7f788315d3ea1a45e51ae168589Richard Uhler  CHECK(!flock_.HasFile()) << "OatFileAssistant::Lock already acquired";
12366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
12466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  if (OatFileName() == nullptr) {
12566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    *error_msg = "Failed to determine lock file";
12666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    return false;
12766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
12866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string lock_file_name = *OatFileName() + ".flock";
12966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
130581f4e9065b9b7f788315d3ea1a45e51ae168589Richard Uhler  if (!flock_.Init(lock_file_name.c_str(), error_msg)) {
13166fdcbdb1fde4bf65da5e801ba76a8e65391635bVladimir Marko    unlink(lock_file_name.c_str());
13266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    return false;
13366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
13466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  return true;
13566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
13666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
13729d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampebool OatFileAssistant::OatFileCompilerFilterIsOkay(CompilerFilter::Filter target) {
13829d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe  const OatFile* oat_file = GetOatFile();
13929d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe  if (oat_file != nullptr) {
14029d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe    CompilerFilter::Filter current = oat_file->GetCompilerFilter();
14129d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe    return CompilerFilter::IsAsGoodAs(current, target);
14229d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe  }
14329d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe  return false;
144b077e15d2d11b7c81aacbcd4a46c2b1e9c9ba20dCalin Juravle}
14566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
14629d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampebool OatFileAssistant::OdexFileCompilerFilterIsOkay(CompilerFilter::Filter target) {
14729d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe  const OatFile* odex_file = GetOdexFile();
14829d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe  if (odex_file != nullptr) {
14929d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe    CompilerFilter::Filter current = odex_file->GetCompilerFilter();
15029d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe    return CompilerFilter::IsAsGoodAs(current, target);
15195abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  }
15229d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe  return false;
15329d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe}
15495abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler
15529d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas GampeOatFileAssistant::DexOptNeeded OatFileAssistant::GetDexOptNeeded(CompilerFilter::Filter target) {
1568c185bf0c6f18a5349bc87a7e3751ba06d90f461Vladimir Marko  bool compilation_desired = CompilerFilter::IsBytecodeCompilationEnabled(target);
15729d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe
15829d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe  // See if the oat file is in good shape as is.
15929d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe  bool oat_okay = OatFileCompilerFilterIsOkay(target);
16029d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe  if (oat_okay) {
16129d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe    if (compilation_desired) {
16229d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe      if (OatFileIsUpToDate()) {
16329d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe        return kNoDexOptNeeded;
16429d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe      }
16529d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe    } else {
16629d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe      if (!OatFileIsOutOfDate()) {
16729d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe        return kNoDexOptNeeded;
16829d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe      }
16929d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe    }
17029d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe  }
17129d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe
17229d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe  // See if the odex file is in good shape as is.
17329d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe  bool odex_okay = OdexFileCompilerFilterIsOkay(target);
17429d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe  if (odex_okay) {
17529d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe    if (compilation_desired) {
17629d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe      if (OdexFileIsUpToDate()) {
17729d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe        return kNoDexOptNeeded;
17829d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe      }
17929d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe    } else {
18029d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe      if (!OdexFileIsOutOfDate()) {
18129d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe        return kNoDexOptNeeded;
18229d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe      }
18329d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe    }
18495abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  }
18595abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler
18629d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe  // See if we can get an up-to-date file by running patchoat.
18729d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe  if (compilation_desired) {
188d1537b569b6cd18297c5e02d13cdd588c4366c51Richard Uhler    if (odex_okay && OdexFileNeedsRelocation() && OdexFileHasPatchInfo()) {
18929d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe      return kPatchOatNeeded;
19029d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe    }
19129d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe
192d1537b569b6cd18297c5e02d13cdd588c4366c51Richard Uhler    if (oat_okay && OatFileNeedsRelocation() && OatFileHasPatchInfo()) {
19329d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe      return kSelfPatchOatNeeded;
19429d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe    }
19566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
19695abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler
19729d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe  // We can only run dex2oat if there are original dex files.
1989b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  return HasOriginalDexFiles() ? kDex2OatNeeded : kNoDexOptNeeded;
19966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
20066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
2016619cdd9f133c90f5d3a28d7723887b888a9f45aRichard Uhlerbool OatFileAssistant::IsUpToDate() {
2026619cdd9f133c90f5d3a28d7723887b888a9f45aRichard Uhler  return OatFileIsUpToDate() || OdexFileIsUpToDate();
2036619cdd9f133c90f5d3a28d7723887b888a9f45aRichard Uhler}
2046619cdd9f133c90f5d3a28d7723887b888a9f45aRichard Uhler
2051e860619cdcc9c0b6a202a247c50cf7633ac7b74Richard UhlerOatFileAssistant::ResultOfAttemptToUpdate
2061e860619cdcc9c0b6a202a247c50cf7633ac7b74Richard UhlerOatFileAssistant::MakeUpToDate(CompilerFilter::Filter target, std::string* error_msg) {
20729d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe  switch (GetDexOptNeeded(target)) {
2081e860619cdcc9c0b6a202a247c50cf7633ac7b74Richard Uhler    case kNoDexOptNeeded: return kUpdateSucceeded;
20929d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe    case kDex2OatNeeded: return GenerateOatFile(target, error_msg);
21095abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler    case kPatchOatNeeded: return RelocateOatFile(OdexFileName(), error_msg);
21195abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler    case kSelfPatchOatNeeded: return RelocateOatFile(OatFileName(), error_msg);
21266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
21366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  UNREACHABLE();
21466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
21566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
21666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerstd::unique_ptr<OatFile> OatFileAssistant::GetBestOatFile() {
2175f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler  // The best oat files are, in descending order of bestness:
2185f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler  // 1. Properly relocated files. These may be opened executable.
2195f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler  // 2. Not out-of-date files that are already opened non-executable.
2205f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler  // 3. Not out-of-date files that we must reopen non-executable.
2215f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler
22266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  if (OatFileIsUpToDate()) {
22366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    oat_file_released_ = true;
22466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    return std::move(cached_oat_file_);
22566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
22666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
22766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  if (OdexFileIsUpToDate()) {
22866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    oat_file_released_ = true;
22966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    return std::move(cached_odex_file_);
23066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
23166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
2325f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler  VLOG(oat) << "Oat File Assistant: No relocated oat file found,"
2335f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler    << " attempting to fall back to interpreting oat file instead.";
2345f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler
2355f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler  if (!OatFileIsOutOfDate() && !OatFileIsExecutable()) {
2365f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler    oat_file_released_ = true;
2375f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler    return std::move(cached_oat_file_);
2385f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler  }
2395f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler
2405f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler  if (!OdexFileIsOutOfDate() && !OdexFileIsExecutable()) {
2415f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler    oat_file_released_ = true;
2425f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler    return std::move(cached_odex_file_);
2435f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler  }
24466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
2455f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler  if (!OatFileIsOutOfDate()) {
2465f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler    load_executable_ = false;
2475f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler    ClearOatFileCache();
24866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    if (!OatFileIsOutOfDate()) {
2495f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler      CHECK(!OatFileIsExecutable());
2505f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler      oat_file_released_ = true;
2515f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler      return std::move(cached_oat_file_);
25266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    }
2535f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler  }
25466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
2555f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler  if (!OdexFileIsOutOfDate()) {
2565f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler    load_executable_ = false;
2575f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler    ClearOdexFileCache();
25866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    if (!OdexFileIsOutOfDate()) {
2595f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler      CHECK(!OdexFileIsExecutable());
2605f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler      oat_file_released_ = true;
2615f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler      return std::move(cached_odex_file_);
26266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    }
26366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
26466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
26566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  return std::unique_ptr<OatFile>();
26666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
26766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
26866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerstd::vector<std::unique_ptr<const DexFile>> OatFileAssistant::LoadDexFiles(
26966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    const OatFile& oat_file, const char* dex_location) {
27066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::vector<std::unique_ptr<const DexFile>> dex_files;
27166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
27266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Load the primary dex file.
27366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string error_msg;
27466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  const OatFile::OatDexFile* oat_dex_file = oat_file.GetOatDexFile(
27566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      dex_location, nullptr, false);
27666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  if (oat_dex_file == nullptr) {
27766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    LOG(WARNING) << "Attempt to load out-of-date oat file "
27866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      << oat_file.GetLocation() << " for dex location " << dex_location;
27966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    return std::vector<std::unique_ptr<const DexFile>>();
28066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
28166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
282b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin  std::unique_ptr<const DexFile> dex_file = oat_dex_file->OpenDexFile(&error_msg);
28366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  if (dex_file.get() == nullptr) {
28466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    LOG(WARNING) << "Failed to open dex file from oat dex file: " << error_msg;
28566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    return std::vector<std::unique_ptr<const DexFile>>();
28666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
28766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  dex_files.push_back(std::move(dex_file));
28866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
28966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Load secondary multidex files
29090e34043ff7bf8926e8fe6a6d5011a9daa68d320Andreas Gampe  for (size_t i = 1; ; i++) {
29190e34043ff7bf8926e8fe6a6d5011a9daa68d320Andreas Gampe    std::string secondary_dex_location = DexFile::GetMultiDexLocation(i, dex_location);
29266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    oat_dex_file = oat_file.GetOatDexFile(secondary_dex_location.c_str(), nullptr, false);
2932cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier    if (oat_dex_file == nullptr) {
29466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      // There are no more secondary dex files to load.
29566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      break;
29666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    }
29766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
298b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin    dex_file = oat_dex_file->OpenDexFile(&error_msg);
29966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    if (dex_file.get() == nullptr) {
30066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      LOG(WARNING) << "Failed to open dex file from oat dex file: " << error_msg;
30166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      return std::vector<std::unique_ptr<const DexFile>>();
30266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    }
30366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    dex_files.push_back(std::move(dex_file));
30466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
30566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  return dex_files;
30666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
30766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
3089b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhlerbool OatFileAssistant::HasOriginalDexFiles() {
3099b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  // Ensure GetRequiredDexChecksum has been run so that
3109b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  // has_original_dex_files_ is initialized. We don't care about the result of
3119b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  // GetRequiredDexChecksum.
3129b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  GetRequiredDexChecksum();
3139b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  return has_original_dex_files_;
3149b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler}
3159b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler
31666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerconst std::string* OatFileAssistant::OdexFileName() {
31766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  if (!cached_odex_file_name_attempted_) {
31866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    cached_odex_file_name_attempted_ = true;
31966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
32066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    std::string error_msg;
32166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    cached_odex_file_name_found_ = DexFilenameToOdexFilename(
322b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin        dex_location_, isa_, &cached_odex_file_name_, &error_msg);
32366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    if (!cached_odex_file_name_found_) {
32466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      // If we can't figure out the odex file, we treat it as if the odex
32566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      // file was inaccessible.
32666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      LOG(WARNING) << "Failed to determine odex file name: " << error_msg;
32766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    }
32866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
32966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  return cached_odex_file_name_found_ ? &cached_odex_file_name_ : nullptr;
33066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
33166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
33266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerbool OatFileAssistant::OdexFileExists() {
33366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  return GetOdexFile() != nullptr;
33466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
33566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
33695abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard UhlerOatFileAssistant::OatStatus OatFileAssistant::OdexFileStatus() {
33766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  if (OdexFileIsOutOfDate()) {
33895abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler    return kOatOutOfDate;
33966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
34066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  if (OdexFileIsUpToDate()) {
34195abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler    return kOatUpToDate;
34266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
34395abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  return kOatNeedsRelocation;
34466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
34566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
34666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerbool OatFileAssistant::OdexFileIsOutOfDate() {
34766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  if (!odex_file_is_out_of_date_attempted_) {
34866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    odex_file_is_out_of_date_attempted_ = true;
34966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    const OatFile* odex_file = GetOdexFile();
35066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    if (odex_file == nullptr) {
35166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      cached_odex_file_is_out_of_date_ = true;
35266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    } else {
35366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      cached_odex_file_is_out_of_date_ = GivenOatFileIsOutOfDate(*odex_file);
35466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    }
35566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
35666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  return cached_odex_file_is_out_of_date_;
35766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
35866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
35966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerbool OatFileAssistant::OdexFileNeedsRelocation() {
36095abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  return OdexFileStatus() == kOatNeedsRelocation;
36166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
36266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
36366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerbool OatFileAssistant::OdexFileIsUpToDate() {
36466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  if (!odex_file_is_up_to_date_attempted_) {
36566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    odex_file_is_up_to_date_attempted_ = true;
36666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    const OatFile* odex_file = GetOdexFile();
36766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    if (odex_file == nullptr) {
36866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      cached_odex_file_is_up_to_date_ = false;
36966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    } else {
37066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      cached_odex_file_is_up_to_date_ = GivenOatFileIsUpToDate(*odex_file);
37166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    }
37266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
37366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  return cached_odex_file_is_up_to_date_;
37466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
37566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
376cd7e7f78b8e97c1f6419f3f44e0d5fdc6eddfdc6Narayan KamathCompilerFilter::Filter OatFileAssistant::OdexFileCompilerFilter() {
377cd7e7f78b8e97c1f6419f3f44e0d5fdc6eddfdc6Narayan Kamath  const OatFile* odex_file = GetOdexFile();
378cd7e7f78b8e97c1f6419f3f44e0d5fdc6eddfdc6Narayan Kamath  CHECK(odex_file != nullptr);
379cd7e7f78b8e97c1f6419f3f44e0d5fdc6eddfdc6Narayan Kamath
380cd7e7f78b8e97c1f6419f3f44e0d5fdc6eddfdc6Narayan Kamath  return odex_file->GetCompilerFilter();
381cd7e7f78b8e97c1f6419f3f44e0d5fdc6eddfdc6Narayan Kamath}
382fbc31087932a65e036a153afab3049dc5298656aMathieu Chartierstd::string OatFileAssistant::ArtFileName(const OatFile* oat_file) const {
383fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier  const std::string oat_file_location = oat_file->GetLocation();
384fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier  // Replace extension with .art
385fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier  const size_t last_ext = oat_file_location.find_last_of('.');
386fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier  if (last_ext == std::string::npos) {
387fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier    LOG(ERROR) << "No extension in oat file " << oat_file_location;
388fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier    return std::string();
389fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier  }
390fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier  return oat_file_location.substr(0, last_ext) + ".art";
391fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier}
392fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier
39366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerconst std::string* OatFileAssistant::OatFileName() {
39466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  if (!cached_oat_file_name_attempted_) {
39566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    cached_oat_file_name_attempted_ = true;
39666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
39766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    // Compute the oat file name from the dex location.
39866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    // TODO: The oat file assistant should be the definitive place for
39966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    // determining the oat file name from the dex location, not
40066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    // GetDalvikCacheFilename.
40166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    std::string cache_dir = StringPrintf("%s%s",
40266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler        DalvikCacheDirectory().c_str(), GetInstructionSetString(isa_));
40366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    std::string error_msg;
404740eec92a7f63e8ddff1e007ae624d548a4e5a16Richard Uhler    cached_oat_file_name_found_ = GetDalvikCacheFilename(dex_location_.c_str(),
405b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin        cache_dir.c_str(), &cached_oat_file_name_, &error_msg);
40666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    if (!cached_oat_file_name_found_) {
40766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      // If we can't determine the oat file name, we treat the oat file as
40866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      // inaccessible.
40966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      LOG(WARNING) << "Failed to determine oat file name for dex location "
41066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler        << dex_location_ << ": " << error_msg;
41166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    }
41266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
41366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  return cached_oat_file_name_found_ ? &cached_oat_file_name_ : nullptr;
41466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
41566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
41666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerbool OatFileAssistant::OatFileExists() {
41766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  return GetOatFile() != nullptr;
41866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
41966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
42095abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard UhlerOatFileAssistant::OatStatus OatFileAssistant::OatFileStatus() {
42166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  if (OatFileIsOutOfDate()) {
42295abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler    return kOatOutOfDate;
42366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
42466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  if (OatFileIsUpToDate()) {
42595abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler    return kOatUpToDate;
42666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
42795abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  return kOatNeedsRelocation;
42866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
42966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
43066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerbool OatFileAssistant::OatFileIsOutOfDate() {
43166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  if (!oat_file_is_out_of_date_attempted_) {
43266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    oat_file_is_out_of_date_attempted_ = true;
43366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    const OatFile* oat_file = GetOatFile();
43466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    if (oat_file == nullptr) {
43566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      cached_oat_file_is_out_of_date_ = true;
43666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    } else {
43766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      cached_oat_file_is_out_of_date_ = GivenOatFileIsOutOfDate(*oat_file);
43866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    }
43966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
44066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  return cached_oat_file_is_out_of_date_;
44166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
44266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
44366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerbool OatFileAssistant::OatFileNeedsRelocation() {
44495abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  return OatFileStatus() == kOatNeedsRelocation;
44566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
44666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
44766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerbool OatFileAssistant::OatFileIsUpToDate() {
44866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  if (!oat_file_is_up_to_date_attempted_) {
44966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    oat_file_is_up_to_date_attempted_ = true;
45066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    const OatFile* oat_file = GetOatFile();
45166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    if (oat_file == nullptr) {
45266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      cached_oat_file_is_up_to_date_ = false;
45366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    } else {
45466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      cached_oat_file_is_up_to_date_ = GivenOatFileIsUpToDate(*oat_file);
45566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    }
45666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
45766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  return cached_oat_file_is_up_to_date_;
45866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
45966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
460cd7e7f78b8e97c1f6419f3f44e0d5fdc6eddfdc6Narayan KamathCompilerFilter::Filter OatFileAssistant::OatFileCompilerFilter() {
461cd7e7f78b8e97c1f6419f3f44e0d5fdc6eddfdc6Narayan Kamath  const OatFile* oat_file = GetOatFile();
462cd7e7f78b8e97c1f6419f3f44e0d5fdc6eddfdc6Narayan Kamath  CHECK(oat_file != nullptr);
463cd7e7f78b8e97c1f6419f3f44e0d5fdc6eddfdc6Narayan Kamath
464cd7e7f78b8e97c1f6419f3f44e0d5fdc6eddfdc6Narayan Kamath  return oat_file->GetCompilerFilter();
465cd7e7f78b8e97c1f6419f3f44e0d5fdc6eddfdc6Narayan Kamath}
466cd7e7f78b8e97c1f6419f3f44e0d5fdc6eddfdc6Narayan Kamath
46795abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard UhlerOatFileAssistant::OatStatus OatFileAssistant::GivenOatFileStatus(const OatFile& file) {
46866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // TODO: This could cause GivenOatFileIsOutOfDate to be called twice, which
46966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // is more work than we need to do. If performance becomes a concern, and
47066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // this method is actually called, this should be fixed.
47166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  if (GivenOatFileIsOutOfDate(file)) {
47295abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler    return kOatOutOfDate;
47366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
47466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  if (GivenOatFileIsUpToDate(file)) {
47595abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler    return kOatUpToDate;
47666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
47795abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  return kOatNeedsRelocation;
47866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
47966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
48066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerbool OatFileAssistant::GivenOatFileIsOutOfDate(const OatFile& file) {
48166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Verify the dex checksum.
4822cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  // Note: GetOatDexFile will return null if the dex checksum doesn't match
48366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // what we provide, which verifies the primary dex checksum for us.
48466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  const uint32_t* dex_checksum_pointer = GetRequiredDexChecksum();
48566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  const OatFile::OatDexFile* oat_dex_file = file.GetOatDexFile(
486740eec92a7f63e8ddff1e007ae624d548a4e5a16Richard Uhler      dex_location_.c_str(), dex_checksum_pointer, false);
4872cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  if (oat_dex_file == nullptr) {
48866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    return true;
48966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
49066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
49166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Verify the dex checksums for any secondary multidex files
49290e34043ff7bf8926e8fe6a6d5011a9daa68d320Andreas Gampe  for (size_t i = 1; ; i++) {
49366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    std::string secondary_dex_location
494740eec92a7f63e8ddff1e007ae624d548a4e5a16Richard Uhler      = DexFile::GetMultiDexLocation(i, dex_location_.c_str());
49566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    const OatFile::OatDexFile* secondary_oat_dex_file
49666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      = file.GetOatDexFile(secondary_dex_location.c_str(), nullptr, false);
4972cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier    if (secondary_oat_dex_file == nullptr) {
49866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      // There are no more secondary dex files to check.
49966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      break;
50066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    }
50166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
50266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    std::string error_msg;
50366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    uint32_t expected_secondary_checksum = 0;
50466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    if (DexFile::GetChecksum(secondary_dex_location.c_str(),
505b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin          &expected_secondary_checksum, &error_msg)) {
50666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      uint32_t actual_secondary_checksum
50766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler        = secondary_oat_dex_file->GetDexFileLocationChecksum();
50866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      if (expected_secondary_checksum != actual_secondary_checksum) {
50966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler        VLOG(oat) << "Dex checksum does not match for secondary dex: "
51066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler          << secondary_dex_location
51166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler          << ". Expected: " << expected_secondary_checksum
51266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler          << ", Actual: " << actual_secondary_checksum;
51367ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler        return true;
51466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      }
51566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    } else {
51666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      // If we can't get the checksum for the secondary location, we assume
51766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      // the dex checksum is up to date for this and all other secondary dex
51866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      // files.
51966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      break;
52066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    }
52166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
52266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
52329d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe  CompilerFilter::Filter current_compiler_filter = file.GetCompilerFilter();
52429d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe  VLOG(oat) << "Compiler filter for " << file.GetLocation() << " is " << current_compiler_filter;
525a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler
526845e5064580bd37ad5014f7aa0d078be7265464dNicolas Geoffray  // Verify the image checksum
52729d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe  if (CompilerFilter::DependsOnImageChecksum(current_compiler_filter)) {
52829d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe    const ImageInfo* image_info = GetImageInfo();
52929d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe    if (image_info == nullptr) {
53029d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe      VLOG(oat) << "No image for oat image checksum to match against.";
53129d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe
5321153ae16f243adb30fc8509c619025d30408c74aRichard Uhler      if (HasOriginalDexFiles()) {
5331153ae16f243adb30fc8509c619025d30408c74aRichard Uhler        return true;
5341153ae16f243adb30fc8509c619025d30408c74aRichard Uhler      }
5351153ae16f243adb30fc8509c619025d30408c74aRichard Uhler
5361153ae16f243adb30fc8509c619025d30408c74aRichard Uhler      // If there is no original dex file to fall back to, grudgingly accept
5371153ae16f243adb30fc8509c619025d30408c74aRichard Uhler      // the oat file. This could technically lead to crashes, but there's no
5381153ae16f243adb30fc8509c619025d30408c74aRichard Uhler      // way we could find a better oat file to use for this dex location,
5391153ae16f243adb30fc8509c619025d30408c74aRichard Uhler      // and it's better than being stuck in a boot loop with no way out.
5401153ae16f243adb30fc8509c619025d30408c74aRichard Uhler      // The problem will hopefully resolve itself the next time the runtime
5411153ae16f243adb30fc8509c619025d30408c74aRichard Uhler      // starts up.
5421153ae16f243adb30fc8509c619025d30408c74aRichard Uhler      LOG(WARNING) << "Dex location " << dex_location_ << " does not seem to include dex file. "
5431153ae16f243adb30fc8509c619025d30408c74aRichard Uhler        << "Allow oat file use. This is potentially dangerous.";
5441153ae16f243adb30fc8509c619025d30408c74aRichard Uhler    } else if (file.GetOatHeader().GetImageFileLocationOatChecksum()
5451153ae16f243adb30fc8509c619025d30408c74aRichard Uhler        != GetCombinedImageChecksum()) {
54629d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe      VLOG(oat) << "Oat image checksum does not match image checksum.";
54729d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe      return true;
54829d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe    }
54929d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe  } else {
55029d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe    VLOG(oat) << "Image checksum test skipped for compiler filter " << current_compiler_filter;
55166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
55266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
55329d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe  // Verify the profile hasn't changed recently.
55429d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe  // TODO: Move this check to OatFileCompilerFilterIsOkay? Nothing bad should
55529d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe  // happen if we use an oat file compiled with an out-of-date profile.
55629d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe  if (CompilerFilter::DependsOnProfile(current_compiler_filter)) {
55729d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe    if (profile_changed_) {
55829d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe      VLOG(oat) << "The profile has changed recently.";
55929d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe      return true;
56029d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe    }
56129d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe  } else {
56229d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe    VLOG(oat) << "Profile check skipped for compiler filter " << current_compiler_filter;
56366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
56466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
56529d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe  // Everything looks good; the dex file is not out of date.
56666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  return false;
56766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
56866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
56966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerbool OatFileAssistant::GivenOatFileNeedsRelocation(const OatFile& file) {
57095abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  return GivenOatFileStatus(file) == kOatNeedsRelocation;
57166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
57266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
57366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerbool OatFileAssistant::GivenOatFileIsUpToDate(const OatFile& file) {
57466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  if (GivenOatFileIsOutOfDate(file)) {
57566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    return false;
57666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
57766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
57829d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe  CompilerFilter::Filter current_compiler_filter = file.GetCompilerFilter();
57966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
5808c185bf0c6f18a5349bc87a7e3751ba06d90f461Vladimir Marko  if (CompilerFilter::IsBytecodeCompilationEnabled(current_compiler_filter)) {
58129d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe    if (!file.IsPic()) {
58229d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe      const ImageInfo* image_info = GetImageInfo();
58329d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe      if (image_info == nullptr) {
58429d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe        VLOG(oat) << "No image to check oat relocation against.";
58529d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe        return false;
58629d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe      }
58766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
58829d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe      // Verify the oat_data_begin recorded for the image in the oat file matches
58929d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe      // the actual oat_data_begin for boot.oat in the image.
59029d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe      const OatHeader& oat_header = file.GetOatHeader();
59129d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe      uintptr_t oat_data_begin = oat_header.GetImageFileLocationOatDataBegin();
59229d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe      if (oat_data_begin != image_info->oat_data_begin) {
59329d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe        VLOG(oat) << file.GetLocation() <<
59429d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe          ": Oat file image oat_data_begin (" << oat_data_begin << ")"
59529d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe          << " does not match actual image oat_data_begin ("
59629d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe          << image_info->oat_data_begin << ")";
59729d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe        return false;
59829d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe      }
599a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler
60029d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe      // Verify the oat_patch_delta recorded for the image in the oat file matches
60129d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe      // the actual oat_patch_delta for the image.
60229d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe      int32_t oat_patch_delta = oat_header.GetImagePatchDelta();
60329d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe      if (oat_patch_delta != image_info->patch_delta) {
60429d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe        VLOG(oat) << file.GetLocation() <<
60529d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe          ": Oat file image patch delta (" << oat_patch_delta << ")"
60629d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe          << " does not match actual image patch delta ("
60729d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe          << image_info->patch_delta << ")";
60829d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe        return false;
60929d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe      }
61029d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe    } else {
61129d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe      // Oat files compiled in PIC mode do not require relocation.
61229d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe      VLOG(oat) << "Oat relocation test skipped for PIC oat file";
61329d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe    }
61429d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe  } else {
61529d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe    VLOG(oat) << "Oat relocation test skipped for compiler filter " << current_compiler_filter;
61666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
61766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  return true;
61866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
61966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
6201e860619cdcc9c0b6a202a247c50cf7633ac7b74Richard UhlerOatFileAssistant::ResultOfAttemptToUpdate
6211e860619cdcc9c0b6a202a247c50cf7633ac7b74Richard UhlerOatFileAssistant::RelocateOatFile(const std::string* input_file, std::string* error_msg) {
62266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  CHECK(error_msg != nullptr);
62366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
62495abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  if (input_file == nullptr) {
625740eec92a7f63e8ddff1e007ae624d548a4e5a16Richard Uhler    *error_msg = "Patching of oat file for dex location " + dex_location_
62695abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler      + " not attempted because the input file name could not be determined.";
6271e860619cdcc9c0b6a202a247c50cf7633ac7b74Richard Uhler    return kUpdateNotAttempted;
62866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
62995abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  const std::string& input_file_name = *input_file;
63066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
63166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  if (OatFileName() == nullptr) {
632740eec92a7f63e8ddff1e007ae624d548a4e5a16Richard Uhler    *error_msg = "Patching of oat file for dex location " + dex_location_
63366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      + " not attempted because the oat file name could not be determined.";
6341e860619cdcc9c0b6a202a247c50cf7633ac7b74Richard Uhler    return kUpdateNotAttempted;
63566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
63666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  const std::string& oat_file_name = *OatFileName();
63766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
63866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  const ImageInfo* image_info = GetImageInfo();
63966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Runtime* runtime = Runtime::Current();
64066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  if (image_info == nullptr) {
64166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    *error_msg = "Patching of oat file " + oat_file_name
64266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      + " not attempted because no image location was found.";
6431e860619cdcc9c0b6a202a247c50cf7633ac7b74Richard Uhler    return kUpdateNotAttempted;
64466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
64566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
64666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  if (!runtime->IsDex2OatEnabled()) {
64766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    *error_msg = "Patching of oat file " + oat_file_name
64866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      + " not attempted because dex2oat is disabled";
6491e860619cdcc9c0b6a202a247c50cf7633ac7b74Richard Uhler    return kUpdateNotAttempted;
65066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
65166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
65266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::vector<std::string> argv;
65366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  argv.push_back(runtime->GetPatchoatExecutable());
65466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  argv.push_back("--instruction-set=" + std::string(GetInstructionSetString(isa_)));
65595abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler  argv.push_back("--input-oat-file=" + input_file_name);
65666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  argv.push_back("--output-oat-file=" + oat_file_name);
65766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  argv.push_back("--patched-image-location=" + image_info->location);
65866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
65966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string command_line(Join(argv, ' '));
66066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  if (!Exec(argv, error_msg)) {
66166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    // Manually delete the file. This ensures there is no garbage left over if
66266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    // the process unexpectedly died.
66366fdcbdb1fde4bf65da5e801ba76a8e65391635bVladimir Marko    unlink(oat_file_name.c_str());
6641e860619cdcc9c0b6a202a247c50cf7633ac7b74Richard Uhler    return kUpdateFailed;
66566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
66666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
66766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Mark that the oat file has changed and we should try to reload.
66866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  ClearOatFileCache();
6691e860619cdcc9c0b6a202a247c50cf7633ac7b74Richard Uhler  return kUpdateSucceeded;
67066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
67166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
6721e860619cdcc9c0b6a202a247c50cf7633ac7b74Richard UhlerOatFileAssistant::ResultOfAttemptToUpdate
6731e860619cdcc9c0b6a202a247c50cf7633ac7b74Richard UhlerOatFileAssistant::GenerateOatFile(CompilerFilter::Filter target, std::string* error_msg) {
67466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  CHECK(error_msg != nullptr);
67566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
6768327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  Runtime* runtime = Runtime::Current();
6778327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  if (!runtime->IsDex2OatEnabled()) {
678740eec92a7f63e8ddff1e007ae624d548a4e5a16Richard Uhler    *error_msg = "Generation of oat file for dex location " + dex_location_
6798327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler      + " not attempted because dex2oat is disabled.";
6801e860619cdcc9c0b6a202a247c50cf7633ac7b74Richard Uhler    return kUpdateNotAttempted;
68166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
68266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
6838327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  if (OatFileName() == nullptr) {
6848327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler    *error_msg = "Generation of oat file for dex location " + dex_location_
6858327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler      + " not attempted because the oat file name could not be determined.";
6861e860619cdcc9c0b6a202a247c50cf7633ac7b74Richard Uhler    return kUpdateNotAttempted;
68766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
6888327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  const std::string& oat_file_name = *OatFileName();
68966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
69066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // dex2oat ignores missing dex files and doesn't report an error.
69166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Check explicitly here so we can detect the error properly.
69266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // TODO: Why does dex2oat behave that way?
693740eec92a7f63e8ddff1e007ae624d548a4e5a16Richard Uhler  if (!OS::FileExists(dex_location_.c_str())) {
694740eec92a7f63e8ddff1e007ae624d548a4e5a16Richard Uhler    *error_msg = "Dex location " + dex_location_ + " does not exists.";
6951e860619cdcc9c0b6a202a247c50cf7633ac7b74Richard Uhler    return kUpdateNotAttempted;
69666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
69766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
6988327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  std::unique_ptr<File> oat_file;
6998327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  oat_file.reset(OS::CreateEmptyFile(oat_file_name.c_str()));
7008327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  if (oat_file.get() == nullptr) {
7018327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler    *error_msg = "Generation of oat file " + oat_file_name
7028327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler      + " not attempted because the oat file could not be created.";
7031e860619cdcc9c0b6a202a247c50cf7633ac7b74Richard Uhler    return kUpdateNotAttempted;
7048327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  }
7058327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler
7068327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  if (fchmod(oat_file->Fd(), 0644) != 0) {
7078327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler    *error_msg = "Generation of oat file " + oat_file_name
7088327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler      + " not attempted because the oat file could not be made world readable.";
7098327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler    oat_file->Erase();
7101e860619cdcc9c0b6a202a247c50cf7633ac7b74Richard Uhler    return kUpdateNotAttempted;
7118327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  }
7128327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler
7138327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  std::vector<std::string> args;
7148327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  args.push_back("--dex-file=" + dex_location_);
7158327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  args.push_back("--oat-fd=" + std::to_string(oat_file->Fd()));
7168327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  args.push_back("--oat-location=" + oat_file_name);
71729d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe  args.push_back("--compiler-filter=" + CompilerFilter::NameOfFilter(target));
7188327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler
71966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  if (!Dex2Oat(args, error_msg)) {
72066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    // Manually delete the file. This ensures there is no garbage left over if
72166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    // the process unexpectedly died.
7228327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler    oat_file->Erase();
72366fdcbdb1fde4bf65da5e801ba76a8e65391635bVladimir Marko    unlink(oat_file_name.c_str());
7241e860619cdcc9c0b6a202a247c50cf7633ac7b74Richard Uhler    return kUpdateFailed;
7258327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  }
7268327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler
7278327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler  if (oat_file->FlushCloseOrErase() != 0) {
7288327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler    *error_msg = "Unable to close oat file " + oat_file_name;
72966fdcbdb1fde4bf65da5e801ba76a8e65391635bVladimir Marko    unlink(oat_file_name.c_str());
7301e860619cdcc9c0b6a202a247c50cf7633ac7b74Richard Uhler    return kUpdateFailed;
73166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
73266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
73366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Mark that the oat file has changed and we should try to reload.
73466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  ClearOatFileCache();
7351e860619cdcc9c0b6a202a247c50cf7633ac7b74Richard Uhler  return kUpdateSucceeded;
73666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
73766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
73866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerbool OatFileAssistant::Dex2Oat(const std::vector<std::string>& args,
73966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler                               std::string* error_msg) {
74066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Runtime* runtime = Runtime::Current();
74166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string image_location = ImageLocation();
74266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  if (image_location.empty()) {
74366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    *error_msg = "No image location found for Dex2Oat.";
74466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    return false;
74566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
74666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
74766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::vector<std::string> argv;
74866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  argv.push_back(runtime->GetCompilerExecutable());
74966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  argv.push_back("--runtime-arg");
75066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  argv.push_back("-classpath");
75166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  argv.push_back("--runtime-arg");
7525872d7cd6ceffe67550d0b021191ec66f1a34c5dJeff Hao  std::string class_path = runtime->GetClassPathString();
7535872d7cd6ceffe67550d0b021191ec66f1a34c5dJeff Hao  if (class_path == "") {
7545872d7cd6ceffe67550d0b021191ec66f1a34c5dJeff Hao    class_path = OatFile::kSpecialSharedLibrary;
7555872d7cd6ceffe67550d0b021191ec66f1a34c5dJeff Hao  }
7565872d7cd6ceffe67550d0b021191ec66f1a34c5dJeff Hao  argv.push_back(class_path);
7577a4d0157eb690266928902a67922f346e290f4c6Nicolas Geoffray  if (runtime->IsDebuggable()) {
7580de1133ba600f299b3d67938f650720d9f859eb2Sebastien Hertz    argv.push_back("--debuggable");
7590de1133ba600f299b3d67938f650720d9f859eb2Sebastien Hertz  }
760b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin  runtime->AddCurrentRuntimeFeaturesAsDex2OatArguments(&argv);
76166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
76266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  if (!runtime->IsVerificationEnabled()) {
76366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    argv.push_back("--compiler-filter=verify-none");
76466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
76566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
76666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  if (runtime->MustRelocateIfPossible()) {
76766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    argv.push_back("--runtime-arg");
76866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    argv.push_back("-Xrelocate");
76966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  } else {
77066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    argv.push_back("--runtime-arg");
77166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    argv.push_back("-Xnorelocate");
77266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
77366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
77466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  if (!kIsTargetBuild) {
77566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    argv.push_back("--host");
77666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
77766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
77866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  argv.push_back("--boot-image=" + image_location);
77966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
78066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::vector<std::string> compiler_options = runtime->GetCompilerOptions();
78166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  argv.insert(argv.end(), compiler_options.begin(), compiler_options.end());
78266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
78366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  argv.insert(argv.end(), args.begin(), args.end());
78466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
78566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string command_line(Join(argv, ' '));
78666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  return Exec(argv, error_msg);
78766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
78866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
78966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerbool OatFileAssistant::DexFilenameToOdexFilename(const std::string& location,
79066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    InstructionSet isa, std::string* odex_filename, std::string* error_msg) {
79166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  CHECK(odex_filename != nullptr);
79266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  CHECK(error_msg != nullptr);
79366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
79466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // The odex file name is formed by replacing the dex_location extension with
7956343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  // .odex and inserting an oat/<isa> directory. For example:
79666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  //   location = /foo/bar/baz.jar
7976343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  //   odex_location = /foo/bar/oat/<isa>/baz.odex
79866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
7996343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  // Find the directory portion of the dex location and add the oat/<isa>
8006343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  // directory.
80166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  size_t pos = location.rfind('/');
80266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  if (pos == std::string::npos) {
80366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    *error_msg = "Dex location " + location + " has no directory.";
80466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    return false;
80566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
80666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string dir = location.substr(0, pos+1);
8076343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler  dir += "oat/" + std::string(GetInstructionSetString(isa));
80866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
80966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Find the file portion of the dex location.
81066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string file;
81166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  if (pos == std::string::npos) {
81266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    file = location;
81366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  } else {
81466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    file = location.substr(pos+1);
81566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
81666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
81766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Get the base part of the file without the extension.
81866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  pos = file.rfind('.');
81966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  if (pos == std::string::npos) {
82066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    *error_msg = "Dex location " + location + " has no extension.";
82166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    return false;
82266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
82366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string base = file.substr(0, pos);
82466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
82566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  *odex_filename = dir + "/" + base + ".odex";
82666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  return true;
82766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
82866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
82966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerstd::string OatFileAssistant::DalvikCacheDirectory() {
83066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Note: We don't cache this, because it will only be called once by
83129d38e77c553c6cf71fc4dafe2d22b4e3f814872Andreas Gampe  // OatFileName.
83266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
83366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // TODO: The work done in GetDalvikCache is overkill for what we need.
83466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // Ideally a new API for getting the DalvikCacheDirectory the way we want
83566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // (without existence testing, creation, or death) is provided with the rest
83666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // of the GetDalvikCache family of functions. Until such an API is in place,
83766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // we use GetDalvikCache to avoid duplicating the logic for determining the
83866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  // dalvik cache directory.
83966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  std::string result;
84066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  bool have_android_data;
84166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  bool dalvik_cache_exists;
84266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  bool is_global_cache;
84366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  GetDalvikCache("", false, &result, &have_android_data, &dalvik_cache_exists, &is_global_cache);
84466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  return result;
84566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
84666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
84766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerstd::string OatFileAssistant::ImageLocation() {
84866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  Runtime* runtime = Runtime::Current();
8498994a04162a92759f8ec531d18ee8901145dfda0Andreas Gampe  const std::vector<gc::space::ImageSpace*>& image_spaces =
8508994a04162a92759f8ec531d18ee8901145dfda0Andreas Gampe      runtime->GetHeap()->GetBootImageSpaces();
8518994a04162a92759f8ec531d18ee8901145dfda0Andreas Gampe  if (image_spaces.empty()) {
8528994a04162a92759f8ec531d18ee8901145dfda0Andreas Gampe    return "";
8538994a04162a92759f8ec531d18ee8901145dfda0Andreas Gampe  }
8548994a04162a92759f8ec531d18ee8901145dfda0Andreas Gampe  return image_spaces[0]->GetImageLocation();
85566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
85666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
85766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerconst uint32_t* OatFileAssistant::GetRequiredDexChecksum() {
8589b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  if (!required_dex_checksum_attempted_) {
8599b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler    required_dex_checksum_attempted_ = true;
8609b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler    required_dex_checksum_found_ = false;
86166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    std::string error_msg;
862740eec92a7f63e8ddff1e007ae624d548a4e5a16Richard Uhler    if (DexFile::GetChecksum(dex_location_.c_str(), &cached_required_dex_checksum_, &error_msg)) {
8639b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler      required_dex_checksum_found_ = true;
8649b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler      has_original_dex_files_ = true;
86566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    } else {
86666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      // This can happen if the original dex file has been stripped from the
86766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      // apk.
86866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      VLOG(oat) << "OatFileAssistant: " << error_msg;
8699b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler      has_original_dex_files_ = false;
87066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
87166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      // Get the checksum from the odex if we can.
87266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      const OatFile* odex_file = GetOdexFile();
87366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      if (odex_file != nullptr) {
87466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler        const OatFile::OatDexFile* odex_dex_file = odex_file->GetOatDexFile(
875740eec92a7f63e8ddff1e007ae624d548a4e5a16Richard Uhler            dex_location_.c_str(), nullptr, false);
87666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler        if (odex_dex_file != nullptr) {
8779b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler          cached_required_dex_checksum_ = odex_dex_file->GetDexFileLocationChecksum();
8789b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler          required_dex_checksum_found_ = true;
87966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler        }
88066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      }
88166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    }
88266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
8839b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler  return required_dex_checksum_found_ ? &cached_required_dex_checksum_ : nullptr;
88466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
88566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
88666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerconst OatFile* OatFileAssistant::GetOdexFile() {
88766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  CHECK(!oat_file_released_) << "OdexFile called after oat file released.";
88866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  if (!odex_file_load_attempted_) {
88966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    odex_file_load_attempted_ = true;
89066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    if (OdexFileName() != nullptr) {
89166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      const std::string& odex_file_name = *OdexFileName();
89266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      std::string error_msg;
89366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      cached_odex_file_.reset(OatFile::Open(odex_file_name.c_str(),
8940b4cbd0c2a75b47ae09d21e5d73d2b1709cb5b9eMathieu Chartier                                            odex_file_name.c_str(),
8950b4cbd0c2a75b47ae09d21e5d73d2b1709cb5b9eMathieu Chartier                                            nullptr,
8960b4cbd0c2a75b47ae09d21e5d73d2b1709cb5b9eMathieu Chartier                                            nullptr,
8970b4cbd0c2a75b47ae09d21e5d73d2b1709cb5b9eMathieu Chartier                                            load_executable_,
8980b4cbd0c2a75b47ae09d21e5d73d2b1709cb5b9eMathieu Chartier                                            /*low_4gb*/false,
8990b4cbd0c2a75b47ae09d21e5d73d2b1709cb5b9eMathieu Chartier                                            dex_location_.c_str(),
9000b4cbd0c2a75b47ae09d21e5d73d2b1709cb5b9eMathieu Chartier                                            &error_msg));
90166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      if (cached_odex_file_.get() == nullptr) {
90266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler        VLOG(oat) << "OatFileAssistant test for existing pre-compiled oat file "
90366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler          << odex_file_name << ": " << error_msg;
90466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      }
90566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    }
90666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
90766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  return cached_odex_file_.get();
90866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
90966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
9105f946da9c362216e9144b142ec0e5b90073b836dRichard Uhlerbool OatFileAssistant::OdexFileIsExecutable() {
9115f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler  const OatFile* odex_file = GetOdexFile();
9125f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler  return (odex_file != nullptr && odex_file->IsExecutable());
9135f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler}
9145f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler
915d1537b569b6cd18297c5e02d13cdd588c4366c51Richard Uhlerbool OatFileAssistant::OdexFileHasPatchInfo() {
916d1537b569b6cd18297c5e02d13cdd588c4366c51Richard Uhler  const OatFile* odex_file = GetOdexFile();
917d1537b569b6cd18297c5e02d13cdd588c4366c51Richard Uhler  return (odex_file != nullptr && odex_file->HasPatchInfo());
918d1537b569b6cd18297c5e02d13cdd588c4366c51Richard Uhler}
919d1537b569b6cd18297c5e02d13cdd588c4366c51Richard Uhler
92066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlervoid OatFileAssistant::ClearOdexFileCache() {
92166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  odex_file_load_attempted_ = false;
92266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  cached_odex_file_.reset();
92366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  odex_file_is_out_of_date_attempted_ = false;
92466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  odex_file_is_up_to_date_attempted_ = false;
92566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
92666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
92766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerconst OatFile* OatFileAssistant::GetOatFile() {
92866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  CHECK(!oat_file_released_) << "OatFile called after oat file released.";
92966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  if (!oat_file_load_attempted_) {
93066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    oat_file_load_attempted_ = true;
93166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    if (OatFileName() != nullptr) {
93266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      const std::string& oat_file_name = *OatFileName();
93366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      std::string error_msg;
93466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      cached_oat_file_.reset(OatFile::Open(oat_file_name.c_str(),
9350b4cbd0c2a75b47ae09d21e5d73d2b1709cb5b9eMathieu Chartier                                           oat_file_name.c_str(),
9360b4cbd0c2a75b47ae09d21e5d73d2b1709cb5b9eMathieu Chartier                                           nullptr,
9370b4cbd0c2a75b47ae09d21e5d73d2b1709cb5b9eMathieu Chartier                                           nullptr,
9380b4cbd0c2a75b47ae09d21e5d73d2b1709cb5b9eMathieu Chartier                                           load_executable_,
9390b4cbd0c2a75b47ae09d21e5d73d2b1709cb5b9eMathieu Chartier                                           /*low_4gb*/false,
9400b4cbd0c2a75b47ae09d21e5d73d2b1709cb5b9eMathieu Chartier                                           dex_location_.c_str(),
9410b4cbd0c2a75b47ae09d21e5d73d2b1709cb5b9eMathieu Chartier                                           &error_msg));
94266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      if (cached_oat_file_.get() == nullptr) {
94366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler        VLOG(oat) << "OatFileAssistant test for existing oat file "
94466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler          << oat_file_name << ": " << error_msg;
94566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      }
94666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    }
94766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
94866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  return cached_oat_file_.get();
94966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
95066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
9515f946da9c362216e9144b142ec0e5b90073b836dRichard Uhlerbool OatFileAssistant::OatFileIsExecutable() {
9525f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler  const OatFile* oat_file = GetOatFile();
9535f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler  return (oat_file != nullptr && oat_file->IsExecutable());
9545f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler}
9555f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler
956d1537b569b6cd18297c5e02d13cdd588c4366c51Richard Uhlerbool OatFileAssistant::OatFileHasPatchInfo() {
957d1537b569b6cd18297c5e02d13cdd588c4366c51Richard Uhler  const OatFile* oat_file = GetOatFile();
958d1537b569b6cd18297c5e02d13cdd588c4366c51Richard Uhler  return (oat_file != nullptr && oat_file->HasPatchInfo());
959d1537b569b6cd18297c5e02d13cdd588c4366c51Richard Uhler}
960d1537b569b6cd18297c5e02d13cdd588c4366c51Richard Uhler
96166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlervoid OatFileAssistant::ClearOatFileCache() {
96266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  oat_file_load_attempted_ = false;
96366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  cached_oat_file_.reset();
96466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  oat_file_is_out_of_date_attempted_ = false;
96566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  oat_file_is_up_to_date_attempted_ = false;
96666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
96766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
96866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerconst OatFileAssistant::ImageInfo* OatFileAssistant::GetImageInfo() {
96966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  if (!image_info_load_attempted_) {
97066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    image_info_load_attempted_ = true;
97166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
97266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    Runtime* runtime = Runtime::Current();
973dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao    std::vector<gc::space::ImageSpace*> image_spaces = runtime->GetHeap()->GetBootImageSpaces();
974dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao    if (!image_spaces.empty()) {
975dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao      cached_image_info_.location = image_spaces[0]->GetImageLocation();
97666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
97766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      if (isa_ == kRuntimeISA) {
978dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao        const ImageHeader& image_header = image_spaces[0]->GetImageHeader();
97966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler        cached_image_info_.oat_checksum = image_header.GetOatChecksum();
980073b16c8429d302d5413e8ffc488b03b8f770780Mathieu Chartier        cached_image_info_.oat_data_begin = reinterpret_cast<uintptr_t>(
981073b16c8429d302d5413e8ffc488b03b8f770780Mathieu Chartier            image_header.GetOatDataBegin());
98266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler        cached_image_info_.patch_delta = image_header.GetPatchDelta();
98366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      } else {
98466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler        std::unique_ptr<ImageHeader> image_header(
9854f351aae00f43dd4e3290976f249d3664cc47091Jeff Hao            gc::space::ImageSpace::ReadImageHeaderOrDie(cached_image_info_.location.c_str(), isa_));
98666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler        cached_image_info_.oat_checksum = image_header->GetOatChecksum();
987073b16c8429d302d5413e8ffc488b03b8f770780Mathieu Chartier        cached_image_info_.oat_data_begin = reinterpret_cast<uintptr_t>(
988073b16c8429d302d5413e8ffc488b03b8f770780Mathieu Chartier            image_header->GetOatDataBegin());
98966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler        cached_image_info_.patch_delta = image_header->GetPatchDelta();
99066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler      }
99166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler    }
992dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao    image_info_load_succeeded_ = (!image_spaces.empty());
9934f351aae00f43dd4e3290976f249d3664cc47091Jeff Hao
994539d38c67c521aa17741a41fc4c4462b576adfd9Jeff Hao    combined_image_checksum_ = CalculateCombinedImageChecksum(isa_);
99566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  }
99666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler  return image_info_load_succeeded_ ? &cached_image_info_ : nullptr;
99766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}
99866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
9994f351aae00f43dd4e3290976f249d3664cc47091Jeff Hao// TODO: Use something better than xor.
1000539d38c67c521aa17741a41fc4c4462b576adfd9Jeff Haouint32_t OatFileAssistant::CalculateCombinedImageChecksum(InstructionSet isa) {
10014f351aae00f43dd4e3290976f249d3664cc47091Jeff Hao  uint32_t checksum = 0;
10024f351aae00f43dd4e3290976f249d3664cc47091Jeff Hao  std::vector<gc::space::ImageSpace*> image_spaces =
10034f351aae00f43dd4e3290976f249d3664cc47091Jeff Hao      Runtime::Current()->GetHeap()->GetBootImageSpaces();
1004539d38c67c521aa17741a41fc4c4462b576adfd9Jeff Hao  if (isa == kRuntimeISA) {
1005539d38c67c521aa17741a41fc4c4462b576adfd9Jeff Hao    for (gc::space::ImageSpace* image_space : image_spaces) {
1006539d38c67c521aa17741a41fc4c4462b576adfd9Jeff Hao      checksum ^= image_space->GetImageHeader().GetOatChecksum();
1007539d38c67c521aa17741a41fc4c4462b576adfd9Jeff Hao    }
1008539d38c67c521aa17741a41fc4c4462b576adfd9Jeff Hao  } else {
1009539d38c67c521aa17741a41fc4c4462b576adfd9Jeff Hao    for (gc::space::ImageSpace* image_space : image_spaces) {
1010539d38c67c521aa17741a41fc4c4462b576adfd9Jeff Hao      std::string location = image_space->GetImageLocation();
1011539d38c67c521aa17741a41fc4c4462b576adfd9Jeff Hao      std::unique_ptr<ImageHeader> image_header(
1012539d38c67c521aa17741a41fc4c4462b576adfd9Jeff Hao          gc::space::ImageSpace::ReadImageHeaderOrDie(location.c_str(), isa));
1013539d38c67c521aa17741a41fc4c4462b576adfd9Jeff Hao      checksum ^= image_header->GetOatChecksum();
1014539d38c67c521aa17741a41fc4c4462b576adfd9Jeff Hao    }
10154f351aae00f43dd4e3290976f249d3664cc47091Jeff Hao  }
10164f351aae00f43dd4e3290976f249d3664cc47091Jeff Hao  return checksum;
10174f351aae00f43dd4e3290976f249d3664cc47091Jeff Hao}
10184f351aae00f43dd4e3290976f249d3664cc47091Jeff Hao
10194f351aae00f43dd4e3290976f249d3664cc47091Jeff Haouint32_t OatFileAssistant::GetCombinedImageChecksum() {
10204f351aae00f43dd4e3290976f249d3664cc47091Jeff Hao  if (!image_info_load_attempted_) {
10214f351aae00f43dd4e3290976f249d3664cc47091Jeff Hao    GetImageInfo();
10224f351aae00f43dd4e3290976f249d3664cc47091Jeff Hao  }
10234f351aae00f43dd4e3290976f249d3664cc47091Jeff Hao  return combined_image_checksum_;
10244f351aae00f43dd4e3290976f249d3664cc47091Jeff Hao}
10254f351aae00f43dd4e3290976f249d3664cc47091Jeff Hao
1026fbc31087932a65e036a153afab3049dc5298656aMathieu Chartiergc::space::ImageSpace* OatFileAssistant::OpenImageSpace(const OatFile* oat_file) {
1027fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier  DCHECK(oat_file != nullptr);
1028fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier  std::string art_file = ArtFileName(oat_file);
1029fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier  if (art_file.empty()) {
1030fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier    return nullptr;
1031fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier  }
1032fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier  std::string error_msg;
1033fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier  ScopedObjectAccess soa(Thread::Current());
1034fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier  gc::space::ImageSpace* ret = gc::space::ImageSpace::CreateFromAppImage(art_file.c_str(),
1035fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier                                                                         oat_file,
1036fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier                                                                         &error_msg);
1037e778fc7332238534b173c2c3e0c4502d12f58da3Mathieu Chartier  if (ret == nullptr && (VLOG_IS_ON(image) || OS::FileExists(art_file.c_str()))) {
1038fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier    LOG(INFO) << "Failed to open app image " << art_file.c_str() << " " << error_msg;
1039fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier  }
1040fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier  return ret;
1041fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier}
1042fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier
104366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}  // namespace art
104466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler
1045