/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "patchoat.h"

#include <openssl/sha.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <unistd.h>

#include <string>
#include <vector>

#include "android-base/file.h"
#include "android-base/stringprintf.h"
#include "android-base/strings.h"

#include "art_field-inl.h"
#include "art_method-inl.h"
#include "base/bit_memory_region.h"
#include "base/dumpable.h"
#include "base/file_utils.h"
#include "base/leb128.h"
#include "base/logging.h"  // For InitLogging.
#include "base/mutex.h"
#include "base/memory_region.h"
#include "base/memory_tool.h"
#include "base/os.h"
#include "base/scoped_flock.h"
#include "base/stringpiece.h"
#include "base/unix_file/fd_file.h"
#include "base/unix_file/random_access_file_utils.h"
#include "base/utils.h"
#include "class_root.h"
#include "elf_file.h"
#include "elf_file_impl.h"
#include "elf_utils.h"
#include "gc/space/image_space.h"
#include "image-inl.h"
#include "intern_table.h"
#include "mirror/dex_cache.h"
#include "mirror/executable.h"
#include "mirror/method.h"
#include "mirror/object-inl.h"
#include "mirror/object-refvisitor-inl.h"
#include "mirror/reference.h"
#include "noop_compiler_callbacks.h"
#include "offsets.h"
#include "runtime.h"
#include "scoped_thread_state_change-inl.h"
#include "thread.h"

namespace art {

using android::base::StringPrintf;

namespace {

static const OatHeader* GetOatHeader(const ElfFile* elf_file) {
  uint64_t off = 0;
  if (!elf_file->GetSectionOffsetAndSize(".rodata", &off, nullptr)) {
    return nullptr;
  }

  OatHeader* oat_header = reinterpret_cast<OatHeader*>(elf_file->Begin() + off);
  return oat_header;
}

static File* CreateOrOpen(const char* name) {
  if (OS::FileExists(name)) {
    return OS::OpenFileReadWrite(name);
  } else {
    std::unique_ptr<File> f(OS::CreateEmptyFile(name));
    if (f.get() != nullptr) {
      if (fchmod(f->Fd(), 0644) != 0) {
        PLOG(ERROR) << "Unable to make " << name << " world readable";
        unlink(name);
        return nullptr;
      }
    }
    return f.release();
  }
}

// Either try to close the file (close=true), or erase it.
static bool FinishFile(File* file, bool close) {
  if (close) {
    if (file->FlushCloseOrErase() != 0) {
      PLOG(ERROR) << "Failed to flush and close file.";
      return false;
    }
    return true;
  } else {
    file->Erase();
    return false;
  }
}

static bool SymlinkFile(const std::string& input_filename, const std::string& output_filename) {
  if (input_filename == output_filename) {
    // Input and output are the same, nothing to do.
    return true;
  }

  // Unlink the original filename, since we are overwriting it.
  unlink(output_filename.c_str());

  // Create a symlink from the source file to the target path.
  if (symlink(input_filename.c_str(), output_filename.c_str()) < 0) {
    PLOG(ERROR) << "Failed to create symlink " << output_filename << " -> " << input_filename;
    return false;
  }

  if (kIsDebugBuild) {
    LOG(INFO) << "Created symlink " << output_filename << " -> " << input_filename;
  }

  return true;
}

// Holder class for runtime options and related objects.
class PatchoatRuntimeOptionsHolder {
 public:
  PatchoatRuntimeOptionsHolder(const std::string& image_location, InstructionSet isa) {
    options_.push_back(std::make_pair("compilercallbacks", &callbacks_));
    img_ = "-Ximage:" + image_location;
    options_.push_back(std::make_pair(img_.c_str(), nullptr));
    isa_name_ = GetInstructionSetString(isa);
    options_.push_back(std::make_pair("imageinstructionset",
                                      reinterpret_cast<const void*>(isa_name_.c_str())));
    options_.push_back(std::make_pair("-Xno-sig-chain", nullptr));
    // We do not want the runtime to attempt to patch the image.
    options_.push_back(std::make_pair("-Xnorelocate", nullptr));
    // Don't try to compile.
    options_.push_back(std::make_pair("-Xnoimage-dex2oat", nullptr));
    // Do not accept broken image.
    options_.push_back(std::make_pair("-Xno-dex-file-fallback", nullptr));
  }

  const RuntimeOptions& GetRuntimeOptions() {
    return options_;
  }

