1700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom/*
2700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom * Copyright (C) 2012 The Android Open Source Project
3700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom *
4700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom * Licensed under the Apache License, Version 2.0 (the "License");
5700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom * you may not use this file except in compliance with the License.
6700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom * You may obtain a copy of the License at
7700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom *
8700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom *      http://www.apache.org/licenses/LICENSE-2.0
9700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom *
10700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom * Unless required by applicable law or agreed to in writing, software
11700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom * distributed under the License is distributed on an "AS IS" BASIS,
12700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom * See the License for the specific language governing permissions and
14700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom * limitations under the License.
15700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom */
16700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom
17700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom#include "elf_writer.h"
18700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom
193d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier#include "art_method-inl.h"
20265091e581c9f643b37e7966890911f09e223269Brian Carlstrom#include "base/unix_file/fd_file.h"
21265091e581c9f643b37e7966890911f09e223269Brian Carlstrom#include "class_linker.h"
22225ade2eef559a8609879f142789a4f59aec5704Ian Rogers#include "dex_file-inl.h"
23265091e581c9f643b37e7966890911f09e223269Brian Carlstrom#include "dex_method_iterator.h"
247940e44f4517de5e2634a7e07d58d0fb26160513Brian Carlstrom#include "driver/compiler_driver.h"
25265091e581c9f643b37e7966890911f09e223269Brian Carlstrom#include "elf_file.h"
26265091e581c9f643b37e7966890911f09e223269Brian Carlstrom#include "invoke_type.h"
27225ade2eef559a8609879f142789a4f59aec5704Ian Rogers#include "mirror/object-inl.h"
28265091e581c9f643b37e7966890911f09e223269Brian Carlstrom#include "oat.h"
29265091e581c9f643b37e7966890911f09e223269Brian Carlstrom#include "scoped_thread_state_change.h"
30265091e581c9f643b37e7966890911f09e223269Brian Carlstrom
31700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstromnamespace art {
32700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom
3362d1ca3182a6cbb921799825f43ad36821233fd7Tong Shenuintptr_t ElfWriter::GetOatDataAddress(ElfFile* elf_file) {
3462d1ca3182a6cbb921799825f43ad36821233fd7Tong Shen  uintptr_t oatdata_address = elf_file->FindSymbolAddress(SHT_DYNSYM,
3550cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray                                                           "oatdata",
3650cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray                                                           false);
37265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  CHECK_NE(0U, oatdata_address);
38265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  return oatdata_address;
39265091e581c9f643b37e7966890911f09e223269Brian Carlstrom}
40265091e581c9f643b37e7966890911f09e223269Brian Carlstrom
41700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstromvoid ElfWriter::GetOatElfInformation(File* file,
42a36098b3717e14baf6a173e72082f6ef3b7bcefdVladimir Marko                                     size_t* oat_loaded_size,
43a36098b3717e14baf6a173e72082f6ef3b7bcefdVladimir Marko                                     size_t* oat_data_offset) {
448d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers  std::string error_msg;
45700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers  std::unique_ptr<ElfFile> elf_file(ElfFile::Open(file, false, false, &error_msg));
463470ab4011b5e18d590d5375e2f13a1e3bd69222Alex Light  CHECK(elf_file.get() != nullptr) << error_msg;
47700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom
48a36098b3717e14baf6a173e72082f6ef3b7bcefdVladimir Marko  bool success = elf_file->GetLoadedSize(oat_loaded_size, &error_msg);
49a36098b3717e14baf6a173e72082f6ef3b7bcefdVladimir Marko  CHECK(success) << error_msg;
50a36098b3717e14baf6a173e72082f6ef3b7bcefdVladimir Marko  CHECK_NE(0U, *oat_loaded_size);
51a36098b3717e14baf6a173e72082f6ef3b7bcefdVladimir Marko  *oat_data_offset = GetOatDataAddress(elf_file.get());
52a36098b3717e14baf6a173e72082f6ef3b7bcefdVladimir Marko  CHECK_NE(0U, *oat_data_offset);
53700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom}
54700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom
5562d1ca3182a6cbb921799825f43ad36821233fd7Tong Shenbool ElfWriter::Fixup(File* file, uintptr_t oat_data_begin) {
5662d1ca3182a6cbb921799825f43ad36821233fd7Tong Shen  std::string error_msg;
5762d1ca3182a6cbb921799825f43ad36821233fd7Tong Shen  std::unique_ptr<ElfFile> elf_file(ElfFile::Open(file, true, false, &error_msg));
5862d1ca3182a6cbb921799825f43ad36821233fd7Tong Shen  CHECK(elf_file.get() != nullptr) << error_msg;
5962d1ca3182a6cbb921799825f43ad36821233fd7Tong Shen
6062d1ca3182a6cbb921799825f43ad36821233fd7Tong Shen  // Lookup "oatdata" symbol address.
6162d1ca3182a6cbb921799825f43ad36821233fd7Tong Shen  uintptr_t oatdata_address = ElfWriter::GetOatDataAddress(elf_file.get());
6262d1ca3182a6cbb921799825f43ad36821233fd7Tong Shen  uintptr_t base_address = oat_data_begin - oatdata_address;
6362d1ca3182a6cbb921799825f43ad36821233fd7Tong Shen
6462d1ca3182a6cbb921799825f43ad36821233fd7Tong Shen  return elf_file->Fixup(base_address);
6562d1ca3182a6cbb921799825f43ad36821233fd7Tong Shen}
6662d1ca3182a6cbb921799825f43ad36821233fd7Tong Shen
67700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom}  // namespace art
68