patchoat.cc revision 3c13a794845e0cf7887e33b2ec20de7e6ba85f8f
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
69cf4bf386ef3f527825c70e01130b9276da4f786aAlex Lightstatic bool LocationToFilename(const std::string& location, InstructionSet isa,
70cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light                               std::string* filename) {
71cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light  bool has_system = false;
72cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light  bool has_cache = false;
73cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light  // image_location = /system/framework/boot.art
74cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light  // system_image_location = /system/framework/<image_isa>/boot.art
75cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light  std::string system_filename(GetSystemImageFilename(location.c_str(), isa));
76cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light  if (OS::FileExists(system_filename.c_str())) {
77cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light    has_system = true;
78cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light  }
79cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light
80cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light  bool have_android_data = false;
81cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light  bool dalvik_cache_exists = false;
823c13a794845e0cf7887e33b2ec20de7e6ba85f8fAndreas Gampe  bool is_global_cache = false;
83cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light  std::string dalvik_cache;
84cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light  GetDalvikCache(GetInstructionSetString(isa), false, &dalvik_cache,
853c13a794845e0cf7887e33b2ec20de7e6ba85f8fAndreas Gampe                 &have_android_data, &dalvik_cache_exists, &is_global_cache);
86cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light
87cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light  std::string cache_filename;
88cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light  if (have_android_data && dalvik_cache_exists) {
89cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light    // Always set output location even if it does not exist,
90cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light    // so that the caller knows where to create the image.
91cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light    //
92cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light    // image_location = /system/framework/boot.art
93cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light    // *image_filename = /data/dalvik-cache/<image_isa>/boot.art
94cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light    std::string error_msg;
95cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light    if (GetDalvikCacheFilename(location.c_str(), dalvik_cache.c_str(),
96cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light                               &cache_filename, &error_msg)) {
97cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light      has_cache = true;
98cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light    }
99cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light  }
100cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light  if (has_system) {
101cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light    *filename = system_filename;
102cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light    return true;
103cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light  } else if (has_cache) {
104cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light    *filename = cache_filename;
105cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light    return true;
106cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light  } else {
107cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light    return false;
108cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light  }
109cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light}
110cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light
11153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Lightbool PatchOat::Patch(const std::string& image_location, off_t delta,
11253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light                     File* output_image, InstructionSet isa,
113eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light                     TimingLogger* timings) {
11453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK(Runtime::Current() == nullptr);
11553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK(output_image != nullptr);
11653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK_GE(output_image->Fd(), 0);
11753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK(!image_location.empty()) << "image file must have a filename.";
11853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK_NE(isa, kNone);
11953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
120eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light  TimingLogger::ScopedTiming t("Runtime Setup", timings);
12153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  const char *isa_name = GetInstructionSetString(isa);
122cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light  std::string image_filename;
123cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light  if (!LocationToFilename(image_location, isa, &image_filename)) {
124cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light    LOG(ERROR) << "Unable to find image at location " << image_location;
125cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light    return false;
126cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light  }
12753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  std::unique_ptr<File> input_image(OS::OpenFileForReading(image_filename.c_str()));
12853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (input_image.get() == nullptr) {
129cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light    LOG(ERROR) << "unable to open input image file at " << image_filename
130cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light               << " for location " << image_location;
13153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
13253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
13353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  int64_t image_len = input_image->GetLength();
13453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (image_len < 0) {
13553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    LOG(ERROR) << "Error while getting image length";
13653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
13753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
13853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  ImageHeader image_header;
13953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (sizeof(image_header) != input_image->Read(reinterpret_cast<char*>(&image_header),
14053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light                                              sizeof(image_header), 0)) {
14153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    LOG(ERROR) << "Unable to read image header from image file " << input_image->GetPath();
14253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
14353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
14453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
14553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  // Set up the runtime
146e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers  RuntimeOptions options;
14753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  NoopCompilerCallbacks callbacks;
14853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  options.push_back(std::make_pair("compilercallbacks", &callbacks));
14953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  std::string img = "-Ximage:" + image_location;
15053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  options.push_back(std::make_pair(img.c_str(), nullptr));
15153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  options.push_back(std::make_pair("imageinstructionset", reinterpret_cast<const void*>(isa_name)));
15253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (!Runtime::Create(options, false)) {
15353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    LOG(ERROR) << "Unable to initialize runtime";
15453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
15553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
15653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  // Runtime::Create acquired the mutator_lock_ that is normally given away when we Runtime::Start,
15753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  // give it away now and then switch to a more manageable ScopedObjectAccess.
15853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  Thread::Current()->TransitionFromRunnableToSuspended(kNative);
15953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  ScopedObjectAccess soa(Thread::Current());
16053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
16153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  t.NewTiming("Image and oat Patching setup");
16253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  // Create the map where we will write the image patches to.
163eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light  std::string error_msg;
16453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  std::unique_ptr<MemMap> image(MemMap::MapFile(image_len, PROT_READ | PROT_WRITE, MAP_PRIVATE,
16553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light                                                input_image->Fd(), 0,
16653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light                                                input_image->GetPath().c_str(),
16753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light                                                &error_msg));
16853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (image.get() == nullptr) {
16953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    LOG(ERROR) << "unable to map image file " << input_image->GetPath() << " : " << error_msg;
17053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
17153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
17253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  gc::space::ImageSpace* ispc = Runtime::Current()->GetHeap()->GetImageSpace();
17353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
17453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  PatchOat p(image.release(), ispc->GetLiveBitmap(), ispc->GetMemMap(),
17553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light             delta, timings);
17653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  t.NewTiming("Patching files");
17753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (!p.PatchImage()) {
178a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    LOG(ERROR) << "Failed to patch image file " << input_image->GetPath();
17953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
18053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
18153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
18253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  t.NewTiming("Writing files");
18353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (!p.WriteImage(output_image)) {
18453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
18553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
18653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  return true;
18753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}
18853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
18953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Lightbool PatchOat::Patch(const File* input_oat, const std::string& image_location, off_t delta,
19053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light                     File* output_oat, File* output_image, InstructionSet isa,
191eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light                     TimingLogger* timings) {
19253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK(Runtime::Current() == nullptr);
19353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK(output_image != nullptr);
19453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK_GE(output_image->Fd(), 0);
19553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK(input_oat != nullptr);
19653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK(output_oat != nullptr);
19753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK_GE(input_oat->Fd(), 0);
19853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK_GE(output_oat->Fd(), 0);
19953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK(!image_location.empty()) << "image file must have a filename.";
20053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
201eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light  TimingLogger::ScopedTiming t("Runtime Setup", timings);
20253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
20353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (isa == kNone) {
20453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    Elf32_Ehdr elf_hdr;
20553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    if (sizeof(elf_hdr) != input_oat->Read(reinterpret_cast<char*>(&elf_hdr), sizeof(elf_hdr), 0)) {
20653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      LOG(ERROR) << "unable to read elf header";
20753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      return false;
20853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    }
20953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    isa = ElfISAToInstructionSet(elf_hdr.e_machine);
21053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
21153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  const char* isa_name = GetInstructionSetString(isa);
212cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light  std::string image_filename;
213cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light  if (!LocationToFilename(image_location, isa, &image_filename)) {
214cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light    LOG(ERROR) << "Unable to find image at location " << image_location;
215cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light    return false;
216cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light  }
21753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  std::unique_ptr<File> input_image(OS::OpenFileForReading(image_filename.c_str()));
21853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (input_image.get() == nullptr) {
219cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light    LOG(ERROR) << "unable to open input image file at " << image_filename
220cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light               << " for location " << image_location;
22153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
22253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
22353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  int64_t image_len = input_image->GetLength();
22453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (image_len < 0) {
22553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    LOG(ERROR) << "Error while getting image length";
22653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
22753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
22853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  ImageHeader image_header;
22953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (sizeof(image_header) != input_image->Read(reinterpret_cast<char*>(&image_header),
23053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light                                              sizeof(image_header), 0)) {
23153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    LOG(ERROR) << "Unable to read image header from image file " << input_image->GetPath();
23253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
23353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
23453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  // Set up the runtime
235e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers  RuntimeOptions options;
23653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  NoopCompilerCallbacks callbacks;
23753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  options.push_back(std::make_pair("compilercallbacks", &callbacks));
23853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  std::string img = "-Ximage:" + image_location;
23953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  options.push_back(std::make_pair(img.c_str(), nullptr));
24053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  options.push_back(std::make_pair("imageinstructionset", reinterpret_cast<const void*>(isa_name)));
24153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (!Runtime::Create(options, false)) {
24253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    LOG(ERROR) << "Unable to initialize runtime";
24353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
24453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
24553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  // Runtime::Create acquired the mutator_lock_ that is normally given away when we Runtime::Start,
24653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  // give it away now and then switch to a more manageable ScopedObjectAccess.
24753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  Thread::Current()->TransitionFromRunnableToSuspended(kNative);
24853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  ScopedObjectAccess soa(Thread::Current());
24953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
25053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  t.NewTiming("Image and oat Patching setup");
25153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  // Create the map where we will write the image patches to.
252eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light  std::string error_msg;
25353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  std::unique_ptr<MemMap> image(MemMap::MapFile(image_len, PROT_READ | PROT_WRITE, MAP_PRIVATE,
25453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light                                                input_image->Fd(), 0,
25553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light                                                input_image->GetPath().c_str(),
25653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light                                                &error_msg));
25753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (image.get() == nullptr) {
25853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    LOG(ERROR) << "unable to map image file " << input_image->GetPath() << " : " << error_msg;
25953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
26053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
26153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  gc::space::ImageSpace* ispc = Runtime::Current()->GetHeap()->GetImageSpace();
26253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
26353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  std::unique_ptr<ElfFile> elf(ElfFile::Open(const_cast<File*>(input_oat),
26453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light                                             PROT_READ | PROT_WRITE, MAP_PRIVATE, &error_msg));
26553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (elf.get() == nullptr) {
26653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    LOG(ERROR) << "unable to open oat file " << input_oat->GetPath() << " : " << error_msg;
26753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
26853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
26953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
27053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  PatchOat p(elf.release(), image.release(), ispc->GetLiveBitmap(), ispc->GetMemMap(),
27153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light             delta, timings);
27253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  t.NewTiming("Patching files");
27353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (!p.PatchElf()) {
274a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    LOG(ERROR) << "Failed to patch oat file " << input_oat->GetPath();
27553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
27653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
27753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (!p.PatchImage()) {
278a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    LOG(ERROR) << "Failed to patch image file " << input_image->GetPath();
27953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
28053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
28153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
28253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  t.NewTiming("Writing files");
28353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (!p.WriteElf(output_oat)) {
28453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
28553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
28653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (!p.WriteImage(output_image)) {
28753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
28853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
28953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  return true;
29053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}
29153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
29253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Lightbool PatchOat::WriteElf(File* out) {
293eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light  TimingLogger::ScopedTiming t("Writing Elf File", timings_);
294a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light
29553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK(oat_file_.get() != nullptr);
29653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK(out != nullptr);
29753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  size_t expect = oat_file_->Size();
29853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (out->WriteFully(reinterpret_cast<char*>(oat_file_->Begin()), expect) &&
29953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      out->SetLength(expect) == 0) {
30053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return true;
30153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  } else {
30253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    LOG(ERROR) << "Writing to oat file " << out->GetPath() << " failed.";
30353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
30453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
30553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}
30653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
30753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Lightbool PatchOat::WriteImage(File* out) {
308eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light  TimingLogger::ScopedTiming t("Writing image File", timings_);
309a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  std::string error_msg;
310a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light
311cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light  ScopedFlock img_flock;
312cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light  img_flock.Init(out, &error_msg);
313a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light
31453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK(image_ != nullptr);
31553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK(out != nullptr);
31653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  size_t expect = image_->Size();
31753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (out->WriteFully(reinterpret_cast<char*>(image_->Begin()), expect) &&
31853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      out->SetLength(expect) == 0) {
31953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return true;
32053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  } else {
32153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    LOG(ERROR) << "Writing to image file " << out->GetPath() << " failed.";
32253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
32353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
32453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}
32553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
32653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Lightbool PatchOat::PatchImage() {
32753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  ImageHeader* image_header = reinterpret_cast<ImageHeader*>(image_->Begin());
32853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK_GT(image_->Size(), sizeof(ImageHeader));
32953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  // These are the roots from the original file.
33053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  mirror::Object* img_roots = image_header->GetImageRoots();
33153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  image_header->RelocateImage(delta_);
33253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
33353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  VisitObject(img_roots);
33453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (!image_header->IsValid()) {
33553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    LOG(ERROR) << "reloction renders image header invalid";
33653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
33753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
33853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
33953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  {
340eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light    TimingLogger::ScopedTiming t("Walk Bitmap", timings_);
34153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    // Walk the bitmap.
34253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    WriterMutexLock mu(Thread::Current(), *Locks::heap_bitmap_lock_);
34353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    bitmap_->Walk(PatchOat::BitmapCallback, this);
34453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
34553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  return true;
34653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}
34753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
34853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Lightbool PatchOat::InHeap(mirror::Object* o) {
34953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  uintptr_t begin = reinterpret_cast<uintptr_t>(heap_->Begin());
35053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  uintptr_t end = reinterpret_cast<uintptr_t>(heap_->End());
35153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  uintptr_t obj = reinterpret_cast<uintptr_t>(o);
35253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  return o == nullptr || (begin <= obj && obj < end);
35353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}
35453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
35553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Lightvoid PatchOat::PatchVisitor::operator() (mirror::Object* obj, MemberOffset off,
35653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light                                         bool is_static_unused) const {
35753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  mirror::Object* referent = obj->GetFieldObject<mirror::Object, kVerifyNone>(off);
35853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  DCHECK(patcher_->InHeap(referent)) << "Referent is not in the heap.";
35953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  mirror::Object* moved_object = patcher_->RelocatedAddressOf(referent);
36053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  copy_->SetFieldObjectWithoutWriteBarrier<false, true, kVerifyNone>(off, moved_object);
36153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}
36253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
36353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Lightvoid PatchOat::PatchVisitor::operator() (mirror::Class* cls, mirror::Reference* ref) const {
36453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  MemberOffset off = mirror::Reference::ReferentOffset();
36553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  mirror::Object* referent = ref->GetReferent();
36653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  DCHECK(patcher_->InHeap(referent)) << "Referent is not in the heap.";
36753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  mirror::Object* moved_object = patcher_->RelocatedAddressOf(referent);
36853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  copy_->SetFieldObjectWithoutWriteBarrier<false, true, kVerifyNone>(off, moved_object);
36953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}
37053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
37153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Lightmirror::Object* PatchOat::RelocatedCopyOf(mirror::Object* obj) {
37253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (obj == nullptr) {
37353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return nullptr;
37453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
37553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  DCHECK_GT(reinterpret_cast<uintptr_t>(obj), reinterpret_cast<uintptr_t>(heap_->Begin()));
37653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  DCHECK_LT(reinterpret_cast<uintptr_t>(obj), reinterpret_cast<uintptr_t>(heap_->End()));
37753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  uintptr_t heap_off =
37853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      reinterpret_cast<uintptr_t>(obj) - reinterpret_cast<uintptr_t>(heap_->Begin());
37953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  DCHECK_LT(heap_off, image_->Size());
38053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  return reinterpret_cast<mirror::Object*>(image_->Begin() + heap_off);
38153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}
38253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
38353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Lightmirror::Object* PatchOat::RelocatedAddressOf(mirror::Object* obj) {
38453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (obj == nullptr) {
38553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return nullptr;
38653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  } else {
38753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return reinterpret_cast<mirror::Object*>(reinterpret_cast<byte*>(obj) + delta_);
38853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
38953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}
39053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
39153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light// Called by BitmapCallback
39253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Lightvoid PatchOat::VisitObject(mirror::Object* object) {
39353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  mirror::Object* copy = RelocatedCopyOf(object);
39453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK(copy != nullptr);
39553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (kUseBakerOrBrooksReadBarrier) {
39653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    object->AssertReadBarrierPointer();
39753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    if (kUseBrooksReadBarrier) {
39853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      mirror::Object* moved_to = RelocatedAddressOf(object);
39953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      copy->SetReadBarrierPointer(moved_to);
40053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      DCHECK_EQ(copy->GetReadBarrierPointer(), moved_to);
40153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    }
40253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
40353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  PatchOat::PatchVisitor visitor(this, copy);
40453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  object->VisitReferences<true, kVerifyNone>(visitor, visitor);
40553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (object->IsArtMethod<kVerifyNone>()) {
40653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    FixupMethod(static_cast<mirror::ArtMethod*>(object),
40753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light                static_cast<mirror::ArtMethod*>(copy));
40853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
40953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}
41053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
41153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Lightvoid PatchOat::FixupMethod(mirror::ArtMethod* object, mirror::ArtMethod* copy) {
41253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  // Just update the entry points if it looks like we should.
413eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light  // TODO: sanity check all the pointers' values
41453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  uintptr_t portable = reinterpret_cast<uintptr_t>(
41553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      object->GetEntryPointFromPortableCompiledCode<kVerifyNone>());
41653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (portable != 0) {
41753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    copy->SetEntryPointFromPortableCompiledCode(reinterpret_cast<void*>(portable + delta_));
41853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
41953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  uintptr_t quick= reinterpret_cast<uintptr_t>(
42053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      object->GetEntryPointFromQuickCompiledCode<kVerifyNone>());
42153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (quick != 0) {
42253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    copy->SetEntryPointFromQuickCompiledCode(reinterpret_cast<void*>(quick + delta_));
42353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
42453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  uintptr_t interpreter = reinterpret_cast<uintptr_t>(
42553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      object->GetEntryPointFromInterpreter<kVerifyNone>());
42653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (interpreter != 0) {
42753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    copy->SetEntryPointFromInterpreter(
42853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        reinterpret_cast<mirror::EntryPointFromInterpreter*>(interpreter + delta_));
42953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
43053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
43153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  uintptr_t native_method = reinterpret_cast<uintptr_t>(object->GetNativeMethod());
43253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (native_method != 0) {
43353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    copy->SetNativeMethod(reinterpret_cast<void*>(native_method + delta_));
43453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
43553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
43653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  uintptr_t native_gc_map = reinterpret_cast<uintptr_t>(object->GetNativeGcMap());
43753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (native_gc_map != 0) {
43853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    copy->SetNativeGcMap(reinterpret_cast<uint8_t*>(native_gc_map + delta_));
43953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
44053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}
44153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
442eefbe39799126afdf7d315a79359b9da23d1cef5Alex Lightbool PatchOat::Patch(File* input_oat, off_t delta, File* output_oat, TimingLogger* timings) {
44353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK(input_oat != nullptr);
44453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK(output_oat != nullptr);
44553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK_GE(input_oat->Fd(), 0);
44653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK_GE(output_oat->Fd(), 0);
447eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light  TimingLogger::ScopedTiming t("Setup Oat File Patching", timings);
44853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
44953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  std::string error_msg;
45053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  std::unique_ptr<ElfFile> elf(ElfFile::Open(const_cast<File*>(input_oat),
45153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light                                             PROT_READ | PROT_WRITE, MAP_PRIVATE, &error_msg));
45253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (elf.get() == nullptr) {
45353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    LOG(ERROR) << "unable to open oat file " << input_oat->GetPath() << " : " << error_msg;
45453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
45553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
45653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
45753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  PatchOat p(elf.release(), delta, timings);
45853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  t.NewTiming("Patch Oat file");
45953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (!p.PatchElf()) {
46053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
46153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
46253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
46353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  t.NewTiming("Writing oat file");
46453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (!p.WriteElf(output_oat)) {
46553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
46653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
46753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  return true;
46853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}
46953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
4704b0d2d99b596eebd6da45679896d3af54bc5a935Alex Lighttemplate <typename ptr_t>
4714b0d2d99b596eebd6da45679896d3af54bc5a935Alex Lightbool PatchOat::CheckOatFile(const Elf32_Shdr& patches_sec) {
4724b0d2d99b596eebd6da45679896d3af54bc5a935Alex Light  if (patches_sec.sh_type != SHT_OAT_PATCH) {
47353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
47453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
4754b0d2d99b596eebd6da45679896d3af54bc5a935Alex Light  ptr_t* patches = reinterpret_cast<ptr_t*>(oat_file_->Begin() + patches_sec.sh_offset);
4764b0d2d99b596eebd6da45679896d3af54bc5a935Alex Light  ptr_t* patches_end = patches + (patches_sec.sh_size / sizeof(ptr_t));
47753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  Elf32_Shdr* oat_data_sec = oat_file_->FindSectionByName(".rodata");
47853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  Elf32_Shdr* oat_text_sec = oat_file_->FindSectionByName(".text");
47953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (oat_data_sec == nullptr) {
48053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
48153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
48253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (oat_text_sec == nullptr) {
48353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
48453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
48553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (oat_text_sec->sh_offset <= oat_data_sec->sh_offset) {
48653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
48753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
48853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
48953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  for (; patches < patches_end; patches++) {
49053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    if (oat_text_sec->sh_size <= *patches) {
49153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      return false;
49253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    }
49353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
49453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
49553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  return true;
49653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}
49753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
498a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Lightbool PatchOat::PatchOatHeader() {
499a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  Elf32_Shdr *rodata_sec = oat_file_->FindSectionByName(".rodata");
500a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  if (rodata_sec == nullptr) {
501a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    return false;
502a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  }
503a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  OatHeader* oat_header = reinterpret_cast<OatHeader*>(oat_file_->Begin() + rodata_sec->sh_offset);
504a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  if (!oat_header->IsValid()) {
505a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    LOG(ERROR) << "Elf file " << oat_file_->GetFile().GetPath() << " has an invalid oat header";
506a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    return false;
507a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  }
508a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  oat_header->RelocateOat(delta_);
509a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  return true;
510a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light}
511a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light
51253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Lightbool PatchOat::PatchElf() {
513a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  TimingLogger::ScopedTiming t("Fixup Elf Text Section", timings_);
514a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  if (!PatchTextSection()) {
515a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    return false;
516a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  }
517a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light
518a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  if (!PatchOatHeader()) {
519a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    return false;
520a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  }
521a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light
522a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  bool need_fixup = false;
523a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  t.NewTiming("Fixup Elf Headers");
52453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  // Fixup Phdr's
52553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  for (unsigned int i = 0; i < oat_file_->GetProgramHeaderNum(); i++) {
526daab38ca60c5b91787e29c87a161a2bb8c1b6f11Andreas Gampe    Elf32_Phdr* hdr = oat_file_->GetProgramHeader(i);
527daab38ca60c5b91787e29c87a161a2bb8c1b6f11Andreas Gampe    CHECK(hdr != nullptr);
528daab38ca60c5b91787e29c87a161a2bb8c1b6f11Andreas Gampe    if (hdr->p_vaddr != 0 && hdr->p_vaddr != hdr->p_offset) {
529a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light      need_fixup = true;
530daab38ca60c5b91787e29c87a161a2bb8c1b6f11Andreas Gampe      hdr->p_vaddr += delta_;
53153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    }
532daab38ca60c5b91787e29c87a161a2bb8c1b6f11Andreas Gampe    if (hdr->p_paddr != 0 && hdr->p_paddr != hdr->p_offset) {
533a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light      need_fixup = true;
534daab38ca60c5b91787e29c87a161a2bb8c1b6f11Andreas Gampe      hdr->p_paddr += delta_;
53553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    }
53653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
537a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  if (!need_fixup) {
538a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    // This was never passed through ElfFixup so all headers/symbols just have their offset as
539a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    // their addr. Therefore we do not need to update these parts.
540a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    return true;
541a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  }
542a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  t.NewTiming("Fixup Section Headers");
54353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  for (unsigned int i = 0; i < oat_file_->GetSectionHeaderNum(); i++) {
544daab38ca60c5b91787e29c87a161a2bb8c1b6f11Andreas Gampe    Elf32_Shdr* hdr = oat_file_->GetSectionHeader(i);
545daab38ca60c5b91787e29c87a161a2bb8c1b6f11Andreas Gampe    CHECK(hdr != nullptr);
546daab38ca60c5b91787e29c87a161a2bb8c1b6f11Andreas Gampe    if (hdr->sh_addr != 0) {
547daab38ca60c5b91787e29c87a161a2bb8c1b6f11Andreas Gampe      hdr->sh_addr += delta_;
54853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    }
54953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
55053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
551a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  t.NewTiming("Fixup Dynamics");
55253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  for (Elf32_Word i = 0; i < oat_file_->GetDynamicNum(); i++) {
55353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    Elf32_Dyn& dyn = oat_file_->GetDynamic(i);
55453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    if (IsDynamicSectionPointer(dyn.d_tag, oat_file_->GetHeader().e_machine)) {
55553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      dyn.d_un.d_ptr += delta_;
55653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    }
55753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
55853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
55953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  t.NewTiming("Fixup Elf Symbols");
56053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  // Fixup dynsym
56153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  Elf32_Shdr* dynsym_sec = oat_file_->FindSectionByName(".dynsym");
56253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK(dynsym_sec != nullptr);
56353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (!PatchSymbols(dynsym_sec)) {
56453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
56553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
56653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
56753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  // Fixup symtab
56853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  Elf32_Shdr* symtab_sec = oat_file_->FindSectionByName(".symtab");
56953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (symtab_sec != nullptr) {
57053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    if (!PatchSymbols(symtab_sec)) {
57153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      return false;
57253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    }
57353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
57453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
575e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  t.NewTiming("Fixup Debug Sections");
576e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  if (!oat_file_->FixupDebugSections(delta_)) {
577e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    return false;
578e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  }
579e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
58053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  return true;
58153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}
58253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
58353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Lightbool PatchOat::PatchSymbols(Elf32_Shdr* section) {
58453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  Elf32_Sym* syms = reinterpret_cast<Elf32_Sym*>(oat_file_->Begin() + section->sh_offset);
58553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  const Elf32_Sym* last_sym =
58653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      reinterpret_cast<Elf32_Sym*>(oat_file_->Begin() + section->sh_offset + section->sh_size);
58753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK_EQ(section->sh_size % sizeof(Elf32_Sym), 0u)
58853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      << "Symtab section size is not multiple of symbol size";
58953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  for (; syms < last_sym; syms++) {
59053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    uint8_t sttype = ELF32_ST_TYPE(syms->st_info);
59153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    Elf32_Word shndx = syms->st_shndx;
59253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    if (shndx != SHN_ABS && shndx != SHN_COMMON && shndx != SHN_UNDEF &&
59353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        (sttype == STT_FUNC || sttype == STT_OBJECT)) {
59453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      CHECK_NE(syms->st_value, 0u);
59553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      syms->st_value += delta_;
59653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    }
59753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
59853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  return true;
59953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}
60053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
60153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Lightbool PatchOat::PatchTextSection() {
60253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  Elf32_Shdr* patches_sec = oat_file_->FindSectionByName(".oat_patches");
60353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (patches_sec == nullptr) {
604a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    LOG(ERROR) << ".oat_patches section not found. Aborting patch";
60553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
60653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
6074b0d2d99b596eebd6da45679896d3af54bc5a935Alex Light  if (patches_sec->sh_type != SHT_OAT_PATCH) {
6084b0d2d99b596eebd6da45679896d3af54bc5a935Alex Light    LOG(ERROR) << "Unexpected type of .oat_patches";
6094b0d2d99b596eebd6da45679896d3af54bc5a935Alex Light    return false;
6104b0d2d99b596eebd6da45679896d3af54bc5a935Alex Light  }
6114b0d2d99b596eebd6da45679896d3af54bc5a935Alex Light
6124b0d2d99b596eebd6da45679896d3af54bc5a935Alex Light  switch (patches_sec->sh_entsize) {
6134b0d2d99b596eebd6da45679896d3af54bc5a935Alex Light    case sizeof(uint32_t):
6144b0d2d99b596eebd6da45679896d3af54bc5a935Alex Light      return PatchTextSection<uint32_t>(*patches_sec);
6154b0d2d99b596eebd6da45679896d3af54bc5a935Alex Light    case sizeof(uint64_t):
6164b0d2d99b596eebd6da45679896d3af54bc5a935Alex Light      return PatchTextSection<uint64_t>(*patches_sec);
6174b0d2d99b596eebd6da45679896d3af54bc5a935Alex Light    default:
6184b0d2d99b596eebd6da45679896d3af54bc5a935Alex Light      LOG(ERROR) << ".oat_patches Entsize of " << patches_sec->sh_entsize << "bits "
6194b0d2d99b596eebd6da45679896d3af54bc5a935Alex Light                 << "is not valid";
6204b0d2d99b596eebd6da45679896d3af54bc5a935Alex Light      return false;
6214b0d2d99b596eebd6da45679896d3af54bc5a935Alex Light  }
6224b0d2d99b596eebd6da45679896d3af54bc5a935Alex Light}
6234b0d2d99b596eebd6da45679896d3af54bc5a935Alex Light
6244b0d2d99b596eebd6da45679896d3af54bc5a935Alex Lighttemplate <typename ptr_t>
6254b0d2d99b596eebd6da45679896d3af54bc5a935Alex Lightbool PatchOat::PatchTextSection(const Elf32_Shdr& patches_sec) {
6264b0d2d99b596eebd6da45679896d3af54bc5a935Alex Light  DCHECK(CheckOatFile<ptr_t>(patches_sec)) << "Oat file invalid";
6274b0d2d99b596eebd6da45679896d3af54bc5a935Alex Light  ptr_t* patches = reinterpret_cast<ptr_t*>(oat_file_->Begin() + patches_sec.sh_offset);
6284b0d2d99b596eebd6da45679896d3af54bc5a935Alex Light  ptr_t* patches_end = patches + (patches_sec.sh_size / sizeof(ptr_t));
62953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  Elf32_Shdr* oat_text_sec = oat_file_->FindSectionByName(".text");
63053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK(oat_text_sec != nullptr);
63153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  byte* to_patch = oat_file_->Begin() + oat_text_sec->sh_offset;
63253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  uintptr_t to_patch_end = reinterpret_cast<uintptr_t>(to_patch) + oat_text_sec->sh_size;
63353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
63453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  for (; patches < patches_end; patches++) {
63553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    CHECK_LT(*patches, oat_text_sec->sh_size) << "Bad Patch";
63653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    uint32_t* patch_loc = reinterpret_cast<uint32_t*>(to_patch + *patches);
63753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    CHECK_LT(reinterpret_cast<uintptr_t>(patch_loc), to_patch_end);
63853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    *patch_loc += delta_;
63953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
64053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  return true;
64153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}
64253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
64353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Lightstatic int orig_argc;
64453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Lightstatic char** orig_argv;
64553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
64653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Lightstatic std::string CommandLine() {
64753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  std::vector<std::string> command;
64853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  for (int i = 0; i < orig_argc; ++i) {
64953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    command.push_back(orig_argv[i]);
65053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
65153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  return Join(command, ' ');
65253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}
65353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
65453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Lightstatic void UsageErrorV(const char* fmt, va_list ap) {
65553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  std::string error;
65653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  StringAppendV(&error, fmt, ap);
65753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  LOG(ERROR) << error;
65853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}
65953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
66053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Lightstatic void UsageError(const char* fmt, ...) {
66153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  va_list ap;
66253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  va_start(ap, fmt);
66353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageErrorV(fmt, ap);
66453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  va_end(ap);
66553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}
66653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
66753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Lightstatic void Usage(const char *fmt, ...) {
66853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  va_list ap;
66953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  va_start(ap, fmt);
67053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageErrorV(fmt, ap);
67153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  va_end(ap);
67253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
67353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("Command: %s", CommandLine().c_str());
67453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("Usage: patchoat [options]...");
67553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("");
67653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("  --instruction-set=<isa>: Specifies the instruction set the patched code is");
67753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("      compiled for. Required if you use --input-oat-location");
67853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("");
67953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("  --input-oat-file=<file.oat>: Specifies the exact filename of the oat file to be");
68053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("      patched.");
68153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("");
68253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("  --input-oat-fd=<file-descriptor>: Specifies the file-descriptor of the oat file");
68353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("      to be patched.");
68453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("");
68553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("  --input-oat-location=<file.oat>: Specifies the 'location' to read the patched");
68653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("      oat file from. If used one must also supply the --instruction-set");
68753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("");
68853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("  --input-image-location=<file.art>: Specifies the 'location' of the image file to");
68953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("      be patched. If --instruction-set is not given it will use the instruction set");
69053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("      extracted from the --input-oat-file.");
69153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("");
69253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("  --output-oat-file=<file.oat>: Specifies the exact file to write the patched oat");
69353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("      file to.");
69453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("");
69553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("  --output-oat-fd=<file-descriptor>: Specifies the file-descriptor to write the");
69653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("      the patched oat file to.");
69753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("");
69853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("  --output-image-file=<file.art>: Specifies the exact file to write the patched");
69953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("      image file to.");
70053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("");
70153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("  --output-image-fd=<file-descriptor>: Specifies the file-descriptor to write the");
70253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("      the patched image file to.");
70353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("");
70453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("  --orig-base-offset=<original-base-offset>: Specify the base offset the input file");
70553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("      was compiled with. This is needed if one is specifying a --base-offset");
70653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("");
70753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("  --base-offset=<new-base-offset>: Specify the base offset we will repatch the");
70853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("      given files to use. This requires that --orig-base-offset is also given.");
70953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("");
71053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("  --base-offset-delta=<delta>: Specify the amount to change the old base-offset by.");
71153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("      This value may be negative.");
71253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("");
71353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("  --patched-image-file=<file.art>: Use the same patch delta as was used to patch");
71453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("      the given image file.");
71553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("");
71653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("  --patched-image-location=<file.art>: Use the same patch delta as was used to");
71753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("      patch the given image location. If used one must also specify the");
718a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  UsageError("      --instruction-set flag. It will search for this image in the same way that");
719a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  UsageError("      is done when loading one.");
72053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("");
721cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light  UsageError("  --lock-output: Obtain a flock on output oat file before starting.");
722cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light  UsageError("");
723cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light  UsageError("  --no-lock-output: Do not attempt to obtain a flock on output oat file.");
724cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light  UsageError("");
72553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("  --dump-timings: dump out patch timing information");
72653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("");
72753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("  --no-dump-timings: do not dump out patch timing information");
72853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("");
72953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
73053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  exit(EXIT_FAILURE);
73153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}
73253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
733eefbe39799126afdf7d315a79359b9da23d1cef5Alex Lightstatic bool ReadBaseDelta(const char* name, off_t* delta, std::string* error_msg) {
73453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK(name != nullptr);
73553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK(delta != nullptr);
73653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  std::unique_ptr<File> file;
73753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (OS::FileExists(name)) {
73853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    file.reset(OS::OpenFileForReading(name));
73953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    if (file.get() == nullptr) {
740eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light      *error_msg = "Failed to open file %s for reading";
74153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      return false;
74253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    }
74353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  } else {
744eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light    *error_msg = "File %s does not exist";
74553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
74653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
74753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  CHECK(file.get() != nullptr);
74853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  ImageHeader hdr;
74953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (sizeof(hdr) != file->Read(reinterpret_cast<char*>(&hdr), sizeof(hdr), 0)) {
750eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light    *error_msg = "Failed to read file %s";
75153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
75253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
75353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (!hdr.IsValid()) {
754eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light    *error_msg = "%s does not contain a valid image header.";
75553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return false;
75653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
75753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  *delta = hdr.GetPatchDelta();
75853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  return true;
75953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}
76053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
76153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Lightstatic File* CreateOrOpen(const char* name, bool* created) {
76253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (OS::FileExists(name)) {
76353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    *created = false;
76453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return OS::OpenFileReadWrite(name);
76553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  } else {
76653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    *created = true;
767cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light    std::unique_ptr<File> f(OS::CreateEmptyFile(name));
768cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light    if (f.get() != nullptr) {
769cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light      if (fchmod(f->Fd(), 0644) != 0) {
770cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light        PLOG(ERROR) << "Unable to make " << name << " world readable";
771cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light        unlink(name);
772cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light        return nullptr;
773cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light      }
774cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light    }
775cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light    return f.release();
77653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
77753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}
77853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
779eefbe39799126afdf7d315a79359b9da23d1cef5Alex Lightstatic int patchoat(int argc, char **argv) {
78053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  InitLogging(argv);
78153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  const bool debug = kIsDebugBuild;
78253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  orig_argc = argc;
78353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  orig_argv = argv;
78453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  TimingLogger timings("patcher", false, false);
78553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
78653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  InitLogging(argv);
78753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
78853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  // Skip over the command name.
78953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  argv++;
79053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  argc--;
79153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
79253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (argc == 0) {
79353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    Usage("No arguments specified");
79453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
79553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
79653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  timings.StartTiming("Patchoat");
79753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
79853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  // cmd line args
79953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  bool isa_set = false;
80053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  InstructionSet isa = kNone;
80153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  std::string input_oat_filename;
80253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  std::string input_oat_location;
80353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  int input_oat_fd = -1;
80453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  bool have_input_oat = false;
80553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  std::string input_image_location;
80653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  std::string output_oat_filename;
80753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  int output_oat_fd = -1;
80853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  bool have_output_oat = false;
80953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  std::string output_image_filename;
81053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  int output_image_fd = -1;
81153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  bool have_output_image = false;
81253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  uintptr_t base_offset = 0;
81353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  bool base_offset_set = false;
81453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  uintptr_t orig_base_offset = 0;
81553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  bool orig_base_offset_set = false;
81653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  off_t base_delta = 0;
81753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  bool base_delta_set = false;
81853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  std::string patched_image_filename;
81953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  std::string patched_image_location;
82053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  bool dump_timings = kIsDebugBuild;
821cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light  bool lock_output = true;
82253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
82353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  for (int i = 0; i < argc; i++) {
82453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    const StringPiece option(argv[i]);
82553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    const bool log_options = false;
82653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    if (log_options) {
82753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      LOG(INFO) << "patchoat: option[" << i << "]=" << argv[i];
82853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    }
82953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    if (option.starts_with("--instruction-set=")) {
83053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      isa_set = true;
83153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      const char* isa_str = option.substr(strlen("--instruction-set=")).data();
83220c89303a9d89ba857bf969ad14a31f12c3be878Andreas Gampe      isa = GetInstructionSetFromString(isa_str);
83320c89303a9d89ba857bf969ad14a31f12c3be878Andreas Gampe      if (isa == kNone) {
83420c89303a9d89ba857bf969ad14a31f12c3be878Andreas Gampe        Usage("Unknown or invalid instruction set %s", isa_str);
83553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      }
83653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    } else if (option.starts_with("--input-oat-location=")) {
83753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      if (have_input_oat) {
83853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        Usage("Only one of --input-oat-file, --input-oat-location and --input-oat-fd may be used.");
83953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      }
84053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      have_input_oat = true;
84153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      input_oat_location = option.substr(strlen("--input-oat-location=")).data();
84253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    } else if (option.starts_with("--input-oat-file=")) {
84353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      if (have_input_oat) {
84453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        Usage("Only one of --input-oat-file, --input-oat-location and --input-oat-fd may be used.");
84553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      }
84653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      have_input_oat = true;
84753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      input_oat_filename = option.substr(strlen("--input-oat-file=")).data();
84853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    } else if (option.starts_with("--input-oat-fd=")) {
84953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      if (have_input_oat) {
85053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        Usage("Only one of --input-oat-file, --input-oat-location and --input-oat-fd may be used.");
85153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      }
85253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      have_input_oat = true;
85353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      const char* oat_fd_str = option.substr(strlen("--input-oat-fd=")).data();
85453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      if (!ParseInt(oat_fd_str, &input_oat_fd)) {
85553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        Usage("Failed to parse --input-oat-fd argument '%s' as an integer", oat_fd_str);
85653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      }
85753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      if (input_oat_fd < 0) {
85853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        Usage("--input-oat-fd pass a negative value %d", input_oat_fd);
85953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      }
86053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    } else if (option.starts_with("--input-image-location=")) {
86153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      input_image_location = option.substr(strlen("--input-image-location=")).data();
86253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    } else if (option.starts_with("--output-oat-file=")) {
86353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      if (have_output_oat) {
864cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light        Usage("Only one of --output-oat-file, and --output-oat-fd may be used.");
86553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      }
86653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      have_output_oat = true;
86753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      output_oat_filename = option.substr(strlen("--output-oat-file=")).data();
86853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    } else if (option.starts_with("--output-oat-fd=")) {
86953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      if (have_output_oat) {
870cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light        Usage("Only one of --output-oat-file, --output-oat-fd may be used.");
87153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      }
87253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      have_output_oat = true;
87353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      const char* oat_fd_str = option.substr(strlen("--output-oat-fd=")).data();
87453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      if (!ParseInt(oat_fd_str, &output_oat_fd)) {
87553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        Usage("Failed to parse --output-oat-fd argument '%s' as an integer", oat_fd_str);
87653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      }
87753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      if (output_oat_fd < 0) {
87853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        Usage("--output-oat-fd pass a negative value %d", output_oat_fd);
87953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      }
88053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    } else if (option.starts_with("--output-image-file=")) {
88153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      if (have_output_image) {
882cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light        Usage("Only one of --output-image-file, and --output-image-fd may be used.");
88353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      }
88453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      have_output_image = true;
88553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      output_image_filename = option.substr(strlen("--output-image-file=")).data();
88653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    } else if (option.starts_with("--output-image-fd=")) {
88753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      if (have_output_image) {
888cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light        Usage("Only one of --output-image-file, and --output-image-fd may be used.");
88953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      }
89053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      have_output_image = true;
89153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      const char* image_fd_str = option.substr(strlen("--output-image-fd=")).data();
89253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      if (!ParseInt(image_fd_str, &output_image_fd)) {
89353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        Usage("Failed to parse --output-image-fd argument '%s' as an integer", image_fd_str);
89453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      }
89553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      if (output_image_fd < 0) {
89653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        Usage("--output-image-fd pass a negative value %d", output_image_fd);
89753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      }
89853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    } else if (option.starts_with("--orig-base-offset=")) {
89953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      const char* orig_base_offset_str = option.substr(strlen("--orig-base-offset=")).data();
90053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      orig_base_offset_set = true;
90153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      if (!ParseUint(orig_base_offset_str, &orig_base_offset)) {
90253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        Usage("Failed to parse --orig-base-offset argument '%s' as an uintptr_t",
90353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light              orig_base_offset_str);
90453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      }
90553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    } else if (option.starts_with("--base-offset=")) {
90653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      const char* base_offset_str = option.substr(strlen("--base-offset=")).data();
90753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      base_offset_set = true;
90853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      if (!ParseUint(base_offset_str, &base_offset)) {
90953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        Usage("Failed to parse --base-offset argument '%s' as an uintptr_t", base_offset_str);
91053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      }
91153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    } else if (option.starts_with("--base-offset-delta=")) {
91253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      const char* base_delta_str = option.substr(strlen("--base-offset-delta=")).data();
91353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      base_delta_set = true;
91453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      if (!ParseInt(base_delta_str, &base_delta)) {
91553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        Usage("Failed to parse --base-offset-delta argument '%s' as an off_t", base_delta_str);
91653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      }
91753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    } else if (option.starts_with("--patched-image-location=")) {
91853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      patched_image_location = option.substr(strlen("--patched-image-location=")).data();
91953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    } else if (option.starts_with("--patched-image-file=")) {
92053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      patched_image_filename = option.substr(strlen("--patched-image-file=")).data();
921cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light    } else if (option == "--lock-output") {
922cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light      lock_output = true;
923cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light    } else if (option == "--no-lock-output") {
924cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light      lock_output = false;
92553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    } else if (option == "--dump-timings") {
92653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      dump_timings = true;
92753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    } else if (option == "--no-dump-timings") {
92853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      dump_timings = false;
92953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    } else {
93053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      Usage("Unknown argument %s", option.data());
93153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    }
93253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
93353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
93453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  {
93553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    // Only 1 of these may be set.
93653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    uint32_t cnt = 0;
93753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    cnt += (base_delta_set) ? 1 : 0;
93853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    cnt += (base_offset_set && orig_base_offset_set) ? 1 : 0;
93953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    cnt += (!patched_image_filename.empty()) ? 1 : 0;
94053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    cnt += (!patched_image_location.empty()) ? 1 : 0;
94153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    if (cnt > 1) {
94253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      Usage("Only one of --base-offset/--orig-base-offset, --base-offset-delta, "
94353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light            "--patched-image-filename or --patched-image-location may be used.");
94453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    } else if (cnt == 0) {
94553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      Usage("Must specify --base-offset-delta, --base-offset and --orig-base-offset, "
94653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light            "--patched-image-location or --patched-image-file");
94753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    }
94853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
94953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
95053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (have_input_oat != have_output_oat) {
95153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    Usage("Either both input and output oat must be supplied or niether must be.");
95253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
95353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
95453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if ((!input_image_location.empty()) != have_output_image) {
95553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    Usage("Either both input and output image must be supplied or niether must be.");
95653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
95753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
95853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  // We know we have both the input and output so rename for clarity.
95953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  bool have_image_files = have_output_image;
96053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  bool have_oat_files = have_output_oat;
96153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
96253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (!have_oat_files && !have_image_files) {
96353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    Usage("Must be patching either an oat or an image file or both.");
96453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
96553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
96653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (!have_oat_files && !isa_set) {
96753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    Usage("Must include ISA if patching an image file without an oat file.");
96853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
96953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
97053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (!input_oat_location.empty()) {
97153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    if (!isa_set) {
97253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      Usage("specifying a location requires specifying an instruction set");
97353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    }
974cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light    if (!LocationToFilename(input_oat_location, isa, &input_oat_filename)) {
975cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light      Usage("Unable to find filename for input oat location %s", input_oat_location.c_str());
97653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    }
97753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    if (debug) {
978cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light      LOG(INFO) << "Using input-oat-file " << input_oat_filename;
97953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    }
98053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
98153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (!patched_image_location.empty()) {
98253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    if (!isa_set) {
98353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      Usage("specifying a location requires specifying an instruction set");
98453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    }
985a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    std::string system_filename;
986a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    bool has_system = false;
987a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    std::string cache_filename;
988a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    bool has_cache = false;
989a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    bool has_android_data_unused = false;
9903c13a794845e0cf7887e33b2ec20de7e6ba85f8fAndreas Gampe    bool is_global_cache = false;
991a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    if (!gc::space::ImageSpace::FindImageFilename(patched_image_location.c_str(), isa,
992a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light                                                  &system_filename, &has_system, &cache_filename,
9933c13a794845e0cf7887e33b2ec20de7e6ba85f8fAndreas Gampe                                                  &has_android_data_unused, &has_cache,
9943c13a794845e0cf7887e33b2ec20de7e6ba85f8fAndreas Gampe                                                  &is_global_cache)) {
995a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light      Usage("Unable to determine image file for location %s", patched_image_location.c_str());
996a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    }
997a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    if (has_cache) {
998a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light      patched_image_filename = cache_filename;
999a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    } else if (has_system) {
1000a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light      LOG(WARNING) << "Only image file found was in /system for image location "
1001a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light                   << patched_image_location;
1002a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light      patched_image_filename = system_filename;
1003a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    } else {
1004a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light      Usage("Unable to determine image file for location %s", patched_image_location.c_str());
1005a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    }
100653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    if (debug) {
100753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      LOG(INFO) << "Using patched-image-file " << patched_image_filename;
100853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    }
100953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
101053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
101153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (!base_delta_set) {
101253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    if (orig_base_offset_set && base_offset_set) {
101353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      base_delta_set = true;
101453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      base_delta = base_offset - orig_base_offset;
101553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    } else if (!patched_image_filename.empty()) {
101653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      base_delta_set = true;
101753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      std::string error_msg;
1018eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light      if (!ReadBaseDelta(patched_image_filename.c_str(), &base_delta, &error_msg)) {
101953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        Usage(error_msg.c_str(), patched_image_filename.c_str());
102053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      }
102153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    } else {
102253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      if (base_offset_set) {
102353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        Usage("Unable to determine original base offset.");
102453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      } else {
102553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        Usage("Must supply a desired new offset or delta.");
102653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      }
102753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    }
102853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
102953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
103053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (!IsAligned<kPageSize>(base_delta)) {
103153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    Usage("Base offset/delta must be alligned to a pagesize (0x%08x) boundary.", kPageSize);
103253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
103353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
103453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  // Do we need to cleanup output files if we fail?
103553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  bool new_image_out = false;
103653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  bool new_oat_out = false;
103753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
103853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  std::unique_ptr<File> input_oat;
103953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  std::unique_ptr<File> output_oat;
104053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  std::unique_ptr<File> output_image;
104153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
104253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (have_image_files) {
104353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    CHECK(!input_image_location.empty());
104453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
104553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    if (output_image_fd != -1) {
1046cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light      if (output_image_filename.empty()) {
1047cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light        output_image_filename = "output-image-file";
1048cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light      }
104953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      output_image.reset(new File(output_image_fd, output_image_filename));
105053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    } else {
105153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      CHECK(!output_image_filename.empty());
105253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      output_image.reset(CreateOrOpen(output_image_filename.c_str(), &new_image_out));
105353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    }
105453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  } else {
105553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    CHECK(output_image_filename.empty() && output_image_fd == -1 && input_image_location.empty());
105653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
105753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
105853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (have_oat_files) {
105953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    if (input_oat_fd != -1) {
1060cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light      if (input_oat_filename.empty()) {
1061cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light        input_oat_filename = "input-oat-file";
1062cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light      }
106353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      input_oat.reset(new File(input_oat_fd, input_oat_filename));
106453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    } else {
106553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      CHECK(!input_oat_filename.empty());
106653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      input_oat.reset(OS::OpenFileForReading(input_oat_filename.c_str()));
10671c83cbc4a817acbd7f9abb5b29a2d418a958e6a1Andreas Gampe      if (input_oat.get() == nullptr) {
10681c83cbc4a817acbd7f9abb5b29a2d418a958e6a1Andreas Gampe        LOG(ERROR) << "Could not open input oat file: " << strerror(errno);
10691c83cbc4a817acbd7f9abb5b29a2d418a958e6a1Andreas Gampe      }
107053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    }
107153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
107253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    if (output_oat_fd != -1) {
1073cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light      if (output_oat_filename.empty()) {
1074cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light        output_oat_filename = "output-oat-file";
1075a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light      }
1076cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light      output_oat.reset(new File(output_oat_fd, output_oat_filename));
107753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    } else {
107853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      CHECK(!output_oat_filename.empty());
107953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      output_oat.reset(CreateOrOpen(output_oat_filename.c_str(), &new_oat_out));
108053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    }
108153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
108253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
108353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  auto cleanup = [&output_image_filename, &output_oat_filename,
108453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light                  &new_oat_out, &new_image_out, &timings, &dump_timings](bool success) {
108553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    timings.EndTiming();
108653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    if (!success) {
108753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      if (new_oat_out) {
108853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        CHECK(!output_oat_filename.empty());
108953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        unlink(output_oat_filename.c_str());
109053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      }
109153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      if (new_image_out) {
109253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        CHECK(!output_image_filename.empty());
109353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light        unlink(output_image_filename.c_str());
109453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      }
109553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    }
109653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    if (dump_timings) {
109753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      LOG(INFO) << Dumpable<TimingLogger>(timings);
109853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    }
109953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  };
110053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
1101cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light  if ((have_oat_files && (input_oat.get() == nullptr || output_oat.get() == nullptr)) ||
1102cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light      (have_image_files && output_image.get() == nullptr)) {
1103cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light    cleanup(false);
1104cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light    return EXIT_FAILURE;
1105cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light  }
1106cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light
1107cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light  ScopedFlock output_oat_lock;
1108cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light  if (lock_output) {
1109cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light    std::string error_msg;
1110cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light    if (have_oat_files && !output_oat_lock.Init(output_oat.get(), &error_msg)) {
1111cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light      LOG(ERROR) << "Unable to lock output oat " << output_image->GetPath() << ": " << error_msg;
1112cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light      cleanup(false);
1113cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light      return EXIT_FAILURE;
1114cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light    }
1115cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light  }
1116cf4bf386ef3f527825c70e01130b9276da4f786aAlex Light
111753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (debug) {
1118a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    LOG(INFO) << "moving offset by " << base_delta
1119a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light              << " (0x" << std::hex << base_delta << ") bytes or "
1120a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light              << std::dec << (base_delta/kPageSize) << " pages.";
112153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
112253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
112353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  bool ret;
112453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (have_image_files && have_oat_files) {
112553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    TimingLogger::ScopedTiming pt("patch image and oat", &timings);
112653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    ret = PatchOat::Patch(input_oat.get(), input_image_location, base_delta,
1127eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light                          output_oat.get(), output_image.get(), isa, &timings);
112853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  } else if (have_oat_files) {
112953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    TimingLogger::ScopedTiming pt("patch oat", &timings);
1130eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light    ret = PatchOat::Patch(input_oat.get(), base_delta, output_oat.get(), &timings);
113153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  } else {
113253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    TimingLogger::ScopedTiming pt("patch image", &timings);
113353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    CHECK(have_image_files);
1134eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light    ret = PatchOat::Patch(input_image_location, base_delta, output_image.get(), isa, &timings);
113553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
113653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  cleanup(ret);
113753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  return (ret) ? EXIT_SUCCESS : EXIT_FAILURE;
113853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}
113953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
114053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}  // namespace art
114153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
114253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Lightint main(int argc, char **argv) {
114353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  return art::patchoat(argc, argv);
114453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}
1145