 private:
  RuntimeOptions options_;
  NoopCompilerCallbacks callbacks_;
  std::string isa_name_;
  std::string img_;
};

}  // namespace

bool PatchOat::GeneratePatch(
    const MemMap& original,
    const MemMap& relocated,
    std::vector<uint8_t>* output,
    std::string* error_msg) {
  // FORMAT of the patch (aka image relocation) file:
  // * SHA-256 digest (32 bytes) of original/unrelocated file (e.g., the one from /system)
  // * List of monotonically increasing offsets (max value defined by uint32_t) at which relocations
  //   occur.
  //   Each element is represented as the delta from the previous offset in the list (first element
  //   is a delta from 0). Each delta is encoded using unsigned LEB128: little-endian
  //   variable-length 7 bits per byte encoding, where all bytes have the highest bit (0x80) set
  //   except for the final byte which does not have that bit set. For example, 0x3f is offset 0x3f,
  //   whereas 0xbf 0x05 is offset (0x3f & 0x7f) | (0x5 << 7) which is 0x2bf. Most deltas end up
  //   being encoding using just one byte, achieving ~4x decrease in relocation file size compared
  //   to the encoding where offsets are stored verbatim, as uint32_t.

  size_t original_size = original.Size();
  size_t relocated_size = relocated.Size();
  if (original_size != relocated_size) {
    *error_msg =
        StringPrintf(
            "Original and relocated image sizes differ: %zu vs %zu", original_size, relocated_size);
    return false;
  }
  if (original_size > UINT32_MAX) {
    *error_msg = StringPrintf("Image too large: %zu" , original_size);
    return false;
  }

  const ImageHeader& relocated_header =
      *reinterpret_cast<const ImageHeader*>(relocated.Begin());
  // Offsets are supposed to differ between original and relocated by this value
  off_t expected_diff = relocated_header.GetPatchDelta();
  if (expected_diff == 0) {
    // Can't identify offsets which are supposed to differ due to relocation
    *error_msg = "Relocation delta is 0";
    return false;
  }

  const ImageHeader* image_header = reinterpret_cast<const ImageHeader*>(original.Begin());
  if (image_header->GetStorageMode() != ImageHeader::kStorageModeUncompressed) {
    *error_msg = "Unexpected compressed image.";
    return false;
  }
  if (image_header->IsAppImage()) {
    *error_msg = "Unexpected app image.";
    return false;
  }
  if (image_header->GetPointerSize() != PointerSize::k32 &&
      image_header->GetPointerSize() != PointerSize::k64) {
    *error_msg = "Unexpected pointer size.";
    return false;
  }
  static_assert(sizeof(GcRoot<mirror::Object>) == sizeof(mirror::HeapReference<mirror::Object>),
                "Expecting heap GC roots and references to have the same size.");
  DCHECK_LE(sizeof(GcRoot<mirror::Object>), static_cast<size_t>(image_header->GetPointerSize()));

  const size_t image_bitmap_offset = RoundUp(sizeof(ImageHeader) + image_header->GetDataSize(),
                                             kPageSize);
  const size_t end_of_bitmap = image_bitmap_offset + image_header->GetImageBitmapSection().Size();
  const ImageSection& relocation_section = image_header->GetImageRelocationsSection();
  MemoryRegion relocations_data(original.Begin() + end_of_bitmap, relocation_section.Size());
  size_t image_end = image_header->GetClassTableSection().End();
  if (!IsAligned<sizeof(GcRoot<mirror::Object>)>(image_end)) {
    *error_msg = StringPrintf("Unaligned image end: %zu", image_end);
    return false;
  }
  size_t num_indexes = image_end / sizeof(GcRoot<mirror::Object>);
  if (relocation_section.Size() != BitsToBytesRoundUp(num_indexes)) {
    *error_msg = StringPrintf("Unexpected size of relocation section: %zu expected: %zu",
                              static_cast<size_t>(relocation_section.Size()),
                              BitsToBytesRoundUp(num_indexes));
    return false;
  }
  BitMemoryRegion relocation_bitmap(relocations_data, /* bit_offset */ 0u, num_indexes);

  // Output the SHA-256 digest of the original
  output->resize(SHA256_DIGEST_LENGTH);
  const uint8_t* original_bytes = original.Begin();
  SHA256(original_bytes, original_size, output->data());

  // Check the list of offsets at which the original and patched images differ.
  size_t diff_offset_count = 0;
  const uint8_t* relocated_bytes = relocated.Begin();
  for (size_t index = 0; index != num_indexes; ++index) {
    size_t offset = index * sizeof(GcRoot<mirror::Object>);
    uint32_t original_value = *reinterpret_cast<const uint32_t*>(original_bytes + offset);
    uint32_t relocated_value = *reinterpret_cast<const uint32_t*>(relocated_bytes + offset);
    off_t diff = relocated_value - original_value;
    if (diff == 0) {
      CHECK(!relocation_bitmap.LoadBit(index));
      continue;
    } else if (diff != expected_diff) {
      *error_msg =
          StringPrintf(
              "Unexpected diff at offset %zu. Expected: %jd, but was: %jd",
              offset,
              (intmax_t) expected_diff,
              (intmax_t) diff);
      return false;
    }
    CHECK(relocation_bitmap.LoadBit(index));
    diff_offset_count++;
  }
  size_t tail_bytes = original_size - image_end;
  CHECK_EQ(memcmp(original_bytes + image_end, relocated_bytes + image_end, tail_bytes), 0);

  if (diff_offset_count == 0) {
    *error_msg = "Original and patched images are identical";
    return false;
  }

  return true;
}

static bool WriteRelFile(
    const MemMap& original,
    const MemMap& relocated,
    const std::string& rel_filename,
    std::string* error_msg) {
  std::vector<uint8_t> output;
  if (!PatchOat::GeneratePatch(original, relocated, &output, error_msg)) {
    return false;
  }

  std::unique_ptr<File> rel_file(OS::CreateEmptyFileWriteOnly(rel_filename.c_str()));
  if (rel_file.get() == nullptr) {
    *error_msg = StringPrintf("Failed to create/open output file %s", rel_filename.c_str());
    return false;
  }
  if (!rel_file->WriteFully(output.data(), output.size())) {
    *error_msg = StringPrintf("Failed to write to %s", rel_filename.c_str());
    return false;
  }
  if (rel_file->FlushCloseOrErase() != 0) {
    *error_msg = StringPrintf("Failed to flush and close %s", rel_filename.c_str());
    return false;
  }

  return true;
}

static bool CheckImageIdenticalToOriginalExceptForRelocation(
    const std::string& relocated_filename,
    const std::string& original_filename,
    std::string* error_msg) {
  *error_msg = "";
  std::string rel_filename = original_filename + ".rel";
  std::unique_ptr<File> rel_file(OS::OpenFileForReading(rel_filename.c_str()));
  if (rel_file.get() == nullptr) {
    *error_msg = StringPrintf("Failed to open image relocation file %s", rel_filename.c_str());
    return false;
  }
  int64_t rel_size = rel_file->GetLength();
  if (rel_size < 0) {
    *error_msg = StringPrintf("Error while getting size of image relocation file %s",
                              rel_filename.c_str());
    return false;
  }
  if (rel_size != SHA256_DIGEST_LENGTH) {
    *error_msg = StringPrintf("Unexpected size of image relocation file %s: %" PRId64
                                  ", expected %zu",
                              rel_filename.c_str(),
                              rel_size,
                              static_cast<size_t>(SHA256_DIGEST_LENGTH));
    return false;
  }
  std::unique_ptr<uint8_t[]> rel(new uint8_t[rel_size]);
  if (!rel_file->ReadFully(rel.get(), rel_size)) {
    *error_msg = StringPrintf("Failed to read image relocation file %s", rel_filename.c_str());
    return false;
  }

  std::unique_ptr<File> image_file(OS::OpenFileForReading(relocated_filename.c_str()));
  if (image_file.get() == nullptr) {
    *error_msg = StringPrintf("Unable to open relocated image file  %s",
                              relocated_filename.c_str());
    return false;
  }

  int64_t image_size = image_file->GetLength();
  if (image_size < 0) {
    *error_msg = StringPrintf("Error while getting size of relocated image file %s",
                              relocated_filename.c_str());
    return false;
  }
  if (static_cast<uint64_t>(image_size) < sizeof(ImageHeader)) {
    *error_msg =
        StringPrintf(
            "Relocated image file %s too small: %" PRId64,
                relocated_filename.c_str(), image_size);
    return false;
  }
  if (image_size > std::numeric_limits<uint32_t>::max()) {
    *error_msg =
        StringPrintf(
            "Relocated image file %s too large: %" PRId64, relocated_filename.c_str(), image_size);
    return false;
  }

  std::unique_ptr<uint8_t[]> image(new uint8_t[image_size]);
  if (!image_file->ReadFully(image.get(), image_size)) {
    *error_msg = StringPrintf("Failed to read relocated image file %s", relocated_filename.c_str());
    return false;
  }

  const ImageHeader& image_header = *reinterpret_cast<const ImageHeader*>(image.get());
  if (image_header.GetStorageMode() != ImageHeader::kStorageModeUncompressed) {
    *error_msg = StringPrintf("Unsuported compressed image file %s",
                              relocated_filename.c_str());
    return false;
  }
  size_t image_end = image_header.GetClassTableSection().End();
  if (image_end > static_cast<uint64_t>(image_size) || !IsAligned<4u>(image_end)) {
    *error_msg = StringPrintf("Heap size too big or unaligned in image file %s: %zu",
                              relocated_filename.c_str(),
                              image_end);
    return false;
  }
  size_t number_of_relocation_locations = image_end / 4u;
  const ImageSection& relocation_section = image_header.GetImageRelocationsSection();
  if (relocation_section.Size() != BitsToBytesRoundUp(number_of_relocation_locations)) {
    *error_msg = StringPrintf("Unexpected size of relocation section in image file %s: %zu"
                                  " expected: %zu",
                              relocated_filename.c_str(),
                              static_cast<size_t>(relocation_section.Size()),
                              BitsToBytesRoundUp(number_of_relocation_locations));
    return false;
  }
  if (relocation_section.End() != image_size) {
    *error_msg = StringPrintf("Relocation section does not end at file end in image file %s: %zu"
                                  " expected: %" PRId64,
                              relocated_filename.c_str(),
                              static_cast<size_t>(relocation_section.End()),
                              image_size);
    return false;
  }

  off_t expected_diff = image_header.GetPatchDelta();
  if (expected_diff == 0) {
    *error_msg = StringPrintf("Unsuported patch delta of zero in %s",
                              relocated_filename.c_str());
    return false;
  }

  // Relocated image is expected to differ from the original due to relocation.
  // Unrelocate the image in memory to compensate.
  MemoryRegion relocations(image.get() + relocation_section.Offset(), relocation_section.Size());
  BitMemoryRegion relocation_bitmask(relocations,
                                     /* bit_offset */ 0u,
                                     number_of_relocation_locations);
  for (size_t index = 0; index != number_of_relocation_locations; ++index) {
    if (relocation_bitmask.LoadBit(index)) {
      uint32_t* image_value = reinterpret_cast<uint32_t*>(image.get() + index * 4u);
      *image_value -= expected_diff;
    }
  }

  // Image in memory is now supposed to be identical to the original.  We
  // confirm this by comparing the digest of the in-memory image to the expected
  // digest from relocation file.
  uint8_t image_digest[SHA256_DIGEST_LENGTH];
  SHA256(image.get(), image_size, image_digest);
  if (memcmp(image_digest, rel.get(), SHA256_DIGEST_LENGTH) != 0) {
    *error_msg =
        StringPrintf(
            "Relocated image %s does not match the original %s after unrelocation",
            relocated_filename.c_str(),
            original_filename.c_str());
    return false;
  }

  // Relocated image is identical to the original, once relocations are taken into account
  return true;
}

static bool VerifySymlink(const std::string& intended_target, const std::string& link_name) {
  std::string actual_target;
  if (!android::base::Readlink(link_name, &actual_target)) {
    PLOG(ERROR) << "Readlink on " << link_name << " failed.";
    return false;
  }
  return actual_target == intended_target;
}

static bool VerifyVdexAndOatSymlinks(const std::string& input_image_filename,
                                     const std::string& output_image_filename) {
  return VerifySymlink(ImageHeader::GetVdexLocationFromImageLocation(input_image_filename),
                       ImageHeader::GetVdexLocationFromImageLocation(output_image_filename))
      && VerifySymlink(ImageHeader::GetOatLocationFromImageLocation(input_image_filename),
                       ImageHeader::GetOatLocationFromImageLocation(output_image_filename));
}

bool PatchOat::CreateVdexAndOatSymlinks(const std::string& input_image_filename,
                                        const std::string& output_image_filename) {
  std::string input_vdex_filename =
      ImageHeader::GetVdexLocationFromImageLocation(input_image_filename);
  std::string input_oat_filename =
      ImageHeader::GetOatLocationFromImageLocation(input_image_filename);

  std::unique_ptr<File> input_oat_file(OS::OpenFileForReading(input_oat_filename.c_str()));
  if (input_oat_file.get() == nullptr) {
    LOG(ERROR) << "Unable to open input oat file at " << input_oat_filename;
    return false;
  }
  std::string error_msg;
  std::unique_ptr<ElfFile> elf(ElfFile::Open(input_oat_file.get(),
                                             PROT_READ | PROT_WRITE,
                                             MAP_PRIVATE,
                                             &error_msg));
  if (elf.get() == nullptr) {
    LOG(ERROR) << "Unable to open oat file " << input_oat_filename << " : " << error_msg;
    return false;
  }

  MaybePic is_oat_pic = IsOatPic(elf.get());
  if (is_oat_pic >= ERROR_FIRST) {
    // Error logged by IsOatPic
    return false;
  } else if (is_oat_pic == NOT_PIC) {
    LOG(ERROR) << "patchoat cannot be used on non-PIC oat file: " << input_oat_filename;
    return false;
  }

  CHECK(is_oat_pic == PIC);

  std::string output_vdex_filename =
      ImageHeader::GetVdexLocationFromImageLocation(output_image_filename);
  std::string output_oat_filename =
      ImageHeader::GetOatLocationFromImageLocation(output_image_filename);

  return SymlinkFile(input_oat_filename, output_oat_filename) &&
         SymlinkFile(input_vdex_filename, output_vdex_filename);
}

bool PatchOat::Patch(const std::string& image_location,
                     off_t delta,
                     const std::string& output_image_directory,
                     const std::string& output_image_relocation_directory,
                     InstructionSet isa,
                     TimingLogger* timings) {
  bool output_image = !output_image_directory.empty();
  bool output_image_relocation = !output_image_relocation_directory.empty();
  if ((!output_image) && (!output_image_relocation)) {
    // Nothing to do
    return true;
  }
  if ((output_image_relocation) && (delta == 0)) {
    LOG(ERROR) << "Cannot output image relocation information when requested relocation delta is 0";
    return false;
  }

  CHECK(Runtime::Current() == nullptr);
  CHECK(!image_location.empty()) << "image file must have a filename.";

  TimingLogger::ScopedTiming t("Runtime Setup", timings);

  CHECK_NE(isa, InstructionSet::kNone);

  // Set up the runtime
  PatchoatRuntimeOptionsHolder options_holder(image_location, isa);
  if (!Runtime::Create(options_holder.GetRuntimeOptions(), false)) {
    LOG(ERROR) << "Unable to initialize runtime";
    return false;
  }
  std::unique_ptr<Runtime> runtime(Runtime::Current());

  // Runtime::Create acquired the mutator_lock_ that is normally given away when we Runtime::Start,
  // give it away now and then switch to a more manageable ScopedObjectAccess.
  Thread::Current()->TransitionFromRunnableToSuspended(kNative);
  ScopedObjectAccess soa(Thread::Current());

  std::vector<gc::space::ImageSpace*> spaces = Runtime::Current()->GetHeap()->GetBootImageSpaces();
  std::map<gc::space::ImageSpace*, std::unique_ptr<MemMap>> space_to_memmap_map;

  for (size_t i = 0; i < spaces.size(); ++i) {
    t.NewTiming("Image Patching setup");
    gc::space::ImageSpace* space = spaces[i];
    std::string input_image_filename = space->GetImageFilename();
    std::unique_ptr<File> input_image(OS::OpenFileForReading(input_image_filename.c_str()));
    if (input_image.get() == nullptr) {
      LOG(ERROR) << "Unable to open input image file at " << input_image_filename;
      return false;
    }

    int64_t image_len = input_image->GetLength();
    if (image_len < 0) {
      LOG(ERROR) << "Error while getting image length";
      return false;
    }
    ImageHeader image_header;
    if (sizeof(image_header) != input_image->Read(reinterpret_cast<char*>(&image_header),
                                                  sizeof(image_header), 0)) {
      LOG(ERROR) << "Unable to read image header from image file " << input_image->GetPath();
    }

    /*bool is_image_pic = */IsImagePic(image_header, input_image->GetPath());
    // Nothing special to do right now since the image always needs to get patched.
    // Perhaps in some far-off future we may have images with relative addresses that are true-PIC.

    // Create the map where we will write the image patches to.
    std::string error_msg;
    std::unique_ptr<MemMap> image(MemMap::MapFile(image_len,
                                                  PROT_READ | PROT_WRITE,
                                                  MAP_PRIVATE,
                                                  input_image->Fd(),
                                                  0,
                                                  /*low_4gb*/false,
                                                  input_image->GetPath().c_str(),
                                                  &error_msg));
    if (image.get() == nullptr) {
      LOG(ERROR) << "Unable to map image file " << input_image->GetPath() << " : " << error_msg;
      return false;
    }


    space_to_memmap_map.emplace(space, std::move(image));
    PatchOat p = PatchOat(isa,
                          space_to_memmap_map[space].get(),
                          space->GetLiveBitmap(),
                          space->GetMemMap(),
                          delta,
                          &space_to_memmap_map,
                          timings);

    t.NewTiming("Patching image");
    if (!p.PatchImage(i == 0)) {
      LOG(ERROR) << "Failed to patch image file " << input_image_filename;
      return false;
    }

    // Write the patched image spaces.
    if (output_image) {
      std::string output_image_filename;
      if (!GetDalvikCacheFilename(space->GetImageLocation().c_str(),
                                  output_image_directory.c_str(),
                                  &output_image_filename,
                                  &error_msg)) {
        LOG(ERROR) << "Failed to find relocated image file name: " << error_msg;
        return false;
      }

      if (!CreateVdexAndOatSymlinks(input_image_filename, output_image_filename))
        return false;

      t.NewTiming("Writing image");
      std::unique_ptr<File> output_image_file(CreateOrOpen(output_image_filename.c_str()));
      if (output_image_file.get() == nullptr) {
        LOG(ERROR) << "Failed to open output image file at " << output_image_filename;
        return false;
      }

      bool success = p.WriteImage(output_image_file.get());
      success = FinishFile(output_image_file.get(), success);
      if (!success) {
        return false;
      }
    }

    if (output_image_relocation) {
      t.NewTiming("Writing image relocation");
      std::string original_image_filename(space->GetImageLocation() + ".rel");
      std::string image_relocation_filename =
          output_image_relocation_directory
              + (android::base::StartsWith(original_image_filename, "/") ? "" : "/")
              + original_image_filename.substr(original_image_filename.find_last_of("/"));
      int64_t input_image_size = input_image->GetLength();
      if (input_image_size < 0) {
        LOG(ERROR) << "Error while getting input image size";
        return false;
      }
      std::unique_ptr<MemMap> original(MemMap::MapFile(input_image_size,
                                                       PROT_READ,
                                                       MAP_PRIVATE,
                                                       input_image->Fd(),
                                                       0,
                                                       /*low_4gb*/false,
                                                       input_image->GetPath().c_str(),
                                                       &error_msg));
      if (original.get() == nullptr) {
        LOG(ERROR) << "Unable to map image file " << input_image->GetPath() << " : " << error_msg;
        return false;
      }

      const MemMap* relocated = p.image_;

      if (!WriteRelFile(*original, *relocated, image_relocation_filename, &error_msg)) {
        LOG(ERROR) << "Failed to create image relocation file " << image_relocation_filename
            << ": " << error_msg;
        return false;
      }
    }
  }

  if (!kIsDebugBuild && !(kRunningOnMemoryTool && kMemoryToolDetectsLeaks)) {
    // We want to just exit on non-debug builds, not bringing the runtime down
    // in an orderly fashion. So release the following fields.
    runtime.release();
  }

  return true;
}

bool PatchOat::Verify(const std::string& image_location,
                      const std::string& output_image_directory,
                      InstructionSet isa,
                      TimingLogger* timings) {
  if (image_location.empty()) {
    LOG(ERROR) << "Original image file not provided";
    return false;
  }
  if (output_image_directory.empty()) {
    LOG(ERROR) << "Relocated image directory not provided";
    return false;
  }

  TimingLogger::ScopedTiming t("Runtime Setup", timings);

  CHECK_NE(isa, InstructionSet::kNone);

  // Set up the runtime
  PatchoatRuntimeOptionsHolder options_holder(image_location, isa);
  if (!Runtime::Create(options_holder.GetRuntimeOptions(), false)) {
    LOG(ERROR) << "Unable to initialize runtime";
    return false;
  }
  std::unique_ptr<Runtime> runtime(Runtime::Current());

  // Runtime::Create acquired the mutator_lock_ that is normally given away when we Runtime::Start,
  // give it away now and then switch to a more manageable ScopedObjectAccess.
  Thread::Current()->TransitionFromRunnableToSuspended(kNative);
  ScopedObjectAccess soa(Thread::Current());

  t.NewTiming("Image Verification setup");
  std::vector<gc::space::ImageSpace*> spaces = Runtime::Current()->GetHeap()->GetBootImageSpaces();

  // TODO: Check that no other .rel files exist in the original dir

  bool success = true;
  std::string image_location_dir = android::base::Dirname(image_location);
  for (size_t i = 0; i < spaces.size(); ++i) {
    gc::space::ImageSpace* space = spaces[i];

    std::string relocated_image_filename;
    std::string error_msg;
    if (!GetDalvikCacheFilename(space->GetImageLocation().c_str(),
            output_image_directory.c_str(), &relocated_image_filename, &error_msg)) {
      LOG(ERROR) << "Failed to find relocated image file name: " << error_msg;
      success = false;
      break;
    }
    // location:     /system/framework/boot.art
    // isa:          arm64
    // basename:     boot.art
    // original:     /system/framework/arm64/boot.art
    // relocation:   /system/framework/arm64/boot.art.rel
    std::string original_image_filename =
        GetSystemImageFilename(space->GetImageLocation().c_str(), isa);

    if (!CheckImageIdenticalToOriginalExceptForRelocation(
            relocated_image_filename, original_image_filename, &error_msg)) {
      LOG(ERROR) << error_msg;
      success = false;
      break;
    }

    if (!VerifyVdexAndOatSymlinks(original_image_filename, relocated_image_filename)) {
      LOG(ERROR) << "Verification of vdex and oat symlinks for "
                 << space->GetImageLocation() << " failed.";
      success = false;
      break;
    }
  }

  if (!kIsDebugBuild && !(kRunningOnMemoryTool && kMemoryToolDetectsLeaks)) {
    // We want to just exit on non-debug builds, not bringing the runtime down
    // in an orderly fashion. So release the following fields.
    runtime.release();
  }

  return success;
}

bool PatchOat::WriteImage(File* out) {
  CHECK(out != nullptr);
  TimingLogger::ScopedTiming t("Writing image File", timings_);
  std::string error_msg;

  // No error checking here, this is best effort. The locking may or may not
  // succeed and we don't really care either way.
  ScopedFlock img_flock = LockedFile::DupOf(out->Fd(), out->GetPath(),
                                            true /* read_only_mode */, &error_msg);

  CHECK(image_ != nullptr);
  size_t expect = image_->Size();
  if (out->WriteFully(reinterpret_cast<char*>(image_->Begin()), expect) &&
      out->SetLength(expect) == 0) {
    return true;
  } else {
    LOG(ERROR) << "Writing to image file " << out->GetPath() << " failed.";
    return false;
  }
}

bool PatchOat::IsImagePic(const ImageHeader& image_header, const std::string& image_path) {
  if (!image_header.CompilePic()) {
    if (kIsDebugBuild) {
      LOG(INFO) << "image at location " << image_path << " was *not* compiled pic";
    }
    return false;
  }

  if (kIsDebugBuild) {
    LOG(INFO) << "image at location " << image_path << " was compiled PIC";
  }

  return true;
}

PatchOat::MaybePic PatchOat::IsOatPic(const ElfFile* oat_in) {
  if (oat_in == nullptr) {
    LOG(ERROR) << "No ELF input oat fie available";
    return ERROR_OAT_FILE;
  }

  const std::string& file_path = oat_in->GetFilePath();

  const OatHeader* oat_header = GetOatHeader(oat_in);
  if (oat_header == nullptr) {
    LOG(ERROR) << "Failed to find oat header in oat file " << file_path;
    return ERROR_OAT_FILE;
  }

  if (!oat_header->IsValid()) {
    LOG(ERROR) << "Elf file " << file_path << " has an invalid oat header";
    return ERROR_OAT_FILE;
  }

  bool is_pic = oat_header->IsPic();
  if (kIsDebugBuild) {
    LOG(INFO) << "Oat file at " << file_path << " is " << (is_pic ? "PIC" : "not pic");
  }

  return is_pic ? PIC : NOT_PIC;
}

class PatchOat::PatchOatArtFieldVisitor : public ArtFieldVisitor {
 public:
  explicit PatchOatArtFieldVisitor(PatchOat* patch_oat) : patch_oat_(patch_oat) {}

