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 17 #include "elf_patcher.h" 18 19 #include <vector> 20 #include <set> 21 22 #include "elf_file.h" 23 #include "elf_utils.h" 24 #include "mirror/art_field-inl.h" 25 #include "mirror/art_method-inl.h" 26 #include "mirror/array-inl.h" 27 #include "mirror/class-inl.h" 28 #include "mirror/class_loader.h" 29 #include "mirror/dex_cache-inl.h" 30 #include "mirror/object-inl.h" 31 #include "mirror/object_array-inl.h" 32 #include "mirror/string-inl.h" 33 #include "oat.h" 34 #include "os.h" 35 #include "utils.h" 36 37 namespace art { 38 39 bool ElfPatcher::Patch(const CompilerDriver* driver, ElfFile* elf_file, 40 const std::string& oat_location, 41 ImageAddressCallback cb, void* cb_data, 42 std::string* error_msg) { 43 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 44 const OatFile* oat_file = class_linker->FindOpenedOatFileFromOatLocation(oat_location); 45 if (oat_file == nullptr) { 46 CHECK(Runtime::Current()->IsCompiler()); 47 oat_file = OatFile::Open(oat_location, oat_location, nullptr, nullptr, false, error_msg); 48 if (oat_file == nullptr) { 49 *error_msg = StringPrintf("Unable to find or open oat file at '%s': %s", oat_location.c_str(), 50 error_msg->c_str()); 51 return false; 52 } 53 CHECK_EQ(class_linker->RegisterOatFile(oat_file), oat_file); 54 } 55 return ElfPatcher::Patch(driver, elf_file, oat_file, 56 reinterpret_cast<uintptr_t>(oat_file->Begin()), cb, cb_data, error_msg); 57 } 58 59 bool ElfPatcher::Patch(const CompilerDriver* driver, ElfFile* elf, const OatFile* oat_file, 60 uintptr_t oat_data_start, ImageAddressCallback cb, void* cb_data, 61 std::string* error_msg) { 62 Elf32_Shdr* data_sec = elf->FindSectionByName(".rodata"); 63 if (data_sec == nullptr) { 64 *error_msg = "Unable to find .rodata section and oat header"; 65 return false; 66 } 67 OatHeader* oat_header = reinterpret_cast<OatHeader*>(elf->Begin() + data_sec->sh_offset); 68 if (!oat_header->IsValid()) { 69 *error_msg = "Oat header was not valid"; 70 return false; 71 } 72 73 ElfPatcher p(driver, elf, oat_file, oat_header, oat_data_start, cb, cb_data, error_msg); 74 return p.PatchElf(); 75 } 76 77 mirror::ArtMethod* ElfPatcher::GetTargetMethod(const CompilerDriver::CallPatchInformation* patch) { 78 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 79 StackHandleScope<1> hs(Thread::Current()); 80 Handle<mirror::DexCache> dex_cache( 81 hs.NewHandle(class_linker->FindDexCache(*patch->GetTargetDexFile()))); 82 mirror::ArtMethod* method = class_linker->ResolveMethod(*patch->GetTargetDexFile(), 83 patch->GetTargetMethodIdx(), 84 dex_cache, 85 NullHandle<mirror::ClassLoader>(), 86 NullHandle<mirror::ArtMethod>(), 87 patch->GetTargetInvokeType()); 88 CHECK(method != NULL) 89 << patch->GetTargetDexFile()->GetLocation() << " " << patch->GetTargetMethodIdx(); 90 CHECK(!method->IsRuntimeMethod()) 91 << patch->GetTargetDexFile()->GetLocation() << " " << patch->GetTargetMethodIdx(); 92 CHECK(dex_cache->GetResolvedMethods()->Get(patch->GetTargetMethodIdx()) == method) 93 << patch->GetTargetDexFile()->GetLocation() << " " << patch->GetReferrerMethodIdx() << " " 94 << PrettyMethod(dex_cache->GetResolvedMethods()->Get(patch->GetTargetMethodIdx())) << " " 95 << PrettyMethod(method); 96 return method; 97 } 98 99 mirror::String* ElfPatcher::GetTargetString(const CompilerDriver::StringPatchInformation* patch) { 100 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 101 StackHandleScope<1> hs(Thread::Current()); 102 Handle<mirror::DexCache> dex_cache(hs.NewHandle(class_linker->FindDexCache(patch->GetDexFile()))); 103 mirror::String* string = class_linker->ResolveString(patch->GetDexFile(), patch->GetStringIdx(), 104 dex_cache); 105 CHECK(string != nullptr) << patch->GetDexFile().GetLocation() << " " << patch->GetStringIdx(); 106 return string; 107 } 108 109 mirror::Class* ElfPatcher::GetTargetType(const CompilerDriver::TypePatchInformation* patch) { 110 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 111 StackHandleScope<2> hs(Thread::Current()); 112 Handle<mirror::DexCache> dex_cache(hs.NewHandle(class_linker->FindDexCache(patch->GetDexFile()))); 113 mirror::Class* klass = class_linker->ResolveType(patch->GetDexFile(), patch->GetTargetTypeIdx(), 114 dex_cache, NullHandle<mirror::ClassLoader>()); 115 CHECK(klass != NULL) 116 << patch->GetDexFile().GetLocation() << " " << patch->GetTargetTypeIdx(); 117 CHECK(dex_cache->GetResolvedTypes()->Get(patch->GetTargetTypeIdx()) == klass) 118 << patch->GetDexFile().GetLocation() << " " << patch->GetReferrerMethodIdx() << " " 119 << PrettyClass(dex_cache->GetResolvedTypes()->Get(patch->GetTargetTypeIdx())) << " " 120 << PrettyClass(klass); 121 return klass; 122 } 123 124 void ElfPatcher::AddPatch(uintptr_t p) { 125 if (write_patches_ && patches_set_.find(p) == patches_set_.end()) { 126 patches_set_.insert(p); 127 patches_.push_back(p); 128 } 129 } 130 131 uint32_t* ElfPatcher::GetPatchLocation(uintptr_t patch_ptr) { 132 CHECK_GE(patch_ptr, reinterpret_cast<uintptr_t>(oat_file_->Begin())); 133 CHECK_LE(patch_ptr, reinterpret_cast<uintptr_t>(oat_file_->End())); 134 uintptr_t off = patch_ptr - reinterpret_cast<uintptr_t>(oat_file_->Begin()); 135 uintptr_t ret = reinterpret_cast<uintptr_t>(oat_header_) + off; 136 137 CHECK_GE(ret, reinterpret_cast<uintptr_t>(elf_file_->Begin())); 138 CHECK_LT(ret, reinterpret_cast<uintptr_t>(elf_file_->End())); 139 return reinterpret_cast<uint32_t*>(ret); 140 } 141 142 void ElfPatcher::SetPatchLocation(const CompilerDriver::PatchInformation* patch, uint32_t value) { 143 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 144 const void* quick_oat_code = class_linker->GetQuickOatCodeFor(patch->GetDexFile(), 145 patch->GetReferrerClassDefIdx(), 146 patch->GetReferrerMethodIdx()); 147 // TODO: make this Thumb2 specific 148 uint8_t* base = reinterpret_cast<uint8_t*>(reinterpret_cast<uintptr_t>(quick_oat_code) & ~0x1); 149 uintptr_t patch_ptr = reinterpret_cast<uintptr_t>(base + patch->GetLiteralOffset()); 150 uint32_t* patch_location = GetPatchLocation(patch_ptr); 151 if (kIsDebugBuild) { 152 if (patch->IsCall()) { 153 const CompilerDriver::CallPatchInformation* cpatch = patch->AsCall(); 154 const DexFile::MethodId& id = 155 cpatch->GetTargetDexFile()->GetMethodId(cpatch->GetTargetMethodIdx()); 156 uint32_t expected = reinterpret_cast<uintptr_t>(&id) & 0xFFFFFFFF; 157 uint32_t actual = *patch_location; 158 CHECK(actual == expected || actual == value) << "Patching call failed: " << std::hex 159 << " actual=" << actual 160 << " expected=" << expected 161 << " value=" << value; 162 } 163 if (patch->IsType()) { 164 const CompilerDriver::TypePatchInformation* tpatch = patch->AsType(); 165 const DexFile::TypeId& id = tpatch->GetDexFile().GetTypeId(tpatch->GetTargetTypeIdx()); 166 uint32_t expected = reinterpret_cast<uintptr_t>(&id) & 0xFFFFFFFF; 167 uint32_t actual = *patch_location; 168 CHECK(actual == expected || actual == value) << "Patching type failed: " << std::hex 169 << " actual=" << actual 170 << " expected=" << expected 171 << " value=" << value; 172 } 173 } 174 *patch_location = value; 175 oat_header_->UpdateChecksum(patch_location, sizeof(value)); 176 177 if (patch->IsCall() && patch->AsCall()->IsRelative()) { 178 // We never record relative patches. 179 return; 180 } 181 uintptr_t loc = patch_ptr - (reinterpret_cast<uintptr_t>(oat_file_->Begin()) + 182 oat_header_->GetExecutableOffset()); 183 CHECK_GT(patch_ptr, reinterpret_cast<uintptr_t>(oat_file_->Begin()) + 184 oat_header_->GetExecutableOffset()); 185 CHECK_LT(loc, oat_file_->Size() - oat_header_->GetExecutableOffset()); 186 AddPatch(loc); 187 } 188 189 bool ElfPatcher::PatchElf() { 190 // TODO if we are adding patches the resulting ELF file might have a 191 // potentially rather large amount of free space where patches might have been 192 // placed. We should adjust the ELF file to get rid of this excess space. 193 if (write_patches_) { 194 patches_.reserve(compiler_driver_->GetCodeToPatch().size() + 195 compiler_driver_->GetMethodsToPatch().size() + 196 compiler_driver_->GetClassesToPatch().size() + 197 compiler_driver_->GetStringsToPatch().size()); 198 } 199 Thread* self = Thread::Current(); 200 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 201 const char* old_cause = self->StartAssertNoThreadSuspension("ElfPatcher"); 202 203 typedef std::vector<const CompilerDriver::CallPatchInformation*> CallPatches; 204 const CallPatches& code_to_patch = compiler_driver_->GetCodeToPatch(); 205 for (size_t i = 0; i < code_to_patch.size(); i++) { 206 const CompilerDriver::CallPatchInformation* patch = code_to_patch[i]; 207 208 mirror::ArtMethod* target = GetTargetMethod(patch); 209 uintptr_t quick_code = reinterpret_cast<uintptr_t>(class_linker->GetQuickOatCodeFor(target)); 210 DCHECK_NE(quick_code, 0U) << PrettyMethod(target); 211 const OatFile* target_oat = 212 class_linker->FindOpenedOatDexFileForDexFile(*patch->GetTargetDexFile())->GetOatFile(); 213 // Get where the data actually starts. if target is this oat_file_ it is oat_data_start_, 214 // otherwise it is wherever target_oat is loaded. 215 uintptr_t oat_data_addr = GetBaseAddressFor(target_oat); 216 uintptr_t code_base = reinterpret_cast<uintptr_t>(target_oat->Begin()); 217 uintptr_t code_offset = quick_code - code_base; 218 bool is_quick_offset = false; 219 if (quick_code == reinterpret_cast<uintptr_t>(GetQuickToInterpreterBridge())) { 220 is_quick_offset = true; 221 code_offset = oat_header_->GetQuickToInterpreterBridgeOffset(); 222 } else if (quick_code == 223 reinterpret_cast<uintptr_t>(class_linker->GetQuickGenericJniTrampoline())) { 224 CHECK(target->IsNative()); 225 is_quick_offset = true; 226 code_offset = oat_header_->GetQuickGenericJniTrampolineOffset(); 227 } 228 uintptr_t value; 229 if (patch->IsRelative()) { 230 // value to patch is relative to the location being patched 231 const void* quick_oat_code = 232 class_linker->GetQuickOatCodeFor(patch->GetDexFile(), 233 patch->GetReferrerClassDefIdx(), 234 patch->GetReferrerMethodIdx()); 235 if (is_quick_offset) { 236 // If its a quick offset it means that we are doing a relative patch from the class linker 237 // oat_file to the elf_patcher oat_file so we need to adjust the quick oat code to be the 238 // one in the output oat_file (ie where it is actually going to be loaded). 239 quick_code = PointerToLowMemUInt32(reinterpret_cast<void*>(oat_data_addr + code_offset)); 240 quick_oat_code = 241 reinterpret_cast<const void*>(reinterpret_cast<uintptr_t>(quick_oat_code) + 242 oat_data_addr - code_base); 243 } 244 uintptr_t base = reinterpret_cast<uintptr_t>(quick_oat_code); 245 uintptr_t patch_location = base + patch->GetLiteralOffset(); 246 value = quick_code - patch_location + patch->RelativeOffset(); 247 } else if (code_offset != 0) { 248 value = PointerToLowMemUInt32(reinterpret_cast<void*>(oat_data_addr + code_offset)); 249 } else { 250 value = 0; 251 } 252 SetPatchLocation(patch, value); 253 } 254 255 const CallPatches& methods_to_patch = compiler_driver_->GetMethodsToPatch(); 256 for (size_t i = 0; i < methods_to_patch.size(); i++) { 257 const CompilerDriver::CallPatchInformation* patch = methods_to_patch[i]; 258 mirror::ArtMethod* target = GetTargetMethod(patch); 259 SetPatchLocation(patch, PointerToLowMemUInt32(get_image_address_(cb_data_, target))); 260 } 261 262 for (const CompilerDriver::TypePatchInformation* patch : compiler_driver_->GetClassesToPatch()) { 263 mirror::Class* target = GetTargetType(patch); 264 SetPatchLocation(patch, PointerToLowMemUInt32(get_image_address_(cb_data_, target))); 265 } 266 for (const CompilerDriver::StringPatchInformation* patch : 267 compiler_driver_->GetStringsToPatch()) { 268 mirror::String* target = GetTargetString(patch); 269 SetPatchLocation(patch, PointerToLowMemUInt32(get_image_address_(cb_data_, target))); 270 } 271 272 self->EndAssertNoThreadSuspension(old_cause); 273 274 if (write_patches_) { 275 return WriteOutPatchData(); 276 } 277 return true; 278 } 279 280 bool ElfPatcher::WriteOutPatchData() { 281 Elf32_Shdr* shdr = elf_file_->FindSectionByName(".oat_patches"); 282 if (shdr != nullptr) { 283 CHECK_EQ(shdr, elf_file_->FindSectionByType(SHT_OAT_PATCH)) 284 << "Incorrect type for .oat_patches section"; 285 CHECK_LE(patches_.size() * sizeof(uintptr_t), shdr->sh_size) 286 << "We got more patches than anticipated"; 287 CHECK_LE(reinterpret_cast<uintptr_t>(elf_file_->Begin()) + shdr->sh_offset + shdr->sh_size, 288 reinterpret_cast<uintptr_t>(elf_file_->End())) << "section is too large"; 289 CHECK(shdr == elf_file_->GetSectionHeader(elf_file_->GetSectionHeaderNum() - 1) || 290 shdr->sh_offset + shdr->sh_size <= (shdr + 1)->sh_offset) 291 << "Section overlaps onto next section"; 292 // It's mmap'd so we can just memcpy. 293 memcpy(elf_file_->Begin() + shdr->sh_offset, patches_.data(), 294 patches_.size() * sizeof(uintptr_t)); 295 // TODO We should fill in the newly empty space between the last patch and 296 // the start of the next section by moving the following sections down if 297 // possible. 298 shdr->sh_size = patches_.size() * sizeof(uintptr_t); 299 return true; 300 } else { 301 LOG(ERROR) << "Unable to find section header for SHT_OAT_PATCH"; 302 *error_msg_ = "Unable to find section to write patch information to in "; 303 *error_msg_ += elf_file_->GetFile().GetPath(); 304 return false; 305 } 306 } 307 308 } // namespace art 309