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