  void Visit(ArtField* field) OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
    ArtField* const dest = patch_oat_->RelocatedCopyOf(field);
    dest->SetDeclaringClass(
        patch_oat_->RelocatedAddressOfPointer(field->GetDeclaringClass().Ptr()));
  }

 private:
  PatchOat* const patch_oat_;
};

void PatchOat::PatchArtFields(const ImageHeader* image_header) {
  PatchOatArtFieldVisitor visitor(this);
  image_header->VisitPackedArtFields(&visitor, heap_->Begin());
}

class PatchOat::PatchOatArtMethodVisitor : public ArtMethodVisitor {
 public:
  explicit PatchOatArtMethodVisitor(PatchOat* patch_oat) : patch_oat_(patch_oat) {}

  void Visit(ArtMethod* method) OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
    ArtMethod* const dest = patch_oat_->RelocatedCopyOf(method);
    patch_oat_->FixupMethod(method, dest);
  }

 private:
  PatchOat* const patch_oat_;
};

void PatchOat::PatchArtMethods(const ImageHeader* image_header) {
  const PointerSize pointer_size = InstructionSetPointerSize(isa_);
  PatchOatArtMethodVisitor visitor(this);
  image_header->VisitPackedArtMethods(&visitor, heap_->Begin(), pointer_size);
}

