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_); 120cdca476bf3394ce9d97a369e84e701b427009318Mathieu Chartier void PatchImtConflictTables(const ImageHeader* image_header) 121cdca476bf3394ce9d97a369e84e701b427009318Mathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_); 122d39645e22b8db1767cf64dc1200a9e4b2f939ed2Mathieu Chartier void PatchInternedStrings(const ImageHeader* image_header) 12390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_); 124208a5cb383dd9dcd3461f89b74af5df67dc8d794Mathieu Chartier void PatchClassTable(const ImageHeader* image_header) 125208a5cb383dd9dcd3461f89b74af5df67dc8d794Mathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_); 126c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier void PatchDexFileArrays(mirror::ObjectArray<mirror::Object>* img_roots) 12790443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_); 12853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light 12953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light bool WriteElf(File* out); 13053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light bool WriteImage(File* out); 13153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light 132c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier template <typename T> 133d39645e22b8db1767cf64dc1200a9e4b2f939ed2Mathieu Chartier T* RelocatedCopyOf(T* obj) const { 134c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier if (obj == nullptr) { 135c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier return nullptr; 136c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier } 137e271fe1e2797205c57c052212c32139234f781eaJeff Hao DCHECK_GT(reinterpret_cast<uintptr_t>(obj), reinterpret_cast<uintptr_t>(heap_->Begin())); 138e271fe1e2797205c57c052212c32139234f781eaJeff Hao DCHECK_LT(reinterpret_cast<uintptr_t>(obj), reinterpret_cast<uintptr_t>(heap_->End())); 139c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier uintptr_t heap_off = 140c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier reinterpret_cast<uintptr_t>(obj) - reinterpret_cast<uintptr_t>(heap_->Begin()); 141e271fe1e2797205c57c052212c32139234f781eaJeff Hao DCHECK_LT(heap_off, image_->Size()); 142c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier return reinterpret_cast<T*>(image_->Begin() + heap_off); 143c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier } 144c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier 145c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier template <typename T> 146dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao T* RelocatedCopyOfFollowImages(T* obj) const { 147dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao if (obj == nullptr) { 148dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao return nullptr; 149dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao } 150dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao // Find ImageSpace this belongs to. 151dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao auto image_spaces = Runtime::Current()->GetHeap()->GetBootImageSpaces(); 152dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao for (gc::space::ImageSpace* image_space : image_spaces) { 153dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao if (image_space->Contains(obj)) { 154dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao uintptr_t heap_off = reinterpret_cast<uintptr_t>(obj) - 155dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao reinterpret_cast<uintptr_t>(image_space->GetMemMap()->Begin()); 156dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao return reinterpret_cast<T*>(space_map_->find(image_space)->second->Begin() + heap_off); 157dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao } 158dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao } 159dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao LOG(FATAL) << "Did not find object in boot image space " << obj; 160dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao UNREACHABLE(); 161dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao } 162dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao 163dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao template <typename T> 164d39645e22b8db1767cf64dc1200a9e4b2f939ed2Mathieu Chartier T* RelocatedAddressOfPointer(T* obj) const { 165e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier if (obj == nullptr) { 166e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return obj; 167e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier } 168e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier auto ret = reinterpret_cast<uintptr_t>(obj) + delta_; 169e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier // Trim off high bits in case negative relocation with 64 bit patchoat. 170e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier if (InstructionSetPointerSize(isa_) == sizeof(uint32_t)) { 171e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier ret = static_cast<uintptr_t>(static_cast<uint32_t>(ret)); 172e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier } 173e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return reinterpret_cast<T*>(ret); 174e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier } 175e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier 176e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier template <typename T> 177d39645e22b8db1767cf64dc1200a9e4b2f939ed2Mathieu Chartier T RelocatedAddressOfIntPointer(T obj) const { 178e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier if (obj == 0) { 179e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return obj; 180e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier } 181e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier T ret = obj + delta_; 182e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier // Trim off high bits in case negative relocation with 64 bit patchoat. 183e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier if (InstructionSetPointerSize(isa_) == 4) { 184e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier ret = static_cast<T>(static_cast<uint32_t>(ret)); 185e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier } 186e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return ret; 187c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier } 18853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light 189eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light // Walks through the old image and patches the mmap'd copy of it to the new offset. It does not 190eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light // change the heap. 19153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light class PatchVisitor { 19253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light public: 19353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light PatchVisitor(PatchOat* patcher, mirror::Object* copy) : patcher_(patcher), copy_(copy) {} 19453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light ~PatchVisitor() {} 19553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light void operator() (mirror::Object* obj, MemberOffset off, bool b) const 196da7c650022a974be10e2f00fa07d5109e3d8826fMathieu Chartier REQUIRES(Locks::mutator_lock_, Locks::heap_bitmap_lock_); 19753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light // For reference classes. 19853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light void operator() (mirror::Class* cls, mirror::Reference* ref) const 199da7c650022a974be10e2f00fa07d5109e3d8826fMathieu Chartier REQUIRES(Locks::mutator_lock_, Locks::heap_bitmap_lock_); 200da7c650022a974be10e2f00fa07d5109e3d8826fMathieu Chartier // TODO: Consider using these for updating native class roots? 201da7c650022a974be10e2f00fa07d5109e3d8826fMathieu Chartier void VisitRootIfNonNull(mirror::CompressedReference<mirror::Object>* root ATTRIBUTE_UNUSED) 202da7c650022a974be10e2f00fa07d5109e3d8826fMathieu Chartier const {} 203da7c650022a974be10e2f00fa07d5109e3d8826fMathieu Chartier void VisitRoot(mirror::CompressedReference<mirror::Object>* root ATTRIBUTE_UNUSED) const {} 204da7c650022a974be10e2f00fa07d5109e3d8826fMathieu Chartier 20553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light private: 206d4c4d953035d4418126d36517e402f411d6a87f3Ian Rogers PatchOat* const patcher_; 207d4c4d953035d4418126d36517e402f411d6a87f3Ian Rogers mirror::Object* const copy_; 20853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light }; 20953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light 210eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light // The elf file we are patching. 211eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light std::unique_ptr<ElfFile> oat_file_; 212eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light // A mmap of the image we are patching. This is modified. 213d4c4d953035d4418126d36517e402f411d6a87f3Ian Rogers const MemMap* const image_; 214d4c4d953035d4418126d36517e402f411d6a87f3Ian Rogers // The bitmap over the image within the heap we are patching. This is not modified. 215d4c4d953035d4418126d36517e402f411d6a87f3Ian Rogers gc::accounting::ContinuousSpaceBitmap* const bitmap_; 216eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light // The heap we are patching. This is not modified. 217d4c4d953035d4418126d36517e402f411d6a87f3Ian Rogers const MemMap* const heap_; 218eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light // The amount we are changing the offset by. 219d4c4d953035d4418126d36517e402f411d6a87f3Ian Rogers const off_t delta_; 2202d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier // Active instruction set, used to know the entrypoint size. 2212d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier const InstructionSet isa_; 2222d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier 223dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao const std::map<gc::space::ImageSpace*, std::unique_ptr<MemMap>>* space_map_; 224dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao 2252d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier TimingLogger* timings_; 226eefbe39799126afdf7d315a79359b9da23d1cef5Alex Light 227d39645e22b8db1767cf64dc1200a9e4b2f939ed2Mathieu Chartier friend class FixupRootVisitor; 2284b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier friend class RelocatedPointerVisitor; 22954d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier friend class PatchOatArtFieldVisitor; 23054d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier friend class PatchOatArtMethodVisitor; 23153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light DISALLOW_IMPLICIT_CONSTRUCTORS(PatchOat); 23253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}; 23353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light 23453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light} // namespace art 23553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light#endif // ART_PATCHOAT_PATCHOAT_H_ 236