Home | History | Annotate | Download | only in patchoat
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 #include "patchoat.h"
     17 
     18 #include <stdio.h>
     19 #include <stdlib.h>
     20 #include <sys/file.h>
     21 #include <sys/stat.h>
     22 #include <unistd.h>
     23 
     24 #include <string>
     25 #include <vector>
     26 
     27 #include "android-base/stringprintf.h"
     28 #include "android-base/strings.h"
     29 
     30 #include "art_field-inl.h"
     31 #include "art_method-inl.h"
     32 #include "base/dumpable.h"
     33 #include "base/memory_tool.h"
     34 #include "base/scoped_flock.h"
     35 #include "base/stringpiece.h"
     36 #include "base/unix_file/fd_file.h"
     37 #include "base/unix_file/random_access_file_utils.h"
     38 #include "elf_utils.h"
     39 #include "elf_file.h"
     40 #include "elf_file_impl.h"
     41 #include "gc/space/image_space.h"
     42 #include "image-inl.h"
     43 #include "intern_table.h"
     44 #include "mirror/dex_cache.h"
     45 #include "mirror/executable.h"
     46 #include "mirror/object-inl.h"
     47 #include "mirror/object-refvisitor-inl.h"
     48 #include "mirror/method.h"
     49 #include "mirror/reference.h"
     50 #include "noop_compiler_callbacks.h"
     51 #include "offsets.h"
     52 #include "os.h"
     53 #include "runtime.h"
     54 #include "scoped_thread_state_change-inl.h"
     55 #include "thread.h"
     56 #include "utils.h"
     57 
     58 namespace art {
     59 
     60 static const OatHeader* GetOatHeader(const ElfFile* elf_file) {
     61   uint64_t off = 0;
     62   if (!elf_file->GetSectionOffsetAndSize(".rodata", &off, nullptr)) {
     63     return nullptr;
     64   }
     65 
     66   OatHeader* oat_header = reinterpret_cast<OatHeader*>(elf_file->Begin() + off);
     67   return oat_header;
     68 }
     69 
     70 static File* CreateOrOpen(const char* name) {
     71   if (OS::FileExists(name)) {
     72     return OS::OpenFileReadWrite(name);
     73   } else {
     74     std::unique_ptr<File> f(OS::CreateEmptyFile(name));
     75     if (f.get() != nullptr) {
     76       if (fchmod(f->Fd(), 0644) != 0) {
     77         PLOG(ERROR) << "Unable to make " << name << " world readable";
     78         unlink(name);
     79         return nullptr;
     80       }
     81     }
     82     return f.release();
     83   }
     84 }
     85 
     86 // Either try to close the file (close=true), or erase it.
     87 static bool FinishFile(File* file, bool close) {
     88   if (close) {
     89     if (file->FlushCloseOrErase() != 0) {
     90       PLOG(ERROR) << "Failed to flush and close file.";
     91       return false;
     92     }
     93     return true;
     94   } else {
     95     file->Erase();
     96     return false;
     97   }
     98 }
     99 
    100 static bool SymlinkFile(const std::string& input_filename, const std::string& output_filename) {
    101   if (input_filename == output_filename) {
    102     // Input and output are the same, nothing to do.
    103     return true;
    104   }
    105 
    106   // Unlink the original filename, since we are overwriting it.
    107   unlink(output_filename.c_str());
    108 
    109   // Create a symlink from the source file to the target path.
    110   if (symlink(input_filename.c_str(), output_filename.c_str()) < 0) {
    111     PLOG(ERROR) << "Failed to create symlink " << output_filename << " -> " << input_filename;
    112     return false;
    113   }
    114 
    115   if (kIsDebugBuild) {
    116     LOG(INFO) << "Created symlink " << output_filename << " -> " << input_filename;
    117   }
    118 
    119   return true;
    120 }
    121 
    122 bool PatchOat::Patch(const std::string& image_location,
    123                      off_t delta,
    124                      const std::string& output_directory,
    125                      InstructionSet isa,
    126                      TimingLogger* timings) {
    127   CHECK(Runtime::Current() == nullptr);
    128   CHECK(!image_location.empty()) << "image file must have a filename.";
    129 
    130   TimingLogger::ScopedTiming t("Runtime Setup", timings);
    131 
    132   CHECK_NE(isa, kNone);
    133   const char* isa_name = GetInstructionSetString(isa);
    134 
    135   // Set up the runtime
    136   RuntimeOptions options;
    137   NoopCompilerCallbacks callbacks;
    138   options.push_back(std::make_pair("compilercallbacks", &callbacks));
    139   std::string img = "-Ximage:" + image_location;
    140   options.push_back(std::make_pair(img.c_str(), nullptr));
    141   options.push_back(std::make_pair("imageinstructionset", reinterpret_cast<const void*>(isa_name)));
    142   options.push_back(std::make_pair("-Xno-sig-chain", nullptr));
    143   if (!Runtime::Create(options, false)) {
    144     LOG(ERROR) << "Unable to initialize runtime";
    145     return false;
    146   }
    147   std::unique_ptr<Runtime> runtime(Runtime::Current());
    148 
    149   // Runtime::Create acquired the mutator_lock_ that is normally given away when we Runtime::Start,
    150   // give it away now and then switch to a more manageable ScopedObjectAccess.
    151   Thread::Current()->TransitionFromRunnableToSuspended(kNative);
    152   ScopedObjectAccess soa(Thread::Current());
    153 
    154   t.NewTiming("Image Patching setup");
    155   std::vector<gc::space::ImageSpace*> spaces = Runtime::Current()->GetHeap()->GetBootImageSpaces();
    156   std::map<gc::space::ImageSpace*, std::unique_ptr<File>> space_to_file_map;
    157   std::map<gc::space::ImageSpace*, std::unique_ptr<MemMap>> space_to_memmap_map;
    158   std::map<gc::space::ImageSpace*, PatchOat> space_to_patchoat_map;
    159 
    160   for (size_t i = 0; i < spaces.size(); ++i) {
    161     gc::space::ImageSpace* space = spaces[i];
    162     std::string input_image_filename = space->GetImageFilename();
    163     std::unique_ptr<File> input_image(OS::OpenFileForReading(input_image_filename.c_str()));
    164     if (input_image.get() == nullptr) {
    165       LOG(ERROR) << "Unable to open input image file at " << input_image_filename;
    166       return false;
    167     }
    168 
    169     int64_t image_len = input_image->GetLength();
    170     if (image_len < 0) {
    171       LOG(ERROR) << "Error while getting image length";
    172       return false;
    173     }
    174     ImageHeader image_header;
    175     if (sizeof(image_header) != input_image->Read(reinterpret_cast<char*>(&image_header),
    176                                                   sizeof(image_header), 0)) {
    177       LOG(ERROR) << "Unable to read image header from image file " << input_image->GetPath();
    178     }
    179 
    180     /*bool is_image_pic = */IsImagePic(image_header, input_image->GetPath());
    181     // Nothing special to do right now since the image always needs to get patched.
    182     // Perhaps in some far-off future we may have images with relative addresses that are true-PIC.
    183 
    184     // Create the map where we will write the image patches to.
    185     std::string error_msg;
    186     std::unique_ptr<MemMap> image(MemMap::MapFile(image_len,
    187                                                   PROT_READ | PROT_WRITE,
    188                                                   MAP_PRIVATE,
    189                                                   input_image->Fd(),
    190                                                   0,
    191                                                   /*low_4gb*/false,
    192                                                   input_image->GetPath().c_str(),
    193                                                   &error_msg));
    194     if (image.get() == nullptr) {
    195       LOG(ERROR) << "Unable to map image file " << input_image->GetPath() << " : " << error_msg;
    196       return false;
    197     }
    198     space_to_file_map.emplace(space, std::move(input_image));
    199     space_to_memmap_map.emplace(space, std::move(image));
    200   }
    201 
    202   // Symlink PIC oat and vdex files and patch the image spaces in memory.
    203   for (size_t i = 0; i < spaces.size(); ++i) {
    204     gc::space::ImageSpace* space = spaces[i];
    205     std::string input_image_filename = space->GetImageFilename();
    206     std::string input_vdex_filename =
    207         ImageHeader::GetVdexLocationFromImageLocation(input_image_filename);
    208     std::string input_oat_filename =
    209         ImageHeader::GetOatLocationFromImageLocation(input_image_filename);
    210     std::unique_ptr<File> input_oat_file(OS::OpenFileForReading(input_oat_filename.c_str()));
    211     if (input_oat_file.get() == nullptr) {
    212       LOG(ERROR) << "Unable to open input oat file at " << input_oat_filename;
    213       return false;
    214     }
    215     std::string error_msg;
    216     std::unique_ptr<ElfFile> elf(ElfFile::Open(input_oat_file.get(),
    217                                                PROT_READ | PROT_WRITE, MAP_PRIVATE, &error_msg));
    218     if (elf.get() == nullptr) {
    219       LOG(ERROR) << "Unable to open oat file " << input_oat_file->GetPath() << " : " << error_msg;
    220       return false;
    221     }
    222 
    223     MaybePic is_oat_pic = IsOatPic(elf.get());
    224     if (is_oat_pic >= ERROR_FIRST) {
    225       // Error logged by IsOatPic
    226       return false;
    227     } else if (is_oat_pic == NOT_PIC) {
    228       LOG(ERROR) << "patchoat cannot be used on non-PIC oat file: " << input_oat_file->GetPath();
    229       return false;
    230     } else {
    231       CHECK(is_oat_pic == PIC);
    232 
    233       // Create a symlink.
    234       std::string converted_image_filename = space->GetImageLocation();
    235       std::replace(converted_image_filename.begin() + 1, converted_image_filename.end(), '/', '@');
    236       std::string output_image_filename = output_directory +
    237           (android::base::StartsWith(converted_image_filename, "/") ? "" : "/") +
    238           converted_image_filename;
    239       std::string output_vdex_filename =
    240           ImageHeader::GetVdexLocationFromImageLocation(output_image_filename);
    241       std::string output_oat_filename =
    242           ImageHeader::GetOatLocationFromImageLocation(output_image_filename);
    243 
    244       if (!ReplaceOatFileWithSymlink(input_oat_file->GetPath(),
    245                                      output_oat_filename) ||
    246           !SymlinkFile(input_vdex_filename, output_vdex_filename)) {
    247         // Errors already logged by above call.
    248         return false;
    249       }
    250     }
    251 
    252     PatchOat& p = space_to_patchoat_map.emplace(space,
    253                                                 PatchOat(
    254                                                     isa,
    255                                                     space_to_memmap_map.find(space)->second.get(),
    256                                                     space->GetLiveBitmap(),
    257                                                     space->GetMemMap(),
    258                                                     delta,
    259                                                     &space_to_memmap_map,
    260                                                     timings)).first->second;
    261 
    262     t.NewTiming("Patching image");
    263     if (!p.PatchImage(i == 0)) {
    264       LOG(ERROR) << "Failed to patch image file " << input_image_filename;
    265       return false;
    266     }
    267   }
    268 
    269   // Write the patched image spaces.
    270   for (size_t i = 0; i < spaces.size(); ++i) {
    271     gc::space::ImageSpace* space = spaces[i];
    272 
    273     t.NewTiming("Writing image");
    274     std::string converted_image_filename = space->GetImageLocation();
    275     std::replace(converted_image_filename.begin() + 1, converted_image_filename.end(), '/', '@');
    276     std::string output_image_filename = output_directory +
    277         (android::base::StartsWith(converted_image_filename, "/") ? "" : "/") +
    278         converted_image_filename;
    279     std::unique_ptr<File> output_image_file(CreateOrOpen(output_image_filename.c_str()));
    280     if (output_image_file.get() == nullptr) {
    281       LOG(ERROR) << "Failed to open output image file at " << output_image_filename;
    282       return false;
    283     }
    284 
    285     PatchOat& p = space_to_patchoat_map.find(space)->second;
    286 
    287     bool success = p.WriteImage(output_image_file.get());
    288     success = FinishFile(output_image_file.get(), success);
    289     if (!success) {
    290       return false;
    291     }
    292   }
    293 
    294   if (!kIsDebugBuild && !(RUNNING_ON_MEMORY_TOOL && kMemoryToolDetectsLeaks)) {
    295     // We want to just exit on non-debug builds, not bringing the runtime down
    296     // in an orderly fashion. So release the following fields.
    297     runtime.release();
    298   }
    299 
    300   return true;
    301 }
    302 
    303 bool PatchOat::WriteImage(File* out) {
    304   TimingLogger::ScopedTiming t("Writing image File", timings_);
    305   std::string error_msg;
    306 
    307   // No error checking here, this is best effort. The locking may or may not
    308   // succeed and we don't really care either way.
    309   ScopedFlock img_flock = LockedFile::DupOf(out->Fd(), out->GetPath(),
    310                                             true /* read_only_mode */, &error_msg);
    311 
    312   CHECK(image_ != nullptr);
    313   CHECK(out != nullptr);
    314   size_t expect = image_->Size();
    315   if (out->WriteFully(reinterpret_cast<char*>(image_->Begin()), expect) &&
    316       out->SetLength(expect) == 0) {
    317     return true;
    318   } else {
    319     LOG(ERROR) << "Writing to image file " << out->GetPath() << " failed.";
    320     return false;
    321   }
    322 }
    323 
    324 bool PatchOat::IsImagePic(const ImageHeader& image_header, const std::string& image_path) {
    325   if (!image_header.CompilePic()) {
    326     if (kIsDebugBuild) {
    327       LOG(INFO) << "image at location " << image_path << " was *not* compiled pic";
    328     }
    329     return false;
    330   }
    331 
    332   if (kIsDebugBuild) {
    333     LOG(INFO) << "image at location " << image_path << " was compiled PIC";
    334   }
    335 
    336   return true;
    337 }
    338 
    339 PatchOat::MaybePic PatchOat::IsOatPic(const ElfFile* oat_in) {
    340   if (oat_in == nullptr) {
    341     LOG(ERROR) << "No ELF input oat fie available";
    342     return ERROR_OAT_FILE;
    343   }
    344 
    345   const std::string& file_path = oat_in->GetFilePath();
    346 
    347   const OatHeader* oat_header = GetOatHeader(oat_in);
    348   if (oat_header == nullptr) {
    349     LOG(ERROR) << "Failed to find oat header in oat file " << file_path;
    350     return ERROR_OAT_FILE;
    351   }
    352 
    353   if (!oat_header->IsValid()) {
    354     LOG(ERROR) << "Elf file " << file_path << " has an invalid oat header";
    355     return ERROR_OAT_FILE;
    356   }
    357 
    358   bool is_pic = oat_header->IsPic();
    359   if (kIsDebugBuild) {
    360     LOG(INFO) << "Oat file at " << file_path << " is " << (is_pic ? "PIC" : "not pic");
    361   }
    362 
    363   return is_pic ? PIC : NOT_PIC;
    364 }
    365 
    366 bool PatchOat::ReplaceOatFileWithSymlink(const std::string& input_oat_filename,
    367                                          const std::string& output_oat_filename) {
    368   // Delete the original file, since we won't need it.
    369   unlink(output_oat_filename.c_str());
    370 
    371   // Create a symlink from the old oat to the new oat
    372   if (symlink(input_oat_filename.c_str(), output_oat_filename.c_str()) < 0) {
    373     int err = errno;
    374     LOG(ERROR) << "Failed to create symlink at " << output_oat_filename
    375                << " error(" << err << "): " << strerror(err);
    376     return false;
    377   }
    378 
    379   if (kIsDebugBuild) {
    380     LOG(INFO) << "Created symlink " << output_oat_filename << " -> " << input_oat_filename;
    381   }
    382 
    383   return true;
    384 }
    385 
    386 class PatchOat::PatchOatArtFieldVisitor : public ArtFieldVisitor {
    387  public:
    388   explicit PatchOatArtFieldVisitor(PatchOat* patch_oat) : patch_oat_(patch_oat) {}
    389 
    390   void Visit(ArtField* field) OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
    391     ArtField* const dest = patch_oat_->RelocatedCopyOf(field);
    392     dest->SetDeclaringClass(
    393         patch_oat_->RelocatedAddressOfPointer(field->GetDeclaringClass().Ptr()));
    394   }
    395 
    396  private:
    397   PatchOat* const patch_oat_;
    398 };
    399 
    400 void PatchOat::PatchArtFields(const ImageHeader* image_header) {
    401   PatchOatArtFieldVisitor visitor(this);
    402   image_header->VisitPackedArtFields(&visitor, heap_->Begin());
    403 }
    404 
    405 class PatchOat::PatchOatArtMethodVisitor : public ArtMethodVisitor {
    406  public:
    407   explicit PatchOatArtMethodVisitor(PatchOat* patch_oat) : patch_oat_(patch_oat) {}
    408 
    409   void Visit(ArtMethod* method) OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
    410     ArtMethod* const dest = patch_oat_->RelocatedCopyOf(method);
    411     patch_oat_->FixupMethod(method, dest);
    412   }
    413 
    414  private:
    415   PatchOat* const patch_oat_;
    416 };
    417 
    418 void PatchOat::PatchArtMethods(const ImageHeader* image_header) {
    419   const PointerSize pointer_size = InstructionSetPointerSize(isa_);
    420   PatchOatArtMethodVisitor visitor(this);
    421   image_header->VisitPackedArtMethods(&visitor, heap_->Begin(), pointer_size);
    422 }
    423 
    424 void PatchOat::PatchImTables(const ImageHeader* image_header) {
    425   const PointerSize pointer_size = InstructionSetPointerSize(isa_);
    426   // We can safely walk target image since the conflict tables are independent.
    427   image_header->VisitPackedImTables(
    428       [this](ArtMethod* method) {
    429         return RelocatedAddressOfPointer(method);
    430       },
    431       image_->Begin(),
    432       pointer_size);
    433 }
    434 
    435 void PatchOat::PatchImtConflictTables(const ImageHeader* image_header) {
    436   const PointerSize pointer_size = InstructionSetPointerSize(isa_);
    437   // We can safely walk target image since the conflict tables are independent.
    438   image_header->VisitPackedImtConflictTables(
    439       [this](ArtMethod* method) {
    440         return RelocatedAddressOfPointer(method);
    441       },
    442       image_->Begin(),
    443       pointer_size);
    444 }
    445 
    446 class PatchOat::FixupRootVisitor : public RootVisitor {
    447  public:
    448   explicit FixupRootVisitor(const PatchOat* patch_oat) : patch_oat_(patch_oat) {
    449   }
    450 
    451   void VisitRoots(mirror::Object*** roots, size_t count, const RootInfo& info ATTRIBUTE_UNUSED)
    452       OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
    453     for (size_t i = 0; i < count; ++i) {
    454       *roots[i] = patch_oat_->RelocatedAddressOfPointer(*roots[i]);
    455     }
    456   }
    457 
    458   void VisitRoots(mirror::CompressedReference<mirror::Object>** roots, size_t count,
    459                   const RootInfo& info ATTRIBUTE_UNUSED)
    460       OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
    461     for (size_t i = 0; i < count; ++i) {
    462       roots[i]->Assign(patch_oat_->RelocatedAddressOfPointer(roots[i]->AsMirrorPtr()));
    463     }
    464   }
    465 
    466  private:
    467   const PatchOat* const patch_oat_;
    468 };
    469 
    470 void PatchOat::PatchInternedStrings(const ImageHeader* image_header) {
    471   const auto& section = image_header->GetImageSection(ImageHeader::kSectionInternedStrings);
    472   InternTable temp_table;
    473   // Note that we require that ReadFromMemory does not make an internal copy of the elements.
    474   // This also relies on visit roots not doing any verification which could fail after we update
    475   // the roots to be the image addresses.
    476   temp_table.AddTableFromMemory(image_->Begin() + section.Offset());
    477   FixupRootVisitor visitor(this);
    478   temp_table.VisitRoots(&visitor, kVisitRootFlagAllRoots);
    479 }
    480 
    481 void PatchOat::PatchClassTable(const ImageHeader* image_header) {
    482   const auto& section = image_header->GetImageSection(ImageHeader::kSectionClassTable);
    483   if (section.Size() == 0) {
    484     return;
    485   }
    486   // Note that we require that ReadFromMemory does not make an internal copy of the elements.
    487   // This also relies on visit roots not doing any verification which could fail after we update
    488   // the roots to be the image addresses.
    489   WriterMutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_);
    490   ClassTable temp_table;
    491   temp_table.ReadFromMemory(image_->Begin() + section.Offset());
    492   FixupRootVisitor visitor(this);
    493   temp_table.VisitRoots(UnbufferedRootVisitor(&visitor, RootInfo(kRootUnknown)));
    494 }
    495 
    496 
    497 class PatchOat::RelocatedPointerVisitor {
    498  public:
    499   explicit RelocatedPointerVisitor(PatchOat* patch_oat) : patch_oat_(patch_oat) {}
    500 
    501   template <typename T>
    502   T* operator()(T* ptr, void** dest_addr ATTRIBUTE_UNUSED = 0) const {
    503     return patch_oat_->RelocatedAddressOfPointer(ptr);
    504   }
    505 
    506  private:
    507   PatchOat* const patch_oat_;
    508 };
    509 
    510 void PatchOat::PatchDexFileArrays(mirror::ObjectArray<mirror::Object>* img_roots) {
    511   auto* dex_caches = down_cast<mirror::ObjectArray<mirror::DexCache>*>(
    512       img_roots->Get(ImageHeader::kDexCaches));
    513   const PointerSize pointer_size = InstructionSetPointerSize(isa_);
    514   for (size_t i = 0, count = dex_caches->GetLength(); i < count; ++i) {
    515     auto* orig_dex_cache = dex_caches->GetWithoutChecks(i);
    516     auto* copy_dex_cache = RelocatedCopyOf(orig_dex_cache);
    517     // Though the DexCache array fields are usually treated as native pointers, we set the full
    518     // 64-bit values here, clearing the top 32 bits for 32-bit targets. The zero-extension is
    519     // done by casting to the unsigned type uintptr_t before casting to int64_t, i.e.
    520     //     static_cast<int64_t>(reinterpret_cast<uintptr_t>(image_begin_ + offset))).
    521     mirror::StringDexCacheType* orig_strings = orig_dex_cache->GetStrings();
    522     mirror::StringDexCacheType* relocated_strings = RelocatedAddressOfPointer(orig_strings);
    523     copy_dex_cache->SetField64<false>(
    524         mirror::DexCache::StringsOffset(),
    525         static_cast<int64_t>(reinterpret_cast<uintptr_t>(relocated_strings)));
    526     if (orig_strings != nullptr) {
    527       orig_dex_cache->FixupStrings(RelocatedCopyOf(orig_strings), RelocatedPointerVisitor(this));
    528     }
    529     mirror::TypeDexCacheType* orig_types = orig_dex_cache->GetResolvedTypes();
    530     mirror::TypeDexCacheType* relocated_types = RelocatedAddressOfPointer(orig_types);
    531     copy_dex_cache->SetField64<false>(
    532         mirror::DexCache::ResolvedTypesOffset(),
    533         static_cast<int64_t>(reinterpret_cast<uintptr_t>(relocated_types)));
    534     if (orig_types != nullptr) {
    535       orig_dex_cache->FixupResolvedTypes(RelocatedCopyOf(orig_types),
    536                                          RelocatedPointerVisitor(this));
    537     }
    538     mirror::MethodDexCacheType* orig_methods = orig_dex_cache->GetResolvedMethods();
    539     mirror::MethodDexCacheType* relocated_methods = RelocatedAddressOfPointer(orig_methods);
    540     copy_dex_cache->SetField64<false>(
    541         mirror::DexCache::ResolvedMethodsOffset(),
    542         static_cast<int64_t>(reinterpret_cast<uintptr_t>(relocated_methods)));
    543     if (orig_methods != nullptr) {
    544       mirror::MethodDexCacheType* copy_methods = RelocatedCopyOf(orig_methods);
    545       for (size_t j = 0, num = orig_dex_cache->NumResolvedMethods(); j != num; ++j) {
    546         mirror::MethodDexCachePair orig =
    547             mirror::DexCache::GetNativePairPtrSize(orig_methods, j, pointer_size);
    548         mirror::MethodDexCachePair copy(RelocatedAddressOfPointer(orig.object), orig.index);
    549         mirror::DexCache::SetNativePairPtrSize(copy_methods, j, copy, pointer_size);
    550       }
    551     }
    552     mirror::FieldDexCacheType* orig_fields = orig_dex_cache->GetResolvedFields();
    553     mirror::FieldDexCacheType* relocated_fields = RelocatedAddressOfPointer(orig_fields);
    554     copy_dex_cache->SetField64<false>(
    555         mirror::DexCache::ResolvedFieldsOffset(),
    556         static_cast<int64_t>(reinterpret_cast<uintptr_t>(relocated_fields)));
    557     if (orig_fields != nullptr) {
    558       mirror::FieldDexCacheType* copy_fields = RelocatedCopyOf(orig_fields);
    559       for (size_t j = 0, num = orig_dex_cache->NumResolvedFields(); j != num; ++j) {
    560         mirror::FieldDexCachePair orig =
    561             mirror::DexCache::GetNativePairPtrSize(orig_fields, j, pointer_size);
    562         mirror::FieldDexCachePair copy(RelocatedAddressOfPointer(orig.object), orig.index);
    563         mirror::DexCache::SetNativePairPtrSize(copy_fields, j, copy, pointer_size);
    564       }
    565     }
    566     mirror::MethodTypeDexCacheType* orig_method_types = orig_dex_cache->GetResolvedMethodTypes();
    567     mirror::MethodTypeDexCacheType* relocated_method_types =
    568         RelocatedAddressOfPointer(orig_method_types);
    569     copy_dex_cache->SetField64<false>(
    570         mirror::DexCache::ResolvedMethodTypesOffset(),
    571         static_cast<int64_t>(reinterpret_cast<uintptr_t>(relocated_method_types)));
    572     if (orig_method_types != nullptr) {
    573       orig_dex_cache->FixupResolvedMethodTypes(RelocatedCopyOf(orig_method_types),
    574                                                RelocatedPointerVisitor(this));
    575     }
    576 
    577     GcRoot<mirror::CallSite>* orig_call_sites = orig_dex_cache->GetResolvedCallSites();
    578     GcRoot<mirror::CallSite>* relocated_call_sites = RelocatedAddressOfPointer(orig_call_sites);
    579     copy_dex_cache->SetField64<false>(
    580         mirror::DexCache::ResolvedCallSitesOffset(),
    581         static_cast<int64_t>(reinterpret_cast<uintptr_t>(relocated_call_sites)));
    582     if (orig_call_sites != nullptr) {
    583       orig_dex_cache->FixupResolvedCallSites(RelocatedCopyOf(orig_call_sites),
    584                                              RelocatedPointerVisitor(this));
    585     }
    586   }
    587 }
    588 
    589 bool PatchOat::PatchImage(bool primary_image) {
    590   ImageHeader* image_header = reinterpret_cast<ImageHeader*>(image_->Begin());
    591   CHECK_GT(image_->Size(), sizeof(ImageHeader));
    592   // These are the roots from the original file.
    593   auto* img_roots = image_header->GetImageRoots();
    594   image_header->RelocateImage(delta_);
    595 
    596   PatchArtFields(image_header);
    597   PatchArtMethods(image_header);
    598   PatchImTables(image_header);
    599   PatchImtConflictTables(image_header);
    600   PatchInternedStrings(image_header);
    601   PatchClassTable(image_header);
    602   // Patch dex file int/long arrays which point to ArtFields.
    603   PatchDexFileArrays(img_roots);
    604 
    605   if (primary_image) {
    606     VisitObject(img_roots);
    607   }
    608 
    609   if (!image_header->IsValid()) {
    610     LOG(ERROR) << "relocation renders image header invalid";
    611     return false;
    612   }
    613 
    614   {
    615     TimingLogger::ScopedTiming t("Walk Bitmap", timings_);
    616     // Walk the bitmap.
    617     WriterMutexLock mu(Thread::Current(), *Locks::heap_bitmap_lock_);
    618     auto visitor = [&](mirror::Object* obj) REQUIRES_SHARED(Locks::mutator_lock_) {
    619       VisitObject(obj);
    620     };
    621     bitmap_->Walk(visitor);
    622   }
    623   return true;
    624 }
    625 
    626 
    627 void PatchOat::PatchVisitor::operator() (ObjPtr<mirror::Object> obj,
    628                                          MemberOffset off,
    629                                          bool is_static_unused ATTRIBUTE_UNUSED) const {
    630   mirror::Object* referent = obj->GetFieldObject<mirror::Object, kVerifyNone>(off);
    631   mirror::Object* moved_object = patcher_->RelocatedAddressOfPointer(referent);
    632   copy_->SetFieldObjectWithoutWriteBarrier<false, true, kVerifyNone>(off, moved_object);
    633 }
    634 
    635 void PatchOat::PatchVisitor::operator() (ObjPtr<mirror::Class> cls ATTRIBUTE_UNUSED,
    636                                          ObjPtr<mirror::Reference> ref) const {
    637   MemberOffset off = mirror::Reference::ReferentOffset();
    638   mirror::Object* referent = ref->GetReferent();
    639   DCHECK(referent == nullptr ||
    640          Runtime::Current()->GetHeap()->ObjectIsInBootImageSpace(referent)) << referent;
    641   mirror::Object* moved_object = patcher_->RelocatedAddressOfPointer(referent);
    642   copy_->SetFieldObjectWithoutWriteBarrier<false, true, kVerifyNone>(off, moved_object);
    643 }
    644 
    645 // Called by PatchImage.
    646 void PatchOat::VisitObject(mirror::Object* object) {
    647   mirror::Object* copy = RelocatedCopyOf(object);
    648   CHECK(copy != nullptr);
    649   if (kUseBakerReadBarrier) {
    650     object->AssertReadBarrierState();
    651   }
    652   PatchOat::PatchVisitor visitor(this, copy);
    653   object->VisitReferences<kVerifyNone>(visitor, visitor);
    654   if (object->IsClass<kVerifyNone>()) {
    655     const PointerSize pointer_size = InstructionSetPointerSize(isa_);
    656     mirror::Class* klass = object->AsClass();
    657     mirror::Class* copy_klass = down_cast<mirror::Class*>(copy);
    658     RelocatedPointerVisitor native_visitor(this);
    659     klass->FixupNativePointers(copy_klass, pointer_size, native_visitor);
    660     auto* vtable = klass->GetVTable();
    661     if (vtable != nullptr) {
    662       vtable->Fixup(RelocatedCopyOfFollowImages(vtable), pointer_size, native_visitor);
    663     }
    664     mirror::IfTable* iftable = klass->GetIfTable();
    665     for (int32_t i = 0; i < klass->GetIfTableCount(); ++i) {
    666       if (iftable->GetMethodArrayCount(i) > 0) {
    667         auto* method_array = iftable->GetMethodArray(i);
    668         CHECK(method_array != nullptr);
    669         method_array->Fixup(RelocatedCopyOfFollowImages(method_array),
    670                             pointer_size,
    671                             native_visitor);
    672       }
    673     }
    674   } else if (object->GetClass() == mirror::Method::StaticClass() ||
    675              object->GetClass() == mirror::Constructor::StaticClass()) {
    676     // Need to go update the ArtMethod.
    677     auto* dest = down_cast<mirror::Executable*>(copy);
    678     auto* src = down_cast<mirror::Executable*>(object);
    679     dest->SetArtMethod(RelocatedAddressOfPointer(src->GetArtMethod()));
    680   }
    681 }
    682 
    683 void PatchOat::FixupMethod(ArtMethod* object, ArtMethod* copy) {
    684   const PointerSize pointer_size = InstructionSetPointerSize(isa_);
    685   copy->CopyFrom(object, pointer_size);
    686   // Just update the entry points if it looks like we should.
    687   // TODO: sanity check all the pointers' values
    688   copy->SetDeclaringClass(RelocatedAddressOfPointer(object->GetDeclaringClass()));
    689   copy->SetDexCacheResolvedMethods(
    690       RelocatedAddressOfPointer(object->GetDexCacheResolvedMethods(pointer_size)), pointer_size);
    691   copy->SetEntryPointFromQuickCompiledCodePtrSize(RelocatedAddressOfPointer(
    692       object->GetEntryPointFromQuickCompiledCodePtrSize(pointer_size)), pointer_size);
    693   // No special handling for IMT conflict table since all pointers are moved by the same offset.
    694   copy->SetDataPtrSize(RelocatedAddressOfPointer(
    695       object->GetDataPtrSize(pointer_size)), pointer_size);
    696 }
    697 
    698 static int orig_argc;
    699 static char** orig_argv;
    700 
    701 static std::string CommandLine() {
    702   std::vector<std::string> command;
    703   for (int i = 0; i < orig_argc; ++i) {
    704     command.push_back(orig_argv[i]);
    705   }
    706   return android::base::Join(command, ' ');
    707 }
    708 
    709 static void UsageErrorV(const char* fmt, va_list ap) {
    710   std::string error;
    711   android::base::StringAppendV(&error, fmt, ap);
    712   LOG(ERROR) << error;
    713 }
    714 
    715 static void UsageError(const char* fmt, ...) {
    716   va_list ap;
    717   va_start(ap, fmt);
    718   UsageErrorV(fmt, ap);
    719   va_end(ap);
    720 }
    721 
    722 NO_RETURN static void Usage(const char *fmt, ...) {
    723   va_list ap;
    724   va_start(ap, fmt);
    725   UsageErrorV(fmt, ap);
    726   va_end(ap);
    727 
    728   UsageError("Command: %s", CommandLine().c_str());
    729   UsageError("Usage: patchoat [options]...");
    730   UsageError("");
    731   UsageError("  --instruction-set=<isa>: Specifies the instruction set the patched code is");
    732   UsageError("      compiled for (required).");
    733   UsageError("");
    734   UsageError("  --input-image-location=<file.art>: Specifies the 'location' of the image file to");
    735   UsageError("      be patched.");
    736   UsageError("");
    737   UsageError("  --output-image-file=<file.art>: Specifies the exact file to write the patched");
    738   UsageError("      image file to.");
    739   UsageError("");
    740   UsageError("  --base-offset-delta=<delta>: Specify the amount to change the old base-offset by.");
    741   UsageError("      This value may be negative.");
    742   UsageError("");
    743   UsageError("  --dump-timings: dump out patch timing information");
    744   UsageError("");
    745   UsageError("  --no-dump-timings: do not dump out patch timing information");
    746   UsageError("");
    747 
    748   exit(EXIT_FAILURE);
    749 }
    750 
    751 static int patchoat_image(TimingLogger& timings,
    752                           InstructionSet isa,
    753                           const std::string& input_image_location,
    754                           const std::string& output_image_filename,
    755                           off_t base_delta,
    756                           bool base_delta_set,
    757                           bool debug) {
    758   CHECK(!input_image_location.empty());
    759   if (output_image_filename.empty()) {
    760     Usage("Image patching requires --output-image-file");
    761   }
    762 
    763   if (!base_delta_set) {
    764     Usage("Must supply a desired new offset or delta.");
    765   }
    766 
    767   if (!IsAligned<kPageSize>(base_delta)) {
    768     Usage("Base offset/delta must be aligned to a pagesize (0x%08x) boundary.", kPageSize);
    769   }
    770 
    771   if (debug) {
    772     LOG(INFO) << "moving offset by " << base_delta
    773         << " (0x" << std::hex << base_delta << ") bytes or "
    774         << std::dec << (base_delta/kPageSize) << " pages.";
    775   }
    776 
    777   TimingLogger::ScopedTiming pt("patch image and oat", &timings);
    778 
    779   std::string output_directory =
    780       output_image_filename.substr(0, output_image_filename.find_last_of('/'));
    781   bool ret = PatchOat::Patch(input_image_location, base_delta, output_directory, isa, &timings);
    782 
    783   if (kIsDebugBuild) {
    784     LOG(INFO) << "Exiting with return ... " << ret;
    785   }
    786   return ret ? EXIT_SUCCESS : EXIT_FAILURE;
    787 }
    788 
    789 static int patchoat(int argc, char **argv) {
    790   InitLogging(argv, Runtime::Abort);
    791   MemMap::Init();
    792   const bool debug = kIsDebugBuild;
    793   orig_argc = argc;
    794   orig_argv = argv;
    795   TimingLogger timings("patcher", false, false);
    796 
    797   // Skip over the command name.
    798   argv++;
    799   argc--;
    800 
    801   if (argc == 0) {
    802     Usage("No arguments specified");
    803   }
    804 
    805   timings.StartTiming("Patchoat");
    806 
    807   // cmd line args
    808   bool isa_set = false;
    809   InstructionSet isa = kNone;
    810   std::string input_image_location;
    811   std::string output_image_filename;
    812   off_t base_delta = 0;
    813   bool base_delta_set = false;
    814   bool dump_timings = kIsDebugBuild;
    815 
    816   for (int i = 0; i < argc; ++i) {
    817     const StringPiece option(argv[i]);
    818     const bool log_options = false;
    819     if (log_options) {
    820       LOG(INFO) << "patchoat: option[" << i << "]=" << argv[i];
    821     }
    822     if (option.starts_with("--instruction-set=")) {
    823       isa_set = true;
    824       const char* isa_str = option.substr(strlen("--instruction-set=")).data();
    825       isa = GetInstructionSetFromString(isa_str);
    826       if (isa == kNone) {
    827         Usage("Unknown or invalid instruction set %s", isa_str);
    828       }
    829     } else if (option.starts_with("--input-image-location=")) {
    830       input_image_location = option.substr(strlen("--input-image-location=")).data();
    831     } else if (option.starts_with("--output-image-file=")) {
    832       output_image_filename = option.substr(strlen("--output-image-file=")).data();
    833     } else if (option.starts_with("--base-offset-delta=")) {
    834       const char* base_delta_str = option.substr(strlen("--base-offset-delta=")).data();
    835       base_delta_set = true;
    836       if (!ParseInt(base_delta_str, &base_delta)) {
    837         Usage("Failed to parse --base-offset-delta argument '%s' as an off_t", base_delta_str);
    838       }
    839     } else if (option == "--dump-timings") {
    840       dump_timings = true;
    841     } else if (option == "--no-dump-timings") {
    842       dump_timings = false;
    843     } else {
    844       Usage("Unknown argument %s", option.data());
    845     }
    846   }
    847 
    848   // The instruction set is mandatory. This simplifies things...
    849   if (!isa_set) {
    850     Usage("Instruction set must be set.");
    851   }
    852 
    853   int ret = patchoat_image(timings,
    854                            isa,
    855                            input_image_location,
    856                            output_image_filename,
    857                            base_delta,
    858                            base_delta_set,
    859                            debug);
    860 
    861   timings.EndTiming();
    862   if (dump_timings) {
    863     LOG(INFO) << Dumpable<TimingLogger>(timings);
    864   }
    865 
    866   return ret;
    867 }
    868 
    869 }  // namespace art
    870 
    871 int main(int argc, char **argv) {
    872   return art::patchoat(argc, argv);
    873 }
    874