void PatchOat::PatchImTables(const ImageHeader* image_header) {
  const PointerSize pointer_size = InstructionSetPointerSize(isa_);
  // We can safely walk target image since the conflict tables are independent.
  image_header->VisitPackedImTables(
      [this](ArtMethod* method) {
        return RelocatedAddressOfPointer(method);
      },
      image_->Begin(),
      pointer_size);
}

void PatchOat::PatchImtConflictTables(const ImageHeader* image_header) {
  const PointerSize pointer_size = InstructionSetPointerSize(isa_);
  // We can safely walk target image since the conflict tables are independent.
  image_header->VisitPackedImtConflictTables(
      [this](ArtMethod* method) {
        return RelocatedAddressOfPointer(method);
      },
      image_->Begin(),
      pointer_size);
}

class PatchOat::FixupRootVisitor : public RootVisitor {
 public:
  explicit FixupRootVisitor(const PatchOat* patch_oat) : patch_oat_(patch_oat) {
  }

  void VisitRoots(mirror::Object*** roots, size_t count, const RootInfo& info ATTRIBUTE_UNUSED)
      OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
    for (size_t i = 0; i < count; ++i) {
      *roots[i] = patch_oat_->RelocatedAddressOfPointer(*roots[i]);
    }
  }

  void VisitRoots(mirror::CompressedReference<mirror::Object>** roots, size_t count,
                  const RootInfo& info ATTRIBUTE_UNUSED)
      OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
    for (size_t i = 0; i < count; ++i) {
      roots[i]->Assign(patch_oat_->RelocatedAddressOfPointer(roots[i]->AsMirrorPtr()));
    }
  }

 private:
  const PatchOat* const patch_oat_;
};

