153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light/* 253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light * Copyright (C) 2014 The Android Open Source Project 353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light * 453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light * Licensed under the Apache License, Version 2.0 (the "License"); 553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light * you may not use this file except in compliance with the License. 653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light * You may obtain a copy of the License at 753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light * 853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light * http://www.apache.org/licenses/LICENSE-2.0 953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light * 1053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light * Unless required by applicable law or agreed to in writing, software 1153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light * distributed under the License is distributed on an "AS IS" BASIS, 1253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light * See the License for the specific language governing permissions and 1453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light * limitations under the License. 1553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light */ 1653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light 1753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light#ifndef ART_PATCHOAT_PATCHOAT_H_ 1853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light#define ART_PATCHOAT_PATCHOAT_H_ 1953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light 20d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#include "arch/instruction_set.h" 2153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light#include "base/macros.h" 2253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light#include "base/mutex.h" 2353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light#include "elf_file.h" 2453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light#include "elf_utils.h" 2553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light#include "gc/accounting/space_bitmap.h" 26dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao#include "gc/space/image_space.h" 2753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light#include "gc/heap.h" 28d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#include "os.h" 29dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao#include "runtime.h" 3053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light 3153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Lightnamespace art { 3253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light 33e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierclass ArtMethod; 3453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Lightclass ImageHeader; 3546774767fcf7780d1455e755729198648d08742eIgor Murashkinclass OatHeader; 3653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light 3753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Lightnamespace mirror { 3853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Lightclass Object; 39e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierclass PointerArray; 4053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Lightclass Reference; 4153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Lightclass Class; 42c8ccf68b805c92674545f63e0341ba47e8d9701cAndreas Gampe} // namespace mirror 4353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light 4453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Lightclass PatchOat { 4553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light public: 4646774767fcf7780d1455e755729198648d08742eIgor Murashkin // Patch only the oat file 4746774767fcf7780d1455e755729198648d08742eIgor Murashkin static bool Patch(File* oat_in, off_t delta, File* oat_out, TimingLogger* timings, 4846774767fcf7780d1455e755729198648d08742eIgor Murashkin bool output_oat_opened_from_fd, // Was this using --oatput-oat-fd ? 4946774767fcf7780d1455e755729198648d08742eIgor Murashkin bool new_oat_out); // Output oat was a new file created by us? 5053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light 5146774767fcf7780d1455e755729198648d08742eIgor Murashkin // Patch only the image (art file) 5253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light static bool Patch(const std::string& art_location, off_t delta, File* art_out, InstructionSet isa, 53eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light TimingLogger* timings); 5453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light 5546774767fcf7780d1455e755729198648d08742eIgor Murashkin // Patch both the image and the oat file 5602bc0b70beedfe258c2147c2b4a205fbf3d6eebcAndreas Gampe static bool Patch(const std::string& art_location, 5702bc0b70beedfe258c2147c2b4a205fbf3d6eebcAndreas Gampe off_t delta, 5802bc0b70beedfe258c2147c2b4a205fbf3d6eebcAndreas Gampe const std::string& output_directory, 5902bc0b70beedfe258c2147c2b4a205fbf3d6eebcAndreas Gampe InstructionSet isa, 6002bc0b70beedfe258c2147c2b4a205fbf3d6eebcAndreas Gampe TimingLogger* timings); 6153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light 62dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao ~PatchOat() {} 63dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao PatchOat(PatchOat&&) = default; 64dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao 6553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light private: 6653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light // Takes ownership only of the ElfFile. All other pointers are only borrowed. 67eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light PatchOat(ElfFile* oat_file, off_t delta, TimingLogger* timings) 68d4c4d953035d4418126d36517e402f411d6a87f3Ian Rogers : oat_file_(oat_file), image_(nullptr), bitmap_(nullptr), heap_(nullptr), delta_(delta), 69dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao isa_(kNone), space_map_(nullptr), timings_(timings) {} 702d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier PatchOat(InstructionSet isa, MemMap* image, gc::accounting::ContinuousSpaceBitmap* bitmap, 71eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light MemMap* heap, off_t delta, TimingLogger* timings) 7253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light : image_(image), bitmap_(bitmap), heap_(heap), 73dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao delta_(delta), isa_(isa), space_map_(nullptr), timings_(timings) {} 742d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier PatchOat(InstructionSet isa, ElfFile* oat_file, MemMap* image, 752d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier gc::accounting::ContinuousSpaceBitmap* bitmap, MemMap* heap, off_t delta, 76dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao std::map<gc::space::ImageSpace*, std::unique_ptr<MemMap>>* map, TimingLogger* timings) 7753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light : oat_file_(oat_file), image_(image), bitmap_(bitmap), heap_(heap), 78dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao delta_(delta), isa_(isa), space_map_(map), timings_(timings) {} 7953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light 8046774767fcf7780d1455e755729198648d08742eIgor Murashkin // Was the .art image at image_path made with --compile-pic ? 8146774767fcf7780d1455e755729198648d08742eIgor Murashkin static bool IsImagePic(const ImageHeader& image_header, const std::string& image_path); 8246774767fcf7780d1455e755729198648d08742eIgor Murashkin 8346774767fcf7780d1455e755729198648d08742eIgor Murashkin enum MaybePic { 8446774767fcf7780d1455e755729198648d08742eIgor Murashkin NOT_PIC, // Code not pic. Patch as usual. 8546774767fcf7780d1455e755729198648d08742eIgor Murashkin PIC, // Code was pic. Create symlink; skip OAT patching. 8646774767fcf7780d1455e755729198648d08742eIgor Murashkin ERROR_OAT_FILE, // Failed to symlink oat file 8746774767fcf7780d1455e755729198648d08742eIgor Murashkin ERROR_FIRST = ERROR_OAT_FILE, 8846774767fcf7780d1455e755729198648d08742eIgor Murashkin }; 8946774767fcf7780d1455e755729198648d08742eIgor Murashkin 9046774767fcf7780d1455e755729198648d08742eIgor Murashkin // Was the .oat image at oat_in made with --compile-pic ? 9146774767fcf7780d1455e755729198648d08742eIgor Murashkin static MaybePic IsOatPic(const ElfFile* oat_in); 9246774767fcf7780d1455e755729198648d08742eIgor Murashkin 9346774767fcf7780d1455e755729198648d08742eIgor Murashkin // Attempt to replace the file with a symlink 9446774767fcf7780d1455e755729198648d08742eIgor Murashkin // Returns false if it fails 9546774767fcf7780d1455e755729198648d08742eIgor Murashkin static bool ReplaceOatFileWithSymlink(const std::string& input_oat_filename, 9646774767fcf7780d1455e755729198648d08742eIgor Murashkin const std::string& output_oat_filename, 9746774767fcf7780d1455e755729198648d08742eIgor Murashkin bool output_oat_opened_from_fd, 9846774767fcf7780d1455e755729198648d08742eIgor Murashkin bool new_oat_out); // Output oat was newly created? 9946774767fcf7780d1455e755729198648d08742eIgor Murashkin 10053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light static void BitmapCallback(mirror::Object* obj, void* arg) 10190443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 10253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light reinterpret_cast<PatchOat*>(arg)->VisitObject(obj); 10353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light } 10453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light 10553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light void VisitObject(mirror::Object* obj) 10690443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_); 107e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier void FixupMethod(ArtMethod* object, ArtMethod* copy) 10890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_); 10953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light 11053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light // Patches oat in place, modifying the oat_file given to the constructor. 11153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light bool PatchElf(); 11262d1ca3182a6cbb921799825f43ad36821233fd7Tong Shen template <typename ElfFileImpl> 11362d1ca3182a6cbb921799825f43ad36821233fd7Tong Shen bool PatchElf(ElfFileImpl* oat_file); 11462d1ca3182a6cbb921799825f43ad36821233fd7Tong Shen template <typename ElfFileImpl> 11562d1ca3182a6cbb921799825f43ad36821233fd7Tong Shen bool PatchOatHeader(ElfFileImpl* oat_file); 11653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light 117dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao bool PatchImage(bool primary_image) SHARED_REQUIRES(Locks::mutator_lock_); 11890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier void PatchArtFields(const ImageHeader* image_header) SHARED_REQUIRES(Locks::mutator_lock_); 11990443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier void PatchArtMethods(const ImageHeader* image_header) SHARED_REQUIRES(Locks::mutator_lock_); 120df2d4f22d5e89692c90b443da82fe2930518418bArtem Udovichenko void PatchImTables(const ImageHeader* image_header) SHARED_REQUIRES(Locks::mutator_lock_); 121cdca476bf3394ce9d97a369e84e701b427009318Mathieu Chartier void PatchImtConflictTables(const ImageHeader* image_header) 122cdca476bf3394ce9d97a369e84e701b427009318Mathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_); 123d39645e22b8db1767cf64dc1200a9e4b2f939ed2Mathieu Chartier void PatchInternedStrings(const ImageHeader* image_header) 12490443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_); 125208a5cb383dd9dcd3461f89b74af5df67dc8d794Mathieu Chartier void PatchClassTable(const ImageHeader* image_header) 126208a5cb383dd9dcd3461f89b74af5df67dc8d794Mathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_); 127c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier void PatchDexFileArrays(mirror::ObjectArray<mirror::Object>* img_roots) 12890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_); 12953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light 13053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light bool WriteElf(File* out); 13153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light bool WriteImage(File* out); 13253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light 133c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier template <typename T> 134d39645e22b8db1767cf64dc1200a9e4b2f939ed2Mathieu Chartier T* RelocatedCopyOf(T* obj) const { 135c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier if (obj == nullptr) { 136c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier return nullptr; 137c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier } 138e271fe1e2797205c57c052212c32139234f781eaJeff Hao DCHECK_GT(reinterpret_cast<uintptr_t>(obj), reinterpret_cast<uintptr_t>(heap_->Begin())); 139e271fe1e2797205c57c052212c32139234f781eaJeff Hao DCHECK_LT(reinterpret_cast<uintptr_t>(obj), reinterpret_cast<uintptr_t>(heap_->End())); 140c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier uintptr_t heap_off = 141c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier reinterpret_cast<uintptr_t>(obj) - reinterpret_cast<uintptr_t>(heap_->Begin()); 142e271fe1e2797205c57c052212c32139234f781eaJeff Hao DCHECK_LT(heap_off, image_->Size()); 143c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier return reinterpret_cast<T*>(image_->Begin() + heap_off); 144c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier } 145c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier 146c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier template <typename T> 147dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao T* RelocatedCopyOfFollowImages(T* obj) const { 148dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao if (obj == nullptr) { 149dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao return nullptr; 150dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao } 151dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao // Find ImageSpace this belongs to. 152dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao auto image_spaces = Runtime::Current()->GetHeap()->GetBootImageSpaces(); 153dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao for (gc::space::ImageSpace* image_space : image_spaces) { 154dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao if (image_space->Contains(obj)) { 155dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao uintptr_t heap_off = reinterpret_cast<uintptr_t>(obj) - 156dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao reinterpret_cast<uintptr_t>(image_space->GetMemMap()->Begin()); 157dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao return reinterpret_cast<T*>(space_map_->find(image_space)->second->Begin() + heap_off); 158dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao } 159dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao } 160dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao LOG(FATAL) << "Did not find object in boot image space " << obj; 161dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao UNREACHABLE(); 162dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao } 163dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao 164dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao template <typename T> 165d39645e22b8db1767cf64dc1200a9e4b2f939ed2Mathieu Chartier T* RelocatedAddressOfPointer(T* obj) const { 166e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier if (obj == nullptr) { 167e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return obj; 168e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier } 169e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier auto ret = reinterpret_cast<uintptr_t>(obj) + delta_; 170e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier // Trim off high bits in case negative relocation with 64 bit patchoat. 171e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier if (InstructionSetPointerSize(isa_) == sizeof(uint32_t)) { 172e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier ret = static_cast<uintptr_t>(static_cast<uint32_t>(ret)); 173e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier } 174e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return reinterpret_cast<T*>(ret); 175e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier } 176e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier 177e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier template <typename T> 178d39645e22b8db1767cf64dc1200a9e4b2f939ed2Mathieu Chartier T RelocatedAddressOfIntPointer(T obj) const { 179e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier if (obj == 0) { 180e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return obj; 181e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier } 182e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier T ret = obj + delta_; 183e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier // Trim off high bits in case negative relocation with 64 bit patchoat. 184e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier if (InstructionSetPointerSize(isa_) == 4) { 185e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier ret = static_cast<T>(static_cast<uint32_t>(ret)); 186e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier } 187e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return ret; 188c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier } 18953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light 190eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light // Walks through the old image and patches the mmap'd copy of it to the new offset. It does not 191eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light // change the heap. 19253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light class PatchVisitor { 19353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light public: 19453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light PatchVisitor(PatchOat* patcher, mirror::Object* copy) : patcher_(patcher), copy_(copy) {} 19553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light ~PatchVisitor() {} 19653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light void operator() (mirror::Object* obj, MemberOffset off, bool b) const 197da7c650022a974be10e2f00fa07d5109e3d8826fMathieu Chartier REQUIRES(Locks::mutator_lock_, Locks::heap_bitmap_lock_); 19853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light // For reference classes. 19953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light void operator() (mirror::Class* cls, mirror::Reference* ref) const 200da7c650022a974be10e2f00fa07d5109e3d8826fMathieu Chartier REQUIRES(Locks::mutator_lock_, Locks::heap_bitmap_lock_); 201da7c650022a974be10e2f00fa07d5109e3d8826fMathieu Chartier // TODO: Consider using these for updating native class roots? 202da7c650022a974be10e2f00fa07d5109e3d8826fMathieu Chartier void VisitRootIfNonNull(mirror::CompressedReference<mirror::Object>* root ATTRIBUTE_UNUSED) 203da7c650022a974be10e2f00fa07d5109e3d8826fMathieu Chartier const {} 204da7c650022a974be10e2f00fa07d5109e3d8826fMathieu Chartier void VisitRoot(mirror::CompressedReference<mirror::Object>* root ATTRIBUTE_UNUSED) const {} 205da7c650022a974be10e2f00fa07d5109e3d8826fMathieu Chartier 20653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light private: 207d4c4d953035d4418126d36517e402f411d6a87f3Ian Rogers PatchOat* const patcher_; 208d4c4d953035d4418126d36517e402f411d6a87f3Ian Rogers mirror::Object* const copy_; 20953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light }; 21053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light 211eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light // The elf file we are patching. 212eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light std::unique_ptr<ElfFile> oat_file_; 213eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light // A mmap of the image we are patching. This is modified. 214d4c4d953035d4418126d36517e402f411d6a87f3Ian Rogers const MemMap* const image_; 215d4c4d953035d4418126d36517e402f411d6a87f3Ian Rogers // The bitmap over the image within the heap we are patching. This is not modified. 216d4c4d953035d4418126d36517e402f411d6a87f3Ian Rogers gc::accounting::ContinuousSpaceBitmap* const bitmap_; 217eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light // The heap we are patching. This is not modified. 218d4c4d953035d4418126d36517e402f411d6a87f3Ian Rogers const MemMap* const heap_; 219eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light // The amount we are changing the offset by. 220d4c4d953035d4418126d36517e402f411d6a87f3Ian Rogers const off_t delta_; 2212d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier // Active instruction set, used to know the entrypoint size. 2222d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier const InstructionSet isa_; 2232d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier 224dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao const std::map<gc::space::ImageSpace*, std::unique_ptr<MemMap>>* space_map_; 225dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao 2262d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier TimingLogger* timings_; 227eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light 228d39645e22b8db1767cf64dc1200a9e4b2f939ed2Mathieu Chartier friend class FixupRootVisitor; 2294b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier friend class RelocatedPointerVisitor; 23054d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier friend class PatchOatArtFieldVisitor; 23154d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier friend class PatchOatArtMethodVisitor; 23253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light DISALLOW_IMPLICIT_CONSTRUCTORS(PatchOat); 23353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}; 23453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light 23553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light} // namespace art 23653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light#endif // ART_PATCHOAT_PATCHOAT_H_ 237