patchoat.cc revision 1c83cbc4a817acbd7f9abb5b29a2d418a958e6a1
153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light/*
253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light * Copyright (C) 2014 The Android Open Source Project
353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light *
453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light * Licensed under the Apache License, Version 2.0 (the "License");
553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light * you may not use this file except in compliance with the License.
653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light * You may obtain a copy of the License at
753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light *
853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light *      http://www.apache.org/licenses/LICENSE-2.0
953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light *
1053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light * Unless required by applicable law or agreed to in writing, software
1153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light * distributed under the License is distributed on an "AS IS" BASIS,
1253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light * See the License for the specific language governing permissions and
1453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light * limitations under the License.
1553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light */
1653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light#include "patchoat.h"
1753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
1853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light#include <stdio.h>
1953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light#include <stdlib.h>
20a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light#include <sys/file.h>
2153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light#include <sys/stat.h>
22a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light#include <unistd.h>
2353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
2453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light#include <string>
2553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light#include <vector>
2653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
27a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light#include "base/scoped_flock.h"
2853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light#include "base/stringpiece.h"
2953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light#include "base/stringprintf.h"
3053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light#include "elf_utils.h"
3153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light#include "elf_file.h"
32e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers#include "gc/space/image_space.h"
3353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light#include "image.h"
3453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light#include "instruction_set.h"
3553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light#include "mirror/art_field.h"
3653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light#include "mirror/art_field-inl.h"
3753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light#include "mirror/art_method.h"
3853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light#include "mirror/art_method-inl.h"
3953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light#include "mirror/object.h"
4053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light#include "mirror/object-inl.h"
4153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light#include "mirror/reference.h"
4253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light#include "noop_compiler_callbacks.h"
4353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light#include "offsets.h"
4453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light#include "os.h"
4553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light#include "runtime.h"
4653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light#include "scoped_thread_state_change.h"
4753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light#include "thread.h"
4853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light#include "utils.h"
4953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
5053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Lightnamespace art {
5153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
5253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Lightstatic InstructionSet ElfISAToInstructionSet(Elf32_Word isa) {
5353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  switch (isa) {
5453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    case EM_ARM:
5553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      return kArm;
5653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    case EM_AARCH64:
5753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      return kArm64;
5853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    case EM_386:
5953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      return kX86;
6053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    case EM_X86_64:
6153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      return kX86_64;
6253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    case EM_MIPS:
6353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      return kMips;
6453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    default:
6553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      return kNone;
6653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
6753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}
6853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
6953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Lightbool PatchOat::Patch(const std::string& image_location, off_t delta,
7053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light                     File* output_image, InstructionSet isa,
71eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light                     TimingLogger* timings) {
7253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK(Runtime::Current() == nullptr);
7353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK(output_image != nullptr);
7453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK_GE(output_image->Fd(), 0);
7553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK(!image_location.empty()) << "image file must have a filename.";
7653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK_NE(isa, kNone);
7753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
78eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light  TimingLogger::ScopedTiming t("Runtime Setup", timings);
7953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  const char *isa_name = GetInstructionSetString(isa);
8053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  std::string image_filename(GetSystemImageFilename(image_location.c_str(), isa));
8153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  std::unique_ptr<File> input_image(OS::OpenFileForReading(image_filename.c_str()));
8253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (input_image.get() == nullptr) {
8353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    LOG(ERROR) << "unable to open input image file.";
8453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
8553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
8653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  int64_t image_len = input_image->GetLength();
8753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (image_len < 0) {
8853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    LOG(ERROR) << "Error while getting image length";
8953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
9053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
9153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  ImageHeader image_header;
9253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (sizeof(image_header) != input_image->Read(reinterpret_cast<char*>(&image_header),
9353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light                                              sizeof(image_header), 0)) {
9453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    LOG(ERROR) << "Unable to read image header from image file " << input_image->GetPath();
9553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
9653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
9753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
9853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  // Set up the runtime
99e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers  RuntimeOptions options;
10053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  NoopCompilerCallbacks callbacks;
10153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  options.push_back(std::make_pair("compilercallbacks", &callbacks));
10253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  std::string img = "-Ximage:" + image_location;
10353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  options.push_back(std::make_pair(img.c_str(), nullptr));
10453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  options.push_back(std::make_pair("imageinstructionset", reinterpret_cast<const void*>(isa_name)));
10553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (!Runtime::Create(options, false)) {
10653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    LOG(ERROR) << "Unable to initialize runtime";
10753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
10853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
10953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  // Runtime::Create acquired the mutator_lock_ that is normally given away when we Runtime::Start,
11053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  // give it away now and then switch to a more manageable ScopedObjectAccess.
11153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  Thread::Current()->TransitionFromRunnableToSuspended(kNative);
11253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  ScopedObjectAccess soa(Thread::Current());
11353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
11453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  t.NewTiming("Image and oat Patching setup");
11553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  // Create the map where we will write the image patches to.
116eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light  std::string error_msg;
11753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  std::unique_ptr<MemMap> image(MemMap::MapFile(image_len, PROT_READ | PROT_WRITE, MAP_PRIVATE,
11853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light                                                input_image->Fd(), 0,
11953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light                                                input_image->GetPath().c_str(),
12053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light                                                &error_msg));
12153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (image.get() == nullptr) {
12253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    LOG(ERROR) << "unable to map image file " << input_image->GetPath() << " : " << error_msg;
12353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
12453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
12553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  gc::space::ImageSpace* ispc = Runtime::Current()->GetHeap()->GetImageSpace();
12653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
12753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  PatchOat p(image.release(), ispc->GetLiveBitmap(), ispc->GetMemMap(),
12853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light             delta, timings);
12953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  t.NewTiming("Patching files");
13053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (!p.PatchImage()) {
131a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    LOG(ERROR) << "Failed to patch image file " << input_image->GetPath();
13253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
13353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
13453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
13553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  t.NewTiming("Writing files");
13653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (!p.WriteImage(output_image)) {
13753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
13853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
13953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  return true;
14053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}
14153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
14253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Lightbool PatchOat::Patch(const File* input_oat, const std::string& image_location, off_t delta,
14353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light                     File* output_oat, File* output_image, InstructionSet isa,
144eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light                     TimingLogger* timings) {
14553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK(Runtime::Current() == nullptr);
14653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK(output_image != nullptr);
14753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK_GE(output_image->Fd(), 0);
14853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK(input_oat != nullptr);
14953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK(output_oat != nullptr);
15053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK_GE(input_oat->Fd(), 0);
15153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK_GE(output_oat->Fd(), 0);
15253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK(!image_location.empty()) << "image file must have a filename.";
15353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
154eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light  TimingLogger::ScopedTiming t("Runtime Setup", timings);
15553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
15653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (isa == kNone) {
15753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    Elf32_Ehdr elf_hdr;
15853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    if (sizeof(elf_hdr) != input_oat->Read(reinterpret_cast<char*>(&elf_hdr), sizeof(elf_hdr), 0)) {
15953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      LOG(ERROR) << "unable to read elf header";
16053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      return false;
16153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    }
16253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    isa = ElfISAToInstructionSet(elf_hdr.e_machine);
16353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
16453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  const char* isa_name = GetInstructionSetString(isa);
16553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  std::string image_filename(GetSystemImageFilename(image_location.c_str(), isa));
16653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  std::unique_ptr<File> input_image(OS::OpenFileForReading(image_filename.c_str()));
16753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (input_image.get() == nullptr) {
16853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    LOG(ERROR) << "unable to open input image file.";
16953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
17053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
17153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  int64_t image_len = input_image->GetLength();
17253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (image_len < 0) {
17353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    LOG(ERROR) << "Error while getting image length";
17453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
17553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
17653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  ImageHeader image_header;
17753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (sizeof(image_header) != input_image->Read(reinterpret_cast<char*>(&image_header),
17853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light                                              sizeof(image_header), 0)) {
17953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    LOG(ERROR) << "Unable to read image header from image file " << input_image->GetPath();
18053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
18153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
18253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  // Set up the runtime
183e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers  RuntimeOptions options;
18453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  NoopCompilerCallbacks callbacks;
18553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  options.push_back(std::make_pair("compilercallbacks", &callbacks));
18653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  std::string img = "-Ximage:" + image_location;
18753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  options.push_back(std::make_pair(img.c_str(), nullptr));
18853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  options.push_back(std::make_pair("imageinstructionset", reinterpret_cast<const void*>(isa_name)));
18953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (!Runtime::Create(options, false)) {
19053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    LOG(ERROR) << "Unable to initialize runtime";
19153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
19253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
19353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  // Runtime::Create acquired the mutator_lock_ that is normally given away when we Runtime::Start,
19453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  // give it away now and then switch to a more manageable ScopedObjectAccess.
19553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  Thread::Current()->TransitionFromRunnableToSuspended(kNative);
19653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  ScopedObjectAccess soa(Thread::Current());
19753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
19853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  t.NewTiming("Image and oat Patching setup");
19953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  // Create the map where we will write the image patches to.
200eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light  std::string error_msg;
20153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  std::unique_ptr<MemMap> image(MemMap::MapFile(image_len, PROT_READ | PROT_WRITE, MAP_PRIVATE,
20253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light                                                input_image->Fd(), 0,
20353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light                                                input_image->GetPath().c_str(),
20453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light                                                &error_msg));
20553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (image.get() == nullptr) {
20653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    LOG(ERROR) << "unable to map image file " << input_image->GetPath() << " : " << error_msg;
20753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
20853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
20953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  gc::space::ImageSpace* ispc = Runtime::Current()->GetHeap()->GetImageSpace();
21053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
21153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  std::unique_ptr<ElfFile> elf(ElfFile::Open(const_cast<File*>(input_oat),
21253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light                                             PROT_READ | PROT_WRITE, MAP_PRIVATE, &error_msg));
21353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (elf.get() == nullptr) {
21453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    LOG(ERROR) << "unable to open oat file " << input_oat->GetPath() << " : " << error_msg;
21553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
21653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
21753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
21853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  PatchOat p(elf.release(), image.release(), ispc->GetLiveBitmap(), ispc->GetMemMap(),
21953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light             delta, timings);
22053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  t.NewTiming("Patching files");
22153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (!p.PatchElf()) {
222a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    LOG(ERROR) << "Failed to patch oat file " << input_oat->GetPath();
22353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
22453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
22553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (!p.PatchImage()) {
226a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    LOG(ERROR) << "Failed to patch image file " << input_image->GetPath();
22753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
22853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
22953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
23053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  t.NewTiming("Writing files");
23153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (!p.WriteElf(output_oat)) {
23253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
23353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
23453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (!p.WriteImage(output_image)) {
23553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
23653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
23753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  return true;
23853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}
23953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
24053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Lightbool PatchOat::WriteElf(File* out) {
241eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light  TimingLogger::ScopedTiming t("Writing Elf File", timings_);
242a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  std::string error_msg;
243a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light
244a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  // Lock the output file.
245a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  ScopedFlock flock;
246a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  flock.Init(out, &error_msg);
247a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light
24853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK(oat_file_.get() != nullptr);
24953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK(out != nullptr);
25053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  size_t expect = oat_file_->Size();
25153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (out->WriteFully(reinterpret_cast<char*>(oat_file_->Begin()), expect) &&
25253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      out->SetLength(expect) == 0) {
25353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return true;
25453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  } else {
25553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    LOG(ERROR) << "Writing to oat file " << out->GetPath() << " failed.";
25653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
25753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
25853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}
25953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
26053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Lightbool PatchOat::WriteImage(File* out) {
261eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light  TimingLogger::ScopedTiming t("Writing image File", timings_);
262a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  std::string error_msg;
263a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light
264a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  // Lock the output file.
265a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  ScopedFlock flock;
266a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  flock.Init(out, &error_msg);
267a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light
26853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK(image_ != nullptr);
26953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK(out != nullptr);
27053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  size_t expect = image_->Size();
27153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (out->WriteFully(reinterpret_cast<char*>(image_->Begin()), expect) &&
27253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      out->SetLength(expect) == 0) {
27353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return true;
27453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  } else {
27553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    LOG(ERROR) << "Writing to image file " << out->GetPath() << " failed.";
27653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
27753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
27853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}
27953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
28053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Lightbool PatchOat::PatchImage() {
28153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  ImageHeader* image_header = reinterpret_cast<ImageHeader*>(image_->Begin());
28253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK_GT(image_->Size(), sizeof(ImageHeader));
28353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  // These are the roots from the original file.
28453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  mirror::Object* img_roots = image_header->GetImageRoots();
28553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  image_header->RelocateImage(delta_);
28653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
28753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  VisitObject(img_roots);
28853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (!image_header->IsValid()) {
28953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    LOG(ERROR) << "reloction renders image header invalid";
29053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
29153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
29253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
29353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  {
294eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light    TimingLogger::ScopedTiming t("Walk Bitmap", timings_);
29553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    // Walk the bitmap.
29653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    WriterMutexLock mu(Thread::Current(), *Locks::heap_bitmap_lock_);
29753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    bitmap_->Walk(PatchOat::BitmapCallback, this);
29853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
29953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  return true;
30053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}
30153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
30253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Lightbool PatchOat::InHeap(mirror::Object* o) {
30353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  uintptr_t begin = reinterpret_cast<uintptr_t>(heap_->Begin());
30453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  uintptr_t end = reinterpret_cast<uintptr_t>(heap_->End());
30553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  uintptr_t obj = reinterpret_cast<uintptr_t>(o);
30653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  return o == nullptr || (begin <= obj && obj < end);
30753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}
30853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
30953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Lightvoid PatchOat::PatchVisitor::operator() (mirror::Object* obj, MemberOffset off,
31053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light                                         bool is_static_unused) const {
31153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  mirror::Object* referent = obj->GetFieldObject<mirror::Object, kVerifyNone>(off);
31253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  DCHECK(patcher_->InHeap(referent)) << "Referent is not in the heap.";
31353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  mirror::Object* moved_object = patcher_->RelocatedAddressOf(referent);
31453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  copy_->SetFieldObjectWithoutWriteBarrier<false, true, kVerifyNone>(off, moved_object);
31553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}
31653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
31753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Lightvoid PatchOat::PatchVisitor::operator() (mirror::Class* cls, mirror::Reference* ref) const {
31853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  MemberOffset off = mirror::Reference::ReferentOffset();
31953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  mirror::Object* referent = ref->GetReferent();
32053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  DCHECK(patcher_->InHeap(referent)) << "Referent is not in the heap.";
32153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  mirror::Object* moved_object = patcher_->RelocatedAddressOf(referent);
32253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  copy_->SetFieldObjectWithoutWriteBarrier<false, true, kVerifyNone>(off, moved_object);
32353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}
32453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
32553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Lightmirror::Object* PatchOat::RelocatedCopyOf(mirror::Object* obj) {
32653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (obj == nullptr) {
32753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return nullptr;
32853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
32953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  DCHECK_GT(reinterpret_cast<uintptr_t>(obj), reinterpret_cast<uintptr_t>(heap_->Begin()));
33053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  DCHECK_LT(reinterpret_cast<uintptr_t>(obj), reinterpret_cast<uintptr_t>(heap_->End()));
33153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  uintptr_t heap_off =
33253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      reinterpret_cast<uintptr_t>(obj) - reinterpret_cast<uintptr_t>(heap_->Begin());
33353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  DCHECK_LT(heap_off, image_->Size());
33453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  return reinterpret_cast<mirror::Object*>(image_->Begin() + heap_off);
33553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}
33653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
33753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Lightmirror::Object* PatchOat::RelocatedAddressOf(mirror::Object* obj) {
33853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (obj == nullptr) {
33953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return nullptr;
34053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  } else {
34153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return reinterpret_cast<mirror::Object*>(reinterpret_cast<byte*>(obj) + delta_);
34253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
34353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}
34453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
34553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light// Called by BitmapCallback
34653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Lightvoid PatchOat::VisitObject(mirror::Object* object) {
34753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  mirror::Object* copy = RelocatedCopyOf(object);
34853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK(copy != nullptr);
34953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (kUseBakerOrBrooksReadBarrier) {
35053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    object->AssertReadBarrierPointer();
35153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    if (kUseBrooksReadBarrier) {
35253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      mirror::Object* moved_to = RelocatedAddressOf(object);
35353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      copy->SetReadBarrierPointer(moved_to);
35453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      DCHECK_EQ(copy->GetReadBarrierPointer(), moved_to);
35553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    }
35653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
35753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  PatchOat::PatchVisitor visitor(this, copy);
35853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  object->VisitReferences<true, kVerifyNone>(visitor, visitor);
35953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (object->IsArtMethod<kVerifyNone>()) {
36053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    FixupMethod(static_cast<mirror::ArtMethod*>(object),
36153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light                static_cast<mirror::ArtMethod*>(copy));
36253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
36353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}
36453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
36553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Lightvoid PatchOat::FixupMethod(mirror::ArtMethod* object, mirror::ArtMethod* copy) {
36653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  // Just update the entry points if it looks like we should.
367eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light  // TODO: sanity check all the pointers' values
36853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  uintptr_t portable = reinterpret_cast<uintptr_t>(
36953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      object->GetEntryPointFromPortableCompiledCode<kVerifyNone>());
37053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (portable != 0) {
37153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    copy->SetEntryPointFromPortableCompiledCode(reinterpret_cast<void*>(portable + delta_));
37253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
37353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  uintptr_t quick= reinterpret_cast<uintptr_t>(
37453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      object->GetEntryPointFromQuickCompiledCode<kVerifyNone>());
37553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (quick != 0) {
37653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    copy->SetEntryPointFromQuickCompiledCode(reinterpret_cast<void*>(quick + delta_));
37753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
37853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  uintptr_t interpreter = reinterpret_cast<uintptr_t>(
37953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      object->GetEntryPointFromInterpreter<kVerifyNone>());
38053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (interpreter != 0) {
38153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    copy->SetEntryPointFromInterpreter(
38253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        reinterpret_cast<mirror::EntryPointFromInterpreter*>(interpreter + delta_));
38353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
38453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
38553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  uintptr_t native_method = reinterpret_cast<uintptr_t>(object->GetNativeMethod());
38653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (native_method != 0) {
38753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    copy->SetNativeMethod(reinterpret_cast<void*>(native_method + delta_));
38853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
38953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
39053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  uintptr_t native_gc_map = reinterpret_cast<uintptr_t>(object->GetNativeGcMap());
39153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (native_gc_map != 0) {
39253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    copy->SetNativeGcMap(reinterpret_cast<uint8_t*>(native_gc_map + delta_));
39353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
39453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}
39553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
396eefbe39799126afdf7d315a79359b9da23d1cef5Alex Lightbool PatchOat::Patch(File* input_oat, off_t delta, File* output_oat, TimingLogger* timings) {
39753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK(input_oat != nullptr);
39853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK(output_oat != nullptr);
39953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK_GE(input_oat->Fd(), 0);
40053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK_GE(output_oat->Fd(), 0);
401eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light  TimingLogger::ScopedTiming t("Setup Oat File Patching", timings);
40253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
40353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  std::string error_msg;
40453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  std::unique_ptr<ElfFile> elf(ElfFile::Open(const_cast<File*>(input_oat),
40553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light                                             PROT_READ | PROT_WRITE, MAP_PRIVATE, &error_msg));
40653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (elf.get() == nullptr) {
40753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    LOG(ERROR) << "unable to open oat file " << input_oat->GetPath() << " : " << error_msg;
40853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
40953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
41053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
41153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  PatchOat p(elf.release(), delta, timings);
41253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  t.NewTiming("Patch Oat file");
41353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (!p.PatchElf()) {
41453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
41553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
41653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
41753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  t.NewTiming("Writing oat file");
41853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (!p.WriteElf(output_oat)) {
41953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
42053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
42153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  return true;
42253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}
42353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
42453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Lightbool PatchOat::CheckOatFile() {
42553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  Elf32_Shdr* patches_sec = oat_file_->FindSectionByName(".oat_patches");
42653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (patches_sec == nullptr) {
42753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
42853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
42953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (patches_sec->sh_type != SHT_OAT_PATCH) {
43053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
43153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
43253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  uintptr_t* patches = reinterpret_cast<uintptr_t*>(oat_file_->Begin() + patches_sec->sh_offset);
43353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  uintptr_t* patches_end = patches + (patches_sec->sh_size/sizeof(uintptr_t));
43453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  Elf32_Shdr* oat_data_sec = oat_file_->FindSectionByName(".rodata");
43553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  Elf32_Shdr* oat_text_sec = oat_file_->FindSectionByName(".text");
43653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (oat_data_sec == nullptr) {
43753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
43853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
43953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (oat_text_sec == nullptr) {
44053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
44153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
44253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (oat_text_sec->sh_offset <= oat_data_sec->sh_offset) {
44353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
44453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
44553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
44653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  for (; patches < patches_end; patches++) {
44753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    if (oat_text_sec->sh_size <= *patches) {
44853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      return false;
44953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    }
45053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
45153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
45253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  return true;
45353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}
45453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
455a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Lightbool PatchOat::PatchOatHeader() {
456a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  Elf32_Shdr *rodata_sec = oat_file_->FindSectionByName(".rodata");
457a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  if (rodata_sec == nullptr) {
458a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    return false;
459a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  }
460a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  OatHeader* oat_header = reinterpret_cast<OatHeader*>(oat_file_->Begin() + rodata_sec->sh_offset);
461a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  if (!oat_header->IsValid()) {
462a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    LOG(ERROR) << "Elf file " << oat_file_->GetFile().GetPath() << " has an invalid oat header";
463a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    return false;
464a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  }
465a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  oat_header->RelocateOat(delta_);
466a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  return true;
467a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light}
468a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light
46953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Lightbool PatchOat::PatchElf() {
470a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  TimingLogger::ScopedTiming t("Fixup Elf Text Section", timings_);
471a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  if (!PatchTextSection()) {
472a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    return false;
473a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  }
474a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light
475a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  if (!PatchOatHeader()) {
476a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    return false;
477a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  }
478a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light
479a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  bool need_fixup = false;
480a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  t.NewTiming("Fixup Elf Headers");
48153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  // Fixup Phdr's
48253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  for (unsigned int i = 0; i < oat_file_->GetProgramHeaderNum(); i++) {
48353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    Elf32_Phdr& hdr = oat_file_->GetProgramHeader(i);
484a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    if (hdr.p_vaddr != 0 && hdr.p_vaddr != hdr.p_offset) {
485a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light      need_fixup = true;
48653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      hdr.p_vaddr += delta_;
48753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    }
488a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    if (hdr.p_paddr != 0 && hdr.p_paddr != hdr.p_offset) {
489a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light      need_fixup = true;
49053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      hdr.p_paddr += delta_;
49153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    }
49253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
493a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  if (!need_fixup) {
494a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    // This was never passed through ElfFixup so all headers/symbols just have their offset as
495a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    // their addr. Therefore we do not need to update these parts.
496a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    return true;
497a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  }
498a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  t.NewTiming("Fixup Section Headers");
49953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  for (unsigned int i = 0; i < oat_file_->GetSectionHeaderNum(); i++) {
50053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    Elf32_Shdr& hdr = oat_file_->GetSectionHeader(i);
50153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    if (hdr.sh_addr != 0) {
50253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      hdr.sh_addr += delta_;
50353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    }
50453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
50553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
506a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  t.NewTiming("Fixup Dynamics");
50753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  for (Elf32_Word i = 0; i < oat_file_->GetDynamicNum(); i++) {
50853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    Elf32_Dyn& dyn = oat_file_->GetDynamic(i);
50953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    if (IsDynamicSectionPointer(dyn.d_tag, oat_file_->GetHeader().e_machine)) {
51053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      dyn.d_un.d_ptr += delta_;
51153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    }
51253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
51353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
51453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  t.NewTiming("Fixup Elf Symbols");
51553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  // Fixup dynsym
51653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  Elf32_Shdr* dynsym_sec = oat_file_->FindSectionByName(".dynsym");
51753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK(dynsym_sec != nullptr);
51853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (!PatchSymbols(dynsym_sec)) {
51953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
52053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
52153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
52253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  // Fixup symtab
52353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  Elf32_Shdr* symtab_sec = oat_file_->FindSectionByName(".symtab");
52453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (symtab_sec != nullptr) {
52553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    if (!PatchSymbols(symtab_sec)) {
52653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      return false;
52753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    }
52853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
52953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
53053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  return true;
53153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}
53253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
53353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Lightbool PatchOat::PatchSymbols(Elf32_Shdr* section) {
53453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  Elf32_Sym* syms = reinterpret_cast<Elf32_Sym*>(oat_file_->Begin() + section->sh_offset);
53553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  const Elf32_Sym* last_sym =
53653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      reinterpret_cast<Elf32_Sym*>(oat_file_->Begin() + section->sh_offset + section->sh_size);
53753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK_EQ(section->sh_size % sizeof(Elf32_Sym), 0u)
53853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      << "Symtab section size is not multiple of symbol size";
53953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  for (; syms < last_sym; syms++) {
54053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    uint8_t sttype = ELF32_ST_TYPE(syms->st_info);
54153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    Elf32_Word shndx = syms->st_shndx;
54253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    if (shndx != SHN_ABS && shndx != SHN_COMMON && shndx != SHN_UNDEF &&
54353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        (sttype == STT_FUNC || sttype == STT_OBJECT)) {
54453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      CHECK_NE(syms->st_value, 0u);
54553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      syms->st_value += delta_;
54653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    }
54753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
54853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  return true;
54953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}
55053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
55153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Lightbool PatchOat::PatchTextSection() {
55253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  Elf32_Shdr* patches_sec = oat_file_->FindSectionByName(".oat_patches");
55353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (patches_sec == nullptr) {
554a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    LOG(ERROR) << ".oat_patches section not found. Aborting patch";
55553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
55653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
55753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  DCHECK(CheckOatFile()) << "Oat file invalid";
55853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK_EQ(patches_sec->sh_type, SHT_OAT_PATCH) << "Unexpected type of .oat_patches";
55953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  uintptr_t* patches = reinterpret_cast<uintptr_t*>(oat_file_->Begin() + patches_sec->sh_offset);
56053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  uintptr_t* patches_end = patches + (patches_sec->sh_size/sizeof(uintptr_t));
56153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  Elf32_Shdr* oat_text_sec = oat_file_->FindSectionByName(".text");
56253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK(oat_text_sec != nullptr);
56353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  byte* to_patch = oat_file_->Begin() + oat_text_sec->sh_offset;
56453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  uintptr_t to_patch_end = reinterpret_cast<uintptr_t>(to_patch) + oat_text_sec->sh_size;
56553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
56653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  for (; patches < patches_end; patches++) {
56753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    CHECK_LT(*patches, oat_text_sec->sh_size) << "Bad Patch";
56853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    uint32_t* patch_loc = reinterpret_cast<uint32_t*>(to_patch + *patches);
56953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    CHECK_LT(reinterpret_cast<uintptr_t>(patch_loc), to_patch_end);
57053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    *patch_loc += delta_;
57153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
57253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
57353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  return true;
57453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}
57553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
57653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Lightstatic int orig_argc;
57753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Lightstatic char** orig_argv;
57853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
57953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Lightstatic std::string CommandLine() {
58053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  std::vector<std::string> command;
58153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  for (int i = 0; i < orig_argc; ++i) {
58253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    command.push_back(orig_argv[i]);
58353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
58453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  return Join(command, ' ');
58553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}
58653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
58753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Lightstatic void UsageErrorV(const char* fmt, va_list ap) {
58853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  std::string error;
58953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  StringAppendV(&error, fmt, ap);
59053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  LOG(ERROR) << error;
59153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}
59253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
59353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Lightstatic void UsageError(const char* fmt, ...) {
59453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  va_list ap;
59553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  va_start(ap, fmt);
59653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageErrorV(fmt, ap);
59753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  va_end(ap);
59853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}
59953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
60053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Lightstatic void Usage(const char *fmt, ...) {
60153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  va_list ap;
60253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  va_start(ap, fmt);
60353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageErrorV(fmt, ap);
60453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  va_end(ap);
60553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
60653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("Command: %s", CommandLine().c_str());
60753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("Usage: patchoat [options]...");
60853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("");
60953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("  --instruction-set=<isa>: Specifies the instruction set the patched code is");
61053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("      compiled for. Required if you use --input-oat-location");
61153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("");
61253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("  --input-oat-file=<file.oat>: Specifies the exact filename of the oat file to be");
61353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("      patched.");
61453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("");
61553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("  --input-oat-fd=<file-descriptor>: Specifies the file-descriptor of the oat file");
61653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("      to be patched.");
61753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("");
61853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("  --input-oat-location=<file.oat>: Specifies the 'location' to read the patched");
61953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("      oat file from. If used one must also supply the --instruction-set");
62053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("");
62153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("  --input-image-location=<file.art>: Specifies the 'location' of the image file to");
62253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("      be patched. If --instruction-set is not given it will use the instruction set");
62353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("      extracted from the --input-oat-file.");
62453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("");
62553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("  --output-oat-file=<file.oat>: Specifies the exact file to write the patched oat");
62653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("      file to.");
62753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("");
62853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("  --output-oat-location=<file.oat>: Specifies the 'location' to write the patched");
62953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("      oat file to. If used one must also specify the --instruction-set");
63053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("");
63153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("  --output-oat-fd=<file-descriptor>: Specifies the file-descriptor to write the");
63253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("      the patched oat file to.");
63353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("");
63453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("  --output-image-file=<file.art>: Specifies the exact file to write the patched");
63553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("      image file to.");
63653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("");
63753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("  --output-image-fd=<file-descriptor>: Specifies the file-descriptor to write the");
63853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("      the patched image file to.");
63953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("");
64053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("  --output-image-location=<file.art>: Specifies the 'location' to write the patched");
64153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("      image file to. If used one must also specify the --instruction-set");
64253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("");
64353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("  --orig-base-offset=<original-base-offset>: Specify the base offset the input file");
64453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("      was compiled with. This is needed if one is specifying a --base-offset");
64553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("");
64653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("  --base-offset=<new-base-offset>: Specify the base offset we will repatch the");
64753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("      given files to use. This requires that --orig-base-offset is also given.");
64853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("");
64953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("  --base-offset-delta=<delta>: Specify the amount to change the old base-offset by.");
65053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("      This value may be negative.");
65153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("");
65253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("  --patched-image-file=<file.art>: Use the same patch delta as was used to patch");
65353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("      the given image file.");
65453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("");
65553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("  --patched-image-location=<file.art>: Use the same patch delta as was used to");
65653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("      patch the given image location. If used one must also specify the");
657a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  UsageError("      --instruction-set flag. It will search for this image in the same way that");
658a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  UsageError("      is done when loading one.");
65953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("");
66053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("  --dump-timings: dump out patch timing information");
66153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("");
66253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("  --no-dump-timings: do not dump out patch timing information");
66353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("");
66453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
66553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  exit(EXIT_FAILURE);
66653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}
66753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
668eefbe39799126afdf7d315a79359b9da23d1cef5Alex Lightstatic bool ReadBaseDelta(const char* name, off_t* delta, std::string* error_msg) {
66953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK(name != nullptr);
67053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK(delta != nullptr);
67153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  std::unique_ptr<File> file;
67253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (OS::FileExists(name)) {
67353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    file.reset(OS::OpenFileForReading(name));
67453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    if (file.get() == nullptr) {
675eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light      *error_msg = "Failed to open file %s for reading";
67653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      return false;
67753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    }
67853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  } else {
679eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light    *error_msg = "File %s does not exist";
68053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
68153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
68253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK(file.get() != nullptr);
68353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  ImageHeader hdr;
68453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (sizeof(hdr) != file->Read(reinterpret_cast<char*>(&hdr), sizeof(hdr), 0)) {
685eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light    *error_msg = "Failed to read file %s";
68653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
68753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
68853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (!hdr.IsValid()) {
689eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light    *error_msg = "%s does not contain a valid image header.";
69053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
69153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
69253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  *delta = hdr.GetPatchDelta();
69353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  return true;
69453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}
69553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
69653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Lightstatic File* CreateOrOpen(const char* name, bool* created) {
69753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (OS::FileExists(name)) {
69853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    *created = false;
69953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return OS::OpenFileReadWrite(name);
70053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  } else {
70153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    *created = true;
70253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return OS::CreateEmptyFile(name);
70353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
70453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}
70553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
706eefbe39799126afdf7d315a79359b9da23d1cef5Alex Lightstatic int patchoat(int argc, char **argv) {
70753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  InitLogging(argv);
70853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  const bool debug = kIsDebugBuild;
70953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  orig_argc = argc;
71053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  orig_argv = argv;
71153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  TimingLogger timings("patcher", false, false);
71253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
71353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  InitLogging(argv);
71453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
71553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  // Skip over the command name.
71653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  argv++;
71753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  argc--;
71853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
71953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (argc == 0) {
72053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    Usage("No arguments specified");
72153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
72253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
72353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  timings.StartTiming("Patchoat");
72453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
72553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  // cmd line args
72653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  bool isa_set = false;
72753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  InstructionSet isa = kNone;
72853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  std::string input_oat_filename;
72953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  std::string input_oat_location;
73053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  int input_oat_fd = -1;
73153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  bool have_input_oat = false;
73253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  std::string input_image_location;
73353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  std::string output_oat_filename;
73453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  std::string output_oat_location;
73553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  int output_oat_fd = -1;
73653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  bool have_output_oat = false;
73753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  std::string output_image_filename;
73853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  std::string output_image_location;
73953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  int output_image_fd = -1;
74053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  bool have_output_image = false;
74153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  uintptr_t base_offset = 0;
74253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  bool base_offset_set = false;
74353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  uintptr_t orig_base_offset = 0;
74453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  bool orig_base_offset_set = false;
74553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  off_t base_delta = 0;
74653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  bool base_delta_set = false;
74753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  std::string patched_image_filename;
74853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  std::string patched_image_location;
74953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  bool dump_timings = kIsDebugBuild;
75053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
75153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  for (int i = 0; i < argc; i++) {
75253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    const StringPiece option(argv[i]);
75353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    const bool log_options = false;
75453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    if (log_options) {
75553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      LOG(INFO) << "patchoat: option[" << i << "]=" << argv[i];
75653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    }
757eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light    // TODO: GetInstructionSetFromString shouldn't LOG(FATAL).
75853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    if (option.starts_with("--instruction-set=")) {
75953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      isa_set = true;
76053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      const char* isa_str = option.substr(strlen("--instruction-set=")).data();
76153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      if (!strcmp("arm", isa_str)) {
76253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        isa = kArm;
76353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      } else if (!strcmp("arm64", isa_str)) {
76453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        isa = kArm64;
76553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      } else if (!strcmp("x86", isa_str)) {
76653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        isa = kX86;
76753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      } else if (!strcmp("x86_64", isa_str)) {
76853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        isa = kX86_64;
76953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      } else if (!strcmp("mips", isa_str)) {
77053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        isa = kMips;
77153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      } else {
77253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        Usage("Unknown instruction set %s", isa_str);
77353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      }
77453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    } else if (option.starts_with("--input-oat-location=")) {
77553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      if (have_input_oat) {
77653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        Usage("Only one of --input-oat-file, --input-oat-location and --input-oat-fd may be used.");
77753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      }
77853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      have_input_oat = true;
77953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      input_oat_location = option.substr(strlen("--input-oat-location=")).data();
78053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    } else if (option.starts_with("--input-oat-file=")) {
78153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      if (have_input_oat) {
78253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        Usage("Only one of --input-oat-file, --input-oat-location and --input-oat-fd may be used.");
78353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      }
78453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      have_input_oat = true;
78553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      input_oat_filename = option.substr(strlen("--input-oat-file=")).data();
78653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    } else if (option.starts_with("--input-oat-fd=")) {
78753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      if (have_input_oat) {
78853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        Usage("Only one of --input-oat-file, --input-oat-location and --input-oat-fd may be used.");
78953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      }
79053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      have_input_oat = true;
79153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      const char* oat_fd_str = option.substr(strlen("--input-oat-fd=")).data();
79253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      if (!ParseInt(oat_fd_str, &input_oat_fd)) {
79353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        Usage("Failed to parse --input-oat-fd argument '%s' as an integer", oat_fd_str);
79453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      }
79553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      if (input_oat_fd < 0) {
79653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        Usage("--input-oat-fd pass a negative value %d", input_oat_fd);
79753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      }
79853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    } else if (option.starts_with("--input-image-location=")) {
79953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      input_image_location = option.substr(strlen("--input-image-location=")).data();
80053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    } else if (option.starts_with("--output-oat-location=")) {
80153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      if (have_output_oat) {
80253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        Usage("Only one of --output-oat-file, --output-oat-location and --output-oat-fd may "
80353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light              "be used.");
80453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      }
80553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      have_output_oat = true;
80653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      output_oat_location = option.substr(strlen("--output-oat-location=")).data();
80753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    } else if (option.starts_with("--output-oat-file=")) {
80853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      if (have_output_oat) {
80953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        Usage("Only one of --output-oat-file, --output-oat-location and --output-oat-fd may "
81053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light              "be used.");
81153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      }
81253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      have_output_oat = true;
81353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      output_oat_filename = option.substr(strlen("--output-oat-file=")).data();
81453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    } else if (option.starts_with("--output-oat-fd=")) {
81553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      if (have_output_oat) {
81653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        Usage("Only one of --output-oat-file, --output-oat-location and --output-oat-fd may "
81753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light              "be used.");
81853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      }
81953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      have_output_oat = true;
82053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      const char* oat_fd_str = option.substr(strlen("--output-oat-fd=")).data();
82153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      if (!ParseInt(oat_fd_str, &output_oat_fd)) {
82253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        Usage("Failed to parse --output-oat-fd argument '%s' as an integer", oat_fd_str);
82353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      }
82453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      if (output_oat_fd < 0) {
82553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        Usage("--output-oat-fd pass a negative value %d", output_oat_fd);
82653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      }
82753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    } else if (option.starts_with("--output-image-location=")) {
82853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      if (have_output_image) {
82953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        Usage("Only one of --output-image-file, --output-image-location and --output-image-fd may "
83053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light              "be used.");
83153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      }
83253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      have_output_image = true;
83353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      output_image_location= option.substr(strlen("--output-image-location=")).data();
83453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    } else if (option.starts_with("--output-image-file=")) {
83553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      if (have_output_image) {
83653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        Usage("Only one of --output-image-file, --output-image-location and --output-image-fd may "
83753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light              "be used.");
83853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      }
83953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      have_output_image = true;
84053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      output_image_filename = option.substr(strlen("--output-image-file=")).data();
84153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    } else if (option.starts_with("--output-image-fd=")) {
84253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      if (have_output_image) {
84353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        Usage("Only one of --output-image-file, --output-image-location and --output-image-fd "
84453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light              "may be used.");
84553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      }
84653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      have_output_image = true;
84753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      const char* image_fd_str = option.substr(strlen("--output-image-fd=")).data();
84853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      if (!ParseInt(image_fd_str, &output_image_fd)) {
84953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        Usage("Failed to parse --output-image-fd argument '%s' as an integer", image_fd_str);
85053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      }
85153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      if (output_image_fd < 0) {
85253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        Usage("--output-image-fd pass a negative value %d", output_image_fd);
85353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      }
85453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    } else if (option.starts_with("--orig-base-offset=")) {
85553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      const char* orig_base_offset_str = option.substr(strlen("--orig-base-offset=")).data();
85653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      orig_base_offset_set = true;
85753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      if (!ParseUint(orig_base_offset_str, &orig_base_offset)) {
85853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        Usage("Failed to parse --orig-base-offset argument '%s' as an uintptr_t",
85953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light              orig_base_offset_str);
86053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      }
86153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    } else if (option.starts_with("--base-offset=")) {
86253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      const char* base_offset_str = option.substr(strlen("--base-offset=")).data();
86353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      base_offset_set = true;
86453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      if (!ParseUint(base_offset_str, &base_offset)) {
86553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        Usage("Failed to parse --base-offset argument '%s' as an uintptr_t", base_offset_str);
86653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      }
86753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    } else if (option.starts_with("--base-offset-delta=")) {
86853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      const char* base_delta_str = option.substr(strlen("--base-offset-delta=")).data();
86953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      base_delta_set = true;
87053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      if (!ParseInt(base_delta_str, &base_delta)) {
87153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        Usage("Failed to parse --base-offset-delta argument '%s' as an off_t", base_delta_str);
87253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      }
87353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    } else if (option.starts_with("--patched-image-location=")) {
87453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      patched_image_location = option.substr(strlen("--patched-image-location=")).data();
87553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    } else if (option.starts_with("--patched-image-file=")) {
87653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      patched_image_filename = option.substr(strlen("--patched-image-file=")).data();
87753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    } else if (option == "--dump-timings") {
87853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      dump_timings = true;
87953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    } else if (option == "--no-dump-timings") {
88053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      dump_timings = false;
88153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    } else {
88253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      Usage("Unknown argument %s", option.data());
88353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    }
88453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
88553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
88653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  {
88753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    // Only 1 of these may be set.
88853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    uint32_t cnt = 0;
88953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    cnt += (base_delta_set) ? 1 : 0;
89053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    cnt += (base_offset_set && orig_base_offset_set) ? 1 : 0;
89153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    cnt += (!patched_image_filename.empty()) ? 1 : 0;
89253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    cnt += (!patched_image_location.empty()) ? 1 : 0;
89353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    if (cnt > 1) {
89453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      Usage("Only one of --base-offset/--orig-base-offset, --base-offset-delta, "
89553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light            "--patched-image-filename or --patched-image-location may be used.");
89653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    } else if (cnt == 0) {
89753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      Usage("Must specify --base-offset-delta, --base-offset and --orig-base-offset, "
89853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light            "--patched-image-location or --patched-image-file");
89953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    }
90053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
90153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
90253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (have_input_oat != have_output_oat) {
90353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    Usage("Either both input and output oat must be supplied or niether must be.");
90453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
90553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
90653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if ((!input_image_location.empty()) != have_output_image) {
90753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    Usage("Either both input and output image must be supplied or niether must be.");
90853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
90953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
91053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  // We know we have both the input and output so rename for clarity.
91153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  bool have_image_files = have_output_image;
91253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  bool have_oat_files = have_output_oat;
91353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
91453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (!have_oat_files && !have_image_files) {
91553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    Usage("Must be patching either an oat or an image file or both.");
91653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
91753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
91853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (!have_oat_files && !isa_set) {
91953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    Usage("Must include ISA if patching an image file without an oat file.");
92053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
92153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
92253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (!input_oat_location.empty()) {
92353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    if (!isa_set) {
92453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      Usage("specifying a location requires specifying an instruction set");
92553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    }
92653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    input_oat_filename = GetSystemImageFilename(input_oat_location.c_str(), isa);
92753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    if (debug) {
92853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      LOG(INFO) << "Using input-oat-file " << input_oat_filename;
92953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    }
93053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
93153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (!output_oat_location.empty()) {
93253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    if (!isa_set) {
93353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      Usage("specifying a location requires specifying an instruction set");
93453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    }
93553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    output_oat_filename = GetSystemImageFilename(output_oat_location.c_str(), isa);
93653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    if (debug) {
93753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      LOG(INFO) << "Using output-oat-file " << output_oat_filename;
93853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    }
93953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
94053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (!output_image_location.empty()) {
94153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    if (!isa_set) {
94253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      Usage("specifying a location requires specifying an instruction set");
94353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    }
94453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    output_image_filename = GetSystemImageFilename(output_image_location.c_str(), isa);
94553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    if (debug) {
94653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      LOG(INFO) << "Using output-image-file " << output_image_filename;
94753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    }
94853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
94953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (!patched_image_location.empty()) {
95053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    if (!isa_set) {
95153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      Usage("specifying a location requires specifying an instruction set");
95253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    }
953a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    std::string system_filename;
954a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    bool has_system = false;
955a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    std::string cache_filename;
956a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    bool has_cache = false;
957a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    bool has_android_data_unused = false;
958a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    if (!gc::space::ImageSpace::FindImageFilename(patched_image_location.c_str(), isa,
959a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light                                                  &system_filename, &has_system, &cache_filename,
960a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light                                                  &has_android_data_unused, &has_cache)) {
961a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light      Usage("Unable to determine image file for location %s", patched_image_location.c_str());
962a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    }
963a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    if (has_cache) {
964a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light      patched_image_filename = cache_filename;
965a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    } else if (has_system) {
966a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light      LOG(WARNING) << "Only image file found was in /system for image location "
967a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light                   << patched_image_location;
968a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light      patched_image_filename = system_filename;
969a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    } else {
970a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light      Usage("Unable to determine image file for location %s", patched_image_location.c_str());
971a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    }
97253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    if (debug) {
97353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      LOG(INFO) << "Using patched-image-file " << patched_image_filename;
97453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    }
97553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
97653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
97753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (!base_delta_set) {
97853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    if (orig_base_offset_set && base_offset_set) {
97953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      base_delta_set = true;
98053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      base_delta = base_offset - orig_base_offset;
98153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    } else if (!patched_image_filename.empty()) {
98253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      base_delta_set = true;
98353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      std::string error_msg;
984eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light      if (!ReadBaseDelta(patched_image_filename.c_str(), &base_delta, &error_msg)) {
98553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        Usage(error_msg.c_str(), patched_image_filename.c_str());
98653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      }
98753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    } else {
98853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      if (base_offset_set) {
98953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        Usage("Unable to determine original base offset.");
99053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      } else {
99153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        Usage("Must supply a desired new offset or delta.");
99253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      }
99353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    }
99453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
99553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
99653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (!IsAligned<kPageSize>(base_delta)) {
99753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    Usage("Base offset/delta must be alligned to a pagesize (0x%08x) boundary.", kPageSize);
99853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
99953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
100053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  // Do we need to cleanup output files if we fail?
100153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  bool new_image_out = false;
100253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  bool new_oat_out = false;
100353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
100453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  std::unique_ptr<File> input_oat;
100553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  std::unique_ptr<File> output_oat;
100653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  std::unique_ptr<File> output_image;
100753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
100853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (have_image_files) {
100953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    CHECK(!input_image_location.empty());
101053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
101153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    if (output_image_fd != -1) {
101253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      output_image.reset(new File(output_image_fd, output_image_filename));
101353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    } else {
101453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      CHECK(!output_image_filename.empty());
101553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      output_image.reset(CreateOrOpen(output_image_filename.c_str(), &new_image_out));
101653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    }
101753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  } else {
101853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    CHECK(output_image_filename.empty() && output_image_fd == -1 && input_image_location.empty());
101953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
102053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
102153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (have_oat_files) {
102253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    if (input_oat_fd != -1) {
102353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      input_oat.reset(new File(input_oat_fd, input_oat_filename));
102453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    } else {
102553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      CHECK(!input_oat_filename.empty());
102653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      input_oat.reset(OS::OpenFileForReading(input_oat_filename.c_str()));
10271c83cbc4a817acbd7f9abb5b29a2d418a958e6a1Andreas Gampe      if (input_oat.get() == nullptr) {
10281c83cbc4a817acbd7f9abb5b29a2d418a958e6a1Andreas Gampe        LOG(ERROR) << "Could not open input oat file: " << strerror(errno);
10291c83cbc4a817acbd7f9abb5b29a2d418a958e6a1Andreas Gampe      }
103053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    }
103153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
103253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    if (output_oat_fd != -1) {
103353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      output_oat.reset(new File(output_oat_fd, output_oat_filename));
1034a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    } else if (output_oat_filename == input_oat_filename) {
1035a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light      // This could be a wierd situation, since we'd be writting from an mmap'd copy of this file.
1036a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light      // Lets just unlink it.
1037a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light      if (0 != unlink(input_oat_filename.c_str())) {
1038a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light        PLOG(ERROR) << "Could not unlink " << input_oat_filename << " to make room for output";
1039a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light        return false;
1040a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light      }
1041a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light      output_oat.reset(OS::CreateEmptyFile(output_oat_filename.c_str()));
104253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    } else {
104353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      CHECK(!output_oat_filename.empty());
104453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      output_oat.reset(CreateOrOpen(output_oat_filename.c_str(), &new_oat_out));
104553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    }
104653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
104753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
104853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  auto cleanup = [&output_image_filename, &output_oat_filename,
104953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light                  &new_oat_out, &new_image_out, &timings, &dump_timings](bool success) {
105053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    timings.EndTiming();
105153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    if (!success) {
105253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      if (new_oat_out) {
105353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        CHECK(!output_oat_filename.empty());
105453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        unlink(output_oat_filename.c_str());
105553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      }
105653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      if (new_image_out) {
105753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        CHECK(!output_image_filename.empty());
105853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        unlink(output_image_filename.c_str());
105953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      }
106053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    }
106153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    if (dump_timings) {
106253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      LOG(INFO) << Dumpable<TimingLogger>(timings);
106353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    }
106453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  };
106553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
106653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (debug) {
1067a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    LOG(INFO) << "moving offset by " << base_delta
1068a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light              << " (0x" << std::hex << base_delta << ") bytes or "
1069a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light              << std::dec << (base_delta/kPageSize) << " pages.";
107053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
107153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
107253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  bool ret;
107353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (have_image_files && have_oat_files) {
107453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    TimingLogger::ScopedTiming pt("patch image and oat", &timings);
107553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    ret = PatchOat::Patch(input_oat.get(), input_image_location, base_delta,
1076eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light                          output_oat.get(), output_image.get(), isa, &timings);
107753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  } else if (have_oat_files) {
107853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    TimingLogger::ScopedTiming pt("patch oat", &timings);
1079eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light    ret = PatchOat::Patch(input_oat.get(), base_delta, output_oat.get(), &timings);
108053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  } else {
108153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    TimingLogger::ScopedTiming pt("patch image", &timings);
108253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    CHECK(have_image_files);
1083eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light    ret = PatchOat::Patch(input_image_location, base_delta, output_image.get(), isa, &timings);
108453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
108553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  cleanup(ret);
1086a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  sync();
108753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  return (ret) ? EXIT_SUCCESS : EXIT_FAILURE;
108853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}
108953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
109053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}  // namespace art
109153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
109253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Lightint main(int argc, char **argv) {
109353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  return art::patchoat(argc, argv);
109453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}
1095