void PatchOat::PatchInternedStrings(const ImageHeader* image_header) {
  const auto& section = image_header->GetInternedStringsSection();
  if (section.Size() == 0) {
    return;
  }
  InternTable temp_table;
  // Note that we require that ReadFromMemory does not make an internal copy of the elements.
  // This also relies on visit roots not doing any verification which could fail after we update
  // the roots to be the image addresses.
  temp_table.AddTableFromMemory(image_->Begin() + section.Offset());
  FixupRootVisitor visitor(this);
  temp_table.VisitRoots(&visitor, kVisitRootFlagAllRoots);
}

void PatchOat::PatchClassTable(const ImageHeader* image_header) {
  const auto& section = image_header->GetClassTableSection();
  if (section.Size() == 0) {
    return;
  }
  // Note that we require that ReadFromMemory does not make an internal copy of the elements.
  // This also relies on visit roots not doing any verification which could fail after we update
  // the roots to be the image addresses.
  WriterMutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_);
  ClassTable temp_table;
  temp_table.ReadFromMemory(image_->Begin() + section.Offset());
  FixupRootVisitor visitor(this);
  temp_table.VisitRoots(UnbufferedRootVisitor(&visitor, RootInfo(kRootUnknown)));
}


class PatchOat::RelocatedPointerVisitor {
 public:
  explicit RelocatedPointerVisitor(PatchOat* patch_oat) : patch_oat_(patch_oat) {}

  template <typename T>
  T* operator()(T* ptr, void** dest_addr ATTRIBUTE_UNUSED = nullptr) const {
    return patch_oat_->RelocatedAddressOfPointer(ptr);
  }

 private:
  PatchOat* const patch_oat_;
};

void PatchOat::PatchDexFileArrays(mirror::ObjectArray<mirror::Object>* img_roots) {
  auto* dex_caches = down_cast<mirror::ObjectArray<mirror::DexCache>*>(
      img_roots->Get(ImageHeader::kDexCaches));
  const PointerSize pointer_size = InstructionSetPointerSize(isa_);
  for (size_t i = 0, count = dex_caches->GetLength(); i < count; ++i) {
    auto* orig_dex_cache = dex_caches->GetWithoutChecks(i);
    auto* copy_dex_cache = RelocatedCopyOf(orig_dex_cache);
    // Though the DexCache array fields are usually treated as native pointers, we set the full
    // 64-bit values here, clearing the top 32 bits for 32-bit targets. The zero-extension is
    // done by casting to the unsigned type uintptr_t before casting to int64_t, i.e.
    //     static_cast<int64_t>(reinterpret_cast<uintptr_t>(image_begin_ + offset))).
    mirror::StringDexCacheType* orig_strings = orig_dex_cache->GetStrings();
    mirror::StringDexCacheType* relocated_strings = RelocatedAddressOfPointer(orig_strings);
    copy_dex_cache->SetField64<false>(
        mirror::DexCache::StringsOffset(),
        static_cast<int64_t>(reinterpret_cast<uintptr_t>(relocated_strings)));
    if (orig_strings != nullptr) {
      orig_dex_cache->FixupStrings(RelocatedCopyOf(orig_strings), RelocatedPointerVisitor(this));
    }
    mirror::TypeDexCacheType* orig_types = orig_dex_cache->GetResolvedTypes();
    mirror::TypeDexCacheType* relocated_types = RelocatedAddressOfPointer(orig_types);
    copy_dex_cache->SetField64<false>(
        mirror::DexCache::ResolvedTypesOffset(),
        static_cast<int64_t>(reinterpret_cast<uintptr_t>(relocated_types)));
    if (orig_types != nullptr) {
      orig_dex_cache->FixupResolvedTypes(RelocatedCopyOf(orig_types),
                                         RelocatedPointerVisitor(this));
    }
    mirror::MethodDexCacheType* orig_methods = orig_dex_cache->GetResolvedMethods();
    mirror::MethodDexCacheType* relocated_methods = RelocatedAddressOfPointer(orig_methods);
    copy_dex_cache->SetField64<false>(
        mirror::DexCache::ResolvedMethodsOffset(),
        static_cast<int64_t>(reinterpret_cast<uintptr_t>(relocated_methods)));
    if (orig_methods != nullptr) {
      mirror::MethodDexCacheType* copy_methods = RelocatedCopyOf(orig_methods);
      for (size_t j = 0, num = orig_dex_cache->NumResolvedMethods(); j != num; ++j) {
        mirror::MethodDexCachePair orig =
            mirror::DexCache::GetNativePairPtrSize(orig_methods, j, pointer_size);
        mirror::MethodDexCachePair copy(RelocatedAddressOfPointer(orig.object), orig.index);
        mirror::DexCache::SetNativePairPtrSize(copy_methods, j, copy, pointer_size);
      }
    }
    mirror::FieldDexCacheType* orig_fields = orig_dex_cache->GetResolvedFields();
    mirror::FieldDexCacheType* relocated_fields = RelocatedAddressOfPointer(orig_fields);
    copy_dex_cache->SetField64<false>(
        mirror::DexCache::ResolvedFieldsOffset(),
        static_cast<int64_t>(reinterpret_cast<uintptr_t>(relocated_fields)));
    if (orig_fields != nullptr) {
      mirror::FieldDexCacheType* copy_fields = RelocatedCopyOf(orig_fields);
      for (size_t j = 0, num = orig_dex_cache->NumResolvedFields(); j != num; ++j) {
        mirror::FieldDexCachePair orig =
            mirror::DexCache::GetNativePairPtrSize(orig_fields, j, pointer_size);
        mirror::FieldDexCachePair copy(RelocatedAddressOfPointer(orig.object), orig.index);
        mirror::DexCache::SetNativePairPtrSize(copy_fields, j, copy, pointer_size);
      }
    }
    mirror::MethodTypeDexCacheType* orig_method_types = orig_dex_cache->GetResolvedMethodTypes();
    mirror::MethodTypeDexCacheType* relocated_method_types =
        RelocatedAddressOfPointer(orig_method_types);
    copy_dex_cache->SetField64<false>(
        mirror::DexCache::ResolvedMethodTypesOffset(),
        static_cast<int64_t>(reinterpret_cast<uintptr_t>(relocated_method_types)));
    if (orig_method_types != nullptr) {
      orig_dex_cache->FixupResolvedMethodTypes(RelocatedCopyOf(orig_method_types),
                                               RelocatedPointerVisitor(this));
    }

    GcRoot<mirror::CallSite>* orig_call_sites = orig_dex_cache->GetResolvedCallSites();
    GcRoot<mirror::CallSite>* relocated_call_sites = RelocatedAddressOfPointer(orig_call_sites);
    copy_dex_cache->SetField64<false>(
        mirror::DexCache::ResolvedCallSitesOffset(),
        static_cast<int64_t>(reinterpret_cast<uintptr_t>(relocated_call_sites)));
    if (orig_call_sites != nullptr) {
      orig_dex_cache->FixupResolvedCallSites(RelocatedCopyOf(orig_call_sites),
                                             RelocatedPointerVisitor(this));
    }
  }
}

bool PatchOat::PatchImage(bool primary_image) {
  ImageHeader* image_header = reinterpret_cast<ImageHeader*>(image_->Begin());
  CHECK_GT(image_->Size(), sizeof(ImageHeader));
  // These are the roots from the original file.
  mirror::ObjectArray<mirror::Object>* img_roots = image_header->GetImageRoots().Ptr();
  image_header->RelocateImage(delta_);

  PatchArtFields(image_header);
  PatchArtMethods(image_header);
  PatchImTables(image_header);
  PatchImtConflictTables(image_header);
  PatchInternedStrings(image_header);
  PatchClassTable(image_header);
  // Patch dex file int/long arrays which point to ArtFields.
  PatchDexFileArrays(img_roots);

  if (primary_image) {
    VisitObject(img_roots);
  }

  if (!image_header->IsValid()) {
    LOG(ERROR) << "relocation renders image header invalid";
    return false;
  }

  {
    TimingLogger::ScopedTiming t("Walk Bitmap", timings_);
    // Walk the bitmap.
    WriterMutexLock mu(Thread::Current(), *Locks::heap_bitmap_lock_);
    auto visitor = [&](mirror::Object* obj) REQUIRES_SHARED(Locks::mutator_lock_) {
      VisitObject(obj);
    };
    bitmap_->Walk(visitor);
  }
  return true;
}


void PatchOat::PatchVisitor::operator() (ObjPtr<mirror::Object> obj,
                                         MemberOffset off,
                                         bool is_static_unused ATTRIBUTE_UNUSED) const {
  mirror::Object* referent = obj->GetFieldObject<mirror::Object, kVerifyNone>(off);
  mirror::Object* moved_object = patcher_->RelocatedAddressOfPointer(referent);
  copy_->SetFieldObjectWithoutWriteBarrier<false, true, kVerifyNone>(off, moved_object);
}

void PatchOat::PatchVisitor::operator() (ObjPtr<mirror::Class> cls ATTRIBUTE_UNUSED,
                                         ObjPtr<mirror::Reference> ref) const {
  MemberOffset off = mirror::Reference::ReferentOffset();
  mirror::Object* referent = ref->GetReferent();
  DCHECK(referent == nullptr ||
         Runtime::Current()->GetHeap()->ObjectIsInBootImageSpace(referent)) << referent;
  mirror::Object* moved_object = patcher_->RelocatedAddressOfPointer(referent);
  copy_->SetFieldObjectWithoutWriteBarrier<false, true, kVerifyNone>(off, moved_object);
}

// Called by PatchImage.
void PatchOat::VisitObject(mirror::Object* object) {
  mirror::Object* copy = RelocatedCopyOf(object);
  CHECK(copy != nullptr);
  if (kUseBakerReadBarrier) {
    object->AssertReadBarrierState();
  }
  PatchOat::PatchVisitor visitor(this, copy);
  object->VisitReferences<kVerifyNone>(visitor, visitor);
  if (object->IsClass<kVerifyNone>()) {
    const PointerSize pointer_size = InstructionSetPointerSize(isa_);
    mirror::Class* klass = object->AsClass();
    mirror::Class* copy_klass = down_cast<mirror::Class*>(copy);
    RelocatedPointerVisitor native_visitor(this);
    klass->FixupNativePointers(copy_klass, pointer_size, native_visitor);
    auto* vtable = klass->GetVTable();
    if (vtable != nullptr) {
      vtable->Fixup(RelocatedCopyOfFollowImages(vtable), pointer_size, native_visitor);
    }
    mirror::IfTable* iftable = klass->GetIfTable();
    for (int32_t i = 0; i < klass->GetIfTableCount(); ++i) {
      if (iftable->GetMethodArrayCount(i) > 0) {
        auto* method_array = iftable->GetMethodArray(i);
        CHECK(method_array != nullptr);
        method_array->Fixup(RelocatedCopyOfFollowImages(method_array),
                            pointer_size,
                            native_visitor);
      }
    }
  } else if (object->GetClass() == GetClassRoot<mirror::Method>() ||
             object->GetClass() == GetClassRoot<mirror::Constructor>()) {
    // Need to go update the ArtMethod.
    auto* dest = down_cast<mirror::Executable*>(copy);
    auto* src = down_cast<mirror::Executable*>(object);
    dest->SetArtMethod(RelocatedAddressOfPointer(src->GetArtMethod()));
  }
}

void PatchOat::FixupMethod(ArtMethod* object, ArtMethod* copy) {
  const PointerSize pointer_size = InstructionSetPointerSize(isa_);
  copy->CopyFrom(object, pointer_size);
  // Just update the entry points if it looks like we should.
  // TODO: sanity check all the pointers' values
  copy->SetDeclaringClass(RelocatedAddressOfPointer(object->GetDeclaringClass().Ptr()));
  copy->SetEntryPointFromQuickCompiledCodePtrSize(RelocatedAddressOfPointer(
      object->GetEntryPointFromQuickCompiledCodePtrSize(pointer_size)), pointer_size);
  // No special handling for IMT conflict table since all pointers are moved by the same offset.
  copy->SetDataPtrSize(RelocatedAddressOfPointer(
      object->GetDataPtrSize(pointer_size)), pointer_size);
}

static int orig_argc;
static char** orig_argv;

static std::string CommandLine() {
  std::vector<std::string> command;
  for (int i = 0; i < orig_argc; ++i) {
    command.push_back(orig_argv[i]);
  }
  return android::base::Join(command, ' ');
}

static void UsageErrorV(const char* fmt, va_list ap) {
  std::string error;
  android::base::StringAppendV(&error, fmt, ap);
  LOG(ERROR) << error;
}

static void UsageError(const char* fmt, ...) {
  va_list ap;
  va_start(ap, fmt);
  UsageErrorV(fmt, ap);
  va_end(ap);
}

NO_RETURN static void Usage(const char *fmt, ...) {
  va_list ap;
  va_start(ap, fmt);
  UsageErrorV(fmt, ap);
  va_end(ap);

  UsageError("Command: %s", CommandLine().c_str());
  UsageError("Usage: patchoat [options]...");
  UsageError("");
  UsageError("  --instruction-set=<isa>: Specifies the instruction set the patched code is");
  UsageError("      compiled for (required).");
  UsageError("");
  UsageError("  --input-image-location=<file.art>: Specifies the 'location' of the image file to");
  UsageError("      be patched.");
  UsageError("");
  UsageError("  --output-image-directory=<dir>: Specifies the directory to write the patched");
  UsageError("      image file(s) to.");
  UsageError("");
  UsageError("  --output-image-relocation-directory=<dir>: Specifies the directory to write");
  UsageError("      the image relocation information to.");
  UsageError("");
  UsageError("  --base-offset-delta=<delta>: Specify the amount to change the old base-offset by.");
  UsageError("      This value may be negative.");
  UsageError("");
  UsageError("  --verify: Verify an existing patched file instead of creating one.");
  UsageError("");
  UsageError("  --dump-timings: dump out patch timing information");
  UsageError("");
  UsageError("  --no-dump-timings: do not dump out patch timing information");
  UsageError("");

  exit(EXIT_FAILURE);
}

static int patchoat_patch_image(TimingLogger& timings,
                                InstructionSet isa,
                                const std::string& input_image_location,
                                const std::string& output_image_directory,
                                const std::string& output_image_relocation_directory,
                                off_t base_delta,
                                bool base_delta_set,
                                bool debug) {
  CHECK(!input_image_location.empty());
  if ((output_image_directory.empty()) && (output_image_relocation_directory.empty())) {
    Usage("Image patching requires --output-image-directory or --output-image-relocation-directory");
  }

  if (!base_delta_set) {
    Usage("Must supply a desired new offset or delta.");
  }

  if (!IsAligned<kPageSize>(base_delta)) {
    Usage("Base offset/delta must be aligned to a pagesize (0x%08x) boundary.", kPageSize);
  }

  if (debug) {
    LOG(INFO) << "moving offset by " << base_delta
        << " (0x" << std::hex << base_delta << ") bytes or "
        << std::dec << (base_delta/kPageSize) << " pages.";
  }

  TimingLogger::ScopedTiming pt("patch image and oat", &timings);

  bool ret =
      PatchOat::Patch(
          input_image_location,
          base_delta,
          output_image_directory,
          output_image_relocation_directory,
          isa,
          &timings);

  if (kIsDebugBuild) {
    LOG(INFO) << "Exiting with return ... " << ret;
  }
  return ret ? EXIT_SUCCESS : EXIT_FAILURE;
}

static int patchoat_verify_image(TimingLogger& timings,
                                 InstructionSet isa,
                                 const std::string& input_image_location,
                                 const std::string& output_image_directory) {
  CHECK(!input_image_location.empty());
  TimingLogger::ScopedTiming pt("verify image and oat", &timings);

  bool ret =
      PatchOat::Verify(
          input_image_location,
          output_image_directory,
          isa,
          &timings);

  if (kIsDebugBuild) {
    LOG(INFO) << "Exiting with return ... " << ret;
  }
  return ret ? EXIT_SUCCESS : EXIT_FAILURE;
}

static int patchoat(int argc, char **argv) {
  Locks::Init();
  InitLogging(argv, Runtime::Abort);
  MemMap::Init();
  const bool debug = kIsDebugBuild;
  orig_argc = argc;
  orig_argv = argv;
  TimingLogger timings("patcher", false, false);

  // Skip over the command name.
  argv++;
  argc--;

  if (argc == 0) {
    Usage("No arguments specified");
  }

  timings.StartTiming("Patchoat");

  // cmd line args
  bool isa_set = false;
  InstructionSet isa = InstructionSet::kNone;
  std::string input_image_location;
  std::string output_image_directory;
  std::string output_image_relocation_directory;
  off_t base_delta = 0;
  bool base_delta_set = false;
  bool dump_timings = kIsDebugBuild;
  bool verify = false;

  for (int i = 0; i < argc; ++i) {
    const StringPiece option(argv[i]);
    const bool log_options = false;
    if (log_options) {
      LOG(INFO) << "patchoat: option[" << i << "]=" << argv[i];
    }
    if (option.starts_with("--instruction-set=")) {
      isa_set = true;
      const char* isa_str = option.substr(strlen("--instruction-set=")).data();
      isa = GetInstructionSetFromString(isa_str);
      if (isa == InstructionSet::kNone) {
        Usage("Unknown or invalid instruction set %s", isa_str);
      }
    } else if (option.starts_with("--input-image-location=")) {
      input_image_location = option.substr(strlen("--input-image-location=")).data();
    } else if (option.starts_with("--output-image-directory=")) {
      output_image_directory = option.substr(strlen("--output-image-directory=")).data();
    } else if (option.starts_with("--output-image-relocation-directory=")) {
      output_image_relocation_directory =
          option.substr(strlen("--output-image-relocation-directory=")).data();
    } else if (option.starts_with("--base-offset-delta=")) {
      const char* base_delta_str = option.substr(strlen("--base-offset-delta=")).data();
      base_delta_set = true;
      if (!ParseInt(base_delta_str, &base_delta)) {
        Usage("Failed to parse --base-offset-delta argument '%s' as an off_t", base_delta_str);
      }
    } else if (option == "--dump-timings") {
      dump_timings = true;
    } else if (option == "--no-dump-timings") {
      dump_timings = false;
    } else if (option == "--verify") {
      verify = true;
    } else {
      Usage("Unknown argument %s", option.data());
    }
  }

  // The instruction set is mandatory. This simplifies things...
  if (!isa_set) {
    Usage("Instruction set must be set.");
  }

  int ret;
  if (verify) {
    ret = patchoat_verify_image(timings,
                                isa,
                                input_image_location,
                                output_image_directory);
  } else {
    ret = patchoat_patch_image(timings,
                               isa,
                               input_image_location,
                               output_image_directory,
                               output_image_relocation_directory,
                               base_delta,
                               base_delta_set,
                               debug);
  }

  timings.EndTiming();
  if (dump_timings) {
    LOG(INFO) << Dumpable<TimingLogger>(timings);
  }

  return ret;
}

}  // namespace art

int main(int argc, char **argv) {
  return art::patchoat(argc, argv);
}
